dbm

package module
v1.0.2 Latest Latest
Warning

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

Go to latest
Published: Jun 25, 2026 License: MIT Imports: 14 Imported by: 0

README

dbm

Simple Database Connection Manager for GORM

Go Version Go Reference Coverage CI

dbm is a lightweight connection manager that wraps GORM, giving you multi-database support, auto-migration, data seeding, and lifecycle hooks, all with a clean, minimal API.


Features

  • Multi-Database: register and manage multiple named connections
  • Auto-Migrate: run schema migrations automatically on connect
  • Seeding: seed data using functions or interfaces
  • Hooks: lifecycle callbacks when connections are created
  • Connection Pooling: configure max open/idle connections, lifetime, etc.
  • DSN Parsing: parse connection URIs into config structs
  • Driver Registry: easily add new database drivers
  • Pluggable Drivers: MySQL, PostgreSQL, SQLite, SQL Server, ClickHouse, TiDB, CockroachDB available as opt-in subpackages
  • Tree-Shakeable Imports: import only the drivers you need (driver/sqlite, driver/all, ...)

Supported Databases

Driver dbm Subpackage GORM Driver Package
MySQL github.com/morkid/dbm/driver/mysql gorm.io/driver/mysql
TiDB github.com/morkid/dbm/driver/tidb gorm.io/driver/mysql (MySQL-compatible wire protocol)
Postgres github.com/morkid/dbm/driver/postgres gorm.io/driver/postgres
CockroachDB github.com/morkid/dbm/driver/cockroach gorm.io/driver/postgres (PostgreSQL-compatible wire protocol)
SQLite github.com/morkid/dbm/driver/sqlite github.com/glebarez/sqlite (pure Go, no CGO)
SQL Server github.com/morkid/dbm/driver/mssql (registers as Type sqlserver) gorm.io/driver/sqlserver
ClickHouse github.com/morkid/dbm/driver/clickhouse gorm.io/driver/clickhouse

Drivers live in per-driver subpackages under github.com/morkid/dbm/driver/<name>/ and auto-register themselves via init(). Use either:

  • import _ "github.com/morkid/dbm/driver/all": pull in every supported driver
  • import _ "github.com/morkid/dbm/driver/<name>": import only what you need (smaller binary)

Note: dbm is a deliberately driver-agnostic core. Without importing at least one driver subpackage, no Config{Type: "..."} value will resolve at Connect() time.

Adding a new driver is as simple as creating a driver/<name>/ subpackage that calls RegisterDriver (see Adding a Custom Driver).

Installation

go get github.com/morkid/dbm

Each database driver is a separate opt-in subpackage, pick one of these:

# Import one specific driver
go get github.com/morkid/dbm/driver/sqlite

# ... or import every supported driver at once
go get github.com/morkid/dbm/driver/all

Available driver subpackages: driver/mysql, driver/postgres, driver/sqlite, driver/mssql, driver/clickhouse, driver/tidb, driver/cockroach, driver/all.

Quick Start

package main

import (
    "gorm.io/gorm"
    "github.com/morkid/dbm"

    // Pick the driver(s) you need. Use `driver/all` instead of
    // `driver/sqlite` here to enable every supported database.
    _ "github.com/morkid/dbm/driver/sqlite"
)

type User struct {
    gorm.Model
    Name string
}

func main() {
    mgr := dbm.New()

    // Register a connection with auto-migration
    mgr.Register("default", dbm.Config{
        AutoMigrate:    true,
        MigrationItems: []any{&User{}},
    })

    // Connect (migration runs automatically)
    mgr.Connect("default")

    // Get the connection
    db := mgr.GetDefault()
    db.Create(&User{Name: "Alice"})
}

Usage

Register & Connect
mgr := dbm.New()

mgr.Register("users", dbm.Config{
    Type:           "postgres",
    Host:           "localhost",
    Port:           "5432",
    User:           "postgres",
    Pass:           "secret",
    Name:           "usersdb",
    AutoMigrate:    true,
    MigrationItems: []any{&User{}, &Account{}},
})

mgr.Register("cache", dbm.Config{
    Type: "sqlite",
    Name: "/tmp/cache.db",
})

// Connect on demand
mgr.Connect("users")
mgr.Connect("cache")

// Or connect immediately during registration
mgr.Register("logs", dbm.Config{Type: "sqlite"}, true)
Get Connection
// Get the default connection (panics if not set)
db := mgr.GetDefault()
db.Find(&users)

// Get a named connection (returns error if not found)
db, err := mgr.Get("users")
if err != nil {
    log.Fatal(err)
}
db.Where("active = ?", true).Find(&activeUsers)

// Set a different default
mgr.SetDefault("users")
DSN Parsing
conf := &dbm.Config{}
conf.FromDSN("mysql://user:pass@localhost:3306/mydb?charset=utf8mb4&parseTime=True&loc=Local")
Auto-Migration & Seeding
mgr.Register("app", dbm.Config{
    AutoMigrate:    true,
    MigrationItems: []any{&User{}, &Post{}},
    MigrationSeeds: []any{
        &User{Name: "admin"},                    // raw model
        dbm.Seed(func(tx *gorm.DB) error {       // seed function
            return tx.Create(&User{Name: "seed"}).Error
        }),
        &MySeeder{},                             // seeder interface
    },
})
Lifecycle Hooks
dbm.OnConnectionCreated(func(name string, db *gorm.DB) {
    log.Printf("connected: %s", name)
})
Connection Pooling
mgr.Register("db", dbm.Config{
    MaxOpenConns: 25,
    MaxIdleConns: 10,
    MaxIdleTime:  300, // seconds
    MaxLifeTime:  3600, // seconds
})

Configuration

"Supported Drivers" column:

  • all means the field is applied universally to every driver through connection_manager.go (gorm.Config / connection pool / migration hooks).
  • Driver-specific lists (e.g. mysql, postgres) name the driver subpackage (e.g. driver/mysql/driver.go) that consumes the field in its own BuildDSN / Open.
  • The driver name (mysql, postgres, cockroach, tidb, sqlite, sqlserver, clickhouse) is the Config.Type value, it is the key the driver self-registers under inside dbm's registry, not the subpackage directory name (sqlserver is registered by the driver/mssql subpackage).

Fields not consumed by the active driver are silently ignored or, for SQL Server SSLMode, intentionally dropped to avoid producing invalid DSN.

Field Type Default Description Supported Drivers
Type string "sqlite" Database driver type all
Host string driver-specific Host address all
Port string driver-specific Port number all
User string driver-specific Username all
Pass string driver-specific Password all
Name string ":memory:" (sqlite) Database name / path all
SSLMode string "" SSL mode (MySQL:tls; Postgres/CockroachDB: sslmode; MSSQL: also drives encrypt DSN, "disable" -> encrypt=disabled, "require" -> encrypt=true, "skip-verify" -> encrypt=true + trustservercertificate=true, unknown values are ignored; value is lowercased and whitespace-trimmed) mysql, postgres, cockroach, sqlserver
PreferSimpleProtocol bool false Prefer simple protocol (Postgres/CockroachDB:extra=prefer_simple_protocol:true decoded in Open, applied via postgres.New(cfg)) postgres, cockroach
ConnectTimeout int 0 Postgres/CockroachDB connect timeout (sec suffix) postgres, cockroach
WithoutQuotingCheck bool false Skip identifier quoting (Postgres/CockroachDB:extra=without_quoting_check:true decoded in Open, applied via postgres.New(cfg)) postgres, cockroach
SQLiteCache string "shared" SQLite cache mode (shared/private) sqlite
SQLitePragmas map[string]string nil SQLite PRAGMA settings, applied per connection sqlite
Timezone string driver-specific Timezone mysql, postgres, cockroach
TablePrefix string "" Table name prefix all
SingularTableDisabled bool false Disable singular table names all
NamingStrategy schema.Namer nil Fully custom NamingStrategy (overrides TablePrefix + SingularTableDisabled) all
ExtraParams string "" Extra query parameters (merged into DSN, driver-level set keys take precedence) all
Charset string "utf8mb4" Connection charset (MySQL/TiDB:charset DSN parameter; defaults to utf8mb4 when empty) mysql, tidb
Collation string "" MySQL/TiDB connection collation mysql, tidb
DialTimeout int 0 MySQL/TiDB connect timeout (sec suffix) mysql, tidb
ReadTimeout int 0 MySQL/TiDB read timeout (sec suffix) mysql, tidb
WriteTimeout int 0 MySQL/TiDB write timeout (sec suffix) mysql, tidb
SkipVersionCheck bool false Skip version probe (MySQL/TiDB:extra=skip_version_check:true decoded in Open, applied via mysql.New(cfg)). Particularly useful for TiDB to avoid MySQL-specific version queries. mysql, tidb
ClickHouseTableEngine string "" Default table engine for AutoMigrate (clickhouse.Config.DefaultTableEngineOpts). Encoded asextra=table_engine:VALUE (U+001F-separated extras). clickhouse
ClickHouseCompression string "" Default compression for new tables (LZ4, ZSTD, None). Encoded asextra=default_compression:VALUE. clickhouse
ClickHouseGranularity int 0 (driver default) Default index granularity. 0 = unset. Encoded asextra=default_granularity:N. clickhouse
SkipInitVersion bool false Skip version probe (clickhouse.Config.SkipInitializeWithVersion). Encoded asextra=skip_init_version:true. clickhouse
ClickHouseDtPrecisionDisabled bool false Disable datetime precision for AutoMigrate. Encoded asextra=disable_datetime_precision:true. clickhouse
InterpolateParams bool false go-sql-driver client-side interp mysql, tidb
MultiStatements bool false Multi-statement queries (MySQL/TiDB) mysql, tidb
MaxAllowedPacket int 0 MySQL/TiDB packet override (bytes) mysql, tidb
WithReturningDisabled bool false Disable RETURNING clause (Postgres/CockroachDB + MySQL/TiDB; encoded asextra=without_returning:true / extra=disable_with_returning:true and reapplied via <driver>.New(cfg)) mysql, tidb, postgres, cockroach
LogLevel string "warn" Log verbosity: silent, error, warn, info all
Logger logger.Interface nil Custom GORM logger (overrides LogLevel) all
LogSlowThreshold int 200 Slow query threshold in ms all
LogColorful bool auto (stderr) Enable colored log output all
LogNotFound bool false Log record-not-found errors all
Plugins []gorm.Plugin nil GORM plugins registered on Connect() all
PrepareStmt bool false Enable prepared statement caching all
PrepareStmtMaxSize int 0 (unlimited) Prepared statement cache size limit all
PrepareStmtTTL int 0 (no expiry) Prepared statement TTL (seconds, clamped to 0 if negative) all
CreateBatchSize int 0 (unlimited) Default batch size for Create() all
DryRun bool false Generate SQL without executing all
SkipDefaultTransaction bool false Disable GORM's default transaction all
TranslateError bool false Translate driver errors to GORM all
NowFunc func() time.Time nil Override "now" function for tests all
AutoPingDisabled bool false Disable GORM's automatic ping all
AllowGlobalUpdate bool false Allow UPDATE/DELETE without WHERE all
QueryFields bool false Always prefix SELECT columns all
KeepFKConstraints bool false Opt-in to FK generation during AutoMigrate all
AppName string "" App name reported to server (Postgres/CockroachDB:application_name, MSSQL: app name). When empty, falls back to the connection ConnName. postgres, cockroach, sqlserver
SSFailoverPartner string "" MSSQL database mirroring failover partner (DSNfailoverPartner=host[:port]). Empty = no failover. sqlserver
SSFailoverPort string "" Failover partner port; combined with SSFailoverPartner intofailoverPartner=host:port. sqlserver
SSWorkstation string "" Workstation identifier (DSNworkstation id=...); empty falls back to Config.ConnName. sqlserver
SSReadOnlyIntent bool false Route connection to a readable secondary (DSNapplicationintent=readonly). sqlserver
SSPacketSize int 0 (driver default) TDS packet size in bytes (DSNpacket size=N). 0 leaves driver default (4096). sqlserver
SSRetryDisabled bool false RESERVED for future use. go-mssqldb 1.7.2 has no retry-related DSN parameter or struct field, so this field has no current effect on the connection path. Included so callers can opt-in once the upstream driver adds support. sqlserver
SSDialTimeout int 0 MSSQL dial timeout in seconds (DSNdial timeout=Ns). sqlserver
SSConnTimeout int 0 MSSQL login / connection timeout in seconds (DSNconnection timeout=Ns). sqlserver
SSKeepAlive int 0 MSSQL keepalive interval in seconds (DSNkeepalive=Ns). sqlserver
DefaultStringSize int 0 (driver default) Default string length used by AutoMigrate for string columns without an explicit size. Encoded asextra=default_string_size:N in DSN, parsed in Open, applied via <driver>.New(cfg) for mysql/tidb (mysql.Config.DefaultStringSize) and sqlserver (sqlserver.Config.DefaultStringSize). mysql, tidb, sqlserver
AutoMigrate bool false Run auto-migration on connect all
MigrationItems []any nil Models to migrate all
MigrationSeeds []any nil Seed data (model / Seed / Seeder) all
MaxOpenConns int 2 Max open connections all
MaxIdleConns int 1 Max idle connections all
MaxIdleTime int 300 Max idle time (seconds) all
MaxLifeTime int 3600 Max connection lifetime (seconds) all

Adding a Custom Driver

If the engine you need isn't covered by a built-in driver/<name> subpackage (or you just want to point dbm at your own gorm.Dialector), you can plug it in from anywhere inside your application, no PRs upstream, no fork. The recipe is: write a small package that calls dbm.RegisterDriver once in an init() function, then make sure your binary imports that package.

A custom driver is the right call when:

  • The engine has its own gorm.io/driver/<x> and you just want a thin dbm wrapper around it.
  • You're prototyping an in-memory or test backend (mock, sqlmock, a gRPC-backed fake, ...).
  • You're shipping a private engine inside your own module and don't need to upstream it.
The ConnectionBuilder contract

A ConnectionBuilder is the one struct you fill in. Three fields:

type ConnectionBuilder struct {
    BuildDSN      func(config dbm.Config) string   // Config -> DSN string
    Open          func(dsn string) gorm.Dialector // DSN -> gorm.Dialector
    DefaultConfig dbm.Config                      // fallbacks for zero-valued Config
}
  • BuildDSN receives a fully-resolved dbm.Config (driver defaults already applied) and returns the DSN string your GORM driver expects.
  • Open receives that DSN and returns the gorm.Dialector that GORM dials with.
  • DefaultConfig provides fallback values for unset Config fields, typically Host, Port, User, Pass, Name, Timezone, and the connection-pool sizing fields.
Step-by-step example

Below is a self-contained snippet that registers a brand-new mycustom dialect and immediately puts it to use. The function does two things, in order. First it calls dbm.RegisterDriver("mycustom", dbm.ConnectionBuilder{...}), which tells dbm how to turn a dbm.Config into a DSN string (BuildDSN) and which gorm.Dialector to open it with (Open). Then it creates a connection manager with dbm.New() and routes the new dialect into the manager via mgr.Register("default", dbm.Config{Type: "mycustom", ...}). Once RegisterDriver has run, mgr.Connect("default") and mgr.Get("default") flow exactly as they would for any built-in driver, the dialect behaves like one from dbm's own driver/<name> family, just declared inline.

package mycustom

import (
    "fmt"
    "strings"
    "github.com/morkid/dbm"
    "github.com/glebarez/sqlite"
    "gorm.io/gorm"
)

func main() {
    dbm.RegisterDriver("mycustom", dbm.ConnectionBuilder{
        BuildDSN: func(c dbm.Config) string {
            return strings.Trim(c.Name + "?" + c.ExtraParams, "?")
        },
        Open: sqlite.Open,
        DefaultConfig: dbm.Config{
            ConnName:     "mycustom",
            Name:         ":memory:",
        },
    })

    mgr := dbm.New()
    mgr.Register("default", dbm.Config{
        Type: "mycustom",
        Name: "/data/foo.db",
    })
}
Contributing a new built-in driver

To upstream a new driver into this repository, see CONTRIBUTING.md.

License

MIT

Documentation

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func OnConnectionCreated

func OnConnectionCreated(callback ConnectionCallback)

OnConnectionCreated registers a callback function that is called when a connection is created

func RegisterDriver

func RegisterDriver(dialect string, builder ConnectionBuilder)

RegisterDriver registers a database driver

Types

type Config

type Config struct {
	// ConnName is a unique identifier for this connection (e.g., "default", "replica").
	ConnName string `json:"conn_name,omitempty" example:"main"`

	// Type selects the database driver. Supported: "mysql", "postgres",
	// "sqlite", "sqlserver", "clickhouse".
	Type string `json:"type,omitempty" example:"mysql"`

	// Host is the database server hostname or IP address.
	Host string `json:"host,omitempty" example:"localhost"`

	// Port is the database server port (e.g., "3306" for MySQL).
	Port string `json:"port,omitempty" example:"3306"`

	// Name is the database name (or file path for SQLite).
	Name string `json:"name,omitempty" example:"test"`

	// User is the authentication username.
	User string `json:"user,omitempty" example:"root"`

	// Pass is the authentication password.
	Pass string `json:"pass,omitempty" example:"password"`

	// LogLevel controls GORM's log verbosity. Values: "silent", "error", "warn", "info".
	// Empty string defaults to "warn".
	LogLevel string `json:"log_level,omitempty" example:"warn"`

	// Logger sets a custom GORM logger. When set, LogLevel and LogSlowThreshold are ignored.
	Logger logger.Interface `json:"-"`

	// LogSlowThreshold is the slow query threshold in milliseconds. 0 means use default (200ms).
	LogSlowThreshold int `json:"log_slow_threshold,omitempty" example:"200"`

	// LogColorful enables colored GORM log output. Zero value means auto-detect based on stderr.
	LogColorful bool `json:"log_colorful,omitempty" example:"true"`

	// LogNotFound enables logging of "record not found" errors.
	LogNotFound bool `json:"log_not_found,omitempty" example:"true"`

	// Plugins registers GORM plugins (e.g., opentelemetry, prometheus).
	// Registered via dbConn.Use() on each Connect().
	Plugins []gorm.Plugin `json:"-"`

	// PrepareStmt enables prepared statement caching in GORM.
	PrepareStmt bool `json:"prepare_stmt,omitempty" example:"true"`

	// PrepareStmtMaxSize limits the prepared statement cache size. 0 means unlimited.
	PrepareStmtMaxSize int `json:"prepare_stmt_max_size,omitempty" example:"100"`

	// PrepareStmtTTL is the prepared statement TTL in seconds. 0 means no expiry.
	PrepareStmtTTL int `json:"prepare_stmt_ttl,omitempty" example:"300"`

	// Charset sets the connection charset (primarily for MySQL).
	Charset string `json:"charset,omitempty" example:"utf8mb4"`

	// Collation sets the MySQL connection collation (e.g. "utf8mb4_unicode_ci").
	// Appended as the `collation` DSN parameter.
	Collation string `json:"collation,omitempty" example:"utf8mb4_unicode_ci"`

	// DialTimeout is the MySQL connect timeout in seconds. Appended as
	// `connect_timeout=Ns` to the DSN. 0 leaves it unset.
	DialTimeout int `json:"dial_timeout,omitempty" example:"5"`

	// ReadTimeout is the MySQL read timeout in seconds. Appended as
	// `readTimeout=Ns` to the DSN. 0 leaves it unset.
	ReadTimeout int `json:"read_timeout,omitempty" example:"30"`

	// WriteTimeout is the MySQL write timeout in seconds. Appended as
	// `writeTimeout=Ns` to the DSN. 0 leaves it unset.
	WriteTimeout int `json:"write_timeout,omitempty" example:"10"`

	// SkipVersionCheck skips the default version probe performed by the
	// MySQL driver on first connect (mysql.Config.SkipInitializeWithVersion).
	// Encoded into the DSN as extra=skip_version_check:true and reapplied via
	// mysql.New(cfg) inside driver_mysql.go -- no driver.go modification needed.
	SkipVersionCheck bool `json:"skip_version_check,omitempty" example:"true"`

	// InterpolateParams enables client-side parameter interpolation in the
	// go-sql-driver. Appended as `interpolateParams=true` to the DSN.
	InterpolateParams bool `json:"interpolate_params,omitempty" example:"true"`

	// MultiStatements enables running multiple statements in a single query
	// (e.g. inside a migration script). Appended as `multiStatements=true`.
	// Security note: opt-in only; can allow SQL injection in multi-statement contexts.
	MultiStatements bool `json:"multi_statements,omitempty" example:"true"`

	// MaxAllowedPacket overrides the go-sql-driver default maximum packet size
	// (in bytes). Appended as `maxAllowedPacket=N` to the DSN. 0 leaves it unset.
	MaxAllowedPacket int `json:"max_allowed_packet,omitempty" example:"67108864"`

	// WithReturningDisabled requests the RETURNING clause to be disabled
	// for INSERT/UPDATE. For MySQL, applied via mysql.Config.DisableWithReturning
	// (an effective no-op semantically since MySQL doesn't use RETURNING by
	// default, but the flag is honored for parity). For Postgres, applied
	// via postgres.Config.WithoutReturning (PgBouncer compatibility).
	// Both are encoded as extra=without_returning:true in the DSN and
	// reapplied via <driver>.New(cfg) inside driver_<name>.go.
	WithReturningDisabled bool `json:"with_returning_disabled,omitempty" example:"true"`

	// SQLiteCache sets SQLite's cache mode. Values: "shared" (multiple
	// connections share a single in-memory cache), "private" (each connection
	// has its own cache). Empty string (the zero value) defaults to "shared"
	// to preserve historical behavior. Appended as the `cache=...` DSN parameter.
	SQLiteCache string `json:"sqlite_cache,omitempty" example:"private"`

	// SQLitePragmas applies PRAGMA settings to every new SQLite connection
	// via the modernc.org/sqlite inline pragma syntax (`_pragma=key(value)`
	// appended once per entry). Useful for tuning: `journal_mode=WAL`,
	// `busy_timeout=5000`, `foreign_keys=on`, `synchronous=NORMAL`, etc.
	SQLitePragmas map[string]string `json:"sqlite_pragmas,omitempty"`

	// ClickHouseTableEngine sets the default table engine for AutoMigrate
	// when creating tables without an explicit engine (clickhouse.Config.
	// DefaultTableEngineOpts). Encoded into the DSN as `extra=table_engine:...`
	// and reapplied via clickhouse.New(cfg) inside driver_clickhouse.go -- no
	// driver.go modification needed.
	ClickHouseTableEngine string `` /* 139-byte string literal not displayed */

	// ClickHouseCompression sets the default compression for new tables
	// during AutoMigrate (clickhouse.Config.DefaultCompression). Values:
	// "LZ4" (default, lossless), "ZSTD" (better ratio), "None" (no compression).
	// Encoded into the DSN as `extra=default_compression:<value>` and
	// reapplied via clickhouse.New(cfg).
	ClickHouseCompression string `json:"clickhouse_compression,omitempty" example:"ZSTD"`

	// ClickHouseGranularity sets the default index granularity (1 granule
	// = 8192 rows by default). Encoded into the DSN as
	// `extra=default_granularity:N` and reapplied via clickhouse.New(cfg).
	ClickHouseGranularity int `json:"clickhouse_granularity,omitempty" example:"3"`

	// SkipInitVersion skips the version probe performed by gorm.io/driver/clickhouse
	// (clickhouse.Config.SkipInitializeWithVersion). Encoded into the DSN as
	// `extra=skip_init_version:true` and reapplied via clickhouse.New(cfg).
	SkipInitVersion bool `json:"skip_init_version,omitempty" example:"true"`

	// ClickHouseDtPrecisionDisabled disables datetime precision at column
	// level for AutoMigrate (clickhouse.Config.DisableDatetimePrecision).
	// Encoded into the DSN as `extra=disable_datetime_precision:true` and
	// reapplied via clickhouse.New(cfg).
	ClickHouseDtPrecisionDisabled bool `json:"clickhouse_dt_precision_disabled,omitempty" example:"true"`

	// CreateBatchSize sets the default batch size for Create(). 0 means unlimited (GORM default).
	CreateBatchSize int `json:"create_batch_size,omitempty" example:"1000"`

	// DryRun generates SQL statements without executing them. Useful for debugging
	// or inspecting generated queries before running them against a real database.
	DryRun bool `json:"dry_run,omitempty" example:"true"`

	// SkipDefaultTransaction disables GORM's default transaction wrapping for
	// create/update/delete operations. Improves throughput when callers manage
	// their own transactions.
	SkipDefaultTransaction bool `json:"skip_default_transaction,omitempty" example:"true"`

	// TranslateError translates database driver errors into well-known GORM
	// errors (e.g., gorm.ErrDuplicatedKey) when possible.
	TranslateError bool `json:"translate_error,omitempty" example:"true"`

	// NowFunc overrides the function used by GORM to obtain the current time
	// (e.g., for "created_at" / "updated_at" defaults). Useful for deterministic tests.
	NowFunc func() time.Time `json:"-"`

	// AutoPingDisabled disables GORM's automatic ping on connection setup.
	AutoPingDisabled bool `json:"auto_ping_disabled,omitempty" example:"true"`

	// AllowGlobalUpdate permits UPDATE/DELETE without a WHERE clause
	// (e.g., `db.Model(&User{}).Update("name", "x")`). Use with care.
	AllowGlobalUpdate bool `json:"allow_global_update,omitempty" example:"true"`

	// QueryFields forces SELECT statements to use fully qualified column names
	// (e.g., `SELECT users.name FROM users` instead of `SELECT name FROM users`).
	QueryFields bool `json:"query_fields,omitempty" example:"true"`

	// KeepFKConstraints controls FK generation during AutoMigrate.
	// With KeepFKConstraints=true, FK constraints are generated during
	// migration. The mapping is inverted so that the zero value (false/default)
	// preserves the historical default (FK constraints are NOT generated).
	// Set KeepFKConstraints=true to opt-in to FK generation.
	KeepFKConstraints bool `json:"keep_fk_constraints,omitempty" example:"true"`

	// SingularTableDisabled disables singular table names (e.g., "users" instead of "user").
	// Default is false, meaning singular table names are enabled (current behavior).
	SingularTableDisabled bool `json:"singular_table_disabled,omitempty" example:"true"`

	// NamingStrategy sets a fully custom naming strategy. When non-nil,
	// SingularTableDisabled and TablePrefix are ignored.
	NamingStrategy schema.Namer `json:"-"`

	// TablePrefix is a prefix prepended to all table names.
	TablePrefix string `json:"table_prefix,omitempty" example:""`

	// AppName is the application name reported to the database server
	// (Postgres: application_name, SQL Server: app name).
	// When empty, falls back to the connection ConnName.
	AppName string `json:"app_name,omitempty" example:"order-service"`

	// Timezone sets the session timezone (e.g., "UTC", "Local").
	Timezone string `json:"timezone,omitempty" example:"UTC"`

	// SSLMode controls TLS/SSL. Values: "disable", "require",
	// "skip-verify", "preferred" (driver-dependent).
	SSLMode string `json:"ssl_mode,omitempty" example:"disable"`

	// PreferSimpleProtocol prefers the simple query protocol over the
	// extended one. Useful when connecting through PgBouncer in transaction
	// pooling mode (postgres.Config.PreferSimpleProtocol).
	// Encoded into the DSN as extra=prefer_simple_protocol:true and
	// reapplied via postgres.New(cfg) inside driver_postgres.go.
	PreferSimpleProtocol bool `json:"prefer_simple_protocol,omitempty" example:"true"`

	// ConnectTimeout is the Postgres connect timeout in seconds. Appended
	// as `connect_timeout=Ns` to the DSN. 0 leaves it unset (driver default).
	ConnectTimeout int `json:"connect_timeout,omitempty" example:"10"`

	// WithoutQuotingCheck disables identifier quoting checks performed by
	// the Postgres driver (postgres.Config.WithoutQuotingCheck).
	// Use with caution -- misquoted identifiers can corrupt queries.
	// Encoded into the DSN as extra=without_quoting_check:true and
	// reapplied via postgres.New(cfg) inside driver_postgres.go.
	WithoutQuotingCheck bool `json:"without_quoting_check,omitempty" example:"true"`

	// SSFailoverPartner is the database mirroring failover partner hostname.
	// Appended as `failoverPartner=host[:port]` to the MSSQL DSN. When
	// SSFailoverPort is set, the value combines into `host:port`.
	SSFailoverPartner string `json:"ss_failover_partner,omitempty" example:"secondary.example.com"`

	// SSFailoverPort is the failover partner port. Combined with
	// SSFailoverPartner to form the `failoverPartner` DSN parameter.
	SSFailoverPort string `json:"ss_failover_port,omitempty" example:"1433"`

	// SSWorkstation sets the workstation identifier reported to the server.
	// Appended as `workstation id=...` to the MSSQL DSN. Empty falls back to c.ConnName.
	SSWorkstation string `json:"ss_workstation,omitempty" example:"workstation-01"`

	// SSReadOnlyIntent routes the connection to a readable secondary.
	// Appended as `applicationintent=readonly` to the MSSQL DSN.
	SSReadOnlyIntent bool `json:"ss_read_only_intent,omitempty" example:"true"`

	// SSPacketSize is the TDS packet size in bytes (driver default 4096).
	// Appended as `packet size=N` to the MSSQL DSN. 0 leaves it unset.
	SSPacketSize int `json:"ss_packet_size,omitempty" example:"4096"`

	// SSRetryDisabled is RESERVED for future use. go-mssqldb 1.7.2 does NOT
	// expose any retry-related DSN parameter or sqlserver.Config field for
	// connection retry behavior, so setting this field has no current effect
	// on the open path. The field is included so callers can opt-in once the
	// upstream driver adds support; the BuildDSN/Open path is unchanged today.
	SSRetryDisabled bool `json:"ss_retry_disabled,omitempty" example:"true"`

	// SSDialTimeout is the MSSQL dial timeout in seconds. Appended as
	// `dial timeout=Ns` to the MSSQL DSN. 0 leaves it unset (driver default).
	SSDialTimeout int `json:"ss_dial_timeout,omitempty" example:"5"`

	// SSConnTimeout is the MSSQL login / connection timeout in seconds.
	// Appended as `connection timeout=Ns` to the MSSQL DSN. 0 leaves it unset.
	SSConnTimeout int `json:"ss_conn_timeout,omitempty" example:"30"`

	// SSKeepAlive is the MSSQL keepalive interval in seconds. Appended as
	// `keepalive=Ns` to the MSSQL DSN. 0 leaves it unset.
	SSKeepAlive int `json:"ss_keep_alive,omitempty" example:"30"`

	// DefaultStringSize sets the default string length used by AutoMigrate
	// for string columns that don't have an explicit size (sqlserver.Config.
	// DefaultStringSize and mysql.Config.DefaultStringSize). Encoded into the
	// DSN as `extra=default_string_size:N` and reapplied via <driver>.New(cfg)
	// inside driver_<name>.go -- no driver.go modification needed.
	DefaultStringSize int `json:"default_string_size,omitempty" example:"191"`

	// MaxOpenConns limits the maximum number of open connections.
	MaxOpenConns int `json:"max_open_conns,omitempty" example:"10"`

	// MaxIdleConns limits the maximum number of idle connections.
	MaxIdleConns int `json:"max_idle_conns,omitempty" example:"5"`

	// MaxIdleTime is the maximum idle time in seconds before a connection is closed.
	MaxIdleTime int `json:"max_idle_time,omitempty" example:"300"`

	// MaxLifeTime is the maximum lifetime in seconds for a connection.
	MaxLifeTime int `json:"max_life_time,omitempty" example:"3600"`

	// ExtraParams holds additional DSN query parameters not covered by other fields.
	ExtraParams string `json:"extra_params,omitempty" example:""`

	// AutoMigrate enables automatic schema migration on Connect().
	AutoMigrate bool `json:"auto_migrate,omitempty" example:"true"`

	// MigrationItems lists model structs to auto-migrate.
	MigrationItems []any `json:"-"`

	// MigrationSeeds lists seed data (raw models, Seed funcs, or Seeder interfaces).
	MigrationSeeds []any `json:"-"`
}

Config holds database connection configuration.

func (*Config) FromDSN

func (c *Config) FromDSN(dsn string) error

FromDSN parses a DSN string and populates the Config struct It returns an error if the DSN is invalid

type Connection

type Connection interface {
	// Register registers a database connection under the given name using
	// the provided config. The first registered connection is automatically
	// promoted to the default. When autoConnect is true, Register also
	// opens the connection immediately; otherwise the underlying handle is
	// opened lazily on the first call to Connect or Migrate. A second
	// Register with a name that is already known is a no-op.
	Register(name string, config Config, autoConnect ...bool) error

	// Get returns the GORM handle currently associated with the given
	// name. It returns an error when no connection has been registered
	// under that name.
	Get(name string) (*gorm.DB, error)

	// Connect opens the underlying database for the registered name and
	// returns its GORM handle. When override is false, the freshly opened
	// handle is used transiently and does not replace the stored
	// connection (used internally by Migrate); when override is true, or
	// when override is omitted entirely, the opened handle replaces the
	// one stored under the name.
	Connect(name string, override ...bool) (*gorm.DB, error)

	// Migrate runs gorm.AutoMigrate over the connection's MigrationItems
	// and applies the configured MigrationSeeds inside a single
	// transaction per seed. It opens a transient connection via
	// Connect(name, false) that is closed once migration completes.
	Migrate(name string) error

	// GetDefault returns the GORM handle for the connection currently
	// designated as default. It panics if no default has been set or if
	// the registered default name cannot be resolved.
	GetDefault() *gorm.DB

	// SetDefault designates the named connection as the one returned by
	// GetDefault. The named connection itself must already be registered.
	SetDefault(name string)
}

Connection is an interface for database connections

func New

func New() Connection

New creates a new connection manager It returns a pointer to a connectionManager struct

type ConnectionBuilder

type ConnectionBuilder struct {
	BuildDSN      func(config Config) string
	Open          func(dsn string) gorm.Dialector
	DefaultConfig Config
}

ConnectionBuilder is a builder for database connections

func GetDriver

func GetDriver(dialect string) (ConnectionBuilder, bool)

GetDriver returns a registered driver by dialect name

type ConnectionCallback

type ConnectionCallback func(name string, db *gorm.DB)

ConnectionCallback is a callback function that is called when a connection is created

type Seed

type Seed func(db *gorm.DB) error

Seed is a function that seeds the database It receives a gorm database instance and returns an error if the seeding fails

type Seeder

type Seeder interface {
	Seed(db *gorm.DB) error
}

Seeder is an interface for seeding the database It has a Seed method that receives a gorm database instance and returns an error if the seeding fails

Directories

Path Synopsis
driver
all
Package all bundles every built-in driver shipped in this repository behind a single side-effect import.
Package all bundles every built-in driver shipped in this repository behind a single side-effect import.

Jump to

Keyboard shortcuts

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