@@ -382,6 +382,7 @@ type SQLiteStmt struct {
382
382
t string
383
383
closed bool
384
384
cls bool // True if the statement was created by SQLiteConn.Query
385
+ reset bool // True if the statement needs to reset before reuse
385
386
}
386
387
387
388
// SQLiteResult implements sql.Result.
@@ -1921,26 +1922,97 @@ func (s *SQLiteStmt) NumInput() int {
1921
1922
1922
1923
var placeHolder = []byte {0 }
1923
1924
1925
+ func hasNamedArgs (args []driver.NamedValue ) bool {
1926
+ for _ , v := range args {
1927
+ if v .Name != "" {
1928
+ return true
1929
+ }
1930
+ }
1931
+ return false
1932
+ }
1933
+
1924
1934
func (s * SQLiteStmt ) bind (args []driver.NamedValue ) error {
1925
- rv := C .sqlite3_reset (s .s )
1926
- if rv != C .SQLITE_ROW && rv != C .SQLITE_OK && rv != C .SQLITE_DONE {
1927
- return s .c .lastError ()
1935
+ if s .reset {
1936
+ // The statement was previously used so we need to reset it.
1937
+ rv := C .sqlite3_reset (s .s )
1938
+ if rv != C .SQLITE_ROW && rv != C .SQLITE_OK && rv != C .SQLITE_DONE {
1939
+ return s .c .lastError ()
1940
+ }
1941
+ } else {
1942
+ // First call to bind, future calls will need to reset the statement.
1943
+ s .reset = true
1944
+ }
1945
+
1946
+ if hasNamedArgs (args ) {
1947
+ return s .bindIndices (args )
1948
+ }
1949
+
1950
+ var rv C.int
1951
+ for _ , arg := range args {
1952
+ n := C .int (arg .Ordinal )
1953
+ switch v := arg .Value .(type ) {
1954
+ case nil :
1955
+ rv = C .sqlite3_bind_null (s .s , n )
1956
+ case string :
1957
+ p := stringData (v )
1958
+ rv = C ._sqlite3_bind_text (s .s , n , (* C .char )(unsafe .Pointer (p )), C .int (len (v )))
1959
+ case int64 :
1960
+ rv = C .sqlite3_bind_int64 (s .s , n , C .sqlite3_int64 (v ))
1961
+ case bool :
1962
+ val := 0
1963
+ if v {
1964
+ val = 1
1965
+ }
1966
+ rv = C .sqlite3_bind_int (s .s , n , C .int (val ))
1967
+ case float64 :
1968
+ rv = C .sqlite3_bind_double (s .s , n , C .double (v ))
1969
+ case []byte :
1970
+ if v == nil {
1971
+ rv = C .sqlite3_bind_null (s .s , n )
1972
+ } else {
1973
+ ln := len (v )
1974
+ if ln == 0 {
1975
+ v = placeHolder
1976
+ }
1977
+ rv = C ._sqlite3_bind_blob (s .s , n , unsafe .Pointer (& v [0 ]), C .int (ln ))
1978
+ }
1979
+ case time.Time :
1980
+ ts := v .Format (SQLiteTimestampFormats [0 ])
1981
+ p := stringData (ts )
1982
+ rv = C ._sqlite3_bind_text (s .s , n , (* C .char )(unsafe .Pointer (p )), C .int (len (ts )))
1983
+ }
1984
+ if rv != C .SQLITE_OK {
1985
+ return s .c .lastError ()
1986
+ }
1928
1987
}
1988
+ return nil
1989
+ }
1990
+
1991
+ func (s * SQLiteStmt ) bindIndices (args []driver.NamedValue ) error {
1992
+ // Find the longest named parameter name.
1993
+ n := 0
1994
+ for _ , v := range args {
1995
+ if m := len (v .Name ); m > n {
1996
+ n = m
1997
+ }
1998
+ }
1999
+ buf := make ([]byte , 0 , n + 2 ) // +2 for placeholder and null terminator
1929
2000
1930
2001
bindIndices := make ([][3 ]int , len (args ))
1931
- prefixes := []string {":" , "@" , "$" }
1932
2002
for i , v := range args {
1933
2003
bindIndices [i ][0 ] = args [i ].Ordinal
1934
2004
if v .Name != "" {
1935
- for j := range prefixes {
1936
- cname := C .CString (prefixes [j ] + v .Name )
1937
- bindIndices [i ][j ] = int (C .sqlite3_bind_parameter_index (s .s , cname ))
1938
- C .free (unsafe .Pointer (cname ))
2005
+ for j , c := range []byte {':' , '@' , '$' } {
2006
+ buf = append (buf [:0 ], c )
2007
+ buf = append (buf , v .Name ... )
2008
+ buf = append (buf , 0 )
2009
+ bindIndices [i ][j ] = int (C .sqlite3_bind_parameter_index (s .s , (* C .char )(unsafe .Pointer (& buf [0 ]))))
1939
2010
}
1940
2011
args [i ].Ordinal = bindIndices [i ][0 ]
1941
2012
}
1942
2013
}
1943
2014
2015
+ var rv C.int
1944
2016
for i , arg := range args {
1945
2017
for j := range bindIndices [i ] {
1946
2018
if bindIndices [i ][j ] == 0 {
@@ -1951,20 +2023,16 @@ func (s *SQLiteStmt) bind(args []driver.NamedValue) error {
1951
2023
case nil :
1952
2024
rv = C .sqlite3_bind_null (s .s , n )
1953
2025
case string :
1954
- if len (v ) == 0 {
1955
- rv = C ._sqlite3_bind_text (s .s , n , (* C .char )(unsafe .Pointer (& placeHolder [0 ])), C .int (0 ))
1956
- } else {
1957
- b := []byte (v )
1958
- rv = C ._sqlite3_bind_text (s .s , n , (* C .char )(unsafe .Pointer (& b [0 ])), C .int (len (b )))
1959
- }
2026
+ p := stringData (v )
2027
+ rv = C ._sqlite3_bind_text (s .s , n , (* C .char )(unsafe .Pointer (p )), C .int (len (v )))
1960
2028
case int64 :
1961
2029
rv = C .sqlite3_bind_int64 (s .s , n , C .sqlite3_int64 (v ))
1962
2030
case bool :
2031
+ val := 0
1963
2032
if v {
1964
- rv = C .sqlite3_bind_int (s .s , n , 1 )
1965
- } else {
1966
- rv = C .sqlite3_bind_int (s .s , n , 0 )
2033
+ val = 1
1967
2034
}
2035
+ rv = C .sqlite3_bind_int (s .s , n , C .int (val ))
1968
2036
case float64 :
1969
2037
rv = C .sqlite3_bind_double (s .s , n , C .double (v ))
1970
2038
case []byte :
@@ -1978,8 +2046,9 @@ func (s *SQLiteStmt) bind(args []driver.NamedValue) error {
1978
2046
rv = C ._sqlite3_bind_blob (s .s , n , unsafe .Pointer (& v [0 ]), C .int (ln ))
1979
2047
}
1980
2048
case time.Time :
1981
- b := []byte (v .Format (SQLiteTimestampFormats [0 ]))
1982
- rv = C ._sqlite3_bind_text (s .s , n , (* C .char )(unsafe .Pointer (& b [0 ])), C .int (len (b )))
2049
+ ts := v .Format (SQLiteTimestampFormats [0 ])
2050
+ p := stringData (ts )
2051
+ rv = C ._sqlite3_bind_text (s .s , n , (* C .char )(unsafe .Pointer (p )), C .int (len (ts )))
1983
2052
}
1984
2053
if rv != C .SQLITE_OK {
1985
2054
return s .c .lastError ()
0 commit comments