This commit is contained in:
Yasuhiro Matsumoto 2017-08-30 13:29:47 +09:00
parent ee720241fc
commit 911f1c4fa6
1 changed files with 24 additions and 2 deletions

View File

@ -182,6 +182,7 @@ type SQLiteTx struct {
// SQLiteStmt implement sql.Stmt. // SQLiteStmt implement sql.Stmt.
type SQLiteStmt struct { type SQLiteStmt struct {
mu sync.Mutex
c *SQLiteConn c *SQLiteConn
s *C.sqlite3_stmt s *C.sqlite3_stmt
t string t string
@ -803,6 +804,8 @@ func (c *SQLiteConn) prepare(ctx context.Context, query string) (driver.Stmt, er
// Close the statement. // Close the statement.
func (s *SQLiteStmt) Close() error { func (s *SQLiteStmt) Close() error {
s.mu.Lock()
defer s.mu.Unlock()
if s.closed { if s.closed {
return nil return nil
} }
@ -980,7 +983,9 @@ func (s *SQLiteStmt) exec(ctx context.Context, args []namedValue) (driver.Result
// Close the rows. // Close the rows.
func (rc *SQLiteRows) Close() error { func (rc *SQLiteRows) Close() error {
rc.s.mu.Lock()
if rc.s.closed || rc.closed { if rc.s.closed || rc.closed {
rc.s.mu.Unlock()
return nil return nil
} }
rc.closed = true rc.closed = true
@ -988,18 +993,23 @@ func (rc *SQLiteRows) Close() error {
close(rc.done) close(rc.done)
} }
if rc.cls { if rc.cls {
rc.s.mu.Unlock()
return rc.s.Close() return rc.s.Close()
} }
rv := C.sqlite3_reset(rc.s.s) rv := C.sqlite3_reset(rc.s.s)
if rv != C.SQLITE_OK { if rv != C.SQLITE_OK {
rc.s.mu.Unlock()
return rc.s.c.lastError() return rc.s.c.lastError()
} }
rc.s.mu.Unlock()
return nil return nil
} }
// Columns return column names. // Columns return column names.
func (rc *SQLiteRows) Columns() []string { func (rc *SQLiteRows) Columns() []string {
if rc.nc != len(rc.cols) { rc.s.mu.Lock()
defer rc.s.mu.Unlock()
if rc.s.s != nil && rc.nc != len(rc.cols) {
rc.cols = make([]string, rc.nc) rc.cols = make([]string, rc.nc)
for i := 0; i < rc.nc; i++ { for i := 0; i < rc.nc; i++ {
rc.cols[i] = C.GoString(C.sqlite3_column_name(rc.s.s, C.int(i))) rc.cols[i] = C.GoString(C.sqlite3_column_name(rc.s.s, C.int(i)))
@ -1010,7 +1020,9 @@ func (rc *SQLiteRows) Columns() []string {
// DeclTypes return column types. // DeclTypes return column types.
func (rc *SQLiteRows) DeclTypes() []string { func (rc *SQLiteRows) DeclTypes() []string {
if rc.decltype == nil { rc.s.mu.Lock()
defer rc.s.mu.Unlock()
if rc.s.s != nil && rc.decltype == nil {
rc.decltype = make([]string, rc.nc) rc.decltype = make([]string, rc.nc)
for i := 0; i < rc.nc; i++ { for i := 0; i < rc.nc; i++ {
rc.decltype[i] = strings.ToLower(C.GoString(C.sqlite3_column_decltype(rc.s.s, C.int(i)))) rc.decltype[i] = strings.ToLower(C.GoString(C.sqlite3_column_decltype(rc.s.s, C.int(i))))
@ -1021,20 +1033,30 @@ func (rc *SQLiteRows) DeclTypes() []string {
// Next move cursor to next. // Next move cursor to next.
func (rc *SQLiteRows) Next(dest []driver.Value) error { func (rc *SQLiteRows) Next(dest []driver.Value) error {
if rc.s.closed {
return io.EOF
}
rc.s.mu.Lock()
rv := C.sqlite3_step(rc.s.s) rv := C.sqlite3_step(rc.s.s)
if rv == C.SQLITE_DONE { if rv == C.SQLITE_DONE {
rc.s.mu.Unlock()
return io.EOF return io.EOF
} }
if rv != C.SQLITE_ROW { if rv != C.SQLITE_ROW {
defer rc.s.mu.Unlock()
rv = C.sqlite3_reset(rc.s.s) rv = C.sqlite3_reset(rc.s.s)
if rv != C.SQLITE_OK { if rv != C.SQLITE_OK {
return rc.s.c.lastError() return rc.s.c.lastError()
} }
rc.s.mu.Unlock()
return nil return nil
} }
rc.DeclTypes() rc.DeclTypes()
rc.s.mu.Lock()
defer rc.s.mu.Unlock()
for i := range dest { for i := range dest {
switch C.sqlite3_column_type(rc.s.s, C.int(i)) { switch C.sqlite3_column_type(rc.s.s, C.int(i)) {
case C.SQLITE_INTEGER: case C.SQLITE_INTEGER: