mirror of https://github.com/mattn/go-sqlite3.git
Add IsNullCallbackArg
This commit is contained in:
parent
f08f1b6b9c
commit
274eefa1e3
|
@ -409,3 +409,9 @@ func callbackSyntheticForTests(v reflect.Value, err error) callbackArgConverter
|
|||
return v, err
|
||||
}
|
||||
}
|
||||
|
||||
// NULL is passed into custom functions as a nil byte slice.
|
||||
func IsNullCallbackArg(arg interface{}) bool {
|
||||
val, ok := arg.([]byte)
|
||||
return ok && val == nil
|
||||
}
|
||||
|
|
|
@ -965,10 +965,12 @@ func (c *SQLiteConn) begin(ctx context.Context) (driver.Tx, error) {
|
|||
// The argument is may be either in parentheses or it may be separated from
|
||||
// the pragma name by an equal sign. The two syntaxes yield identical results.
|
||||
// In many pragmas, the argument is a boolean. The boolean can be one of:
|
||||
//
|
||||
// 1 yes true on
|
||||
// 0 no false off
|
||||
//
|
||||
// You can specify a DSN string using a URI as the filename.
|
||||
//
|
||||
// test.db
|
||||
// file:test.db?cache=shared&mode=memory
|
||||
// :memory:
|
||||
|
@ -1000,6 +1002,7 @@ func (c *SQLiteConn) begin(ctx context.Context) (driver.Tx, error) {
|
|||
// does in fact change can result in incorrect query results and/or SQLITE_CORRUPT errors.
|
||||
//
|
||||
// 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".
|
||||
//
|
||||
|
@ -1060,8 +1063,6 @@ func (c *SQLiteConn) begin(ctx context.Context) (driver.Tx, error) {
|
|||
// When this pragma is on, the SQLITE_MASTER tables in which database
|
||||
// can be changed using ordinary UPDATE, INSERT, and DELETE statements.
|
||||
// Warning: misuse of this pragma can easily result in a corrupt database file.
|
||||
//
|
||||
//
|
||||
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")
|
||||
|
|
|
@ -1439,6 +1439,70 @@ func TestFunctionRegistration(t *testing.T) {
|
|||
}
|
||||
}
|
||||
|
||||
func TestNullCallbackArg(t *testing.T) {
|
||||
sql.Register("sqlite3_NullCallbackArg", &SQLiteDriver{
|
||||
ConnectHook: func(conn *SQLiteConn) error {
|
||||
return conn.RegisterFunc("isNullArg", IsNullCallbackArg, true)
|
||||
},
|
||||
})
|
||||
db, err := sql.Open("sqlite3_NullCallbackArg", ":memory:")
|
||||
if err != nil {
|
||||
t.Fatal("Failed to open database:", err)
|
||||
}
|
||||
defer db.Close()
|
||||
|
||||
_, err = db.Exec("CREATE TABLE test (id integer not null primary key, col_int int, col_float float, col_blob blob, col_bool bool)")
|
||||
if err != nil {
|
||||
t.Fatal("Failed to create table:", err)
|
||||
}
|
||||
|
||||
_, err = db.Exec("insert into test values (1, NULL, NULL, NULL, NULL), (2, ?, ?, ?, ?)", 1, 1.5, []byte("blob"), false)
|
||||
if err != nil {
|
||||
t.Fatal("Failed to insert records:", err)
|
||||
}
|
||||
_, err = db.Exec("insert into test values (3, NULL, ?, NULL, ?)", 1.5, true)
|
||||
if err != nil {
|
||||
t.Fatal("Failed to insert records:", err)
|
||||
}
|
||||
_, err = db.Exec("insert into test values (4, NULL, NULL, ?, NULL)", []byte{})
|
||||
if err != nil {
|
||||
t.Fatal("Failed to insert records:", err)
|
||||
}
|
||||
|
||||
tests := []struct {
|
||||
id int64
|
||||
nullInt bool
|
||||
nullFloat bool
|
||||
nullBlob bool
|
||||
nullBool bool
|
||||
}{
|
||||
{1, true, true, true, true},
|
||||
{2, false, false, false, false},
|
||||
{3, true, false, true, false},
|
||||
{4, true, true, false, true},
|
||||
}
|
||||
|
||||
for _, test := range tests {
|
||||
var retInt, retFloat, retBlob, retBool bool
|
||||
err = db.QueryRow("select isNullArg(col_int), isNullArg(col_float), isNullArg(col_blob), isNullArg(col_bool) from test where id = $1", test.id).Scan(&retInt, &retFloat, &retBlob, &retBool)
|
||||
if err != nil {
|
||||
t.Fatal("Query failed:", err)
|
||||
}
|
||||
if retInt != test.nullInt {
|
||||
t.Fatalf("isNullArg returned wrong value for col_int, got %v, want %v", retInt, test.nullInt)
|
||||
}
|
||||
if retFloat != test.nullFloat {
|
||||
t.Fatalf("isNullArg returned wrong value for col_float, got %v, want %v", retFloat, test.nullFloat)
|
||||
}
|
||||
if retBlob != test.nullBlob {
|
||||
t.Fatalf("isNullArg returned wrong value for col_blob, got %v, want %v", retBlob, test.nullBlob)
|
||||
}
|
||||
if retBool != test.nullBool {
|
||||
t.Fatalf("isNullArg returned wrong value for col_bool, got %v, want %v", retBool, test.nullBlob)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
type sumAggregator int64
|
||||
|
||||
func (s *sumAggregator) Step(x int64) {
|
||||
|
|
Loading…
Reference in New Issue