@@ -2182,26 +2182,90 @@ func (s *SQLiteStmt) NumInput() int {
21822182
21832183var placeHolder = []byte {0 }
21842184
2185+ func hasNamedArgs (args []driver.NamedValue ) bool {
2186+ for _ , v := range args {
2187+ if v .Name != "" {
2188+ return true
2189+ }
2190+ }
2191+ return false
2192+ }
2193+
21852194func (s * SQLiteStmt ) bind (args []driver.NamedValue ) error {
21862195 rv := C .sqlite3_reset (s .s )
21872196 if rv != C .SQLITE_ROW && rv != C .SQLITE_OK && rv != C .SQLITE_DONE {
21882197 return s .c .lastError ()
21892198 }
21902199
2200+ if hasNamedArgs (args ) {
2201+ return s .bindIndices (args )
2202+ }
2203+
2204+ for _ , arg := range args {
2205+ n := C .int (arg .Ordinal )
2206+ switch v := arg .Value .(type ) {
2207+ case nil :
2208+ rv = C .sqlite3_bind_null (s .s , n )
2209+ case string :
2210+ p := stringData (v )
2211+ rv = C ._sqlite3_bind_text (s .s , n , (* C .char )(unsafe .Pointer (p )), C .int (len (v )))
2212+ case int64 :
2213+ rv = C .sqlite3_bind_int64 (s .s , n , C .sqlite3_int64 (v ))
2214+ case bool :
2215+ val := 0
2216+ if v {
2217+ val = 1
2218+ }
2219+ rv = C .sqlite3_bind_int (s .s , n , C .int (val ))
2220+ case float64 :
2221+ rv = C .sqlite3_bind_double (s .s , n , C .double (v ))
2222+ case []byte :
2223+ if v == nil {
2224+ rv = C .sqlite3_bind_null (s .s , n )
2225+ } else {
2226+ ln := len (v )
2227+ if ln == 0 {
2228+ v = placeHolder
2229+ }
2230+ rv = C ._sqlite3_bind_blob (s .s , n , unsafe .Pointer (& v [0 ]), C .int (ln ))
2231+ }
2232+ case time.Time :
2233+ ts := v .Format (SQLiteTimestampFormats [0 ])
2234+ p := stringData (ts )
2235+ rv = C ._sqlite3_bind_text (s .s , n , (* C .char )(unsafe .Pointer (p )), C .int (len (ts )))
2236+ }
2237+ if rv != C .SQLITE_OK {
2238+ return s .c .lastError ()
2239+ }
2240+ }
2241+ return nil
2242+ }
2243+
2244+ func (s * SQLiteStmt ) bindIndices (args []driver.NamedValue ) error {
2245+ // Find the longest named parameter name.
2246+ n := 0
2247+ for _ , v := range args {
2248+ if m := len (v .Name ); m > n {
2249+ n = m
2250+ }
2251+ }
2252+ buf := make ([]byte , 0 , n + 2 ) // +2 for placeholder and null terminator
2253+
21912254 bindIndices := make ([][3 ]int , len (args ))
2192- prefixes := []string {":" , "@" , "$" }
21932255 for i , v := range args {
21942256 bindIndices [i ][0 ] = args [i ].Ordinal
21952257 if v .Name != "" {
2196- for j := range prefixes {
2197- cname := C .CString (prefixes [j ] + v .Name )
2198- bindIndices [i ][j ] = int (C .sqlite3_bind_parameter_index (s .s , cname ))
2199- C .free (unsafe .Pointer (cname ))
2258+ for j , c := range []byte {':' , '@' , '$' } {
2259+ buf = append (buf [:0 ], c )
2260+ buf = append (buf , v .Name ... )
2261+ buf = append (buf , 0 )
2262+ bindIndices [i ][j ] = int (C .sqlite3_bind_parameter_index (s .s , (* C .char )(unsafe .Pointer (& buf [0 ]))))
22002263 }
22012264 args [i ].Ordinal = bindIndices [i ][0 ]
22022265 }
22032266 }
22042267
2268+ var rv C.int
22052269 for i , arg := range args {
22062270 for j := range bindIndices [i ] {
22072271 if bindIndices [i ][j ] == 0 {
@@ -2212,20 +2276,16 @@ func (s *SQLiteStmt) bind(args []driver.NamedValue) error {
22122276 case nil :
22132277 rv = C .sqlite3_bind_null (s .s , n )
22142278 case string :
2215- if len (v ) == 0 {
2216- rv = C ._sqlite3_bind_text (s .s , n , (* C .char )(unsafe .Pointer (& placeHolder [0 ])), C .int (0 ))
2217- } else {
2218- b := []byte (v )
2219- rv = C ._sqlite3_bind_text (s .s , n , (* C .char )(unsafe .Pointer (& b [0 ])), C .int (len (b )))
2220- }
2279+ p := stringData (v )
2280+ rv = C ._sqlite3_bind_text (s .s , n , (* C .char )(unsafe .Pointer (p )), C .int (len (v )))
22212281 case int64 :
22222282 rv = C .sqlite3_bind_int64 (s .s , n , C .sqlite3_int64 (v ))
22232283 case bool :
2284+ val := 0
22242285 if v {
2225- rv = C .sqlite3_bind_int (s .s , n , 1 )
2226- } else {
2227- rv = C .sqlite3_bind_int (s .s , n , 0 )
2286+ val = 1
22282287 }
2288+ rv = C .sqlite3_bind_int (s .s , n , C .int (val ))
22292289 case float64 :
22302290 rv = C .sqlite3_bind_double (s .s , n , C .double (v ))
22312291 case []byte :
@@ -2239,8 +2299,9 @@ func (s *SQLiteStmt) bind(args []driver.NamedValue) error {
22392299 rv = C ._sqlite3_bind_blob (s .s , n , unsafe .Pointer (& v [0 ]), C .int (ln ))
22402300 }
22412301 case time.Time :
2242- b := []byte (v .Format (SQLiteTimestampFormats [0 ]))
2243- rv = C ._sqlite3_bind_text (s .s , n , (* C .char )(unsafe .Pointer (& b [0 ])), C .int (len (b )))
2302+ ts := v .Format (SQLiteTimestampFormats [0 ])
2303+ p := stringData (ts )
2304+ rv = C ._sqlite3_bind_text (s .s , n , (* C .char )(unsafe .Pointer (p )), C .int (len (ts )))
22442305 }
22452306 if rv != C .SQLITE_OK {
22462307 return s .c .lastError ()
0 commit comments