sqalx

package module
v0.2.2 Latest Latest
Warning

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

Go to latest
Published: Mar 6, 2019 License: MIT Imports: 6 Imported by: 0

README

sqalx

GoDoc Go Report Card

sqalx (pronounced 'scale-x') is a library built on top of sqlx that allows to seamlessly create nested transactions and to avoid thinking about whether or not a function is called within a transaction. With sqalx you can easily create reusable and composable functions that can be called within or out of transactions and that can create transactions themselves.

Getting started

$ go get github.com/heetch/sqalx
Import sqlax
import "github.com/heetch/sqalx"
Usage
package main

import (
	"log"

	"github.com/heetch/sqalx"
	"github.com/jmoiron/sqlx"
	_ "github.com/lib/pq"
)

func main() {
	// Connect to PostgreSQL with sqlx.
	db, err := sqlx.Connect("postgres", "user=foo dbname=bar sslmode=disable")
	if err != nil {
		log.Fatal(err)
	}

	defer db.Close()

	// Pass the db to sqalx.
	// It returns a sqalx.Node. A Node is a wrapper around sqlx.DB or sqlx.Tx.
	node, err := sqalx.New(db)
	if err != nil {
		log.Fatal(err)
	}

	err = createUser(node)
	if err != nil {
		log.Fatal(err)
	}
}

func createUser(node sqalx.Node) error {
	// Exec a query
	_, _ = node.Exec("INSERT INTO ....") // you can use a node as if it were a *sqlx.DB or a *sqlx.Tx

	// Let's create a transaction.
	// A transaction is also a sqalx.Node.
	tx, err := node.Beginx()
	if err != nil {
		return err
	}
	defer tx.Rollback()

	_, _ = tx.Exec("UPDATE ...")

	// Now we call another function and pass it the transaction.
	err = updateGroups(tx)
	if err != nil {
		return nil
	}

	return tx.Commit()
}

func updateGroups(node sqlax.Node) error {
	// Notice we are creating a new transaction.
	// This would normally cause a dead lock without sqalx.
	tx, err := node.Beginx()
	if err != nil {
		return err
	}
	defer tx.Rollback()

	_, _ = tx.Exec("INSERT ...")
	_, _ = tx.Exec("UPDATE ...")
	_, _ = tx.Exec("DELETE ...")

	return tx.Commit()
}
PostgreSQL Savepoints

When using the PostgreSQL driver, an option can be passed to New to enable the use of PostgreSQL Savepoints for nested transactions.

node, err := sqalx.New(db, sqalx.SavePoint(true))

Issue

Please open an issue if you encounter any problem.

License

The library is released under the MIT license. See LICENSE file.

Documentation

Index

Constants

This section is empty.

Variables

View Source
var (
	// ErrNotInTransaction is returned when using Commit
	// outside of a transaction.
	ErrNotInTransaction = errors.New("not in transaction")

	// ErrIncompatibleOption is returned when using an option incompatible
	// with the selected driver.
	ErrIncompatibleOption = errors.New("incompatible option")
)

Functions

This section is empty.

Types

type Driver

type Driver interface {
	sqlx.Execer
	sqlx.ExecerContext
	sqlx.Queryer
	sqlx.QueryerContext
	sqlx.Preparer
	sqlx.PreparerContext
	BindNamed(query string, arg interface{}) (string, []interface{}, error)
	DriverName() string
	Get(dest interface{}, query string, args ...interface{}) error
	GetContext(ctx context.Context, dest interface{}, query string, args ...interface{}) error
	MustExec(query string, args ...interface{}) sql.Result
	MustExecContext(ctx context.Context, query string, args ...interface{}) sql.Result
	NamedExec(query string, arg interface{}) (sql.Result, error)
	NamedExecContext(ctx context.Context, query string, arg interface{}) (sql.Result, error)
	NamedQuery(query string, arg interface{}) (*sqlx.Rows, error)
	NamedQueryContext(ctx context.Context, query string, arg interface{}) (*sqlx.Rows, error)
	PrepareNamed(query string) (*sqlx.NamedStmt, error)
	PrepareNamedContext(ctx context.Context, query string) (*sqlx.NamedStmt, error)
	Preparex(query string) (*sqlx.Stmt, error)
	PreparexContext(ctx context.Context, query string) (*sqlx.Stmt, error)
	Rebind(query string) string
	Select(dest interface{}, query string, args ...interface{}) error
	SelectContext(ctx context.Context, dest interface{}, query string, args ...interface{}) error
}

A Driver can query the database. It can either be a *sqlx.DB or a *sqlx.Tx and therefore is limited to the methods they have in common.

type Node

type Node interface {
	Driver

	// Close the underlying sqlx connection.
	Close() error
	// Begin a new transaction.
	Beginx() (Node, error)
	// Rollback the associated transaction.
	Rollback() error
	// Commit the assiociated transaction.
	Commit() error
	// Tx returns the underlying transaction.
	Tx() *sqlx.Tx
}

A Node is a database driver that can manage nested transactions.

func Connect

func Connect(driverName, dataSourceName string, options ...Option) (Node, error)

Connect to a database.

func New

func New(db *sqlx.DB, options ...Option) (Node, error)

New creates a new Node with the given DB.

func NewFromTransaction

func NewFromTransaction(tx *sqlx.Tx, options ...Option) (Node, error)

NewFromTransaction creates a new Node from the given transaction.

type Option

type Option func(*node) error

Option to configure sqalx

func SavePoint

func SavePoint(enabled bool) Option

SavePoint option enables PostgreSQL Savepoints for nested transactions.

Jump to

Keyboard shortcuts

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