xgorm

package module
v1.1.0 Latest Latest
Warning

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

Go to latest
Published: Nov 4, 2026 License: MIT Imports: 26 Imported by: 0

README

xgorm

A named GORM database registry with explicit pool ownership and bounded startup checks. Supports MySQL, PostgreSQL, SQLite, and SQL Server.

Install

Requires Go 1.27.3 or later. SQLite uses go-sqlite3 and requires CGO and a C compiler.

go get github.com/lazyboon/xgorm

Start a database

package main

import (
    "context"
    "log"

    "github.com/lazyboon/xgorm"
)

func main() {
    config := xgorm.Config{
        Alias: "main",
		Driver: xgorm.DriverSQLite,
		DSN: ":memory:",
        PingTimeout: 5,
		MaxOpenConns: 1,
		MaxIdleConns: 1,
    }
    if err := xgorm.Init(context.Background(), []xgorm.Config{config}); err != nil {
        log.Fatal(err)
    }
    defer xgorm.CloseAll()

    db := xgorm.Get("main")
    var value int
    if err := db.WithContext(context.Background()).Raw("SELECT 1").Scan(&value).Error; err != nil {
        log.Print(err)
    }
}

See the executable ExampleInit for SQLite CRUD and a transaction. Schema creation and migrations belong to the caller; initialization never runs migrations or manages indexes.

Connection settings

Alias, Driver, DSN, PingTimeout, and MaxOpenConns are required. Aliases must be unique and have no surrounding whitespace. Time settings use integer seconds. MaxIdleConns may be zero, must not be negative, and cannot exceed MaxOpenConns. ConnMaxLifetime and ConnMaxIdleTime are non-negative; zero disables recycling.

DSNs use each native driver's format. xgorm does not build DSNs, escape credentials, or add TLS settings:

Driver DSN example
DriverMySQL user:password@tcp(localhost:3306)/example?parseTime=true
DriverPostgres host=localhost user=example dbname=example sslmode=require timezone=UTC
DriverSQLite file:example.db
DriverSQLServer sqlserver://user:password@localhost:1433?database=example

Choose TLS and authentication options for your environment. DSNs can contain secrets; avoid logging them.

Private SQLite memory databases (:memory: or an equivalent file: URI) require MaxOpenConns=1. Every memory database, including file:example?mode=memory&cache=shared, requires at least one idle connection and both recycling limits set to zero. Shared memory URIs allow multiple connections. File databases do not have these memory restrictions.

PostgreSQL DSNs are parsed by pgx, including quoted keyword values and percent-encoded URI values. An explicit timezone also controls GORM timestamp scanning. Legacy TimeZone and time_zone aliases are normalized; conflicting legacy values fail unless canonical timezone is present. Canonical timezone takes precedence. Explicit locations must be loadable by Go's time package.

MySQL initialization retains the GORM driver's version probe and uses its result for dialect behavior. The startup wrapper supplies the startup context to the driver's background-context version query. Driver upgrades that change that probe should be reviewed and tested; prepared statements and transactions still use the original SQL pool.

Lifecycle and ownership

  • Init(ctx, []Config) validates the whole batch, opens pools, initializes GORM, checks connectivity, and publishes the batch atomically. Failure closes pools created by that call and preserves the registry.
  • ctx and each connection's PingTimeout bound context-aware startup work. Driver operations or plugins that ignore context can exceed that deadline. Successful databases do not retain the startup context; use db.WithContext(requestCtx) for runtime work.
  • Get(alias) returns a shared *gorm.DB, or nil when absent. Use WithContext or Session for request settings. Do not mutate the shared root or close its pool directly.
  • Stop database consumers before Close(alias) or CloseAll(). They remove aliases and close owned pools, retaining aliases in errors. CloseAll attempts every close. An absent alias closes successfully.
  • Initialize during application startup. Do not overlap initialization with registry shutdown. The registry is process-wide; libraries sharing a process must coordinate aliases and shutdown.

Config.GORM accepts native GORM settings such as logging, naming, prepared statements, and plugins. It must not supply ConnPool or Dialector. The configuration is copied, including its plugin and clause maps; other referenced values may remain shared and must be safe for their use. Plugins must retain the owned SQL pool and wrappers must expose it through gorm.GetDBConnector. Automatic GORM ping is replaced by the bounded startup check. Debug enables SQL info logging.

Migrating from earlier v1 releases

This update retains the v1 module path but changes APIs:

  • Keep the github.com/lazyboon/xgorm import path and upgrade the Go toolchain.
  • Replace Init([]*Config) with Init(ctx, []Config) and supply explicit driver, pool limits, and positive ping timeout.
  • Replace pointer *uint pool and timeout fields with explicit int values in seconds. Rename MaxOpenConn / MaxIdleConn to MaxOpenConns / MaxIdleConns, and GormConfig to GORM. Update JSON keys to max_open_conns and max_idle_conns. FillDefaults is removed.
  • The former exported Open helper is removed. Use Init and Get; this version has no exported Open(ctx) API.
  • MySQL/PostgreSQL index builders and index managers are removed. Move schema and index migrations into application-managed migrations.
  • Handle errors returned by initialization and shutdown, and coordinate shared registry ownership.

Test

CGO_ENABLED=1 go test -race ./...
go vet ./...

Tests use temporary SQLite databases, fake SQL connections, and local ephemeral listeners. No database service or Docker is needed. Native database behavior beyond these fixtures should also be checked against your supported server versions.

License

MIT.

Documentation

Overview

Package xgorm manages named GORM databases and their connection pools. Initialize databases at startup and stop their consumers before calling CloseAll.

Index

Examples

Constants

This section is empty.

Variables

This section is empty.

Functions

func Close

func Close(alias string) error

Close removes and closes a named database, returning nil if the alias is absent. Stop its consumers first; pool closure cannot stop arbitrary application goroutines.

func CloseAll

func CloseAll() error

CloseAll removes every registered database and attempts to close each pool. Call it after all database consumers have stopped. Errors retain their database aliases.

func Get

func Get(alias string) *gorm.DB

Get returns the shared database for alias, or nil if no database is registered. Use WithContext or Session for request-specific settings; do not mutate or close the shared root.

func Init

func Init(ctx context.Context, configs []Config) error

Init initializes and health-checks a batch of databases before registering it. Failure leaves the registry unchanged and closes pools created by this call. ctx controls context-aware initialization work and is not retained by registered databases. Initialize during startup and do not overlap initialization with registry shutdown.

Example
config := Config{Alias: "example", Driver: DriverSQLite, DSN: ":memory:", PingTimeout: 1, MaxOpenConns: 1, MaxIdleConns: 1}
if err := Init(context.Background(), []Config{config}); err != nil {
	panic(err)
}
defer Close("example")
db := Get("example")
if err := db.AutoMigrate(&exampleRecord{}); err != nil {
	panic(err)
}
if err := db.Transaction(func(tx *gorm.DB) error { return tx.Create(&exampleRecord{Name: "Ada"}).Error }); err != nil {
	panic(err)
}
var record exampleRecord
if err := db.First(&record).Error; err != nil {
	panic(err)
}
fmt.Println(record.Name)
Output:
Ada

Types

type Config

type Config struct {
	// Alias identifies the database in the package registry and must be unique.
	Alias string `json:"alias"`

	// Driver selects the SQL dialect and driver.
	Driver Driver `json:"driver"`

	// DSN is the driver-specific data source name and may contain credentials.
	DSN string `json:"dsn"`

	// Debug enables GORM's info-level SQL logging.
	Debug bool `json:"debug"`

	// GORM supplies fresh ORM settings such as logging, naming, migrations, and plugins.
	// ConnPool and Dialector must be unset; xgorm owns connection creation and shutdown.
	// ClauseBuilders and Plugins maps are copied, but their values and other referenced objects are shared.
	// Shared plugins and callbacks must be safe for their intended concurrent use.
	// Pool wrappers must expose the original SQL pool through GORM's GetDBConnector interface.
	// Automatic GORM Ping is always disabled in favor of the bounded startup check.
	GORM *gorm.Config `json:"-"`

	// PingTimeout bounds context-aware startup checks, including MySQL version detection.
	// Driver operations or plugins that ignore context may not honor this timeout.
	PingTimeout int `json:"ping_timeout"`

	// MaxOpenConns limits the number of open connections and must be positive.
	MaxOpenConns int `json:"max_open_conns"`

	// MaxIdleConns limits retained idle connections; zero retains none.
	MaxIdleConns int `json:"max_idle_conns"`

	// ConnMaxLifetime limits connection reuse by age; zero disables this limit.
	ConnMaxLifetime int `json:"conn_max_lifetime"`

	// ConnMaxIdleTime limits how long a connection may remain idle; zero disables this limit.
	ConnMaxIdleTime int `json:"conn_max_idle_time"`
}

Config defines a named database and its connection pool. Durations are expressed in seconds. Connection limits and PingTimeout are explicit; lifetime and idle-time limits of zero are disabled. Configuration and referenced objects must not be mutated during initialization.

func (Config) Validate

func (c Config) Validate() error

Validate checks driver, connection, and pool settings without opening a connection.

type Driver

type Driver string

Driver identifies a supported GORM database dialect.

const (
	DriverMySQL     Driver = "mysql"
	DriverPostgres  Driver = "postgres"
	DriverSQLite    Driver = "sqlite"
	DriverSQLServer Driver = "sqlserver"
)

Supported SQL drivers.

func (Driver) Validate

func (d Driver) Validate() error

Validate reports whether the driver is supported.

Jump to

Keyboard shortcuts

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