db

package
v0.4.1 Latest Latest
Warning

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

Go to latest
Published: Dec 24, 2025 License: GPL-3.0 Imports: 11 Imported by: 0

README

Database Configuration

This package provides a flexible configuration system for GORM database connections with support for MySQL and PostgreSQL.

Features

  • Auto-build DSN from individual connection parameters
  • Support for MySQL and PostgreSQL
  • Connection pool configuration
  • Read-write separation with dbresolver
  • Multiple database sources and replicas

Configuration Modes

1. Simple Mode (Single Database)

Use NewSimpleManagerConfig for a single database connection:

primary := db.DBConfig{
    Type:       db.MySQL,
    Host:       "localhost",
    Port:       3306,
    Username:   "root",
    Password:   "secret",
    Database:   "myapp",
    Params:     "charset=utf8mb4&parseTime=True",
    PoolConfig: db.DefaultPoolConfig(),
}

config := db.NewSimpleManagerConfig(primary, nil)
manager, err := db.NewGORMManagerFromConfig(config)
2. Read-Write Split Mode

Use NewReadWriteSplitConfig for read-write separation:

primary := db.DBConfig{
    Type:     db.MySQL,
    Host:     "primary.db.local",
    Database: "myapp",
    Username: "root",
    Password: "secret",
}

// Optional: Additional write databases
sources := []db.DBConfig{
    {
        Type:     db.MySQL,
        Host:     "source1.db.local",
        Database: "myapp",
        Username: "root",
        Password: "secret",
    },
}

// Read-only replicas
replicas := []db.DBConfig{
    {
        Type:     db.MySQL,
        Host:     "replica1.db.local",
        Database: "myapp",
        Username: "readonly",
        Password: "secret",
    },
}

config := db.NewReadWriteSplitConfig(primary, sources, replicas, nil)
manager, err := db.NewGORMManagerFromConfig(config)

DSN Configuration

You have two options for specifying database connections:

Option 1: Explicit DSN

Set the DSN string directly:

config := db.DBConfig{
    Type: db.MySQL,
    DSN:  "root:password@tcp(localhost:3306)/myapp?charset=utf8mb4",
}
Option 2: Auto-build from Parameters

Specify individual connection parameters, and the DSN will be built automatically:

config := db.DBConfig{
    Type:     db.MySQL,
    Host:     "localhost",
    Port:     3306,  // Optional: defaults to 3306 for MySQL, 5432 for PostgreSQL
    Username: "root",
    Password: "password",
    Database: "myapp",
    Params:   "charset=utf8mb4&parseTime=True&loc=Local",  // Optional
}

// DSN is automatically built when GetDSN() is called
dsn := config.GetDSN()
// Result: root:password@tcp(localhost:3306)/myapp?charset=utf8mb4&parseTime=True&loc=Local
MySQL DSN Format

When auto-building, MySQL DSN follows this format:

username:password@tcp(host:port)/database?params
PostgreSQL DSN Format

When auto-building, PostgreSQL DSN follows this format:

host=host port=port user=username password=password dbname=database params

Note: PostgreSQL passwords with special characters are automatically URL-encoded.

Understanding Primary, Sources, and Replicas

The configuration structure supports three types of database connections:

  • Primary: The initial database connection (required)

    • Always the first connection established
    • Handles all operations when Sources and Replicas are empty
  • Sources: Additional write databases (optional)

    • Used for write operations (INSERT, UPDATE, DELETE)
    • When specified, writes are distributed among Sources using the configured policy
    • If empty, Primary handles all writes
  • Replicas: Read-only databases (optional)

    • Used for read operations (SELECT)
    • Reads are distributed among Replicas using the configured policy
    • If empty, reads go to Primary (or Sources if specified)
Common Scenarios

Scenario 1: Single Database

// Primary only - handles all reads and writes
config := db.NewSimpleManagerConfig(primary, nil)

Scenario 2: Read Replicas Only

// Primary handles writes, replicas handle reads
config := db.NewReadWriteSplitConfig(primary, nil, replicas, nil)

Scenario 3: Multiple Write Sources and Read Replicas

// Primary + sources handle writes, replicas handle reads
config := db.NewReadWriteSplitConfig(primary, sources, replicas, nil)

Connection Pool Configuration

Configure connection pooling for each database:

poolConfig := db.PoolConfig{
    ConnMaxIdleTime: 10 * time.Minute,
    ConnMaxLifetime: 60 * time.Minute,
    MaxIdleConns:    5,
    MaxOpenConns:    10,
}

config := db.DBConfig{
    // ... other fields
    PoolConfig: poolConfig,
}

Or use the defaults:

config := db.DBConfig{
    // ... other fields
    PoolConfig: db.DefaultPoolConfig(),
}

Complete Example

package main

import (
    "log"
    "github.com/ducminhgd/gao/db"
)

func main() {
    // Configure primary database
    primary := db.DBConfig{
        Type:       db.MySQL,
        Host:       "primary.db.local",
        Port:       3306,
        Username:   "root",
        Password:   "secret",
        Database:   "myapp",
        Params:     "charset=utf8mb4&parseTime=True&loc=Local",
        PoolConfig: db.DefaultPoolConfig(),
    }

    // Configure read replicas
    replicas := []db.DBConfig{
        {
            Type:       db.MySQL,
            Host:       "replica1.db.local",
            Database:   "myapp",
            Username:   "readonly",
            Password:   "secret",
            PoolConfig: db.DefaultPoolConfig(),
        },
        {
            Type:       db.MySQL,
            Host:       "replica2.db.local",
            Database:   "myapp",
            Username:   "readonly",
            Password:   "secret",
            PoolConfig: db.DefaultPoolConfig(),
        },
    }

    // Create configuration
    config := db.NewReadWriteSplitConfig(primary, nil, replicas, nil)

    // Create manager
    manager, err := db.NewGORMManagerFromConfig(config)
    if err != nil {
        log.Fatal(err)
    }
    defer manager.Close()

    // Use the database
    db := manager.DB()
    // ... perform database operations
}

Notes

  • DSN strings take precedence over individual parameters
  • Default ports: MySQL (3306), PostgreSQL (5432)
  • Special characters in PostgreSQL passwords are automatically URL-encoded
  • The GetDSN() method returns an empty string if required parameters (Host, Database) are missing

Documentation

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func RawOrderBySQL

func RawOrderBySQL[ListOrders ~[]string](o ListOrders, separator string) string

RawOrderBySQL generates an SQL ORDER BY clause based on the provided list of orders.

Parameters: - o: a list of orders of type ListOrders. - separator: a string used to split the orders into sort fields and sort directions.

Return: - a string representing the generated SQL ORDER BY clause.

Types

type DBConfig added in v0.4.0

type DBConfig struct {
	// Type is the database type (mysql or postgres)
	Type DatabaseType
	// DSN is the Data Source Name for the database connection
	// If empty, it will be built from Host, Port, Username, Password, Database, and Params
	DSN string
	// Host is the database host (used if DSN is empty)
	Host string
	// Port is the database port (used if DSN is empty)
	Port int
	// Username is the database username (used if DSN is empty)
	Username string
	// Password is the database password (used if DSN is empty)
	Password string
	// Database is the database name (used if DSN is empty)
	Database string
	// Params contains additional connection parameters (used if DSN is empty)
	// For MySQL: e.g., "charset=utf8mb4&parseTime=True&loc=Local"
	// For PostgreSQL: e.g., "sslmode=disable&TimeZone=UTC"
	Params string
	// PoolConfig contains connection pool settings
	PoolConfig PoolConfig
}

DBConfig represents the configuration for a single database connection

func (*DBConfig) GetDSN added in v0.4.0

func (c *DBConfig) GetDSN() string

GetDSN returns the DSN string. If DSN is already set, it returns it directly. Otherwise, it builds the DSN from Host, Port, Username, Password, Database, and Params.

type DatabaseType added in v0.4.0

type DatabaseType string

DatabaseType represents the type of database (MySQL or PostgreSQL)

const (
	// MySQL database type
	MySQL DatabaseType = "mysql"
	// PostgreSQL database type
	PostgreSQL DatabaseType = "postgres"
	// SQLite database type
	SQLite DatabaseType = "sqlite"
)

type GORMManager

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

func NewGORMManager

func NewGORMManager(d gorm.Dialector, opts ...gorm.Option) (*GORMManager, error)

NewGORMManager creates a new GORMManager instance.

Parameters: - d: the gorm.Dialector to be used for the GORMManager. - opts: a variadic parameter of gorm.Option to be applied to the GORMManager.

Returns: - *GORMManager: the newly created GORMManager instance. - error: an error if the GORMManager creation fails.

func NewGORMManagerFromConfig added in v0.4.0

func NewGORMManagerFromConfig(config ManagerConfig) (*GORMManager, error)

NewGORMManagerFromConfig creates a new GORMManager with the provided configuration. This function supports MySQL and PostgreSQL databases with multiple sources and replicas.

Parameters: - config: the ManagerConfig containing database configuration

Returns: - *GORMManager: the newly created GORMManager instance - error: an error if the manager creation fails

func (*GORMManager) AddReplicaDialector

func (m *GORMManager) AddReplicaDialector(d gorm.Dialector, pc PoolConfig) (*GORMManager, error)

AddReplicaDialector adds a replica dialector to the GORMManager.

Parameters: - d: the gorm.Dialector to be added as a replica. - pc: the PoolConfig containing connection settings.

Returns: - *GORMManager: the updated GORMManager instance. - error: an error if the dialector registration fails.

func (*GORMManager) AddSourceDialector

func (m *GORMManager) AddSourceDialector(d gorm.Dialector, pc PoolConfig) (*GORMManager, error)

AddSourceDialector adds a source dialector to the GORMManager.

Parameters: - d: the gorm.Dialector to be added as a source. - pc: the PoolConfig containing connection settings.

Returns: - *GORMManager: the updated GORMManager instance. - error: an error if the dialector registration fails.

func (*GORMManager) Close added in v0.4.0

func (m *GORMManager) Close() error

Close closes all database connections

Returns: - error: an error if closing fails

func (*GORMManager) DB added in v0.2.1

func (m *GORMManager) DB() *gorm.DB

DB returns the underlying *gorm.DB instance of the GORMManager.

Parameters: - None

Returns: - *gorm.DB: the underlying *gorm.DB instance.

func (*GORMManager) WithLogger

func (m *GORMManager) WithLogger(lgr logger.Interface) *GORMManager

WithLogger sets the logger for the GORMManager instance.

Parameters: - lgr: the logger.Interface to be set for the GORMManager.

Returns: - *GORMManager: the updated GORMManager instance with the new logger.

type ManagerConfig added in v0.4.0

type ManagerConfig struct {
	// Primary is the primary database configuration (required)
	// This is always the initial connection to the database
	Primary DBConfig

	// Sources is a list of write database configurations (optional)
	// When specified, these databases (along with Primary) handle write operations
	// If empty, Primary handles all write operations
	Sources []DBConfig

	// Replicas is a list of read-only database configurations (optional)
	// These databases handle read operations when using dbresolver
	// If empty, reads go to Primary (or Sources if specified)
	Replicas []DBConfig

	// GormConfig contains GORM-specific configuration
	GormConfig *gorm.Config
}

ManagerConfig represents the configuration for the database manager

Two configuration modes are supported:

  1. Simple mode (single database): Set only Primary for a single database connection

2. Multi-database mode (read-write separation):

  • Sources: List of write databases (if empty, Primary is used as the sole write DB)
  • Replicas: List of read-only databases
  • Primary: The initial connection (always required)

Note: If you specify Sources, the Primary connection becomes the default connection, and Sources + Replicas are used by dbresolver for read-write splitting. If Sources is empty, Primary handles both reads and writes.

func NewReadWriteSplitConfig added in v0.4.0

func NewReadWriteSplitConfig(primary DBConfig, sources []DBConfig, replicas []DBConfig, gormConfig *gorm.Config) ManagerConfig

NewReadWriteSplitConfig creates a ManagerConfig with read-write separation This sets up a configuration where writes go to source databases and reads go to replicas.

Parameters:

  • primary: The primary database configuration (serves as the initial connection)
  • sources: Additional write databases (optional, can be empty)
  • replicas: Read-only databases
  • gormConfig: Optional GORM configuration (can be nil)

Returns:

  • ManagerConfig: A manager config with read-write separation

func NewSimpleManagerConfig added in v0.4.0

func NewSimpleManagerConfig(primary DBConfig, gormConfig *gorm.Config) ManagerConfig

NewSimpleManagerConfig creates a ManagerConfig for a single database connection This is a convenience function for the most common use case.

Parameters:

  • primary: The primary database configuration
  • gormConfig: Optional GORM configuration (can be nil)

Returns:

  • ManagerConfig: A manager config with only the primary database

type PoolConfig

type PoolConfig struct {
	ConnMaxIdleTime time.Duration `default:"10m"`
	ConnMaxLifetime time.Duration `default:"60m"`
	MaxIdleConns    int           `default:"5"`
	MaxOpenConns    int           `default:"10"`
}

func DefaultPoolConfig added in v0.4.0

func DefaultPoolConfig() PoolConfig

DefaultPoolConfig returns a PoolConfig with default values

Jump to

Keyboard shortcuts

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