mirror of
				https://github.com/go-gitea/gitea.git
				synced 2025-10-26 12:27:06 +00:00 
			
		
		
		
	Added all required dependencies
This commit is contained in:
		
							
								
								
									
										21
									
								
								vendor/github.com/mattn/go-sqlite3/LICENSE
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										21
									
								
								vendor/github.com/mattn/go-sqlite3/LICENSE
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,21 @@ | ||||
| The MIT License (MIT) | ||||
|  | ||||
| Copyright (c) 2014 Yasuhiro Matsumoto | ||||
|  | ||||
| Permission is hereby granted, free of charge, to any person obtaining a copy | ||||
| of this software and associated documentation files (the "Software"), to deal | ||||
| in the Software without restriction, including without limitation the rights | ||||
| to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | ||||
| copies of the Software, and to permit persons to whom the Software is | ||||
| furnished to do so, subject to the following conditions: | ||||
|  | ||||
| The above copyright notice and this permission notice shall be included in all | ||||
| copies or substantial portions of the Software. | ||||
|  | ||||
| THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||||
| IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||||
| FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | ||||
| AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | ||||
| LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | ||||
| OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE | ||||
| SOFTWARE. | ||||
							
								
								
									
										81
									
								
								vendor/github.com/mattn/go-sqlite3/README.md
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										81
									
								
								vendor/github.com/mattn/go-sqlite3/README.md
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,81 @@ | ||||
| go-sqlite3 | ||||
| ========== | ||||
|  | ||||
| [](https://travis-ci.org/mattn/go-sqlite3) | ||||
| [](https://coveralls.io/r/mattn/go-sqlite3?branch=master) | ||||
| [](http://godoc.org/github.com/mattn/go-sqlite3) | ||||
|  | ||||
| Description | ||||
| ----------- | ||||
|  | ||||
| sqlite3 driver conforming to the built-in database/sql interface | ||||
|  | ||||
| Installation | ||||
| ------------ | ||||
|  | ||||
| This package can be installed with the go get command: | ||||
|  | ||||
|     go get github.com/mattn/go-sqlite3 | ||||
|      | ||||
| _go-sqlite3_ is *cgo* package. | ||||
| 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. | ||||
|      | ||||
| Documentation | ||||
| ------------- | ||||
|  | ||||
| API documentation can be found here: http://godoc.org/github.com/mattn/go-sqlite3 | ||||
|  | ||||
| Examples can be found under the `./_example` directory | ||||
|  | ||||
| FAQ | ||||
| --- | ||||
|  | ||||
| * Want to build go-sqlite3 with libsqlite3 on my linux. | ||||
|  | ||||
|     Use `go build --tags "libsqlite3 linux"` | ||||
|  | ||||
| * Want to build go-sqlite3 with libsqlite3 on OS X. | ||||
|  | ||||
|     Install sqlite3 from homebrew: `brew install sqlite3` | ||||
|  | ||||
|     Use `go build --tags "libsqlite3 darwin"` | ||||
|  | ||||
| * Want to build go-sqlite3 with icu extension. | ||||
|  | ||||
|    Use `go build --tags "icu"` | ||||
|  | ||||
| * 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.  | ||||
|     > See: https://github.com/mattn/go-sqlite3/issues/27 | ||||
|  | ||||
| * Getting insert error while query is opened. | ||||
|  | ||||
|     > You can pass some arguments into the connection string, for example, a URI. | ||||
|     > See: https://github.com/mattn/go-sqlite3/issues/39 | ||||
|  | ||||
| * Do you want to cross compile? mingw on Linux or Mac? | ||||
|  | ||||
|     > See: https://github.com/mattn/go-sqlite3/issues/106 | ||||
|     > See also: http://www.limitlessfx.com/cross-compile-golang-app-for-windows-from-linux.html | ||||
|  | ||||
| * Want to get time.Time with current locale | ||||
|  | ||||
|     Use `loc=auto` in SQLite3 filename schema like `file:foo.db?loc=auto`. | ||||
|  | ||||
| License | ||||
| ------- | ||||
|  | ||||
| MIT: http://mattn.mit-license.org/2012 | ||||
|  | ||||
| sqlite3-binding.c, sqlite3-binding.h, sqlite3ext.h | ||||
|  | ||||
| The -binding suffix was added to avoid build failures under gccgo. | ||||
|  | ||||
| In this repository, those files are an amalgamation of code that was copied from SQLite3. The license of that code is the same as the license of SQLite3. | ||||
|  | ||||
| Author | ||||
| ------ | ||||
|  | ||||
| Yasuhiro Matsumoto (a.k.a mattn) | ||||
							
								
								
									
										79
									
								
								vendor/github.com/mattn/go-sqlite3/backup.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										79
									
								
								vendor/github.com/mattn/go-sqlite3/backup.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,79 @@ | ||||
| // 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> | ||||
| */ | ||||
| import "C" | ||||
| import ( | ||||
| 	"runtime" | ||||
| 	"unsafe" | ||||
| ) | ||||
|  | ||||
| type SQLiteBackup struct { | ||||
| 	b *C.sqlite3_backup | ||||
| } | ||||
|  | ||||
| func (c *SQLiteConn) Backup(dest string, conn *SQLiteConn, src string) (*SQLiteBackup, error) { | ||||
| 	destptr := C.CString(dest) | ||||
| 	defer C.free(unsafe.Pointer(destptr)) | ||||
| 	srcptr := C.CString(src) | ||||
| 	defer C.free(unsafe.Pointer(srcptr)) | ||||
|  | ||||
| 	if b := C.sqlite3_backup_init(c.db, destptr, conn.db, srcptr); b != nil { | ||||
| 		bb := &SQLiteBackup{b: b} | ||||
| 		runtime.SetFinalizer(bb, (*SQLiteBackup).Finish) | ||||
| 		return bb, nil | ||||
| 	} | ||||
| 	return nil, c.lastError() | ||||
| } | ||||
|  | ||||
| // Backs up for one step. Calls the underlying `sqlite3_backup_step` function. | ||||
| // This function returns a boolean indicating if the backup is done and | ||||
| // an error signalling any other error. Done is returned if the underlying C | ||||
| // function returns SQLITE_DONE (Code 101) | ||||
| func (b *SQLiteBackup) Step(p int) (bool, error) { | ||||
| 	ret := C.sqlite3_backup_step(b.b, C.int(p)) | ||||
| 	if ret == C.SQLITE_DONE { | ||||
| 		return true, nil | ||||
| 	} else if ret != 0 && ret != C.SQLITE_LOCKED && ret != C.SQLITE_BUSY { | ||||
| 		return false, Error{Code: ErrNo(ret)} | ||||
| 	} | ||||
| 	return false, nil | ||||
| } | ||||
|  | ||||
| func (b *SQLiteBackup) Remaining() int { | ||||
| 	return int(C.sqlite3_backup_remaining(b.b)) | ||||
| } | ||||
|  | ||||
| func (b *SQLiteBackup) PageCount() int { | ||||
| 	return int(C.sqlite3_backup_pagecount(b.b)) | ||||
| } | ||||
|  | ||||
| func (b *SQLiteBackup) Finish() error { | ||||
| 	return b.Close() | ||||
| } | ||||
|  | ||||
| func (b *SQLiteBackup) Close() error { | ||||
| 	ret := C.sqlite3_backup_finish(b.b) | ||||
|  | ||||
| 	// sqlite3_backup_finish() never fails, it just returns the | ||||
| 	// error code from previous operations, so clean up before | ||||
| 	// checking and returning an error | ||||
| 	b.b = nil | ||||
| 	runtime.SetFinalizer(b, nil) | ||||
|  | ||||
| 	if ret != 0 { | ||||
| 		return Error{Code: ErrNo(ret)} | ||||
| 	} | ||||
| 	return nil | ||||
| } | ||||
							
								
								
									
										340
									
								
								vendor/github.com/mattn/go-sqlite3/callback.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										340
									
								
								vendor/github.com/mattn/go-sqlite3/callback.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,340 @@ | ||||
| // 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 | ||||
|  | ||||
| // You can't export a Go function to C and have definitions in the C | ||||
| // preamble in the same file, so we have to have callbackTrampoline in | ||||
| // its own file. Because we need a separate file anyway, the support | ||||
| // code for SQLite custom functions is in here. | ||||
|  | ||||
| /* | ||||
| #ifndef USE_LIBSQLITE3 | ||||
| #include <sqlite3-binding.h> | ||||
| #else | ||||
| #include <sqlite3.h> | ||||
| #endif | ||||
| #include <stdlib.h> | ||||
|  | ||||
| void _sqlite3_result_text(sqlite3_context* ctx, const char* s); | ||||
| void _sqlite3_result_blob(sqlite3_context* ctx, const void* b, int l); | ||||
| */ | ||||
| import "C" | ||||
|  | ||||
| import ( | ||||
| 	"errors" | ||||
| 	"fmt" | ||||
| 	"math" | ||||
| 	"reflect" | ||||
| 	"sync" | ||||
| 	"unsafe" | ||||
| ) | ||||
|  | ||||
| //export callbackTrampoline | ||||
| func callbackTrampoline(ctx *C.sqlite3_context, argc int, argv **C.sqlite3_value) { | ||||
| 	args := (*[(math.MaxInt32 - 1) / unsafe.Sizeof((*C.sqlite3_value)(nil))]*C.sqlite3_value)(unsafe.Pointer(argv))[:argc:argc] | ||||
| 	fi := lookupHandle(uintptr(C.sqlite3_user_data(ctx))).(*functionInfo) | ||||
| 	fi.Call(ctx, args) | ||||
| } | ||||
|  | ||||
| //export stepTrampoline | ||||
| func stepTrampoline(ctx *C.sqlite3_context, argc int, argv **C.sqlite3_value) { | ||||
| 	args := (*[(math.MaxInt32 - 1) / unsafe.Sizeof((*C.sqlite3_value)(nil))]*C.sqlite3_value)(unsafe.Pointer(argv))[:argc:argc] | ||||
| 	ai := lookupHandle(uintptr(C.sqlite3_user_data(ctx))).(*aggInfo) | ||||
| 	ai.Step(ctx, args) | ||||
| } | ||||
|  | ||||
| //export doneTrampoline | ||||
| func doneTrampoline(ctx *C.sqlite3_context) { | ||||
| 	handle := uintptr(C.sqlite3_user_data(ctx)) | ||||
| 	ai := lookupHandle(handle).(*aggInfo) | ||||
| 	ai.Done(ctx) | ||||
| } | ||||
|  | ||||
| // Use handles to avoid passing Go pointers to C. | ||||
|  | ||||
| type handleVal struct { | ||||
| 	db  *SQLiteConn | ||||
| 	val interface{} | ||||
| } | ||||
|  | ||||
| var handleLock sync.Mutex | ||||
| var handleVals = make(map[uintptr]handleVal) | ||||
| var handleIndex uintptr = 100 | ||||
|  | ||||
| func newHandle(db *SQLiteConn, v interface{}) uintptr { | ||||
| 	handleLock.Lock() | ||||
| 	defer handleLock.Unlock() | ||||
| 	i := handleIndex | ||||
| 	handleIndex++ | ||||
| 	handleVals[i] = handleVal{db, v} | ||||
| 	return i | ||||
| } | ||||
|  | ||||
| func lookupHandle(handle uintptr) interface{} { | ||||
| 	handleLock.Lock() | ||||
| 	defer handleLock.Unlock() | ||||
| 	r, ok := handleVals[handle] | ||||
| 	if !ok { | ||||
| 		if handle >= 100 && handle < handleIndex { | ||||
| 			panic("deleted handle") | ||||
| 		} else { | ||||
| 			panic("invalid handle") | ||||
| 		} | ||||
| 	} | ||||
| 	return r.val | ||||
| } | ||||
|  | ||||
| func deleteHandles(db *SQLiteConn) { | ||||
| 	handleLock.Lock() | ||||
| 	defer handleLock.Unlock() | ||||
| 	for handle, val := range handleVals { | ||||
| 		if val.db == db { | ||||
| 			delete(handleVals, handle) | ||||
| 		} | ||||
| 	} | ||||
| } | ||||
|  | ||||
| // This is only here so that tests can refer to it. | ||||
| type callbackArgRaw C.sqlite3_value | ||||
|  | ||||
| type callbackArgConverter func(*C.sqlite3_value) (reflect.Value, error) | ||||
|  | ||||
| type callbackArgCast struct { | ||||
| 	f   callbackArgConverter | ||||
| 	typ reflect.Type | ||||
| } | ||||
|  | ||||
| func (c callbackArgCast) Run(v *C.sqlite3_value) (reflect.Value, error) { | ||||
| 	val, err := c.f(v) | ||||
| 	if err != nil { | ||||
| 		return reflect.Value{}, err | ||||
| 	} | ||||
| 	if !val.Type().ConvertibleTo(c.typ) { | ||||
| 		return reflect.Value{}, fmt.Errorf("cannot convert %s to %s", val.Type(), c.typ) | ||||
| 	} | ||||
| 	return val.Convert(c.typ), nil | ||||
| } | ||||
|  | ||||
| func callbackArgInt64(v *C.sqlite3_value) (reflect.Value, error) { | ||||
| 	if C.sqlite3_value_type(v) != C.SQLITE_INTEGER { | ||||
| 		return reflect.Value{}, fmt.Errorf("argument must be an INTEGER") | ||||
| 	} | ||||
| 	return reflect.ValueOf(int64(C.sqlite3_value_int64(v))), nil | ||||
| } | ||||
|  | ||||
| func callbackArgBool(v *C.sqlite3_value) (reflect.Value, error) { | ||||
| 	if C.sqlite3_value_type(v) != C.SQLITE_INTEGER { | ||||
| 		return reflect.Value{}, fmt.Errorf("argument must be an INTEGER") | ||||
| 	} | ||||
| 	i := int64(C.sqlite3_value_int64(v)) | ||||
| 	val := false | ||||
| 	if i != 0 { | ||||
| 		val = true | ||||
| 	} | ||||
| 	return reflect.ValueOf(val), nil | ||||
| } | ||||
|  | ||||
| func callbackArgFloat64(v *C.sqlite3_value) (reflect.Value, error) { | ||||
| 	if C.sqlite3_value_type(v) != C.SQLITE_FLOAT { | ||||
| 		return reflect.Value{}, fmt.Errorf("argument must be a FLOAT") | ||||
| 	} | ||||
| 	return reflect.ValueOf(float64(C.sqlite3_value_double(v))), nil | ||||
| } | ||||
|  | ||||
| func callbackArgBytes(v *C.sqlite3_value) (reflect.Value, error) { | ||||
| 	switch C.sqlite3_value_type(v) { | ||||
| 	case C.SQLITE_BLOB: | ||||
| 		l := C.sqlite3_value_bytes(v) | ||||
| 		p := C.sqlite3_value_blob(v) | ||||
| 		return reflect.ValueOf(C.GoBytes(p, l)), nil | ||||
| 	case C.SQLITE_TEXT: | ||||
| 		l := C.sqlite3_value_bytes(v) | ||||
| 		c := unsafe.Pointer(C.sqlite3_value_text(v)) | ||||
| 		return reflect.ValueOf(C.GoBytes(c, l)), nil | ||||
| 	default: | ||||
| 		return reflect.Value{}, fmt.Errorf("argument must be BLOB or TEXT") | ||||
| 	} | ||||
| } | ||||
|  | ||||
| func callbackArgString(v *C.sqlite3_value) (reflect.Value, error) { | ||||
| 	switch C.sqlite3_value_type(v) { | ||||
| 	case C.SQLITE_BLOB: | ||||
| 		l := C.sqlite3_value_bytes(v) | ||||
| 		p := (*C.char)(C.sqlite3_value_blob(v)) | ||||
| 		return reflect.ValueOf(C.GoStringN(p, l)), nil | ||||
| 	case C.SQLITE_TEXT: | ||||
| 		c := (*C.char)(unsafe.Pointer(C.sqlite3_value_text(v))) | ||||
| 		return reflect.ValueOf(C.GoString(c)), nil | ||||
| 	default: | ||||
| 		return reflect.Value{}, fmt.Errorf("argument must be BLOB or TEXT") | ||||
| 	} | ||||
| } | ||||
|  | ||||
| func callbackArgGeneric(v *C.sqlite3_value) (reflect.Value, error) { | ||||
| 	switch C.sqlite3_value_type(v) { | ||||
| 	case C.SQLITE_INTEGER: | ||||
| 		return callbackArgInt64(v) | ||||
| 	case C.SQLITE_FLOAT: | ||||
| 		return callbackArgFloat64(v) | ||||
| 	case C.SQLITE_TEXT: | ||||
| 		return callbackArgString(v) | ||||
| 	case C.SQLITE_BLOB: | ||||
| 		return callbackArgBytes(v) | ||||
| 	case C.SQLITE_NULL: | ||||
| 		// Interpret NULL as a nil byte slice. | ||||
| 		var ret []byte | ||||
| 		return reflect.ValueOf(ret), nil | ||||
| 	default: | ||||
| 		panic("unreachable") | ||||
| 	} | ||||
| } | ||||
|  | ||||
| func callbackArg(typ reflect.Type) (callbackArgConverter, error) { | ||||
| 	switch typ.Kind() { | ||||
| 	case reflect.Interface: | ||||
| 		if typ.NumMethod() != 0 { | ||||
| 			return nil, errors.New("the only supported interface type is interface{}") | ||||
| 		} | ||||
| 		return callbackArgGeneric, nil | ||||
| 	case reflect.Slice: | ||||
| 		if typ.Elem().Kind() != reflect.Uint8 { | ||||
| 			return nil, errors.New("the only supported slice type is []byte") | ||||
| 		} | ||||
| 		return callbackArgBytes, nil | ||||
| 	case reflect.String: | ||||
| 		return callbackArgString, nil | ||||
| 	case reflect.Bool: | ||||
| 		return callbackArgBool, nil | ||||
| 	case reflect.Int64: | ||||
| 		return callbackArgInt64, nil | ||||
| 	case reflect.Int8, reflect.Int16, reflect.Int32, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Int, reflect.Uint: | ||||
| 		c := callbackArgCast{callbackArgInt64, typ} | ||||
| 		return c.Run, nil | ||||
| 	case reflect.Float64: | ||||
| 		return callbackArgFloat64, nil | ||||
| 	case reflect.Float32: | ||||
| 		c := callbackArgCast{callbackArgFloat64, typ} | ||||
| 		return c.Run, nil | ||||
| 	default: | ||||
| 		return nil, fmt.Errorf("don't know how to convert to %s", typ) | ||||
| 	} | ||||
| } | ||||
|  | ||||
| func callbackConvertArgs(argv []*C.sqlite3_value, converters []callbackArgConverter, variadic callbackArgConverter) ([]reflect.Value, error) { | ||||
| 	var args []reflect.Value | ||||
|  | ||||
| 	if len(argv) < len(converters) { | ||||
| 		return nil, fmt.Errorf("function requires at least %d arguments", len(converters)) | ||||
| 	} | ||||
|  | ||||
| 	for i, arg := range argv[:len(converters)] { | ||||
| 		v, err := converters[i](arg) | ||||
| 		if err != nil { | ||||
| 			return nil, err | ||||
| 		} | ||||
| 		args = append(args, v) | ||||
| 	} | ||||
|  | ||||
| 	if variadic != nil { | ||||
| 		for _, arg := range argv[len(converters):] { | ||||
| 			v, err := variadic(arg) | ||||
| 			if err != nil { | ||||
| 				return nil, err | ||||
| 			} | ||||
| 			args = append(args, v) | ||||
| 		} | ||||
| 	} | ||||
| 	return args, nil | ||||
| } | ||||
|  | ||||
| type callbackRetConverter func(*C.sqlite3_context, reflect.Value) error | ||||
|  | ||||
| func callbackRetInteger(ctx *C.sqlite3_context, v reflect.Value) error { | ||||
| 	switch v.Type().Kind() { | ||||
| 	case reflect.Int64: | ||||
| 	case reflect.Int8, reflect.Int16, reflect.Int32, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Int, reflect.Uint: | ||||
| 		v = v.Convert(reflect.TypeOf(int64(0))) | ||||
| 	case reflect.Bool: | ||||
| 		b := v.Interface().(bool) | ||||
| 		if b { | ||||
| 			v = reflect.ValueOf(int64(1)) | ||||
| 		} else { | ||||
| 			v = reflect.ValueOf(int64(0)) | ||||
| 		} | ||||
| 	default: | ||||
| 		return fmt.Errorf("cannot convert %s to INTEGER", v.Type()) | ||||
| 	} | ||||
|  | ||||
| 	C.sqlite3_result_int64(ctx, C.sqlite3_int64(v.Interface().(int64))) | ||||
| 	return nil | ||||
| } | ||||
|  | ||||
| func callbackRetFloat(ctx *C.sqlite3_context, v reflect.Value) error { | ||||
| 	switch v.Type().Kind() { | ||||
| 	case reflect.Float64: | ||||
| 	case reflect.Float32: | ||||
| 		v = v.Convert(reflect.TypeOf(float64(0))) | ||||
| 	default: | ||||
| 		return fmt.Errorf("cannot convert %s to FLOAT", v.Type()) | ||||
| 	} | ||||
|  | ||||
| 	C.sqlite3_result_double(ctx, C.double(v.Interface().(float64))) | ||||
| 	return nil | ||||
| } | ||||
|  | ||||
| func callbackRetBlob(ctx *C.sqlite3_context, v reflect.Value) error { | ||||
| 	if v.Type().Kind() != reflect.Slice || v.Type().Elem().Kind() != reflect.Uint8 { | ||||
| 		return fmt.Errorf("cannot convert %s to BLOB", v.Type()) | ||||
| 	} | ||||
| 	i := v.Interface() | ||||
| 	if i == nil || len(i.([]byte)) == 0 { | ||||
| 		C.sqlite3_result_null(ctx) | ||||
| 	} else { | ||||
| 		bs := i.([]byte) | ||||
| 		C._sqlite3_result_blob(ctx, unsafe.Pointer(&bs[0]), C.int(len(bs))) | ||||
| 	} | ||||
| 	return nil | ||||
| } | ||||
|  | ||||
| func callbackRetText(ctx *C.sqlite3_context, v reflect.Value) error { | ||||
| 	if v.Type().Kind() != reflect.String { | ||||
| 		return fmt.Errorf("cannot convert %s to TEXT", v.Type()) | ||||
| 	} | ||||
| 	C._sqlite3_result_text(ctx, C.CString(v.Interface().(string))) | ||||
| 	return nil | ||||
| } | ||||
|  | ||||
| func callbackRet(typ reflect.Type) (callbackRetConverter, error) { | ||||
| 	switch typ.Kind() { | ||||
| 	case reflect.Slice: | ||||
| 		if typ.Elem().Kind() != reflect.Uint8 { | ||||
| 			return nil, errors.New("the only supported slice type is []byte") | ||||
| 		} | ||||
| 		return callbackRetBlob, nil | ||||
| 	case reflect.String: | ||||
| 		return callbackRetText, nil | ||||
| 	case reflect.Bool, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Int, reflect.Uint: | ||||
| 		return callbackRetInteger, nil | ||||
| 	case reflect.Float32, reflect.Float64: | ||||
| 		return callbackRetFloat, nil | ||||
| 	default: | ||||
| 		return nil, fmt.Errorf("don't know how to convert to %s", typ) | ||||
| 	} | ||||
| } | ||||
|  | ||||
| func callbackError(ctx *C.sqlite3_context, err error) { | ||||
| 	cstr := C.CString(err.Error()) | ||||
| 	defer C.free(unsafe.Pointer(cstr)) | ||||
| 	C.sqlite3_result_error(ctx, cstr, -1) | ||||
| } | ||||
|  | ||||
| // Test support code. Tests are not allowed to import "C", so we can't | ||||
| // declare any functions that use C.sqlite3_value. | ||||
| func callbackSyntheticForTests(v reflect.Value, err error) callbackArgConverter { | ||||
| 	return func(*C.sqlite3_value) (reflect.Value, error) { | ||||
| 		return v, err | ||||
| 	} | ||||
| } | ||||
							
								
								
									
										114
									
								
								vendor/github.com/mattn/go-sqlite3/doc.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										114
									
								
								vendor/github.com/mattn/go-sqlite3/doc.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,114 @@ | ||||
| /* | ||||
| Package sqlite3 provides interface to SQLite3 databases. | ||||
|  | ||||
| This works as a driver for database/sql. | ||||
|  | ||||
| Installation | ||||
|  | ||||
|     go get github.com/mattn/go-sqlite3 | ||||
|  | ||||
| Supported Types | ||||
|  | ||||
| Currently, go-sqlite3 supports the following data types. | ||||
|  | ||||
|     +------------------------------+ | ||||
|     |go        | sqlite3           | | ||||
|     |----------|-------------------| | ||||
|     |nil       | null              | | ||||
|     |int       | integer           | | ||||
|     |int64     | integer           | | ||||
|     |float64   | float             | | ||||
|     |bool      | integer           | | ||||
|     |[]byte    | blob              | | ||||
|     |string    | text              | | ||||
|     |time.Time | timestamp/datetime| | ||||
|     +------------------------------+ | ||||
|  | ||||
| SQLite3 Extension | ||||
|  | ||||
| You can write your own extension module for sqlite3. For example, below is an | ||||
| extension for a Regexp matcher operation. | ||||
|  | ||||
|     #include <pcre.h> | ||||
|     #include <string.h> | ||||
|     #include <stdio.h> | ||||
|     #include <sqlite3ext.h> | ||||
|  | ||||
|     SQLITE_EXTENSION_INIT1 | ||||
|     static void regexp_func(sqlite3_context *context, int argc, sqlite3_value **argv) { | ||||
|       if (argc >= 2) { | ||||
|         const char *target  = (const char *)sqlite3_value_text(argv[1]); | ||||
|         const char *pattern = (const char *)sqlite3_value_text(argv[0]); | ||||
|         const char* errstr = NULL; | ||||
|         int erroff = 0; | ||||
|         int vec[500]; | ||||
|         int n, rc; | ||||
|         pcre* re = pcre_compile(pattern, 0, &errstr, &erroff, NULL); | ||||
|         rc = pcre_exec(re, NULL, target, strlen(target), 0, 0, vec, 500); | ||||
|         if (rc <= 0) { | ||||
|           sqlite3_result_error(context, errstr, 0); | ||||
|           return; | ||||
|         } | ||||
|         sqlite3_result_int(context, 1); | ||||
|       } | ||||
|     } | ||||
|  | ||||
|     #ifdef _WIN32 | ||||
|     __declspec(dllexport) | ||||
|     #endif | ||||
|     int sqlite3_extension_init(sqlite3 *db, char **errmsg, | ||||
|           const sqlite3_api_routines *api) { | ||||
|       SQLITE_EXTENSION_INIT2(api); | ||||
|       return sqlite3_create_function(db, "regexp", 2, SQLITE_UTF8, | ||||
|           (void*)db, regexp_func, NULL, NULL); | ||||
|     } | ||||
|  | ||||
| It needs to be built as a so/dll shared library. And you need to register | ||||
| the extension module like below. | ||||
|  | ||||
| 	sql.Register("sqlite3_with_extensions", | ||||
| 		&sqlite3.SQLiteDriver{ | ||||
| 			Extensions: []string{ | ||||
| 				"sqlite3_mod_regexp", | ||||
| 			}, | ||||
| 		}) | ||||
|  | ||||
| Then, you can use this extension. | ||||
|  | ||||
| 	rows, err := db.Query("select text from mytable where name regexp '^golang'") | ||||
|  | ||||
| Connection Hook | ||||
|  | ||||
| You can hook and inject your code when the connection is established. database/sql | ||||
| doesn't provide a way to get native go-sqlite3 interfaces. So if you want, | ||||
| you need to set ConnectHook and get the SQLiteConn. | ||||
|  | ||||
| 	sql.Register("sqlite3_with_hook_example", | ||||
| 			&sqlite3.SQLiteDriver{ | ||||
| 					ConnectHook: func(conn *sqlite3.SQLiteConn) error { | ||||
| 						sqlite3conn = append(sqlite3conn, conn) | ||||
| 						return nil | ||||
| 					}, | ||||
| 			}) | ||||
|  | ||||
| Go SQlite3 Extensions | ||||
|  | ||||
| If you want to register Go functions as SQLite extension functions, | ||||
| call RegisterFunction from ConnectHook. | ||||
|  | ||||
| 	regex = func(re, s string) (bool, error) { | ||||
| 		return regexp.MatchString(re, s) | ||||
| 	} | ||||
| 	sql.Register("sqlite3_with_go_func", | ||||
| 			&sqlite3.SQLiteDriver{ | ||||
| 					ConnectHook: func(conn *sqlite3.SQLiteConn) error { | ||||
| 						return conn.RegisterFunc("regexp", regex, true) | ||||
| 					}, | ||||
| 			}) | ||||
|  | ||||
| See the documentation of RegisterFunc for more details. | ||||
|  | ||||
| */ | ||||
| package sqlite3 | ||||
|  | ||||
| import "C" | ||||
							
								
								
									
										128
									
								
								vendor/github.com/mattn/go-sqlite3/error.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										128
									
								
								vendor/github.com/mattn/go-sqlite3/error.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,128 @@ | ||||
| // 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 | ||||
|  | ||||
| import "C" | ||||
|  | ||||
| type ErrNo int | ||||
|  | ||||
| const ErrNoMask C.int = 0xff | ||||
|  | ||||
| type ErrNoExtended int | ||||
|  | ||||
| type Error struct { | ||||
| 	Code         ErrNo         /* The error code returned by SQLite */ | ||||
| 	ExtendedCode ErrNoExtended /* The extended error code returned by SQLite */ | ||||
| 	err          string        /* The error string returned by sqlite3_errmsg(), | ||||
| 	this usually contains more specific details. */ | ||||
| } | ||||
|  | ||||
| // result codes from http://www.sqlite.org/c3ref/c_abort.html | ||||
| var ( | ||||
| 	ErrError      = ErrNo(1)  /* SQL error or missing database */ | ||||
| 	ErrInternal   = ErrNo(2)  /* Internal logic error in SQLite */ | ||||
| 	ErrPerm       = ErrNo(3)  /* Access permission denied */ | ||||
| 	ErrAbort      = ErrNo(4)  /* Callback routine requested an abort */ | ||||
| 	ErrBusy       = ErrNo(5)  /* The database file is locked */ | ||||
| 	ErrLocked     = ErrNo(6)  /* A table in the database is locked */ | ||||
| 	ErrNomem      = ErrNo(7)  /* A malloc() failed */ | ||||
| 	ErrReadonly   = ErrNo(8)  /* Attempt to write a readonly database */ | ||||
| 	ErrInterrupt  = ErrNo(9)  /* Operation terminated by sqlite3_interrupt() */ | ||||
| 	ErrIoErr      = ErrNo(10) /* Some kind of disk I/O error occurred */ | ||||
| 	ErrCorrupt    = ErrNo(11) /* The database disk image is malformed */ | ||||
| 	ErrNotFound   = ErrNo(12) /* Unknown opcode in sqlite3_file_control() */ | ||||
| 	ErrFull       = ErrNo(13) /* Insertion failed because database is full */ | ||||
| 	ErrCantOpen   = ErrNo(14) /* Unable to open the database file */ | ||||
| 	ErrProtocol   = ErrNo(15) /* Database lock protocol error */ | ||||
| 	ErrEmpty      = ErrNo(16) /* Database is empty */ | ||||
| 	ErrSchema     = ErrNo(17) /* The database schema changed */ | ||||
| 	ErrTooBig     = ErrNo(18) /* String or BLOB exceeds size limit */ | ||||
| 	ErrConstraint = ErrNo(19) /* Abort due to constraint violation */ | ||||
| 	ErrMismatch   = ErrNo(20) /* Data type mismatch */ | ||||
| 	ErrMisuse     = ErrNo(21) /* Library used incorrectly */ | ||||
| 	ErrNoLFS      = ErrNo(22) /* Uses OS features not supported on host */ | ||||
| 	ErrAuth       = ErrNo(23) /* Authorization denied */ | ||||
| 	ErrFormat     = ErrNo(24) /* Auxiliary database format error */ | ||||
| 	ErrRange      = ErrNo(25) /* 2nd parameter to sqlite3_bind out of range */ | ||||
| 	ErrNotADB     = ErrNo(26) /* File opened that is not a database file */ | ||||
| 	ErrNotice     = ErrNo(27) /* Notifications from sqlite3_log() */ | ||||
| 	ErrWarning    = ErrNo(28) /* Warnings from sqlite3_log() */ | ||||
| ) | ||||
|  | ||||
| func (err ErrNo) Error() string { | ||||
| 	return Error{Code: err}.Error() | ||||
| } | ||||
|  | ||||
| func (err ErrNo) Extend(by int) ErrNoExtended { | ||||
| 	return ErrNoExtended(int(err) | (by << 8)) | ||||
| } | ||||
|  | ||||
| func (err ErrNoExtended) Error() string { | ||||
| 	return Error{Code: ErrNo(C.int(err) & ErrNoMask), ExtendedCode: err}.Error() | ||||
| } | ||||
|  | ||||
| func (err Error) Error() string { | ||||
| 	if err.err != "" { | ||||
| 		return err.err | ||||
| 	} | ||||
| 	return errorString(err) | ||||
| } | ||||
|  | ||||
| // result codes from http://www.sqlite.org/c3ref/c_abort_rollback.html | ||||
| var ( | ||||
| 	ErrIoErrRead              = ErrIoErr.Extend(1) | ||||
| 	ErrIoErrShortRead         = ErrIoErr.Extend(2) | ||||
| 	ErrIoErrWrite             = ErrIoErr.Extend(3) | ||||
| 	ErrIoErrFsync             = ErrIoErr.Extend(4) | ||||
| 	ErrIoErrDirFsync          = ErrIoErr.Extend(5) | ||||
| 	ErrIoErrTruncate          = ErrIoErr.Extend(6) | ||||
| 	ErrIoErrFstat             = ErrIoErr.Extend(7) | ||||
| 	ErrIoErrUnlock            = ErrIoErr.Extend(8) | ||||
| 	ErrIoErrRDlock            = ErrIoErr.Extend(9) | ||||
| 	ErrIoErrDelete            = ErrIoErr.Extend(10) | ||||
| 	ErrIoErrBlocked           = ErrIoErr.Extend(11) | ||||
| 	ErrIoErrNoMem             = ErrIoErr.Extend(12) | ||||
| 	ErrIoErrAccess            = ErrIoErr.Extend(13) | ||||
| 	ErrIoErrCheckReservedLock = ErrIoErr.Extend(14) | ||||
| 	ErrIoErrLock              = ErrIoErr.Extend(15) | ||||
| 	ErrIoErrClose             = ErrIoErr.Extend(16) | ||||
| 	ErrIoErrDirClose          = ErrIoErr.Extend(17) | ||||
| 	ErrIoErrSHMOpen           = ErrIoErr.Extend(18) | ||||
| 	ErrIoErrSHMSize           = ErrIoErr.Extend(19) | ||||
| 	ErrIoErrSHMLock           = ErrIoErr.Extend(20) | ||||
| 	ErrIoErrSHMMap            = ErrIoErr.Extend(21) | ||||
| 	ErrIoErrSeek              = ErrIoErr.Extend(22) | ||||
| 	ErrIoErrDeleteNoent       = ErrIoErr.Extend(23) | ||||
| 	ErrIoErrMMap              = ErrIoErr.Extend(24) | ||||
| 	ErrIoErrGetTempPath       = ErrIoErr.Extend(25) | ||||
| 	ErrIoErrConvPath          = ErrIoErr.Extend(26) | ||||
| 	ErrLockedSharedCache      = ErrLocked.Extend(1) | ||||
| 	ErrBusyRecovery           = ErrBusy.Extend(1) | ||||
| 	ErrBusySnapshot           = ErrBusy.Extend(2) | ||||
| 	ErrCantOpenNoTempDir      = ErrCantOpen.Extend(1) | ||||
| 	ErrCantOpenIsDir          = ErrCantOpen.Extend(2) | ||||
| 	ErrCantOpenFullPath       = ErrCantOpen.Extend(3) | ||||
| 	ErrCantOpenConvPath       = ErrCantOpen.Extend(4) | ||||
| 	ErrCorruptVTab            = ErrCorrupt.Extend(1) | ||||
| 	ErrReadonlyRecovery       = ErrReadonly.Extend(1) | ||||
| 	ErrReadonlyCantLock       = ErrReadonly.Extend(2) | ||||
| 	ErrReadonlyRollback       = ErrReadonly.Extend(3) | ||||
| 	ErrReadonlyDbMoved        = ErrReadonly.Extend(4) | ||||
| 	ErrAbortRollback          = ErrAbort.Extend(2) | ||||
| 	ErrConstraintCheck        = ErrConstraint.Extend(1) | ||||
| 	ErrConstraintCommitHook   = ErrConstraint.Extend(2) | ||||
| 	ErrConstraintForeignKey   = ErrConstraint.Extend(3) | ||||
| 	ErrConstraintFunction     = ErrConstraint.Extend(4) | ||||
| 	ErrConstraintNotNull      = ErrConstraint.Extend(5) | ||||
| 	ErrConstraintPrimaryKey   = ErrConstraint.Extend(6) | ||||
| 	ErrConstraintTrigger      = ErrConstraint.Extend(7) | ||||
| 	ErrConstraintUnique       = ErrConstraint.Extend(8) | ||||
| 	ErrConstraintVTab         = ErrConstraint.Extend(9) | ||||
| 	ErrConstraintRowId        = ErrConstraint.Extend(10) | ||||
| 	ErrNoticeRecoverWAL       = ErrNotice.Extend(1) | ||||
| 	ErrNoticeRecoverRollback  = ErrNotice.Extend(2) | ||||
| 	ErrWarningAutoIndex       = ErrWarning.Extend(1) | ||||
| ) | ||||
							
								
								
									
										197855
									
								
								vendor/github.com/mattn/go-sqlite3/sqlite3-binding.c
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										197855
									
								
								vendor/github.com/mattn/go-sqlite3/sqlite3-binding.c
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
							
								
								
									
										10347
									
								
								vendor/github.com/mattn/go-sqlite3/sqlite3-binding.h
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										10347
									
								
								vendor/github.com/mattn/go-sqlite3/sqlite3-binding.h
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
							
								
								
									
										887
									
								
								vendor/github.com/mattn/go-sqlite3/sqlite3.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										887
									
								
								vendor/github.com/mattn/go-sqlite3/sqlite3.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,887 @@ | ||||
| // 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 | ||||
|  | ||||
| /* | ||||
| #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: -Wno-deprecated-declarations | ||||
| #ifndef USE_LIBSQLITE3 | ||||
| #include <sqlite3-binding.h> | ||||
| #else | ||||
| #include <sqlite3.h> | ||||
| #endif | ||||
| #include <stdlib.h> | ||||
| #include <string.h> | ||||
|  | ||||
| #ifdef __CYGWIN__ | ||||
| # include <errno.h> | ||||
| #endif | ||||
|  | ||||
| #ifndef SQLITE_OPEN_READWRITE | ||||
| # define SQLITE_OPEN_READWRITE 0 | ||||
| #endif | ||||
|  | ||||
| #ifndef SQLITE_OPEN_FULLMUTEX | ||||
| # define SQLITE_OPEN_FULLMUTEX 0 | ||||
| #endif | ||||
|  | ||||
| #ifndef SQLITE_DETERMINISTIC | ||||
| # define SQLITE_DETERMINISTIC 0 | ||||
| #endif | ||||
|  | ||||
| static int | ||||
| _sqlite3_open_v2(const char *filename, sqlite3 **ppDb, int flags, const char *zVfs) { | ||||
| #ifdef SQLITE_OPEN_URI | ||||
|   return sqlite3_open_v2(filename, ppDb, flags | SQLITE_OPEN_URI, zVfs); | ||||
| #else | ||||
|   return sqlite3_open_v2(filename, ppDb, flags, zVfs); | ||||
| #endif | ||||
| } | ||||
|  | ||||
| static int | ||||
| _sqlite3_bind_text(sqlite3_stmt *stmt, int n, char *p, int np) { | ||||
|   return sqlite3_bind_text(stmt, n, p, np, SQLITE_TRANSIENT); | ||||
| } | ||||
|  | ||||
| static int | ||||
| _sqlite3_bind_blob(sqlite3_stmt *stmt, int n, void *p, int np) { | ||||
|   return sqlite3_bind_blob(stmt, n, p, np, SQLITE_TRANSIENT); | ||||
| } | ||||
|  | ||||
| #include <stdio.h> | ||||
| #include <stdint.h> | ||||
|  | ||||
| static int | ||||
| _sqlite3_exec(sqlite3* db, const char* pcmd, long long* rowid, long long* changes) | ||||
| { | ||||
|   int rv = sqlite3_exec(db, pcmd, 0, 0, 0); | ||||
|   *rowid = (long long) sqlite3_last_insert_rowid(db); | ||||
|   *changes = (long long) sqlite3_changes(db); | ||||
|   return rv; | ||||
| } | ||||
|  | ||||
| static int | ||||
| _sqlite3_step(sqlite3_stmt* stmt, long long* rowid, long long* changes) | ||||
| { | ||||
|   int rv = sqlite3_step(stmt); | ||||
|   sqlite3* db = sqlite3_db_handle(stmt); | ||||
|   *rowid = (long long) sqlite3_last_insert_rowid(db); | ||||
|   *changes = (long long) sqlite3_changes(db); | ||||
|   return rv; | ||||
| } | ||||
|  | ||||
| void _sqlite3_result_text(sqlite3_context* ctx, const char* s) { | ||||
|   sqlite3_result_text(ctx, s, -1, &free); | ||||
| } | ||||
|  | ||||
| void _sqlite3_result_blob(sqlite3_context* ctx, const void* b, int l) { | ||||
|   sqlite3_result_blob(ctx, b, l, SQLITE_TRANSIENT); | ||||
| } | ||||
|  | ||||
|  | ||||
| int _sqlite3_create_function( | ||||
|   sqlite3 *db, | ||||
|   const char *zFunctionName, | ||||
|   int nArg, | ||||
|   int eTextRep, | ||||
|   uintptr_t pApp, | ||||
|   void (*xFunc)(sqlite3_context*,int,sqlite3_value**), | ||||
|   void (*xStep)(sqlite3_context*,int,sqlite3_value**), | ||||
|   void (*xFinal)(sqlite3_context*) | ||||
| ) { | ||||
|   return sqlite3_create_function(db, zFunctionName, nArg, eTextRep, (void*) pApp, xFunc, xStep, xFinal); | ||||
| } | ||||
|  | ||||
| void callbackTrampoline(sqlite3_context*, int, sqlite3_value**); | ||||
| */ | ||||
| import "C" | ||||
| import ( | ||||
| 	"database/sql" | ||||
| 	"database/sql/driver" | ||||
| 	"errors" | ||||
| 	"fmt" | ||||
| 	"io" | ||||
| 	"net/url" | ||||
| 	"reflect" | ||||
| 	"runtime" | ||||
| 	"strconv" | ||||
| 	"strings" | ||||
| 	"time" | ||||
| 	"unsafe" | ||||
| ) | ||||
|  | ||||
| // Timestamp formats understood by both this module and SQLite. | ||||
| // The first format in the slice will be used when saving time values | ||||
| // into the database. When parsing a string from a timestamp or | ||||
| // datetime column, the formats are tried in order. | ||||
| var SQLiteTimestampFormats = []string{ | ||||
| 	// By default, store timestamps with whatever timezone they come with. | ||||
| 	// When parsed, they will be returned with the same timezone. | ||||
| 	"2006-01-02 15:04:05.999999999-07:00", | ||||
| 	"2006-01-02T15:04:05.999999999-07:00", | ||||
| 	"2006-01-02 15:04:05.999999999", | ||||
| 	"2006-01-02T15:04:05.999999999", | ||||
| 	"2006-01-02 15:04:05", | ||||
| 	"2006-01-02T15:04:05", | ||||
| 	"2006-01-02 15:04", | ||||
| 	"2006-01-02T15:04", | ||||
| 	"2006-01-02", | ||||
| } | ||||
|  | ||||
| func init() { | ||||
| 	sql.Register("sqlite3", &SQLiteDriver{}) | ||||
| } | ||||
|  | ||||
| // Version returns SQLite library version information. | ||||
| func Version() (libVersion string, libVersionNumber int, sourceId string) { | ||||
| 	libVersion = C.GoString(C.sqlite3_libversion()) | ||||
| 	libVersionNumber = int(C.sqlite3_libversion_number()) | ||||
| 	sourceId = C.GoString(C.sqlite3_sourceid()) | ||||
| 	return libVersion, libVersionNumber, sourceId | ||||
| } | ||||
|  | ||||
| // Driver struct. | ||||
| type SQLiteDriver struct { | ||||
| 	Extensions  []string | ||||
| 	ConnectHook func(*SQLiteConn) error | ||||
| } | ||||
|  | ||||
| // Conn struct. | ||||
| type SQLiteConn struct { | ||||
| 	db          *C.sqlite3 | ||||
| 	loc         *time.Location | ||||
| 	txlock      string | ||||
| 	funcs       []*functionInfo | ||||
| 	aggregators []*aggInfo | ||||
| } | ||||
|  | ||||
| // Tx struct. | ||||
| type SQLiteTx struct { | ||||
| 	c *SQLiteConn | ||||
| } | ||||
|  | ||||
| // Stmt struct. | ||||
| type SQLiteStmt struct { | ||||
| 	c      *SQLiteConn | ||||
| 	s      *C.sqlite3_stmt | ||||
| 	nv     int | ||||
| 	nn     []string | ||||
| 	t      string | ||||
| 	closed bool | ||||
| 	cls    bool | ||||
| } | ||||
|  | ||||
| // Result struct. | ||||
| type SQLiteResult struct { | ||||
| 	id      int64 | ||||
| 	changes int64 | ||||
| } | ||||
|  | ||||
| // Rows struct. | ||||
| type SQLiteRows struct { | ||||
| 	s        *SQLiteStmt | ||||
| 	nc       int | ||||
| 	cols     []string | ||||
| 	decltype []string | ||||
| 	cls      bool | ||||
| } | ||||
|  | ||||
| type functionInfo struct { | ||||
| 	f                 reflect.Value | ||||
| 	argConverters     []callbackArgConverter | ||||
| 	variadicConverter callbackArgConverter | ||||
| 	retConverter      callbackRetConverter | ||||
| } | ||||
|  | ||||
| func (fi *functionInfo) Call(ctx *C.sqlite3_context, argv []*C.sqlite3_value) { | ||||
| 	args, err := callbackConvertArgs(argv, fi.argConverters, fi.variadicConverter) | ||||
| 	if err != nil { | ||||
| 		callbackError(ctx, err) | ||||
| 		return | ||||
| 	} | ||||
|  | ||||
| 	ret := fi.f.Call(args) | ||||
|  | ||||
| 	if len(ret) == 2 && ret[1].Interface() != nil { | ||||
| 		callbackError(ctx, ret[1].Interface().(error)) | ||||
| 		return | ||||
| 	} | ||||
|  | ||||
| 	err = fi.retConverter(ctx, ret[0]) | ||||
| 	if err != nil { | ||||
| 		callbackError(ctx, err) | ||||
| 		return | ||||
| 	} | ||||
| } | ||||
|  | ||||
| type aggInfo struct { | ||||
| 	constructor reflect.Value | ||||
|  | ||||
| 	// Active aggregator objects for aggregations in flight. The | ||||
| 	// aggregators are indexed by a counter stored in the aggregation | ||||
| 	// user data space provided by sqlite. | ||||
| 	active map[int64]reflect.Value | ||||
| 	next   int64 | ||||
|  | ||||
| 	stepArgConverters     []callbackArgConverter | ||||
| 	stepVariadicConverter callbackArgConverter | ||||
|  | ||||
| 	doneRetConverter callbackRetConverter | ||||
| } | ||||
|  | ||||
| func (ai *aggInfo) agg(ctx *C.sqlite3_context) (int64, reflect.Value, error) { | ||||
| 	aggIdx := (*int64)(C.sqlite3_aggregate_context(ctx, C.int(8))) | ||||
| 	if *aggIdx == 0 { | ||||
| 		*aggIdx = ai.next | ||||
| 		ret := ai.constructor.Call(nil) | ||||
| 		if len(ret) == 2 && ret[1].Interface() != nil { | ||||
| 			return 0, reflect.Value{}, ret[1].Interface().(error) | ||||
| 		} | ||||
| 		if ret[0].IsNil() { | ||||
| 			return 0, reflect.Value{}, errors.New("aggregator constructor returned nil state") | ||||
| 		} | ||||
| 		ai.next++ | ||||
| 		ai.active[*aggIdx] = ret[0] | ||||
| 	} | ||||
| 	return *aggIdx, ai.active[*aggIdx], nil | ||||
| } | ||||
|  | ||||
| func (ai *aggInfo) Step(ctx *C.sqlite3_context, argv []*C.sqlite3_value) { | ||||
| 	_, agg, err := ai.agg(ctx) | ||||
| 	if err != nil { | ||||
| 		callbackError(ctx, err) | ||||
| 		return | ||||
| 	} | ||||
|  | ||||
| 	args, err := callbackConvertArgs(argv, ai.stepArgConverters, ai.stepVariadicConverter) | ||||
| 	if err != nil { | ||||
| 		callbackError(ctx, err) | ||||
| 		return | ||||
| 	} | ||||
|  | ||||
| 	ret := agg.MethodByName("Step").Call(args) | ||||
| 	if len(ret) == 1 && ret[0].Interface() != nil { | ||||
| 		callbackError(ctx, ret[0].Interface().(error)) | ||||
| 		return | ||||
| 	} | ||||
| } | ||||
|  | ||||
| func (ai *aggInfo) Done(ctx *C.sqlite3_context) { | ||||
| 	idx, agg, err := ai.agg(ctx) | ||||
| 	if err != nil { | ||||
| 		callbackError(ctx, err) | ||||
| 		return | ||||
| 	} | ||||
| 	defer func() { delete(ai.active, idx) }() | ||||
|  | ||||
| 	ret := agg.MethodByName("Done").Call(nil) | ||||
| 	if len(ret) == 2 && ret[1].Interface() != nil { | ||||
| 		callbackError(ctx, ret[1].Interface().(error)) | ||||
| 		return | ||||
| 	} | ||||
|  | ||||
| 	err = ai.doneRetConverter(ctx, ret[0]) | ||||
| 	if err != nil { | ||||
| 		callbackError(ctx, err) | ||||
| 		return | ||||
| 	} | ||||
| } | ||||
|  | ||||
| // Commit transaction. | ||||
| func (tx *SQLiteTx) Commit() error { | ||||
| 	_, err := tx.c.exec("COMMIT") | ||||
| 	if err != nil && err.(Error).Code == C.SQLITE_BUSY { | ||||
| 		// sqlite3 will leave the transaction open in this scenario. | ||||
| 		// However, database/sql considers the transaction complete once we | ||||
| 		// return from Commit() - we must clean up to honour its semantics. | ||||
| 		tx.c.exec("ROLLBACK") | ||||
| 	} | ||||
| 	return err | ||||
| } | ||||
|  | ||||
| // Rollback transaction. | ||||
| func (tx *SQLiteTx) Rollback() error { | ||||
| 	_, err := tx.c.exec("ROLLBACK") | ||||
| 	return err | ||||
| } | ||||
|  | ||||
| // RegisterFunc makes a Go function available as a SQLite function. | ||||
| // | ||||
| // The Go function can have arguments of the following types: any | ||||
| // numeric type except complex, bool, []byte, string and | ||||
| // interface{}. interface{} arguments are given the direct translation | ||||
| // of the SQLite data type: int64 for INTEGER, float64 for FLOAT, | ||||
| // []byte for BLOB, string for TEXT. | ||||
| // | ||||
| // The function can additionally be variadic, as long as the type of | ||||
| // the variadic argument is one of the above. | ||||
| // | ||||
| // If pure is true. SQLite will assume that the function's return | ||||
| // value depends only on its inputs, and make more aggressive | ||||
| // optimizations in its queries. | ||||
| // | ||||
| // See _example/go_custom_funcs for a detailed example. | ||||
| func (c *SQLiteConn) RegisterFunc(name string, impl interface{}, pure bool) error { | ||||
| 	var fi functionInfo | ||||
| 	fi.f = reflect.ValueOf(impl) | ||||
| 	t := fi.f.Type() | ||||
| 	if t.Kind() != reflect.Func { | ||||
| 		return errors.New("Non-function passed to RegisterFunc") | ||||
| 	} | ||||
| 	if t.NumOut() != 1 && t.NumOut() != 2 { | ||||
| 		return errors.New("SQLite functions must return 1 or 2 values") | ||||
| 	} | ||||
| 	if t.NumOut() == 2 && !t.Out(1).Implements(reflect.TypeOf((*error)(nil)).Elem()) { | ||||
| 		return errors.New("Second return value of SQLite function must be error") | ||||
| 	} | ||||
|  | ||||
| 	numArgs := t.NumIn() | ||||
| 	if t.IsVariadic() { | ||||
| 		numArgs-- | ||||
| 	} | ||||
|  | ||||
| 	for i := 0; i < numArgs; i++ { | ||||
| 		conv, err := callbackArg(t.In(i)) | ||||
| 		if err != nil { | ||||
| 			return err | ||||
| 		} | ||||
| 		fi.argConverters = append(fi.argConverters, conv) | ||||
| 	} | ||||
|  | ||||
| 	if t.IsVariadic() { | ||||
| 		conv, err := callbackArg(t.In(numArgs).Elem()) | ||||
| 		if err != nil { | ||||
| 			return err | ||||
| 		} | ||||
| 		fi.variadicConverter = conv | ||||
| 		// Pass -1 to sqlite so that it allows any number of | ||||
| 		// arguments. The call helper verifies that the minimum number | ||||
| 		// of arguments is present for variadic functions. | ||||
| 		numArgs = -1 | ||||
| 	} | ||||
|  | ||||
| 	conv, err := callbackRet(t.Out(0)) | ||||
| 	if err != nil { | ||||
| 		return err | ||||
| 	} | ||||
| 	fi.retConverter = conv | ||||
|  | ||||
| 	// fi must outlast the database connection, or we'll have dangling pointers. | ||||
| 	c.funcs = append(c.funcs, &fi) | ||||
|  | ||||
| 	cname := C.CString(name) | ||||
| 	defer C.free(unsafe.Pointer(cname)) | ||||
| 	opts := C.SQLITE_UTF8 | ||||
| 	if pure { | ||||
| 		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) | ||||
| 	if rv != C.SQLITE_OK { | ||||
| 		return c.lastError() | ||||
| 	} | ||||
| 	return nil | ||||
| } | ||||
|  | ||||
| // AutoCommit return which currently auto commit or not. | ||||
| func (c *SQLiteConn) AutoCommit() bool { | ||||
| 	return int(C.sqlite3_get_autocommit(c.db)) != 0 | ||||
| } | ||||
|  | ||||
| func (c *SQLiteConn) lastError() Error { | ||||
| 	return Error{ | ||||
| 		Code:         ErrNo(C.sqlite3_errcode(c.db)), | ||||
| 		ExtendedCode: ErrNoExtended(C.sqlite3_extended_errcode(c.db)), | ||||
| 		err:          C.GoString(C.sqlite3_errmsg(c.db)), | ||||
| 	} | ||||
| } | ||||
|  | ||||
| // Implements Execer | ||||
| func (c *SQLiteConn) Exec(query string, args []driver.Value) (driver.Result, error) { | ||||
| 	if len(args) == 0 { | ||||
| 		return c.exec(query) | ||||
| 	} | ||||
|  | ||||
| 	for { | ||||
| 		s, err := c.Prepare(query) | ||||
| 		if err != nil { | ||||
| 			return nil, err | ||||
| 		} | ||||
| 		var res driver.Result | ||||
| 		if s.(*SQLiteStmt).s != nil { | ||||
| 			na := s.NumInput() | ||||
| 			if len(args) < na { | ||||
| 				return nil, fmt.Errorf("Not enough args to execute query. Expected %d, got %d.", na, len(args)) | ||||
| 			} | ||||
| 			res, err = s.Exec(args[:na]) | ||||
| 			if err != nil && err != driver.ErrSkip { | ||||
| 				s.Close() | ||||
| 				return nil, err | ||||
| 			} | ||||
| 			args = args[na:] | ||||
| 		} | ||||
| 		tail := s.(*SQLiteStmt).t | ||||
| 		s.Close() | ||||
| 		if tail == "" { | ||||
| 			return res, nil | ||||
| 		} | ||||
| 		query = tail | ||||
| 	} | ||||
| } | ||||
|  | ||||
| // Implements Queryer | ||||
| func (c *SQLiteConn) Query(query string, args []driver.Value) (driver.Rows, error) { | ||||
| 	for { | ||||
| 		s, err := c.Prepare(query) | ||||
| 		if err != nil { | ||||
| 			return nil, err | ||||
| 		} | ||||
| 		s.(*SQLiteStmt).cls = true | ||||
| 		na := s.NumInput() | ||||
| 		if len(args) < na { | ||||
| 			return nil, fmt.Errorf("Not enough args to execute query. Expected %d, got %d.", na, len(args)) | ||||
| 		} | ||||
| 		rows, err := s.Query(args[:na]) | ||||
| 		if err != nil && err != driver.ErrSkip { | ||||
| 			s.Close() | ||||
| 			return nil, err | ||||
| 		} | ||||
| 		args = args[na:] | ||||
| 		tail := s.(*SQLiteStmt).t | ||||
| 		if tail == "" { | ||||
| 			return rows, nil | ||||
| 		} | ||||
| 		rows.Close() | ||||
| 		s.Close() | ||||
| 		query = tail | ||||
| 	} | ||||
| } | ||||
|  | ||||
| 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. | ||||
| func (c *SQLiteConn) Begin() (driver.Tx, error) { | ||||
| 	if _, err := c.exec(c.txlock); err != nil { | ||||
| 		return nil, err | ||||
| 	} | ||||
| 	return &SQLiteTx{c}, nil | ||||
| } | ||||
|  | ||||
| func errorString(err Error) string { | ||||
| 	return C.GoString(C.sqlite3_errstr(C.int(err.Code))) | ||||
| } | ||||
|  | ||||
| // Open database and return a new connection. | ||||
| // You can specify a DSN string using a URI as the filename. | ||||
| //   test.db | ||||
| //   file:test.db?cache=shared&mode=memory | ||||
| //   :memory: | ||||
| //   file::memory: | ||||
| // go-sqlite3 adds the following query parameters to those used by SQLite: | ||||
| //   _loc=XXX | ||||
| //     Specify location of time format. It's possible to specify "auto". | ||||
| //   _busy_timeout=XXX | ||||
| //     Specify value for sqlite3_busy_timeout. | ||||
| //   _txlock=XXX | ||||
| //     Specify locking behavior for transactions.  XXX can be "immediate", | ||||
| //     "deferred", "exclusive". | ||||
| func (d *SQLiteDriver) Open(dsn string) (driver.Conn, error) { | ||||
| 	if C.sqlite3_threadsafe() == 0 { | ||||
| 		return nil, errors.New("sqlite library was not compiled for thread-safe operation") | ||||
| 	} | ||||
|  | ||||
| 	var loc *time.Location | ||||
| 	txlock := "BEGIN" | ||||
| 	busy_timeout := 5000 | ||||
| 	pos := strings.IndexRune(dsn, '?') | ||||
| 	if pos >= 1 { | ||||
| 		params, err := url.ParseQuery(dsn[pos+1:]) | ||||
| 		if err != nil { | ||||
| 			return nil, err | ||||
| 		} | ||||
|  | ||||
| 		// _loc | ||||
| 		if val := params.Get("_loc"); val != "" { | ||||
| 			if val == "auto" { | ||||
| 				loc = time.Local | ||||
| 			} else { | ||||
| 				loc, err = time.LoadLocation(val) | ||||
| 				if err != nil { | ||||
| 					return nil, fmt.Errorf("Invalid _loc: %v: %v", val, err) | ||||
| 				} | ||||
| 			} | ||||
| 		} | ||||
|  | ||||
| 		// _busy_timeout | ||||
| 		if val := params.Get("_busy_timeout"); val != "" { | ||||
| 			iv, err := strconv.ParseInt(val, 10, 64) | ||||
| 			if err != nil { | ||||
| 				return nil, fmt.Errorf("Invalid _busy_timeout: %v: %v", val, err) | ||||
| 			} | ||||
| 			busy_timeout = int(iv) | ||||
| 		} | ||||
|  | ||||
| 		// _txlock | ||||
| 		if val := params.Get("_txlock"); val != "" { | ||||
| 			switch val { | ||||
| 			case "immediate": | ||||
| 				txlock = "BEGIN IMMEDIATE" | ||||
| 			case "exclusive": | ||||
| 				txlock = "BEGIN EXCLUSIVE" | ||||
| 			case "deferred": | ||||
| 				txlock = "BEGIN" | ||||
| 			default: | ||||
| 				return nil, fmt.Errorf("Invalid _txlock: %v", val) | ||||
| 			} | ||||
| 		} | ||||
|  | ||||
| 		if !strings.HasPrefix(dsn, "file:") { | ||||
| 			dsn = dsn[:pos] | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	var db *C.sqlite3 | ||||
| 	name := C.CString(dsn) | ||||
| 	defer C.free(unsafe.Pointer(name)) | ||||
| 	rv := C._sqlite3_open_v2(name, &db, | ||||
| 		C.SQLITE_OPEN_FULLMUTEX| | ||||
| 			C.SQLITE_OPEN_READWRITE| | ||||
| 			C.SQLITE_OPEN_CREATE, | ||||
| 		nil) | ||||
| 	if rv != 0 { | ||||
| 		return nil, Error{Code: ErrNo(rv)} | ||||
| 	} | ||||
| 	if db == nil { | ||||
| 		return nil, errors.New("sqlite succeeded without returning a database") | ||||
| 	} | ||||
|  | ||||
| 	rv = C.sqlite3_busy_timeout(db, C.int(busy_timeout)) | ||||
| 	if rv != C.SQLITE_OK { | ||||
| 		return nil, Error{Code: ErrNo(rv)} | ||||
| 	} | ||||
|  | ||||
| 	conn := &SQLiteConn{db: db, loc: loc, txlock: txlock} | ||||
|  | ||||
| 	if len(d.Extensions) > 0 { | ||||
| 		if err := conn.loadExtensions(d.Extensions); err != nil { | ||||
| 			return nil, err | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	if d.ConnectHook != nil { | ||||
| 		if err := d.ConnectHook(conn); err != nil { | ||||
| 			return nil, err | ||||
| 		} | ||||
| 	} | ||||
| 	runtime.SetFinalizer(conn, (*SQLiteConn).Close) | ||||
| 	return conn, nil | ||||
| } | ||||
|  | ||||
| // Close the connection. | ||||
| func (c *SQLiteConn) Close() error { | ||||
| 	deleteHandles(c) | ||||
| 	rv := C.sqlite3_close_v2(c.db) | ||||
| 	if rv != C.SQLITE_OK { | ||||
| 		return c.lastError() | ||||
| 	} | ||||
| 	c.db = nil | ||||
| 	runtime.SetFinalizer(c, nil) | ||||
| 	return nil | ||||
| } | ||||
|  | ||||
| // Prepare the query string. Return a new statement. | ||||
| func (c *SQLiteConn) Prepare(query string) (driver.Stmt, error) { | ||||
| 	pquery := C.CString(query) | ||||
| 	defer C.free(unsafe.Pointer(pquery)) | ||||
| 	var s *C.sqlite3_stmt | ||||
| 	var tail *C.char | ||||
| 	rv := C.sqlite3_prepare_v2(c.db, pquery, -1, &s, &tail) | ||||
| 	if rv != C.SQLITE_OK { | ||||
| 		return nil, c.lastError() | ||||
| 	} | ||||
| 	var t string | ||||
| 	if tail != nil && *tail != '\000' { | ||||
| 		t = strings.TrimSpace(C.GoString(tail)) | ||||
| 	} | ||||
| 	nv := int(C.sqlite3_bind_parameter_count(s)) | ||||
| 	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) | ||||
| 	return ss, nil | ||||
| } | ||||
|  | ||||
| // Close the statement. | ||||
| func (s *SQLiteStmt) Close() error { | ||||
| 	if s.closed { | ||||
| 		return nil | ||||
| 	} | ||||
| 	s.closed = true | ||||
| 	if s.c == nil || s.c.db == nil { | ||||
| 		return errors.New("sqlite statement with already closed database connection") | ||||
| 	} | ||||
| 	rv := C.sqlite3_finalize(s.s) | ||||
| 	if rv != C.SQLITE_OK { | ||||
| 		return s.c.lastError() | ||||
| 	} | ||||
| 	runtime.SetFinalizer(s, nil) | ||||
| 	return nil | ||||
| } | ||||
|  | ||||
| // Return a number of parameters. | ||||
| func (s *SQLiteStmt) NumInput() int { | ||||
| 	return s.nv | ||||
| } | ||||
|  | ||||
| type bindArg struct { | ||||
| 	n int | ||||
| 	v driver.Value | ||||
| } | ||||
|  | ||||
| func (s *SQLiteStmt) bind(args []driver.Value) error { | ||||
| 	rv := C.sqlite3_reset(s.s) | ||||
| 	if rv != C.SQLITE_ROW && rv != C.SQLITE_OK && rv != C.SQLITE_DONE { | ||||
| 		return s.c.lastError() | ||||
| 	} | ||||
|  | ||||
| 	var vargs []bindArg | ||||
| 	narg := len(args) | ||||
| 	vargs = make([]bindArg, narg) | ||||
| 	if len(s.nn) > 0 { | ||||
| 		for i, v := range s.nn { | ||||
| 			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 { | ||||
| 		n := C.int(varg.n) | ||||
| 		v := varg.v | ||||
| 		switch v := v.(type) { | ||||
| 		case nil: | ||||
| 			rv = C.sqlite3_bind_null(s.s, n) | ||||
| 		case string: | ||||
| 			if len(v) == 0 { | ||||
| 				b := []byte{0} | ||||
| 				rv = C._sqlite3_bind_text(s.s, n, (*C.char)(unsafe.Pointer(&b[0])), C.int(0)) | ||||
| 			} else { | ||||
| 				b := []byte(v) | ||||
| 				rv = C._sqlite3_bind_text(s.s, n, (*C.char)(unsafe.Pointer(&b[0])), C.int(len(b))) | ||||
| 			} | ||||
| 		case int64: | ||||
| 			rv = C.sqlite3_bind_int64(s.s, n, C.sqlite3_int64(v)) | ||||
| 		case bool: | ||||
| 			if bool(v) { | ||||
| 				rv = C.sqlite3_bind_int(s.s, n, 1) | ||||
| 			} else { | ||||
| 				rv = C.sqlite3_bind_int(s.s, n, 0) | ||||
| 			} | ||||
| 		case float64: | ||||
| 			rv = C.sqlite3_bind_double(s.s, n, C.double(v)) | ||||
| 		case []byte: | ||||
| 			if len(v) == 0 { | ||||
| 				rv = C._sqlite3_bind_blob(s.s, n, nil, 0) | ||||
| 			} else { | ||||
| 				rv = C._sqlite3_bind_blob(s.s, n, unsafe.Pointer(&v[0]), C.int(len(v))) | ||||
| 			} | ||||
| 		case time.Time: | ||||
| 			b := []byte(v.Format(SQLiteTimestampFormats[0])) | ||||
| 			rv = C._sqlite3_bind_text(s.s, n, (*C.char)(unsafe.Pointer(&b[0])), C.int(len(b))) | ||||
| 		} | ||||
| 		if rv != C.SQLITE_OK { | ||||
| 			return s.c.lastError() | ||||
| 		} | ||||
| 	} | ||||
| 	return nil | ||||
| } | ||||
|  | ||||
| // Query the statement with arguments. Return records. | ||||
| func (s *SQLiteStmt) Query(args []driver.Value) (driver.Rows, error) { | ||||
| 	if err := s.bind(args); err != nil { | ||||
| 		return nil, err | ||||
| 	} | ||||
| 	return &SQLiteRows{s, int(C.sqlite3_column_count(s.s)), nil, nil, s.cls}, nil | ||||
| } | ||||
|  | ||||
| // Return last inserted ID. | ||||
| func (r *SQLiteResult) LastInsertId() (int64, error) { | ||||
| 	return r.id, nil | ||||
| } | ||||
|  | ||||
| // Return how many rows affected. | ||||
| func (r *SQLiteResult) RowsAffected() (int64, error) { | ||||
| 	return r.changes, nil | ||||
| } | ||||
|  | ||||
| // Execute the statement with arguments. Return result object. | ||||
| func (s *SQLiteStmt) Exec(args []driver.Value) (driver.Result, error) { | ||||
| 	if err := s.bind(args); err != nil { | ||||
| 		C.sqlite3_reset(s.s) | ||||
| 		C.sqlite3_clear_bindings(s.s) | ||||
| 		return nil, err | ||||
| 	} | ||||
| 	var rowid, changes C.longlong | ||||
| 	rv := C._sqlite3_step(s.s, &rowid, &changes) | ||||
| 	if rv != C.SQLITE_ROW && rv != C.SQLITE_OK && rv != C.SQLITE_DONE { | ||||
| 		err := s.c.lastError() | ||||
| 		C.sqlite3_reset(s.s) | ||||
| 		C.sqlite3_clear_bindings(s.s) | ||||
| 		return nil, err | ||||
| 	} | ||||
| 	return &SQLiteResult{int64(rowid), int64(changes)}, nil | ||||
| } | ||||
|  | ||||
| // Close the rows. | ||||
| func (rc *SQLiteRows) Close() error { | ||||
| 	if rc.s.closed { | ||||
| 		return nil | ||||
| 	} | ||||
| 	if rc.cls { | ||||
| 		return rc.s.Close() | ||||
| 	} | ||||
| 	rv := C.sqlite3_reset(rc.s.s) | ||||
| 	if rv != C.SQLITE_OK { | ||||
| 		return rc.s.c.lastError() | ||||
| 	} | ||||
| 	return nil | ||||
| } | ||||
|  | ||||
| // Return column names. | ||||
| func (rc *SQLiteRows) Columns() []string { | ||||
| 	if rc.nc != len(rc.cols) { | ||||
| 		rc.cols = make([]string, rc.nc) | ||||
| 		for i := 0; i < rc.nc; i++ { | ||||
| 			rc.cols[i] = C.GoString(C.sqlite3_column_name(rc.s.s, C.int(i))) | ||||
| 		} | ||||
| 	} | ||||
| 	return rc.cols | ||||
| } | ||||
|  | ||||
| // Return column types. | ||||
| func (rc *SQLiteRows) DeclTypes() []string { | ||||
| 	if rc.decltype == nil { | ||||
| 		rc.decltype = make([]string, rc.nc) | ||||
| 		for i := 0; i < rc.nc; i++ { | ||||
| 			rc.decltype[i] = strings.ToLower(C.GoString(C.sqlite3_column_decltype(rc.s.s, C.int(i)))) | ||||
| 		} | ||||
| 	} | ||||
| 	return rc.decltype | ||||
| } | ||||
|  | ||||
| // Move cursor to next. | ||||
| func (rc *SQLiteRows) Next(dest []driver.Value) error { | ||||
| 	rv := C.sqlite3_step(rc.s.s) | ||||
| 	if rv == C.SQLITE_DONE { | ||||
| 		return io.EOF | ||||
| 	} | ||||
| 	if rv != C.SQLITE_ROW { | ||||
| 		rv = C.sqlite3_reset(rc.s.s) | ||||
| 		if rv != C.SQLITE_OK { | ||||
| 			return rc.s.c.lastError() | ||||
| 		} | ||||
| 		return nil | ||||
| 	} | ||||
|  | ||||
| 	rc.DeclTypes() | ||||
|  | ||||
| 	for i := range dest { | ||||
| 		switch C.sqlite3_column_type(rc.s.s, C.int(i)) { | ||||
| 		case C.SQLITE_INTEGER: | ||||
| 			val := int64(C.sqlite3_column_int64(rc.s.s, C.int(i))) | ||||
| 			switch rc.decltype[i] { | ||||
| 			case "timestamp", "datetime", "date": | ||||
| 				var t time.Time | ||||
| 				// Assume a millisecond unix timestamp if it's 13 digits -- too | ||||
| 				// large to be a reasonable timestamp in seconds. | ||||
| 				if val > 1e12 || val < -1e12 { | ||||
| 					val *= int64(time.Millisecond) // convert ms to nsec | ||||
| 				} else { | ||||
| 					val *= int64(time.Second) // convert sec to nsec | ||||
| 				} | ||||
| 				t = time.Unix(0, val).UTC() | ||||
| 				if rc.s.c.loc != nil { | ||||
| 					t = t.In(rc.s.c.loc) | ||||
| 				} | ||||
| 				dest[i] = t | ||||
| 			case "boolean": | ||||
| 				dest[i] = val > 0 | ||||
| 			default: | ||||
| 				dest[i] = val | ||||
| 			} | ||||
| 		case C.SQLITE_FLOAT: | ||||
| 			dest[i] = float64(C.sqlite3_column_double(rc.s.s, C.int(i))) | ||||
| 		case C.SQLITE_BLOB: | ||||
| 			p := C.sqlite3_column_blob(rc.s.s, C.int(i)) | ||||
| 			if p == nil { | ||||
| 				dest[i] = nil | ||||
| 				continue | ||||
| 			} | ||||
| 			n := int(C.sqlite3_column_bytes(rc.s.s, C.int(i))) | ||||
| 			switch dest[i].(type) { | ||||
| 			case sql.RawBytes: | ||||
| 				dest[i] = (*[1 << 30]byte)(unsafe.Pointer(p))[0:n] | ||||
| 			default: | ||||
| 				slice := make([]byte, n) | ||||
| 				copy(slice[:], (*[1 << 30]byte)(unsafe.Pointer(p))[0:n]) | ||||
| 				dest[i] = slice | ||||
| 			} | ||||
| 		case C.SQLITE_NULL: | ||||
| 			dest[i] = nil | ||||
| 		case C.SQLITE_TEXT: | ||||
| 			var err error | ||||
| 			var timeVal time.Time | ||||
|  | ||||
| 			n := int(C.sqlite3_column_bytes(rc.s.s, C.int(i))) | ||||
| 			s := C.GoStringN((*C.char)(unsafe.Pointer(C.sqlite3_column_text(rc.s.s, C.int(i)))), C.int(n)) | ||||
|  | ||||
| 			switch rc.decltype[i] { | ||||
| 			case "timestamp", "datetime", "date": | ||||
| 				var t time.Time | ||||
| 				s = strings.TrimSuffix(s, "Z") | ||||
| 				for _, format := range SQLiteTimestampFormats { | ||||
| 					if timeVal, err = time.ParseInLocation(format, s, time.UTC); err == nil { | ||||
| 						t = timeVal | ||||
| 						break | ||||
| 					} | ||||
| 				} | ||||
| 				if err != nil { | ||||
| 					// The column is a time value, so return the zero time on parse failure. | ||||
| 					t = time.Time{} | ||||
| 				} | ||||
| 				if rc.s.c.loc != nil { | ||||
| 					t = t.In(rc.s.c.loc) | ||||
| 				} | ||||
| 				dest[i] = t | ||||
| 			default: | ||||
| 				dest[i] = []byte(s) | ||||
| 			} | ||||
|  | ||||
| 		} | ||||
| 	} | ||||
| 	return nil | ||||
| } | ||||
							
								
								
									
										13
									
								
								vendor/github.com/mattn/go-sqlite3/sqlite3_fts5.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										13
									
								
								vendor/github.com/mattn/go-sqlite3/sqlite3_fts5.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,13 @@ | ||||
| // 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 fts5 | ||||
|  | ||||
| package sqlite3 | ||||
|  | ||||
| /* | ||||
| #cgo CFLAGS: -DSQLITE_ENABLE_FTS5 | ||||
| #cgo LDFLAGS: -lm | ||||
| */ | ||||
| import "C" | ||||
							
								
								
									
										13
									
								
								vendor/github.com/mattn/go-sqlite3/sqlite3_icu.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										13
									
								
								vendor/github.com/mattn/go-sqlite3/sqlite3_icu.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,13 @@ | ||||
| // 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 icu  | ||||
|  | ||||
| package sqlite3 | ||||
|  | ||||
| /* | ||||
| #cgo LDFLAGS: -licuuc -licui18n | ||||
| #cgo CFLAGS: -DSQLITE_ENABLE_ICU | ||||
| */ | ||||
| import "C" | ||||
							
								
								
									
										12
									
								
								vendor/github.com/mattn/go-sqlite3/sqlite3_json1.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										12
									
								
								vendor/github.com/mattn/go-sqlite3/sqlite3_json1.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,12 @@ | ||||
| // 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 json1 | ||||
|  | ||||
| package sqlite3 | ||||
|  | ||||
| /* | ||||
| #cgo CFLAGS: -DSQLITE_ENABLE_JSON1 | ||||
| */ | ||||
| import "C" | ||||
							
								
								
									
										14
									
								
								vendor/github.com/mattn/go-sqlite3/sqlite3_libsqlite3.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										14
									
								
								vendor/github.com/mattn/go-sqlite3/sqlite3_libsqlite3.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,14 @@ | ||||
| // 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 libsqlite3 | ||||
|  | ||||
| package sqlite3 | ||||
|  | ||||
| /* | ||||
| #cgo CFLAGS: -DUSE_LIBSQLITE3 | ||||
| #cgo linux LDFLAGS: -lsqlite3 | ||||
| #cgo darwin LDFLAGS: -L/usr/local/opt/sqlite/lib -lsqlite3 | ||||
| */ | ||||
| import "C" | ||||
							
								
								
									
										67
									
								
								vendor/github.com/mattn/go-sqlite3/sqlite3_load_extension.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										67
									
								
								vendor/github.com/mattn/go-sqlite3/sqlite3_load_extension.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,67 @@ | ||||
| // 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 !sqlite_omit_load_extension | ||||
|  | ||||
| package sqlite3 | ||||
|  | ||||
| /* | ||||
| #ifndef USE_LIBSQLITE3 | ||||
| #include <sqlite3-binding.h> | ||||
| #else | ||||
| #include <sqlite3.h> | ||||
| #endif | ||||
| #include <stdlib.h> | ||||
| */ | ||||
| import "C" | ||||
| import ( | ||||
| 	"errors" | ||||
| 	"unsafe" | ||||
| ) | ||||
|  | ||||
| func (c *SQLiteConn) loadExtensions(extensions []string) error { | ||||
| 	rv := C.sqlite3_enable_load_extension(c.db, 1) | ||||
| 	if rv != C.SQLITE_OK { | ||||
| 		return errors.New(C.GoString(C.sqlite3_errmsg(c.db))) | ||||
| 	} | ||||
|  | ||||
| 	for _, extension := range extensions { | ||||
| 		cext := C.CString(extension) | ||||
| 		defer C.free(unsafe.Pointer(cext)) | ||||
| 		rv = C.sqlite3_load_extension(c.db, cext, nil, nil) | ||||
| 		if rv != C.SQLITE_OK { | ||||
| 			return errors.New(C.GoString(C.sqlite3_errmsg(c.db))) | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	rv = C.sqlite3_enable_load_extension(c.db, 0) | ||||
| 	if rv != C.SQLITE_OK { | ||||
| 		return errors.New(C.GoString(C.sqlite3_errmsg(c.db))) | ||||
| 	} | ||||
| 	return nil | ||||
| } | ||||
|  | ||||
| func (c *SQLiteConn) LoadExtension(lib string, entry string) error { | ||||
| 	rv := C.sqlite3_enable_load_extension(c.db, 1) | ||||
| 	if rv != C.SQLITE_OK { | ||||
| 		return errors.New(C.GoString(C.sqlite3_errmsg(c.db))) | ||||
| 	} | ||||
|  | ||||
| 	clib := C.CString(lib) | ||||
| 	defer C.free(unsafe.Pointer(clib)) | ||||
| 	centry := C.CString(entry) | ||||
| 	defer C.free(unsafe.Pointer(centry)) | ||||
|  | ||||
| 	rv = C.sqlite3_load_extension(c.db, clib, centry, nil) | ||||
| 	if rv != C.SQLITE_OK { | ||||
| 		return errors.New(C.GoString(C.sqlite3_errmsg(c.db))) | ||||
| 	} | ||||
|  | ||||
| 	rv = C.sqlite3_enable_load_extension(c.db, 0) | ||||
| 	if rv != C.SQLITE_OK { | ||||
| 		return errors.New(C.GoString(C.sqlite3_errmsg(c.db))) | ||||
| 	} | ||||
|  | ||||
| 	return nil | ||||
| } | ||||
							
								
								
									
										23
									
								
								vendor/github.com/mattn/go-sqlite3/sqlite3_omit_load_extension.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										23
									
								
								vendor/github.com/mattn/go-sqlite3/sqlite3_omit_load_extension.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,23 @@ | ||||
| // 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 sqlite_omit_load_extension | ||||
|  | ||||
| package sqlite3 | ||||
|  | ||||
| /* | ||||
| #cgo CFLAGS: -DSQLITE_OMIT_LOAD_EXTENSION | ||||
| */ | ||||
| import "C" | ||||
| import ( | ||||
| 	"errors" | ||||
| ) | ||||
|  | ||||
| func (c *SQLiteConn) loadExtensions(extensions []string) error { | ||||
| 	return errors.New("Extensions have been disabled for static builds") | ||||
| } | ||||
|  | ||||
| func (c *SQLiteConn) LoadExtension(lib string, entry string) error { | ||||
| 	return errors.New("Extensions have been disabled for static builds") | ||||
| } | ||||
							
								
								
									
										13
									
								
								vendor/github.com/mattn/go-sqlite3/sqlite3_other.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										13
									
								
								vendor/github.com/mattn/go-sqlite3/sqlite3_other.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,13 @@ | ||||
| // 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 !windows | ||||
|  | ||||
| package sqlite3 | ||||
|  | ||||
| /* | ||||
| #cgo CFLAGS: -I. | ||||
| #cgo linux LDFLAGS: -ldl | ||||
| */ | ||||
| import "C" | ||||
							
								
								
									
										14
									
								
								vendor/github.com/mattn/go-sqlite3/sqlite3_windows.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										14
									
								
								vendor/github.com/mattn/go-sqlite3/sqlite3_windows.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,14 @@ | ||||
| // 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 windows | ||||
|  | ||||
| package sqlite3 | ||||
|  | ||||
| /* | ||||
| #cgo CFLAGS: -I. -fno-stack-check -fno-stack-protector -mno-stack-arg-probe | ||||
| #cgo windows,386 CFLAGS: -D_USE_32BIT_TIME_T | ||||
| #cgo LDFLAGS: -lmingwex -lmingw32 | ||||
| */ | ||||
| import "C" | ||||
							
								
								
									
										565
									
								
								vendor/github.com/mattn/go-sqlite3/sqlite3ext.h
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										565
									
								
								vendor/github.com/mattn/go-sqlite3/sqlite3ext.h
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,565 @@ | ||||
| #ifndef USE_LIBSQLITE3 | ||||
| /* | ||||
| ** 2006 June 7 | ||||
| ** | ||||
| ** The author disclaims copyright to this source code.  In place of | ||||
| ** a legal notice, here is a blessing: | ||||
| ** | ||||
| **    May you do good and not evil. | ||||
| **    May you find forgiveness for yourself and forgive others. | ||||
| **    May you share freely, never taking more than you give. | ||||
| ** | ||||
| ************************************************************************* | ||||
| ** This header file defines the SQLite interface for use by | ||||
| ** shared libraries that want to be imported as extensions into | ||||
| ** an SQLite instance.  Shared libraries that intend to be loaded | ||||
| ** as extensions by SQLite should #include this file instead of | ||||
| ** sqlite3.h. | ||||
| */ | ||||
| #ifndef SQLITE3EXT_H | ||||
| #define SQLITE3EXT_H | ||||
| #include "sqlite3.h" | ||||
|  | ||||
| /* | ||||
| ** The following structure holds pointers to all of the SQLite API | ||||
| ** routines. | ||||
| ** | ||||
| ** WARNING:  In order to maintain backwards compatibility, add new | ||||
| ** interfaces to the end of this structure only.  If you insert new | ||||
| ** interfaces in the middle of this structure, then older different | ||||
| ** versions of SQLite will not be able to load each other's shared | ||||
| ** libraries! | ||||
| */ | ||||
| struct sqlite3_api_routines { | ||||
|   void * (*aggregate_context)(sqlite3_context*,int nBytes); | ||||
|   int  (*aggregate_count)(sqlite3_context*); | ||||
|   int  (*bind_blob)(sqlite3_stmt*,int,const void*,int n,void(*)(void*)); | ||||
|   int  (*bind_double)(sqlite3_stmt*,int,double); | ||||
|   int  (*bind_int)(sqlite3_stmt*,int,int); | ||||
|   int  (*bind_int64)(sqlite3_stmt*,int,sqlite_int64); | ||||
|   int  (*bind_null)(sqlite3_stmt*,int); | ||||
|   int  (*bind_parameter_count)(sqlite3_stmt*); | ||||
|   int  (*bind_parameter_index)(sqlite3_stmt*,const char*zName); | ||||
|   const char * (*bind_parameter_name)(sqlite3_stmt*,int); | ||||
|   int  (*bind_text)(sqlite3_stmt*,int,const char*,int n,void(*)(void*)); | ||||
|   int  (*bind_text16)(sqlite3_stmt*,int,const void*,int,void(*)(void*)); | ||||
|   int  (*bind_value)(sqlite3_stmt*,int,const sqlite3_value*); | ||||
|   int  (*busy_handler)(sqlite3*,int(*)(void*,int),void*); | ||||
|   int  (*busy_timeout)(sqlite3*,int ms); | ||||
|   int  (*changes)(sqlite3*); | ||||
|   int  (*close)(sqlite3*); | ||||
|   int  (*collation_needed)(sqlite3*,void*,void(*)(void*,sqlite3*, | ||||
|                            int eTextRep,const char*)); | ||||
|   int  (*collation_needed16)(sqlite3*,void*,void(*)(void*,sqlite3*, | ||||
|                              int eTextRep,const void*)); | ||||
|   const void * (*column_blob)(sqlite3_stmt*,int iCol); | ||||
|   int  (*column_bytes)(sqlite3_stmt*,int iCol); | ||||
|   int  (*column_bytes16)(sqlite3_stmt*,int iCol); | ||||
|   int  (*column_count)(sqlite3_stmt*pStmt); | ||||
|   const char * (*column_database_name)(sqlite3_stmt*,int); | ||||
|   const void * (*column_database_name16)(sqlite3_stmt*,int); | ||||
|   const char * (*column_decltype)(sqlite3_stmt*,int i); | ||||
|   const void * (*column_decltype16)(sqlite3_stmt*,int); | ||||
|   double  (*column_double)(sqlite3_stmt*,int iCol); | ||||
|   int  (*column_int)(sqlite3_stmt*,int iCol); | ||||
|   sqlite_int64  (*column_int64)(sqlite3_stmt*,int iCol); | ||||
|   const char * (*column_name)(sqlite3_stmt*,int); | ||||
|   const void * (*column_name16)(sqlite3_stmt*,int); | ||||
|   const char * (*column_origin_name)(sqlite3_stmt*,int); | ||||
|   const void * (*column_origin_name16)(sqlite3_stmt*,int); | ||||
|   const char * (*column_table_name)(sqlite3_stmt*,int); | ||||
|   const void * (*column_table_name16)(sqlite3_stmt*,int); | ||||
|   const unsigned char * (*column_text)(sqlite3_stmt*,int iCol); | ||||
|   const void * (*column_text16)(sqlite3_stmt*,int iCol); | ||||
|   int  (*column_type)(sqlite3_stmt*,int iCol); | ||||
|   sqlite3_value* (*column_value)(sqlite3_stmt*,int iCol); | ||||
|   void * (*commit_hook)(sqlite3*,int(*)(void*),void*); | ||||
|   int  (*complete)(const char*sql); | ||||
|   int  (*complete16)(const void*sql); | ||||
|   int  (*create_collation)(sqlite3*,const char*,int,void*, | ||||
|                            int(*)(void*,int,const void*,int,const void*)); | ||||
|   int  (*create_collation16)(sqlite3*,const void*,int,void*, | ||||
|                              int(*)(void*,int,const void*,int,const void*)); | ||||
|   int  (*create_function)(sqlite3*,const char*,int,int,void*, | ||||
|                           void (*xFunc)(sqlite3_context*,int,sqlite3_value**), | ||||
|                           void (*xStep)(sqlite3_context*,int,sqlite3_value**), | ||||
|                           void (*xFinal)(sqlite3_context*)); | ||||
|   int  (*create_function16)(sqlite3*,const void*,int,int,void*, | ||||
|                             void (*xFunc)(sqlite3_context*,int,sqlite3_value**), | ||||
|                             void (*xStep)(sqlite3_context*,int,sqlite3_value**), | ||||
|                             void (*xFinal)(sqlite3_context*)); | ||||
|   int (*create_module)(sqlite3*,const char*,const sqlite3_module*,void*); | ||||
|   int  (*data_count)(sqlite3_stmt*pStmt); | ||||
|   sqlite3 * (*db_handle)(sqlite3_stmt*); | ||||
|   int (*declare_vtab)(sqlite3*,const char*); | ||||
|   int  (*enable_shared_cache)(int); | ||||
|   int  (*errcode)(sqlite3*db); | ||||
|   const char * (*errmsg)(sqlite3*); | ||||
|   const void * (*errmsg16)(sqlite3*); | ||||
|   int  (*exec)(sqlite3*,const char*,sqlite3_callback,void*,char**); | ||||
|   int  (*expired)(sqlite3_stmt*); | ||||
|   int  (*finalize)(sqlite3_stmt*pStmt); | ||||
|   void  (*free)(void*); | ||||
|   void  (*free_table)(char**result); | ||||
|   int  (*get_autocommit)(sqlite3*); | ||||
|   void * (*get_auxdata)(sqlite3_context*,int); | ||||
|   int  (*get_table)(sqlite3*,const char*,char***,int*,int*,char**); | ||||
|   int  (*global_recover)(void); | ||||
|   void  (*interruptx)(sqlite3*); | ||||
|   sqlite_int64  (*last_insert_rowid)(sqlite3*); | ||||
|   const char * (*libversion)(void); | ||||
|   int  (*libversion_number)(void); | ||||
|   void *(*malloc)(int); | ||||
|   char * (*mprintf)(const char*,...); | ||||
|   int  (*open)(const char*,sqlite3**); | ||||
|   int  (*open16)(const void*,sqlite3**); | ||||
|   int  (*prepare)(sqlite3*,const char*,int,sqlite3_stmt**,const char**); | ||||
|   int  (*prepare16)(sqlite3*,const void*,int,sqlite3_stmt**,const void**); | ||||
|   void * (*profile)(sqlite3*,void(*)(void*,const char*,sqlite_uint64),void*); | ||||
|   void  (*progress_handler)(sqlite3*,int,int(*)(void*),void*); | ||||
|   void *(*realloc)(void*,int); | ||||
|   int  (*reset)(sqlite3_stmt*pStmt); | ||||
|   void  (*result_blob)(sqlite3_context*,const void*,int,void(*)(void*)); | ||||
|   void  (*result_double)(sqlite3_context*,double); | ||||
|   void  (*result_error)(sqlite3_context*,const char*,int); | ||||
|   void  (*result_error16)(sqlite3_context*,const void*,int); | ||||
|   void  (*result_int)(sqlite3_context*,int); | ||||
|   void  (*result_int64)(sqlite3_context*,sqlite_int64); | ||||
|   void  (*result_null)(sqlite3_context*); | ||||
|   void  (*result_text)(sqlite3_context*,const char*,int,void(*)(void*)); | ||||
|   void  (*result_text16)(sqlite3_context*,const void*,int,void(*)(void*)); | ||||
|   void  (*result_text16be)(sqlite3_context*,const void*,int,void(*)(void*)); | ||||
|   void  (*result_text16le)(sqlite3_context*,const void*,int,void(*)(void*)); | ||||
|   void  (*result_value)(sqlite3_context*,sqlite3_value*); | ||||
|   void * (*rollback_hook)(sqlite3*,void(*)(void*),void*); | ||||
|   int  (*set_authorizer)(sqlite3*,int(*)(void*,int,const char*,const char*, | ||||
|                          const char*,const char*),void*); | ||||
|   void  (*set_auxdata)(sqlite3_context*,int,void*,void (*)(void*)); | ||||
|   char * (*snprintf)(int,char*,const char*,...); | ||||
|   int  (*step)(sqlite3_stmt*); | ||||
|   int  (*table_column_metadata)(sqlite3*,const char*,const char*,const char*, | ||||
|                                 char const**,char const**,int*,int*,int*); | ||||
|   void  (*thread_cleanup)(void); | ||||
|   int  (*total_changes)(sqlite3*); | ||||
|   void * (*trace)(sqlite3*,void(*xTrace)(void*,const char*),void*); | ||||
|   int  (*transfer_bindings)(sqlite3_stmt*,sqlite3_stmt*); | ||||
|   void * (*update_hook)(sqlite3*,void(*)(void*,int ,char const*,char const*, | ||||
|                                          sqlite_int64),void*); | ||||
|   void * (*user_data)(sqlite3_context*); | ||||
|   const void * (*value_blob)(sqlite3_value*); | ||||
|   int  (*value_bytes)(sqlite3_value*); | ||||
|   int  (*value_bytes16)(sqlite3_value*); | ||||
|   double  (*value_double)(sqlite3_value*); | ||||
|   int  (*value_int)(sqlite3_value*); | ||||
|   sqlite_int64  (*value_int64)(sqlite3_value*); | ||||
|   int  (*value_numeric_type)(sqlite3_value*); | ||||
|   const unsigned char * (*value_text)(sqlite3_value*); | ||||
|   const void * (*value_text16)(sqlite3_value*); | ||||
|   const void * (*value_text16be)(sqlite3_value*); | ||||
|   const void * (*value_text16le)(sqlite3_value*); | ||||
|   int  (*value_type)(sqlite3_value*); | ||||
|   char *(*vmprintf)(const char*,va_list); | ||||
|   /* Added ??? */ | ||||
|   int (*overload_function)(sqlite3*, const char *zFuncName, int nArg); | ||||
|   /* Added by 3.3.13 */ | ||||
|   int (*prepare_v2)(sqlite3*,const char*,int,sqlite3_stmt**,const char**); | ||||
|   int (*prepare16_v2)(sqlite3*,const void*,int,sqlite3_stmt**,const void**); | ||||
|   int (*clear_bindings)(sqlite3_stmt*); | ||||
|   /* Added by 3.4.1 */ | ||||
|   int (*create_module_v2)(sqlite3*,const char*,const sqlite3_module*,void*, | ||||
|                           void (*xDestroy)(void *)); | ||||
|   /* Added by 3.5.0 */ | ||||
|   int (*bind_zeroblob)(sqlite3_stmt*,int,int); | ||||
|   int (*blob_bytes)(sqlite3_blob*); | ||||
|   int (*blob_close)(sqlite3_blob*); | ||||
|   int (*blob_open)(sqlite3*,const char*,const char*,const char*,sqlite3_int64, | ||||
|                    int,sqlite3_blob**); | ||||
|   int (*blob_read)(sqlite3_blob*,void*,int,int); | ||||
|   int (*blob_write)(sqlite3_blob*,const void*,int,int); | ||||
|   int (*create_collation_v2)(sqlite3*,const char*,int,void*, | ||||
|                              int(*)(void*,int,const void*,int,const void*), | ||||
|                              void(*)(void*)); | ||||
|   int (*file_control)(sqlite3*,const char*,int,void*); | ||||
|   sqlite3_int64 (*memory_highwater)(int); | ||||
|   sqlite3_int64 (*memory_used)(void); | ||||
|   sqlite3_mutex *(*mutex_alloc)(int); | ||||
|   void (*mutex_enter)(sqlite3_mutex*); | ||||
|   void (*mutex_free)(sqlite3_mutex*); | ||||
|   void (*mutex_leave)(sqlite3_mutex*); | ||||
|   int (*mutex_try)(sqlite3_mutex*); | ||||
|   int (*open_v2)(const char*,sqlite3**,int,const char*); | ||||
|   int (*release_memory)(int); | ||||
|   void (*result_error_nomem)(sqlite3_context*); | ||||
|   void (*result_error_toobig)(sqlite3_context*); | ||||
|   int (*sleep)(int); | ||||
|   void (*soft_heap_limit)(int); | ||||
|   sqlite3_vfs *(*vfs_find)(const char*); | ||||
|   int (*vfs_register)(sqlite3_vfs*,int); | ||||
|   int (*vfs_unregister)(sqlite3_vfs*); | ||||
|   int (*xthreadsafe)(void); | ||||
|   void (*result_zeroblob)(sqlite3_context*,int); | ||||
|   void (*result_error_code)(sqlite3_context*,int); | ||||
|   int (*test_control)(int, ...); | ||||
|   void (*randomness)(int,void*); | ||||
|   sqlite3 *(*context_db_handle)(sqlite3_context*); | ||||
|   int (*extended_result_codes)(sqlite3*,int); | ||||
|   int (*limit)(sqlite3*,int,int); | ||||
|   sqlite3_stmt *(*next_stmt)(sqlite3*,sqlite3_stmt*); | ||||
|   const char *(*sql)(sqlite3_stmt*); | ||||
|   int (*status)(int,int*,int*,int); | ||||
|   int (*backup_finish)(sqlite3_backup*); | ||||
|   sqlite3_backup *(*backup_init)(sqlite3*,const char*,sqlite3*,const char*); | ||||
|   int (*backup_pagecount)(sqlite3_backup*); | ||||
|   int (*backup_remaining)(sqlite3_backup*); | ||||
|   int (*backup_step)(sqlite3_backup*,int); | ||||
|   const char *(*compileoption_get)(int); | ||||
|   int (*compileoption_used)(const char*); | ||||
|   int (*create_function_v2)(sqlite3*,const char*,int,int,void*, | ||||
|                             void (*xFunc)(sqlite3_context*,int,sqlite3_value**), | ||||
|                             void (*xStep)(sqlite3_context*,int,sqlite3_value**), | ||||
|                             void (*xFinal)(sqlite3_context*), | ||||
|                             void(*xDestroy)(void*)); | ||||
|   int (*db_config)(sqlite3*,int,...); | ||||
|   sqlite3_mutex *(*db_mutex)(sqlite3*); | ||||
|   int (*db_status)(sqlite3*,int,int*,int*,int); | ||||
|   int (*extended_errcode)(sqlite3*); | ||||
|   void (*log)(int,const char*,...); | ||||
|   sqlite3_int64 (*soft_heap_limit64)(sqlite3_int64); | ||||
|   const char *(*sourceid)(void); | ||||
|   int (*stmt_status)(sqlite3_stmt*,int,int); | ||||
|   int (*strnicmp)(const char*,const char*,int); | ||||
|   int (*unlock_notify)(sqlite3*,void(*)(void**,int),void*); | ||||
|   int (*wal_autocheckpoint)(sqlite3*,int); | ||||
|   int (*wal_checkpoint)(sqlite3*,const char*); | ||||
|   void *(*wal_hook)(sqlite3*,int(*)(void*,sqlite3*,const char*,int),void*); | ||||
|   int (*blob_reopen)(sqlite3_blob*,sqlite3_int64); | ||||
|   int (*vtab_config)(sqlite3*,int op,...); | ||||
|   int (*vtab_on_conflict)(sqlite3*); | ||||
|   /* Version 3.7.16 and later */ | ||||
|   int (*close_v2)(sqlite3*); | ||||
|   const char *(*db_filename)(sqlite3*,const char*); | ||||
|   int (*db_readonly)(sqlite3*,const char*); | ||||
|   int (*db_release_memory)(sqlite3*); | ||||
|   const char *(*errstr)(int); | ||||
|   int (*stmt_busy)(sqlite3_stmt*); | ||||
|   int (*stmt_readonly)(sqlite3_stmt*); | ||||
|   int (*stricmp)(const char*,const char*); | ||||
|   int (*uri_boolean)(const char*,const char*,int); | ||||
|   sqlite3_int64 (*uri_int64)(const char*,const char*,sqlite3_int64); | ||||
|   const char *(*uri_parameter)(const char*,const char*); | ||||
|   char *(*vsnprintf)(int,char*,const char*,va_list); | ||||
|   int (*wal_checkpoint_v2)(sqlite3*,const char*,int,int*,int*); | ||||
|   /* Version 3.8.7 and later */ | ||||
|   int (*auto_extension)(void(*)(void)); | ||||
|   int (*bind_blob64)(sqlite3_stmt*,int,const void*,sqlite3_uint64, | ||||
|                      void(*)(void*)); | ||||
|   int (*bind_text64)(sqlite3_stmt*,int,const char*,sqlite3_uint64, | ||||
|                       void(*)(void*),unsigned char); | ||||
|   int (*cancel_auto_extension)(void(*)(void)); | ||||
|   int (*load_extension)(sqlite3*,const char*,const char*,char**); | ||||
|   void *(*malloc64)(sqlite3_uint64); | ||||
|   sqlite3_uint64 (*msize)(void*); | ||||
|   void *(*realloc64)(void*,sqlite3_uint64); | ||||
|   void (*reset_auto_extension)(void); | ||||
|   void (*result_blob64)(sqlite3_context*,const void*,sqlite3_uint64, | ||||
|                         void(*)(void*)); | ||||
|   void (*result_text64)(sqlite3_context*,const char*,sqlite3_uint64, | ||||
|                          void(*)(void*), unsigned char); | ||||
|   int (*strglob)(const char*,const char*); | ||||
|   /* Version 3.8.11 and later */ | ||||
|   sqlite3_value *(*value_dup)(const sqlite3_value*); | ||||
|   void (*value_free)(sqlite3_value*); | ||||
|   int (*result_zeroblob64)(sqlite3_context*,sqlite3_uint64); | ||||
|   int (*bind_zeroblob64)(sqlite3_stmt*, int, sqlite3_uint64); | ||||
|   /* Version 3.9.0 and later */ | ||||
|   unsigned int (*value_subtype)(sqlite3_value*); | ||||
|   void (*result_subtype)(sqlite3_context*,unsigned int); | ||||
|   /* Version 3.10.0 and later */ | ||||
|   int (*status64)(int,sqlite3_int64*,sqlite3_int64*,int); | ||||
|   int (*strlike)(const char*,const char*,unsigned int); | ||||
|   int (*db_cacheflush)(sqlite3*); | ||||
|   /* Version 3.12.0 and later */ | ||||
|   int (*system_errno)(sqlite3*); | ||||
|   /* Version 3.14.0 and later */ | ||||
|   int (*trace_v2)(sqlite3*,unsigned,int(*)(unsigned,void*,void*,void*),void*); | ||||
|   char *(*expanded_sql)(sqlite3_stmt*); | ||||
| }; | ||||
|  | ||||
| /* | ||||
| ** This is the function signature used for all extension entry points.  It | ||||
| ** is also defined in the file "loadext.c". | ||||
| */ | ||||
| typedef int (*sqlite3_loadext_entry)( | ||||
|   sqlite3 *db,                       /* Handle to the database. */ | ||||
|   char **pzErrMsg,                   /* Used to set error string on failure. */ | ||||
|   const sqlite3_api_routines *pThunk /* Extension API function pointers. */ | ||||
| ); | ||||
|  | ||||
| /* | ||||
| ** The following macros redefine the API routines so that they are | ||||
| ** redirected through the global sqlite3_api structure. | ||||
| ** | ||||
| ** This header file is also used by the loadext.c source file | ||||
| ** (part of the main SQLite library - not an extension) so that | ||||
| ** it can get access to the sqlite3_api_routines structure | ||||
| ** definition.  But the main library does not want to redefine | ||||
| ** the API.  So the redefinition macros are only valid if the | ||||
| ** SQLITE_CORE macros is undefined. | ||||
| */ | ||||
| #if !defined(SQLITE_CORE) && !defined(SQLITE_OMIT_LOAD_EXTENSION) | ||||
| #define sqlite3_aggregate_context      sqlite3_api->aggregate_context | ||||
| #ifndef SQLITE_OMIT_DEPRECATED | ||||
| #define sqlite3_aggregate_count        sqlite3_api->aggregate_count | ||||
| #endif | ||||
| #define sqlite3_bind_blob              sqlite3_api->bind_blob | ||||
| #define sqlite3_bind_double            sqlite3_api->bind_double | ||||
| #define sqlite3_bind_int               sqlite3_api->bind_int | ||||
| #define sqlite3_bind_int64             sqlite3_api->bind_int64 | ||||
| #define sqlite3_bind_null              sqlite3_api->bind_null | ||||
| #define sqlite3_bind_parameter_count   sqlite3_api->bind_parameter_count | ||||
| #define sqlite3_bind_parameter_index   sqlite3_api->bind_parameter_index | ||||
| #define sqlite3_bind_parameter_name    sqlite3_api->bind_parameter_name | ||||
| #define sqlite3_bind_text              sqlite3_api->bind_text | ||||
| #define sqlite3_bind_text16            sqlite3_api->bind_text16 | ||||
| #define sqlite3_bind_value             sqlite3_api->bind_value | ||||
| #define sqlite3_busy_handler           sqlite3_api->busy_handler | ||||
| #define sqlite3_busy_timeout           sqlite3_api->busy_timeout | ||||
| #define sqlite3_changes                sqlite3_api->changes | ||||
| #define sqlite3_close                  sqlite3_api->close | ||||
| #define sqlite3_collation_needed       sqlite3_api->collation_needed | ||||
| #define sqlite3_collation_needed16     sqlite3_api->collation_needed16 | ||||
| #define sqlite3_column_blob            sqlite3_api->column_blob | ||||
| #define sqlite3_column_bytes           sqlite3_api->column_bytes | ||||
| #define sqlite3_column_bytes16         sqlite3_api->column_bytes16 | ||||
| #define sqlite3_column_count           sqlite3_api->column_count | ||||
| #define sqlite3_column_database_name   sqlite3_api->column_database_name | ||||
| #define sqlite3_column_database_name16 sqlite3_api->column_database_name16 | ||||
| #define sqlite3_column_decltype        sqlite3_api->column_decltype | ||||
| #define sqlite3_column_decltype16      sqlite3_api->column_decltype16 | ||||
| #define sqlite3_column_double          sqlite3_api->column_double | ||||
| #define sqlite3_column_int             sqlite3_api->column_int | ||||
| #define sqlite3_column_int64           sqlite3_api->column_int64 | ||||
| #define sqlite3_column_name            sqlite3_api->column_name | ||||
| #define sqlite3_column_name16          sqlite3_api->column_name16 | ||||
| #define sqlite3_column_origin_name     sqlite3_api->column_origin_name | ||||
| #define sqlite3_column_origin_name16   sqlite3_api->column_origin_name16 | ||||
| #define sqlite3_column_table_name      sqlite3_api->column_table_name | ||||
| #define sqlite3_column_table_name16    sqlite3_api->column_table_name16 | ||||
| #define sqlite3_column_text            sqlite3_api->column_text | ||||
| #define sqlite3_column_text16          sqlite3_api->column_text16 | ||||
| #define sqlite3_column_type            sqlite3_api->column_type | ||||
| #define sqlite3_column_value           sqlite3_api->column_value | ||||
| #define sqlite3_commit_hook            sqlite3_api->commit_hook | ||||
| #define sqlite3_complete               sqlite3_api->complete | ||||
| #define sqlite3_complete16             sqlite3_api->complete16 | ||||
| #define sqlite3_create_collation       sqlite3_api->create_collation | ||||
| #define sqlite3_create_collation16     sqlite3_api->create_collation16 | ||||
| #define sqlite3_create_function        sqlite3_api->create_function | ||||
| #define sqlite3_create_function16      sqlite3_api->create_function16 | ||||
| #define sqlite3_create_module          sqlite3_api->create_module | ||||
| #define sqlite3_create_module_v2       sqlite3_api->create_module_v2 | ||||
| #define sqlite3_data_count             sqlite3_api->data_count | ||||
| #define sqlite3_db_handle              sqlite3_api->db_handle | ||||
| #define sqlite3_declare_vtab           sqlite3_api->declare_vtab | ||||
| #define sqlite3_enable_shared_cache    sqlite3_api->enable_shared_cache | ||||
| #define sqlite3_errcode                sqlite3_api->errcode | ||||
| #define sqlite3_errmsg                 sqlite3_api->errmsg | ||||
| #define sqlite3_errmsg16               sqlite3_api->errmsg16 | ||||
| #define sqlite3_exec                   sqlite3_api->exec | ||||
| #ifndef SQLITE_OMIT_DEPRECATED | ||||
| #define sqlite3_expired                sqlite3_api->expired | ||||
| #endif | ||||
| #define sqlite3_finalize               sqlite3_api->finalize | ||||
| #define sqlite3_free                   sqlite3_api->free | ||||
| #define sqlite3_free_table             sqlite3_api->free_table | ||||
| #define sqlite3_get_autocommit         sqlite3_api->get_autocommit | ||||
| #define sqlite3_get_auxdata            sqlite3_api->get_auxdata | ||||
| #define sqlite3_get_table              sqlite3_api->get_table | ||||
| #ifndef SQLITE_OMIT_DEPRECATED | ||||
| #define sqlite3_global_recover         sqlite3_api->global_recover | ||||
| #endif | ||||
| #define sqlite3_interrupt              sqlite3_api->interruptx | ||||
| #define sqlite3_last_insert_rowid      sqlite3_api->last_insert_rowid | ||||
| #define sqlite3_libversion             sqlite3_api->libversion | ||||
| #define sqlite3_libversion_number      sqlite3_api->libversion_number | ||||
| #define sqlite3_malloc                 sqlite3_api->malloc | ||||
| #define sqlite3_mprintf                sqlite3_api->mprintf | ||||
| #define sqlite3_open                   sqlite3_api->open | ||||
| #define sqlite3_open16                 sqlite3_api->open16 | ||||
| #define sqlite3_prepare                sqlite3_api->prepare | ||||
| #define sqlite3_prepare16              sqlite3_api->prepare16 | ||||
| #define sqlite3_prepare_v2             sqlite3_api->prepare_v2 | ||||
| #define sqlite3_prepare16_v2           sqlite3_api->prepare16_v2 | ||||
| #define sqlite3_profile                sqlite3_api->profile | ||||
| #define sqlite3_progress_handler       sqlite3_api->progress_handler | ||||
| #define sqlite3_realloc                sqlite3_api->realloc | ||||
| #define sqlite3_reset                  sqlite3_api->reset | ||||
| #define sqlite3_result_blob            sqlite3_api->result_blob | ||||
| #define sqlite3_result_double          sqlite3_api->result_double | ||||
| #define sqlite3_result_error           sqlite3_api->result_error | ||||
| #define sqlite3_result_error16         sqlite3_api->result_error16 | ||||
| #define sqlite3_result_int             sqlite3_api->result_int | ||||
| #define sqlite3_result_int64           sqlite3_api->result_int64 | ||||
| #define sqlite3_result_null            sqlite3_api->result_null | ||||
| #define sqlite3_result_text            sqlite3_api->result_text | ||||
| #define sqlite3_result_text16          sqlite3_api->result_text16 | ||||
| #define sqlite3_result_text16be        sqlite3_api->result_text16be | ||||
| #define sqlite3_result_text16le        sqlite3_api->result_text16le | ||||
| #define sqlite3_result_value           sqlite3_api->result_value | ||||
| #define sqlite3_rollback_hook          sqlite3_api->rollback_hook | ||||
| #define sqlite3_set_authorizer         sqlite3_api->set_authorizer | ||||
| #define sqlite3_set_auxdata            sqlite3_api->set_auxdata | ||||
| #define sqlite3_snprintf               sqlite3_api->snprintf | ||||
| #define sqlite3_step                   sqlite3_api->step | ||||
| #define sqlite3_table_column_metadata  sqlite3_api->table_column_metadata | ||||
| #define sqlite3_thread_cleanup         sqlite3_api->thread_cleanup | ||||
| #define sqlite3_total_changes          sqlite3_api->total_changes | ||||
| #define sqlite3_trace                  sqlite3_api->trace | ||||
| #ifndef SQLITE_OMIT_DEPRECATED | ||||
| #define sqlite3_transfer_bindings      sqlite3_api->transfer_bindings | ||||
| #endif | ||||
| #define sqlite3_update_hook            sqlite3_api->update_hook | ||||
| #define sqlite3_user_data              sqlite3_api->user_data | ||||
| #define sqlite3_value_blob             sqlite3_api->value_blob | ||||
| #define sqlite3_value_bytes            sqlite3_api->value_bytes | ||||
| #define sqlite3_value_bytes16          sqlite3_api->value_bytes16 | ||||
| #define sqlite3_value_double           sqlite3_api->value_double | ||||
| #define sqlite3_value_int              sqlite3_api->value_int | ||||
| #define sqlite3_value_int64            sqlite3_api->value_int64 | ||||
| #define sqlite3_value_numeric_type     sqlite3_api->value_numeric_type | ||||
| #define sqlite3_value_text             sqlite3_api->value_text | ||||
| #define sqlite3_value_text16           sqlite3_api->value_text16 | ||||
| #define sqlite3_value_text16be         sqlite3_api->value_text16be | ||||
| #define sqlite3_value_text16le         sqlite3_api->value_text16le | ||||
| #define sqlite3_value_type             sqlite3_api->value_type | ||||
| #define sqlite3_vmprintf               sqlite3_api->vmprintf | ||||
| #define sqlite3_vsnprintf              sqlite3_api->vsnprintf | ||||
| #define sqlite3_overload_function      sqlite3_api->overload_function | ||||
| #define sqlite3_prepare_v2             sqlite3_api->prepare_v2 | ||||
| #define sqlite3_prepare16_v2           sqlite3_api->prepare16_v2 | ||||
| #define sqlite3_clear_bindings         sqlite3_api->clear_bindings | ||||
| #define sqlite3_bind_zeroblob          sqlite3_api->bind_zeroblob | ||||
| #define sqlite3_blob_bytes             sqlite3_api->blob_bytes | ||||
| #define sqlite3_blob_close             sqlite3_api->blob_close | ||||
| #define sqlite3_blob_open              sqlite3_api->blob_open | ||||
| #define sqlite3_blob_read              sqlite3_api->blob_read | ||||
| #define sqlite3_blob_write             sqlite3_api->blob_write | ||||
| #define sqlite3_create_collation_v2    sqlite3_api->create_collation_v2 | ||||
| #define sqlite3_file_control           sqlite3_api->file_control | ||||
| #define sqlite3_memory_highwater       sqlite3_api->memory_highwater | ||||
| #define sqlite3_memory_used            sqlite3_api->memory_used | ||||
| #define sqlite3_mutex_alloc            sqlite3_api->mutex_alloc | ||||
| #define sqlite3_mutex_enter            sqlite3_api->mutex_enter | ||||
| #define sqlite3_mutex_free             sqlite3_api->mutex_free | ||||
| #define sqlite3_mutex_leave            sqlite3_api->mutex_leave | ||||
| #define sqlite3_mutex_try              sqlite3_api->mutex_try | ||||
| #define sqlite3_open_v2                sqlite3_api->open_v2 | ||||
| #define sqlite3_release_memory         sqlite3_api->release_memory | ||||
| #define sqlite3_result_error_nomem     sqlite3_api->result_error_nomem | ||||
| #define sqlite3_result_error_toobig    sqlite3_api->result_error_toobig | ||||
| #define sqlite3_sleep                  sqlite3_api->sleep | ||||
| #define sqlite3_soft_heap_limit        sqlite3_api->soft_heap_limit | ||||
| #define sqlite3_vfs_find               sqlite3_api->vfs_find | ||||
| #define sqlite3_vfs_register           sqlite3_api->vfs_register | ||||
| #define sqlite3_vfs_unregister         sqlite3_api->vfs_unregister | ||||
| #define sqlite3_threadsafe             sqlite3_api->xthreadsafe | ||||
| #define sqlite3_result_zeroblob        sqlite3_api->result_zeroblob | ||||
| #define sqlite3_result_error_code      sqlite3_api->result_error_code | ||||
| #define sqlite3_test_control           sqlite3_api->test_control | ||||
| #define sqlite3_randomness             sqlite3_api->randomness | ||||
| #define sqlite3_context_db_handle      sqlite3_api->context_db_handle | ||||
| #define sqlite3_extended_result_codes  sqlite3_api->extended_result_codes | ||||
| #define sqlite3_limit                  sqlite3_api->limit | ||||
| #define sqlite3_next_stmt              sqlite3_api->next_stmt | ||||
| #define sqlite3_sql                    sqlite3_api->sql | ||||
| #define sqlite3_status                 sqlite3_api->status | ||||
| #define sqlite3_backup_finish          sqlite3_api->backup_finish | ||||
| #define sqlite3_backup_init            sqlite3_api->backup_init | ||||
| #define sqlite3_backup_pagecount       sqlite3_api->backup_pagecount | ||||
| #define sqlite3_backup_remaining       sqlite3_api->backup_remaining | ||||
| #define sqlite3_backup_step            sqlite3_api->backup_step | ||||
| #define sqlite3_compileoption_get      sqlite3_api->compileoption_get | ||||
| #define sqlite3_compileoption_used     sqlite3_api->compileoption_used | ||||
| #define sqlite3_create_function_v2     sqlite3_api->create_function_v2 | ||||
| #define sqlite3_db_config              sqlite3_api->db_config | ||||
| #define sqlite3_db_mutex               sqlite3_api->db_mutex | ||||
| #define sqlite3_db_status              sqlite3_api->db_status | ||||
| #define sqlite3_extended_errcode       sqlite3_api->extended_errcode | ||||
| #define sqlite3_log                    sqlite3_api->log | ||||
| #define sqlite3_soft_heap_limit64      sqlite3_api->soft_heap_limit64 | ||||
| #define sqlite3_sourceid               sqlite3_api->sourceid | ||||
| #define sqlite3_stmt_status            sqlite3_api->stmt_status | ||||
| #define sqlite3_strnicmp               sqlite3_api->strnicmp | ||||
| #define sqlite3_unlock_notify          sqlite3_api->unlock_notify | ||||
| #define sqlite3_wal_autocheckpoint     sqlite3_api->wal_autocheckpoint | ||||
| #define sqlite3_wal_checkpoint         sqlite3_api->wal_checkpoint | ||||
| #define sqlite3_wal_hook               sqlite3_api->wal_hook | ||||
| #define sqlite3_blob_reopen            sqlite3_api->blob_reopen | ||||
| #define sqlite3_vtab_config            sqlite3_api->vtab_config | ||||
| #define sqlite3_vtab_on_conflict       sqlite3_api->vtab_on_conflict | ||||
| /* Version 3.7.16 and later */ | ||||
| #define sqlite3_close_v2               sqlite3_api->close_v2 | ||||
| #define sqlite3_db_filename            sqlite3_api->db_filename | ||||
| #define sqlite3_db_readonly            sqlite3_api->db_readonly | ||||
| #define sqlite3_db_release_memory      sqlite3_api->db_release_memory | ||||
| #define sqlite3_errstr                 sqlite3_api->errstr | ||||
| #define sqlite3_stmt_busy              sqlite3_api->stmt_busy | ||||
| #define sqlite3_stmt_readonly          sqlite3_api->stmt_readonly | ||||
| #define sqlite3_stricmp                sqlite3_api->stricmp | ||||
| #define sqlite3_uri_boolean            sqlite3_api->uri_boolean | ||||
| #define sqlite3_uri_int64              sqlite3_api->uri_int64 | ||||
| #define sqlite3_uri_parameter          sqlite3_api->uri_parameter | ||||
| #define sqlite3_uri_vsnprintf          sqlite3_api->vsnprintf | ||||
| #define sqlite3_wal_checkpoint_v2      sqlite3_api->wal_checkpoint_v2 | ||||
| /* Version 3.8.7 and later */ | ||||
| #define sqlite3_auto_extension         sqlite3_api->auto_extension | ||||
| #define sqlite3_bind_blob64            sqlite3_api->bind_blob64 | ||||
| #define sqlite3_bind_text64            sqlite3_api->bind_text64 | ||||
| #define sqlite3_cancel_auto_extension  sqlite3_api->cancel_auto_extension | ||||
| #define sqlite3_load_extension         sqlite3_api->load_extension | ||||
| #define sqlite3_malloc64               sqlite3_api->malloc64 | ||||
| #define sqlite3_msize                  sqlite3_api->msize | ||||
| #define sqlite3_realloc64              sqlite3_api->realloc64 | ||||
| #define sqlite3_reset_auto_extension   sqlite3_api->reset_auto_extension | ||||
| #define sqlite3_result_blob64          sqlite3_api->result_blob64 | ||||
| #define sqlite3_result_text64          sqlite3_api->result_text64 | ||||
| #define sqlite3_strglob                sqlite3_api->strglob | ||||
| /* Version 3.8.11 and later */ | ||||
| #define sqlite3_value_dup              sqlite3_api->value_dup | ||||
| #define sqlite3_value_free             sqlite3_api->value_free | ||||
| #define sqlite3_result_zeroblob64      sqlite3_api->result_zeroblob64 | ||||
| #define sqlite3_bind_zeroblob64        sqlite3_api->bind_zeroblob64 | ||||
| /* Version 3.9.0 and later */ | ||||
| #define sqlite3_value_subtype          sqlite3_api->value_subtype | ||||
| #define sqlite3_result_subtype         sqlite3_api->result_subtype | ||||
| /* Version 3.10.0 and later */ | ||||
| #define sqlite3_status64               sqlite3_api->status64 | ||||
| #define sqlite3_strlike                sqlite3_api->strlike | ||||
| #define sqlite3_db_cacheflush          sqlite3_api->db_cacheflush | ||||
| /* Version 3.12.0 and later */ | ||||
| #define sqlite3_system_errno           sqlite3_api->system_errno | ||||
| /* Version 3.14.0 and later */ | ||||
| #define sqlite3_trace_v2               sqlite3_api->trace_v2 | ||||
| #define sqlite3_expanded_sql           sqlite3_api->expanded_sql | ||||
| #endif /* !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 | ||||
|   ** extension */ | ||||
| # define SQLITE_EXTENSION_INIT1     const sqlite3_api_routines *sqlite3_api=0; | ||||
| # define SQLITE_EXTENSION_INIT2(v)  sqlite3_api=v; | ||||
| # define SQLITE_EXTENSION_INIT3     \ | ||||
|     extern const sqlite3_api_routines *sqlite3_api; | ||||
| #else | ||||
|   /* This case when the file is being statically linked into the | ||||
|   ** application */ | ||||
| # define SQLITE_EXTENSION_INIT1     /*no-op*/ | ||||
| # define SQLITE_EXTENSION_INIT2(v)  (void)v; /* unused parameter */ | ||||
| # define SQLITE_EXTENSION_INIT3     /*no-op*/ | ||||
| #endif | ||||
|  | ||||
| #endif /* SQLITE3EXT_H */ | ||||
| #else // USE_LIBSQLITE3 | ||||
|  // If users really want to link against the system sqlite3 we | ||||
| // need to make this file a noop. | ||||
|  #endif | ||||
							
								
								
									
										415
									
								
								vendor/github.com/mattn/go-sqlite3/tracecallback.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										415
									
								
								vendor/github.com/mattn/go-sqlite3/tracecallback.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,415 @@ | ||||
| // 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 | ||||
| // license that can be found in the LICENSE file. | ||||
| // +build trace | ||||
|  | ||||
| package sqlite3 | ||||
|  | ||||
| /* | ||||
| #ifndef USE_LIBSQLITE3 | ||||
| #include <sqlite3-binding.h> | ||||
| #else | ||||
| #include <sqlite3.h> | ||||
| #endif | ||||
| #include <stdlib.h> | ||||
|  | ||||
| void stepTrampoline(sqlite3_context*, int, sqlite3_value**); | ||||
| void doneTrampoline(sqlite3_context*); | ||||
| void traceCallbackTrampoline(unsigned traceEventCode, void *ctx, void *p, void *x); | ||||
| */ | ||||
| import "C" | ||||
|  | ||||
| import ( | ||||
| 	"errors" | ||||
| 	"fmt" | ||||
| 	"reflect" | ||||
| 	"strings" | ||||
| 	"sync" | ||||
| 	"unsafe" | ||||
| ) | ||||
|  | ||||
| // Trace... constants identify the possible events causing callback invocation. | ||||
| // Values are same as the corresponding SQLite Trace Event Codes. | ||||
| const ( | ||||
| 	TraceStmt    = C.SQLITE_TRACE_STMT | ||||
| 	TraceProfile = C.SQLITE_TRACE_PROFILE | ||||
| 	TraceRow     = C.SQLITE_TRACE_ROW | ||||
| 	TraceClose   = C.SQLITE_TRACE_CLOSE | ||||
| ) | ||||
|  | ||||
| type TraceInfo struct { | ||||
| 	// Pack together the shorter fields, to keep the struct smaller. | ||||
| 	// On a 64-bit machine there would be padding | ||||
| 	// between EventCode and ConnHandle; having AutoCommit here is "free": | ||||
| 	EventCode  uint32 | ||||
| 	AutoCommit bool | ||||
| 	ConnHandle uintptr | ||||
|  | ||||
| 	// Usually filled, unless EventCode = TraceClose = SQLITE_TRACE_CLOSE: | ||||
| 	// identifier for a prepared statement: | ||||
| 	StmtHandle uintptr | ||||
|  | ||||
| 	// Two strings filled when EventCode = TraceStmt = SQLITE_TRACE_STMT: | ||||
| 	// (1) either the unexpanded SQL text of the prepared statement, or | ||||
| 	//     an SQL comment that indicates the invocation of a trigger; | ||||
| 	// (2) expanded SQL, if requested and if (1) is not an SQL comment. | ||||
| 	StmtOrTrigger string | ||||
| 	ExpandedSQL   string // only if requested (TraceConfig.WantExpandedSQL = true) | ||||
|  | ||||
| 	// filled when EventCode = TraceProfile = SQLITE_TRACE_PROFILE: | ||||
| 	// estimated number of nanoseconds that the prepared statement took to run: | ||||
| 	RunTimeNanosec int64 | ||||
|  | ||||
| 	DBError Error | ||||
| } | ||||
|  | ||||
| // TraceUserCallback gives the signature for a trace function | ||||
| // provided by the user (Go application programmer). | ||||
| // SQLite 3.14 documentation (as of September 2, 2016) | ||||
| // for SQL Trace Hook = sqlite3_trace_v2(): | ||||
| // The integer return value from the callback is currently ignored, | ||||
| // though this may change in future releases. Callback implementations | ||||
| // should return zero to ensure future compatibility. | ||||
| type TraceUserCallback func(TraceInfo) int | ||||
|  | ||||
| type TraceConfig struct { | ||||
| 	Callback        TraceUserCallback | ||||
| 	EventMask       uint | ||||
| 	WantExpandedSQL bool | ||||
| } | ||||
|  | ||||
| func fillDBError(dbErr *Error, db *C.sqlite3) { | ||||
| 	// See SQLiteConn.lastError(), in file 'sqlite3.go' at the time of writing (Sept 5, 2016) | ||||
| 	dbErr.Code = ErrNo(C.sqlite3_errcode(db)) | ||||
| 	dbErr.ExtendedCode = ErrNoExtended(C.sqlite3_extended_errcode(db)) | ||||
| 	dbErr.err = C.GoString(C.sqlite3_errmsg(db)) | ||||
| } | ||||
|  | ||||
| func fillExpandedSQL(info *TraceInfo, db *C.sqlite3, pStmt unsafe.Pointer) { | ||||
| 	if pStmt == nil { | ||||
| 		panic("No SQLite statement pointer in P arg of trace_v2 callback") | ||||
| 	} | ||||
|  | ||||
| 	expSQLiteCStr := C.sqlite3_expanded_sql((*C.sqlite3_stmt)(pStmt)) | ||||
| 	if expSQLiteCStr == nil { | ||||
| 		fillDBError(&info.DBError, db) | ||||
| 		return | ||||
| 	} | ||||
| 	info.ExpandedSQL = C.GoString(expSQLiteCStr) | ||||
| } | ||||
|  | ||||
| //export traceCallbackTrampoline | ||||
| func traceCallbackTrampoline( | ||||
| 	traceEventCode uint, | ||||
| 	// Parameter named 'C' in SQLite docs = Context given at registration: | ||||
| 	ctx unsafe.Pointer, | ||||
| 	// Parameter named 'P' in SQLite docs (Primary event data?): | ||||
| 	p unsafe.Pointer, | ||||
| 	// Parameter named 'X' in SQLite docs (eXtra event data?): | ||||
| 	xValue unsafe.Pointer) int { | ||||
|  | ||||
| 	if ctx == nil { | ||||
| 		panic(fmt.Sprintf("No context (ev 0x%x)", traceEventCode)) | ||||
| 	} | ||||
|  | ||||
| 	contextDB := (*C.sqlite3)(ctx) | ||||
| 	connHandle := uintptr(ctx) | ||||
|  | ||||
| 	var traceConf TraceConfig | ||||
| 	var found bool | ||||
| 	if traceEventCode == TraceClose { | ||||
| 		// clean up traceMap: 'pop' means get and delete | ||||
| 		traceConf, found = popTraceMapping(connHandle) | ||||
| 	} else { | ||||
| 		traceConf, found = lookupTraceMapping(connHandle) | ||||
| 	} | ||||
|  | ||||
| 	if !found { | ||||
| 		panic(fmt.Sprintf("Mapping not found for handle 0x%x (ev 0x%x)", | ||||
| 			connHandle, traceEventCode)) | ||||
| 	} | ||||
|  | ||||
| 	var info TraceInfo | ||||
|  | ||||
| 	info.EventCode = uint32(traceEventCode) | ||||
| 	info.AutoCommit = (int(C.sqlite3_get_autocommit(contextDB)) != 0) | ||||
| 	info.ConnHandle = connHandle | ||||
|  | ||||
| 	switch traceEventCode { | ||||
| 	case TraceStmt: | ||||
| 		info.StmtHandle = uintptr(p) | ||||
|  | ||||
| 		var xStr string | ||||
| 		if xValue != nil { | ||||
| 			xStr = C.GoString((*C.char)(xValue)) | ||||
| 		} | ||||
| 		info.StmtOrTrigger = xStr | ||||
| 		if !strings.HasPrefix(xStr, "--") { | ||||
| 			// Not SQL comment, therefore the current event | ||||
| 			// is not related to a trigger. | ||||
| 			// The user might want to receive the expanded SQL; | ||||
| 			// let's check: | ||||
| 			if traceConf.WantExpandedSQL { | ||||
| 				fillExpandedSQL(&info, contextDB, p) | ||||
| 			} | ||||
| 		} | ||||
|  | ||||
| 	case TraceProfile: | ||||
| 		info.StmtHandle = uintptr(p) | ||||
|  | ||||
| 		if xValue == nil { | ||||
| 			panic("NULL pointer in X arg of trace_v2 callback for SQLITE_TRACE_PROFILE event") | ||||
| 		} | ||||
|  | ||||
| 		info.RunTimeNanosec = *(*int64)(xValue) | ||||
|  | ||||
| 		// sample the error //TODO: is it safe? is it useful? | ||||
| 		fillDBError(&info.DBError, contextDB) | ||||
|  | ||||
| 	case TraceRow: | ||||
| 		info.StmtHandle = uintptr(p) | ||||
|  | ||||
| 	case TraceClose: | ||||
| 		handle := uintptr(p) | ||||
| 		if handle != info.ConnHandle { | ||||
| 			panic(fmt.Sprintf("Different conn handle 0x%x (expected 0x%x) in SQLITE_TRACE_CLOSE event.", | ||||
| 				handle, info.ConnHandle)) | ||||
| 		} | ||||
|  | ||||
| 	default: | ||||
| 		// Pass unsupported events to the user callback (if configured); | ||||
| 		// let the user callback decide whether to panic or ignore them. | ||||
| 	} | ||||
|  | ||||
| 	// Do not execute user callback when the event was not requested by user! | ||||
| 	// Remember that the Close event is always selected when | ||||
| 	// registering this callback trampoline with SQLite --- for cleanup. | ||||
| 	// In the future there may be more events forced to "selected" in SQLite | ||||
| 	// for the driver's needs. | ||||
| 	if traceConf.EventMask&traceEventCode == 0 { | ||||
| 		return 0 | ||||
| 	} | ||||
|  | ||||
| 	r := 0 | ||||
| 	if traceConf.Callback != nil { | ||||
| 		r = traceConf.Callback(info) | ||||
| 	} | ||||
| 	return r | ||||
| } | ||||
|  | ||||
| type traceMapEntry struct { | ||||
| 	config TraceConfig | ||||
| } | ||||
|  | ||||
| var traceMapLock sync.Mutex | ||||
| var traceMap = make(map[uintptr]traceMapEntry) | ||||
|  | ||||
| func addTraceMapping(connHandle uintptr, traceConf TraceConfig) { | ||||
| 	traceMapLock.Lock() | ||||
| 	defer traceMapLock.Unlock() | ||||
|  | ||||
| 	oldEntryCopy, found := traceMap[connHandle] | ||||
| 	if found { | ||||
| 		panic(fmt.Sprintf("Adding trace config %v: handle 0x%x already registered (%v).", | ||||
| 			traceConf, connHandle, oldEntryCopy.config)) | ||||
| 	} | ||||
| 	traceMap[connHandle] = traceMapEntry{config: traceConf} | ||||
| 	fmt.Printf("Added trace config %v: handle 0x%x.\n", traceConf, connHandle) | ||||
| } | ||||
|  | ||||
| func lookupTraceMapping(connHandle uintptr) (TraceConfig, bool) { | ||||
| 	traceMapLock.Lock() | ||||
| 	defer traceMapLock.Unlock() | ||||
|  | ||||
| 	entryCopy, found := traceMap[connHandle] | ||||
| 	return entryCopy.config, found | ||||
| } | ||||
|  | ||||
| // 'pop' = get and delete from map before returning the value to the caller | ||||
| func popTraceMapping(connHandle uintptr) (TraceConfig, bool) { | ||||
| 	traceMapLock.Lock() | ||||
| 	defer traceMapLock.Unlock() | ||||
|  | ||||
| 	entryCopy, found := traceMap[connHandle] | ||||
| 	if found { | ||||
| 		delete(traceMap, connHandle) | ||||
| 		fmt.Printf("Pop handle 0x%x: deleted trace config %v.\n", connHandle, entryCopy.config) | ||||
| 	} | ||||
| 	return entryCopy.config, found | ||||
| } | ||||
|  | ||||
| // RegisterAggregator makes a Go type available as a SQLite aggregation function. | ||||
| // | ||||
| // Because aggregation is incremental, it's implemented in Go with a | ||||
| // type that has 2 methods: func Step(values) accumulates one row of | ||||
| // data into the accumulator, and func Done() ret finalizes and | ||||
| // returns the aggregate value. "values" and "ret" may be any type | ||||
| // supported by RegisterFunc. | ||||
| // | ||||
| // RegisterAggregator takes as implementation a constructor function | ||||
| // that constructs an instance of the aggregator type each time an | ||||
| // aggregation begins. The constructor must return a pointer to a | ||||
| // type, or an interface that implements Step() and Done(). | ||||
| // | ||||
| // The constructor function and the Step/Done methods may optionally | ||||
| // return an error in addition to their other return values. | ||||
| // | ||||
| // See _example/go_custom_funcs for a detailed example. | ||||
| func (c *SQLiteConn) RegisterAggregator(name string, impl interface{}, pure bool) error { | ||||
| 	var ai aggInfo | ||||
| 	ai.constructor = reflect.ValueOf(impl) | ||||
| 	t := ai.constructor.Type() | ||||
| 	if t.Kind() != reflect.Func { | ||||
| 		return errors.New("non-function passed to RegisterAggregator") | ||||
| 	} | ||||
| 	if t.NumOut() != 1 && t.NumOut() != 2 { | ||||
| 		return errors.New("SQLite aggregator constructors must return 1 or 2 values") | ||||
| 	} | ||||
| 	if t.NumOut() == 2 && !t.Out(1).Implements(reflect.TypeOf((*error)(nil)).Elem()) { | ||||
| 		return errors.New("Second return value of SQLite function must be error") | ||||
| 	} | ||||
| 	if t.NumIn() != 0 { | ||||
| 		return errors.New("SQLite aggregator constructors must not have arguments") | ||||
| 	} | ||||
|  | ||||
| 	agg := t.Out(0) | ||||
| 	switch agg.Kind() { | ||||
| 	case reflect.Ptr, reflect.Interface: | ||||
| 	default: | ||||
| 		return errors.New("SQlite aggregator constructor must return a pointer object") | ||||
| 	} | ||||
| 	stepFn, found := agg.MethodByName("Step") | ||||
| 	if !found { | ||||
| 		return errors.New("SQlite aggregator doesn't have a Step() function") | ||||
| 	} | ||||
| 	step := stepFn.Type | ||||
| 	if step.NumOut() != 0 && step.NumOut() != 1 { | ||||
| 		return errors.New("SQlite aggregator Step() function must return 0 or 1 values") | ||||
| 	} | ||||
| 	if step.NumOut() == 1 && !step.Out(0).Implements(reflect.TypeOf((*error)(nil)).Elem()) { | ||||
| 		return errors.New("type of SQlite aggregator Step() return value must be error") | ||||
| 	} | ||||
|  | ||||
| 	stepNArgs := step.NumIn() | ||||
| 	start := 0 | ||||
| 	if agg.Kind() == reflect.Ptr { | ||||
| 		// Skip over the method receiver | ||||
| 		stepNArgs-- | ||||
| 		start++ | ||||
| 	} | ||||
| 	if step.IsVariadic() { | ||||
| 		stepNArgs-- | ||||
| 	} | ||||
| 	for i := start; i < start+stepNArgs; i++ { | ||||
| 		conv, err := callbackArg(step.In(i)) | ||||
| 		if err != nil { | ||||
| 			return err | ||||
| 		} | ||||
| 		ai.stepArgConverters = append(ai.stepArgConverters, conv) | ||||
| 	} | ||||
| 	if step.IsVariadic() { | ||||
| 		conv, err := callbackArg(t.In(start + stepNArgs).Elem()) | ||||
| 		if err != nil { | ||||
| 			return err | ||||
| 		} | ||||
| 		ai.stepVariadicConverter = conv | ||||
| 		// Pass -1 to sqlite so that it allows any number of | ||||
| 		// arguments. The call helper verifies that the minimum number | ||||
| 		// of arguments is present for variadic functions. | ||||
| 		stepNArgs = -1 | ||||
| 	} | ||||
|  | ||||
| 	doneFn, found := agg.MethodByName("Done") | ||||
| 	if !found { | ||||
| 		return errors.New("SQlite aggregator doesn't have a Done() function") | ||||
| 	} | ||||
| 	done := doneFn.Type | ||||
| 	doneNArgs := done.NumIn() | ||||
| 	if agg.Kind() == reflect.Ptr { | ||||
| 		// Skip over the method receiver | ||||
| 		doneNArgs-- | ||||
| 	} | ||||
| 	if doneNArgs != 0 { | ||||
| 		return errors.New("SQlite aggregator Done() function must have no arguments") | ||||
| 	} | ||||
| 	if done.NumOut() != 1 && done.NumOut() != 2 { | ||||
| 		return errors.New("SQLite aggregator Done() function must return 1 or 2 values") | ||||
| 	} | ||||
| 	if done.NumOut() == 2 && !done.Out(1).Implements(reflect.TypeOf((*error)(nil)).Elem()) { | ||||
| 		return errors.New("second return value of SQLite aggregator Done() function must be error") | ||||
| 	} | ||||
|  | ||||
| 	conv, err := callbackRet(done.Out(0)) | ||||
| 	if err != nil { | ||||
| 		return err | ||||
| 	} | ||||
| 	ai.doneRetConverter = conv | ||||
| 	ai.active = make(map[int64]reflect.Value) | ||||
| 	ai.next = 1 | ||||
|  | ||||
| 	// ai must outlast the database connection, or we'll have dangling pointers. | ||||
| 	c.aggregators = append(c.aggregators, &ai) | ||||
|  | ||||
| 	cname := C.CString(name) | ||||
| 	defer C.free(unsafe.Pointer(cname)) | ||||
| 	opts := C.SQLITE_UTF8 | ||||
| 	if pure { | ||||
| 		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))) | ||||
| 	if rv != C.SQLITE_OK { | ||||
| 		return c.lastError() | ||||
| 	} | ||||
| 	return nil | ||||
| } | ||||
|  | ||||
| // SetTrace installs or removes the trace callback for the given database connection. | ||||
| // It's not named 'RegisterTrace' because only one callback can be kept and called. | ||||
| // Calling SetTrace a second time on same database connection | ||||
| // overrides (cancels) any prior callback and all its settings: | ||||
| // event mask, etc. | ||||
| func (c *SQLiteConn) SetTrace(requested *TraceConfig) error { | ||||
| 	connHandle := uintptr(unsafe.Pointer(c.db)) | ||||
|  | ||||
| 	_, _ = popTraceMapping(connHandle) | ||||
|  | ||||
| 	if requested == nil { | ||||
| 		// The traceMap entry was deleted already by popTraceMapping(): | ||||
| 		// can disable all events now, no need to watch for TraceClose. | ||||
| 		err := c.setSQLiteTrace(0) | ||||
| 		return err | ||||
| 	} | ||||
|  | ||||
| 	reqCopy := *requested | ||||
|  | ||||
| 	// Disable potentially expensive operations | ||||
| 	// if their result will not be used. We are doing this | ||||
| 	// just in case the caller provided nonsensical input. | ||||
| 	if reqCopy.EventMask&TraceStmt == 0 { | ||||
| 		reqCopy.WantExpandedSQL = false | ||||
| 	} | ||||
|  | ||||
| 	addTraceMapping(connHandle, reqCopy) | ||||
|  | ||||
| 	// The callback trampoline function does cleanup on Close event, | ||||
| 	// regardless of the presence or absence of the user callback. | ||||
| 	// Therefore it needs the Close event to be selected: | ||||
| 	actualEventMask := reqCopy.EventMask | TraceClose | ||||
| 	err := c.setSQLiteTrace(actualEventMask) | ||||
| 	return err | ||||
| } | ||||
|  | ||||
| func (c *SQLiteConn) setSQLiteTrace(sqliteEventMask uint) error { | ||||
| 	rv := C.sqlite3_trace_v2(c.db, | ||||
| 		C.uint(sqliteEventMask), | ||||
| 		(*[0]byte)(unsafe.Pointer(C.traceCallbackTrampoline)), | ||||
| 		unsafe.Pointer(c.db)) // Fourth arg is same as first: we are | ||||
| 	// passing the database connection handle as callback context. | ||||
|  | ||||
| 	if rv != C.SQLITE_OK { | ||||
| 		return c.lastError() | ||||
| 	} | ||||
| 	return nil | ||||
| } | ||||
							
								
								
									
										9
									
								
								vendor/github.com/mattn/go-sqlite3/tracecallback_noimpl.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										9
									
								
								vendor/github.com/mattn/go-sqlite3/tracecallback_noimpl.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,9 @@ | ||||
| // +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") | ||||
| } | ||||
		Reference in New Issue
	
	Block a user
	 Thomas Boerger
					Thomas Boerger