rwdb

package module
v0.0.0-...-0d10fac Latest Latest
Warning

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

Go to latest
Published: Nov 8, 2017 License: MIT Imports: 7 Imported by: 0

README

rwdb

Build Status GoDoc Coverage Status Go Report Card

Database wrapper that manage read write connections

Install

go get github.com/andizzle/rwdb

Create connections

package main

import "github.com/andizzle/rwdb"

var conns = []string{
        "tcp://user:pass@write/dbname",
        "tcp://user:pass@read1/dbname",
        "tcp://user:pass@read2/dbname",
        "tcp://user:pass@read3/dbname",
}


// unable to open write will cause an error
db, err := rwdb.Open("driver", conns...)

Rotation read and Sticky read

Query a database rotate the use of database connections

Basic usage
db, err := rwdb.Open("driver", conns...)

// Use the first connection
db.QueryContext(ctx)

// Use the next connection
db.QueryContext(ctx)

Execute a statement will cause all subsequent queries to use the write connection (sticky connection). This is to allow the immediate reading of records that have been written to the database during the current request cycle.

db, err := rwdb.Open("driver", conns...)

// Use the next connection
db.QueryContext(ctx)

// Use the write conenction
db.ExecContext(ctx)

// Use the write connection
db.Query()

Sticky can be turned off

db.SetSticky(false)
A more practical example

The db is marked as modified if there's a successful Write to the databse, which turns on the sticky logic. However, the real world usecase would require modified value to be reset on each request session.

Here's what we can do:

db, err := rwdb.Open("driver", conns...)

func RecordUserLogin() {
        d := db.New()       // This will make sure the following read are not affected by 
                            // other sessions' write action

        d.Query("SELECT * from `users` where id = ?")
        ...
        d.Exec("UPDATE `users` set last_login_at = now();")
        d.Query(...)        // Connection is set to the writer
}

License

License

Documentation

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

This section is empty.

Types

type CPool

type CPool struct {
	// contains filtered or unexported fields
}

CPool holds the master and slave connection pools

func (*CPool) AddReader

func (c *CPool) AddReader(db *sql.DB)

AddReader append a db connection to the pool

func (*CPool) AddWriter

func (c *CPool) AddWriter(db *sql.DB)

AddWriter prepend a db connection to the pool Previous writer automatically become a reader

func (*CPool) Reader

func (c *CPool) Reader() (*sql.DB, error)

Reader gets the reader connection next in line

func (*CPool) Writer

func (c *CPool) Writer() (*sql.DB, error)

Writer gets the writer connection

type DB

type DB struct {
	// contains filtered or unexported fields
}

DB holds connection pool(s) This should be created once, and for each acquaring of new db pool, use New()

func Open

func Open(driver string, dataSourceNames ...string) (*DB, error)

Open creates the DB instance The opening of each underline connection is non-blocking

func (*DB) Begin

func (db *DB) Begin() (*sql.Tx, error)

Begin starts a transaction on Writer It's likely the subsequent queries will perform a write

func (*DB) Close

func (db *DB) Close() error

Close closes all physical db connections

func (*DB) Driver

func (db *DB) Driver() driver.Driver

Driver returns the driver of the DB The Writer's driver represents all readers

func (*DB) Exec

func (db *DB) Exec(query string, args ...interface{}) (sql.Result, error)

Exec writes to Writer and mark db as modified

func (*DB) ExecContext

func (db *DB) ExecContext(ctx context.Context, query string, args ...interface{}) (sql.Result, error)

ExecContext execute a query with context and mark the db as modified

func (*DB) New

func (db *DB) New() *DB

New creates a new DB with the same sticky and Connection pool, but reset modified

func (*DB) Ping

func (db *DB) Ping() error

Ping execute a ping context with a background context

func (*DB) PingContext

func (db *DB) PingContext(ctx context.Context) error

PingContext pings all physical dbs with context

func (*DB) Prepare

func (db *DB) Prepare(query string) (Stmt, error)

Prepare prepare stateuments with a background context

func (*DB) PrepareContext

func (db *DB) PrepareContext(ctx context.Context, query string) (Stmt, error)

PrepareContext two statements, one in Writer one in Reader The statement will be executed in the writer and queries in reader

func (*DB) Query

func (db *DB) Query(query string, args ...interface{}) (*sql.Rows, error)

Query perform a query context with background context

func (*DB) QueryContext

func (db *DB) QueryContext(ctx context.Context, query string, args ...interface{}) (*sql.Rows, error)

QueryContext executes a query that returns rows, typically a SELECT. The args are for any placeholder parameters in the query. The query will be performed in the next connection

func (*DB) QueryRow

func (db *DB) QueryRow(query string, args ...interface{}) Row

QueryRow runs the QueryRowContext with a background context

func (*DB) QueryRowContext

func (db *DB) QueryRowContext(ctx context.Context, query string, args ...interface{}) Row

QueryRowContext perform the underline QueryRowContext of sql.DB on the next connection

func (*DB) SetConnMaxLifetime

func (db *DB) SetConnMaxLifetime(d time.Duration)

SetConnMaxLifetime sets the maximum amount of time a connection may be reused for all connections. This is concurrency safe.

func (*DB) SetMaxIdleConns

func (db *DB) SetMaxIdleConns(n int)

SetMaxIdleConns sets the max idel conns for all connections. This is concurrency safe.

func (*DB) SetMaxOpenConns

func (db *DB) SetMaxOpenConns(n int)

SetMaxOpenConns sets the max open connections limit for all connections. This is concurrency safe.

func (*DB) SetSticky

func (db *DB) SetSticky(stick bool)

SetSticky allows sticky be turned on and off

type Row

type Row interface {
	Scan(dest ...interface{}) error
}

Row allow us to write our custom row struct

type Stmt

type Stmt interface {
	Close() error
	Exec(args ...interface{}) (sql.Result, error)
	ExecContext(ctx context.Context, args ...interface{}) (sql.Result, error)
	Query(args ...interface{}) (*sql.Rows, error)
	QueryContext(ctx context.Context, args ...interface{}) (*sql.Rows, error)
	QueryRow(args ...interface{}) Row
	QueryRowContext(ctx context.Context, args ...interface{}) Row
}

Stmt allows DB

Jump to

Keyboard shortcuts

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