This commit is contained in:
Nuno Cruces
2023-02-20 13:38:03 +00:00
parent 2f5b9837e1
commit df687a1c54
6 changed files with 61 additions and 6 deletions

View File

@@ -26,14 +26,18 @@ func (sqlite) Open(name string) (driver.Conn, error) {
return nil, err
}
var txBegin = "BEGIN "
var txBegin string
var pragmas strings.Builder
if _, after, ok := strings.Cut(name, "?"); ok {
query, _ := url.ParseQuery(after)
switch v := query.Get("_txlock"); v {
switch s := query.Get("_txlock"); s {
case "":
txBegin = "BEGIN"
case "deferred", "immediate", "exclusive":
txBegin += v
txBegin = "BEGIN " + s
default:
return nil, fmt.Errorf("sqlite3: invalid _txlock: %s", s)
}
for _, p := range query["_pragma"] {
@@ -219,6 +223,8 @@ func (s stmt) Query(args []driver.Value) (driver.Rows, error) {
}
func (s stmt) ExecContext(ctx context.Context, args []driver.NamedValue) (driver.Result, error) {
// Use QueryContext to setup bindings.
// No need to close rows: that simply resets the statement, exec does the same.
_, err := s.QueryContext(ctx, args)
if err != nil {
return nil, err

View File

@@ -78,7 +78,8 @@ func Test_Open_pragma_invalid(t *testing.T) {
}
func Test_Open_txLock(t *testing.T) {
db, err := sql.Open("sqlite3", filepath.Join(t.TempDir(), "test.db")+
db, err := sql.Open("sqlite3", "file:"+
filepath.Join(t.TempDir(), "test.db")+
"?_txlock=exclusive&_pragma=busy_timeout(0)")
if err != nil {
t.Fatal(err)
@@ -101,6 +102,10 @@ func Test_Open_txLock(t *testing.T) {
if rc := serr.Code(); rc != sqlite3.BUSY {
t.Errorf("got %d, want sqlite3.BUSY", rc)
}
var terr interface{ Temporary() bool }
if !errors.As(err, &terr) || !terr.Temporary() {
t.Error("not temporary", err)
}
if got := err.Error(); got != `sqlite3: database is locked` {
t.Error("got message: ", got)
}
@@ -111,6 +116,22 @@ func Test_Open_txLock(t *testing.T) {
}
}
func Test_Open_txLock_invalid(t *testing.T) {
db, err := sql.Open("sqlite3", "file::memory:?_txlock=xclusive")
if err != nil {
t.Fatal(err)
}
defer db.Close()
_, err = db.Conn(context.TODO())
if err == nil {
t.Fatal("want error")
}
if got := err.Error(); got != `sqlite3: invalid _txlock: xclusive` {
t.Error("got message: ", got)
}
}
func Test_BeginTx(t *testing.T) {
ctx, cancel := context.WithCancel(context.Background())
defer cancel()
@@ -122,7 +143,7 @@ func Test_BeginTx(t *testing.T) {
defer db.Close()
_, err = db.BeginTx(ctx, &sql.TxOptions{Isolation: sql.LevelReadCommitted})
if err != isolationErr {
if err.Error() != string(isolationErr) {
t.Error("want isolationErr")
}
@@ -205,7 +226,7 @@ func Test_Prepare(t *testing.T) {
}
_, err = db.Prepare(`SELECT 1; SELECT 2`)
if err != tailErr {
if err.Error() != string(tailErr) {
t.Error("want tailErr")
}
}