github.com/mattn/go-sqlite3: Update to latest version.
Motivation: To make things work with Go 1.6
Specifically to get this https://github.com/mattn/go-sqlite3/pull/267
and https://github.com/mattn/go-sqlite3/pull/268
Change-Id: I66daa419daebfddf1382ade56af4d1806eebf409
diff --git a/go/src/github.com/mattn/go-sqlite3/README.google b/go/src/github.com/mattn/go-sqlite3/README.google
index 5178e55..855cb16 100644
--- a/go/src/github.com/mattn/go-sqlite3/README.google
+++ b/go/src/github.com/mattn/go-sqlite3/README.google
@@ -1,5 +1,5 @@
-URL: https://github.com/mattn/go-sqlite3/archive/f33c9767fbdd0d10fab2b7bf056e80bdf30c8ed1.zip
-Version: f33c9767fbdd0d10fab2b7bf056e80bdf30c8ed1.zip
+URL: https://github.com/mattn/go-sqlite3/archive/10876d7dac65f02064c03d7372a2f1dfb90043fe.zip
+Version: 10876d7dac65f02064c03d7372a2f1dfb90043fe
License: MIT
License File: LICENSE
diff --git a/go/src/github.com/mattn/go-sqlite3/README.md b/go/src/github.com/mattn/go-sqlite3/README.md
index 6767e8e..d69e305 100644
--- a/go/src/github.com/mattn/go-sqlite3/README.md
+++ b/go/src/github.com/mattn/go-sqlite3/README.md
@@ -1,8 +1,9 @@
go-sqlite3
==========
-[![Build Status](https://travis-ci.org/mattn/go-sqlite3.png?branch=master)](https://travis-ci.org/mattn/go-sqlite3)
-[![Coverage Status](https://coveralls.io/repos/mattn/go-sqlite3/badge.png?branch=master)](https://coveralls.io/r/mattn/go-sqlite3?branch=master)
+[![Build Status](https://travis-ci.org/mattn/go-sqlite3.svg?branch=master)](https://travis-ci.org/mattn/go-sqlite3)
+[![Coverage Status](https://coveralls.io/repos/mattn/go-sqlite3/badge.svg?branch=master)](https://coveralls.io/r/mattn/go-sqlite3?branch=master)
+[![GoDoc](https://godoc.org/github.com/mattn/go-sqlite3?status.svg)](http://godoc.org/github.com/mattn/go-sqlite3)
Description
-----------
@@ -48,7 +49,7 @@
> 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 cross compiling? mingw on Linux or Mac?
+* Do you want to cross compile? mingw on Linux or Mac?
> See: https://github.com/mattn/go-sqlite3/issues/106
> See also: http://www.limitlessfx.com/cross-compile-golang-app-for-windows-from-linux.html
@@ -66,7 +67,7 @@
The -binding suffix was added to avoid build failures under gccgo.
-In this repository, those files are amalgamation code that copied from SQLite3. The license of those codes are depend on the license of SQLite3.
+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
------
diff --git a/go/src/github.com/mattn/go-sqlite3/callback.go b/go/src/github.com/mattn/go-sqlite3/callback.go
index ee9d40c..e2bf3c6 100644
--- a/go/src/github.com/mattn/go-sqlite3/callback.go
+++ b/go/src/github.com/mattn/go-sqlite3/callback.go
@@ -24,29 +24,75 @@
"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 := (*functionInfo)(unsafe.Pointer(C.sqlite3_user_data(ctx)))
+ 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 := (*aggInfo)(unsafe.Pointer(C.sqlite3_user_data(ctx)))
+ ai := lookupHandle(uintptr(C.sqlite3_user_data(ctx))).(*aggInfo)
ai.Step(ctx, args)
}
//export doneTrampoline
func doneTrampoline(ctx *C.sqlite3_context) {
- ai := (*aggInfo)(unsafe.Pointer(C.sqlite3_user_data(ctx)))
+ 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
diff --git a/go/src/github.com/mattn/go-sqlite3/doc.go b/go/src/github.com/mattn/go-sqlite3/doc.go
index a45d852..597c75f 100644
--- a/go/src/github.com/mattn/go-sqlite3/doc.go
+++ b/go/src/github.com/mattn/go-sqlite3/doc.go
@@ -1,7 +1,7 @@
/*
Package sqlite3 provides interface to SQLite3 databases.
-This works as driver for database/sql.
+This works as a driver for database/sql.
Installation
@@ -9,7 +9,7 @@
Supported Types
-Currently, go-sqlite3 support following data types.
+Currently, go-sqlite3 supports the following data types.
+------------------------------+
|go | sqlite3 |
@@ -26,8 +26,8 @@
SQLite3 Extension
-You can write your own extension module for sqlite3. For example, below is a
-extension for Regexp matcher operation.
+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>
@@ -63,8 +63,8 @@
(void*)db, regexp_func, NULL, NULL);
}
-It need to build as so/dll shared library. And you need to register
-extension module like below.
+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{
@@ -79,9 +79,9 @@
Connection Hook
-You can hook and inject your codes when connection established. database/sql
-doesn't provide the way to get native go-sqlite3 interfaces. So if you want,
-you need to hook ConnectHook and get the SQLiteConn.
+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{
diff --git a/go/src/github.com/mattn/go-sqlite3/sqlite3.go b/go/src/github.com/mattn/go-sqlite3/sqlite3.go
index f79ef2d..afeb99e 100644
--- a/go/src/github.com/mattn/go-sqlite3/sqlite3.go
+++ b/go/src/github.com/mattn/go-sqlite3/sqlite3.go
@@ -130,7 +130,7 @@
sql.Register("sqlite3", &SQLiteDriver{})
}
-// Return SQLite library Version information.
+// 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())
@@ -367,7 +367,7 @@
if pure {
opts |= C.SQLITE_DETERMINISTIC
}
- rv := C._sqlite3_create_function(c.db, cname, C.int(numArgs), C.int(opts), C.uintptr_t(uintptr(unsafe.Pointer(&fi))), (*[0]byte)(unsafe.Pointer(C.callbackTrampoline)), nil, nil)
+ 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()
}
@@ -492,7 +492,7 @@
if pure {
opts |= C.SQLITE_DETERMINISTIC
}
- rv := C._sqlite3_create_function(c.db, cname, C.int(stepNArgs), C.int(opts), C.uintptr_t(uintptr(unsafe.Pointer(&ai))), nil, (*[0]byte)(unsafe.Pointer(C.stepTrampoline)), (*[0]byte)(unsafe.Pointer(C.doneTrampoline)))
+ 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()
}
@@ -598,7 +598,7 @@
}
// Open database and return a new connection.
-// You can specify DSN string with URI filename.
+// You can specify a DSN string using a URI as the filename.
// test.db
// file:test.db?cache=shared&mode=memory
// :memory:
@@ -705,6 +705,7 @@
// 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()
@@ -714,7 +715,7 @@
return nil
}
-// Prepare query string. Return a new statement.
+// 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))
@@ -814,11 +815,11 @@
case float64:
rv = C.sqlite3_bind_double(s.s, n, C.double(v))
case []byte:
- var p *byte
- if len(v) > 0 {
- p = &v[0]
+ 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)))
}
- rv = C._sqlite3_bind_blob(s.s, n, unsafe.Pointer(p), 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)))
@@ -892,6 +893,17 @@
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)
@@ -906,12 +918,7 @@
return nil
}
- 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))))
- }
- }
+ rc.DeclTypes()
for i := range dest {
switch C.sqlite3_column_type(rc.s.s, C.int(i)) {
diff --git a/go/src/github.com/mattn/go-sqlite3/sqlite3_fts5.go b/go/src/github.com/mattn/go-sqlite3/sqlite3_fts5.go
new file mode 100644
index 0000000..0e65d69
--- /dev/null
+++ b/go/src/github.com/mattn/go-sqlite3/sqlite3_fts5.go
@@ -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"
diff --git a/go/src/github.com/mattn/go-sqlite3/sqlite3_json1.go b/go/src/github.com/mattn/go-sqlite3/sqlite3_json1.go
new file mode 100644
index 0000000..a7b2473
--- /dev/null
+++ b/go/src/github.com/mattn/go-sqlite3/sqlite3_json1.go
@@ -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"
diff --git a/go/src/github.com/mattn/go-sqlite3/sqlite3_test.go b/go/src/github.com/mattn/go-sqlite3/sqlite3_test.go
index 9efd313..c7996c6 100644
--- a/go/src/github.com/mattn/go-sqlite3/sqlite3_test.go
+++ b/go/src/github.com/mattn/go-sqlite3/sqlite3_test.go
@@ -1279,6 +1279,41 @@
}
}
+func TestDeclTypes(t *testing.T) {
+
+ d := SQLiteDriver{}
+
+ conn, err := d.Open(":memory:")
+ if err != nil {
+ t.Fatal("Failed to begin transaction:", err)
+ }
+ defer conn.Close()
+
+ sqlite3conn := conn.(*SQLiteConn)
+
+ _, err = sqlite3conn.Exec("create table foo (id integer not null primary key, name text)", nil)
+ if err != nil {
+ t.Fatal("Failed to create table:", err)
+ }
+
+ _, err = sqlite3conn.Exec("insert into foo(name) values(\"bar\")", nil)
+ if err != nil {
+ t.Fatal("Failed to insert:", err)
+ }
+
+ rs, err := sqlite3conn.Query("select * from foo", nil)
+ if err != nil {
+ t.Fatal("Failed to select:", err)
+ }
+ defer rs.Close()
+
+ declTypes := rs.(*SQLiteRows).DeclTypes()
+
+ if !reflect.DeepEqual(declTypes, []string{"integer", "text"}) {
+ t.Fatal("Unexpected declTypes:", declTypes)
+ }
+}
+
var customFunctionOnce sync.Once
func BenchmarkCustomFunctions(b *testing.B) {