From 0b8d97f96dd4db0e50a1cb68a0740a55017c469b Mon Sep 17 00:00:00 2001 From: EuAndreh Date: Wed, 14 Aug 2024 17:31:36 -0300 Subject: git mv _example doc/examples/ --- _example/fuzz/fuzz_openexec.go | 30 ------- _example/json/json.go | 81 ------------------- _example/limit/limit.go | 113 --------------------------- _example/mod_regexp/Makefile | 27 ------- _example/mod_regexp/extension.go | 43 ---------- _example/mod_regexp/sqlite3_mod_regexp.c | 35 --------- doc/examples/fuzz/fuzz_openexec.go | 30 +++++++ doc/examples/json/json.go | 81 +++++++++++++++++++ doc/examples/limit/limit.go | 113 +++++++++++++++++++++++++++ doc/examples/mod_regexp/Makefile | 27 +++++++ doc/examples/mod_regexp/extension.go | 43 ++++++++++ doc/examples/mod_regexp/sqlite3_mod_regexp.c | 35 +++++++++ 12 files changed, 329 insertions(+), 329 deletions(-) delete mode 100644 _example/fuzz/fuzz_openexec.go delete mode 100644 _example/json/json.go delete mode 100644 _example/limit/limit.go delete mode 100644 _example/mod_regexp/Makefile delete mode 100644 _example/mod_regexp/extension.go delete mode 100644 _example/mod_regexp/sqlite3_mod_regexp.c create mode 100644 doc/examples/fuzz/fuzz_openexec.go create mode 100644 doc/examples/json/json.go create mode 100644 doc/examples/limit/limit.go create mode 100644 doc/examples/mod_regexp/Makefile create mode 100644 doc/examples/mod_regexp/extension.go create mode 100644 doc/examples/mod_regexp/sqlite3_mod_regexp.c diff --git a/_example/fuzz/fuzz_openexec.go b/_example/fuzz/fuzz_openexec.go deleted file mode 100644 index 5326044..0000000 --- a/_example/fuzz/fuzz_openexec.go +++ /dev/null @@ -1,30 +0,0 @@ -package sqlite3_fuzz - -import ( - "bytes" - "database/sql" - "io/ioutil" - - _ "github.com/mattn/go-sqlite3" -) - -func FuzzOpenExec(data []byte) int { - sep := bytes.IndexByte(data, 0) - if sep <= 0 { - return 0 - } - err := ioutil.WriteFile("/tmp/fuzz.db", data[sep+1:], 0644) - if err != nil { - return 0 - } - db, err := sql.Open("sqlite3", "/tmp/fuzz.db") - if err != nil { - return 0 - } - defer db.Close() - _, err = db.Exec(string(data[:sep-1])) - if err != nil { - return 0 - } - return 1 -} diff --git a/_example/json/json.go b/_example/json/json.go deleted file mode 100644 index 181934b..0000000 --- a/_example/json/json.go +++ /dev/null @@ -1,81 +0,0 @@ -package main - -import ( - "database/sql" - "database/sql/driver" - "encoding/json" - "fmt" - _ "github.com/mattn/go-sqlite3" - "log" - "os" -) - -type Tag struct { - Name string `json:"name"` - Country string `json:"country"` -} - -func (t *Tag) Scan(value interface{}) error { - return json.Unmarshal([]byte(value.(string)), t) -} - -func (t *Tag) Value() (driver.Value, error) { - b, err := json.Marshal(t) - return string(b), err -} - -func main() { - os.Remove("./foo.db") - - db, err := sql.Open("sqlite3", "./foo.db") - if err != nil { - log.Fatal(err) - } - defer db.Close() - - _, err = db.Exec(`create table foo (tag jsonb)`) - if err != nil { - log.Fatal(err) - } - - stmt, err := db.Prepare("insert into foo(tag) values(?)") - if err != nil { - log.Fatal(err) - } - defer stmt.Close() - _, err = stmt.Exec(`{"name": "mattn", "country": "japan"}`) - if err != nil { - log.Fatal(err) - } - _, err = stmt.Exec(`{"name": "michael", "country": "usa"}`) - if err != nil { - log.Fatal(err) - } - - var country string - err = db.QueryRow("select tag->>'country' from foo where tag->>'name' = 'mattn'").Scan(&country) - if err != nil { - log.Fatal(err) - } - fmt.Println(country) - - var tag Tag - err = db.QueryRow("select tag from foo where tag->>'name' = 'mattn'").Scan(&tag) - if err != nil { - log.Fatal(err) - } - - fmt.Println(tag.Name) - - tag.Country = "日本" - _, err = db.Exec(`update foo set tag = ? where tag->>'name' == 'mattn'`, &tag) - if err != nil { - log.Fatal(err) - } - - err = db.QueryRow("select tag->>'country' from foo where tag->>'name' = 'mattn'").Scan(&country) - if err != nil { - log.Fatal(err) - } - fmt.Println(country) -} diff --git a/_example/limit/limit.go b/_example/limit/limit.go deleted file mode 100644 index c1adfe8..0000000 --- a/_example/limit/limit.go +++ /dev/null @@ -1,113 +0,0 @@ -package main - -import ( - "database/sql" - "fmt" - "log" - "os" - "strings" - - "github.com/mattn/go-sqlite3" -) - -func createBulkInsertQuery(n int, start int) (query string, args []any) { - values := make([]string, n) - args = make([]any, n*2) - pos := 0 - for i := 0; i < n; i++ { - values[i] = "(?, ?)" - args[pos] = start + i - args[pos+1] = fmt.Sprintf("こんにちは世界%03d", i) - pos += 2 - } - query = fmt.Sprintf( - "insert into foo(id, name) values %s", - strings.Join(values, ", "), - ) - return -} - -func bulkInsert(db *sql.DB, query string, args []any) (err error) { - stmt, err := db.Prepare(query) - if err != nil { - return - } - - _, err = stmt.Exec(args...) - if err != nil { - return - } - - return -} - -func main() { - var sqlite3conn *sqlite3.SQLiteConn - sql.Register("sqlite3_with_limit", &sqlite3.SQLiteDriver{ - ConnectHook: func(conn *sqlite3.SQLiteConn) error { - sqlite3conn = conn - return nil - }, - }) - - os.Remove("./foo.db") - db, err := sql.Open("sqlite3_with_limit", "./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 - } - - if sqlite3conn == nil { - log.Fatal("not set sqlite3 connection") - } - - limitVariableNumber := sqlite3conn.GetLimit(sqlite3.SQLITE_LIMIT_VARIABLE_NUMBER) - log.Printf("default SQLITE_LIMIT_VARIABLE_NUMBER: %d", limitVariableNumber) - - num := 400 - query, args := createBulkInsertQuery(num, 0) - err = bulkInsert(db, query, args) - if err != nil { - log.Fatal(err) - } - - smallLimitVariableNumber := 100 - sqlite3conn.SetLimit(sqlite3.SQLITE_LIMIT_VARIABLE_NUMBER, smallLimitVariableNumber) - - limitVariableNumber = sqlite3conn.GetLimit(sqlite3.SQLITE_LIMIT_VARIABLE_NUMBER) - log.Printf("updated SQLITE_LIMIT_VARIABLE_NUMBER: %d", limitVariableNumber) - - query, args = createBulkInsertQuery(num, num) - err = bulkInsert(db, query, args) - if err != nil { - if err != nil { - log.Printf("expect failed since SQLITE_LIMIT_VARIABLE_NUMBER is too small: %v", err) - } - } - - bigLimitVariableNumber := 999999 - sqlite3conn.SetLimit(sqlite3.SQLITE_LIMIT_VARIABLE_NUMBER, bigLimitVariableNumber) - limitVariableNumber = sqlite3conn.GetLimit(sqlite3.SQLITE_LIMIT_VARIABLE_NUMBER) - log.Printf("set SQLITE_LIMIT_VARIABLE_NUMBER: %d", bigLimitVariableNumber) - log.Printf("updated SQLITE_LIMIT_VARIABLE_NUMBER: %d", limitVariableNumber) - - query, args = createBulkInsertQuery(500, num+num) - err = bulkInsert(db, query, args) - if err != nil { - if err != nil { - log.Fatal(err) - } - } - - log.Println("no error if SQLITE_LIMIT_VARIABLE_NUMBER > 999") -} diff --git a/_example/mod_regexp/Makefile b/_example/mod_regexp/Makefile deleted file mode 100644 index 1ef69a6..0000000 --- a/_example/mod_regexp/Makefile +++ /dev/null @@ -1,27 +0,0 @@ -ifeq ($(OS),Windows_NT) -EXE=extension.exe -LIB_EXT=dll -RM=cmd /c del -LDFLAG= -else -EXE=extension -ifeq ($(shell uname -s),Darwin) -LIB_EXT=dylib -else -LIB_EXT=so -endif -RM=rm -f -LDFLAG=-fPIC -endif -LIB=sqlite3_mod_regexp.$(LIB_EXT) - -all : $(EXE) $(LIB) - -$(EXE) : extension.go - go build $< - -$(LIB) : sqlite3_mod_regexp.c - gcc $(LDFLAG) -shared -o $@ $< -lsqlite3 -lpcre - -clean : - @-$(RM) $(EXE) $(LIB) diff --git a/_example/mod_regexp/extension.go b/_example/mod_regexp/extension.go deleted file mode 100644 index 61ceb55..0000000 --- a/_example/mod_regexp/extension.go +++ /dev/null @@ -1,43 +0,0 @@ -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) - } -} diff --git a/_example/mod_regexp/sqlite3_mod_regexp.c b/_example/mod_regexp/sqlite3_mod_regexp.c deleted file mode 100644 index d3ad149..0000000 --- a/_example/mod_regexp/sqlite3_mod_regexp.c +++ /dev/null @@ -1,35 +0,0 @@ -#include -#include -#include -#include - -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); - if (!re) { - sqlite3_result_error(context, errstr, 0); - return; - } - rc = pcre_exec(re, NULL, target, strlen(target), 0, 0, vec, 500); - if (rc <= 0) { - sqlite3_result_int(context, 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); -} diff --git a/doc/examples/fuzz/fuzz_openexec.go b/doc/examples/fuzz/fuzz_openexec.go new file mode 100644 index 0000000..5326044 --- /dev/null +++ b/doc/examples/fuzz/fuzz_openexec.go @@ -0,0 +1,30 @@ +package sqlite3_fuzz + +import ( + "bytes" + "database/sql" + "io/ioutil" + + _ "github.com/mattn/go-sqlite3" +) + +func FuzzOpenExec(data []byte) int { + sep := bytes.IndexByte(data, 0) + if sep <= 0 { + return 0 + } + err := ioutil.WriteFile("/tmp/fuzz.db", data[sep+1:], 0644) + if err != nil { + return 0 + } + db, err := sql.Open("sqlite3", "/tmp/fuzz.db") + if err != nil { + return 0 + } + defer db.Close() + _, err = db.Exec(string(data[:sep-1])) + if err != nil { + return 0 + } + return 1 +} diff --git a/doc/examples/json/json.go b/doc/examples/json/json.go new file mode 100644 index 0000000..181934b --- /dev/null +++ b/doc/examples/json/json.go @@ -0,0 +1,81 @@ +package main + +import ( + "database/sql" + "database/sql/driver" + "encoding/json" + "fmt" + _ "github.com/mattn/go-sqlite3" + "log" + "os" +) + +type Tag struct { + Name string `json:"name"` + Country string `json:"country"` +} + +func (t *Tag) Scan(value interface{}) error { + return json.Unmarshal([]byte(value.(string)), t) +} + +func (t *Tag) Value() (driver.Value, error) { + b, err := json.Marshal(t) + return string(b), err +} + +func main() { + os.Remove("./foo.db") + + db, err := sql.Open("sqlite3", "./foo.db") + if err != nil { + log.Fatal(err) + } + defer db.Close() + + _, err = db.Exec(`create table foo (tag jsonb)`) + if err != nil { + log.Fatal(err) + } + + stmt, err := db.Prepare("insert into foo(tag) values(?)") + if err != nil { + log.Fatal(err) + } + defer stmt.Close() + _, err = stmt.Exec(`{"name": "mattn", "country": "japan"}`) + if err != nil { + log.Fatal(err) + } + _, err = stmt.Exec(`{"name": "michael", "country": "usa"}`) + if err != nil { + log.Fatal(err) + } + + var country string + err = db.QueryRow("select tag->>'country' from foo where tag->>'name' = 'mattn'").Scan(&country) + if err != nil { + log.Fatal(err) + } + fmt.Println(country) + + var tag Tag + err = db.QueryRow("select tag from foo where tag->>'name' = 'mattn'").Scan(&tag) + if err != nil { + log.Fatal(err) + } + + fmt.Println(tag.Name) + + tag.Country = "日本" + _, err = db.Exec(`update foo set tag = ? where tag->>'name' == 'mattn'`, &tag) + if err != nil { + log.Fatal(err) + } + + err = db.QueryRow("select tag->>'country' from foo where tag->>'name' = 'mattn'").Scan(&country) + if err != nil { + log.Fatal(err) + } + fmt.Println(country) +} diff --git a/doc/examples/limit/limit.go b/doc/examples/limit/limit.go new file mode 100644 index 0000000..c1adfe8 --- /dev/null +++ b/doc/examples/limit/limit.go @@ -0,0 +1,113 @@ +package main + +import ( + "database/sql" + "fmt" + "log" + "os" + "strings" + + "github.com/mattn/go-sqlite3" +) + +func createBulkInsertQuery(n int, start int) (query string, args []any) { + values := make([]string, n) + args = make([]any, n*2) + pos := 0 + for i := 0; i < n; i++ { + values[i] = "(?, ?)" + args[pos] = start + i + args[pos+1] = fmt.Sprintf("こんにちは世界%03d", i) + pos += 2 + } + query = fmt.Sprintf( + "insert into foo(id, name) values %s", + strings.Join(values, ", "), + ) + return +} + +func bulkInsert(db *sql.DB, query string, args []any) (err error) { + stmt, err := db.Prepare(query) + if err != nil { + return + } + + _, err = stmt.Exec(args...) + if err != nil { + return + } + + return +} + +func main() { + var sqlite3conn *sqlite3.SQLiteConn + sql.Register("sqlite3_with_limit", &sqlite3.SQLiteDriver{ + ConnectHook: func(conn *sqlite3.SQLiteConn) error { + sqlite3conn = conn + return nil + }, + }) + + os.Remove("./foo.db") + db, err := sql.Open("sqlite3_with_limit", "./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 + } + + if sqlite3conn == nil { + log.Fatal("not set sqlite3 connection") + } + + limitVariableNumber := sqlite3conn.GetLimit(sqlite3.SQLITE_LIMIT_VARIABLE_NUMBER) + log.Printf("default SQLITE_LIMIT_VARIABLE_NUMBER: %d", limitVariableNumber) + + num := 400 + query, args := createBulkInsertQuery(num, 0) + err = bulkInsert(db, query, args) + if err != nil { + log.Fatal(err) + } + + smallLimitVariableNumber := 100 + sqlite3conn.SetLimit(sqlite3.SQLITE_LIMIT_VARIABLE_NUMBER, smallLimitVariableNumber) + + limitVariableNumber = sqlite3conn.GetLimit(sqlite3.SQLITE_LIMIT_VARIABLE_NUMBER) + log.Printf("updated SQLITE_LIMIT_VARIABLE_NUMBER: %d", limitVariableNumber) + + query, args = createBulkInsertQuery(num, num) + err = bulkInsert(db, query, args) + if err != nil { + if err != nil { + log.Printf("expect failed since SQLITE_LIMIT_VARIABLE_NUMBER is too small: %v", err) + } + } + + bigLimitVariableNumber := 999999 + sqlite3conn.SetLimit(sqlite3.SQLITE_LIMIT_VARIABLE_NUMBER, bigLimitVariableNumber) + limitVariableNumber = sqlite3conn.GetLimit(sqlite3.SQLITE_LIMIT_VARIABLE_NUMBER) + log.Printf("set SQLITE_LIMIT_VARIABLE_NUMBER: %d", bigLimitVariableNumber) + log.Printf("updated SQLITE_LIMIT_VARIABLE_NUMBER: %d", limitVariableNumber) + + query, args = createBulkInsertQuery(500, num+num) + err = bulkInsert(db, query, args) + if err != nil { + if err != nil { + log.Fatal(err) + } + } + + log.Println("no error if SQLITE_LIMIT_VARIABLE_NUMBER > 999") +} diff --git a/doc/examples/mod_regexp/Makefile b/doc/examples/mod_regexp/Makefile new file mode 100644 index 0000000..1ef69a6 --- /dev/null +++ b/doc/examples/mod_regexp/Makefile @@ -0,0 +1,27 @@ +ifeq ($(OS),Windows_NT) +EXE=extension.exe +LIB_EXT=dll +RM=cmd /c del +LDFLAG= +else +EXE=extension +ifeq ($(shell uname -s),Darwin) +LIB_EXT=dylib +else +LIB_EXT=so +endif +RM=rm -f +LDFLAG=-fPIC +endif +LIB=sqlite3_mod_regexp.$(LIB_EXT) + +all : $(EXE) $(LIB) + +$(EXE) : extension.go + go build $< + +$(LIB) : sqlite3_mod_regexp.c + gcc $(LDFLAG) -shared -o $@ $< -lsqlite3 -lpcre + +clean : + @-$(RM) $(EXE) $(LIB) diff --git a/doc/examples/mod_regexp/extension.go b/doc/examples/mod_regexp/extension.go new file mode 100644 index 0000000..61ceb55 --- /dev/null +++ b/doc/examples/mod_regexp/extension.go @@ -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) + } +} diff --git a/doc/examples/mod_regexp/sqlite3_mod_regexp.c b/doc/examples/mod_regexp/sqlite3_mod_regexp.c new file mode 100644 index 0000000..d3ad149 --- /dev/null +++ b/doc/examples/mod_regexp/sqlite3_mod_regexp.c @@ -0,0 +1,35 @@ +#include +#include +#include +#include + +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); + if (!re) { + sqlite3_result_error(context, errstr, 0); + return; + } + rc = pcre_exec(re, NULL, target, strlen(target), 0, 0, vec, 500); + if (rc <= 0) { + sqlite3_result_int(context, 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); +} -- cgit v1.2.3