vendor: update sqlite to fix "database is locked" errors (#2116)
closes #2040
upstream commit: acfa601240
			
			
This commit is contained in:
		
							parent
							
								
									a52cd59727
								
							
						
					
					
						commit
						2ef33b5338
					
				
					 18 changed files with 10627 additions and 5910 deletions
				
			
		
							
								
								
									
										30
									
								
								vendor/github.com/mattn/go-sqlite3/README.md
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										30
									
								
								vendor/github.com/mattn/go-sqlite3/README.md
									
									
									
										generated
									
									
										vendored
									
									
								
							|  | @ -1,9 +1,10 @@ | ||||||
| go-sqlite3 | go-sqlite3 | ||||||
| ========== | ========== | ||||||
| 
 | 
 | ||||||
|  | [](http://godoc.org/github.com/mattn/go-sqlite3) | ||||||
| [](https://travis-ci.org/mattn/go-sqlite3) | [](https://travis-ci.org/mattn/go-sqlite3) | ||||||
| [](https://coveralls.io/r/mattn/go-sqlite3?branch=master) | [](https://coveralls.io/r/mattn/go-sqlite3?branch=master) | ||||||
| [](http://godoc.org/github.com/mattn/go-sqlite3) | [](https://goreportcard.com/report/github.com/mattn/go-sqlite3) | ||||||
| 
 | 
 | ||||||
| Description | Description | ||||||
| ----------- | ----------- | ||||||
|  | @ -16,11 +17,11 @@ Installation | ||||||
| This package can be installed with the go get command: | This package can be installed with the go get command: | ||||||
| 
 | 
 | ||||||
|     go get github.com/mattn/go-sqlite3 |     go get github.com/mattn/go-sqlite3 | ||||||
|      | 
 | ||||||
| _go-sqlite3_ is *cgo* package. | _go-sqlite3_ is *cgo* package. | ||||||
| If you want to build your app using go-sqlite3, you need gcc. | If you want to build your app using go-sqlite3, you need gcc. | ||||||
| However, if you install _go-sqlite3_ with `go install github.com/mattn/go-sqlite3`, you don't need gcc to build your app anymore. | However, if you install _go-sqlite3_ with `go install github.com/mattn/go-sqlite3`, you don't need gcc to build your app anymore. | ||||||
|      | 
 | ||||||
| Documentation | Documentation | ||||||
| ------------- | ------------- | ||||||
| 
 | 
 | ||||||
|  | @ -45,25 +46,40 @@ FAQ | ||||||
| 
 | 
 | ||||||
|    Use `go build --tags "icu"` |    Use `go build --tags "icu"` | ||||||
| 
 | 
 | ||||||
|  |    Available extensions: `json1`, `fts5`, `icu` | ||||||
|  | 
 | ||||||
| * Can't build go-sqlite3 on windows 64bit. | * Can't build go-sqlite3 on windows 64bit. | ||||||
| 
 | 
 | ||||||
|     > Probably, you are using go 1.0, go1.0 has a problem when it comes to compiling/linking on windows 64bit.  |     > Probably, you are using go 1.0, go1.0 has a problem when it comes to compiling/linking on windows 64bit. | ||||||
|     > See: https://github.com/mattn/go-sqlite3/issues/27 |     > See: [#27](https://github.com/mattn/go-sqlite3/issues/27) | ||||||
| 
 | 
 | ||||||
| * Getting insert error while query is opened. | * Getting insert error while query is opened. | ||||||
| 
 | 
 | ||||||
|     > You can pass some arguments into the connection string, for example, a URI. |     > You can pass some arguments into the connection string, for example, a URI. | ||||||
|     > See: https://github.com/mattn/go-sqlite3/issues/39 |     > See: [#39](https://github.com/mattn/go-sqlite3/issues/39) | ||||||
| 
 | 
 | ||||||
| * Do you want to cross compile? mingw on Linux or Mac? | * Do you want to cross compile? mingw on Linux or Mac? | ||||||
| 
 | 
 | ||||||
|     > See: https://github.com/mattn/go-sqlite3/issues/106 |     > See: [#106](https://github.com/mattn/go-sqlite3/issues/106) | ||||||
|     > See also: http://www.limitlessfx.com/cross-compile-golang-app-for-windows-from-linux.html |     > See also: http://www.limitlessfx.com/cross-compile-golang-app-for-windows-from-linux.html | ||||||
| 
 | 
 | ||||||
| * Want to get time.Time with current locale | * Want to get time.Time with current locale | ||||||
| 
 | 
 | ||||||
|     Use `loc=auto` in SQLite3 filename schema like `file:foo.db?loc=auto`. |     Use `loc=auto` in SQLite3 filename schema like `file:foo.db?loc=auto`. | ||||||
| 
 | 
 | ||||||
|  | * Can I use this in multiple routines concurrently? | ||||||
|  | 
 | ||||||
|  |     Yes for readonly. But, No for writable. See [#50](https://github.com/mattn/go-sqlite3/issues/50), [#51](https://github.com/mattn/go-sqlite3/issues/51), [#209](https://github.com/mattn/go-sqlite3/issues/209). | ||||||
|  | 
 | ||||||
|  | * Why is it racy if I use a `sql.Open("sqlite3", ":memory:")` database? | ||||||
|  | 
 | ||||||
|  |     Each connection to :memory: opens a brand new in-memory sql database, so if | ||||||
|  |     the stdlib's sql engine happens to open another connection and you've only | ||||||
|  |     specified ":memory:", that connection will see a brand new database. A | ||||||
|  |     workaround is to use "file::memory:?mode=memory&cache=shared". Every | ||||||
|  |     connection to this string will point to the same in-memory database. See | ||||||
|  |     [#204](https://github.com/mattn/go-sqlite3/issues/204) for more info. | ||||||
|  | 
 | ||||||
| License | License | ||||||
| ------- | ------- | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
							
								
								
									
										14
									
								
								vendor/github.com/mattn/go-sqlite3/backup.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										14
									
								
								vendor/github.com/mattn/go-sqlite3/backup.go
									
									
									
										generated
									
									
										vendored
									
									
								
							|  | @ -19,10 +19,12 @@ import ( | ||||||
| 	"unsafe" | 	"unsafe" | ||||||
| ) | ) | ||||||
| 
 | 
 | ||||||
|  | // SQLiteBackup implement interface of Backup.
 | ||||||
| type SQLiteBackup struct { | type SQLiteBackup struct { | ||||||
| 	b *C.sqlite3_backup | 	b *C.sqlite3_backup | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | // Backup make backup from src to dest.
 | ||||||
| func (c *SQLiteConn) Backup(dest string, conn *SQLiteConn, src string) (*SQLiteBackup, error) { | func (c *SQLiteConn) Backup(dest string, conn *SQLiteConn, src string) (*SQLiteBackup, error) { | ||||||
| 	destptr := C.CString(dest) | 	destptr := C.CString(dest) | ||||||
| 	defer C.free(unsafe.Pointer(destptr)) | 	defer C.free(unsafe.Pointer(destptr)) | ||||||
|  | @ -37,10 +39,10 @@ func (c *SQLiteConn) Backup(dest string, conn *SQLiteConn, src string) (*SQLiteB | ||||||
| 	return nil, c.lastError() | 	return nil, c.lastError() | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| // Backs up for one step. Calls the underlying `sqlite3_backup_step` function.
 | // Step to backs up for one step. Calls the underlying `sqlite3_backup_step`
 | ||||||
| // This function returns a boolean indicating if the backup is done and
 | // function.  This function returns a boolean indicating if the backup is done
 | ||||||
| // an error signalling any other error. Done is returned if the underlying C
 | // and an error signalling any other error. Done is returned if the underlying
 | ||||||
| // function returns SQLITE_DONE (Code 101)
 | // C function returns SQLITE_DONE (Code 101)
 | ||||||
| func (b *SQLiteBackup) Step(p int) (bool, error) { | func (b *SQLiteBackup) Step(p int) (bool, error) { | ||||||
| 	ret := C.sqlite3_backup_step(b.b, C.int(p)) | 	ret := C.sqlite3_backup_step(b.b, C.int(p)) | ||||||
| 	if ret == C.SQLITE_DONE { | 	if ret == C.SQLITE_DONE { | ||||||
|  | @ -51,18 +53,22 @@ func (b *SQLiteBackup) Step(p int) (bool, error) { | ||||||
| 	return false, nil | 	return false, nil | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | // Remaining return whether have the rest for backup.
 | ||||||
| func (b *SQLiteBackup) Remaining() int { | func (b *SQLiteBackup) Remaining() int { | ||||||
| 	return int(C.sqlite3_backup_remaining(b.b)) | 	return int(C.sqlite3_backup_remaining(b.b)) | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | // PageCount return count of pages.
 | ||||||
| func (b *SQLiteBackup) PageCount() int { | func (b *SQLiteBackup) PageCount() int { | ||||||
| 	return int(C.sqlite3_backup_pagecount(b.b)) | 	return int(C.sqlite3_backup_pagecount(b.b)) | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | // Finish close backup.
 | ||||||
| func (b *SQLiteBackup) Finish() error { | func (b *SQLiteBackup) Finish() error { | ||||||
| 	return b.Close() | 	return b.Close() | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | // Close close backup.
 | ||||||
| func (b *SQLiteBackup) Close() error { | func (b *SQLiteBackup) Close() error { | ||||||
| 	ret := C.sqlite3_backup_finish(b.b) | 	ret := C.sqlite3_backup_finish(b.b) | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
							
								
								
									
										4
									
								
								vendor/github.com/mattn/go-sqlite3/callback.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										4
									
								
								vendor/github.com/mattn/go-sqlite3/callback.go
									
									
									
										generated
									
									
										vendored
									
									
								
							|  | @ -40,8 +40,8 @@ func callbackTrampoline(ctx *C.sqlite3_context, argc int, argv **C.sqlite3_value | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| //export stepTrampoline
 | //export stepTrampoline
 | ||||||
| func stepTrampoline(ctx *C.sqlite3_context, argc int, argv **C.sqlite3_value) { | func stepTrampoline(ctx *C.sqlite3_context, argc C.int, argv **C.sqlite3_value) { | ||||||
| 	args := (*[(math.MaxInt32 - 1) / unsafe.Sizeof((*C.sqlite3_value)(nil))]*C.sqlite3_value)(unsafe.Pointer(argv))[:argc:argc] | 	args := (*[(math.MaxInt32 - 1) / unsafe.Sizeof((*C.sqlite3_value)(nil))]*C.sqlite3_value)(unsafe.Pointer(argv))[:int(argc):int(argc)] | ||||||
| 	ai := lookupHandle(uintptr(C.sqlite3_user_data(ctx))).(*aggInfo) | 	ai := lookupHandle(uintptr(C.sqlite3_user_data(ctx))).(*aggInfo) | ||||||
| 	ai.Step(ctx, args) | 	ai.Step(ctx, args) | ||||||
| } | } | ||||||
|  |  | ||||||
							
								
								
									
										2
									
								
								vendor/github.com/mattn/go-sqlite3/doc.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										2
									
								
								vendor/github.com/mattn/go-sqlite3/doc.go
									
									
									
										generated
									
									
										vendored
									
									
								
							|  | @ -110,5 +110,3 @@ See the documentation of RegisterFunc for more details. | ||||||
| 
 | 
 | ||||||
| */ | */ | ||||||
| package sqlite3 | package sqlite3 | ||||||
| 
 |  | ||||||
| import "C" |  | ||||||
|  |  | ||||||
							
								
								
									
										9
									
								
								vendor/github.com/mattn/go-sqlite3/error.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										9
									
								
								vendor/github.com/mattn/go-sqlite3/error.go
									
									
									
										generated
									
									
										vendored
									
									
								
							|  | @ -7,12 +7,16 @@ package sqlite3 | ||||||
| 
 | 
 | ||||||
| import "C" | import "C" | ||||||
| 
 | 
 | ||||||
|  | // ErrNo inherit errno.
 | ||||||
| type ErrNo int | type ErrNo int | ||||||
| 
 | 
 | ||||||
|  | // ErrNoMask is mask code.
 | ||||||
| const ErrNoMask C.int = 0xff | const ErrNoMask C.int = 0xff | ||||||
| 
 | 
 | ||||||
|  | // ErrNoExtended is extended errno.
 | ||||||
| type ErrNoExtended int | type ErrNoExtended int | ||||||
| 
 | 
 | ||||||
|  | // Error implement sqlite error code.
 | ||||||
| type Error struct { | type Error struct { | ||||||
| 	Code         ErrNo         /* The error code returned by SQLite */ | 	Code         ErrNo         /* The error code returned by SQLite */ | ||||||
| 	ExtendedCode ErrNoExtended /* The extended error code returned by SQLite */ | 	ExtendedCode ErrNoExtended /* The extended error code returned by SQLite */ | ||||||
|  | @ -52,14 +56,17 @@ var ( | ||||||
| 	ErrWarning    = ErrNo(28) /* Warnings from sqlite3_log() */ | 	ErrWarning    = ErrNo(28) /* Warnings from sqlite3_log() */ | ||||||
| ) | ) | ||||||
| 
 | 
 | ||||||
|  | // Error return error message from errno.
 | ||||||
| func (err ErrNo) Error() string { | func (err ErrNo) Error() string { | ||||||
| 	return Error{Code: err}.Error() | 	return Error{Code: err}.Error() | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | // Extend return extended errno.
 | ||||||
| func (err ErrNo) Extend(by int) ErrNoExtended { | func (err ErrNo) Extend(by int) ErrNoExtended { | ||||||
| 	return ErrNoExtended(int(err) | (by << 8)) | 	return ErrNoExtended(int(err) | (by << 8)) | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | // Error return error message that is extended code.
 | ||||||
| func (err ErrNoExtended) Error() string { | func (err ErrNoExtended) Error() string { | ||||||
| 	return Error{Code: ErrNo(C.int(err) & ErrNoMask), ExtendedCode: err}.Error() | 	return Error{Code: ErrNo(C.int(err) & ErrNoMask), ExtendedCode: err}.Error() | ||||||
| } | } | ||||||
|  | @ -121,7 +128,7 @@ var ( | ||||||
| 	ErrConstraintTrigger      = ErrConstraint.Extend(7) | 	ErrConstraintTrigger      = ErrConstraint.Extend(7) | ||||||
| 	ErrConstraintUnique       = ErrConstraint.Extend(8) | 	ErrConstraintUnique       = ErrConstraint.Extend(8) | ||||||
| 	ErrConstraintVTab         = ErrConstraint.Extend(9) | 	ErrConstraintVTab         = ErrConstraint.Extend(9) | ||||||
| 	ErrConstraintRowId        = ErrConstraint.Extend(10) | 	ErrConstraintRowID        = ErrConstraint.Extend(10) | ||||||
| 	ErrNoticeRecoverWAL       = ErrNotice.Extend(1) | 	ErrNoticeRecoverWAL       = ErrNotice.Extend(1) | ||||||
| 	ErrNoticeRecoverRollback  = ErrNotice.Extend(2) | 	ErrNoticeRecoverRollback  = ErrNotice.Extend(2) | ||||||
| 	ErrWarningAutoIndex       = ErrWarning.Extend(1) | 	ErrWarningAutoIndex       = ErrWarning.Extend(1) | ||||||
|  |  | ||||||
							
								
								
									
										14445
									
								
								vendor/github.com/mattn/go-sqlite3/sqlite3-binding.c
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										14445
									
								
								vendor/github.com/mattn/go-sqlite3/sqlite3-binding.c
									
									
									
										generated
									
									
										vendored
									
									
								
							
										
											
												File diff suppressed because it is too large
												Load diff
											
										
									
								
							
							
								
								
									
										782
									
								
								vendor/github.com/mattn/go-sqlite3/sqlite3-binding.h
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										782
									
								
								vendor/github.com/mattn/go-sqlite3/sqlite3-binding.h
									
									
									
										generated
									
									
										vendored
									
									
								
							
										
											
												File diff suppressed because it is too large
												Load diff
											
										
									
								
							
							
								
								
									
										334
									
								
								vendor/github.com/mattn/go-sqlite3/sqlite3.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										334
									
								
								vendor/github.com/mattn/go-sqlite3/sqlite3.go
									
									
									
										generated
									
									
										vendored
									
									
								
							|  | @ -7,9 +7,10 @@ package sqlite3 | ||||||
| 
 | 
 | ||||||
| /* | /* | ||||||
| #cgo CFLAGS: -std=gnu99 | #cgo CFLAGS: -std=gnu99 | ||||||
| #cgo CFLAGS: -DSQLITE_ENABLE_RTREE -DSQLITE_THREADSAFE | #cgo CFLAGS: -DSQLITE_ENABLE_RTREE -DSQLITE_THREADSAFE=1 | ||||||
| #cgo CFLAGS: -DSQLITE_ENABLE_FTS3 -DSQLITE_ENABLE_FTS3_PARENTHESIS -DSQLITE_ENABLE_FTS4_UNICODE61 | #cgo CFLAGS: -DSQLITE_ENABLE_FTS3 -DSQLITE_ENABLE_FTS3_PARENTHESIS -DSQLITE_ENABLE_FTS4_UNICODE61 | ||||||
| #cgo CFLAGS: -DSQLITE_TRACE_SIZE_LIMIT=15 | #cgo CFLAGS: -DSQLITE_TRACE_SIZE_LIMIT=15 | ||||||
|  | #cgo CFLAGS: -DSQLITE_DISABLE_INTRINSIC | ||||||
| #cgo CFLAGS: -Wno-deprecated-declarations | #cgo CFLAGS: -Wno-deprecated-declarations | ||||||
| #ifndef USE_LIBSQLITE3 | #ifndef USE_LIBSQLITE3 | ||||||
| #include <sqlite3-binding.h> | #include <sqlite3-binding.h> | ||||||
|  | @ -112,14 +113,17 @@ import ( | ||||||
| 	"runtime" | 	"runtime" | ||||||
| 	"strconv" | 	"strconv" | ||||||
| 	"strings" | 	"strings" | ||||||
|  | 	"sync" | ||||||
| 	"time" | 	"time" | ||||||
| 	"unsafe" | 	"unsafe" | ||||||
|  | 
 | ||||||
|  | 	"golang.org/x/net/context" | ||||||
| ) | ) | ||||||
| 
 | 
 | ||||||
| // Timestamp formats understood by both this module and SQLite.
 | // SQLiteTimestampFormats is timestamp formats understood by both this module
 | ||||||
| // The first format in the slice will be used when saving time values
 | // and SQLite.  The first format in the slice will be used when saving time
 | ||||||
| // into the database. When parsing a string from a timestamp or
 | // values into the database. When parsing a string from a timestamp or datetime
 | ||||||
| // datetime column, the formats are tried in order.
 | // column, the formats are tried in order.
 | ||||||
| var SQLiteTimestampFormats = []string{ | var SQLiteTimestampFormats = []string{ | ||||||
| 	// By default, store timestamps with whatever timezone they come with.
 | 	// By default, store timestamps with whatever timezone they come with.
 | ||||||
| 	// When parsed, they will be returned with the same timezone.
 | 	// When parsed, they will be returned with the same timezone.
 | ||||||
|  | @ -139,21 +143,22 @@ func init() { | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| // Version returns SQLite library version information.
 | // Version returns SQLite library version information.
 | ||||||
| func Version() (libVersion string, libVersionNumber int, sourceId string) { | func Version() (libVersion string, libVersionNumber int, sourceID string) { | ||||||
| 	libVersion = C.GoString(C.sqlite3_libversion()) | 	libVersion = C.GoString(C.sqlite3_libversion()) | ||||||
| 	libVersionNumber = int(C.sqlite3_libversion_number()) | 	libVersionNumber = int(C.sqlite3_libversion_number()) | ||||||
| 	sourceId = C.GoString(C.sqlite3_sourceid()) | 	sourceID = C.GoString(C.sqlite3_sourceid()) | ||||||
| 	return libVersion, libVersionNumber, sourceId | 	return libVersion, libVersionNumber, sourceID | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| // Driver struct.
 | // SQLiteDriver implement sql.Driver.
 | ||||||
| type SQLiteDriver struct { | type SQLiteDriver struct { | ||||||
| 	Extensions  []string | 	Extensions  []string | ||||||
| 	ConnectHook func(*SQLiteConn) error | 	ConnectHook func(*SQLiteConn) error | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| // Conn struct.
 | // SQLiteConn implement sql.Conn.
 | ||||||
| type SQLiteConn struct { | type SQLiteConn struct { | ||||||
|  | 	dbMu        sync.Mutex | ||||||
| 	db          *C.sqlite3 | 	db          *C.sqlite3 | ||||||
| 	loc         *time.Location | 	loc         *time.Location | ||||||
| 	txlock      string | 	txlock      string | ||||||
|  | @ -161,35 +166,34 @@ type SQLiteConn struct { | ||||||
| 	aggregators []*aggInfo | 	aggregators []*aggInfo | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| // Tx struct.
 | // SQLiteTx implemen sql.Tx.
 | ||||||
| type SQLiteTx struct { | type SQLiteTx struct { | ||||||
| 	c *SQLiteConn | 	c *SQLiteConn | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| // Stmt struct.
 | // SQLiteStmt implement sql.Stmt.
 | ||||||
| type SQLiteStmt struct { | type SQLiteStmt struct { | ||||||
| 	c      *SQLiteConn | 	c      *SQLiteConn | ||||||
| 	s      *C.sqlite3_stmt | 	s      *C.sqlite3_stmt | ||||||
| 	nv     int |  | ||||||
| 	nn     []string |  | ||||||
| 	t      string | 	t      string | ||||||
| 	closed bool | 	closed bool | ||||||
| 	cls    bool | 	cls    bool | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| // Result struct.
 | // SQLiteResult implement sql.Result.
 | ||||||
| type SQLiteResult struct { | type SQLiteResult struct { | ||||||
| 	id      int64 | 	id      int64 | ||||||
| 	changes int64 | 	changes int64 | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| // Rows struct.
 | // SQLiteRows implement sql.Rows.
 | ||||||
| type SQLiteRows struct { | type SQLiteRows struct { | ||||||
| 	s        *SQLiteStmt | 	s        *SQLiteStmt | ||||||
| 	nc       int | 	nc       int | ||||||
| 	cols     []string | 	cols     []string | ||||||
| 	decltype []string | 	decltype []string | ||||||
| 	cls      bool | 	cls      bool | ||||||
|  | 	done     chan struct{} | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| type functionInfo struct { | type functionInfo struct { | ||||||
|  | @ -295,19 +299,19 @@ func (ai *aggInfo) Done(ctx *C.sqlite3_context) { | ||||||
| 
 | 
 | ||||||
| // Commit transaction.
 | // Commit transaction.
 | ||||||
| func (tx *SQLiteTx) Commit() error { | func (tx *SQLiteTx) Commit() error { | ||||||
| 	_, err := tx.c.exec("COMMIT") | 	_, err := tx.c.exec(context.Background(), "COMMIT", nil) | ||||||
| 	if err != nil && err.(Error).Code == C.SQLITE_BUSY { | 	if err != nil && err.(Error).Code == C.SQLITE_BUSY { | ||||||
| 		// sqlite3 will leave the transaction open in this scenario.
 | 		// sqlite3 will leave the transaction open in this scenario.
 | ||||||
| 		// However, database/sql considers the transaction complete once we
 | 		// However, database/sql considers the transaction complete once we
 | ||||||
| 		// return from Commit() - we must clean up to honour its semantics.
 | 		// return from Commit() - we must clean up to honour its semantics.
 | ||||||
| 		tx.c.exec("ROLLBACK") | 		tx.c.exec(context.Background(), "ROLLBACK", nil) | ||||||
| 	} | 	} | ||||||
| 	return err | 	return err | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| // Rollback transaction.
 | // Rollback transaction.
 | ||||||
| func (tx *SQLiteTx) Rollback() error { | func (tx *SQLiteTx) Rollback() error { | ||||||
| 	_, err := tx.c.exec("ROLLBACK") | 	_, err := tx.c.exec(context.Background(), "ROLLBACK", nil) | ||||||
| 	return err | 	return err | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | @ -381,34 +385,54 @@ func (c *SQLiteConn) RegisterFunc(name string, impl interface{}, pure bool) erro | ||||||
| 	if pure { | 	if pure { | ||||||
| 		opts |= C.SQLITE_DETERMINISTIC | 		opts |= C.SQLITE_DETERMINISTIC | ||||||
| 	} | 	} | ||||||
| 	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) | 	rv := sqlite3CreateFunction(c.db, cname, C.int(numArgs), C.int(opts), newHandle(c, &fi), C.callbackTrampoline, nil, nil) | ||||||
| 	if rv != C.SQLITE_OK { | 	if rv != C.SQLITE_OK { | ||||||
| 		return c.lastError() | 		return c.lastError() | ||||||
| 	} | 	} | ||||||
| 	return nil | 	return nil | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | func sqlite3CreateFunction(db *C.sqlite3, zFunctionName *C.char, nArg C.int, eTextRep C.int, pApp uintptr, xFunc unsafe.Pointer, xStep unsafe.Pointer, xFinal unsafe.Pointer) C.int { | ||||||
|  | 	return C._sqlite3_create_function(db, zFunctionName, nArg, eTextRep, C.uintptr_t(pApp), (*[0]byte)(unsafe.Pointer(xFunc)), (*[0]byte)(unsafe.Pointer(xStep)), (*[0]byte)(unsafe.Pointer(xFinal))) | ||||||
|  | } | ||||||
|  | 
 | ||||||
| // AutoCommit return which currently auto commit or not.
 | // AutoCommit return which currently auto commit or not.
 | ||||||
| func (c *SQLiteConn) AutoCommit() bool { | func (c *SQLiteConn) AutoCommit() bool { | ||||||
| 	return int(C.sqlite3_get_autocommit(c.db)) != 0 | 	return int(C.sqlite3_get_autocommit(c.db)) != 0 | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| func (c *SQLiteConn) lastError() Error { | func (c *SQLiteConn) lastError() error { | ||||||
|  | 	return lastError(c.db) | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | func lastError(db *C.sqlite3) error { | ||||||
|  | 	rv := C.sqlite3_errcode(db) | ||||||
|  | 	if rv == C.SQLITE_OK { | ||||||
|  | 		return nil | ||||||
|  | 	} | ||||||
| 	return Error{ | 	return Error{ | ||||||
| 		Code:         ErrNo(C.sqlite3_errcode(c.db)), | 		Code:         ErrNo(rv), | ||||||
| 		ExtendedCode: ErrNoExtended(C.sqlite3_extended_errcode(c.db)), | 		ExtendedCode: ErrNoExtended(C.sqlite3_extended_errcode(db)), | ||||||
| 		err:          C.GoString(C.sqlite3_errmsg(c.db)), | 		err:          C.GoString(C.sqlite3_errmsg(db)), | ||||||
| 	} | 	} | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| // Implements Execer
 | // Exec implements Execer.
 | ||||||
| func (c *SQLiteConn) Exec(query string, args []driver.Value) (driver.Result, error) { | func (c *SQLiteConn) Exec(query string, args []driver.Value) (driver.Result, error) { | ||||||
| 	if len(args) == 0 { | 	list := make([]namedValue, len(args)) | ||||||
| 		return c.exec(query) | 	for i, v := range args { | ||||||
|  | 		list[i] = namedValue{ | ||||||
|  | 			Ordinal: i + 1, | ||||||
|  | 			Value:   v, | ||||||
|  | 		} | ||||||
| 	} | 	} | ||||||
|  | 	return c.exec(context.Background(), query, list) | ||||||
|  | } | ||||||
| 
 | 
 | ||||||
|  | func (c *SQLiteConn) exec(ctx context.Context, query string, args []namedValue) (driver.Result, error) { | ||||||
|  | 	start := 0 | ||||||
| 	for { | 	for { | ||||||
| 		s, err := c.Prepare(query) | 		s, err := c.prepare(ctx, query) | ||||||
| 		if err != nil { | 		if err != nil { | ||||||
| 			return nil, err | 			return nil, err | ||||||
| 		} | 		} | ||||||
|  | @ -416,14 +440,19 @@ func (c *SQLiteConn) Exec(query string, args []driver.Value) (driver.Result, err | ||||||
| 		if s.(*SQLiteStmt).s != nil { | 		if s.(*SQLiteStmt).s != nil { | ||||||
| 			na := s.NumInput() | 			na := s.NumInput() | ||||||
| 			if len(args) < na { | 			if len(args) < na { | ||||||
| 				return nil, fmt.Errorf("Not enough args to execute query. Expected %d, got %d.", na, len(args)) | 				s.Close() | ||||||
|  | 				return nil, fmt.Errorf("not enough args to execute query: want %d got %d", na, len(args)) | ||||||
| 			} | 			} | ||||||
| 			res, err = s.Exec(args[:na]) | 			for i := 0; i < na; i++ { | ||||||
|  | 				args[i].Ordinal -= start | ||||||
|  | 			} | ||||||
|  | 			res, err = s.(*SQLiteStmt).exec(ctx, args[:na]) | ||||||
| 			if err != nil && err != driver.ErrSkip { | 			if err != nil && err != driver.ErrSkip { | ||||||
| 				s.Close() | 				s.Close() | ||||||
| 				return nil, err | 				return nil, err | ||||||
| 			} | 			} | ||||||
| 			args = args[na:] | 			args = args[na:] | ||||||
|  | 			start += na | ||||||
| 		} | 		} | ||||||
| 		tail := s.(*SQLiteStmt).t | 		tail := s.(*SQLiteStmt).t | ||||||
| 		s.Close() | 		s.Close() | ||||||
|  | @ -434,24 +463,46 @@ func (c *SQLiteConn) Exec(query string, args []driver.Value) (driver.Result, err | ||||||
| 	} | 	} | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| // Implements Queryer
 | type namedValue struct { | ||||||
|  | 	Name    string | ||||||
|  | 	Ordinal int | ||||||
|  | 	Value   driver.Value | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // Query implements Queryer.
 | ||||||
| func (c *SQLiteConn) Query(query string, args []driver.Value) (driver.Rows, error) { | func (c *SQLiteConn) Query(query string, args []driver.Value) (driver.Rows, error) { | ||||||
|  | 	list := make([]namedValue, len(args)) | ||||||
|  | 	for i, v := range args { | ||||||
|  | 		list[i] = namedValue{ | ||||||
|  | 			Ordinal: i + 1, | ||||||
|  | 			Value:   v, | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | 	return c.query(context.Background(), query, list) | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | func (c *SQLiteConn) query(ctx context.Context, query string, args []namedValue) (driver.Rows, error) { | ||||||
|  | 	start := 0 | ||||||
| 	for { | 	for { | ||||||
| 		s, err := c.Prepare(query) | 		s, err := c.prepare(ctx, query) | ||||||
| 		if err != nil { | 		if err != nil { | ||||||
| 			return nil, err | 			return nil, err | ||||||
| 		} | 		} | ||||||
| 		s.(*SQLiteStmt).cls = true | 		s.(*SQLiteStmt).cls = true | ||||||
| 		na := s.NumInput() | 		na := s.NumInput() | ||||||
| 		if len(args) < na { | 		if len(args) < na { | ||||||
| 			return nil, fmt.Errorf("Not enough args to execute query. Expected %d, got %d.", na, len(args)) | 			return nil, fmt.Errorf("not enough args to execute query: want %d got %d", na, len(args)) | ||||||
| 		} | 		} | ||||||
| 		rows, err := s.Query(args[:na]) | 		for i := 0; i < na; i++ { | ||||||
|  | 			args[i].Ordinal -= start | ||||||
|  | 		} | ||||||
|  | 		rows, err := s.(*SQLiteStmt).query(ctx, args[:na]) | ||||||
| 		if err != nil && err != driver.ErrSkip { | 		if err != nil && err != driver.ErrSkip { | ||||||
| 			s.Close() | 			s.Close() | ||||||
| 			return nil, err | 			return rows, err | ||||||
| 		} | 		} | ||||||
| 		args = args[na:] | 		args = args[na:] | ||||||
|  | 		start += na | ||||||
| 		tail := s.(*SQLiteStmt).t | 		tail := s.(*SQLiteStmt).t | ||||||
| 		if tail == "" { | 		if tail == "" { | ||||||
| 			return rows, nil | 			return rows, nil | ||||||
|  | @ -462,21 +513,13 @@ func (c *SQLiteConn) Query(query string, args []driver.Value) (driver.Rows, erro | ||||||
| 	} | 	} | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| func (c *SQLiteConn) exec(cmd string) (driver.Result, error) { |  | ||||||
| 	pcmd := C.CString(cmd) |  | ||||||
| 	defer C.free(unsafe.Pointer(pcmd)) |  | ||||||
| 
 |  | ||||||
| 	var rowid, changes C.longlong |  | ||||||
| 	rv := C._sqlite3_exec(c.db, pcmd, &rowid, &changes) |  | ||||||
| 	if rv != C.SQLITE_OK { |  | ||||||
| 		return nil, c.lastError() |  | ||||||
| 	} |  | ||||||
| 	return &SQLiteResult{int64(rowid), int64(changes)}, nil |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| // Begin transaction.
 | // Begin transaction.
 | ||||||
| func (c *SQLiteConn) Begin() (driver.Tx, error) { | func (c *SQLiteConn) Begin() (driver.Tx, error) { | ||||||
| 	if _, err := c.exec(c.txlock); err != nil { | 	return c.begin(context.Background()) | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | func (c *SQLiteConn) begin(ctx context.Context) (driver.Tx, error) { | ||||||
|  | 	if _, err := c.exec(ctx, c.txlock, nil); err != nil { | ||||||
| 		return nil, err | 		return nil, err | ||||||
| 	} | 	} | ||||||
| 	return &SQLiteTx{c}, nil | 	return &SQLiteTx{c}, nil | ||||||
|  | @ -500,6 +543,8 @@ func errorString(err Error) string { | ||||||
| //   _txlock=XXX
 | //   _txlock=XXX
 | ||||||
| //     Specify locking behavior for transactions.  XXX can be "immediate",
 | //     Specify locking behavior for transactions.  XXX can be "immediate",
 | ||||||
| //     "deferred", "exclusive".
 | //     "deferred", "exclusive".
 | ||||||
|  | //   _foreign_keys=X
 | ||||||
|  | //     Enable or disable enforcement of foreign keys.  X can be 1 or 0.
 | ||||||
| func (d *SQLiteDriver) Open(dsn string) (driver.Conn, error) { | func (d *SQLiteDriver) Open(dsn string) (driver.Conn, error) { | ||||||
| 	if C.sqlite3_threadsafe() == 0 { | 	if C.sqlite3_threadsafe() == 0 { | ||||||
| 		return nil, errors.New("sqlite library was not compiled for thread-safe operation") | 		return nil, errors.New("sqlite library was not compiled for thread-safe operation") | ||||||
|  | @ -507,7 +552,8 @@ func (d *SQLiteDriver) Open(dsn string) (driver.Conn, error) { | ||||||
| 
 | 
 | ||||||
| 	var loc *time.Location | 	var loc *time.Location | ||||||
| 	txlock := "BEGIN" | 	txlock := "BEGIN" | ||||||
| 	busy_timeout := 5000 | 	busyTimeout := 5000 | ||||||
|  | 	foreignKeys := -1 | ||||||
| 	pos := strings.IndexRune(dsn, '?') | 	pos := strings.IndexRune(dsn, '?') | ||||||
| 	if pos >= 1 { | 	if pos >= 1 { | ||||||
| 		params, err := url.ParseQuery(dsn[pos+1:]) | 		params, err := url.ParseQuery(dsn[pos+1:]) | ||||||
|  | @ -533,7 +579,7 @@ func (d *SQLiteDriver) Open(dsn string) (driver.Conn, error) { | ||||||
| 			if err != nil { | 			if err != nil { | ||||||
| 				return nil, fmt.Errorf("Invalid _busy_timeout: %v: %v", val, err) | 				return nil, fmt.Errorf("Invalid _busy_timeout: %v: %v", val, err) | ||||||
| 			} | 			} | ||||||
| 			busy_timeout = int(iv) | 			busyTimeout = int(iv) | ||||||
| 		} | 		} | ||||||
| 
 | 
 | ||||||
| 		// _txlock
 | 		// _txlock
 | ||||||
|  | @ -550,6 +596,18 @@ func (d *SQLiteDriver) Open(dsn string) (driver.Conn, error) { | ||||||
| 			} | 			} | ||||||
| 		} | 		} | ||||||
| 
 | 
 | ||||||
|  | 		// _foreign_keys
 | ||||||
|  | 		if val := params.Get("_foreign_keys"); val != "" { | ||||||
|  | 			switch val { | ||||||
|  | 			case "1": | ||||||
|  | 				foreignKeys = 1 | ||||||
|  | 			case "0": | ||||||
|  | 				foreignKeys = 0 | ||||||
|  | 			default: | ||||||
|  | 				return nil, fmt.Errorf("Invalid _foreign_keys: %v", val) | ||||||
|  | 			} | ||||||
|  | 		} | ||||||
|  | 
 | ||||||
| 		if !strings.HasPrefix(dsn, "file:") { | 		if !strings.HasPrefix(dsn, "file:") { | ||||||
| 			dsn = dsn[:pos] | 			dsn = dsn[:pos] | ||||||
| 		} | 		} | ||||||
|  | @ -570,21 +628,45 @@ func (d *SQLiteDriver) Open(dsn string) (driver.Conn, error) { | ||||||
| 		return nil, errors.New("sqlite succeeded without returning a database") | 		return nil, errors.New("sqlite succeeded without returning a database") | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	rv = C.sqlite3_busy_timeout(db, C.int(busy_timeout)) | 	rv = C.sqlite3_busy_timeout(db, C.int(busyTimeout)) | ||||||
| 	if rv != C.SQLITE_OK { | 	if rv != C.SQLITE_OK { | ||||||
|  | 		C.sqlite3_close_v2(db) | ||||||
| 		return nil, Error{Code: ErrNo(rv)} | 		return nil, Error{Code: ErrNo(rv)} | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
|  | 	exec := func(s string) error { | ||||||
|  | 		cs := C.CString(s) | ||||||
|  | 		rv := C.sqlite3_exec(db, cs, nil, nil, nil) | ||||||
|  | 		C.free(unsafe.Pointer(cs)) | ||||||
|  | 		if rv != C.SQLITE_OK { | ||||||
|  | 			return lastError(db) | ||||||
|  | 		} | ||||||
|  | 		return nil | ||||||
|  | 	} | ||||||
|  | 	if foreignKeys == 0 { | ||||||
|  | 		if err := exec("PRAGMA foreign_keys = OFF;"); err != nil { | ||||||
|  | 			C.sqlite3_close_v2(db) | ||||||
|  | 			return nil, err | ||||||
|  | 		} | ||||||
|  | 	} else if foreignKeys == 1 { | ||||||
|  | 		if err := exec("PRAGMA foreign_keys = ON;"); err != nil { | ||||||
|  | 			C.sqlite3_close_v2(db) | ||||||
|  | 			return nil, err | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
| 	conn := &SQLiteConn{db: db, loc: loc, txlock: txlock} | 	conn := &SQLiteConn{db: db, loc: loc, txlock: txlock} | ||||||
| 
 | 
 | ||||||
| 	if len(d.Extensions) > 0 { | 	if len(d.Extensions) > 0 { | ||||||
| 		if err := conn.loadExtensions(d.Extensions); err != nil { | 		if err := conn.loadExtensions(d.Extensions); err != nil { | ||||||
|  | 			conn.Close() | ||||||
| 			return nil, err | 			return nil, err | ||||||
| 		} | 		} | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	if d.ConnectHook != nil { | 	if d.ConnectHook != nil { | ||||||
| 		if err := d.ConnectHook(conn); err != nil { | 		if err := d.ConnectHook(conn); err != nil { | ||||||
|  | 			conn.Close() | ||||||
| 			return nil, err | 			return nil, err | ||||||
| 		} | 		} | ||||||
| 	} | 	} | ||||||
|  | @ -594,18 +676,33 @@ func (d *SQLiteDriver) Open(dsn string) (driver.Conn, error) { | ||||||
| 
 | 
 | ||||||
| // Close the connection.
 | // Close the connection.
 | ||||||
| func (c *SQLiteConn) Close() error { | func (c *SQLiteConn) Close() error { | ||||||
| 	deleteHandles(c) |  | ||||||
| 	rv := C.sqlite3_close_v2(c.db) | 	rv := C.sqlite3_close_v2(c.db) | ||||||
| 	if rv != C.SQLITE_OK { | 	if rv != C.SQLITE_OK { | ||||||
| 		return c.lastError() | 		return c.lastError() | ||||||
| 	} | 	} | ||||||
|  | 	deleteHandles(c) | ||||||
|  | 	c.dbMu.Lock() | ||||||
| 	c.db = nil | 	c.db = nil | ||||||
|  | 	c.dbMu.Unlock() | ||||||
| 	runtime.SetFinalizer(c, nil) | 	runtime.SetFinalizer(c, nil) | ||||||
| 	return nil | 	return nil | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | func (c *SQLiteConn) dbConnOpen() bool { | ||||||
|  | 	if c == nil { | ||||||
|  | 		return false | ||||||
|  | 	} | ||||||
|  | 	c.dbMu.Lock() | ||||||
|  | 	defer c.dbMu.Unlock() | ||||||
|  | 	return c.db != nil | ||||||
|  | } | ||||||
|  | 
 | ||||||
| // Prepare the query string. Return a new statement.
 | // Prepare the query string. Return a new statement.
 | ||||||
| func (c *SQLiteConn) Prepare(query string) (driver.Stmt, error) { | func (c *SQLiteConn) Prepare(query string) (driver.Stmt, error) { | ||||||
|  | 	return c.prepare(context.Background(), query) | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | func (c *SQLiteConn) prepare(ctx context.Context, query string) (driver.Stmt, error) { | ||||||
| 	pquery := C.CString(query) | 	pquery := C.CString(query) | ||||||
| 	defer C.free(unsafe.Pointer(pquery)) | 	defer C.free(unsafe.Pointer(pquery)) | ||||||
| 	var s *C.sqlite3_stmt | 	var s *C.sqlite3_stmt | ||||||
|  | @ -618,15 +715,7 @@ func (c *SQLiteConn) Prepare(query string) (driver.Stmt, error) { | ||||||
| 	if tail != nil && *tail != '\000' { | 	if tail != nil && *tail != '\000' { | ||||||
| 		t = strings.TrimSpace(C.GoString(tail)) | 		t = strings.TrimSpace(C.GoString(tail)) | ||||||
| 	} | 	} | ||||||
| 	nv := int(C.sqlite3_bind_parameter_count(s)) | 	ss := &SQLiteStmt{c: c, s: s, t: t} | ||||||
| 	var nn []string |  | ||||||
| 	for i := 0; i < nv; i++ { |  | ||||||
| 		pn := C.GoString(C.sqlite3_bind_parameter_name(s, C.int(i+1))) |  | ||||||
| 		if len(pn) > 1 && pn[0] == '$' && 48 <= pn[1] && pn[1] <= 57 { |  | ||||||
| 			nn = append(nn, C.GoString(C.sqlite3_bind_parameter_name(s, C.int(i+1)))) |  | ||||||
| 		} |  | ||||||
| 	} |  | ||||||
| 	ss := &SQLiteStmt{c: c, s: s, nv: nv, nn: nn, t: t} |  | ||||||
| 	runtime.SetFinalizer(ss, (*SQLiteStmt).Close) | 	runtime.SetFinalizer(ss, (*SQLiteStmt).Close) | ||||||
| 	return ss, nil | 	return ss, nil | ||||||
| } | } | ||||||
|  | @ -637,7 +726,7 @@ func (s *SQLiteStmt) Close() error { | ||||||
| 		return nil | 		return nil | ||||||
| 	} | 	} | ||||||
| 	s.closed = true | 	s.closed = true | ||||||
| 	if s.c == nil || s.c.db == nil { | 	if !s.c.dbConnOpen() { | ||||||
| 		return errors.New("sqlite statement with already closed database connection") | 		return errors.New("sqlite statement with already closed database connection") | ||||||
| 	} | 	} | ||||||
| 	rv := C.sqlite3_finalize(s.s) | 	rv := C.sqlite3_finalize(s.s) | ||||||
|  | @ -648,9 +737,9 @@ func (s *SQLiteStmt) Close() error { | ||||||
| 	return nil | 	return nil | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| // Return a number of parameters.
 | // NumInput return a number of parameters.
 | ||||||
| func (s *SQLiteStmt) NumInput() int { | func (s *SQLiteStmt) NumInput() int { | ||||||
| 	return s.nv | 	return int(C.sqlite3_bind_parameter_count(s.s)) | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| type bindArg struct { | type bindArg struct { | ||||||
|  | @ -658,37 +747,30 @@ type bindArg struct { | ||||||
| 	v driver.Value | 	v driver.Value | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| func (s *SQLiteStmt) bind(args []driver.Value) error { | var placeHolder = []byte{0} | ||||||
|  | 
 | ||||||
|  | func (s *SQLiteStmt) bind(args []namedValue) error { | ||||||
| 	rv := C.sqlite3_reset(s.s) | 	rv := C.sqlite3_reset(s.s) | ||||||
| 	if rv != C.SQLITE_ROW && rv != C.SQLITE_OK && rv != C.SQLITE_DONE { | 	if rv != C.SQLITE_ROW && rv != C.SQLITE_OK && rv != C.SQLITE_DONE { | ||||||
| 		return s.c.lastError() | 		return s.c.lastError() | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	var vargs []bindArg | 	for i, v := range args { | ||||||
| 	narg := len(args) | 		if v.Name != "" { | ||||||
| 	vargs = make([]bindArg, narg) | 			cname := C.CString(":" + v.Name) | ||||||
| 	if len(s.nn) > 0 { | 			args[i].Ordinal = int(C.sqlite3_bind_parameter_index(s.s, cname)) | ||||||
| 		for i, v := range s.nn { | 			C.free(unsafe.Pointer(cname)) | ||||||
| 			if pi, err := strconv.Atoi(v[1:]); err == nil { |  | ||||||
| 				vargs[i] = bindArg{pi, args[i]} |  | ||||||
| 			} |  | ||||||
| 		} |  | ||||||
| 	} else { |  | ||||||
| 		for i, v := range args { |  | ||||||
| 			vargs[i] = bindArg{i + 1, v} |  | ||||||
| 		} | 		} | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	for _, varg := range vargs { | 	for _, arg := range args { | ||||||
| 		n := C.int(varg.n) | 		n := C.int(arg.Ordinal) | ||||||
| 		v := varg.v | 		switch v := arg.Value.(type) { | ||||||
| 		switch v := v.(type) { |  | ||||||
| 		case nil: | 		case nil: | ||||||
| 			rv = C.sqlite3_bind_null(s.s, n) | 			rv = C.sqlite3_bind_null(s.s, n) | ||||||
| 		case string: | 		case string: | ||||||
| 			if len(v) == 0 { | 			if len(v) == 0 { | ||||||
| 				b := []byte{0} | 				rv = C._sqlite3_bind_text(s.s, n, (*C.char)(unsafe.Pointer(&placeHolder[0])), C.int(0)) | ||||||
| 				rv = C._sqlite3_bind_text(s.s, n, (*C.char)(unsafe.Pointer(&b[0])), C.int(0)) |  | ||||||
| 			} else { | 			} else { | ||||||
| 				b := []byte(v) | 				b := []byte(v) | ||||||
| 				rv = C._sqlite3_bind_text(s.s, n, (*C.char)(unsafe.Pointer(&b[0])), C.int(len(b))) | 				rv = C._sqlite3_bind_text(s.s, n, (*C.char)(unsafe.Pointer(&b[0])), C.int(len(b))) | ||||||
|  | @ -705,10 +787,9 @@ func (s *SQLiteStmt) bind(args []driver.Value) error { | ||||||
| 			rv = C.sqlite3_bind_double(s.s, n, C.double(v)) | 			rv = C.sqlite3_bind_double(s.s, n, C.double(v)) | ||||||
| 		case []byte: | 		case []byte: | ||||||
| 			if len(v) == 0 { | 			if len(v) == 0 { | ||||||
| 				rv = C._sqlite3_bind_blob(s.s, n, nil, 0) | 				v = placeHolder | ||||||
| 			} else { |  | ||||||
| 				rv = C._sqlite3_bind_blob(s.s, n, unsafe.Pointer(&v[0]), C.int(len(v))) |  | ||||||
| 			} | 			} | ||||||
|  | 			rv = C._sqlite3_bind_blob(s.s, n, unsafe.Pointer(&v[0]), C.int(len(v))) | ||||||
| 		case time.Time: | 		case time.Time: | ||||||
| 			b := []byte(v.Format(SQLiteTimestampFormats[0])) | 			b := []byte(v.Format(SQLiteTimestampFormats[0])) | ||||||
| 			rv = C._sqlite3_bind_text(s.s, n, (*C.char)(unsafe.Pointer(&b[0])), C.int(len(b))) | 			rv = C._sqlite3_bind_text(s.s, n, (*C.char)(unsafe.Pointer(&b[0])), C.int(len(b))) | ||||||
|  | @ -722,29 +803,85 @@ func (s *SQLiteStmt) bind(args []driver.Value) error { | ||||||
| 
 | 
 | ||||||
| // Query the statement with arguments. Return records.
 | // Query the statement with arguments. Return records.
 | ||||||
| func (s *SQLiteStmt) Query(args []driver.Value) (driver.Rows, error) { | func (s *SQLiteStmt) Query(args []driver.Value) (driver.Rows, error) { | ||||||
|  | 	list := make([]namedValue, len(args)) | ||||||
|  | 	for i, v := range args { | ||||||
|  | 		list[i] = namedValue{ | ||||||
|  | 			Ordinal: i + 1, | ||||||
|  | 			Value:   v, | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | 	return s.query(context.Background(), list) | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | func (s *SQLiteStmt) query(ctx context.Context, args []namedValue) (driver.Rows, error) { | ||||||
| 	if err := s.bind(args); err != nil { | 	if err := s.bind(args); err != nil { | ||||||
| 		return nil, err | 		return nil, err | ||||||
| 	} | 	} | ||||||
| 	return &SQLiteRows{s, int(C.sqlite3_column_count(s.s)), nil, nil, s.cls}, nil | 
 | ||||||
|  | 	rows := &SQLiteRows{ | ||||||
|  | 		s:        s, | ||||||
|  | 		nc:       int(C.sqlite3_column_count(s.s)), | ||||||
|  | 		cols:     nil, | ||||||
|  | 		decltype: nil, | ||||||
|  | 		cls:      s.cls, | ||||||
|  | 		done:     make(chan struct{}), | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	go func(db *C.sqlite3) { | ||||||
|  | 		select { | ||||||
|  | 		case <-ctx.Done(): | ||||||
|  | 			select { | ||||||
|  | 			case <-rows.done: | ||||||
|  | 			default: | ||||||
|  | 				C.sqlite3_interrupt(db) | ||||||
|  | 				rows.Close() | ||||||
|  | 			} | ||||||
|  | 		case <-rows.done: | ||||||
|  | 		} | ||||||
|  | 	}(s.c.db) | ||||||
|  | 
 | ||||||
|  | 	return rows, nil | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| // Return last inserted ID.
 | // LastInsertId teturn last inserted ID.
 | ||||||
| func (r *SQLiteResult) LastInsertId() (int64, error) { | func (r *SQLiteResult) LastInsertId() (int64, error) { | ||||||
| 	return r.id, nil | 	return r.id, nil | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| // Return how many rows affected.
 | // RowsAffected return how many rows affected.
 | ||||||
| func (r *SQLiteResult) RowsAffected() (int64, error) { | func (r *SQLiteResult) RowsAffected() (int64, error) { | ||||||
| 	return r.changes, nil | 	return r.changes, nil | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| // Execute the statement with arguments. Return result object.
 | // Exec execute the statement with arguments. Return result object.
 | ||||||
| func (s *SQLiteStmt) Exec(args []driver.Value) (driver.Result, error) { | func (s *SQLiteStmt) Exec(args []driver.Value) (driver.Result, error) { | ||||||
|  | 	list := make([]namedValue, len(args)) | ||||||
|  | 	for i, v := range args { | ||||||
|  | 		list[i] = namedValue{ | ||||||
|  | 			Ordinal: i + 1, | ||||||
|  | 			Value:   v, | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | 	return s.exec(context.Background(), list) | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | func (s *SQLiteStmt) exec(ctx context.Context, args []namedValue) (driver.Result, error) { | ||||||
| 	if err := s.bind(args); err != nil { | 	if err := s.bind(args); err != nil { | ||||||
| 		C.sqlite3_reset(s.s) | 		C.sqlite3_reset(s.s) | ||||||
| 		C.sqlite3_clear_bindings(s.s) | 		C.sqlite3_clear_bindings(s.s) | ||||||
| 		return nil, err | 		return nil, err | ||||||
| 	} | 	} | ||||||
|  | 
 | ||||||
|  | 	done := make(chan struct{}) | ||||||
|  | 	defer close(done) | ||||||
|  | 	go func(db *C.sqlite3) { | ||||||
|  | 		select { | ||||||
|  | 		case <-ctx.Done(): | ||||||
|  | 			C.sqlite3_interrupt(db) | ||||||
|  | 		case <-done: | ||||||
|  | 		} | ||||||
|  | 	}(s.c.db) | ||||||
|  | 
 | ||||||
| 	var rowid, changes C.longlong | 	var rowid, changes C.longlong | ||||||
| 	rv := C._sqlite3_step(s.s, &rowid, &changes) | 	rv := C._sqlite3_step(s.s, &rowid, &changes) | ||||||
| 	if rv != C.SQLITE_ROW && rv != C.SQLITE_OK && rv != C.SQLITE_DONE { | 	if rv != C.SQLITE_ROW && rv != C.SQLITE_OK && rv != C.SQLITE_DONE { | ||||||
|  | @ -753,7 +890,8 @@ func (s *SQLiteStmt) Exec(args []driver.Value) (driver.Result, error) { | ||||||
| 		C.sqlite3_clear_bindings(s.s) | 		C.sqlite3_clear_bindings(s.s) | ||||||
| 		return nil, err | 		return nil, err | ||||||
| 	} | 	} | ||||||
| 	return &SQLiteResult{int64(rowid), int64(changes)}, nil | 
 | ||||||
|  | 	return &SQLiteResult{id: int64(rowid), changes: int64(changes)}, nil | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| // Close the rows.
 | // Close the rows.
 | ||||||
|  | @ -761,6 +899,9 @@ func (rc *SQLiteRows) Close() error { | ||||||
| 	if rc.s.closed { | 	if rc.s.closed { | ||||||
| 		return nil | 		return nil | ||||||
| 	} | 	} | ||||||
|  | 	if rc.done != nil { | ||||||
|  | 		close(rc.done) | ||||||
|  | 	} | ||||||
| 	if rc.cls { | 	if rc.cls { | ||||||
| 		return rc.s.Close() | 		return rc.s.Close() | ||||||
| 	} | 	} | ||||||
|  | @ -771,7 +912,7 @@ func (rc *SQLiteRows) Close() error { | ||||||
| 	return nil | 	return nil | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| // Return column names.
 | // Columns return column names.
 | ||||||
| func (rc *SQLiteRows) Columns() []string { | func (rc *SQLiteRows) Columns() []string { | ||||||
| 	if rc.nc != len(rc.cols) { | 	if rc.nc != len(rc.cols) { | ||||||
| 		rc.cols = make([]string, rc.nc) | 		rc.cols = make([]string, rc.nc) | ||||||
|  | @ -782,7 +923,7 @@ func (rc *SQLiteRows) Columns() []string { | ||||||
| 	return rc.cols | 	return rc.cols | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| // Return column types.
 | // DeclTypes return column types.
 | ||||||
| func (rc *SQLiteRows) DeclTypes() []string { | func (rc *SQLiteRows) DeclTypes() []string { | ||||||
| 	if rc.decltype == nil { | 	if rc.decltype == nil { | ||||||
| 		rc.decltype = make([]string, rc.nc) | 		rc.decltype = make([]string, rc.nc) | ||||||
|  | @ -793,7 +934,7 @@ func (rc *SQLiteRows) DeclTypes() []string { | ||||||
| 	return rc.decltype | 	return rc.decltype | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| // 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 { | ||||||
| 	rv := C.sqlite3_step(rc.s.s) | 	rv := C.sqlite3_step(rc.s.s) | ||||||
| 	if rv == C.SQLITE_DONE { | 	if rv == C.SQLITE_DONE { | ||||||
|  | @ -820,10 +961,11 @@ func (rc *SQLiteRows) Next(dest []driver.Value) error { | ||||||
| 				// large to be a reasonable timestamp in seconds.
 | 				// large to be a reasonable timestamp in seconds.
 | ||||||
| 				if val > 1e12 || val < -1e12 { | 				if val > 1e12 || val < -1e12 { | ||||||
| 					val *= int64(time.Millisecond) // convert ms to nsec
 | 					val *= int64(time.Millisecond) // convert ms to nsec
 | ||||||
|  | 					t = time.Unix(0, val) | ||||||
| 				} else { | 				} else { | ||||||
| 					val *= int64(time.Second) // convert sec to nsec
 | 					t = time.Unix(val, 0) | ||||||
| 				} | 				} | ||||||
| 				t = time.Unix(0, val).UTC() | 				t = t.UTC() | ||||||
| 				if rc.s.c.loc != nil { | 				if rc.s.c.loc != nil { | ||||||
| 					t = t.In(rc.s.c.loc) | 					t = t.In(rc.s.c.loc) | ||||||
| 				} | 				} | ||||||
|  |  | ||||||
							
								
								
									
										103
									
								
								vendor/github.com/mattn/go-sqlite3/sqlite3_context.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										103
									
								
								vendor/github.com/mattn/go-sqlite3/sqlite3_context.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							|  | @ -0,0 +1,103 @@ | ||||||
|  | // Copyright (C) 2014 Yasuhiro Matsumoto <mattn.jp@gmail.com>.
 | ||||||
|  | //
 | ||||||
|  | // Use of this source code is governed by an MIT-style
 | ||||||
|  | // license that can be found in the LICENSE file.
 | ||||||
|  | 
 | ||||||
|  | package sqlite3 | ||||||
|  | 
 | ||||||
|  | /* | ||||||
|  | 
 | ||||||
|  | #ifndef USE_LIBSQLITE3 | ||||||
|  | #include <sqlite3-binding.h> | ||||||
|  | #else | ||||||
|  | #include <sqlite3.h> | ||||||
|  | #endif | ||||||
|  | #include <stdlib.h> | ||||||
|  | // These wrappers are necessary because SQLITE_TRANSIENT
 | ||||||
|  | // is a pointer constant, and cgo doesn't translate them correctly.
 | ||||||
|  | 
 | ||||||
|  | static inline void my_result_text(sqlite3_context *ctx, char *p, int np) { | ||||||
|  | 	sqlite3_result_text(ctx, p, np, SQLITE_TRANSIENT); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | static inline void my_result_blob(sqlite3_context *ctx, void *p, int np) { | ||||||
|  | 	sqlite3_result_blob(ctx, p, np, SQLITE_TRANSIENT); | ||||||
|  | } | ||||||
|  | */ | ||||||
|  | import "C" | ||||||
|  | 
 | ||||||
|  | import ( | ||||||
|  | 	"math" | ||||||
|  | 	"reflect" | ||||||
|  | 	"unsafe" | ||||||
|  | ) | ||||||
|  | 
 | ||||||
|  | const i64 = unsafe.Sizeof(int(0)) > 4 | ||||||
|  | 
 | ||||||
|  | // SQLiteContext behave sqlite3_context
 | ||||||
|  | type SQLiteContext C.sqlite3_context | ||||||
|  | 
 | ||||||
|  | // ResultBool sets the result of an SQL function.
 | ||||||
|  | func (c *SQLiteContext) ResultBool(b bool) { | ||||||
|  | 	if b { | ||||||
|  | 		c.ResultInt(1) | ||||||
|  | 	} else { | ||||||
|  | 		c.ResultInt(0) | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // ResultBlob sets the result of an SQL function.
 | ||||||
|  | // See: sqlite3_result_blob, http://sqlite.org/c3ref/result_blob.html
 | ||||||
|  | func (c *SQLiteContext) ResultBlob(b []byte) { | ||||||
|  | 	if i64 && len(b) > math.MaxInt32 { | ||||||
|  | 		C.sqlite3_result_error_toobig((*C.sqlite3_context)(c)) | ||||||
|  | 		return | ||||||
|  | 	} | ||||||
|  | 	var p *byte | ||||||
|  | 	if len(b) > 0 { | ||||||
|  | 		p = &b[0] | ||||||
|  | 	} | ||||||
|  | 	C.my_result_blob((*C.sqlite3_context)(c), unsafe.Pointer(p), C.int(len(b))) | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // ResultDouble sets the result of an SQL function.
 | ||||||
|  | // See: sqlite3_result_double, http://sqlite.org/c3ref/result_blob.html
 | ||||||
|  | func (c *SQLiteContext) ResultDouble(d float64) { | ||||||
|  | 	C.sqlite3_result_double((*C.sqlite3_context)(c), C.double(d)) | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // ResultInt sets the result of an SQL function.
 | ||||||
|  | // See: sqlite3_result_int, http://sqlite.org/c3ref/result_blob.html
 | ||||||
|  | func (c *SQLiteContext) ResultInt(i int) { | ||||||
|  | 	if i64 && (i > math.MaxInt32 || i < math.MinInt32) { | ||||||
|  | 		C.sqlite3_result_int64((*C.sqlite3_context)(c), C.sqlite3_int64(i)) | ||||||
|  | 	} else { | ||||||
|  | 		C.sqlite3_result_int((*C.sqlite3_context)(c), C.int(i)) | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // ResultInt64 sets the result of an SQL function.
 | ||||||
|  | // See: sqlite3_result_int64, http://sqlite.org/c3ref/result_blob.html
 | ||||||
|  | func (c *SQLiteContext) ResultInt64(i int64) { | ||||||
|  | 	C.sqlite3_result_int64((*C.sqlite3_context)(c), C.sqlite3_int64(i)) | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // ResultNull sets the result of an SQL function.
 | ||||||
|  | // See: sqlite3_result_null, http://sqlite.org/c3ref/result_blob.html
 | ||||||
|  | func (c *SQLiteContext) ResultNull() { | ||||||
|  | 	C.sqlite3_result_null((*C.sqlite3_context)(c)) | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // ResultText sets the result of an SQL function.
 | ||||||
|  | // See: sqlite3_result_text, http://sqlite.org/c3ref/result_blob.html
 | ||||||
|  | func (c *SQLiteContext) ResultText(s string) { | ||||||
|  | 	h := (*reflect.StringHeader)(unsafe.Pointer(&s)) | ||||||
|  | 	cs, l := (*C.char)(unsafe.Pointer(h.Data)), C.int(h.Len) | ||||||
|  | 	C.my_result_text((*C.sqlite3_context)(c), cs, l) | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // ResultZeroblob sets the result of an SQL function.
 | ||||||
|  | // See: sqlite3_result_zeroblob, http://sqlite.org/c3ref/result_blob.html
 | ||||||
|  | func (c *SQLiteContext) ResultZeroblob(n int) { | ||||||
|  | 	C.sqlite3_result_zeroblob((*C.sqlite3_context)(c), C.int(n)) | ||||||
|  | } | ||||||
							
								
								
									
										69
									
								
								vendor/github.com/mattn/go-sqlite3/sqlite3_go18.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										69
									
								
								vendor/github.com/mattn/go-sqlite3/sqlite3_go18.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							|  | @ -0,0 +1,69 @@ | ||||||
|  | // Copyright (C) 2014 Yasuhiro Matsumoto <mattn.jp@gmail.com>.
 | ||||||
|  | //
 | ||||||
|  | // Use of this source code is governed by an MIT-style
 | ||||||
|  | // license that can be found in the LICENSE file.
 | ||||||
|  | 
 | ||||||
|  | // +build go1.8
 | ||||||
|  | 
 | ||||||
|  | package sqlite3 | ||||||
|  | 
 | ||||||
|  | import ( | ||||||
|  | 	"database/sql/driver" | ||||||
|  | 	"errors" | ||||||
|  | 
 | ||||||
|  | 	"context" | ||||||
|  | ) | ||||||
|  | 
 | ||||||
|  | // Ping implement Pinger.
 | ||||||
|  | func (c *SQLiteConn) Ping(ctx context.Context) error { | ||||||
|  | 	if c.db == nil { | ||||||
|  | 		return errors.New("Connection was closed") | ||||||
|  | 	} | ||||||
|  | 	return nil | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // QueryContext implement QueryerContext.
 | ||||||
|  | func (c *SQLiteConn) QueryContext(ctx context.Context, query string, args []driver.NamedValue) (driver.Rows, error) { | ||||||
|  | 	list := make([]namedValue, len(args)) | ||||||
|  | 	for i, nv := range args { | ||||||
|  | 		list[i] = namedValue(nv) | ||||||
|  | 	} | ||||||
|  | 	return c.query(ctx, query, list) | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // ExecContext implement ExecerContext.
 | ||||||
|  | func (c *SQLiteConn) ExecContext(ctx context.Context, query string, args []driver.NamedValue) (driver.Result, error) { | ||||||
|  | 	list := make([]namedValue, len(args)) | ||||||
|  | 	for i, nv := range args { | ||||||
|  | 		list[i] = namedValue(nv) | ||||||
|  | 	} | ||||||
|  | 	return c.exec(ctx, query, list) | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // PrepareContext implement ConnPrepareContext.
 | ||||||
|  | func (c *SQLiteConn) PrepareContext(ctx context.Context, query string) (driver.Stmt, error) { | ||||||
|  | 	return c.prepare(ctx, query) | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // BeginTx implement ConnBeginTx.
 | ||||||
|  | func (c *SQLiteConn) BeginTx(ctx context.Context, opts driver.TxOptions) (driver.Tx, error) { | ||||||
|  | 	return c.begin(ctx) | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // QueryContext implement QueryerContext.
 | ||||||
|  | func (s *SQLiteStmt) QueryContext(ctx context.Context, args []driver.NamedValue) (driver.Rows, error) { | ||||||
|  | 	list := make([]namedValue, len(args)) | ||||||
|  | 	for i, nv := range args { | ||||||
|  | 		list[i] = namedValue(nv) | ||||||
|  | 	} | ||||||
|  | 	return s.query(ctx, list) | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // ExecContext implement ExecerContext.
 | ||||||
|  | func (s *SQLiteStmt) ExecContext(ctx context.Context, args []driver.NamedValue) (driver.Result, error) { | ||||||
|  | 	list := make([]namedValue, len(args)) | ||||||
|  | 	for i, nv := range args { | ||||||
|  | 		list[i] = namedValue(nv) | ||||||
|  | 	} | ||||||
|  | 	return s.exec(ctx, list) | ||||||
|  | } | ||||||
							
								
								
									
										2
									
								
								vendor/github.com/mattn/go-sqlite3/sqlite3_icu.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										2
									
								
								vendor/github.com/mattn/go-sqlite3/sqlite3_icu.go
									
									
									
										generated
									
									
										vendored
									
									
								
							|  | @ -2,7 +2,7 @@ | ||||||
| //
 | //
 | ||||||
| // Use of this source code is governed by an MIT-style
 | // Use of this source code is governed by an MIT-style
 | ||||||
| // license that can be found in the LICENSE file.
 | // license that can be found in the LICENSE file.
 | ||||||
| // +build icu 
 | // +build icu
 | ||||||
| 
 | 
 | ||||||
| package sqlite3 | package sqlite3 | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
							
								
								
									
										2
									
								
								vendor/github.com/mattn/go-sqlite3/sqlite3_load_extension.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										2
									
								
								vendor/github.com/mattn/go-sqlite3/sqlite3_load_extension.go
									
									
									
										generated
									
									
										vendored
									
									
								
							|  | @ -31,6 +31,7 @@ func (c *SQLiteConn) loadExtensions(extensions []string) error { | ||||||
| 		defer C.free(unsafe.Pointer(cext)) | 		defer C.free(unsafe.Pointer(cext)) | ||||||
| 		rv = C.sqlite3_load_extension(c.db, cext, nil, nil) | 		rv = C.sqlite3_load_extension(c.db, cext, nil, nil) | ||||||
| 		if rv != C.SQLITE_OK { | 		if rv != C.SQLITE_OK { | ||||||
|  | 			C.sqlite3_enable_load_extension(c.db, 0) | ||||||
| 			return errors.New(C.GoString(C.sqlite3_errmsg(c.db))) | 			return errors.New(C.GoString(C.sqlite3_errmsg(c.db))) | ||||||
| 		} | 		} | ||||||
| 	} | 	} | ||||||
|  | @ -42,6 +43,7 @@ func (c *SQLiteConn) loadExtensions(extensions []string) error { | ||||||
| 	return nil | 	return nil | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | // LoadExtension load the sqlite3 extension.
 | ||||||
| func (c *SQLiteConn) LoadExtension(lib string, entry string) error { | func (c *SQLiteConn) LoadExtension(lib string, entry string) error { | ||||||
| 	rv := C.sqlite3_enable_load_extension(c.db, 1) | 	rv := C.sqlite3_enable_load_extension(c.db, 1) | ||||||
| 	if rv != C.SQLITE_OK { | 	if rv != C.SQLITE_OK { | ||||||
|  |  | ||||||
|  | @ -1,5 +1,4 @@ | ||||||
| // Copyright (C) 2016 Yasuhiro Matsumoto <mattn.jp@gmail.com>.
 | // Copyright (C) 2016 Yasuhiro Matsumoto <mattn.jp@gmail.com>.
 | ||||||
| // TODO: add "Gimpl do foo" team?
 |  | ||||||
| //
 | //
 | ||||||
| // Use of this source code is governed by an MIT-style
 | // Use of this source code is governed by an MIT-style
 | ||||||
| // license that can be found in the LICENSE file.
 | // license that can be found in the LICENSE file.
 | ||||||
|  | @ -17,7 +16,7 @@ package sqlite3 | ||||||
| 
 | 
 | ||||||
| void stepTrampoline(sqlite3_context*, int, sqlite3_value**); | void stepTrampoline(sqlite3_context*, int, sqlite3_value**); | ||||||
| void doneTrampoline(sqlite3_context*); | void doneTrampoline(sqlite3_context*); | ||||||
| void traceCallbackTrampoline(unsigned traceEventCode, void *ctx, void *p, void *x); | int traceCallbackTrampoline(unsigned int traceEventCode, void *ctx, void *p, void *x); | ||||||
| */ | */ | ||||||
| import "C" | import "C" | ||||||
| 
 | 
 | ||||||
|  | @ -76,7 +75,7 @@ type TraceUserCallback func(TraceInfo) int | ||||||
| 
 | 
 | ||||||
| type TraceConfig struct { | type TraceConfig struct { | ||||||
| 	Callback        TraceUserCallback | 	Callback        TraceUserCallback | ||||||
| 	EventMask       uint | 	EventMask       C.uint | ||||||
| 	WantExpandedSQL bool | 	WantExpandedSQL bool | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | @ -102,13 +101,13 @@ func fillExpandedSQL(info *TraceInfo, db *C.sqlite3, pStmt unsafe.Pointer) { | ||||||
| 
 | 
 | ||||||
| //export traceCallbackTrampoline
 | //export traceCallbackTrampoline
 | ||||||
| func traceCallbackTrampoline( | func traceCallbackTrampoline( | ||||||
| 	traceEventCode uint, | 	traceEventCode C.uint, | ||||||
| 	// Parameter named 'C' in SQLite docs = Context given at registration:
 | 	// Parameter named 'C' in SQLite docs = Context given at registration:
 | ||||||
| 	ctx unsafe.Pointer, | 	ctx unsafe.Pointer, | ||||||
| 	// Parameter named 'P' in SQLite docs (Primary event data?):
 | 	// Parameter named 'P' in SQLite docs (Primary event data?):
 | ||||||
| 	p unsafe.Pointer, | 	p unsafe.Pointer, | ||||||
| 	// Parameter named 'X' in SQLite docs (eXtra event data?):
 | 	// Parameter named 'X' in SQLite docs (eXtra event data?):
 | ||||||
| 	xValue unsafe.Pointer) int { | 	xValue unsafe.Pointer) C.int { | ||||||
| 
 | 
 | ||||||
| 	if ctx == nil { | 	if ctx == nil { | ||||||
| 		panic(fmt.Sprintf("No context (ev 0x%x)", traceEventCode)) | 		panic(fmt.Sprintf("No context (ev 0x%x)", traceEventCode)) | ||||||
|  | @ -196,7 +195,7 @@ func traceCallbackTrampoline( | ||||||
| 	if traceConf.Callback != nil { | 	if traceConf.Callback != nil { | ||||||
| 		r = traceConf.Callback(info) | 		r = traceConf.Callback(info) | ||||||
| 	} | 	} | ||||||
| 	return r | 	return C.int(r) | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| type traceMapEntry struct { | type traceMapEntry struct { | ||||||
|  | @ -358,7 +357,7 @@ func (c *SQLiteConn) RegisterAggregator(name string, impl interface{}, pure bool | ||||||
| 	if pure { | 	if pure { | ||||||
| 		opts |= C.SQLITE_DETERMINISTIC | 		opts |= C.SQLITE_DETERMINISTIC | ||||||
| 	} | 	} | ||||||
| 	rv := C._sqlite3_create_function(c.db, cname, C.int(stepNArgs), C.int(opts), C.uintptr_t(newHandle(c, &ai)), nil, (*[0]byte)(unsafe.Pointer(C.stepTrampoline)), (*[0]byte)(unsafe.Pointer(C.doneTrampoline))) | 	rv := sqlite3CreateFunction(c.db, cname, C.int(stepNArgs), C.int(opts), newHandle(c, &ai), nil, C.stepTrampoline, C.doneTrampoline) | ||||||
| 	if rv != C.SQLITE_OK { | 	if rv != C.SQLITE_OK { | ||||||
| 		return c.lastError() | 		return c.lastError() | ||||||
| 	} | 	} | ||||||
|  | @ -396,7 +395,7 @@ func (c *SQLiteConn) SetTrace(requested *TraceConfig) error { | ||||||
| 	// The callback trampoline function does cleanup on Close event,
 | 	// The callback trampoline function does cleanup on Close event,
 | ||||||
| 	// regardless of the presence or absence of the user callback.
 | 	// regardless of the presence or absence of the user callback.
 | ||||||
| 	// Therefore it needs the Close event to be selected:
 | 	// Therefore it needs the Close event to be selected:
 | ||||||
| 	actualEventMask := reqCopy.EventMask | TraceClose | 	actualEventMask := uint(reqCopy.EventMask | TraceClose) | ||||||
| 	err := c.setSQLiteTrace(actualEventMask) | 	err := c.setSQLiteTrace(actualEventMask) | ||||||
| 	return err | 	return err | ||||||
| } | } | ||||||
							
								
								
									
										57
									
								
								vendor/github.com/mattn/go-sqlite3/sqlite3_type.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										57
									
								
								vendor/github.com/mattn/go-sqlite3/sqlite3_type.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							|  | @ -0,0 +1,57 @@ | ||||||
|  | package sqlite3 | ||||||
|  | 
 | ||||||
|  | /* | ||||||
|  | #ifndef USE_LIBSQLITE3 | ||||||
|  | #include <sqlite3-binding.h> | ||||||
|  | #else | ||||||
|  | #include <sqlite3.h> | ||||||
|  | #endif | ||||||
|  | */ | ||||||
|  | import "C" | ||||||
|  | import ( | ||||||
|  | 	"reflect" | ||||||
|  | 	"time" | ||||||
|  | ) | ||||||
|  | 
 | ||||||
|  | // ColumnTypeDatabaseTypeName implement RowsColumnTypeDatabaseTypeName.
 | ||||||
|  | func (rc *SQLiteRows) ColumnTypeDatabaseTypeName(i int) string { | ||||||
|  | 	return C.GoString(C.sqlite3_column_decltype(rc.s.s, C.int(i))) | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /* | ||||||
|  | func (rc *SQLiteRows) ColumnTypeLength(index int) (length int64, ok bool) { | ||||||
|  | 	return 0, false | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | func (rc *SQLiteRows) ColumnTypePrecisionScale(index int) (precision, scale int64, ok bool) { | ||||||
|  | 	return 0, 0, false | ||||||
|  | } | ||||||
|  | */ | ||||||
|  | 
 | ||||||
|  | // ColumnTypeNullable implement RowsColumnTypeNullable.
 | ||||||
|  | func (rc *SQLiteRows) ColumnTypeNullable(i int) (nullable, ok bool) { | ||||||
|  | 	return true, true | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // ColumnTypeScanType implement RowsColumnTypeScanType.
 | ||||||
|  | func (rc *SQLiteRows) ColumnTypeScanType(i int) reflect.Type { | ||||||
|  | 	switch C.sqlite3_column_type(rc.s.s, C.int(i)) { | ||||||
|  | 	case C.SQLITE_INTEGER: | ||||||
|  | 		switch C.GoString(C.sqlite3_column_decltype(rc.s.s, C.int(i))) { | ||||||
|  | 		case "timestamp", "datetime", "date": | ||||||
|  | 			return reflect.TypeOf(time.Time{}) | ||||||
|  | 		case "boolean": | ||||||
|  | 			return reflect.TypeOf(false) | ||||||
|  | 		} | ||||||
|  | 		return reflect.TypeOf(int64(0)) | ||||||
|  | 	case C.SQLITE_FLOAT: | ||||||
|  | 		return reflect.TypeOf(float64(0)) | ||||||
|  | 	case C.SQLITE_BLOB: | ||||||
|  | 		return reflect.SliceOf(reflect.TypeOf(byte(0))) | ||||||
|  | 	case C.SQLITE_NULL: | ||||||
|  | 		return reflect.TypeOf(nil) | ||||||
|  | 	case C.SQLITE_TEXT: | ||||||
|  | 		return reflect.TypeOf("") | ||||||
|  | 	} | ||||||
|  | 	return reflect.SliceOf(reflect.TypeOf(byte(0))) | ||||||
|  | } | ||||||
							
								
								
									
										646
									
								
								vendor/github.com/mattn/go-sqlite3/sqlite3_vtable.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										646
									
								
								vendor/github.com/mattn/go-sqlite3/sqlite3_vtable.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							|  | @ -0,0 +1,646 @@ | ||||||
|  | // Copyright (C) 2014 Yasuhiro Matsumoto <mattn.jp@gmail.com>.
 | ||||||
|  | //
 | ||||||
|  | // Use of this source code is governed by an MIT-style
 | ||||||
|  | // license that can be found in the LICENSE file.
 | ||||||
|  | // +build vtable
 | ||||||
|  | 
 | ||||||
|  | package sqlite3 | ||||||
|  | 
 | ||||||
|  | /* | ||||||
|  | #cgo CFLAGS: -std=gnu99 | ||||||
|  | #cgo CFLAGS: -DSQLITE_ENABLE_RTREE -DSQLITE_THREADSAFE | ||||||
|  | #cgo CFLAGS: -DSQLITE_ENABLE_FTS3 -DSQLITE_ENABLE_FTS3_PARENTHESIS -DSQLITE_ENABLE_FTS4_UNICODE61 | ||||||
|  | #cgo CFLAGS: -DSQLITE_TRACE_SIZE_LIMIT=15 | ||||||
|  | #cgo CFLAGS: -DSQLITE_ENABLE_COLUMN_METADATA=1 | ||||||
|  | #cgo CFLAGS: -Wno-deprecated-declarations | ||||||
|  | 
 | ||||||
|  | #ifndef USE_LIBSQLITE3 | ||||||
|  | #include <sqlite3-binding.h> | ||||||
|  | #else | ||||||
|  | #include <sqlite3.h> | ||||||
|  | #endif | ||||||
|  | #include <stdlib.h> | ||||||
|  | #include <stdint.h> | ||||||
|  | #include <memory.h> | ||||||
|  | 
 | ||||||
|  | static inline char *_sqlite3_mprintf(char *zFormat, char *arg) { | ||||||
|  |   return sqlite3_mprintf(zFormat, arg); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | typedef struct goVTab goVTab; | ||||||
|  | 
 | ||||||
|  | struct goVTab { | ||||||
|  | 	sqlite3_vtab base; | ||||||
|  | 	void *vTab; | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | uintptr_t goMInit(void *db, void *pAux, int argc, char **argv, char **pzErr, int isCreate); | ||||||
|  | 
 | ||||||
|  | static int cXInit(sqlite3 *db, void *pAux, int argc, const char *const*argv, sqlite3_vtab **ppVTab, char **pzErr, int isCreate) { | ||||||
|  | 	void *vTab = (void *)goMInit(db, pAux, argc, (char**)argv, pzErr, isCreate); | ||||||
|  | 	if (!vTab || *pzErr) { | ||||||
|  | 		return SQLITE_ERROR; | ||||||
|  | 	} | ||||||
|  | 	goVTab *pvTab = (goVTab *)sqlite3_malloc(sizeof(goVTab)); | ||||||
|  | 	if (!pvTab) { | ||||||
|  | 		*pzErr = sqlite3_mprintf("%s", "Out of memory"); | ||||||
|  | 		return SQLITE_NOMEM; | ||||||
|  | 	} | ||||||
|  | 	memset(pvTab, 0, sizeof(goVTab)); | ||||||
|  | 	pvTab->vTab = vTab; | ||||||
|  | 
 | ||||||
|  | 	*ppVTab = (sqlite3_vtab *)pvTab; | ||||||
|  | 	*pzErr = 0; | ||||||
|  | 	return SQLITE_OK; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | static inline int cXCreate(sqlite3 *db, void *pAux, int argc, const char *const*argv, sqlite3_vtab **ppVTab, char **pzErr) { | ||||||
|  | 	return cXInit(db, pAux, argc, argv, ppVTab, pzErr, 1); | ||||||
|  | } | ||||||
|  | static inline int cXConnect(sqlite3 *db, void *pAux, int argc, const char *const*argv, sqlite3_vtab **ppVTab, char **pzErr) { | ||||||
|  | 	return cXInit(db, pAux, argc, argv, ppVTab, pzErr, 0); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | char* goVBestIndex(void *pVTab, void *icp); | ||||||
|  | 
 | ||||||
|  | static inline int cXBestIndex(sqlite3_vtab *pVTab, sqlite3_index_info *info) { | ||||||
|  | 	char *pzErr = goVBestIndex(((goVTab*)pVTab)->vTab, info); | ||||||
|  | 	if (pzErr) { | ||||||
|  | 		if (pVTab->zErrMsg) | ||||||
|  | 			sqlite3_free(pVTab->zErrMsg); | ||||||
|  | 		pVTab->zErrMsg = pzErr; | ||||||
|  | 		return SQLITE_ERROR; | ||||||
|  | 	} | ||||||
|  | 	return SQLITE_OK; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | char* goVRelease(void *pVTab, int isDestroy); | ||||||
|  | 
 | ||||||
|  | static int cXRelease(sqlite3_vtab *pVTab, int isDestroy) { | ||||||
|  | 	char *pzErr = goVRelease(((goVTab*)pVTab)->vTab, isDestroy); | ||||||
|  | 	if (pzErr) { | ||||||
|  | 		if (pVTab->zErrMsg) | ||||||
|  | 			sqlite3_free(pVTab->zErrMsg); | ||||||
|  | 		pVTab->zErrMsg = pzErr; | ||||||
|  | 		return SQLITE_ERROR; | ||||||
|  | 	} | ||||||
|  | 	if (pVTab->zErrMsg) | ||||||
|  | 		sqlite3_free(pVTab->zErrMsg); | ||||||
|  | 	sqlite3_free(pVTab); | ||||||
|  | 	return SQLITE_OK; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | static inline int cXDisconnect(sqlite3_vtab *pVTab) { | ||||||
|  | 	return cXRelease(pVTab, 0); | ||||||
|  | } | ||||||
|  | static inline int cXDestroy(sqlite3_vtab *pVTab) { | ||||||
|  | 	return cXRelease(pVTab, 1); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | typedef struct goVTabCursor goVTabCursor; | ||||||
|  | 
 | ||||||
|  | struct goVTabCursor { | ||||||
|  | 	sqlite3_vtab_cursor base; | ||||||
|  | 	void *vTabCursor; | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | uintptr_t goVOpen(void *pVTab, char **pzErr); | ||||||
|  | 
 | ||||||
|  | static int cXOpen(sqlite3_vtab *pVTab, sqlite3_vtab_cursor **ppCursor) { | ||||||
|  | 	void *vTabCursor = (void *)goVOpen(((goVTab*)pVTab)->vTab, &(pVTab->zErrMsg)); | ||||||
|  | 	goVTabCursor *pCursor = (goVTabCursor *)sqlite3_malloc(sizeof(goVTabCursor)); | ||||||
|  | 	if (!pCursor) { | ||||||
|  | 		return SQLITE_NOMEM; | ||||||
|  | 	} | ||||||
|  | 	memset(pCursor, 0, sizeof(goVTabCursor)); | ||||||
|  | 	pCursor->vTabCursor = vTabCursor; | ||||||
|  | 	*ppCursor = (sqlite3_vtab_cursor *)pCursor; | ||||||
|  | 	return SQLITE_OK; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | static int setErrMsg(sqlite3_vtab_cursor *pCursor, char *pzErr) { | ||||||
|  | 	if (pCursor->pVtab->zErrMsg) | ||||||
|  | 		sqlite3_free(pCursor->pVtab->zErrMsg); | ||||||
|  | 	pCursor->pVtab->zErrMsg = pzErr; | ||||||
|  | 	return SQLITE_ERROR; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | char* goVClose(void *pCursor); | ||||||
|  | 
 | ||||||
|  | static int cXClose(sqlite3_vtab_cursor *pCursor) { | ||||||
|  | 	char *pzErr = goVClose(((goVTabCursor*)pCursor)->vTabCursor); | ||||||
|  | 	if (pzErr) { | ||||||
|  | 		return setErrMsg(pCursor, pzErr); | ||||||
|  | 	} | ||||||
|  | 	sqlite3_free(pCursor); | ||||||
|  | 	return SQLITE_OK; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | char* goVFilter(void *pCursor, int idxNum, char* idxName, int argc, sqlite3_value **argv); | ||||||
|  | 
 | ||||||
|  | static int cXFilter(sqlite3_vtab_cursor *pCursor, int idxNum, const char *idxStr, int argc, sqlite3_value **argv) { | ||||||
|  | 	char *pzErr = goVFilter(((goVTabCursor*)pCursor)->vTabCursor, idxNum, (char*)idxStr, argc, argv); | ||||||
|  | 	if (pzErr) { | ||||||
|  | 		return setErrMsg(pCursor, pzErr); | ||||||
|  | 	} | ||||||
|  | 	return SQLITE_OK; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | char* goVNext(void *pCursor); | ||||||
|  | 
 | ||||||
|  | static int cXNext(sqlite3_vtab_cursor *pCursor) { | ||||||
|  | 	char *pzErr = goVNext(((goVTabCursor*)pCursor)->vTabCursor); | ||||||
|  | 	if (pzErr) { | ||||||
|  | 		return setErrMsg(pCursor, pzErr); | ||||||
|  | 	} | ||||||
|  | 	return SQLITE_OK; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | int goVEof(void *pCursor); | ||||||
|  | 
 | ||||||
|  | static inline int cXEof(sqlite3_vtab_cursor *pCursor) { | ||||||
|  | 	return goVEof(((goVTabCursor*)pCursor)->vTabCursor); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | char* goVColumn(void *pCursor, void *cp, int col); | ||||||
|  | 
 | ||||||
|  | static int cXColumn(sqlite3_vtab_cursor *pCursor, sqlite3_context *ctx, int i) { | ||||||
|  | 	char *pzErr = goVColumn(((goVTabCursor*)pCursor)->vTabCursor, ctx, i); | ||||||
|  | 	if (pzErr) { | ||||||
|  | 		return setErrMsg(pCursor, pzErr); | ||||||
|  | 	} | ||||||
|  | 	return SQLITE_OK; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | char* goVRowid(void *pCursor, sqlite3_int64 *pRowid); | ||||||
|  | 
 | ||||||
|  | static int cXRowid(sqlite3_vtab_cursor *pCursor, sqlite3_int64 *pRowid) { | ||||||
|  | 	char *pzErr = goVRowid(((goVTabCursor*)pCursor)->vTabCursor, pRowid); | ||||||
|  | 	if (pzErr) { | ||||||
|  | 		return setErrMsg(pCursor, pzErr); | ||||||
|  | 	} | ||||||
|  | 	return SQLITE_OK; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | char* goVUpdate(void *pVTab, int argc, sqlite3_value **argv, sqlite3_int64 *pRowid); | ||||||
|  | 
 | ||||||
|  | static int cXUpdate(sqlite3_vtab *pVTab, int argc, sqlite3_value **argv, sqlite3_int64 *pRowid) { | ||||||
|  | 	char *pzErr = goVUpdate(((goVTab*)pVTab)->vTab, argc, argv, pRowid); | ||||||
|  | 	if (pzErr) { | ||||||
|  | 		if (pVTab->zErrMsg) | ||||||
|  | 			sqlite3_free(pVTab->zErrMsg); | ||||||
|  | 		pVTab->zErrMsg = pzErr; | ||||||
|  | 		return SQLITE_ERROR; | ||||||
|  | 	} | ||||||
|  | 	return SQLITE_OK; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | static sqlite3_module goModule = { | ||||||
|  | 	0,                       // iVersion
 | ||||||
|  | 	cXCreate,                // xCreate - create a table
 | ||||||
|  | 	cXConnect,               // xConnect - connect to an existing table
 | ||||||
|  | 	cXBestIndex,             // xBestIndex - Determine search strategy
 | ||||||
|  | 	cXDisconnect,            // xDisconnect - Disconnect from a table
 | ||||||
|  | 	cXDestroy,               // xDestroy - Drop a table
 | ||||||
|  | 	cXOpen,                  // xOpen - open a cursor
 | ||||||
|  | 	cXClose,                 // xClose - close a cursor
 | ||||||
|  | 	cXFilter,                // xFilter - configure scan constraints
 | ||||||
|  | 	cXNext,                  // xNext - advance a cursor
 | ||||||
|  | 	cXEof,                   // xEof
 | ||||||
|  | 	cXColumn,                // xColumn - read data
 | ||||||
|  | 	cXRowid,                 // xRowid - read data
 | ||||||
|  | 	cXUpdate,                // xUpdate - write data
 | ||||||
|  | // Not implemented
 | ||||||
|  | 	0,                       // xBegin - begin transaction
 | ||||||
|  | 	0,                       // xSync - sync transaction
 | ||||||
|  | 	0,                       // xCommit - commit transaction
 | ||||||
|  | 	0,                       // xRollback - rollback transaction
 | ||||||
|  | 	0,                       // xFindFunction - function overloading
 | ||||||
|  | 	0,                       // xRename - rename the table
 | ||||||
|  | 	0,                       // xSavepoint
 | ||||||
|  | 	0,                       // xRelease
 | ||||||
|  | 	0	                     // xRollbackTo
 | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | void goMDestroy(void*); | ||||||
|  | 
 | ||||||
|  | static int _sqlite3_create_module(sqlite3 *db, const char *zName, uintptr_t pClientData) { | ||||||
|  |   return sqlite3_create_module_v2(db, zName, &goModule, (void*) pClientData, goMDestroy); | ||||||
|  | } | ||||||
|  | */ | ||||||
|  | import "C" | ||||||
|  | 
 | ||||||
|  | import ( | ||||||
|  | 	"fmt" | ||||||
|  | 	"math" | ||||||
|  | 	"reflect" | ||||||
|  | 	"unsafe" | ||||||
|  | ) | ||||||
|  | 
 | ||||||
|  | type sqliteModule struct { | ||||||
|  | 	c      *SQLiteConn | ||||||
|  | 	name   string | ||||||
|  | 	module Module | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | type sqliteVTab struct { | ||||||
|  | 	module *sqliteModule | ||||||
|  | 	vTab   VTab | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | type sqliteVTabCursor struct { | ||||||
|  | 	vTab       *sqliteVTab | ||||||
|  | 	vTabCursor VTabCursor | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // Op is type of operations.
 | ||||||
|  | type Op uint8 | ||||||
|  | 
 | ||||||
|  | // Op mean identity of operations.
 | ||||||
|  | const ( | ||||||
|  | 	OpEQ         Op = 2 | ||||||
|  | 	OpGT            = 4 | ||||||
|  | 	OpLE            = 8 | ||||||
|  | 	OpLT            = 16 | ||||||
|  | 	OpGE            = 32 | ||||||
|  | 	OpMATCH         = 64 | ||||||
|  | 	OpLIKE          = 65 /* 3.10.0 and later only */ | ||||||
|  | 	OpGLOB          = 66 /* 3.10.0 and later only */ | ||||||
|  | 	OpREGEXP        = 67 /* 3.10.0 and later only */ | ||||||
|  | 	OpScanUnique    = 1  /* Scan visits at most 1 row */ | ||||||
|  | ) | ||||||
|  | 
 | ||||||
|  | // InfoConstraint give information of constraint.
 | ||||||
|  | type InfoConstraint struct { | ||||||
|  | 	Column int | ||||||
|  | 	Op     Op | ||||||
|  | 	Usable bool | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // InfoOrderBy give information of order-by.
 | ||||||
|  | type InfoOrderBy struct { | ||||||
|  | 	Column int | ||||||
|  | 	Desc   bool | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | func constraints(info *C.sqlite3_index_info) []InfoConstraint { | ||||||
|  | 	l := info.nConstraint | ||||||
|  | 	slice := (*[1 << 30]C.struct_sqlite3_index_constraint)(unsafe.Pointer(info.aConstraint))[:l:l] | ||||||
|  | 
 | ||||||
|  | 	cst := make([]InfoConstraint, 0, l) | ||||||
|  | 	for _, c := range slice { | ||||||
|  | 		var usable bool | ||||||
|  | 		if c.usable > 0 { | ||||||
|  | 			usable = true | ||||||
|  | 		} | ||||||
|  | 		cst = append(cst, InfoConstraint{ | ||||||
|  | 			Column: int(c.iColumn), | ||||||
|  | 			Op:     Op(c.op), | ||||||
|  | 			Usable: usable, | ||||||
|  | 		}) | ||||||
|  | 	} | ||||||
|  | 	return cst | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | func orderBys(info *C.sqlite3_index_info) []InfoOrderBy { | ||||||
|  | 	l := info.nOrderBy | ||||||
|  | 	slice := (*[1 << 30]C.struct_sqlite3_index_orderby)(unsafe.Pointer(info.aOrderBy))[:l:l] | ||||||
|  | 
 | ||||||
|  | 	ob := make([]InfoOrderBy, 0, l) | ||||||
|  | 	for _, c := range slice { | ||||||
|  | 		var desc bool | ||||||
|  | 		if c.desc > 0 { | ||||||
|  | 			desc = true | ||||||
|  | 		} | ||||||
|  | 		ob = append(ob, InfoOrderBy{ | ||||||
|  | 			Column: int(c.iColumn), | ||||||
|  | 			Desc:   desc, | ||||||
|  | 		}) | ||||||
|  | 	} | ||||||
|  | 	return ob | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // IndexResult is a Go struct representation of what eventually ends up in the
 | ||||||
|  | // output fields for `sqlite3_index_info`
 | ||||||
|  | // See: https://www.sqlite.org/c3ref/index_info.html
 | ||||||
|  | type IndexResult struct { | ||||||
|  | 	Used           []bool // aConstraintUsage
 | ||||||
|  | 	IdxNum         int | ||||||
|  | 	IdxStr         string | ||||||
|  | 	AlreadyOrdered bool // orderByConsumed
 | ||||||
|  | 	EstimatedCost  float64 | ||||||
|  | 	EstimatedRows  float64 | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // mPrintf is a utility wrapper around sqlite3_mprintf
 | ||||||
|  | func mPrintf(format, arg string) *C.char { | ||||||
|  | 	cf := C.CString(format) | ||||||
|  | 	defer C.free(unsafe.Pointer(cf)) | ||||||
|  | 	ca := C.CString(arg) | ||||||
|  | 	defer C.free(unsafe.Pointer(ca)) | ||||||
|  | 	return C._sqlite3_mprintf(cf, ca) | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | //export goMInit
 | ||||||
|  | func goMInit(db, pClientData unsafe.Pointer, argc C.int, argv **C.char, pzErr **C.char, isCreate C.int) C.uintptr_t { | ||||||
|  | 	m := lookupHandle(uintptr(pClientData)).(*sqliteModule) | ||||||
|  | 	if m.c.db != (*C.sqlite3)(db) { | ||||||
|  | 		*pzErr = mPrintf("%s", "Inconsistent db handles") | ||||||
|  | 		return 0 | ||||||
|  | 	} | ||||||
|  | 	args := make([]string, argc) | ||||||
|  | 	var A []*C.char | ||||||
|  | 	slice := reflect.SliceHeader{Data: uintptr(unsafe.Pointer(argv)), Len: int(argc), Cap: int(argc)} | ||||||
|  | 	a := reflect.NewAt(reflect.TypeOf(A), unsafe.Pointer(&slice)).Elem().Interface() | ||||||
|  | 	for i, s := range a.([]*C.char) { | ||||||
|  | 		args[i] = C.GoString(s) | ||||||
|  | 	} | ||||||
|  | 	var vTab VTab | ||||||
|  | 	var err error | ||||||
|  | 	if isCreate == 1 { | ||||||
|  | 		vTab, err = m.module.Create(m.c, args) | ||||||
|  | 	} else { | ||||||
|  | 		vTab, err = m.module.Connect(m.c, args) | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	if err != nil { | ||||||
|  | 		*pzErr = mPrintf("%s", err.Error()) | ||||||
|  | 		return 0 | ||||||
|  | 	} | ||||||
|  | 	vt := sqliteVTab{m, vTab} | ||||||
|  | 	*pzErr = nil | ||||||
|  | 	return C.uintptr_t(newHandle(m.c, &vt)) | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | //export goVRelease
 | ||||||
|  | func goVRelease(pVTab unsafe.Pointer, isDestroy C.int) *C.char { | ||||||
|  | 	vt := lookupHandle(uintptr(pVTab)).(*sqliteVTab) | ||||||
|  | 	var err error | ||||||
|  | 	if isDestroy == 1 { | ||||||
|  | 		err = vt.vTab.Destroy() | ||||||
|  | 	} else { | ||||||
|  | 		err = vt.vTab.Disconnect() | ||||||
|  | 	} | ||||||
|  | 	if err != nil { | ||||||
|  | 		return mPrintf("%s", err.Error()) | ||||||
|  | 	} | ||||||
|  | 	return nil | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | //export goVOpen
 | ||||||
|  | func goVOpen(pVTab unsafe.Pointer, pzErr **C.char) C.uintptr_t { | ||||||
|  | 	vt := lookupHandle(uintptr(pVTab)).(*sqliteVTab) | ||||||
|  | 	vTabCursor, err := vt.vTab.Open() | ||||||
|  | 	if err != nil { | ||||||
|  | 		*pzErr = mPrintf("%s", err.Error()) | ||||||
|  | 		return 0 | ||||||
|  | 	} | ||||||
|  | 	vtc := sqliteVTabCursor{vt, vTabCursor} | ||||||
|  | 	*pzErr = nil | ||||||
|  | 	return C.uintptr_t(newHandle(vt.module.c, &vtc)) | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | //export goVBestIndex
 | ||||||
|  | func goVBestIndex(pVTab unsafe.Pointer, icp unsafe.Pointer) *C.char { | ||||||
|  | 	vt := lookupHandle(uintptr(pVTab)).(*sqliteVTab) | ||||||
|  | 	info := (*C.sqlite3_index_info)(icp) | ||||||
|  | 	csts := constraints(info) | ||||||
|  | 	res, err := vt.vTab.BestIndex(csts, orderBys(info)) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return mPrintf("%s", err.Error()) | ||||||
|  | 	} | ||||||
|  | 	if len(res.Used) != len(csts) { | ||||||
|  | 		return mPrintf("Result.Used != expected value", "") | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	// Get a pointer to constraint_usage struct so we can update in place.
 | ||||||
|  | 	l := info.nConstraint | ||||||
|  | 	s := (*[1 << 30]C.struct_sqlite3_index_constraint_usage)(unsafe.Pointer(info.aConstraintUsage))[:l:l] | ||||||
|  | 	index := 1 | ||||||
|  | 	for i := C.int(0); i < info.nConstraint; i++ { | ||||||
|  | 		if res.Used[i] { | ||||||
|  | 			s[i].argvIndex = C.int(index) | ||||||
|  | 			s[i].omit = C.uchar(1) | ||||||
|  | 			index++ | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	info.idxNum = C.int(res.IdxNum) | ||||||
|  | 	idxStr := C.CString(res.IdxStr) | ||||||
|  | 	defer C.free(unsafe.Pointer(idxStr)) | ||||||
|  | 	info.idxStr = idxStr | ||||||
|  | 	info.needToFreeIdxStr = C.int(0) | ||||||
|  | 	if res.AlreadyOrdered { | ||||||
|  | 		info.orderByConsumed = C.int(1) | ||||||
|  | 	} | ||||||
|  | 	info.estimatedCost = C.double(res.EstimatedCost) | ||||||
|  | 	info.estimatedRows = C.sqlite3_int64(res.EstimatedRows) | ||||||
|  | 
 | ||||||
|  | 	return nil | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | //export goVClose
 | ||||||
|  | func goVClose(pCursor unsafe.Pointer) *C.char { | ||||||
|  | 	vtc := lookupHandle(uintptr(pCursor)).(*sqliteVTabCursor) | ||||||
|  | 	err := vtc.vTabCursor.Close() | ||||||
|  | 	if err != nil { | ||||||
|  | 		return mPrintf("%s", err.Error()) | ||||||
|  | 	} | ||||||
|  | 	return nil | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | //export goMDestroy
 | ||||||
|  | func goMDestroy(pClientData unsafe.Pointer) { | ||||||
|  | 	m := lookupHandle(uintptr(pClientData)).(*sqliteModule) | ||||||
|  | 	m.module.DestroyModule() | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | //export goVFilter
 | ||||||
|  | func goVFilter(pCursor unsafe.Pointer, idxNum C.int, idxName *C.char, argc C.int, argv **C.sqlite3_value) *C.char { | ||||||
|  | 	vtc := lookupHandle(uintptr(pCursor)).(*sqliteVTabCursor) | ||||||
|  | 	args := (*[(math.MaxInt32 - 1) / unsafe.Sizeof((*C.sqlite3_value)(nil))]*C.sqlite3_value)(unsafe.Pointer(argv))[:argc:argc] | ||||||
|  | 	vals := make([]interface{}, 0, argc) | ||||||
|  | 	for _, v := range args { | ||||||
|  | 		conv, err := callbackArgGeneric(v) | ||||||
|  | 		if err != nil { | ||||||
|  | 			return mPrintf("%s", err.Error()) | ||||||
|  | 		} | ||||||
|  | 		vals = append(vals, conv.Interface()) | ||||||
|  | 	} | ||||||
|  | 	err := vtc.vTabCursor.Filter(int(idxNum), C.GoString(idxName), vals) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return mPrintf("%s", err.Error()) | ||||||
|  | 	} | ||||||
|  | 	return nil | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | //export goVNext
 | ||||||
|  | func goVNext(pCursor unsafe.Pointer) *C.char { | ||||||
|  | 	vtc := lookupHandle(uintptr(pCursor)).(*sqliteVTabCursor) | ||||||
|  | 	err := vtc.vTabCursor.Next() | ||||||
|  | 	if err != nil { | ||||||
|  | 		return mPrintf("%s", err.Error()) | ||||||
|  | 	} | ||||||
|  | 	return nil | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | //export goVEof
 | ||||||
|  | func goVEof(pCursor unsafe.Pointer) C.int { | ||||||
|  | 	vtc := lookupHandle(uintptr(pCursor)).(*sqliteVTabCursor) | ||||||
|  | 	err := vtc.vTabCursor.EOF() | ||||||
|  | 	if err { | ||||||
|  | 		return 1 | ||||||
|  | 	} | ||||||
|  | 	return 0 | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | //export goVColumn
 | ||||||
|  | func goVColumn(pCursor, cp unsafe.Pointer, col C.int) *C.char { | ||||||
|  | 	vtc := lookupHandle(uintptr(pCursor)).(*sqliteVTabCursor) | ||||||
|  | 	c := (*SQLiteContext)(cp) | ||||||
|  | 	err := vtc.vTabCursor.Column(c, int(col)) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return mPrintf("%s", err.Error()) | ||||||
|  | 	} | ||||||
|  | 	return nil | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | //export goVRowid
 | ||||||
|  | func goVRowid(pCursor unsafe.Pointer, pRowid *C.sqlite3_int64) *C.char { | ||||||
|  | 	vtc := lookupHandle(uintptr(pCursor)).(*sqliteVTabCursor) | ||||||
|  | 	rowid, err := vtc.vTabCursor.Rowid() | ||||||
|  | 	if err != nil { | ||||||
|  | 		return mPrintf("%s", err.Error()) | ||||||
|  | 	} | ||||||
|  | 	*pRowid = C.sqlite3_int64(rowid) | ||||||
|  | 	return nil | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | //export goVUpdate
 | ||||||
|  | func goVUpdate(pVTab unsafe.Pointer, argc C.int, argv **C.sqlite3_value, pRowid *C.sqlite3_int64) *C.char { | ||||||
|  | 	vt := lookupHandle(uintptr(pVTab)).(*sqliteVTab) | ||||||
|  | 
 | ||||||
|  | 	var tname string | ||||||
|  | 	if n, ok := vt.vTab.(interface { | ||||||
|  | 		TableName() string | ||||||
|  | 	}); ok { | ||||||
|  | 		tname = n.TableName() + " " | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	err := fmt.Errorf("virtual %s table %sis read-only", vt.module.name, tname) | ||||||
|  | 	if v, ok := vt.vTab.(VTabUpdater); ok { | ||||||
|  | 		// convert argv
 | ||||||
|  | 		args := (*[(math.MaxInt32 - 1) / unsafe.Sizeof((*C.sqlite3_value)(nil))]*C.sqlite3_value)(unsafe.Pointer(argv))[:argc:argc] | ||||||
|  | 		vals := make([]interface{}, 0, argc) | ||||||
|  | 		for _, v := range args { | ||||||
|  | 			conv, err := callbackArgGeneric(v) | ||||||
|  | 			if err != nil { | ||||||
|  | 				return mPrintf("%s", err.Error()) | ||||||
|  | 			} | ||||||
|  | 
 | ||||||
|  | 			// work around for SQLITE_NULL
 | ||||||
|  | 			x := conv.Interface() | ||||||
|  | 			if z, ok := x.([]byte); ok && z == nil { | ||||||
|  | 				x = nil | ||||||
|  | 			} | ||||||
|  | 
 | ||||||
|  | 			vals = append(vals, x) | ||||||
|  | 		} | ||||||
|  | 
 | ||||||
|  | 		switch { | ||||||
|  | 		case argc == 1: | ||||||
|  | 			err = v.Delete(vals[0]) | ||||||
|  | 
 | ||||||
|  | 		case argc > 1 && vals[0] == nil: | ||||||
|  | 			var id int64 | ||||||
|  | 			id, err = v.Insert(vals[1], vals[2:]) | ||||||
|  | 			if err == nil { | ||||||
|  | 				*pRowid = C.sqlite3_int64(id) | ||||||
|  | 			} | ||||||
|  | 
 | ||||||
|  | 		case argc > 1: | ||||||
|  | 			err = v.Update(vals[1], vals[2:]) | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	if err != nil { | ||||||
|  | 		return mPrintf("%s", err.Error()) | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	return nil | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // Module is a "virtual table module", it defines the implementation of a
 | ||||||
|  | // virtual tables. See: http://sqlite.org/c3ref/module.html
 | ||||||
|  | type Module interface { | ||||||
|  | 	// http://sqlite.org/vtab.html#xcreate
 | ||||||
|  | 	Create(c *SQLiteConn, args []string) (VTab, error) | ||||||
|  | 	// http://sqlite.org/vtab.html#xconnect
 | ||||||
|  | 	Connect(c *SQLiteConn, args []string) (VTab, error) | ||||||
|  | 	// http://sqlite.org/c3ref/create_module.html
 | ||||||
|  | 	DestroyModule() | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // VTab describes a particular instance of the virtual table.
 | ||||||
|  | // See: http://sqlite.org/c3ref/vtab.html
 | ||||||
|  | type VTab interface { | ||||||
|  | 	// http://sqlite.org/vtab.html#xbestindex
 | ||||||
|  | 	BestIndex([]InfoConstraint, []InfoOrderBy) (*IndexResult, error) | ||||||
|  | 	// http://sqlite.org/vtab.html#xdisconnect
 | ||||||
|  | 	Disconnect() error | ||||||
|  | 	// http://sqlite.org/vtab.html#sqlite3_module.xDestroy
 | ||||||
|  | 	Destroy() error | ||||||
|  | 	// http://sqlite.org/vtab.html#xopen
 | ||||||
|  | 	Open() (VTabCursor, error) | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // VTabUpdater is a type that allows a VTab to be inserted, updated, or
 | ||||||
|  | // deleted.
 | ||||||
|  | // See: https://sqlite.org/vtab.html#xupdate
 | ||||||
|  | type VTabUpdater interface { | ||||||
|  | 	Delete(interface{}) error | ||||||
|  | 	Insert(interface{}, []interface{}) (int64, error) | ||||||
|  | 	Update(interface{}, []interface{}) error | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // VTabCursor describes cursors that point into the virtual table and are used
 | ||||||
|  | // to loop through the virtual table. See: http://sqlite.org/c3ref/vtab_cursor.html
 | ||||||
|  | type VTabCursor interface { | ||||||
|  | 	// http://sqlite.org/vtab.html#xclose
 | ||||||
|  | 	Close() error | ||||||
|  | 	// http://sqlite.org/vtab.html#xfilter
 | ||||||
|  | 	Filter(idxNum int, idxStr string, vals []interface{}) error | ||||||
|  | 	// http://sqlite.org/vtab.html#xnext
 | ||||||
|  | 	Next() error | ||||||
|  | 	// http://sqlite.org/vtab.html#xeof
 | ||||||
|  | 	EOF() bool | ||||||
|  | 	// http://sqlite.org/vtab.html#xcolumn
 | ||||||
|  | 	Column(c *SQLiteContext, col int) error | ||||||
|  | 	// http://sqlite.org/vtab.html#xrowid
 | ||||||
|  | 	Rowid() (int64, error) | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // DeclareVTab declares the Schema of a virtual table.
 | ||||||
|  | // See: http://sqlite.org/c3ref/declare_vtab.html
 | ||||||
|  | func (c *SQLiteConn) DeclareVTab(sql string) error { | ||||||
|  | 	zSQL := C.CString(sql) | ||||||
|  | 	defer C.free(unsafe.Pointer(zSQL)) | ||||||
|  | 	rv := C.sqlite3_declare_vtab(c.db, zSQL) | ||||||
|  | 	if rv != C.SQLITE_OK { | ||||||
|  | 		return c.lastError() | ||||||
|  | 	} | ||||||
|  | 	return nil | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // CreateModule registers a virtual table implementation.
 | ||||||
|  | // See: http://sqlite.org/c3ref/create_module.html
 | ||||||
|  | func (c *SQLiteConn) CreateModule(moduleName string, module Module) error { | ||||||
|  | 	mname := C.CString(moduleName) | ||||||
|  | 	defer C.free(unsafe.Pointer(mname)) | ||||||
|  | 	udm := sqliteModule{c, moduleName, module} | ||||||
|  | 	rv := C._sqlite3_create_module(c.db, mname, C.uintptr_t(newHandle(c, &udm))) | ||||||
|  | 	if rv != C.SQLITE_OK { | ||||||
|  | 		return c.lastError() | ||||||
|  | 	} | ||||||
|  | 	return nil | ||||||
|  | } | ||||||
							
								
								
									
										8
									
								
								vendor/github.com/mattn/go-sqlite3/sqlite3ext.h
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										8
									
								
								vendor/github.com/mattn/go-sqlite3/sqlite3ext.h
									
									
									
										generated
									
									
										vendored
									
									
								
							|  | @ -13,7 +13,7 @@ | ||||||
| ** This header file defines the SQLite interface for use by | ** This header file defines the SQLite interface for use by | ||||||
| ** shared libraries that want to be imported as extensions into | ** shared libraries that want to be imported as extensions into | ||||||
| ** an SQLite instance.  Shared libraries that intend to be loaded | ** an SQLite instance.  Shared libraries that intend to be loaded | ||||||
| ** as extensions by SQLite should #include this file instead of | ** as extensions by SQLite should #include this file instead of  | ||||||
| ** sqlite3.h. | ** sqlite3.h. | ||||||
| */ | */ | ||||||
| #ifndef SQLITE3EXT_H | #ifndef SQLITE3EXT_H | ||||||
|  | @ -544,14 +544,14 @@ typedef int (*sqlite3_loadext_entry)( | ||||||
| #endif /* !defined(SQLITE_CORE) && !defined(SQLITE_OMIT_LOAD_EXTENSION) */ | #endif /* !defined(SQLITE_CORE) && !defined(SQLITE_OMIT_LOAD_EXTENSION) */ | ||||||
| 
 | 
 | ||||||
| #if !defined(SQLITE_CORE) && !defined(SQLITE_OMIT_LOAD_EXTENSION) | #if !defined(SQLITE_CORE) && !defined(SQLITE_OMIT_LOAD_EXTENSION) | ||||||
|   /* This case when the file really is being compiled as a loadable
 |   /* This case when the file really is being compiled as a loadable 
 | ||||||
|   ** extension */ |   ** extension */ | ||||||
| # define SQLITE_EXTENSION_INIT1     const sqlite3_api_routines *sqlite3_api=0; | # define SQLITE_EXTENSION_INIT1     const sqlite3_api_routines *sqlite3_api=0; | ||||||
| # define SQLITE_EXTENSION_INIT2(v)  sqlite3_api=v; | # define SQLITE_EXTENSION_INIT2(v)  sqlite3_api=v; | ||||||
| # define SQLITE_EXTENSION_INIT3     \ | # define SQLITE_EXTENSION_INIT3     \ | ||||||
|     extern const sqlite3_api_routines *sqlite3_api; |     extern const sqlite3_api_routines *sqlite3_api; | ||||||
| #else | #else | ||||||
|   /* This case when the file is being statically linked into the
 |   /* This case when the file is being statically linked into the 
 | ||||||
|   ** application */ |   ** application */ | ||||||
| # define SQLITE_EXTENSION_INIT1     /*no-op*/ | # define SQLITE_EXTENSION_INIT1     /*no-op*/ | ||||||
| # define SQLITE_EXTENSION_INIT2(v)  (void)v; /* unused parameter */ | # define SQLITE_EXTENSION_INIT2(v)  (void)v; /* unused parameter */ | ||||||
|  | @ -562,4 +562,4 @@ typedef int (*sqlite3_loadext_entry)( | ||||||
| #else // USE_LIBSQLITE3
 | #else // USE_LIBSQLITE3
 | ||||||
|  // If users really want to link against the system sqlite3 we
 |  // If users really want to link against the system sqlite3 we
 | ||||||
| // need to make this file a noop.
 | // need to make this file a noop.
 | ||||||
|  #endif |  #endif | ||||||
							
								
								
									
										9
									
								
								vendor/github.com/mattn/go-sqlite3/tracecallback_noimpl.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										9
									
								
								vendor/github.com/mattn/go-sqlite3/tracecallback_noimpl.go
									
									
									
										generated
									
									
										vendored
									
									
								
							|  | @ -1,9 +0,0 @@ | ||||||
| // +build !trace
 |  | ||||||
| 
 |  | ||||||
| package sqlite3 |  | ||||||
| 
 |  | ||||||
| import "errors" |  | ||||||
| 
 |  | ||||||
| func (c *SQLiteConn) RegisterAggregator(name string, impl interface{}, pure bool) error { |  | ||||||
| 	return errors.New("This feature is not implemented") |  | ||||||
| } |  | ||||||
							
								
								
									
										6
									
								
								vendor/vendor.json
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										6
									
								
								vendor/vendor.json
									
									
									
									
										vendored
									
									
								
							|  | @ -690,10 +690,10 @@ | ||||||
| 			"revisionTime": "2017-02-23T14:12:10Z" | 			"revisionTime": "2017-02-23T14:12:10Z" | ||||||
| 		}, | 		}, | ||||||
| 		{ | 		{ | ||||||
| 			"checksumSHA1": "9FJUwn3EIgASVki+p8IHgWVC5vQ=", | 			"checksumSHA1": "61HNjGetaBoMp8HBOpuEZRSim8g=", | ||||||
| 			"path": "github.com/mattn/go-sqlite3", | 			"path": "github.com/mattn/go-sqlite3", | ||||||
| 			"revision": "86681de00adef4f8040947b7d35f97000fc5a230", | 			"revision": "acfa60124032040b9f5a9406f5a772ee16fe845e", | ||||||
| 			"revisionTime": "2016-10-28T14:22:18Z" | 			"revisionTime": "2017-07-05T08:25:03Z" | ||||||
| 		}, | 		}, | ||||||
| 		{ | 		{ | ||||||
| 			"checksumSHA1": "9mjAkIoPrJdiGcR0pBa81NoFY4U=", | 			"checksumSHA1": "9mjAkIoPrJdiGcR0pBa81NoFY4U=", | ||||||
|  |  | ||||||
		Loading…
	
		Reference in a new issue