adds vendor directory
vendors dependencies in standard `vendor` directory, managed by glide
This commit is contained in:
133
vendor/github.com/mattn/go-sqlite3/_example/custom_func/main.go
generated
vendored
Normal file
133
vendor/github.com/mattn/go-sqlite3/_example/custom_func/main.go
generated
vendored
Normal file
@@ -0,0 +1,133 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"database/sql"
|
||||
"fmt"
|
||||
"log"
|
||||
"math"
|
||||
"math/rand"
|
||||
|
||||
sqlite "github.com/mattn/go-sqlite3"
|
||||
)
|
||||
|
||||
// Computes x^y
|
||||
func pow(x, y int64) int64 {
|
||||
return int64(math.Pow(float64(x), float64(y)))
|
||||
}
|
||||
|
||||
// Computes the bitwise exclusive-or of all its arguments
|
||||
func xor(xs ...int64) int64 {
|
||||
var ret int64
|
||||
for _, x := range xs {
|
||||
ret ^= x
|
||||
}
|
||||
return ret
|
||||
}
|
||||
|
||||
// Returns a random number. It's actually deterministic here because
|
||||
// we don't seed the RNG, but it's an example of a non-pure function
|
||||
// from SQLite's POV.
|
||||
func getrand() int64 {
|
||||
return rand.Int63()
|
||||
}
|
||||
|
||||
// Computes the standard deviation of a GROUPed BY set of values
|
||||
type stddev struct {
|
||||
xs []int64
|
||||
// Running average calculation
|
||||
sum int64
|
||||
n int64
|
||||
}
|
||||
|
||||
func newStddev() *stddev { return &stddev{} }
|
||||
|
||||
func (s *stddev) Step(x int64) {
|
||||
s.xs = append(s.xs, x)
|
||||
s.sum += x
|
||||
s.n++
|
||||
}
|
||||
|
||||
func (s *stddev) Done() float64 {
|
||||
mean := float64(s.sum) / float64(s.n)
|
||||
var sqDiff []float64
|
||||
for _, x := range s.xs {
|
||||
sqDiff = append(sqDiff, math.Pow(float64(x)-mean, 2))
|
||||
}
|
||||
var dev float64
|
||||
for _, x := range sqDiff {
|
||||
dev += x
|
||||
}
|
||||
dev /= float64(len(sqDiff))
|
||||
return math.Sqrt(dev)
|
||||
}
|
||||
|
||||
func main() {
|
||||
sql.Register("sqlite3_custom", &sqlite.SQLiteDriver{
|
||||
ConnectHook: func(conn *sqlite.SQLiteConn) error {
|
||||
if err := conn.RegisterFunc("pow", pow, true); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := conn.RegisterFunc("xor", xor, true); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := conn.RegisterFunc("rand", getrand, false); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := conn.RegisterAggregator("stddev", newStddev, true); err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
},
|
||||
})
|
||||
|
||||
db, err := sql.Open("sqlite3_custom", ":memory:")
|
||||
if err != nil {
|
||||
log.Fatal("Failed to open database:", err)
|
||||
}
|
||||
defer db.Close()
|
||||
|
||||
var i int64
|
||||
err = db.QueryRow("SELECT pow(2,3)").Scan(&i)
|
||||
if err != nil {
|
||||
log.Fatal("POW query error:", err)
|
||||
}
|
||||
fmt.Println("pow(2,3) =", i) // 8
|
||||
|
||||
err = db.QueryRow("SELECT xor(1,2,3,4,5,6)").Scan(&i)
|
||||
if err != nil {
|
||||
log.Fatal("XOR query error:", err)
|
||||
}
|
||||
fmt.Println("xor(1,2,3,4,5) =", i) // 7
|
||||
|
||||
err = db.QueryRow("SELECT rand()").Scan(&i)
|
||||
if err != nil {
|
||||
log.Fatal("RAND query error:", err)
|
||||
}
|
||||
fmt.Println("rand() =", i) // pseudorandom
|
||||
|
||||
_, err = db.Exec("create table foo (department integer, profits integer)")
|
||||
if err != nil {
|
||||
log.Fatal("Failed to create table:", err)
|
||||
}
|
||||
_, err = db.Exec("insert into foo values (1, 10), (1, 20), (1, 45), (2, 42), (2, 115)")
|
||||
if err != nil {
|
||||
log.Fatal("Failed to insert records:", err)
|
||||
}
|
||||
|
||||
rows, err := db.Query("select department, stddev(profits) from foo group by department")
|
||||
if err != nil {
|
||||
log.Fatal("STDDEV query error:", err)
|
||||
}
|
||||
defer rows.Close()
|
||||
for rows.Next() {
|
||||
var dept int64
|
||||
var dev float64
|
||||
if err := rows.Scan(&dept, &dev); err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
fmt.Printf("dept=%d stddev=%f\n", dept, dev)
|
||||
}
|
||||
if err := rows.Err(); err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
}
|
72
vendor/github.com/mattn/go-sqlite3/_example/hook/hook.go
generated
vendored
Normal file
72
vendor/github.com/mattn/go-sqlite3/_example/hook/hook.go
generated
vendored
Normal file
@@ -0,0 +1,72 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"database/sql"
|
||||
"log"
|
||||
"os"
|
||||
|
||||
"github.com/mattn/go-sqlite3"
|
||||
)
|
||||
|
||||
func main() {
|
||||
sqlite3conn := []*sqlite3.SQLiteConn{}
|
||||
sql.Register("sqlite3_with_hook_example",
|
||||
&sqlite3.SQLiteDriver{
|
||||
ConnectHook: func(conn *sqlite3.SQLiteConn) error {
|
||||
sqlite3conn = append(sqlite3conn, conn)
|
||||
return nil
|
||||
},
|
||||
})
|
||||
os.Remove("./foo.db")
|
||||
os.Remove("./bar.db")
|
||||
|
||||
srcDb, err := sql.Open("sqlite3_with_hook_example", "./foo.db")
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
defer srcDb.Close()
|
||||
srcDb.Ping()
|
||||
|
||||
_, err = srcDb.Exec("create table foo(id int, value text)")
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
_, err = srcDb.Exec("insert into foo values(1, 'foo')")
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
_, err = srcDb.Exec("insert into foo values(2, 'bar')")
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
_, err = srcDb.Query("select * from foo")
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
destDb, err := sql.Open("sqlite3_with_hook_example", "./bar.db")
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
defer destDb.Close()
|
||||
destDb.Ping()
|
||||
|
||||
bk, err := sqlite3conn[1].Backup("main", sqlite3conn[0], "main")
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
|
||||
_, err = bk.Step(-1)
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
_, err = destDb.Query("select * from foo")
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
_, err = destDb.Exec("insert into foo values(3, 'bar')")
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
|
||||
bk.Finish()
|
||||
}
|
22
vendor/github.com/mattn/go-sqlite3/_example/mod_regexp/Makefile
generated
vendored
Normal file
22
vendor/github.com/mattn/go-sqlite3/_example/mod_regexp/Makefile
generated
vendored
Normal file
@@ -0,0 +1,22 @@
|
||||
ifeq ($(OS),Windows_NT)
|
||||
EXE=extension.exe
|
||||
EXT=sqlite3_mod_regexp.dll
|
||||
RM=cmd /c del
|
||||
LDFLAG=
|
||||
else
|
||||
EXE=extension
|
||||
EXT=sqlite3_mod_regexp.so
|
||||
RM=rm
|
||||
LDFLAG=-fPIC
|
||||
endif
|
||||
|
||||
all : $(EXE) $(EXT)
|
||||
|
||||
$(EXE) : extension.go
|
||||
go build $<
|
||||
|
||||
$(EXT) : sqlite3_mod_regexp.c
|
||||
gcc $(LDFLAG) -shared -o $@ $< -lsqlite3 -lpcre
|
||||
|
||||
clean :
|
||||
@-$(RM) $(EXE) $(EXT)
|
43
vendor/github.com/mattn/go-sqlite3/_example/mod_regexp/extension.go
generated
vendored
Normal file
43
vendor/github.com/mattn/go-sqlite3/_example/mod_regexp/extension.go
generated
vendored
Normal file
@@ -0,0 +1,43 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"database/sql"
|
||||
"fmt"
|
||||
"github.com/mattn/go-sqlite3"
|
||||
"log"
|
||||
)
|
||||
|
||||
func main() {
|
||||
sql.Register("sqlite3_with_extensions",
|
||||
&sqlite3.SQLiteDriver{
|
||||
Extensions: []string{
|
||||
"sqlite3_mod_regexp",
|
||||
},
|
||||
})
|
||||
|
||||
db, err := sql.Open("sqlite3_with_extensions", ":memory:")
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
defer db.Close()
|
||||
|
||||
// Force db to make a new connection in pool
|
||||
// by putting the original in a transaction
|
||||
tx, err := db.Begin()
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
defer tx.Commit()
|
||||
|
||||
// New connection works (hopefully!)
|
||||
rows, err := db.Query("select 'hello world' where 'hello world' regexp '^hello.*d$'")
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
defer rows.Close()
|
||||
for rows.Next() {
|
||||
var helloworld string
|
||||
rows.Scan(&helloworld)
|
||||
fmt.Println(helloworld)
|
||||
}
|
||||
}
|
31
vendor/github.com/mattn/go-sqlite3/_example/mod_regexp/sqlite3_mod_regexp.c
generated
vendored
Normal file
31
vendor/github.com/mattn/go-sqlite3/_example/mod_regexp/sqlite3_mod_regexp.c
generated
vendored
Normal file
@@ -0,0 +1,31 @@
|
||||
#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);
|
||||
}
|
24
vendor/github.com/mattn/go-sqlite3/_example/mod_vtable/Makefile
generated
vendored
Normal file
24
vendor/github.com/mattn/go-sqlite3/_example/mod_vtable/Makefile
generated
vendored
Normal file
@@ -0,0 +1,24 @@
|
||||
ifeq ($(OS),Windows_NT)
|
||||
EXE=extension.exe
|
||||
EXT=sqlite3_mod_vtable.dll
|
||||
RM=cmd /c del
|
||||
LIBCURL=-lcurldll
|
||||
LDFLAG=
|
||||
else
|
||||
EXE=extension
|
||||
EXT=sqlite3_mod_vtable.so
|
||||
RM=rm
|
||||
LDFLAG=-fPIC
|
||||
LIBCURL=-lcurl
|
||||
endif
|
||||
|
||||
all : $(EXE) $(EXT)
|
||||
|
||||
$(EXE) : extension.go
|
||||
go build $<
|
||||
|
||||
$(EXT) : sqlite3_mod_vtable.cc
|
||||
g++ $(LDFLAG) -shared -o $@ $< -lsqlite3 $(LIBCURL)
|
||||
|
||||
clean :
|
||||
@-$(RM) $(EXE) $(EXT)
|
37
vendor/github.com/mattn/go-sqlite3/_example/mod_vtable/extension.go
generated
vendored
Normal file
37
vendor/github.com/mattn/go-sqlite3/_example/mod_vtable/extension.go
generated
vendored
Normal file
@@ -0,0 +1,37 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"database/sql"
|
||||
"fmt"
|
||||
"log"
|
||||
|
||||
"github.com/mattn/go-sqlite3"
|
||||
)
|
||||
|
||||
func main() {
|
||||
sql.Register("sqlite3_with_extensions",
|
||||
&sqlite3.SQLiteDriver{
|
||||
Extensions: []string{
|
||||
"sqlite3_mod_vtable",
|
||||
},
|
||||
})
|
||||
|
||||
db, err := sql.Open("sqlite3_with_extensions", ":memory:")
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
defer db.Close()
|
||||
|
||||
db.Exec("create virtual table repo using github(id, full_name, description, html_url)")
|
||||
|
||||
rows, err := db.Query("select id, full_name, description, html_url from repo")
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
defer rows.Close()
|
||||
for rows.Next() {
|
||||
var id, fullName, description, htmlURL string
|
||||
rows.Scan(&id, &fullName, &description, &htmlURL)
|
||||
fmt.Printf("%s: %s\n\t%s\n\t%s\n\n", id, fullName, description, htmlURL)
|
||||
}
|
||||
}
|
1040
vendor/github.com/mattn/go-sqlite3/_example/mod_vtable/picojson.h
generated
vendored
Normal file
1040
vendor/github.com/mattn/go-sqlite3/_example/mod_vtable/picojson.h
generated
vendored
Normal file
File diff suppressed because it is too large
Load Diff
238
vendor/github.com/mattn/go-sqlite3/_example/mod_vtable/sqlite3_mod_vtable.cc
generated
vendored
Normal file
238
vendor/github.com/mattn/go-sqlite3/_example/mod_vtable/sqlite3_mod_vtable.cc
generated
vendored
Normal file
@@ -0,0 +1,238 @@
|
||||
#include <string>
|
||||
#include <sstream>
|
||||
#include <sqlite3-binding.h>
|
||||
#include <sqlite3ext.h>
|
||||
#include <curl/curl.h>
|
||||
#include "picojson.h"
|
||||
|
||||
#ifdef _WIN32
|
||||
# define EXPORT __declspec(dllexport)
|
||||
#else
|
||||
# define EXPORT
|
||||
#endif
|
||||
|
||||
SQLITE_EXTENSION_INIT1;
|
||||
|
||||
typedef struct {
|
||||
char* data; // response data from server
|
||||
size_t size; // response size of data
|
||||
} MEMFILE;
|
||||
|
||||
MEMFILE*
|
||||
memfopen() {
|
||||
MEMFILE* mf = (MEMFILE*) malloc(sizeof(MEMFILE));
|
||||
if (mf) {
|
||||
mf->data = NULL;
|
||||
mf->size = 0;
|
||||
}
|
||||
return mf;
|
||||
}
|
||||
|
||||
void
|
||||
memfclose(MEMFILE* mf) {
|
||||
if (mf->data) free(mf->data);
|
||||
free(mf);
|
||||
}
|
||||
|
||||
size_t
|
||||
memfwrite(char* ptr, size_t size, size_t nmemb, void* stream) {
|
||||
MEMFILE* mf = (MEMFILE*) stream;
|
||||
int block = size * nmemb;
|
||||
if (!mf) return block; // through
|
||||
if (!mf->data)
|
||||
mf->data = (char*) malloc(block);
|
||||
else
|
||||
mf->data = (char*) realloc(mf->data, mf->size + block);
|
||||
if (mf->data) {
|
||||
memcpy(mf->data + mf->size, ptr, block);
|
||||
mf->size += block;
|
||||
}
|
||||
return block;
|
||||
}
|
||||
|
||||
char*
|
||||
memfstrdup(MEMFILE* mf) {
|
||||
char* buf;
|
||||
if (mf->size == 0) return NULL;
|
||||
buf = (char*) malloc(mf->size + 1);
|
||||
memcpy(buf, mf->data, mf->size);
|
||||
buf[mf->size] = 0;
|
||||
return buf;
|
||||
}
|
||||
|
||||
static int
|
||||
my_connect(sqlite3 *db, void *pAux, int argc, const char * const *argv, sqlite3_vtab **ppVTab, char **c) {
|
||||
std::stringstream ss;
|
||||
ss << "CREATE TABLE " << argv[0]
|
||||
<< "(id int, full_name text, description text, html_url text)";
|
||||
int rc = sqlite3_declare_vtab(db, ss.str().c_str());
|
||||
*ppVTab = (sqlite3_vtab *) sqlite3_malloc(sizeof(sqlite3_vtab));
|
||||
memset(*ppVTab, 0, sizeof(sqlite3_vtab));
|
||||
return rc;
|
||||
}
|
||||
|
||||
static int
|
||||
my_create(sqlite3 *db, void *pAux, int argc, const char * const * argv, sqlite3_vtab **ppVTab, char **c) {
|
||||
return my_connect(db, pAux, argc, argv, ppVTab, c);
|
||||
}
|
||||
|
||||
static int my_disconnect(sqlite3_vtab *pVTab) {
|
||||
sqlite3_free(pVTab);
|
||||
return SQLITE_OK;
|
||||
}
|
||||
|
||||
static int
|
||||
my_destroy(sqlite3_vtab *pVTab) {
|
||||
sqlite3_free(pVTab);
|
||||
return SQLITE_OK;
|
||||
}
|
||||
|
||||
typedef struct {
|
||||
sqlite3_vtab_cursor base;
|
||||
int index;
|
||||
picojson::value* rows;
|
||||
} cursor;
|
||||
|
||||
static int
|
||||
my_open(sqlite3_vtab *pVTab, sqlite3_vtab_cursor **ppCursor) {
|
||||
MEMFILE* mf;
|
||||
CURL* curl;
|
||||
char* json;
|
||||
CURLcode res = CURLE_OK;
|
||||
char error[CURL_ERROR_SIZE] = {0};
|
||||
char* cert_file = getenv("SSL_CERT_FILE");
|
||||
|
||||
mf = memfopen();
|
||||
curl = curl_easy_init();
|
||||
curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, 1);
|
||||
curl_easy_setopt(curl, CURLOPT_SSL_VERIFYHOST, 2);
|
||||
curl_easy_setopt(curl, CURLOPT_USERAGENT, "curl/7.29.0");
|
||||
curl_easy_setopt(curl, CURLOPT_URL, "https://api.github.com/repositories");
|
||||
if (cert_file)
|
||||
curl_easy_setopt(curl, CURLOPT_CAINFO, cert_file);
|
||||
curl_easy_setopt(curl, CURLOPT_FOLLOWLOCATION, 1);
|
||||
curl_easy_setopt(curl, CURLOPT_ERRORBUFFER, error);
|
||||
curl_easy_setopt(curl, CURLOPT_WRITEDATA, mf);
|
||||
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, memfwrite);
|
||||
res = curl_easy_perform(curl);
|
||||
curl_easy_cleanup(curl);
|
||||
if (res != CURLE_OK) {
|
||||
std::cerr << error << std::endl;
|
||||
return SQLITE_FAIL;
|
||||
}
|
||||
|
||||
picojson::value* v = new picojson::value;
|
||||
std::string err;
|
||||
picojson::parse(*v, mf->data, mf->data + mf->size, &err);
|
||||
memfclose(mf);
|
||||
|
||||
if (!err.empty()) {
|
||||
delete v;
|
||||
std::cerr << err << std::endl;
|
||||
return SQLITE_FAIL;
|
||||
}
|
||||
|
||||
cursor *c = (cursor *)sqlite3_malloc(sizeof(cursor));
|
||||
c->rows = v;
|
||||
c->index = 0;
|
||||
*ppCursor = &c->base;
|
||||
return SQLITE_OK;
|
||||
}
|
||||
|
||||
static int
|
||||
my_close(cursor *c) {
|
||||
delete c->rows;
|
||||
sqlite3_free(c);
|
||||
return SQLITE_OK;
|
||||
}
|
||||
|
||||
static int
|
||||
my_filter(cursor *c, int idxNum, const char *idxStr, int argc, sqlite3_value **argv) {
|
||||
c->index = 0;
|
||||
return SQLITE_OK;
|
||||
}
|
||||
|
||||
static int
|
||||
my_next(cursor *c) {
|
||||
c->index++;
|
||||
return SQLITE_OK;
|
||||
}
|
||||
|
||||
static int
|
||||
my_eof(cursor *c) {
|
||||
return c->index >= c->rows->get<picojson::array>().size() ? 1 : 0;
|
||||
}
|
||||
|
||||
static int
|
||||
my_column(cursor *c, sqlite3_context *ctxt, int i) {
|
||||
picojson::value v = c->rows->get<picojson::array>()[c->index];
|
||||
picojson::object row = v.get<picojson::object>();
|
||||
const char* p = NULL;
|
||||
switch (i) {
|
||||
case 0:
|
||||
p = row["id"].to_str().c_str();
|
||||
break;
|
||||
case 1:
|
||||
p = row["full_name"].to_str().c_str();
|
||||
break;
|
||||
case 2:
|
||||
p = row["description"].to_str().c_str();
|
||||
break;
|
||||
case 3:
|
||||
p = row["html_url"].to_str().c_str();
|
||||
break;
|
||||
}
|
||||
sqlite3_result_text(ctxt, strdup(p), strlen(p), free);
|
||||
return SQLITE_OK;
|
||||
}
|
||||
|
||||
static int
|
||||
my_rowid(cursor *c, sqlite3_int64 *pRowid) {
|
||||
*pRowid = c->index;
|
||||
return SQLITE_OK;
|
||||
}
|
||||
|
||||
static int
|
||||
my_bestindex(sqlite3_vtab *tab, sqlite3_index_info *pIdxInfo) {
|
||||
return SQLITE_OK;
|
||||
}
|
||||
|
||||
static const sqlite3_module module = {
|
||||
0,
|
||||
my_create,
|
||||
my_connect,
|
||||
my_bestindex,
|
||||
my_disconnect,
|
||||
my_destroy,
|
||||
my_open,
|
||||
(int (*)(sqlite3_vtab_cursor *)) my_close,
|
||||
(int (*)(sqlite3_vtab_cursor *, int, char const *, int, sqlite3_value **)) my_filter,
|
||||
(int (*)(sqlite3_vtab_cursor *)) my_next,
|
||||
(int (*)(sqlite3_vtab_cursor *)) my_eof,
|
||||
(int (*)(sqlite3_vtab_cursor *, sqlite3_context *, int)) my_column,
|
||||
(int (*)(sqlite3_vtab_cursor *, sqlite3_int64 *)) my_rowid,
|
||||
NULL, // my_update
|
||||
NULL, // my_begin
|
||||
NULL, // my_sync
|
||||
NULL, // my_commit
|
||||
NULL, // my_rollback
|
||||
NULL, // my_findfunction
|
||||
NULL, // my_rename
|
||||
};
|
||||
|
||||
static void
|
||||
destructor(void *arg) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
extern "C" {
|
||||
|
||||
EXPORT int
|
||||
sqlite3_extension_init(sqlite3 *db, char **errmsg, const sqlite3_api_routines *api) {
|
||||
SQLITE_EXTENSION_INIT2(api);
|
||||
sqlite3_create_module_v2(db, "github", &module, NULL, destructor);
|
||||
return 0;
|
||||
}
|
||||
|
||||
}
|
106
vendor/github.com/mattn/go-sqlite3/_example/simple/simple.go
generated
vendored
Normal file
106
vendor/github.com/mattn/go-sqlite3/_example/simple/simple.go
generated
vendored
Normal file
@@ -0,0 +1,106 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"database/sql"
|
||||
"fmt"
|
||||
_ "github.com/mattn/go-sqlite3"
|
||||
"log"
|
||||
"os"
|
||||
)
|
||||
|
||||
func main() {
|
||||
os.Remove("./foo.db")
|
||||
|
||||
db, err := sql.Open("sqlite3", "./foo.db")
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
defer db.Close()
|
||||
|
||||
sqlStmt := `
|
||||
create table foo (id integer not null primary key, name text);
|
||||
delete from foo;
|
||||
`
|
||||
_, err = db.Exec(sqlStmt)
|
||||
if err != nil {
|
||||
log.Printf("%q: %s\n", err, sqlStmt)
|
||||
return
|
||||
}
|
||||
|
||||
tx, err := db.Begin()
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
stmt, err := tx.Prepare("insert into foo(id, name) values(?, ?)")
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
defer stmt.Close()
|
||||
for i := 0; i < 100; i++ {
|
||||
_, err = stmt.Exec(i, fmt.Sprintf("こんにちわ世界%03d", i))
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
}
|
||||
tx.Commit()
|
||||
|
||||
rows, err := db.Query("select id, name from foo")
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
defer rows.Close()
|
||||
for rows.Next() {
|
||||
var id int
|
||||
var name string
|
||||
err = rows.Scan(&id, &name)
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
fmt.Println(id, name)
|
||||
}
|
||||
err = rows.Err()
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
|
||||
stmt, err = db.Prepare("select name from foo where id = ?")
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
defer stmt.Close()
|
||||
var name string
|
||||
err = stmt.QueryRow("3").Scan(&name)
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
fmt.Println(name)
|
||||
|
||||
_, err = db.Exec("delete from foo")
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
|
||||
_, err = db.Exec("insert into foo(id, name) values(1, 'foo'), (2, 'bar'), (3, 'baz')")
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
|
||||
rows, err = db.Query("select id, name from foo")
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
defer rows.Close()
|
||||
for rows.Next() {
|
||||
var id int
|
||||
var name string
|
||||
err = rows.Scan(&id, &name)
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
fmt.Println(id, name)
|
||||
}
|
||||
err = rows.Err()
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
}
|
264
vendor/github.com/mattn/go-sqlite3/_example/trace/main.go
generated
vendored
Normal file
264
vendor/github.com/mattn/go-sqlite3/_example/trace/main.go
generated
vendored
Normal file
@@ -0,0 +1,264 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"database/sql"
|
||||
"fmt"
|
||||
"log"
|
||||
"os"
|
||||
|
||||
sqlite3 "github.com/mattn/go-sqlite3"
|
||||
)
|
||||
|
||||
func traceCallback(info sqlite3.TraceInfo) int {
|
||||
// Not very readable but may be useful; uncomment next line in case of doubt:
|
||||
//fmt.Printf("Trace: %#v\n", info)
|
||||
|
||||
var dbErrText string
|
||||
if info.DBError.Code != 0 || info.DBError.ExtendedCode != 0 {
|
||||
dbErrText = fmt.Sprintf("; DB error: %#v", info.DBError)
|
||||
} else {
|
||||
dbErrText = "."
|
||||
}
|
||||
|
||||
// Show the Statement-or-Trigger text in curly braces ('{', '}')
|
||||
// since from the *paired* ASCII characters they are
|
||||
// the least used in SQL syntax, therefore better visual delimiters.
|
||||
// Maybe show 'ExpandedSQL' the same way as 'StmtOrTrigger'.
|
||||
//
|
||||
// A known use of curly braces (outside strings) is
|
||||
// for ODBC escape sequences. Not likely to appear here.
|
||||
//
|
||||
// Template languages, etc. don't matter, we should see their *result*
|
||||
// at *this* level.
|
||||
// Strange curly braces in SQL code that reached the database driver
|
||||
// suggest that there is a bug in the application.
|
||||
// The braces are likely to be either template syntax or
|
||||
// a programming language's string interpolation syntax.
|
||||
|
||||
var expandedText string
|
||||
if info.ExpandedSQL != "" {
|
||||
if info.ExpandedSQL == info.StmtOrTrigger {
|
||||
expandedText = " = exp"
|
||||
} else {
|
||||
expandedText = fmt.Sprintf(" expanded {%q}", info.ExpandedSQL)
|
||||
}
|
||||
} else {
|
||||
expandedText = ""
|
||||
}
|
||||
|
||||
// SQLite docs as of September 6, 2016: Tracing and Profiling Functions
|
||||
// https://www.sqlite.org/c3ref/profile.html
|
||||
//
|
||||
// The profile callback time is in units of nanoseconds, however
|
||||
// the current implementation is only capable of millisecond resolution
|
||||
// so the six least significant digits in the time are meaningless.
|
||||
// Future versions of SQLite might provide greater resolution on the profiler callback.
|
||||
|
||||
var runTimeText string
|
||||
if info.RunTimeNanosec == 0 {
|
||||
if info.EventCode == sqlite3.TraceProfile {
|
||||
//runTimeText = "; no time" // seems confusing
|
||||
runTimeText = "; time 0" // no measurement unit
|
||||
} else {
|
||||
//runTimeText = "; no time" // seems useless and confusing
|
||||
}
|
||||
} else {
|
||||
const nanosPerMillisec = 1000000
|
||||
if info.RunTimeNanosec%nanosPerMillisec == 0 {
|
||||
runTimeText = fmt.Sprintf("; time %d ms", info.RunTimeNanosec/nanosPerMillisec)
|
||||
} else {
|
||||
// unexpected: better than millisecond resolution
|
||||
runTimeText = fmt.Sprintf("; time %d ns!!!", info.RunTimeNanosec)
|
||||
}
|
||||
}
|
||||
|
||||
var modeText string
|
||||
if info.AutoCommit {
|
||||
modeText = "-AC-"
|
||||
} else {
|
||||
modeText = "+Tx+"
|
||||
}
|
||||
|
||||
fmt.Printf("Trace: ev %d %s conn 0x%x, stmt 0x%x {%q}%s%s%s\n",
|
||||
info.EventCode, modeText, info.ConnHandle, info.StmtHandle,
|
||||
info.StmtOrTrigger, expandedText,
|
||||
runTimeText,
|
||||
dbErrText)
|
||||
return 0
|
||||
}
|
||||
|
||||
func main() {
|
||||
eventMask := sqlite3.TraceStmt | sqlite3.TraceProfile | sqlite3.TraceRow | sqlite3.TraceClose
|
||||
|
||||
sql.Register("sqlite3_tracing",
|
||||
&sqlite3.SQLiteDriver{
|
||||
ConnectHook: func(conn *sqlite3.SQLiteConn) error {
|
||||
err := conn.SetTrace(&sqlite3.TraceConfig{
|
||||
Callback: traceCallback,
|
||||
EventMask: uint(eventMask),
|
||||
WantExpandedSQL: true,
|
||||
})
|
||||
return err
|
||||
},
|
||||
})
|
||||
|
||||
os.Exit(dbMain())
|
||||
}
|
||||
|
||||
// Harder to do DB work in main().
|
||||
// It's better with a separate function because
|
||||
// 'defer' and 'os.Exit' don't go well together.
|
||||
//
|
||||
// DO NOT use 'log.Fatal...' below: remember that it's equivalent to
|
||||
// Print() followed by a call to os.Exit(1) --- and
|
||||
// we want to avoid Exit() so 'defer' can do cleanup.
|
||||
// Use 'log.Panic...' instead.
|
||||
|
||||
func dbMain() int {
|
||||
db, err := sql.Open("sqlite3_tracing", ":memory:")
|
||||
if err != nil {
|
||||
fmt.Printf("Failed to open database: %#+v\n", err)
|
||||
return 1
|
||||
}
|
||||
defer db.Close()
|
||||
|
||||
err = db.Ping()
|
||||
if err != nil {
|
||||
log.Panic(err)
|
||||
}
|
||||
|
||||
dbSetup(db)
|
||||
|
||||
dbDoInsert(db)
|
||||
dbDoInsertPrepared(db)
|
||||
dbDoSelect(db)
|
||||
dbDoSelectPrepared(db)
|
||||
|
||||
return 0
|
||||
}
|
||||
|
||||
// 'DDL' stands for "Data Definition Language":
|
||||
|
||||
// Note: "INTEGER PRIMARY KEY NOT NULL AUTOINCREMENT" causes the error
|
||||
// 'near "AUTOINCREMENT": syntax error'; without "NOT NULL" it works.
|
||||
const tableDDL = `CREATE TABLE t1 (
|
||||
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||
note VARCHAR NOT NULL
|
||||
)`
|
||||
|
||||
// 'DML' stands for "Data Manipulation Language":
|
||||
|
||||
const insertDML = "INSERT INTO t1 (note) VALUES (?)"
|
||||
const selectDML = "SELECT id, note FROM t1 WHERE note LIKE ?"
|
||||
|
||||
const textPrefix = "bla-1234567890-"
|
||||
const noteTextPattern = "%Prep%"
|
||||
|
||||
const nGenRows = 4 // Number of Rows to Generate (for *each* approach tested)
|
||||
|
||||
func dbSetup(db *sql.DB) {
|
||||
var err error
|
||||
|
||||
_, err = db.Exec("DROP TABLE IF EXISTS t1")
|
||||
if err != nil {
|
||||
log.Panic(err)
|
||||
}
|
||||
_, err = db.Exec(tableDDL)
|
||||
if err != nil {
|
||||
log.Panic(err)
|
||||
}
|
||||
}
|
||||
|
||||
func dbDoInsert(db *sql.DB) {
|
||||
const Descr = "DB-Exec"
|
||||
for i := 0; i < nGenRows; i++ {
|
||||
result, err := db.Exec(insertDML, textPrefix+Descr)
|
||||
if err != nil {
|
||||
log.Panic(err)
|
||||
}
|
||||
|
||||
resultDoCheck(result, Descr, i)
|
||||
}
|
||||
}
|
||||
|
||||
func dbDoInsertPrepared(db *sql.DB) {
|
||||
const Descr = "DB-Prepare"
|
||||
|
||||
stmt, err := db.Prepare(insertDML)
|
||||
if err != nil {
|
||||
log.Panic(err)
|
||||
}
|
||||
defer stmt.Close()
|
||||
|
||||
for i := 0; i < nGenRows; i++ {
|
||||
result, err := stmt.Exec(textPrefix + Descr)
|
||||
if err != nil {
|
||||
log.Panic(err)
|
||||
}
|
||||
|
||||
resultDoCheck(result, Descr, i)
|
||||
}
|
||||
}
|
||||
|
||||
func resultDoCheck(result sql.Result, callerDescr string, callIndex int) {
|
||||
lastID, err := result.LastInsertId()
|
||||
if err != nil {
|
||||
log.Panic(err)
|
||||
}
|
||||
nAffected, err := result.RowsAffected()
|
||||
if err != nil {
|
||||
log.Panic(err)
|
||||
}
|
||||
|
||||
log.Printf("Exec result for %s (%d): ID = %d, affected = %d\n", callerDescr, callIndex, lastID, nAffected)
|
||||
}
|
||||
|
||||
func dbDoSelect(db *sql.DB) {
|
||||
const Descr = "DB-Query"
|
||||
|
||||
rows, err := db.Query(selectDML, noteTextPattern)
|
||||
if err != nil {
|
||||
log.Panic(err)
|
||||
}
|
||||
defer rows.Close()
|
||||
|
||||
rowsDoFetch(rows, Descr)
|
||||
}
|
||||
|
||||
func dbDoSelectPrepared(db *sql.DB) {
|
||||
const Descr = "DB-Prepare"
|
||||
|
||||
stmt, err := db.Prepare(selectDML)
|
||||
if err != nil {
|
||||
log.Panic(err)
|
||||
}
|
||||
defer stmt.Close()
|
||||
|
||||
rows, err := stmt.Query(noteTextPattern)
|
||||
if err != nil {
|
||||
log.Panic(err)
|
||||
}
|
||||
defer rows.Close()
|
||||
|
||||
rowsDoFetch(rows, Descr)
|
||||
}
|
||||
|
||||
func rowsDoFetch(rows *sql.Rows, callerDescr string) {
|
||||
var nRows int
|
||||
var id int64
|
||||
var note string
|
||||
|
||||
for rows.Next() {
|
||||
err := rows.Scan(&id, ¬e)
|
||||
if err != nil {
|
||||
log.Panic(err)
|
||||
}
|
||||
log.Printf("Row for %s (%d): id=%d, note=%q\n",
|
||||
callerDescr, nRows, id, note)
|
||||
nRows++
|
||||
}
|
||||
if err := rows.Err(); err != nil {
|
||||
log.Panic(err)
|
||||
}
|
||||
log.Printf("Total %d rows for %s.\n", nRows, callerDescr)
|
||||
}
|
38
vendor/github.com/mattn/go-sqlite3/_example/vtable/main.go
generated
vendored
Normal file
38
vendor/github.com/mattn/go-sqlite3/_example/vtable/main.go
generated
vendored
Normal file
@@ -0,0 +1,38 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"database/sql"
|
||||
"fmt"
|
||||
"log"
|
||||
|
||||
"github.com/mattn/go-sqlite3"
|
||||
)
|
||||
|
||||
func main() {
|
||||
sql.Register("sqlite3_with_extensions", &sqlite3.SQLiteDriver{
|
||||
ConnectHook: func(conn *sqlite3.SQLiteConn) error {
|
||||
return conn.CreateModule("github", &githubModule{})
|
||||
},
|
||||
})
|
||||
db, err := sql.Open("sqlite3_with_extensions", ":memory:")
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
defer db.Close()
|
||||
|
||||
_, err = db.Exec("create virtual table repo using github(id, full_name, description, html_url)")
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
|
||||
rows, err := db.Query("select id, full_name, description, html_url from repo")
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
defer rows.Close()
|
||||
for rows.Next() {
|
||||
var id, fullName, description, htmlURL string
|
||||
rows.Scan(&id, &fullName, &description, &htmlURL)
|
||||
fmt.Printf("%s: %s\n\t%s\n\t%s\n\n", id, fullName, description, htmlURL)
|
||||
}
|
||||
}
|
111
vendor/github.com/mattn/go-sqlite3/_example/vtable/vtable.go
generated
vendored
Normal file
111
vendor/github.com/mattn/go-sqlite3/_example/vtable/vtable.go
generated
vendored
Normal file
@@ -0,0 +1,111 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"net/http"
|
||||
|
||||
"github.com/mattn/go-sqlite3"
|
||||
)
|
||||
|
||||
type githubRepo struct {
|
||||
ID int `json:"id"`
|
||||
FullName string `json:"full_name"`
|
||||
Description string `json:"description"`
|
||||
HTMLURL string `json:"html_url"`
|
||||
}
|
||||
|
||||
type githubModule struct {
|
||||
}
|
||||
|
||||
func (m *githubModule) Create(c *sqlite3.SQLiteConn, args []string) (sqlite3.VTab, error) {
|
||||
err := c.DeclareVTab(fmt.Sprintf(`
|
||||
CREATE TABLE %s (
|
||||
id INT,
|
||||
full_name TEXT,
|
||||
description TEXT,
|
||||
html_url TEXT
|
||||
)`, args[0]))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &ghRepoTable{}, nil
|
||||
}
|
||||
|
||||
func (m *githubModule) Connect(c *sqlite3.SQLiteConn, args []string) (sqlite3.VTab, error) {
|
||||
return m.Create(c, args)
|
||||
}
|
||||
|
||||
func (m *githubModule) DestroyModule() {}
|
||||
|
||||
type ghRepoTable struct {
|
||||
repos []githubRepo
|
||||
}
|
||||
|
||||
func (v *ghRepoTable) Open() (sqlite3.VTabCursor, error) {
|
||||
resp, err := http.Get("https://api.github.com/repositories")
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
|
||||
body, err := ioutil.ReadAll(resp.Body)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var repos []githubRepo
|
||||
if err := json.Unmarshal(body, &repos); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &ghRepoCursor{0, repos}, nil
|
||||
}
|
||||
|
||||
func (v *ghRepoTable) BestIndex(cst []sqlite3.InfoConstraint, ob []sqlite3.InfoOrderBy) (*sqlite3.IndexResult, error) {
|
||||
return &sqlite3.IndexResult{}, nil
|
||||
}
|
||||
|
||||
func (v *ghRepoTable) Disconnect() error { return nil }
|
||||
func (v *ghRepoTable) Destroy() error { return nil }
|
||||
|
||||
type ghRepoCursor struct {
|
||||
index int
|
||||
repos []githubRepo
|
||||
}
|
||||
|
||||
func (vc *ghRepoCursor) Column(c *sqlite3.SQLiteContext, col int) error {
|
||||
switch col {
|
||||
case 0:
|
||||
c.ResultInt(vc.repos[vc.index].ID)
|
||||
case 1:
|
||||
c.ResultText(vc.repos[vc.index].FullName)
|
||||
case 2:
|
||||
c.ResultText(vc.repos[vc.index].Description)
|
||||
case 3:
|
||||
c.ResultText(vc.repos[vc.index].HTMLURL)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (vc *ghRepoCursor) Filter(idxNum int, idxStr string, vals []interface{}) error {
|
||||
vc.index = 0
|
||||
return nil
|
||||
}
|
||||
|
||||
func (vc *ghRepoCursor) Next() error {
|
||||
vc.index++
|
||||
return nil
|
||||
}
|
||||
|
||||
func (vc *ghRepoCursor) EOF() bool {
|
||||
return vc.index >= len(vc.repos)
|
||||
}
|
||||
|
||||
func (vc *ghRepoCursor) Rowid() (int64, error) {
|
||||
return int64(vc.index), nil
|
||||
}
|
||||
|
||||
func (vc *ghRepoCursor) Close() error {
|
||||
return nil
|
||||
}
|
Reference in New Issue
Block a user