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():
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:
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())| Parameter | Type | Description |
|---|---|---|
| First argument | string | The driver name connections reference via their Driver field |
| Second argument | database.Driver | A 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:
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)
}| Field | Type | Description |
|---|---|---|
Driver | string | Name of the registered driver |
Host | string | Database server hostname or IP |
Port | int | Database server port |
Database | string | Database name (or file path for SQLite) |
Username | string | Database user |
Password | string | Database password |
MaxOpenConns | int | Maximum number of open connections |
MaxIdleConns | int | Maximum number of idle connections |
ConnMaxLifetime | time.Duration | Maximum lifetime of a connection |
Options | map[string]string | Driver-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():
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():
// 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:
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:
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