txwrap

package module
v0.1.2 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Apr 17, 2023 License: MIT Imports: 4 Imported by: 3

README

TxWrap

TxWrap implements a transaction wrapper around a *sqlx.Tx transaction that simplifies error handling and is guaranteed to either call Commit or Rollback on all transactions it starts.

TxWrap will automatically handle all database errors when using the TxWrap interface. After an error occurs, all future database calls using the same TxWrap will be short-circuited and fail immediately and the transaction will be rolled back.

Usage:

txErr := WithTx(ctx, db, func(tx *txwrap.TxWrap) error {
    query := `SELECT sessionid FROM sessions WHERE sessionid = ?`
    if !tx.Exists(query, sessionId) {
        query = `INSERT INTO session (sessionid, counter) VALUES (?, 0)`
        tx.Exec(query, sessionId)
    }
    query = `UPDATE session SET counter = counter + 1 WHERE sessionid = ?`
    tx.Exec(query, sessionId)
    return nil
})

Note that no error handling is necessary. If any of the database calls (Exists, Exec) fail the transaction will be automatically rolled back. If the function completes with no errors (and the return value is nil) the transaction will be committed. By returning a non-nil error, you can also force a rollback at any time.

Documentation

Overview

Simple wrapper around sqlx.Tx to provide error handling and automatic commit/rollback

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func DBGWithTx

func DBGWithTx(ctx context.Context, dbWrap DBGetter, fn func(tx *TxWrap) error) (rtnErr error)

Main transaction wrapper. If any database call fails, or an error is returned from 'fn' then the transation will be rolled back and the first error will be returned. Otherwise the transaction will be committed and WithTx will return nil.

Note that WithTx *can* be nested. If there is already an error WithTx will immediately return that error. Otherwise it will use the existing outer TxWrap object. Note that this will *not* run a nested DB transation. Begin and Commit/Rollback will only be called once for the *outer* transaction.

func IsTxWrapContext

func IsTxWrapContext(ctx context.Context) bool

Checks to see if the given Context is running a TxWrap transaction

func WithTx

func WithTx(ctx context.Context, db *sqlx.DB, fn func(tx *TxWrap) error) error

Simple transaction wrapper. If any database call fails, or an error is returned from 'fn' then the transation will be rolled back and the first error will be returned. Otherwise the transaction will be committed and WithTx will return nil.

Calls DBGWithTx with 'db' wrapped in SimpleDBGetter

Types

type DBGetter

type DBGetter interface {
	GetDB(ctx context.Context) (*sqlx.DB, error)
	ReleaseDB(*sqlx.DB)
}

Allows for custom database get/release logic If GetDB returns a DB, ReleaseDB is guaranteed to be called once the transaction has been committed or rolledback.

type SimpleDBGetter

type SimpleDBGetter sqlx.DB

Simple implementation of DBGetter for a sqlx.DB

func (*SimpleDBGetter) GetDB

func (db *SimpleDBGetter) GetDB(ctx context.Context) (*sqlx.DB, error)

func (*SimpleDBGetter) ReleaseDB

func (db *SimpleDBGetter) ReleaseDB(instance *sqlx.DB)

type TxWrap

type TxWrap struct {
	Txx *sqlx.Tx
	Err error
	// contains filtered or unexported fields
}

Main TxWrap data-structure. Wraps the sqlx.Tx interface. Once an error is returned from one of the DB calls, no future calls will run and the transaction will be rolled back.

Notes: * Can get the raw sqlx.Tx or Err directly from the struct * TxWrap is not thread-safe, must be synchronized externally to be used by multiple go-routines * If you use sqlx.Rows, sqlx.Row, or sqlx.Stmt directly you'll have to implement and return your errors manually.

func (*TxWrap) Context

func (tx *TxWrap) Context() context.Context

Returns the TxWrap Context (with the txWrapKey). Must use this Context for nested calls to TxWrap

func (*TxWrap) Exec

func (tx *TxWrap) Exec(query string, args ...interface{}) sql.Result

func (*TxWrap) Exists

func (tx *TxWrap) Exists(query string, args ...interface{}) bool

Returns false if there is an error or the query returns sql.ErrNoRows. Otherwise if there is at least 1 matching row, returns true.

func (*TxWrap) Get

func (tx *TxWrap) Get(dest interface{}, query string, args ...interface{}) bool

If there is an error or sql.ErrNoRows will return false, otherwise true. Note that sql.ErrNoRows will *not* error out the TxWrap.

func (*TxWrap) GetBool

func (tx *TxWrap) GetBool(query string, args ...interface{}) bool

func (*TxWrap) GetInt

func (tx *TxWrap) GetInt(query string, args ...interface{}) int

func (*TxWrap) GetInt64 added in v0.1.1

func (tx *TxWrap) GetInt64(query string, args ...interface{}) int64

func (*TxWrap) GetMap

func (tx *TxWrap) GetMap(query string, args ...interface{}) map[string]interface{}

func (*TxWrap) GetString

func (tx *TxWrap) GetString(query string, args ...interface{}) string

func (*TxWrap) NamedExec

func (tx *TxWrap) NamedExec(query string, arg interface{}) sql.Result

func (*TxWrap) Run

func (tx *TxWrap) Run(fn func() error)

Runs a function iff there has been no error

func (*TxWrap) Select

func (tx *TxWrap) Select(dest interface{}, query string, args ...interface{})

func (*TxWrap) SelectMaps

func (tx *TxWrap) SelectMaps(query string, args ...interface{}) []map[string]interface{}

func (*TxWrap) SelectStrings

func (tx *TxWrap) SelectStrings(query string, args ...interface{}) []string

func (*TxWrap) SetErr added in v0.1.1

func (tx *TxWrap) SetErr(err error)

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL