1// Copyright (C) 2014 Yasuhiro Matsumoto <mattn.jp@gmail.com>. 2// 3// Use of this source code is governed by an MIT-style 4// license that can be found in the LICENSE file. 5 6package sqlite3 7 8/* 9#cgo CFLAGS: -std=gnu99 10#cgo CFLAGS: -DSQLITE_ENABLE_RTREE -DSQLITE_THREADSAFE 11#cgo CFLAGS: -DSQLITE_ENABLE_FTS3 -DSQLITE_ENABLE_FTS3_PARENTHESIS -DSQLITE_ENABLE_FTS4_UNICODE61 12#cgo CFLAGS: -DSQLITE_TRACE_SIZE_LIMIT=15 13#ifndef USE_LIBSQLITE3 14#include <sqlite3-binding.h> 15#else 16#include <sqlite3.h> 17#endif 18#include <stdlib.h> 19#include <string.h> 20 21#ifdef __CYGWIN__ 22# include <errno.h> 23#endif 24 25#ifndef SQLITE_OPEN_READWRITE 26# define SQLITE_OPEN_READWRITE 0 27#endif 28 29#ifndef SQLITE_OPEN_FULLMUTEX 30# define SQLITE_OPEN_FULLMUTEX 0 31#endif 32 33#ifndef SQLITE_DETERMINISTIC 34# define SQLITE_DETERMINISTIC 0 35#endif 36 37static int 38_sqlite3_open_v2(const char *filename, sqlite3 **ppDb, int flags, const char *zVfs) { 39#ifdef SQLITE_OPEN_URI 40 return sqlite3_open_v2(filename, ppDb, flags | SQLITE_OPEN_URI, zVfs); 41#else 42 return sqlite3_open_v2(filename, ppDb, flags, zVfs); 43#endif 44} 45 46static int 47_sqlite3_bind_text(sqlite3_stmt *stmt, int n, char *p, int np) { 48 return sqlite3_bind_text(stmt, n, p, np, SQLITE_TRANSIENT); 49} 50 51static int 52_sqlite3_bind_blob(sqlite3_stmt *stmt, int n, void *p, int np) { 53 return sqlite3_bind_blob(stmt, n, p, np, SQLITE_TRANSIENT); 54} 55 56#include <stdio.h> 57#include <stdint.h> 58 59static int 60_sqlite3_exec(sqlite3* db, const char* pcmd, long long* rowid, long long* changes) 61{ 62 int rv = sqlite3_exec(db, pcmd, 0, 0, 0); 63 *rowid = (long long) sqlite3_last_insert_rowid(db); 64 *changes = (long long) sqlite3_changes(db); 65 return rv; 66} 67 68static int 69_sqlite3_step(sqlite3_stmt* stmt, long long* rowid, long long* changes) 70{ 71 int rv = sqlite3_step(stmt); 72 sqlite3* db = sqlite3_db_handle(stmt); 73 *rowid = (long long) sqlite3_last_insert_rowid(db); 74 *changes = (long long) sqlite3_changes(db); 75 return rv; 76} 77 78void _sqlite3_result_text(sqlite3_context* ctx, const char* s) { 79 sqlite3_result_text(ctx, s, -1, &free); 80} 81 82void _sqlite3_result_blob(sqlite3_context* ctx, const void* b, int l) { 83 sqlite3_result_blob(ctx, b, l, SQLITE_TRANSIENT); 84} 85 86 87int _sqlite3_create_function( 88 sqlite3 *db, 89 const char *zFunctionName, 90 int nArg, 91 int eTextRep, 92 uintptr_t pApp, 93 void (*xFunc)(sqlite3_context*,int,sqlite3_value**), 94 void (*xStep)(sqlite3_context*,int,sqlite3_value**), 95 void (*xFinal)(sqlite3_context*) 96) { 97 return sqlite3_create_function(db, zFunctionName, nArg, eTextRep, (void*) pApp, xFunc, xStep, xFinal); 98} 99 100void callbackTrampoline(sqlite3_context*, int, sqlite3_value**); 101*/ 102import "C" 103import ( 104 "database/sql" 105 "database/sql/driver" 106 "errors" 107 "fmt" 108 "io" 109 "net/url" 110 "reflect" 111 "runtime" 112 "strconv" 113 "strings" 114 "time" 115 "unsafe" 116) 117 118// Timestamp formats understood by both this module and SQLite. 119// The first format in the slice will be used when saving time values 120// into the database. When parsing a string from a timestamp or 121// datetime column, the formats are tried in order. 122var SQLiteTimestampFormats = []string{ 123 // By default, store timestamps with whatever timezone they come with. 124 // When parsed, they will be returned with the same timezone. 125 "2006-01-02 15:04:05.999999999-07:00", 126 "2006-01-02T15:04:05.999999999-07:00", 127 "2006-01-02 15:04:05.999999999", 128 "2006-01-02T15:04:05.999999999", 129 "2006-01-02 15:04:05", 130 "2006-01-02T15:04:05", 131 "2006-01-02 15:04", 132 "2006-01-02T15:04", 133 "2006-01-02", 134} 135 136func init() { 137 sql.Register("sqlite3", &SQLiteDriver{}) 138} 139 140// Version returns SQLite library version information. 141func Version() (libVersion string, libVersionNumber int, sourceId string) { 142 libVersion = C.GoString(C.sqlite3_libversion()) 143 libVersionNumber = int(C.sqlite3_libversion_number()) 144 sourceId = C.GoString(C.sqlite3_sourceid()) 145 return libVersion, libVersionNumber, sourceId 146} 147 148// Driver struct. 149type SQLiteDriver struct { 150 Extensions []string 151 ConnectHook func(*SQLiteConn) error 152} 153 154// Conn struct. 155type SQLiteConn struct { 156 db *C.sqlite3 157 loc *time.Location 158 txlock string 159 funcs []*functionInfo 160 aggregators []*aggInfo 161} 162 163// Tx struct. 164type SQLiteTx struct { 165 c *SQLiteConn 166} 167 168// Stmt struct. 169type SQLiteStmt struct { 170 c *SQLiteConn 171 s *C.sqlite3_stmt 172 nv int 173 nn []string 174 t string 175 closed bool 176 cls bool 177} 178 179// Result struct. 180type SQLiteResult struct { 181 id int64 182 changes int64 183} 184 185// Rows struct. 186type SQLiteRows struct { 187 s *SQLiteStmt 188 nc int 189 cols []string 190 decltype []string 191 cls bool 192} 193 194type functionInfo struct { 195 f reflect.Value 196 argConverters []callbackArgConverter 197 variadicConverter callbackArgConverter 198 retConverter callbackRetConverter 199} 200 201func (fi *functionInfo) Call(ctx *C.sqlite3_context, argv []*C.sqlite3_value) { 202 args, err := callbackConvertArgs(argv, fi.argConverters, fi.variadicConverter) 203 if err != nil { 204 callbackError(ctx, err) 205 return 206 } 207 208 ret := fi.f.Call(args) 209 210 if len(ret) == 2 && ret[1].Interface() != nil { 211 callbackError(ctx, ret[1].Interface().(error)) 212 return 213 } 214 215 err = fi.retConverter(ctx, ret[0]) 216 if err != nil { 217 callbackError(ctx, err) 218 return 219 } 220} 221 222type aggInfo struct { 223 constructor reflect.Value 224 225 // Active aggregator objects for aggregations in flight. The 226 // aggregators are indexed by a counter stored in the aggregation 227 // user data space provided by sqlite. 228 active map[int64]reflect.Value 229 next int64 230 231 stepArgConverters []callbackArgConverter 232 stepVariadicConverter callbackArgConverter 233 234 doneRetConverter callbackRetConverter 235} 236 237func (ai *aggInfo) agg(ctx *C.sqlite3_context) (int64, reflect.Value, error) { 238 aggIdx := (*int64)(C.sqlite3_aggregate_context(ctx, C.int(8))) 239 if *aggIdx == 0 { 240 *aggIdx = ai.next 241 ret := ai.constructor.Call(nil) 242 if len(ret) == 2 && ret[1].Interface() != nil { 243 return 0, reflect.Value{}, ret[1].Interface().(error) 244 } 245 if ret[0].IsNil() { 246 return 0, reflect.Value{}, errors.New("aggregator constructor returned nil state") 247 } 248 ai.next++ 249 ai.active[*aggIdx] = ret[0] 250 } 251 return *aggIdx, ai.active[*aggIdx], nil 252} 253 254func (ai *aggInfo) Step(ctx *C.sqlite3_context, argv []*C.sqlite3_value) { 255 _, agg, err := ai.agg(ctx) 256 if err != nil { 257 callbackError(ctx, err) 258 return 259 } 260 261 args, err := callbackConvertArgs(argv, ai.stepArgConverters, ai.stepVariadicConverter) 262 if err != nil { 263 callbackError(ctx, err) 264 return 265 } 266 267 ret := agg.MethodByName("Step").Call(args) 268 if len(ret) == 1 && ret[0].Interface() != nil { 269 callbackError(ctx, ret[0].Interface().(error)) 270 return 271 } 272} 273 274func (ai *aggInfo) Done(ctx *C.sqlite3_context) { 275 idx, agg, err := ai.agg(ctx) 276 if err != nil { 277 callbackError(ctx, err) 278 return 279 } 280 defer func() { delete(ai.active, idx) }() 281 282 ret := agg.MethodByName("Done").Call(nil) 283 if len(ret) == 2 && ret[1].Interface() != nil { 284 callbackError(ctx, ret[1].Interface().(error)) 285 return 286 } 287 288 err = ai.doneRetConverter(ctx, ret[0]) 289 if err != nil { 290 callbackError(ctx, err) 291 return 292 } 293} 294 295// Commit transaction. 296func (tx *SQLiteTx) Commit() error { 297 _, err := tx.c.exec("COMMIT") 298 if err != nil && err.(Error).Code == C.SQLITE_BUSY { 299 // sqlite3 will leave the transaction open in this scenario. 300 // However, database/sql considers the transaction complete once we 301 // return from Commit() - we must clean up to honour its semantics. 302 tx.c.exec("ROLLBACK") 303 } 304 return err 305} 306 307// Rollback transaction. 308func (tx *SQLiteTx) Rollback() error { 309 _, err := tx.c.exec("ROLLBACK") 310 return err 311} 312 313// RegisterFunc makes a Go function available as a SQLite function. 314// 315// The Go function can have arguments of the following types: any 316// numeric type except complex, bool, []byte, string and 317// interface{}. interface{} arguments are given the direct translation 318// of the SQLite data type: int64 for INTEGER, float64 for FLOAT, 319// []byte for BLOB, string for TEXT. 320// 321// The function can additionally be variadic, as long as the type of 322// the variadic argument is one of the above. 323// 324// If pure is true. SQLite will assume that the function's return 325// value depends only on its inputs, and make more aggressive 326// optimizations in its queries. 327// 328// See _example/go_custom_funcs for a detailed example. 329func (c *SQLiteConn) RegisterFunc(name string, impl interface{}, pure bool) error { 330 var fi functionInfo 331 fi.f = reflect.ValueOf(impl) 332 t := fi.f.Type() 333 if t.Kind() != reflect.Func { 334 return errors.New("Non-function passed to RegisterFunc") 335 } 336 if t.NumOut() != 1 && t.NumOut() != 2 { 337 return errors.New("SQLite functions must return 1 or 2 values") 338 } 339 if t.NumOut() == 2 && !t.Out(1).Implements(reflect.TypeOf((*error)(nil)).Elem()) { 340 return errors.New("Second return value of SQLite function must be error") 341 } 342 343 numArgs := t.NumIn() 344 if t.IsVariadic() { 345 numArgs-- 346 } 347 348 for i := 0; i < numArgs; i++ { 349 conv, err := callbackArg(t.In(i)) 350 if err != nil { 351 return err 352 } 353 fi.argConverters = append(fi.argConverters, conv) 354 } 355 356 if t.IsVariadic() { 357 conv, err := callbackArg(t.In(numArgs).Elem()) 358 if err != nil { 359 return err 360 } 361 fi.variadicConverter = conv 362 // Pass -1 to sqlite so that it allows any number of 363 // arguments. The call helper verifies that the minimum number 364 // of arguments is present for variadic functions. 365 numArgs = -1 366 } 367 368 conv, err := callbackRet(t.Out(0)) 369 if err != nil { 370 return err 371 } 372 fi.retConverter = conv 373 374 // fi must outlast the database connection, or we'll have dangling pointers. 375 c.funcs = append(c.funcs, &fi) 376 377 cname := C.CString(name) 378 defer C.free(unsafe.Pointer(cname)) 379 opts := C.SQLITE_UTF8 380 if pure { 381 opts |= C.SQLITE_DETERMINISTIC 382 } 383 rv := C._sqlite3_create_function(c.db, cname, C.int(numArgs), C.int(opts), C.uintptr_t(newHandle(c, &fi)), (*[0]byte)(unsafe.Pointer(C.callbackTrampoline)), nil, nil) 384 if rv != C.SQLITE_OK { 385 return c.lastError() 386 } 387 return nil 388} 389 390// AutoCommit return which currently auto commit or not. 391func (c *SQLiteConn) AutoCommit() bool { 392 return int(C.sqlite3_get_autocommit(c.db)) != 0 393} 394 395func (c *SQLiteConn) lastError() Error { 396 return Error{ 397 Code: ErrNo(C.sqlite3_errcode(c.db)), 398 ExtendedCode: ErrNoExtended(C.sqlite3_extended_errcode(c.db)), 399 err: C.GoString(C.sqlite3_errmsg(c.db)), 400 } 401} 402 403// Implements Execer 404func (c *SQLiteConn) Exec(query string, args []driver.Value) (driver.Result, error) { 405 if len(args) == 0 { 406 return c.exec(query) 407 } 408 409 for { 410 s, err := c.Prepare(query) 411 if err != nil { 412 return nil, err 413 } 414 var res driver.Result 415 if s.(*SQLiteStmt).s != nil { 416 na := s.NumInput() 417 if len(args) < na { 418 return nil, fmt.Errorf("Not enough args to execute query. Expected %d, got %d.", na, len(args)) 419 } 420 res, err = s.Exec(args[:na]) 421 if err != nil && err != driver.ErrSkip { 422 s.Close() 423 return nil, err 424 } 425 args = args[na:] 426 } 427 tail := s.(*SQLiteStmt).t 428 s.Close() 429 if tail == "" { 430 return res, nil 431 } 432 query = tail 433 } 434} 435 436// Implements Queryer 437func (c *SQLiteConn) Query(query string, args []driver.Value) (driver.Rows, error) { 438 for { 439 s, err := c.Prepare(query) 440 if err != nil { 441 return nil, err 442 } 443 s.(*SQLiteStmt).cls = true 444 na := s.NumInput() 445 if len(args) < na { 446 return nil, fmt.Errorf("Not enough args to execute query. Expected %d, got %d.", na, len(args)) 447 } 448 rows, err := s.Query(args[:na]) 449 if err != nil && err != driver.ErrSkip { 450 s.Close() 451 return nil, err 452 } 453 args = args[na:] 454 tail := s.(*SQLiteStmt).t 455 if tail == "" { 456 return rows, nil 457 } 458 rows.Close() 459 s.Close() 460 query = tail 461 } 462} 463 464func (c *SQLiteConn) exec(cmd string) (driver.Result, error) { 465 pcmd := C.CString(cmd) 466 defer C.free(unsafe.Pointer(pcmd)) 467 468 var rowid, changes C.longlong 469 rv := C._sqlite3_exec(c.db, pcmd, &rowid, &changes) 470 if rv != C.SQLITE_OK { 471 return nil, c.lastError() 472 } 473 return &SQLiteResult{int64(rowid), int64(changes)}, nil 474} 475 476// Begin transaction. 477func (c *SQLiteConn) Begin() (driver.Tx, error) { 478 if _, err := c.exec(c.txlock); err != nil { 479 return nil, err 480 } 481 return &SQLiteTx{c}, nil 482} 483 484func errorString(err Error) string { 485 return C.GoString(C.sqlite3_errstr(C.int(err.Code))) 486} 487 488// Open database and return a new connection. 489// You can specify a DSN string using a URI as the filename. 490// test.db 491// file:test.db?cache=shared&mode=memory 492// :memory: 493// file::memory: 494// go-sqlite3 adds the following query parameters to those used by SQLite: 495// _loc=XXX 496// Specify location of time format. It's possible to specify "auto". 497// _busy_timeout=XXX 498// Specify value for sqlite3_busy_timeout. 499// _txlock=XXX 500// Specify locking behavior for transactions. XXX can be "immediate", 501// "deferred", "exclusive". 502func (d *SQLiteDriver) Open(dsn string) (driver.Conn, error) { 503 if C.sqlite3_threadsafe() == 0 { 504 return nil, errors.New("sqlite library was not compiled for thread-safe operation") 505 } 506 507 var loc *time.Location 508 txlock := "BEGIN" 509 busy_timeout := 5000 510 pos := strings.IndexRune(dsn, '?') 511 if pos >= 1 { 512 params, err := url.ParseQuery(dsn[pos+1:]) 513 if err != nil { 514 return nil, err 515 } 516 517 // _loc 518 if val := params.Get("_loc"); val != "" { 519 if val == "auto" { 520 loc = time.Local 521 } else { 522 loc, err = time.LoadLocation(val) 523 if err != nil { 524 return nil, fmt.Errorf("Invalid _loc: %v: %v", val, err) 525 } 526 } 527 } 528 529 // _busy_timeout 530 if val := params.Get("_busy_timeout"); val != "" { 531 iv, err := strconv.ParseInt(val, 10, 64) 532 if err != nil { 533 return nil, fmt.Errorf("Invalid _busy_timeout: %v: %v", val, err) 534 } 535 busy_timeout = int(iv) 536 } 537 538 // _txlock 539 if val := params.Get("_txlock"); val != "" { 540 switch val { 541 case "immediate": 542 txlock = "BEGIN IMMEDIATE" 543 case "exclusive": 544 txlock = "BEGIN EXCLUSIVE" 545 case "deferred": 546 txlock = "BEGIN" 547 default: 548 return nil, fmt.Errorf("Invalid _txlock: %v", val) 549 } 550 } 551 552 if !strings.HasPrefix(dsn, "file:") { 553 dsn = dsn[:pos] 554 } 555 } 556 557 var db *C.sqlite3 558 name := C.CString(dsn) 559 defer C.free(unsafe.Pointer(name)) 560 rv := C._sqlite3_open_v2(name, &db, 561 C.SQLITE_OPEN_FULLMUTEX| 562 C.SQLITE_OPEN_READWRITE| 563 C.SQLITE_OPEN_CREATE, 564 nil) 565 if rv != 0 { 566 return nil, Error{Code: ErrNo(rv)} 567 } 568 if db == nil { 569 return nil, errors.New("sqlite succeeded without returning a database") 570 } 571 572 rv = C.sqlite3_busy_timeout(db, C.int(busy_timeout)) 573 if rv != C.SQLITE_OK { 574 return nil, Error{Code: ErrNo(rv)} 575 } 576 577 conn := &SQLiteConn{db: db, loc: loc, txlock: txlock} 578 579 if len(d.Extensions) > 0 { 580 if err := conn.loadExtensions(d.Extensions); err != nil { 581 return nil, err 582 } 583 } 584 585 if d.ConnectHook != nil { 586 if err := d.ConnectHook(conn); err != nil { 587 return nil, err 588 } 589 } 590 runtime.SetFinalizer(conn, (*SQLiteConn).Close) 591 return conn, nil 592} 593 594// Close the connection. 595func (c *SQLiteConn) Close() error { 596 deleteHandles(c) 597 rv := C.sqlite3_close_v2(c.db) 598 if rv != C.SQLITE_OK { 599 return c.lastError() 600 } 601 c.db = nil 602 runtime.SetFinalizer(c, nil) 603 return nil 604} 605 606// Prepare the query string. Return a new statement. 607func (c *SQLiteConn) Prepare(query string) (driver.Stmt, error) { 608 pquery := C.CString(query) 609 defer C.free(unsafe.Pointer(pquery)) 610 var s *C.sqlite3_stmt 611 var tail *C.char 612 rv := C.sqlite3_prepare_v2(c.db, pquery, -1, &s, &tail) 613 if rv != C.SQLITE_OK { 614 return nil, c.lastError() 615 } 616 var t string 617 if tail != nil && *tail != '\000' { 618 t = strings.TrimSpace(C.GoString(tail)) 619 } 620 nv := int(C.sqlite3_bind_parameter_count(s)) 621 var nn []string 622 for i := 0; i < nv; i++ { 623 pn := C.GoString(C.sqlite3_bind_parameter_name(s, C.int(i+1))) 624 if len(pn) > 1 && pn[0] == '$' && 48 <= pn[1] && pn[1] <= 57 { 625 nn = append(nn, C.GoString(C.sqlite3_bind_parameter_name(s, C.int(i+1)))) 626 } 627 } 628 ss := &SQLiteStmt{c: c, s: s, nv: nv, nn: nn, t: t} 629 runtime.SetFinalizer(ss, (*SQLiteStmt).Close) 630 return ss, nil 631} 632 633// Close the statement. 634func (s *SQLiteStmt) Close() error { 635 if s.closed { 636 return nil 637 } 638 s.closed = true 639 if s.c == nil || s.c.db == nil { 640 return errors.New("sqlite statement with already closed database connection") 641 } 642 rv := C.sqlite3_finalize(s.s) 643 if rv != C.SQLITE_OK { 644 return s.c.lastError() 645 } 646 runtime.SetFinalizer(s, nil) 647 return nil 648} 649 650// Return a number of parameters. 651func (s *SQLiteStmt) NumInput() int { 652 return s.nv 653} 654 655type bindArg struct { 656 n int 657 v driver.Value 658} 659 660func (s *SQLiteStmt) bind(args []driver.Value) error { 661 rv := C.sqlite3_reset(s.s) 662 if rv != C.SQLITE_ROW && rv != C.SQLITE_OK && rv != C.SQLITE_DONE { 663 return s.c.lastError() 664 } 665 666 var vargs []bindArg 667 narg := len(args) 668 vargs = make([]bindArg, narg) 669 if len(s.nn) > 0 { 670 for i, v := range s.nn { 671 if pi, err := strconv.Atoi(v[1:]); err == nil { 672 vargs[i] = bindArg{pi, args[i]} 673 } 674 } 675 } else { 676 for i, v := range args { 677 vargs[i] = bindArg{i + 1, v} 678 } 679 } 680 681 for _, varg := range vargs { 682 n := C.int(varg.n) 683 v := varg.v 684 switch v := v.(type) { 685 case nil: 686 rv = C.sqlite3_bind_null(s.s, n) 687 case string: 688 if len(v) == 0 { 689 b := []byte{0} 690 rv = C._sqlite3_bind_text(s.s, n, (*C.char)(unsafe.Pointer(&b[0])), C.int(0)) 691 } else { 692 b := []byte(v) 693 rv = C._sqlite3_bind_text(s.s, n, (*C.char)(unsafe.Pointer(&b[0])), C.int(len(b))) 694 } 695 case int64: 696 rv = C.sqlite3_bind_int64(s.s, n, C.sqlite3_int64(v)) 697 case bool: 698 if bool(v) { 699 rv = C.sqlite3_bind_int(s.s, n, 1) 700 } else { 701 rv = C.sqlite3_bind_int(s.s, n, 0) 702 } 703 case float64: 704 rv = C.sqlite3_bind_double(s.s, n, C.double(v)) 705 case []byte: 706 if len(v) == 0 { 707 rv = C._sqlite3_bind_blob(s.s, n, nil, 0) 708 } else { 709 rv = C._sqlite3_bind_blob(s.s, n, unsafe.Pointer(&v[0]), C.int(len(v))) 710 } 711 case time.Time: 712 b := []byte(v.Format(SQLiteTimestampFormats[0])) 713 rv = C._sqlite3_bind_text(s.s, n, (*C.char)(unsafe.Pointer(&b[0])), C.int(len(b))) 714 } 715 if rv != C.SQLITE_OK { 716 return s.c.lastError() 717 } 718 } 719 return nil 720} 721 722// Query the statement with arguments. Return records. 723func (s *SQLiteStmt) Query(args []driver.Value) (driver.Rows, error) { 724 if err := s.bind(args); err != nil { 725 return nil, err 726 } 727 return &SQLiteRows{s, int(C.sqlite3_column_count(s.s)), nil, nil, s.cls}, nil 728} 729 730// Return last inserted ID. 731func (r *SQLiteResult) LastInsertId() (int64, error) { 732 return r.id, nil 733} 734 735// Return how many rows affected. 736func (r *SQLiteResult) RowsAffected() (int64, error) { 737 return r.changes, nil 738} 739 740// Execute the statement with arguments. Return result object. 741func (s *SQLiteStmt) Exec(args []driver.Value) (driver.Result, error) { 742 if err := s.bind(args); err != nil { 743 C.sqlite3_reset(s.s) 744 C.sqlite3_clear_bindings(s.s) 745 return nil, err 746 } 747 var rowid, changes C.longlong 748 rv := C._sqlite3_step(s.s, &rowid, &changes) 749 if rv != C.SQLITE_ROW && rv != C.SQLITE_OK && rv != C.SQLITE_DONE { 750 err := s.c.lastError() 751 C.sqlite3_reset(s.s) 752 C.sqlite3_clear_bindings(s.s) 753 return nil, err 754 } 755 return &SQLiteResult{int64(rowid), int64(changes)}, nil 756} 757 758// Close the rows. 759func (rc *SQLiteRows) Close() error { 760 if rc.s.closed { 761 return nil 762 } 763 if rc.cls { 764 return rc.s.Close() 765 } 766 rv := C.sqlite3_reset(rc.s.s) 767 if rv != C.SQLITE_OK { 768 return rc.s.c.lastError() 769 } 770 return nil 771} 772 773// Return column names. 774func (rc *SQLiteRows) Columns() []string { 775 if rc.nc != len(rc.cols) { 776 rc.cols = make([]string, rc.nc) 777 for i := 0; i < rc.nc; i++ { 778 rc.cols[i] = C.GoString(C.sqlite3_column_name(rc.s.s, C.int(i))) 779 } 780 } 781 return rc.cols 782} 783 784// Return column types. 785func (rc *SQLiteRows) DeclTypes() []string { 786 if rc.decltype == nil { 787 rc.decltype = make([]string, rc.nc) 788 for i := 0; i < rc.nc; i++ { 789 rc.decltype[i] = strings.ToLower(C.GoString(C.sqlite3_column_decltype(rc.s.s, C.int(i)))) 790 } 791 } 792 return rc.decltype 793} 794 795// Move cursor to next. 796func (rc *SQLiteRows) Next(dest []driver.Value) error { 797 rv := C.sqlite3_step(rc.s.s) 798 if rv == C.SQLITE_DONE { 799 return io.EOF 800 } 801 if rv != C.SQLITE_ROW { 802 rv = C.sqlite3_reset(rc.s.s) 803 if rv != C.SQLITE_OK { 804 return rc.s.c.lastError() 805 } 806 return nil 807 } 808 809 rc.DeclTypes() 810 811 for i := range dest { 812 switch C.sqlite3_column_type(rc.s.s, C.int(i)) { 813 case C.SQLITE_INTEGER: 814 val := int64(C.sqlite3_column_int64(rc.s.s, C.int(i))) 815 switch rc.decltype[i] { 816 case "timestamp", "datetime", "date": 817 var t time.Time 818 // Assume a millisecond unix timestamp if it's 13 digits -- too 819 // large to be a reasonable timestamp in seconds. 820 if val > 1e12 || val < -1e12 { 821 val *= int64(time.Millisecond) // convert ms to nsec 822 } else { 823 val *= int64(time.Second) // convert sec to nsec 824 } 825 t = time.Unix(0, val).UTC() 826 if rc.s.c.loc != nil { 827 t = t.In(rc.s.c.loc) 828 } 829 dest[i] = t 830 case "boolean": 831 dest[i] = val > 0 832 default: 833 dest[i] = val 834 } 835 case C.SQLITE_FLOAT: 836 dest[i] = float64(C.sqlite3_column_double(rc.s.s, C.int(i))) 837 case C.SQLITE_BLOB: 838 p := C.sqlite3_column_blob(rc.s.s, C.int(i)) 839 if p == nil { 840 dest[i] = nil 841 continue 842 } 843 n := int(C.sqlite3_column_bytes(rc.s.s, C.int(i))) 844 switch dest[i].(type) { 845 case sql.RawBytes: 846 dest[i] = (*[1 << 30]byte)(unsafe.Pointer(p))[0:n] 847 default: 848 slice := make([]byte, n) 849 copy(slice[:], (*[1 << 30]byte)(unsafe.Pointer(p))[0:n]) 850 dest[i] = slice 851 } 852 case C.SQLITE_NULL: 853 dest[i] = nil 854 case C.SQLITE_TEXT: 855 var err error 856 var timeVal time.Time 857 858 n := int(C.sqlite3_column_bytes(rc.s.s, C.int(i))) 859 s := C.GoStringN((*C.char)(unsafe.Pointer(C.sqlite3_column_text(rc.s.s, C.int(i)))), C.int(n)) 860 861 switch rc.decltype[i] { 862 case "timestamp", "datetime", "date": 863 var t time.Time 864 s = strings.TrimSuffix(s, "Z") 865 for _, format := range SQLiteTimestampFormats { 866 if timeVal, err = time.ParseInLocation(format, s, time.UTC); err == nil { 867 t = timeVal 868 break 869 } 870 } 871 if err != nil { 872 // The column is a time value, so return the zero time on parse failure. 873 t = time.Time{} 874 } 875 if rc.s.c.loc != nil { 876 t = t.In(rc.s.c.loc) 877 } 878 dest[i] = t 879 default: 880 dest[i] = []byte(s) 881 } 882 883 } 884 } 885 return nil 886} 887