go-migrationGo Migration
Connections
Documentation

Connection Manager

Manage multiple named database connections with database.NewManager(), RegisterDriver(), AddConnection(), Connection(), and Close().

Connection Manager

The connection manager lets you configure and work with multiple database connections in a single application. This is useful when your app reads from a replica, writes to a primary, or connects to entirely different databases.

Creating a Manager

Create a new connection manager with database.NewManager():

go
import "github.com/gopackx/go-migration/pkg/database"

mgr := database.NewManager()
defer mgr.Close()

The manager holds all your named connections and handles their lifecycle.

Registering Drivers

Before adding connections, register the database drivers you plan to use. RegisterDriver takes the driver name and a Driver value — use the constructors from the drivers sub-package:

go
import (
    "github.com/gopackx/go-migration/pkg/database"
    "github.com/gopackx/go-migration/pkg/database/drivers"
    _ "github.com/lib/pq"
    _ "github.com/go-sql-driver/mysql"
)

mgr := database.NewManager()
mgr.RegisterDriver("postgres", drivers.NewPostgresDriver())
mgr.RegisterDriver("mysql", drivers.NewMySQLDriver())
ParameterTypeDescription
First argumentstringThe driver name connections reference via their Driver field
Second argumentdatabase.DriverA driver implementation, e.g. drivers.NewPostgresDriver(), drivers.NewMySQLDriver(), drivers.NewSQLiteDriver()

Adding Connections

Use mgr.AddConnection() to register a named connection with its discrete connection fields and pool settings. There is no DSN field — the driver builds the DSN from these fields. AddConnection returns an error:

go
err := mgr.AddConnection("primary", database.ConnectionConfig{
    Driver:          "postgres",
    Host:            "localhost",
    Port:            5432,
    Database:        "myapp",
    Username:        "user",
    Password:        "pass",
    MaxOpenConns:    25,
    MaxIdleConns:    5,
    ConnMaxLifetime: 5 * time.Minute,
    Options:         map[string]string{"sslmode": "disable"},
})
if err != nil {
    log.Fatalf("add connection: %v", err)
}
FieldTypeDescription
DriverstringName of the registered driver
HoststringDatabase server hostname or IP
PortintDatabase server port
DatabasestringDatabase name (or file path for SQLite)
UsernamestringDatabase user
PasswordstringDatabase password
MaxOpenConnsintMaximum number of open connections
MaxIdleConnsintMaximum number of idle connections
ConnMaxLifetimetime.DurationMaximum lifetime of a connection
Optionsmap[string]stringDriver-specific options, e.g. {"sslmode": "disable"} for PostgreSQL

The first connection added becomes the default automatically. Use mgr.SetDefault(name) to choose a different default and mgr.Default() to retrieve the default *sql.DB.

Retrieving Connections

Retrieve a *sql.DB instance by name with mgr.Connection():

go
db, err := mgr.Connection("primary")
if err != nil {
    log.Fatalf("failed to get connection: %v", err)
}

// Use db as a standard *sql.DB
rows, err := db.Query("SELECT id, name FROM users")

Connection() returns a standard *sql.DB, so you can use it with any Go database library or ORM — not just go-migration. Connections are opened lazily on first request and cached for reuse.

The Default Connection

The first connection added with AddConnection() automatically becomes the default. You can change it with SetDefault() and retrieve the default *sql.DB with Default():

go
// Choose which named connection is the default.
if err := mgr.SetDefault("primary"); err != nil {
    log.Fatalf("set default: %v", err)
}

// Retrieve the default connection.
db, err := mgr.Default()
if err != nil {
    log.Fatalf("get default connection: %v", err)
}

SetDefault returns an error if the named connection has not been registered. Default returns an error if no default has been set.

Closing Connections

Call mgr.Close() to close all managed connections when your application shuts down:

go
err := mgr.Close()
if err != nil {
    log.Printf("error closing connections: %v", err)
}

This closes every connection that was opened through the manager.

Complete Multi-Connection Example

Here's a full example connecting to both PostgreSQL and MySQL:

main.go
package main

import (
    "fmt"
    "log"
    "time"

    "github.com/gopackx/go-migration/pkg/database"
    "github.com/gopackx/go-migration/pkg/database/drivers"
    _ "github.com/lib/pq"
    _ "github.com/go-sql-driver/mysql"
)

func main() {
    mgr := database.NewManager()
    defer mgr.Close()

    // Register drivers
    mgr.RegisterDriver("postgres", drivers.NewPostgresDriver())
    mgr.RegisterDriver("mysql", drivers.NewMySQLDriver())

    // Add PostgreSQL connection
    if err := mgr.AddConnection("primary", database.ConnectionConfig{
        Driver:          "postgres",
        Host:            "localhost",
        Port:            5432,
        Database:        "myapp",
        Username:        "user",
        Password:        "pass",
        MaxOpenConns:    25,
        MaxIdleConns:    5,
        ConnMaxLifetime: 5 * time.Minute,
        Options:         map[string]string{"sslmode": "disable"},
    }); err != nil {
        log.Fatalf("add primary: %v", err)
    }

    // Add MySQL connection
    if err := mgr.AddConnection("analytics", database.ConnectionConfig{
        Driver:          "mysql",
        Host:            "localhost",
        Port:            3306,
        Database:        "analytics",
        Username:        "user",
        Password:        "pass",
        MaxOpenConns:    10,
        MaxIdleConns:    3,
        ConnMaxLifetime: 5 * time.Minute,
        Options:         map[string]string{"parseTime": "true"},
    }); err != nil {
        log.Fatalf("add analytics: %v", err)
    }

    // Use the PostgreSQL connection
    primaryDB, err := mgr.Connection("primary")
    if err != nil {
        log.Fatalf("primary connection failed: %v", err)
    }

    // Use the MySQL connection
    analyticsDB, err := mgr.Connection("analytics")
    if err != nil {
        log.Fatalf("analytics connection failed: %v", err)
    }

    fmt.Println("Primary DB:", primaryDB.Stats().OpenConnections, "open connections")
    fmt.Println("Analytics DB:", analyticsDB.Stats().OpenConnections, "open connections")
}

Always call mgr.Close() (or use defer mgr.Close()) to release database connections when your application exits.

What's Next?

  • Pool Configuration — tune connection pool settings for your workload
  • Drivers — set up PostgreSQL, MySQL, and SQLite drivers