Fix readonly transactions.

This commit is contained in:
Nuno Cruces
2023-02-25 15:34:24 +00:00
parent 1e4a246d2f
commit 125b8053f8
2 changed files with 25 additions and 10 deletions

16
conn.go
View File

@@ -340,6 +340,22 @@ func (conn *Conn) Savepoint() (release func(*error)) {
}
}
// Pragma executes a PRAGMA statement and returns any result as a string.
//
// https://www.sqlite.org/pragma.html
func (c *Conn) Pragma(str string) string {
stmt := c.MustPrepare(`PRAGMA ` + str)
defer stmt.Close()
if stmt.Step() {
return stmt.ColumnText(0)
}
if err := stmt.Err(); err != nil {
panic(err)
}
return ""
}
func (c *Conn) error(rc uint64, sql ...string) error {
if rc == _OK {
return nil

View File

@@ -62,9 +62,9 @@ func (sqlite) Open(name string) (driver.Conn, error) {
}
type conn struct {
conn *sqlite3.Conn
txBegin string
txReadOnly bool
conn *sqlite3.Conn
txBegin string
txCommit string
}
var (
@@ -90,13 +90,15 @@ func (c conn) BeginTx(ctx context.Context, opts driver.TxOptions) (driver.Tx, er
}
txBegin := c.txBegin
c.txCommit = `COMMIT`
if opts.ReadOnly {
c.txCommit = `
ROLLBACK;
PRAGMA query_only=` + c.conn.Pragma("query_only")
txBegin = `
BEGIN deferred;
PRAGMA query_only=on;
`
PRAGMA query_only=on`
}
c.txReadOnly = opts.ReadOnly
err := c.conn.Exec(txBegin)
if err != nil {
@@ -106,10 +108,7 @@ func (c conn) BeginTx(ctx context.Context, opts driver.TxOptions) (driver.Tx, er
}
func (c conn) Commit() error {
if c.txReadOnly {
return c.Rollback()
}
err := c.conn.Exec(`COMMIT`)
err := c.conn.Exec(c.txCommit)
if err != nil {
c.Rollback()
}