This commit is contained in:
Nuno Cruces
2024-02-02 17:40:55 +00:00
parent 031087327d
commit 9898fbfffa
3 changed files with 22 additions and 19 deletions

View File

@@ -9,7 +9,7 @@
#define SQLITE_VTAB_RENAMER_GO /******/ 0x08 #define SQLITE_VTAB_RENAMER_GO /******/ 0x08
#define SQLITE_VTAB_OVERLOADER_GO /***/ 0x10 #define SQLITE_VTAB_OVERLOADER_GO /***/ 0x10
#define SQLITE_VTAB_CHECKER_GO /******/ 0x20 #define SQLITE_VTAB_CHECKER_GO /******/ 0x20
#define SQLITE_VTAB_TX_GO /***********/ 0x40 #define SQLITE_VTAB_TXN_GO /**********/ 0x40
#define SQLITE_VTAB_SAVEPOINTER_GO /**/ 0x80 #define SQLITE_VTAB_SAVEPOINTER_GO /**/ 0x80
int go_vtab_create(sqlite3_module *, int argc, const char *const *argv, int go_vtab_create(sqlite3_module *, int argc, const char *const *argv,
@@ -193,7 +193,7 @@ int sqlite3_create_module_go(sqlite3 *db, const char *zName, int flags,
if (flags & SQLITE_VTAB_CHECKER_GO) { if (flags & SQLITE_VTAB_CHECKER_GO) {
mod->base.xIntegrity = go_vtab_integrity_wrapper; mod->base.xIntegrity = go_vtab_integrity_wrapper;
} }
if (flags & SQLITE_VTAB_TX_GO) { if (flags & SQLITE_VTAB_TXN_GO) {
mod->base.xBegin = go_vtab_begin; mod->base.xBegin = go_vtab_begin;
mod->base.xSync = go_vtab_sync; mod->base.xSync = go_vtab_sync;
mod->base.xCommit = go_vtab_commit; mod->base.xCommit = go_vtab_commit;

14
txn.go
View File

@@ -25,7 +25,7 @@ type Txn struct {
// https://sqlite.org/lang_transaction.html // https://sqlite.org/lang_transaction.html
func (c *Conn) Begin() Txn { func (c *Conn) Begin() Txn {
// BEGIN even if interrupted. // BEGIN even if interrupted.
err := c.txExecInterrupted(`BEGIN DEFERRED`) err := c.txnExecInterrupted(`BEGIN DEFERRED`)
if err != nil { if err != nil {
panic(err) panic(err)
} }
@@ -54,7 +54,7 @@ func (c *Conn) BeginExclusive() (Txn, error) {
return Txn{c}, nil return Txn{c}, nil
} }
// End calls either [Tx.Commit] or [Tx.Rollback] // End calls either [Txn.Commit] or [Txn.Rollback]
// depending on whether *error points to a nil or non-nil error. // depending on whether *error points to a nil or non-nil error.
// //
// This is meant to be deferred: // This is meant to be deferred:
@@ -107,7 +107,7 @@ func (tx Txn) Commit() error {
// //
// https://sqlite.org/lang_transaction.html // https://sqlite.org/lang_transaction.html
func (tx Txn) Rollback() error { func (tx Txn) Rollback() error {
return tx.c.txExecInterrupted(`ROLLBACK`) return tx.c.txnExecInterrupted(`ROLLBACK`)
} }
// Savepoint is a marker within a transaction // Savepoint is a marker within a transaction
@@ -126,7 +126,7 @@ func (c *Conn) Savepoint() Savepoint {
// Names can be reused; this makes catching bugs more likely. // Names can be reused; this makes catching bugs more likely.
name := saveptName() + "_" + strconv.Itoa(int(rand.Int31())) name := saveptName() + "_" + strconv.Itoa(int(rand.Int31()))
err := c.txExecInterrupted(fmt.Sprintf("SAVEPOINT %q;", name)) err := c.txnExecInterrupted(fmt.Sprintf("SAVEPOINT %q;", name))
if err != nil { if err != nil {
panic(err) panic(err)
} }
@@ -188,7 +188,7 @@ func (s Savepoint) Release(errp *error) {
return return
} }
// ROLLBACK and RELEASE even if interrupted. // ROLLBACK and RELEASE even if interrupted.
err := s.c.txExecInterrupted(fmt.Sprintf(` err := s.c.txnExecInterrupted(fmt.Sprintf(`
ROLLBACK TO %[1]q; ROLLBACK TO %[1]q;
RELEASE %[1]q; RELEASE %[1]q;
`, s.name)) `, s.name))
@@ -204,10 +204,10 @@ func (s Savepoint) Release(errp *error) {
// https://sqlite.org/lang_transaction.html // https://sqlite.org/lang_transaction.html
func (s Savepoint) Rollback() error { func (s Savepoint) Rollback() error {
// ROLLBACK even if interrupted. // ROLLBACK even if interrupted.
return s.c.txExecInterrupted(fmt.Sprintf("ROLLBACK TO %q;", s.name)) return s.c.txnExecInterrupted(fmt.Sprintf("ROLLBACK TO %q;", s.name))
} }
func (c *Conn) txExecInterrupted(sql string) error { func (c *Conn) txnExecInterrupted(sql string) error {
err := c.Exec(sql) err := c.Exec(sql)
if errors.Is(err, INTERRUPT) { if errors.Is(err, INTERRUPT) {
old := c.SetInterrupt(context.Background()) old := c.SetInterrupt(context.Background())

23
vtab.go
View File

@@ -22,7 +22,7 @@ func CreateModule[T VTab](db *Conn, name string, create, connect VTabConstructor
VTAB_RENAMER = 0x08 VTAB_RENAMER = 0x08
VTAB_OVERLOADER = 0x10 VTAB_OVERLOADER = 0x10
VTAB_CHECKER = 0x20 VTAB_CHECKER = 0x20
VTAB_TX = 0x40 VTAB_TXN = 0x40
VTAB_SAVEPOINTER = 0x80 VTAB_SAVEPOINTER = 0x80
) )
@@ -46,8 +46,8 @@ func CreateModule[T VTab](db *Conn, name string, create, connect VTabConstructor
if implements[VTabChecker](vtab) { if implements[VTabChecker](vtab) {
flags |= VTAB_CHECKER flags |= VTAB_CHECKER
} }
if implements[VTabTx](vtab) { if implements[VTabTxn](vtab) {
flags |= VTAB_TX flags |= VTAB_TXN
} }
if implements[VTabSavepointer](vtab) { if implements[VTabSavepointer](vtab) {
flags |= VTAB_SAVEPOINTER flags |= VTAB_SAVEPOINTER
@@ -187,14 +187,14 @@ type VTabChecker interface {
Integrity(schema, table string, flags int) error Integrity(schema, table string, flags int) error
} }
// A VTabTx allows a virtual table to implement // A VTabTxn allows a virtual table to implement
// transactions with two-phase commit. // transactions with two-phase commit.
// //
// Anything that is required as part of a commit that may fail // Anything that is required as part of a commit that may fail
// should be performed in the Sync() callback. // should be performed in the Sync() callback.
// Current versions of SQLite ignore any errors // Current versions of SQLite ignore any errors
// returned by Commit() and Rollback(). // returned by Commit() and Rollback().
type VTabTx interface { type VTabTxn interface {
VTab VTab
// https://sqlite.org/vtab.html#xBegin // https://sqlite.org/vtab.html#xBegin
Begin() error Begin() error
@@ -206,12 +206,15 @@ type VTabTx interface {
Rollback() error Rollback() error
} }
// Deprecated: renamed for consistency with [Conn.TxnState].
type VTabTx = VTabTxn
// A VTabSavepointer allows a virtual table to implement // A VTabSavepointer allows a virtual table to implement
// nested transactions. // nested transactions.
// //
// https://sqlite.org/vtab.html#xsavepoint // https://sqlite.org/vtab.html#xsavepoint
type VTabSavepointer interface { type VTabSavepointer interface {
VTabTx VTabTxn
Savepoint(id int) error Savepoint(id int) error
Release(id int) error Release(id int) error
RollbackTo(id int) error RollbackTo(id int) error
@@ -516,25 +519,25 @@ func vtabIntegrityCallback(ctx context.Context, mod api.Module, pVTab, zSchema,
} }
func vtabBeginCallback(ctx context.Context, mod api.Module, pVTab uint32) uint32 { func vtabBeginCallback(ctx context.Context, mod api.Module, pVTab uint32) uint32 {
vtab := vtabGetHandle(ctx, mod, pVTab).(VTabTx) vtab := vtabGetHandle(ctx, mod, pVTab).(VTabTxn)
err := vtab.Begin() err := vtab.Begin()
return vtabError(ctx, mod, pVTab, _VTAB_ERROR, err) return vtabError(ctx, mod, pVTab, _VTAB_ERROR, err)
} }
func vtabSyncCallback(ctx context.Context, mod api.Module, pVTab uint32) uint32 { func vtabSyncCallback(ctx context.Context, mod api.Module, pVTab uint32) uint32 {
vtab := vtabGetHandle(ctx, mod, pVTab).(VTabTx) vtab := vtabGetHandle(ctx, mod, pVTab).(VTabTxn)
err := vtab.Sync() err := vtab.Sync()
return vtabError(ctx, mod, pVTab, _VTAB_ERROR, err) return vtabError(ctx, mod, pVTab, _VTAB_ERROR, err)
} }
func vtabCommitCallback(ctx context.Context, mod api.Module, pVTab uint32) uint32 { func vtabCommitCallback(ctx context.Context, mod api.Module, pVTab uint32) uint32 {
vtab := vtabGetHandle(ctx, mod, pVTab).(VTabTx) vtab := vtabGetHandle(ctx, mod, pVTab).(VTabTxn)
err := vtab.Commit() err := vtab.Commit()
return vtabError(ctx, mod, pVTab, _VTAB_ERROR, err) return vtabError(ctx, mod, pVTab, _VTAB_ERROR, err)
} }
func vtabRollbackCallback(ctx context.Context, mod api.Module, pVTab uint32) uint32 { func vtabRollbackCallback(ctx context.Context, mod api.Module, pVTab uint32) uint32 {
vtab := vtabGetHandle(ctx, mod, pVTab).(VTabTx) vtab := vtabGetHandle(ctx, mod, pVTab).(VTabTxn)
err := vtab.Rollback() err := vtab.Rollback()
return vtabError(ctx, mod, pVTab, _VTAB_ERROR, err) return vtabError(ctx, mod, pVTab, _VTAB_ERROR, err)
} }