tenancy

package module
v1.1.2 Latest Latest
Warning

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

Go to latest
Published: Jan 11, 2022 License: MIT Imports: 3 Imported by: 0

README

tenancy

A Go library for multitenancy in Postgres using Row Level Security (RLS).

Usage

Tenancy as a connection pool.

By default, tenancy.Open() begins a connection pool which will open a new database connection for each database operation. The purpose of this pool is to support concurrent API layers such as GraphQL where a single request may be served by concurrent database operations.

For uses that do not require concurrent database connections per request, a single connection can be opened with either BeginTx() or Conn() When the request has finished being served, tenancy.Close() should be called which will close any open connections.

Tenancy without a connection pool

To use tenancy with a single connection for all queries rather than a Pool you can use the singleconnection configuration option

    tc, ctx, err := tenancy.Open(ctx, tenanted.DB.DB, "a4fab457-9fb3-4486-a2c3-22e767668506", tenancy.WithSingleConnection())

Tenancy as middleware

auth middleware -> tenancy.Open() -> request handlers -> tenancy.Close()

tenancy for background tasks

for each tenant -> tenancy.Open() -> process requiring tenanted database connection, you will likely use Conn() to get a single connection for the whole process -> tenancy.Close()

Interfaces

The tenancy package provides some interfaces which you can use in your applications where you want to enforce a tenanted database connection. The TContextExecutor interface satisfies the requirements of ORM libraries such as SQLBoiler which was the basis for creating this package.

Acknowledgements

tenancy was created by Joshua Wilkes and is maintained by Common Fate.

Documentation

Index

Constants

This section is empty.

Variables

View Source
var ErrNoTenantSet = errors.New("tenant id not set in context")

Functions

func Close

func Close(ctx context.Context, p *Pool) error

Close unsets the current tenant before returning the connections

func GetID

func GetID(ctx context.Context) string

GetID finds the tenant ID from the context. REQUIRES tenancy.Open() to have run.

Types

type Conn

type Conn struct {
	*sql.Conn
}

Conn implements the TContextExecutor interface

func (*Conn) BeginTx

func (c *Conn) BeginTx(ctx context.Context, opts *sql.TxOptions) (*TTx, error)

func (*Conn) Exec

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

Exec is implemented with background context to satisfy interface

func (*Conn) Query

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

Query is implemented with background context to satisfy interface

func (*Conn) QueryRow

func (c *Conn) QueryRow(query string, args ...interface{}) *sql.Row

QueryRow is implemented with background context to satisfy interface

type Pool

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

Pool manages a connection pool until closed

func FromContext

func FromContext(ctx context.Context) *Pool

FromContext finds the tenanted database connection pool from the context. REQUIRES tenancy.Open() to have run.

func Open

func Open(ctx context.Context, db *sql.DB, tenantID string, opts ...PoolOption) (*Pool, context.Context, error)

Open sets the tenant and returns a database connection scoped to the tenant it returns a new context which contains the tenant ID and the connection

func (*Pool) BeginTx

func (p *Pool) BeginTx(ctx context.Context, opts *sql.TxOptions) (*TTx, error)

checks out a new tenanted connection for this transaction

func (*Pool) Conn

func (p *Pool) Conn(ctx context.Context) (*sql.Conn, error)

Conn will create a new connection and apply the current tenant The opened connection is registered to a pool internally which is closed when tenancy.Close(ctx, Tconn) is called

func (*Pool) Exec

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

Exec is implemented with background context to satisfy interface

func (*Pool) ExecContext

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

Exec is implemented with background context to satisfy interface

func (*Pool) Query

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

Query is implemented with background context to satisfy interface

func (*Pool) QueryContext

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

Query is implemented with background context to satisfy interface

func (*Pool) QueryRow

func (p *Pool) QueryRow(query string, args ...interface{}) *sql.Row

QueryRow is implemented with background context to satisfy interface

func (*Pool) QueryRowContext

func (p *Pool) QueryRowContext(ctx context.Context, query string, args ...interface{}) *sql.Row

QueryRow is implemented with background context to satisfy interface

type PoolOption

type PoolOption func(*PoolOptions)

func WithSingleConnection

func WithSingleConnection() PoolOption

configures tenancy to use a single connection rather than a pool

type PoolOptions

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

type TContextExecutor

type TContextExecutor interface {
	TExecutor

	ExecContext(ctx context.Context, query string, args ...interface{}) (sql.Result, error)
	QueryContext(ctx context.Context, query string, args ...interface{}) (*sql.Rows, error)
	QueryRowContext(ctx context.Context, query string, args ...interface{}) *sql.Row
}

TContextExecutor can perform SQL queries with context and is tenant-scoped.

type TExecutor

type TExecutor interface {
	Exec(query string, args ...interface{}) (sql.Result, error)
	Query(query string, args ...interface{}) (*sql.Rows, error)
	QueryRow(query string, args ...interface{}) *sql.Row
	// contains filtered or unexported methods
}

Executor can perform SQL queries and is tenant-scoped.

type TTransactor

type TTransactor interface {
	Commit() error
	Rollback() error

	TExecutor
}

Transactor can commit and rollback, on top of being able to execute queries and is tenant-scoped.

type TTx

type TTx struct {
	*sql.Tx
}

TTx is a tenancy-scoped database transaction. This type is exported so that you can write methods in your application which enforce that a tenancy-scoped transaction must be passed to them.

Directories

Path Synopsis

Jump to

Keyboard shortcuts

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