@@ -540,7 +540,7 @@ func (c *SQLiteConn) RegisterCollation(name string, cmp func(string, string) int
540
540
defer C .free (unsafe .Pointer (cname ))
541
541
rv := C .sqlite3_create_collation (c .db , cname , C .SQLITE_UTF8 , handle , (* [0 ]byte )(unsafe .Pointer (C .compareTrampoline )))
542
542
if rv != C .SQLITE_OK {
543
- return c .lastError ()
543
+ return c .lastError (int ( rv ) )
544
544
}
545
545
return nil
546
546
}
@@ -675,7 +675,7 @@ func (c *SQLiteConn) RegisterFunc(name string, impl any, pure bool) error {
675
675
}
676
676
rv := sqlite3CreateFunction (c .db , cname , C .int (numArgs ), C .int (opts ), newHandle (c , & fi ), C .callbackTrampoline , nil , nil )
677
677
if rv != C .SQLITE_OK {
678
- return c .lastError ()
678
+ return c .lastError (int ( rv ) )
679
679
}
680
680
return nil
681
681
}
@@ -804,7 +804,7 @@ func (c *SQLiteConn) RegisterAggregator(name string, impl any, pure bool) error
804
804
}
805
805
rv := sqlite3CreateFunction (c .db , cname , C .int (stepNArgs ), C .int (opts ), newHandle (c , & ai ), nil , C .stepTrampoline , C .doneTrampoline )
806
806
if rv != C .SQLITE_OK {
807
- return c .lastError ()
807
+ return c .lastError (int ( rv ) )
808
808
}
809
809
return nil
810
810
}
@@ -816,32 +816,38 @@ func (c *SQLiteConn) AutoCommit() bool {
816
816
return int (C .sqlite3_get_autocommit (c .db )) != 0
817
817
}
818
818
819
- func (c * SQLiteConn ) lastError () error {
820
- return lastError (c .db )
819
+ func (c * SQLiteConn ) lastError (rv int ) error {
820
+ return lastError (c .db , rv )
821
821
}
822
822
823
- // Note: may be called with db == nil
824
- func lastError (db * C.sqlite3 ) error {
825
- rv := C .sqlite3_errcode (db ) // returns SQLITE_NOMEM if db == nil
826
- if rv == C .SQLITE_OK {
823
+ func lastError (db * C.sqlite3 , rv int ) error {
824
+ if rv == SQLITE_OK {
827
825
return nil
828
826
}
829
- extrv := C .sqlite3_extended_errcode (db ) // returns SQLITE_NOMEM if db == nil
830
- errStr := C .GoString (C .sqlite3_errmsg (db )) // returns "out of memory" if db == nil
827
+ extrv := rv
828
+ // Convert the extended result code to a basic result code.
829
+ rv &= ErrNoMask
831
830
832
831
// https://www.sqlite.org/c3ref/system_errno.html
833
832
// sqlite3_system_errno is only meaningful if the error code was SQLITE_CANTOPEN,
834
833
// or it was SQLITE_IOERR and the extended code was not SQLITE_IOERR_NOMEM
835
834
var systemErrno syscall.Errno
836
- if rv == C .SQLITE_CANTOPEN || (rv == C .SQLITE_IOERR && extrv != C .SQLITE_IOERR_NOMEM ) {
835
+ if db != nil && (rv == C .SQLITE_CANTOPEN ||
836
+ (rv == C .SQLITE_IOERR && extrv != C .SQLITE_IOERR_NOMEM )) {
837
837
systemErrno = syscall .Errno (C .sqlite3_system_errno (db ))
838
838
}
839
839
840
+ var msg string
841
+ if db != nil {
842
+ msg = C .GoString (C .sqlite3_errmsg (db ))
843
+ } else {
844
+ msg = errorString (extrv )
845
+ }
840
846
return Error {
841
847
Code : ErrNo (rv ),
842
848
ExtendedCode : ErrNoExtended (extrv ),
843
849
SystemErrno : systemErrno ,
844
- err : errStr ,
850
+ err : msg ,
845
851
}
846
852
}
847
853
@@ -1467,7 +1473,7 @@ func (d *SQLiteDriver) Open(dsn string) (driver.Conn, error) {
1467
1473
if rv != 0 {
1468
1474
// Save off the error _before_ closing the database.
1469
1475
// This is safe even if db is nil.
1470
- err := lastError (db )
1476
+ err := lastError (db , int ( rv ) )
1471
1477
if db != nil {
1472
1478
C .sqlite3_close_v2 (db )
1473
1479
}
@@ -1476,13 +1482,18 @@ func (d *SQLiteDriver) Open(dsn string) (driver.Conn, error) {
1476
1482
if db == nil {
1477
1483
return nil , errors .New ("sqlite succeeded without returning a database" )
1478
1484
}
1485
+ rv = C .sqlite3_extended_result_codes (db , 1 )
1486
+ if rv != SQLITE_OK {
1487
+ C .sqlite3_close_v2 (db )
1488
+ return nil , lastError (db , int (rv ))
1489
+ }
1479
1490
1480
1491
exec := func (s string ) error {
1481
1492
cs := C .CString (s )
1482
1493
rv := C .sqlite3_exec (db , cs , nil , nil , nil )
1483
1494
C .free (unsafe .Pointer (cs ))
1484
1495
if rv != C .SQLITE_OK {
1485
- return lastError (db )
1496
+ return lastError (db , int ( rv ) )
1486
1497
}
1487
1498
return nil
1488
1499
}
@@ -1782,26 +1793,20 @@ func (d *SQLiteDriver) Open(dsn string) (driver.Conn, error) {
1782
1793
}
1783
1794
1784
1795
// Close the connection.
1785
- func (c * SQLiteConn ) Close () error {
1796
+ func (c * SQLiteConn ) Close () (err error ) {
1797
+ c .mu .Lock ()
1798
+ defer c .mu .Unlock ()
1799
+ if c .db == nil {
1800
+ return nil // Already closed
1801
+ }
1802
+ runtime .SetFinalizer (c , nil )
1786
1803
rv := C .sqlite3_close_v2 (c .db )
1787
1804
if rv != C .SQLITE_OK {
1788
- return c . lastError ()
1805
+ err = lastError (nil , int ( rv ) )
1789
1806
}
1790
1807
deleteHandles (c )
1791
- c .mu .Lock ()
1792
1808
c .db = nil
1793
- c .mu .Unlock ()
1794
- runtime .SetFinalizer (c , nil )
1795
- return nil
1796
- }
1797
-
1798
- func (c * SQLiteConn ) dbConnOpen () bool {
1799
- if c == nil {
1800
- return false
1801
- }
1802
- c .mu .Lock ()
1803
- defer c .mu .Unlock ()
1804
- return c .db != nil
1809
+ return err
1805
1810
}
1806
1811
1807
1812
// Prepare the query string. Return a new statement.
@@ -1816,7 +1821,7 @@ func (c *SQLiteConn) prepare(ctx context.Context, query string) (driver.Stmt, er
1816
1821
var tail * C.char
1817
1822
rv := C ._sqlite3_prepare_v2_internal (c .db , pquery , C .int (- 1 ), & s , & tail )
1818
1823
if rv != C .SQLITE_OK {
1819
- return nil , c .lastError ()
1824
+ return nil , c .lastError (int ( rv ) )
1820
1825
}
1821
1826
var t string
1822
1827
if tail != nil && * tail != '\000' {
@@ -1888,7 +1893,7 @@ func (c *SQLiteConn) SetFileControlInt(dbName string, op int, arg int) error {
1888
1893
cArg := C .int (arg )
1889
1894
rv := C .sqlite3_file_control (c .db , cDBName , C .int (op ), unsafe .Pointer (& cArg ))
1890
1895
if rv != C .SQLITE_OK {
1891
- return c .lastError ()
1896
+ return c .lastError (int ( rv ) )
1892
1897
}
1893
1898
return nil
1894
1899
}
@@ -1901,16 +1906,15 @@ func (s *SQLiteStmt) Close() error {
1901
1906
return nil
1902
1907
}
1903
1908
s .closed = true
1904
- if ! s .c .dbConnOpen () {
1905
- return errors .New ("sqlite statement with already closed database connection" )
1906
- }
1907
- rv := C .sqlite3_finalize (s .s )
1909
+ conn := s .c
1910
+ stmt := s .s
1911
+ s .c = nil
1908
1912
s .s = nil
1913
+ runtime .SetFinalizer (s , nil )
1914
+ rv := C .sqlite3_finalize (stmt )
1909
1915
if rv != C .SQLITE_OK {
1910
- return s . c . lastError ()
1916
+ return conn . lastError (int ( rv ) )
1911
1917
}
1912
- s .c = nil
1913
- runtime .SetFinalizer (s , nil )
1914
1918
return nil
1915
1919
}
1916
1920
@@ -1924,7 +1928,7 @@ var placeHolder = []byte{0}
1924
1928
func (s * SQLiteStmt ) bind (args []driver.NamedValue ) error {
1925
1929
rv := C .sqlite3_reset (s .s )
1926
1930
if rv != C .SQLITE_ROW && rv != C .SQLITE_OK && rv != C .SQLITE_DONE {
1927
- return s .c .lastError ()
1931
+ return s .c .lastError (int ( rv ) )
1928
1932
}
1929
1933
1930
1934
bindIndices := make ([][3 ]int , len (args ))
@@ -1982,7 +1986,7 @@ func (s *SQLiteStmt) bind(args []driver.NamedValue) error {
1982
1986
rv = C ._sqlite3_bind_text (s .s , n , (* C .char )(unsafe .Pointer (& b [0 ])), C .int (len (b )))
1983
1987
}
1984
1988
if rv != C .SQLITE_OK {
1985
- return s .c .lastError ()
1989
+ return s .c .lastError (int ( rv ) )
1986
1990
}
1987
1991
}
1988
1992
}
@@ -2092,7 +2096,7 @@ func (s *SQLiteStmt) execSync(args []driver.NamedValue) (driver.Result, error) {
2092
2096
var rowid , changes C.longlong
2093
2097
rv := C ._sqlite3_step_row_internal (s .s , & rowid , & changes )
2094
2098
if rv != C .SQLITE_ROW && rv != C .SQLITE_OK && rv != C .SQLITE_DONE {
2095
- err := s .c .lastError ()
2099
+ err := s .c .lastError (int ( rv ) )
2096
2100
C .sqlite3_reset (s .s )
2097
2101
C .sqlite3_clear_bindings (s .s )
2098
2102
return nil , err
@@ -2128,8 +2132,8 @@ func (rc *SQLiteRows) Close() error {
2128
2132
}
2129
2133
rv := C .sqlite3_reset (s .s )
2130
2134
if rv != C .SQLITE_OK {
2131
- s .mu .Unlock ()
2132
- return s .c .lastError ()
2135
+ rc . s .mu .Unlock ()
2136
+ return rc . s .c .lastError (int ( rv ) )
2133
2137
}
2134
2138
s .mu .Unlock ()
2135
2139
return nil
@@ -2206,7 +2210,7 @@ func (rc *SQLiteRows) nextSyncLocked(dest []driver.Value) error {
2206
2210
if rv != C .SQLITE_ROW {
2207
2211
rv = C .sqlite3_reset (rc .s .s )
2208
2212
if rv != C .SQLITE_OK {
2209
- return rc .s .c .lastError ()
2213
+ return rc .s .c .lastError (int ( rv ) )
2210
2214
}
2211
2215
return nil
2212
2216
}
0 commit comments