dbresolver

package module
v0.2.1 Latest Latest
Warning

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

Go to latest
Published: Oct 27, 2023 License: MIT Imports: 9 Imported by: 0

README

dbresolver

dbresolver is sqlx resolver and wrapper for database cluster.

CI Go Reference

Install

go get github.com/proost/dbresolver

Usage

package main

import (
	"context"
	"fmt"
	"log"
	
	"github.com/jmoiron/sqlx"
	"github.com/proost/dbresolver"
)

func main() {
    var (
        primaryHost       = "localhost"
        primaryPort       = 3306
        primaryUser       = "primary"
        primaryPassword   = "<password>"
        secondaryHost     = "localhost"
        secondaryPort     = 3307
        secondaryUser     = "secondary"
        secondaryPassword = "<password>"
        dbname            = "<dbname>"
    )
    // DSNs
    primaryDSN := fmt.Sprintf(
        "%s:%s@tcp(%s:%d)/%s",
        primaryUser,
        primaryPassword,
        primaryHost,
        primaryPort,
        dbname,
    )
    secondaryDSN := fmt.Sprintf(
        "%s:%s@tcp(%s:%d)/%s",
        secondaryUser,
        secondaryPassword,
        secondaryHost,
        secondaryPort,
        dbname,
    )

    // connect to primary
    primaryDB := sqlx.MustOpen("mysql", primaryDSN)
    // connect to secondary
    secondaryDB := sqlx.MustOpen("mysql", secondaryDSN)

    primaryDBsCfg := &dbresolver.PrimaryDBsConfig{
      DBs:             []*sqlx.DB{primaryDB},
      ReadWritePolicy: dbresolver.ReadWrite,
    }
    resolver := dbresolver.MustNewDBResolver(primaryDBsCfg, dbresolver.WithSecondaryDBs(secondaryDB))
    defer resolver.Close()

    resolver.MustExecContext(context.Background(), "INSERT INTO users (name) VALUES (?)", "foo")
    result, err := resolver.QueryxContext(context.Background(), `SELECT * FROM users WHERE name = "foo"`)
    if err != nil {
      log.Panic(err)
    }

    fmt.Println(result)
}

Important Notes

  • Primary Database will be used when you call these functions
    • Begin
    • BeginTx
    • BeginTxx
    • Beginx
    • Conn
    • Connx
    • Exec
    • ExecContext
    • MustBegin
    • MustBeginTx
    • MustExec
    • MustExecContext
    • NamedExec
    • NamedExecContext
  • Readable Database(Secondary Database or Primary Database depending on configuration) will be used when you call these functions
    • Get
    • GetContext
    • NamedQuery
    • NamedQueryContext
    • Query
    • QueryContext
    • QueryRow
    • QueryRowContext
    • QueryRowx
    • QueryRowxContext
    • Select
    • SelectContext

Contribution

To contribute to this project, you can open a PR or an issue.

Documentation

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

This section is empty.

Types

type DBResolver

type DBResolver interface {
	Begin() (*sql.Tx, error)
	BeginTx(ctx context.Context, opts *sql.TxOptions) (*sql.Tx, error)
	BeginTxx(ctx context.Context, opts *sql.TxOptions) (*sqlx.Tx, error)
	Beginx() (*sqlx.Tx, error)
	BindNamed(query string, arg interface{}) (string, []interface{}, error)
	Close() error
	Conn(ctx context.Context) (*sql.Conn, error)
	Connx(ctx context.Context) (*sqlx.Conn, error)
	Driver() driver.Driver
	DriverName() string
	Exec(query string, args ...interface{}) (sql.Result, error)
	ExecContext(ctx context.Context, query string, args ...interface{}) (sql.Result, error)
	Get(dest interface{}, query string, args ...interface{}) error
	GetContext(ctx context.Context, dest interface{}, query string, args ...interface{}) error
	MapperFunc(mf func(string) string)
	MustBegin() *sqlx.Tx
	MustBeginTx(ctx context.Context, opts *sql.TxOptions) *sqlx.Tx
	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)
	Ping() error
	PingContext(ctx context.Context) error
	Prepare(query string) (Stmt, error)
	PrepareContext(ctx context.Context, query string) (Stmt, error)
	PrepareNamed(query string) (NamedStmt, error)
	PrepareNamedContext(ctx context.Context, query string) (NamedStmt, error)
	Preparex(query string) (Stmt, error)
	PreparexContext(ctx context.Context, query string) (Stmt, error)
	Query(query string, args ...interface{}) (*sql.Rows, error)
	QueryContext(ctx context.Context, query string, args ...interface{}) (*sql.Rows, error)
	QueryRow(query string, args ...interface{}) *sql.Row
	QueryRowContext(ctx context.Context, query string, args ...interface{}) *sql.Row
	QueryRowx(query string, args ...interface{}) *sqlx.Row
	QueryRowxContext(ctx context.Context, query string, args ...interface{}) *sqlx.Row
	Queryx(query string, args ...interface{}) (*sqlx.Rows, error)
	QueryxContext(ctx context.Context, query string, args ...interface{}) (*sqlx.Rows, error)
	Rebind(query string) string
	Select(dest interface{}, query string, args ...interface{}) error
	SelectContext(ctx context.Context, dest interface{}, query string, args ...interface{}) error
	SetConnMaxIdleTime(d time.Duration)
	SetConnMaxLifetime(d time.Duration)
	SetMaxIdleConns(n int)
	SetMaxOpenConns(n int)
	Stats() sql.DBStats
	Unsafe() *sqlx.DB
}

DBResolver chooses one of databases and then executes a query. This supposed to be aligned with sqlx.DB. Some functions which must select from multiple database are only available for the primary DBResolver or the first primary DBResolver (if using multi-primary). For example, `DriverName()`, `Unsafe()`.

func MustNewDBResolver

func MustNewDBResolver(primaryDBsCfg *PrimaryDBsConfig, opts ...OptionFunc) DBResolver

func NewDBResolver

func NewDBResolver(primaryDBsCfg *PrimaryDBsConfig, opts ...OptionFunc) (DBResolver, error)

NewDBResolver creates a new DBResolver and returns it. If no primary DBResolver is given, it returns an error. If you do not give WriteOnly option, it will use the primary DBResolver as the read DBResolver. if you do not give LoadBalancer option, it will use the RandomLoadBalancer.

type LoadBalancer

type LoadBalancer interface {
	// Select returns the database to use for the given operation.
	Select(ctx context.Context, dbs []*sqlx.DB) *sqlx.DB
}

LoadBalancer chooses a database from the given databases.

type NamedStmt

type NamedStmt interface {
	Close() error
	Exec(arg interface{}) (sql.Result, error)
	ExecContext(ctx context.Context, arg interface{}) (sql.Result, error)
	Get(dest interface{}, arg interface{}) error
	GetContext(ctx context.Context, dest interface{}, arg interface{}) error
	MustExec(arg interface{}) sql.Result
	MustExecContext(ctx context.Context, arg interface{}) sql.Result
	Query(arg interface{}) (*sql.Rows, error)
	QueryContext(ctx context.Context, arg interface{}) (*sql.Rows, error)
	QueryRow(arg interface{}) *sqlx.Row
	QueryRowContext(ctx context.Context, arg interface{}) *sqlx.Row
	QueryRowx(arg interface{}) *sqlx.Row
	QueryRowxContext(ctx context.Context, arg interface{}) *sqlx.Row
	Queryx(arg interface{}) (*sqlx.Rows, error)
	QueryxContext(ctx context.Context, arg interface{}) (*sqlx.Rows, error)
	Select(dest interface{}, arg interface{}) error
	SelectContext(ctx context.Context, dest interface{}, arg interface{}) error
	Unsafe() *sqlx.NamedStmt
}

NamedStmt is a wrapper around sqlx.NamedStmt.

type OptionFunc

type OptionFunc func(*Options)

OptionFunc is a function that configures a Options.

func WithLoadBalancer

func WithLoadBalancer(loadBalancer LoadBalancer) OptionFunc

WithLoadBalancer sets the load balancer.

func WithSecondaryDBs

func WithSecondaryDBs(dbs ...*sqlx.DB) OptionFunc

WithSecondaryDBs sets the secondary databases.

type Options

type Options struct {
	SecondaryDBs []*sqlx.DB
	LoadBalancer LoadBalancer
}

Options is the config for dbResolver.

type PrimaryDBsConfig

type PrimaryDBsConfig struct {
	DBs             []*sqlx.DB
	ReadWritePolicy ReadWritePolicy
}

PrimaryDBsConfig is the config of primary databases.

func NewPrimaryDBsConfig

func NewPrimaryDBsConfig(dbs []*sqlx.DB, policy ReadWritePolicy) *PrimaryDBsConfig

NewPrimaryDBsConfig creates a new PrimaryDBsConfig and returns it.

type RandomLoadBalancer

type RandomLoadBalancer struct{}

RandomLoadBalancer is a load balancer that chooses a database randomly.

func NewRandomLoadBalancer

func NewRandomLoadBalancer() *RandomLoadBalancer

func (*RandomLoadBalancer) Select

func (b *RandomLoadBalancer) Select(_ context.Context, dbs []*sqlx.DB) *sqlx.DB

Select returns the database to use for the given operation. If there are no databases, it returns nil. but it should not happen.

type ReadWritePolicy

type ReadWritePolicy string

ReadWritePolicy is the read/write policy for the primary databases.

const (
	ReadWrite ReadWritePolicy = "read-write"
	WriteOnly ReadWritePolicy = "write-only"
)

ReadWritePolicies.

type Stmt

type Stmt interface {
	Close() error
	Exec(args ...interface{}) (sql.Result, error)
	ExecContext(ctx context.Context, args ...interface{}) (sql.Result, error)
	Get(dest interface{}, args ...interface{}) error
	GetContext(ctx context.Context, dest interface{}, args ...interface{}) error
	MustExec(args ...interface{}) sql.Result
	MustExecContext(ctx context.Context, args ...interface{}) sql.Result
	Query(args ...interface{}) (*sql.Rows, error)
	QueryContext(ctx context.Context, args ...interface{}) (*sql.Rows, error)
	QueryRow(args ...interface{}) *sql.Row
	QueryRowContext(ctx context.Context, args ...interface{}) *sql.Row
	QueryRowx(args ...interface{}) *sqlx.Row
	QueryRowxContext(ctx context.Context, args ...interface{}) *sqlx.Row
	Queryx(args ...interface{}) (*sqlx.Rows, error)
	QueryxContext(ctx context.Context, args ...interface{}) (*sqlx.Rows, error)
	Select(dest interface{}, args ...interface{}) error
	SelectContext(ctx context.Context, dest interface{}, args ...interface{}) error
	Unsafe() *sqlx.Stmt
}

Stmt is a wrapper around sqlx.Stmt.

Jump to

Keyboard shortcuts

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