nagaya

package module
v0.1.0 Latest Latest
Warning

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

Go to latest
Published: Dec 25, 2023 License: MIT Imports: 9 Imported by: 0

README

CI PkgGoDev

nagaya

Nagaya provides database multi-tenancy utility for Go web applications.

It is highly inspired by apartment, so you can use nagaya like apartment.

Nagaya is a style of apartments which typical for Edo period in Japan.

Install

go get github.com/aereal/nagaya

Synopsis

import (
  "database/sql"
  "net/http"

  "github.com/aereal/nagaya"
)

func _() {
  var db *sql.DB
  manager := nagaya.NewStd(db)
  yourHandler := http.HandlerFunc(func (w http.ResponseWriter, r *http.Request) {
    // obtain a database connection which bound for the current tenant.
    conn, _ := manager.ObtainConnection(r.Context())
    // run queries against the current tenant.
    _, _ = conn.GetContext(r.Context(), "select * from users")
  })
  // Nagaya middleware sets current tenant to the request context.
  // So you can obtain database connection bound for the current tenant in your HTTP handler via the context.
  mw := nagaya.Middleware(
    manager,
    nagaya.GetTenantFromHeader("tenant-id"), // this option tells the Nagaya uses `tenant-id` request header value as the current tenant
  )
  _ = mw(yourHandler)
}

License

See LICENSE file.

Documentation

Index

Constants

This section is empty.

Variables

View Source
var (
	// ErrNoTenantBound is an error represents no tenant bound for the context.
	ErrNoTenantBound = errors.New("no tenant bound for the context")
	// ErrNoConnectionBound is an error represents no DB connection obtained for the context.
	ErrNoConnectionBound = errors.New("no DB connection bound for the context")
)

Functions

func Middleware

func Middleware[DB DBish, Conn Connish](n *Nagaya[DB, Conn], opts ...MiddlewareOption) func(http.Handler) http.Handler

Middleware returns a middleware function that determines target tenant and obtain the database connection against the tenant.

The consumer must get the obtained connection via Nagaya.ObtainConnection method and use it to access the database.

func WithTenant

func WithTenant(ctx context.Context, tenant Tenant) context.Context

WithTenant returns new context that contains given tenant.

Types

type ChangeTenantError

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

ChangeTenantError is an error type represents the failure of changing current tenant.

func (*ChangeTenantError) Error

func (e *ChangeTenantError) Error() string

func (*ChangeTenantError) Tenant

func (e *ChangeTenantError) Tenant() Tenant

Tenant returns a tenant to be switched.

func (*ChangeTenantError) Unwrap

func (e *ChangeTenantError) Unwrap() error

type Connish

type Connish interface {
	BeginTx(context.Context, *sql.TxOptions) (*sql.Tx, error)
	PingContext(context.Context) error
	ExecContext(context.Context, string, ...any) (sql.Result, error)
	PrepareContext(context.Context, string) (*sql.Stmt, error)
	QueryContext(context.Context, string, ...any) (*sql.Rows, error)
	QueryRowContext(context.Context, string, ...any) *sql.Row
	Close() error
}

type DBish

type DBish interface {
	BeginTx(context.Context, *sql.TxOptions) (*sql.Tx, error)
	PingContext(context.Context) error
	ExecContext(context.Context, string, ...any) (sql.Result, error)
	PrepareContext(context.Context, string) (*sql.Stmt, error)
	QueryContext(context.Context, string, ...any) (*sql.Rows, error)
	QueryRowContext(context.Context, string, ...any) *sql.Row
	Close() error
	Stats() sql.DBStats
	SetConnMaxIdleTime(time.Duration)
	SetConnMaxLifetime(time.Duration)
	SetMaxIdleConns(int)
	SetMaxOpenConns(int)
}

type ErrorHandler

type ErrorHandler func(w http.ResponseWriter, r *http.Request, err error)

type GenerateRequestIDError

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

GenerateRequestIDError is an error type represents the failure of generating ID of the current request.

func (*GenerateRequestIDError) Error

func (e *GenerateRequestIDError) Error() string

func (*GenerateRequestIDError) Unwrap

func (e *GenerateRequestIDError) Unwrap() error

type GetConnFn

type GetConnFn[DB DBish, Conn Connish] func(ctx context.Context, db DB) (Conn, error)

GetConnFn is a function type returns new database connection from the DB.

type MiddlewareOption

type MiddlewareOption func(cfg *middlewareConfig)

MiddlewareOption applies a configuration option value to a middleware.

func GetTenantFromHeader

func GetTenantFromHeader(headerName string) MiddlewareOption

func WithChangeTenantErrorHandler

func WithChangeTenantErrorHandler(handler ErrorHandler) MiddlewareOption

func WithErrorHandler

func WithErrorHandler(handler ErrorHandler) MiddlewareOption

func WithGenerateRequestIDErrorHandler

func WithGenerateRequestIDErrorHandler(handler ErrorHandler) MiddlewareOption

func WithGetTenantFn

func WithGetTenantFn(fn func(r *http.Request) (Tenant, bool)) MiddlewareOption

func WithNoTenantBoundErrorHandler

func WithNoTenantBoundErrorHandler(handler ErrorHandler) MiddlewareOption

func WithObtainConnectionErrorHandler

func WithObtainConnectionErrorHandler(handler ErrorHandler) MiddlewareOption

func WithRequestIDGenerator

func WithRequestIDGenerator(gen RequestIDGenerator) MiddlewareOption

func WithTimeout

func WithTimeout(dur time.Duration) MiddlewareOption

WithTimeout configures the time a middleware waits the change of tenant.

type Nagaya

type Nagaya[DB DBish, Conn Connish] struct {
	// contains filtered or unexported fields
}

func New

func New[DB DBish, Conn Connish](db DB, getConn GetConnFn[DB, Conn]) *Nagaya[DB, Conn]

func NewStd

func NewStd(db *sql.DB) *Nagaya[*sql.DB, *sql.Conn]

func (*Nagaya[DB, Conn]) ObtainConnection

func (n *Nagaya[DB, Conn]) ObtainConnection(ctx context.Context) (conn Conn, err error)

ObtainConnection returns a database connection connected to the current tenant.

type ObtainConnectionError

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

ObtainConnectionError is an error type represents the failure of obtaining DB connection.

func (*ObtainConnectionError) Error

func (e *ObtainConnectionError) Error() string

func (*ObtainConnectionError) Unwrap

func (e *ObtainConnectionError) Unwrap() error

type RequestIDGenerator

type RequestIDGenerator interface {
	GenerateID(ctx context.Context, r *http.Request) (string, error)
}

type RequestIDGeneratorFunc

type RequestIDGeneratorFunc func(ctx context.Context, r *http.Request) (string, error)

func (RequestIDGeneratorFunc) GenerateID

func (f RequestIDGeneratorFunc) GenerateID(ctx context.Context, r *http.Request) (string, error)

type Tenant

type Tenant string

Tenant is an identifier of resource subset stored in the shared database.

func TenantFromContext

func TenantFromContext(ctx context.Context) (Tenant, bool)

TenantFromContext extracts a tenant in the context.

If no tenant is bound for the context, the second return value is a false.

Jump to

Keyboard shortcuts

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