Documentation
¶
Overview ¶
Package migro is a Lucid/Knex-inspired toolkit on top of GORM: a schema builder, a query builder, a generic model layer and a migration runner.
Register the dialects you need with a blank import:
import _ "github.com/LouisRiverstone/migro/dialect/postgres"
Index ¶
- Variables
- func Sticky(ctx context.Context) context.Context
- type Code
- type Config
- type Conn
- type DB
- func (d *DB) Close() error
- func (d *DB) DisableQueryLog()
- func (d *DB) EnableQueryLog()
- func (d *DB) FlushQueryLog()
- func (d *DB) Listen(fn func(QueryEvent)) (off func())
- func (d *DB) Name() string
- func (d *DB) Ping(ctx context.Context) error
- func (d *DB) QueryLog() []QueryEvent
- func (d *DB) SetStrict(s Strict)
- func (d *DB) ShouldBeStrict(on bool)
- func (d *DB) Strictness() Strict
- func (d *DB) Transaction(ctx context.Context, fn func(tx *DB) error) error
- func (d *DB) WithGorm(g *gorm.DB) *DB
- func (d *DB) WriteDB() *DB
- type Error
- type Manager
- type Pool
- type QueryEvent
- type Strict
Constants ¶
This section is empty.
Variables ¶
var ( ErrNotFound = &Error{Code: NotFound, Message: "record not found"} ErrMigrationLocked = &Error{Code: MigrationLocked} ErrUnsupportedFeature = &Error{Code: UnsupportedFeature} ErrPoolAcquireTimeout = &Error{Code: PoolAcquireTimeout} ErrEventAborted = &Error{Code: EventAborted} )
Sentinels for errors.Is.
Functions ¶
func Sticky ¶
Sticky returns a context that sends reads to the primary once a write has run with it (Laravel's "sticky" connection option). Use one per request or job: reads that come before the first write still go to a replica, reads after it see the data just written.
It only matters with Config.Replicas. Pass the returned context to every call of the unit of work.
Types ¶
type Code ¶
type Code string
Code is a stable, machine-readable error identifier.
const ( UnsupportedDialect Code = "UNSUPPORTED_DIALECT" ConnectionFailed Code = "CONNECTION_FAILED" NotFound Code = "NOT_FOUND" MigrationLocked Code = "MIGRATION_LOCKED" MigrationFailed Code = "MIGRATION_FAILED" ChecksumMismatch Code = "MIGRATION_CHECKSUM_MISMATCH" InvalidSchema Code = "INVALID_SCHEMA" UnsupportedFeature Code = "UNSUPPORTED_FEATURE" QueryFailed Code = "QUERY_FAILED" InvalidConfig Code = "INVALID_CONFIG" PoolAcquireTimeout Code = "POOL_ACQUIRE_TIMEOUT" EventAborted Code = "EVENT_ABORTED" EventHandlerFailed Code = "EVENT_HANDLER_FAILED" SeedFailed Code = "SEED_FAILED" DiffFailed Code = "DIFF_FAILED" ShardNotFound Code = "SHARD_NOT_FOUND" ShardFailed Code = "SHARD_FAILED" UnknownMorphType Code = "UNKNOWN_MORPH_TYPE" ProductionBlocked Code = "PRODUCTION_BLOCKED" MassAssignment Code = "MASS_ASSIGNMENT" UnboundModel Code = "UNBOUND_MODEL" RelationNotLoaded Code = "RELATION_NOT_LOADED" CastFailed Code = "CAST_FAILED" LazyLoadingViolation Code = "LAZY_LOADING_VIOLATION" MultipleRecords Code = "MULTIPLE_RECORDS_FOUND" ConnectionNotFound Code = "CONNECTION_NOT_FOUND" PruneFailed Code = "PRUNE_FAILED" )
type Config ¶
type Config struct {
// Dialect name: postgres, cockroachdb, redshift, mysql, mariadb, sqlite, sqlserver, oracle.
Dialect string
DSN string
// Gorm is optional; nil uses GORM defaults with a silent logger.
Gorm *gorm.Config
// Pool configures the connection pool (Knex-style).
Pool Pool
// Replicas are read-only DSNs of the same dialect. Reads go to a replica, writes and
// transactions to the primary. Replication lag can make a read right after a write stale;
// use DB.WriteDB() to force the primary, or migro.Sticky(ctx) to do it after the first write of a request.
Replicas []string
// ReplicaPolicy is "random" (default) or "round-robin".
ReplicaPolicy string
// Deprecated: use Pool.Max.
MaxOpenConns int
// Deprecated: caps idle connections; use Pool.Min to keep connections warm.
MaxIdleConns int
// Deprecated: use Pool.MaxLifetime.
ConnMaxLifetime time.Duration
}
Config configures Open.
type DB ¶
DB bundles a *gorm.DB with the dialect it was opened for.
func OpenContext ¶
OpenContext is Open with a context bounding connection setup.
func (*DB) DisableQueryLog ¶
func (d *DB) DisableQueryLog()
DisableQueryLog stops recording; the recorded statements are kept until FlushQueryLog.
func (*DB) EnableQueryLog ¶
func (d *DB) EnableQueryLog()
EnableQueryLog starts recording statements (Laravel's DB::enableQueryLog).
func (*DB) FlushQueryLog ¶
func (d *DB) FlushQueryLog()
FlushQueryLog discards the recorded statements.
func (*DB) Listen ¶
func (d *DB) Listen(fn func(QueryEvent)) (off func())
Listen calls fn after every statement the database runs (Laravel's DB::listen). The returned function unsubscribes. fn runs on the goroutine that ran the statement and must not block.
func (*DB) Name ¶
Name is the name the database was registered under in a Manager, or "" for a standalone one.
func (*DB) QueryLog ¶
func (d *DB) QueryLog() []QueryEvent
QueryLog returns a copy of the recorded statements.
func (*DB) SetStrict ¶
SetStrict replaces the strictness settings. Transactions and WriteDB handles share them.
func (*DB) ShouldBeStrict ¶
ShouldBeStrict switches every strictness check on or off.
func (*DB) Transaction ¶
Transaction runs fn in a transaction; a non-nil error rolls back. fn receives a *DB bound to the transaction, usable with schema, query, orm and migrate.
type Error ¶
Error is the single error type returned across migro boundaries. Match with errors.Is(err, migro.ErrNotFound) or errors.As.
type Manager ¶
type Manager struct {
// contains filtered or unexported fields
}
Manager holds named database connections and opens each one the first time it is asked for (Laravel's DB::connection). Use cluster.Cluster instead to route by key across shards.
func NewManager ¶
NewManager registers connections by name; def is the one Default and Connection("") return. Nothing connects until a connection is first used.
func (*Manager) Connection ¶
Connection returns the named database, opening it on first use. An empty name means the default.
type Pool ¶
type Pool struct {
// Max open connections (Knex pool.max). 0 = unlimited.
Max int
// Min connections kept warm (Knex pool.min). Best effort: connections are opened at Open
// and kept idle, but database/sql may still close them after IdleTimeout or MaxLifetime.
Min int
// AcquireTimeout bounds the wait for a free connection (Knex acquireConnectionTimeout).
// Exceeding it returns POOL_ACQUIRE_TIMEOUT. 0 = wait until the context ends.
AcquireTimeout time.Duration
// IdleTimeout closes connections idle longer than this (Knex idleTimeoutMillis).
IdleTimeout time.Duration
// MaxLifetime recycles connections older than this.
MaxLifetime time.Duration
// Validate pings a pooled connection on checkout and discards it when the ping fails
// (Knex pool.validate). Only effective for drivers implementing driver.Pinger.
Validate bool
// AfterCreate runs once for every new physical connection (Knex pool.afterCreate),
// e.g. SET TIME ZONE or PRAGMA statements. An error discards the connection.
AfterCreate func(ctx context.Context, conn Conn) error
// contains filtered or unexported fields
}
Pool mirrors Knex's pool options on top of database/sql.
type QueryEvent ¶
QueryEvent describes one executed statement.
type Strict ¶
type Strict struct {
// LazyLoading makes a relation's Get fail with LAZY_LOADING_VIOLATION when the relation was not
// eager loaded (Eloquent's preventLazyLoading). Models that are not persisted yet are exempt.
LazyLoading bool
// OnLazyLoad, when set, is called instead of failing. Use it to log the violation in production
// while still failing in development (Eloquent's handleLazyLoadingViolationUsing).
OnLazyLoad func(model, relation string)
}
Strict turns silent mistakes into errors. It is off by default, so enabling it is opt-in per database (Eloquent's Model::shouldBeStrict()).
Mass assignment and unknown columns are always strict in migro: Fill fails with MASS_ASSIGNMENT and GetAttribute fails with INVALID_SCHEMA, so the only switch that remains is lazy loading.
Directories
¶
| Path | Synopsis |
|---|---|
|
Package cluster routes work across several independent databases (application-level sharding).
|
Package cluster routes work across several independent databases (application-level sharding). |
|
cmd
|
|
|
migro
command
Command migro is the artisan/ace-style CLI.
|
Command migro is the artisan/ace-style CLI. |
|
Package console is the artisan/ace-style command line: migration:run, migration:rollback --step=N, make:migration, db:seed and friends.
|
Package console is the artisan/ace-style command line: migration:run, migration:rollback --step=N, make:migration, db:seed and friends. |
|
Package dbtest has test helpers for code that uses migro: database assertions, a database that rolls back when the test ends, and a query counter (Laravel's assertDatabaseHas, RefreshDatabase and assertQueryCount).
|
Package dbtest has test helpers for code that uses migro: database assertions, a database that rolls back when the test ends, and a query counter (Laravel's assertDatabaseHas, RefreshDatabase and assertQueryCount). |
|
Package dialect defines the per-database adapter contract and a registry.
|
Package dialect defines the per-database adapter contract and a registry. |
|
mysql
Package mysql registers MySQL and MariaDB.
|
Package mysql registers MySQL and MariaDB. |
|
oracle
Package oracle registers Oracle Database using the pure-Go go-ora driver (no cgo).
|
Package oracle registers Oracle Database using the pure-Go go-ora driver (no cgo). |
|
postgres
Package postgres registers PostgreSQL, CockroachDB and Redshift.
|
Package postgres registers PostgreSQL, CockroachDB and Redshift. |
|
sqlite
Package sqlite registers SQLite using the pure-Go (no cgo) glebarez driver.
|
Package sqlite registers SQLite using the pure-Go (no cgo) glebarez driver. |
|
sqlserver
Package sqlserver registers Microsoft SQL Server.
|
Package sqlserver registers Microsoft SQL Server. |
|
Package events is a Lucid-style in-process event emitter plus model lifecycle events.
|
Package events is a Lucid-style in-process event emitter plus model lifecycle events. |
|
integration
|
|
|
database/factories
Package factories holds model factories (Laravel's database/factories, Lucid's factories).
|
Package factories holds model factories (Laravel's database/factories, Lucid's factories). |
|
database/migrations
Package migrations holds one Laravel-style migration class per file, named <yyyymmddhhmmss>_<snake_case>.go and registered from init().
|
Package migrations holds one Laravel-style migration class per file, named <yyyymmddhhmmss>_<snake_case>.go and registered from init(). |
|
database/seeders
Package seeders holds Laravel-style seeder classes, registered from init().
|
Package seeders holds Laravel-style seeder classes, registered from init(). |
|
models
Package models holds the integration database's models, written the way an application would: BaseModel for the instance API, relations declared as typed fields.
|
Package models holds the integration database's models, written the way an application would: BaseModel for the instance API, relations declared as typed fields. |
|
internal
|
|
|
testdb
Package testdb opens the database used by tests.
|
Package testdb opens the database used by tests. |
|
Package migrate runs versioned schema migrations in batches, Knex-style.
|
Package migrate runs versioned schema migrations in batches, Knex-style. |
|
diff
Package diff compares GORM models with a live database and writes the difference as migration files (the same .up.sql / .down.sql format migrate.FromFS reads).
|
Package diff compares GORM models with a live database and writes the difference as migration files (the same .up.sql / .down.sql format migrate.FromFS reads). |
|
Package orm is a Lucid-style model layer: a generic repository over GORM models.
|
Package orm is a Lucid-style model layer: a generic repository over GORM models. |
|
Package query is a Knex-style fluent query builder for tables without a model.
|
Package query is a Knex-style fluent query builder for tables without a model. |
|
Package schema is a Knex-style DDL builder compiled per dialect.
|
Package schema is a Knex-style DDL builder compiled per dialect. |
|
Package seed provides Lucid-style factories and seeders.
|
Package seed provides Lucid-style factories and seeders. |