aboutsummaryrefslogtreecommitdiff
path: root/vendor/github.com/mattn
diff options
context:
space:
mode:
authorNiall Sheridan <nsheridan@gmail.com>2017-10-18 13:15:14 +0100
committerNiall Sheridan <niall@intercom.io>2017-10-18 13:25:46 +0100
commit7b320119ba532fd409ec7dade7ad02011c309599 (patch)
treea39860f35b55e6cc499f8f5bfa969138c5dd6b73 /vendor/github.com/mattn
parent7c99874c7a3e7a89716f3ee0cdf696532e35ae35 (diff)
Update dependencies
Diffstat (limited to 'vendor/github.com/mattn')
-rw-r--r--vendor/github.com/mattn/go-sqlite3/README.md12
-rw-r--r--vendor/github.com/mattn/go-sqlite3/callback.go24
-rw-r--r--vendor/github.com/mattn/go-sqlite3/sqlite3.go177
-rw-r--r--vendor/github.com/mattn/go-sqlite3/sqlite3_libsqlite3.go1
-rw-r--r--vendor/github.com/mattn/go-sqlite3/sqlite3_other.go1
5 files changed, 193 insertions, 22 deletions
diff --git a/vendor/github.com/mattn/go-sqlite3/README.md b/vendor/github.com/mattn/go-sqlite3/README.md
index 8369013..ad00f10 100644
--- a/vendor/github.com/mattn/go-sqlite3/README.md
+++ b/vendor/github.com/mattn/go-sqlite3/README.md
@@ -17,11 +17,11 @@ 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
-------------
@@ -50,7 +50,7 @@ FAQ
* Can't build go-sqlite3 on windows 64bit.
- > Probably, you are using go 1.0, go1.0 has a problem when it comes to compiling/linking on windows 64bit.
+ > Probably, you are using go 1.0, go1.0 has a problem when it comes to compiling/linking on windows 64bit.
> See: [#27](https://github.com/mattn/go-sqlite3/issues/27)
* Getting insert error while query is opened.
@@ -65,13 +65,13 @@ FAQ
* Want to get time.Time with current locale
- Use `loc=auto` in SQLite3 filename schema like `file:foo.db?loc=auto`.
+ Use `_loc=auto` in SQLite3 filename schema like `file:foo.db?_loc=auto`.
-* Can use this in multiple routines concurrently?
+* Can I use this in multiple routines concurrently?
Yes for readonly. But, No for writable. See [#50](https://github.com/mattn/go-sqlite3/issues/50), [#51](https://github.com/mattn/go-sqlite3/issues/51), [#209](https://github.com/mattn/go-sqlite3/issues/209).
-* Why is it racy if I use a `sql.Open("sqlite", ":memory:")` database?
+* Why is it racy if I use a `sql.Open("sqlite3", ":memory:")` database?
Each connection to :memory: opens a brand new in-memory sql database, so if
the stdlib's sql engine happens to open another connection and you've only
diff --git a/vendor/github.com/mattn/go-sqlite3/callback.go b/vendor/github.com/mattn/go-sqlite3/callback.go
index 48fc63a..29ece3d 100644
--- a/vendor/github.com/mattn/go-sqlite3/callback.go
+++ b/vendor/github.com/mattn/go-sqlite3/callback.go
@@ -53,6 +53,30 @@ func doneTrampoline(ctx *C.sqlite3_context) {
ai.Done(ctx)
}
+//export compareTrampoline
+func compareTrampoline(handlePtr uintptr, la C.int, a *C.char, lb C.int, b *C.char) C.int {
+ cmp := lookupHandle(handlePtr).(func(string, string) int)
+ return C.int(cmp(C.GoStringN(a, la), C.GoStringN(b, lb)))
+}
+
+//export commitHookTrampoline
+func commitHookTrampoline(handle uintptr) int {
+ callback := lookupHandle(handle).(func() int)
+ return callback()
+}
+
+//export rollbackHookTrampoline
+func rollbackHookTrampoline(handle uintptr) {
+ callback := lookupHandle(handle).(func())
+ callback()
+}
+
+//export updateHookTrampoline
+func updateHookTrampoline(handle uintptr, op int, db *C.char, table *C.char, rowid int64) {
+ callback := lookupHandle(handle).(func(int, string, string, int64))
+ callback(op, C.GoString(db), C.GoString(table), rowid)
+}
+
// Use handles to avoid passing Go pointers to C.
type handleVal struct {
diff --git a/vendor/github.com/mattn/go-sqlite3/sqlite3.go b/vendor/github.com/mattn/go-sqlite3/sqlite3.go
index 33b9b9c..1ff58c3 100644
--- a/vendor/github.com/mattn/go-sqlite3/sqlite3.go
+++ b/vendor/github.com/mattn/go-sqlite3/sqlite3.go
@@ -7,7 +7,7 @@ package sqlite3
/*
#cgo CFLAGS: -std=gnu99
-#cgo CFLAGS: -DSQLITE_ENABLE_RTREE -DSQLITE_THREADSAFE
+#cgo CFLAGS: -DSQLITE_ENABLE_RTREE -DSQLITE_THREADSAFE=1
#cgo CFLAGS: -DSQLITE_ENABLE_FTS3 -DSQLITE_ENABLE_FTS3_PARENTHESIS -DSQLITE_ENABLE_FTS4_UNICODE61
#cgo CFLAGS: -DSQLITE_TRACE_SIZE_LIMIT=15
#cgo CFLAGS: -DSQLITE_DISABLE_INTRINSIC
@@ -100,6 +100,11 @@ int _sqlite3_create_function(
}
void callbackTrampoline(sqlite3_context*, int, sqlite3_value**);
+
+int compareTrampoline(void*, int, char*, int, char*);
+int commitHookTrampoline(void*);
+void rollbackHookTrampoline(void*);
+void updateHookTrampoline(void*, int, char*, char*, sqlite3_int64);
*/
import "C"
import (
@@ -113,6 +118,7 @@ import (
"runtime"
"strconv"
"strings"
+ "sync"
"time"
"unsafe"
@@ -149,6 +155,12 @@ func Version() (libVersion string, libVersionNumber int, sourceID string) {
return libVersion, libVersionNumber, sourceID
}
+const (
+ SQLITE_DELETE = C.SQLITE_DELETE
+ SQLITE_INSERT = C.SQLITE_INSERT
+ SQLITE_UPDATE = C.SQLITE_UPDATE
+)
+
// SQLiteDriver implement sql.Driver.
type SQLiteDriver struct {
Extensions []string
@@ -157,6 +169,7 @@ type SQLiteDriver struct {
// SQLiteConn implement sql.Conn.
type SQLiteConn struct {
+ mu sync.Mutex
db *C.sqlite3
loc *time.Location
txlock string
@@ -171,6 +184,7 @@ type SQLiteTx struct {
// SQLiteStmt implement sql.Stmt.
type SQLiteStmt struct {
+ mu sync.Mutex
c *SQLiteConn
s *C.sqlite3_stmt
t string
@@ -191,6 +205,7 @@ type SQLiteRows struct {
cols []string
decltype []string
cls bool
+ closed bool
done chan struct{}
}
@@ -313,6 +328,74 @@ func (tx *SQLiteTx) Rollback() error {
return err
}
+// RegisterCollation makes a Go function available as a collation.
+//
+// cmp receives two UTF-8 strings, a and b. The result should be 0 if
+// a==b, -1 if a < b, and +1 if a > b.
+//
+// cmp must always return the same result given the same
+// inputs. Additionally, it must have the following properties for all
+// strings A, B and C: if A==B then B==A; if A==B and B==C then A==C;
+// if A<B then B>A; if A<B and B<C then A<C.
+//
+// If cmp does not obey these constraints, sqlite3's behavior is
+// undefined when the collation is used.
+func (c *SQLiteConn) RegisterCollation(name string, cmp func(string, string) int) error {
+ handle := newHandle(c, cmp)
+ cname := C.CString(name)
+ defer C.free(unsafe.Pointer(cname))
+ rv := C.sqlite3_create_collation(c.db, cname, C.SQLITE_UTF8, unsafe.Pointer(handle), (*[0]byte)(unsafe.Pointer(C.compareTrampoline)))
+ if rv != C.SQLITE_OK {
+ return c.lastError()
+ }
+ return nil
+}
+
+// RegisterCommitHook sets the commit hook for a connection.
+//
+// If the callback returns non-zero the transaction will become a rollback.
+//
+// If there is an existing commit hook for this connection, it will be
+// removed. If callback is nil the existing hook (if any) will be removed
+// without creating a new one.
+func (c *SQLiteConn) RegisterCommitHook(callback func() int) {
+ if callback == nil {
+ C.sqlite3_commit_hook(c.db, nil, nil)
+ } else {
+ C.sqlite3_commit_hook(c.db, (*[0]byte)(unsafe.Pointer(C.commitHookTrampoline)), unsafe.Pointer(newHandle(c, callback)))
+ }
+}
+
+// RegisterRollbackHook sets the rollback hook for a connection.
+//
+// If there is an existing rollback hook for this connection, it will be
+// removed. If callback is nil the existing hook (if any) will be removed
+// without creating a new one.
+func (c *SQLiteConn) RegisterRollbackHook(callback func()) {
+ if callback == nil {
+ C.sqlite3_rollback_hook(c.db, nil, nil)
+ } else {
+ C.sqlite3_rollback_hook(c.db, (*[0]byte)(unsafe.Pointer(C.rollbackHookTrampoline)), unsafe.Pointer(newHandle(c, callback)))
+ }
+}
+
+// RegisterUpdateHook sets the update hook for a connection.
+//
+// The parameters to the callback are the operation (one of the constants
+// SQLITE_INSERT, SQLITE_DELETE, or SQLITE_UPDATE), the database name, the
+// table name, and the rowid.
+//
+// If there is an existing update hook for this connection, it will be
+// removed. If callback is nil the existing hook (if any) will be removed
+// without creating a new one.
+func (c *SQLiteConn) RegisterUpdateHook(callback func(int, string, string, int64)) {
+ if callback == nil {
+ C.sqlite3_update_hook(c.db, nil, nil)
+ } else {
+ C.sqlite3_update_hook(c.db, (*[0]byte)(unsafe.Pointer(C.updateHookTrampoline)), unsafe.Pointer(newHandle(c, callback)))
+ }
+}
+
// RegisterFunc makes a Go function available as a SQLite function.
//
// The Go function can have arguments of the following types: any
@@ -543,6 +626,8 @@ func errorString(err Error) string {
// "deferred", "exclusive".
// _foreign_keys=X
// Enable or disable enforcement of foreign keys. X can be 1 or 0.
+// _recursive_triggers=X
+// Enable or disable recursive triggers. X can be 1 or 0.
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")
@@ -552,6 +637,7 @@ func (d *SQLiteDriver) Open(dsn string) (driver.Conn, error) {
txlock := "BEGIN"
busyTimeout := 5000
foreignKeys := -1
+ recursiveTriggers := -1
pos := strings.IndexRune(dsn, '?')
if pos >= 1 {
params, err := url.ParseQuery(dsn[pos+1:])
@@ -606,6 +692,18 @@ func (d *SQLiteDriver) Open(dsn string) (driver.Conn, error) {
}
}
+ // _recursive_triggers
+ if val := params.Get("_recursive_triggers"); val != "" {
+ switch val {
+ case "1":
+ recursiveTriggers = 1
+ case "0":
+ recursiveTriggers = 0
+ default:
+ return nil, fmt.Errorf("Invalid _recursive_triggers: %v", val)
+ }
+ }
+
if !strings.HasPrefix(dsn, "file:") {
dsn = dsn[:pos]
}
@@ -652,6 +750,17 @@ func (d *SQLiteDriver) Open(dsn string) (driver.Conn, error) {
return nil, err
}
}
+ if recursiveTriggers == 0 {
+ if err := exec("PRAGMA recursive_triggers = OFF;"); err != nil {
+ C.sqlite3_close_v2(db)
+ return nil, err
+ }
+ } else if recursiveTriggers == 1 {
+ if err := exec("PRAGMA recursive_triggers = ON;"); err != nil {
+ C.sqlite3_close_v2(db)
+ return nil, err
+ }
+ }
conn := &SQLiteConn{db: db, loc: loc, txlock: txlock}
@@ -679,11 +788,22 @@ func (c *SQLiteConn) Close() error {
return c.lastError()
}
deleteHandles(c)
+ c.mu.Lock()
c.db = nil
+ c.mu.Unlock()
runtime.SetFinalizer(c, nil)
return nil
}
+func (c *SQLiteConn) dbConnOpen() bool {
+ if c == nil {
+ return false
+ }
+ c.mu.Lock()
+ defer c.mu.Unlock()
+ return c.db != nil
+}
+
// Prepare the query string. Return a new statement.
func (c *SQLiteConn) Prepare(query string) (driver.Stmt, error) {
return c.prepare(context.Background(), query)
@@ -709,14 +829,17 @@ func (c *SQLiteConn) prepare(ctx context.Context, query string) (driver.Stmt, er
// Close the statement.
func (s *SQLiteStmt) Close() error {
+ s.mu.Lock()
+ defer s.mu.Unlock()
if s.closed {
return nil
}
s.closed = true
- if s.c == nil || s.c.db == nil {
+ if !s.c.dbConnOpen() {
return errors.New("sqlite statement with already closed database connection")
}
rv := C.sqlite3_finalize(s.s)
+ s.s = nil
if rv != C.SQLITE_OK {
return s.c.lastError()
}
@@ -734,6 +857,8 @@ type bindArg struct {
v driver.Value
}
+var placeHolder = []byte{0}
+
func (s *SQLiteStmt) bind(args []namedValue) error {
rv := C.sqlite3_reset(s.s)
if rv != C.SQLITE_ROW && rv != C.SQLITE_OK && rv != C.SQLITE_DONE {
@@ -755,8 +880,7 @@ func (s *SQLiteStmt) bind(args []namedValue) error {
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))
+ rv = C._sqlite3_bind_text(s.s, n, (*C.char)(unsafe.Pointer(&placeHolder[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)))
@@ -772,11 +896,11 @@ func (s *SQLiteStmt) bind(args []namedValue) error {
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)))
+ ln := len(v)
+ if ln == 0 {
+ v = placeHolder
}
+ rv = C._sqlite3_bind_blob(s.s, n, unsafe.Pointer(&v[0]), C.int(ln))
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)))
@@ -811,6 +935,7 @@ func (s *SQLiteStmt) query(ctx context.Context, args []namedValue) (driver.Rows,
cols: nil,
decltype: nil,
cls: s.cls,
+ closed: false,
done: make(chan struct{}),
}
@@ -883,25 +1008,33 @@ func (s *SQLiteStmt) exec(ctx context.Context, args []namedValue) (driver.Result
// Close the rows.
func (rc *SQLiteRows) Close() error {
- if rc.s.closed {
+ rc.s.mu.Lock()
+ if rc.s.closed || rc.closed {
+ rc.s.mu.Unlock()
return nil
}
+ rc.closed = true
if rc.done != nil {
close(rc.done)
}
if rc.cls {
+ rc.s.mu.Unlock()
return rc.s.Close()
}
rv := C.sqlite3_reset(rc.s.s)
if rv != C.SQLITE_OK {
+ rc.s.mu.Unlock()
return rc.s.c.lastError()
}
+ rc.s.mu.Unlock()
return nil
}
// Columns return column names.
func (rc *SQLiteRows) Columns() []string {
- if rc.nc != len(rc.cols) {
+ rc.s.mu.Lock()
+ defer rc.s.mu.Unlock()
+ if rc.s.s != nil && rc.nc != len(rc.cols) {
rc.cols = make([]string, rc.nc)
for i := 0; i < rc.nc; i++ {
rc.cols[i] = C.GoString(C.sqlite3_column_name(rc.s.s, C.int(i)))
@@ -910,9 +1043,8 @@ func (rc *SQLiteRows) Columns() []string {
return rc.cols
}
-// DeclTypes return column types.
-func (rc *SQLiteRows) DeclTypes() []string {
- if rc.decltype == nil {
+func (rc *SQLiteRows) declTypes() []string {
+ if rc.s.s != nil && 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))))
@@ -921,8 +1053,20 @@ func (rc *SQLiteRows) DeclTypes() []string {
return rc.decltype
}
+// DeclTypes return column types.
+func (rc *SQLiteRows) DeclTypes() []string {
+ rc.s.mu.Lock()
+ defer rc.s.mu.Unlock()
+ return rc.declTypes()
+}
+
// Next move cursor to next.
func (rc *SQLiteRows) Next(dest []driver.Value) error {
+ if rc.s.closed {
+ return io.EOF
+ }
+ rc.s.mu.Lock()
+ defer rc.s.mu.Unlock()
rv := C.sqlite3_step(rc.s.s)
if rv == C.SQLITE_DONE {
return io.EOF
@@ -935,7 +1079,7 @@ func (rc *SQLiteRows) Next(dest []driver.Value) error {
return nil
}
- rc.DeclTypes()
+ rc.declTypes()
for i := range dest {
switch C.sqlite3_column_type(rc.s.s, C.int(i)) {
@@ -948,10 +1092,11 @@ func (rc *SQLiteRows) Next(dest []driver.Value) error {
// large to be a reasonable timestamp in seconds.
if val > 1e12 || val < -1e12 {
val *= int64(time.Millisecond) // convert ms to nsec
+ t = time.Unix(0, val)
} else {
- val *= int64(time.Second) // convert sec to nsec
+ t = time.Unix(val, 0)
}
- t = time.Unix(0, val).UTC()
+ t = t.UTC()
if rc.s.c.loc != nil {
t = t.In(rc.s.c.loc)
}
diff --git a/vendor/github.com/mattn/go-sqlite3/sqlite3_libsqlite3.go b/vendor/github.com/mattn/go-sqlite3/sqlite3_libsqlite3.go
index 135863e..e4557e6 100644
--- a/vendor/github.com/mattn/go-sqlite3/sqlite3_libsqlite3.go
+++ b/vendor/github.com/mattn/go-sqlite3/sqlite3_libsqlite3.go
@@ -10,5 +10,6 @@ package sqlite3
#cgo CFLAGS: -DUSE_LIBSQLITE3
#cgo linux LDFLAGS: -lsqlite3
#cgo darwin LDFLAGS: -L/usr/local/opt/sqlite/lib -lsqlite3
+#cgo solaris LDFLAGS: -lsqlite3
*/
import "C"
diff --git a/vendor/github.com/mattn/go-sqlite3/sqlite3_other.go b/vendor/github.com/mattn/go-sqlite3/sqlite3_other.go
index a20d02c..f721b5e 100644
--- a/vendor/github.com/mattn/go-sqlite3/sqlite3_other.go
+++ b/vendor/github.com/mattn/go-sqlite3/sqlite3_other.go
@@ -9,5 +9,6 @@ package sqlite3
/*
#cgo CFLAGS: -I.
#cgo linux LDFLAGS: -ldl
+#cgo solaris LDFLAGS: -lc
*/
import "C"