package sqlite3import ()// Txn is an in-progress database transaction.//// https://sqlite.org/lang_transaction.htmltypeTxnstruct { c *Conn}// Begin starts a deferred transaction.// It panics if a transaction is in-progress.// For nested transactions, use [Conn.Savepoint].//// https://sqlite.org/lang_transaction.htmlfunc ( *Conn) () Txn {// BEGIN even if interrupted. := .exec(`BEGIN DEFERRED`)if != nil {panic() }returnTxn{}}// BeginConcurrent starts a concurrent transaction.//// Experimental: requires a custom build of SQLite.//// https://sqlite.org/cgi/src/doc/begin-concurrent/doc/begin_concurrent.mdfunc ( *Conn) () (Txn, error) { := .Exec(`BEGIN CONCURRENT`)if != nil {returnTxn{}, }returnTxn{}, nil}// BeginImmediate starts an immediate transaction.//// https://sqlite.org/lang_transaction.htmlfunc ( *Conn) () (Txn, error) { := .Exec(`BEGIN IMMEDIATE`)if != nil {returnTxn{}, }returnTxn{}, nil}// BeginExclusive starts an exclusive transaction.//// https://sqlite.org/lang_transaction.htmlfunc ( *Conn) () (Txn, error) { := .Exec(`BEGIN EXCLUSIVE`)if != nil {returnTxn{}, }returnTxn{}, nil}// End calls either [Txn.Commit] or [Txn.Rollback]// depending on whether *error points to a nil or non-nil error.//// This is meant to be deferred://// func doWork(db *sqlite3.Conn) (err error) {// tx := db.Begin()// defer tx.End(&err)//// // ... do work in the transaction// }//// https://sqlite.org/lang_transaction.htmlfunc ( Txn) ( *error) { := recover()if != nil {deferpanic() }if * == nil && == nil {// Success path.if .c.GetAutocommit() { // There is nothing to commit.return } * = .Commit()if * == nil {return }// Fall through to the error path. }// Error path.if .c.GetAutocommit() { // There is nothing to rollback.return } := .Rollback()if != nil {panic() }}// Commit commits the transaction.//// https://sqlite.org/lang_transaction.htmlfunc ( Txn) () error {return .c.Exec(`COMMIT`)}// Rollback rolls back the transaction,// even if the connection has been interrupted.//// https://sqlite.org/lang_transaction.htmlfunc ( Txn) () error {// ROLLBACK even if interrupted.return .c.exec(`ROLLBACK`)}// Savepoint is a marker within a transaction// that allows for partial rollback.//// https://sqlite.org/lang_savepoint.htmltypeSavepointstruct { c *Conn name string}// Savepoint establishes a new transaction savepoint.//// https://sqlite.org/lang_savepoint.htmlfunc ( *Conn) () Savepoint { := callerName()if == "" { = "sqlite3.Savepoint" }// Names can be reused, but this makes catching bugs more likely. = QuoteIdentifier( + "_" + strconv.Itoa(int(rand.Int31()))) := .exec(`SAVEPOINT ` + )if != nil {panic() }returnSavepoint{c: , name: }}func callerName() ( string) {var [8]uintptr := runtime.Callers(3, [:])if <= 0 {return"" } := runtime.CallersFrames([:]) , := .Next()for && (strings.HasPrefix(.Function, "database/sql.") ||strings.HasPrefix(.Function, "github.com/ncruces/go-sqlite3/driver.")) { , = .Next() }return .Function}// Release releases the savepoint rolling back any changes// if *error points to a non-nil error.//// This is meant to be deferred://// func doWork(db *sqlite3.Conn) (err error) {// savept := db.Savepoint()// defer savept.Release(&err)//// // ... do work in the transaction// }func ( Savepoint) ( *error) { := recover()if != nil {deferpanic() }if * == nil && == nil {// Success path.if .c.GetAutocommit() { // There is nothing to commit.return } * = .c.Exec(`RELEASE ` + .name)if * == nil {return }// Fall through to the error path. }// Error path.if .c.GetAutocommit() { // There is nothing to rollback.return }// ROLLBACK and RELEASE even if interrupted. := .c.exec(`ROLLBACK TO ` + .name + `; RELEASE ` + .name)if != nil {panic() }}// Rollback rolls the transaction back to the savepoint,// even if the connection has been interrupted.// Rollback does not release the savepoint.//// https://sqlite.org/lang_transaction.htmlfunc ( Savepoint) () error {// ROLLBACK even if interrupted.return .c.exec(`ROLLBACK TO ` + .name)}// TxnState determines the transaction state of a database.//// https://sqlite.org/c3ref/txn_state.htmlfunc ( *Conn) ( string) TxnState {varptr_tif != "" {defer .arena.mark()() = .arena.string() }returnTxnState(.call("sqlite3_txn_state", stk_t(.handle), stk_t()))}// CommitHook registers a callback function to be invoked// whenever a transaction is committed.// Return true to allow the commit operation to continue normally.//// https://sqlite.org/c3ref/commit_hook.htmlfunc ( *Conn) ( func() ( bool)) {varint32if != nil { = 1 } .call("sqlite3_commit_hook_go", stk_t(.handle), stk_t()) .commit = }// RollbackHook registers a callback function to be invoked// whenever a transaction is rolled back.//// https://sqlite.org/c3ref/commit_hook.htmlfunc ( *Conn) ( func()) {varint32if != nil { = 1 } .call("sqlite3_rollback_hook_go", stk_t(.handle), stk_t()) .rollback = }// UpdateHook registers a callback function to be invoked// whenever a row is updated, inserted or deleted in a rowid table.//// https://sqlite.org/c3ref/update_hook.htmlfunc ( *Conn) ( func( AuthorizerActionCode, , string, int64)) {varint32if != nil { = 1 } .call("sqlite3_update_hook_go", stk_t(.handle), stk_t()) .update = }func commitCallback( context.Context, api.Module, ptr_t) ( int32) {if , := .Value(connKey{}).(*Conn); && .handle == && .commit != nil {if !.commit() { = 1 } }return}func rollbackCallback( context.Context, api.Module, ptr_t) {if , := .Value(connKey{}).(*Conn); && .handle == && .rollback != nil { .rollback() }}func updateCallback( context.Context, api.Module, ptr_t, AuthorizerActionCode, , ptr_t, int64) {if , := .Value(connKey{}).(*Conn); && .handle == && .update != nil { := util.ReadString(, , _MAX_NAME) := util.ReadString(, , _MAX_NAME) .update(, , , ) }}// CacheFlush flushes caches to disk mid-transaction.//// https://sqlite.org/c3ref/db_cacheflush.htmlfunc ( *Conn) () error { := res_t(.call("sqlite3_db_cacheflush", stk_t(.handle)))return .error()}
The pages are generated with Goldsv0.8.2. (GOOS=linux GOARCH=amd64)
Golds is a Go 101 project developed by Tapir Liu.
PR and bug reports are welcome and can be submitted to the issue list.
Please follow @zigo_101 (reachable from the left QR code) to get the latest news of Golds.