Documentation
¶
Overview ¶
Package database provides database connectivity and management for modular applications. This module supports multiple database connections with different drivers and provides a unified interface for database operations.
The database module features:
- Multiple database connections with configurable drivers (MySQL, PostgreSQL, SQLite, etc.)
- Connection pooling and health monitoring
- Default connection selection for simplified usage
- Database service abstraction for testing and mocking
- Instance-aware configuration for environment-specific settings
Usage:
app.RegisterModule(database.NewModule())
The module registers database services that provide access to sql.DB instances and higher-level database operations. Other modules can depend on these services for database access.
Configuration:
The module requires a "database" configuration section with connection details for each database instance, including driver, DSN, and connection pool settings.
Index ¶
- Constants
- Variables
- type AWSIAMAuthConfig
- type AWSIAMTokenProvider
- func (p *AWSIAMTokenProvider) BuildDSNWithIAMToken(ctx context.Context, originalDSN string) (string, error)
- func (p *AWSIAMTokenProvider) GetToken(ctx context.Context, endpoint string) (string, error)
- func (p *AWSIAMTokenProvider) SetTokenRefreshCallback(callback TokenRefreshCallback)
- func (p *AWSIAMTokenProvider) StartTokenRefresh(ctx context.Context, endpoint string)
- func (p *AWSIAMTokenProvider) StopTokenRefresh()
- type Config
- type ConnectionConfig
- type DatabaseService
- type EventEmitter
- type IAMTokenProvider
- type Migration
- type MigrationRunner
- type MigrationService
- type Module
- func (m *Module) Constructor() modular.ModuleConstructor
- func (m *Module) Dependencies() []string
- func (m *Module) EmitEvent(ctx context.Context, event cloudevents.Event) error
- func (m *Module) GetConnection(name string) (*sql.DB, bool)
- func (m *Module) GetConnections() []string
- func (m *Module) GetDefaultConnection() *sql.DB
- func (m *Module) GetDefaultService() DatabaseService
- func (m *Module) GetRegisteredEventTypes() []string
- func (m *Module) GetService(name string) (DatabaseService, bool)
- func (m *Module) Init(app modular.Application) error
- func (m *Module) Name() string
- func (m *Module) ProvidesServices() []modular.ServiceProvider
- func (m *Module) RegisterConfig(app modular.Application) error
- func (m *Module) RegisterObservers(subject modular.Subject) error
- func (m *Module) RequiresServices() []modular.ServiceDependency
- func (m *Module) Start(ctx context.Context) error
- func (m *Module) Stop(ctx context.Context) error
- type TokenRefreshCallback
Constants ¶
const ( // Connection events EventTypeConnected = "com.modular.database.connected" EventTypeDisconnected = "com.modular.database.disconnected" EventTypeConnectionError = "com.modular.database.connection.error" // Query events EventTypeQueryExecuted = "com.modular.database.query.executed" EventTypeQueryError = "com.modular.database.query.error" // Transaction events EventTypeTransactionStarted = "com.modular.database.transaction.started" EventTypeTransactionCommitted = "com.modular.database.transaction.committed" EventTypeTransactionRolledBack = "com.modular.database.transaction.rolledback" // Migration events EventTypeMigrationStarted = "com.modular.database.migration.started" EventTypeMigrationCompleted = "com.modular.database.migration.completed" EventTypeMigrationFailed = "com.modular.database.migration.failed" // Configuration events EventTypeConfigLoaded = "com.modular.database.config.loaded" )
Event type constants for database module events. Following CloudEvents specification reverse domain notation.
const ( // DefaultConnectionTimeout is the default timeout for database connection tests DefaultConnectionTimeout = 5 * time.Second )
Constants for database service
const Name = "database"
Module name constant for service registration and dependency resolution.
Variables ¶
var ( ErrIAMAuthNotEnabled = errors.New("AWS IAM auth not enabled") ErrIAMRegionRequired = errors.New("AWS region is required for IAM authentication") ErrIAMDBUserRequired = errors.New("database user is required for IAM authentication") ErrExtractEndpointFailed = errors.New("could not extract endpoint from DSN") ErrNoUserInfoInDSN = errors.New("no user information in DSN to replace password") )
var ( // ErrTransactionNil is returned when a nil transaction is passed to transaction operations ErrTransactionNil = errors.New("transaction cannot be nil") // ErrInvalidTableName is returned when an invalid table name is used ErrInvalidTableName = errors.New("invalid table name: must start with letter/underscore and contain only alphanumeric/underscore characters") // ErrMigrationServiceNotInitialized is returned when migration operations are attempted // without proper migration service initialization ErrMigrationServiceNotInitialized = errors.New("migration service not initialized") )
Static error definitions to avoid dynamic error creation (err113 linter)
var ( ErrNoDefaultService = errors.New("no default database service available") ErrNoSubjectForEventEmission = errors.New("no subject available for event emission") )
Static errors for err113 compliance
var ( ErrInvalidConfigType = errors.New("invalid config type for database module") ErrMissingDriver = errors.New("database connection missing driver") ErrMissingDSN = errors.New("database connection missing DSN") )
var ( ErrEmptyDriver = errors.New("database driver cannot be empty") ErrEmptyDSN = errors.New("database connection string (DSN) cannot be empty") ErrDatabaseNotConnected = errors.New("database not connected") )
Define static errors
Functions ¶
This section is empty.
Types ¶
type AWSIAMAuthConfig ¶
type AWSIAMAuthConfig struct { // Enabled indicates whether AWS IAM authentication is enabled Enabled bool `json:"enabled" yaml:"enabled" env:"AWS_IAM_AUTH_ENABLED"` // Region specifies the AWS region for the RDS instance Region string `json:"region" yaml:"region" env:"AWS_IAM_AUTH_REGION"` // DBUser specifies the database username for IAM authentication DBUser string `json:"db_user" yaml:"db_user" env:"AWS_IAM_AUTH_DB_USER"` // TokenRefreshInterval specifies how often to refresh the IAM token (in seconds) // Default is 10 minutes (600 seconds), tokens expire after 15 minutes TokenRefreshInterval int `json:"token_refresh_interval" yaml:"token_refresh_interval" env:"AWS_IAM_AUTH_TOKEN_REFRESH" default:"600"` // ConnectionTimeout specifies the timeout for database connection tests (in seconds) // Default is 5 seconds ConnectionTimeout time.Duration `json:"connection_timeout" yaml:"connection_timeout" env:"AWS_IAM_AUTH_CONNECTION_TIMEOUT" default:"5s"` }
AWSIAMAuthConfig represents AWS IAM authentication configuration
type AWSIAMTokenProvider ¶
type AWSIAMTokenProvider struct {
// contains filtered or unexported fields
}
AWSIAMTokenProvider manages AWS IAM authentication tokens for RDS
func NewAWSIAMTokenProvider ¶
func NewAWSIAMTokenProvider(authConfig *AWSIAMAuthConfig) (*AWSIAMTokenProvider, error)
NewAWSIAMTokenProvider creates a new AWS IAM token provider
func (*AWSIAMTokenProvider) BuildDSNWithIAMToken ¶
func (p *AWSIAMTokenProvider) BuildDSNWithIAMToken(ctx context.Context, originalDSN string) (string, error)
BuildDSNWithIAMToken takes a DSN and replaces the password with the IAM token
func (*AWSIAMTokenProvider) GetToken ¶
GetToken returns the current valid IAM token, refreshing if necessary
func (*AWSIAMTokenProvider) SetTokenRefreshCallback ¶ added in v1.2.4
func (p *AWSIAMTokenProvider) SetTokenRefreshCallback(callback TokenRefreshCallback)
SetTokenRefreshCallback sets a callback to be notified when tokens are refreshed
func (*AWSIAMTokenProvider) StartTokenRefresh ¶
func (p *AWSIAMTokenProvider) StartTokenRefresh(ctx context.Context, endpoint string)
StartTokenRefresh starts a background goroutine to refresh tokens periodically
func (*AWSIAMTokenProvider) StopTokenRefresh ¶
func (p *AWSIAMTokenProvider) StopTokenRefresh()
StopTokenRefresh stops the background token refresh
type Config ¶
type Config struct { // Connections contains all defined database connections Connections map[string]*ConnectionConfig `json:"connections" yaml:"connections"` // Default specifies the name of the default connection Default string `json:"default" yaml:"default" env:"DEFAULT_DB_CONNECTION"` }
Config represents database module configuration
func (*Config) GetInstanceConfigs ¶
GetInstanceConfigs returns the connections map for instance-aware configuration
type ConnectionConfig ¶
type ConnectionConfig struct { // Driver specifies the database driver to use (e.g., "postgres", "mysql") Driver string `json:"driver" yaml:"driver" env:"DRIVER"` // DSN is the database connection string DSN string `json:"dsn" yaml:"dsn" env:"DSN"` // MaxOpenConnections sets the maximum number of open connections to the database MaxOpenConnections int `json:"max_open_connections" yaml:"max_open_connections" env:"MAX_OPEN_CONNECTIONS"` // MaxIdleConnections sets the maximum number of idle connections in the pool MaxIdleConnections int `json:"max_idle_connections" yaml:"max_idle_connections" env:"MAX_IDLE_CONNECTIONS"` // ConnectionMaxLifetime sets the maximum amount of time a connection may be reused ConnectionMaxLifetime time.Duration `json:"connection_max_lifetime" yaml:"connection_max_lifetime" env:"CONNECTION_MAX_LIFETIME"` // ConnectionMaxIdleTime sets the maximum amount of time a connection may be idle ConnectionMaxIdleTime time.Duration `json:"connection_max_idle_time" yaml:"connection_max_idle_time" env:"CONNECTION_MAX_IDLE_TIME"` // AWSIAMAuth contains AWS IAM authentication configuration AWSIAMAuth *AWSIAMAuthConfig `json:"aws_iam_auth,omitempty" yaml:"aws_iam_auth,omitempty"` }
ConnectionConfig represents configuration for a single database connection
type DatabaseService ¶
type DatabaseService interface { // Connect establishes the database connection Connect() error // Close closes the database connection Close() error // DB returns the underlying database connection DB() *sql.DB // Ping verifies the database connection is still alive Ping(ctx context.Context) error // Stats returns database statistics Stats() sql.DBStats // ExecContext executes a query without returning any rows ExecContext(ctx context.Context, query string, args ...interface{}) (sql.Result, error) // Exec executes a query without returning any rows (using default context) Exec(query string, args ...interface{}) (sql.Result, error) // ExecuteContext executes a query without returning any rows (alias for ExecContext) // Kept for backwards compatibility with earlier API docs/tests ExecuteContext(ctx context.Context, query string, args ...interface{}) (sql.Result, error) // Execute executes a query without returning any rows (alias for Exec) // Kept for backwards compatibility with earlier API docs/tests Execute(query string, args ...interface{}) (sql.Result, error) // PrepareContext prepares a statement for execution PrepareContext(ctx context.Context, query string) (*sql.Stmt, error) // Prepare prepares a statement for execution (using default context) Prepare(query string) (*sql.Stmt, error) // QueryContext executes a query that returns rows QueryContext(ctx context.Context, query string, args ...interface{}) (*sql.Rows, error) // Query executes a query that returns rows (using default context) Query(query string, args ...interface{}) (*sql.Rows, error) // QueryRowContext executes a query that returns a single row QueryRowContext(ctx context.Context, query string, args ...interface{}) *sql.Row // QueryRow executes a query that returns a single row (using default context) QueryRow(query string, args ...interface{}) *sql.Row // BeginTx starts a transaction BeginTx(ctx context.Context, opts *sql.TxOptions) (*sql.Tx, error) // Begin starts a transaction with default options Begin() (*sql.Tx, error) // CommitTransaction commits a transaction and emits appropriate events CommitTransaction(ctx context.Context, tx *sql.Tx) error // RollbackTransaction rolls back a transaction and emits appropriate events RollbackTransaction(ctx context.Context, tx *sql.Tx) error // Migration operations // RunMigration executes a database migration RunMigration(ctx context.Context, migration Migration) error // GetAppliedMigrations returns a list of applied migration IDs GetAppliedMigrations(ctx context.Context) ([]string, error) // CreateMigrationsTable ensures the migrations tracking table exists CreateMigrationsTable(ctx context.Context) error // SetEventEmitter sets the event emitter for migration events SetEventEmitter(emitter EventEmitter) }
DatabaseService defines the operations that can be performed with a database
func NewDatabaseService ¶
func NewDatabaseService(config ConnectionConfig, logger modular.Logger) (DatabaseService, error)
NewDatabaseService creates a new database service from configuration
type EventEmitter ¶ added in v1.2.0
type EventEmitter interface { // EmitEvent emits a cloud event with the provided context EmitEvent(ctx context.Context, event cloudevents.Event) error }
EventEmitter interface for emitting migration events
type IAMTokenProvider ¶ added in v1.2.4
type IAMTokenProvider interface { GetToken(ctx context.Context, endpoint string) (string, error) BuildDSNWithIAMToken(ctx context.Context, originalDSN string) (string, error) StartTokenRefresh(ctx context.Context, endpoint string) StopTokenRefresh() // SetTokenRefreshCallback sets a callback to be notified when tokens are refreshed SetTokenRefreshCallback(callback TokenRefreshCallback) }
IAMTokenProvider defines the interface for AWS IAM token providers
type Migration ¶ added in v1.2.0
type Migration struct { ID string Version string SQL string Up bool // true for up migration, false for down }
Migration represents a database migration
type MigrationRunner ¶ added in v1.2.0
type MigrationRunner struct {
// contains filtered or unexported fields
}
MigrationRunner helps run multiple migrations
func NewMigrationRunner ¶ added in v1.2.0
func NewMigrationRunner(service MigrationService) *MigrationRunner
NewMigrationRunner creates a new migration runner
func (*MigrationRunner) RunMigrations ¶ added in v1.2.0
func (r *MigrationRunner) RunMigrations(ctx context.Context, migrations []Migration) error
RunMigrations runs a set of migrations in order
type MigrationService ¶ added in v1.2.0
type MigrationService interface { // RunMigration executes a single migration RunMigration(ctx context.Context, migration Migration) error // GetAppliedMigrations returns a list of already applied migrations GetAppliedMigrations(ctx context.Context) ([]string, error) // CreateMigrationsTable creates the migrations tracking table CreateMigrationsTable(ctx context.Context) error }
MigrationService provides migration functionality
func NewMigrationService ¶ added in v1.2.0
func NewMigrationService(db *sql.DB, eventEmitter EventEmitter) MigrationService
NewMigrationService creates a new migration service
type Module ¶
type Module struct {
// contains filtered or unexported fields
}
Module represents the database module and implements the modular.Module interface. It manages multiple database connections and provides services for database access.
The module supports:
- Multiple named database connections
- Automatic connection health monitoring
- Default connection selection
- Service abstraction for easier testing
- Instance-aware configuration
- Event observation and emission for database operations
The module implements the following interfaces:
- modular.Module: Basic module lifecycle
- modular.Configurable: Configuration management
- modular.ServiceAware: Service dependency management
- modular.Startable: Startup logic
- modular.Stoppable: Shutdown logic
- modular.ObservableModule: Event observation and emission
func NewModule ¶
func NewModule() *Module
NewModule creates a new database module instance. The returned module must be registered with the application before use.
Example:
dbModule := database.NewModule() app.RegisterModule(dbModule)
func (*Module) Constructor ¶ added in v1.2.4
func (m *Module) Constructor() modular.ModuleConstructor
Constructor provides a dependency injection constructor for the module. This allows the logger service to be properly injected during module initialization.
func (*Module) Dependencies ¶
Dependencies returns the names of modules this module depends on. The database module has no dependencies, making it suitable as a foundation module that other modules can depend on.
func (*Module) EmitEvent ¶ added in v1.2.0
EmitEvent implements the ObservableModule interface. This allows the database module to emit events to registered observers.
func (*Module) GetConnection ¶
GetConnection returns a database connection by name. This method allows access to specific named database connections that were configured in the module's configuration.
Example:
if db, exists := dbModule.GetConnection("primary"); exists { // Use the primary database connection }
func (*Module) GetConnections ¶
GetConnections returns a list of all available connection names. This is useful for discovery and diagnostic purposes.
func (*Module) GetDefaultConnection ¶
GetDefaultConnection returns the default database connection. The default connection is determined by the "default" field in the configuration. If no default is configured or the named connection doesn't exist, this method will return any available connection.
Returns nil if no connections are available.
func (*Module) GetDefaultService ¶
func (m *Module) GetDefaultService() DatabaseService
GetDefaultService returns the default database service. Similar to GetDefaultConnection, but returns a DatabaseService interface that provides additional functionality beyond the raw sql.DB.
func (*Module) GetRegisteredEventTypes ¶ added in v1.2.0
GetRegisteredEventTypes implements the ObservableModule interface. Returns all event types that this database module can emit.
func (*Module) GetService ¶
func (m *Module) GetService(name string) (DatabaseService, bool)
GetService returns a database service by name. Database services provide a higher-level interface than raw database connections, including connection management and additional utilities.
func (*Module) Init ¶
func (m *Module) Init(app modular.Application) error
Init initializes the database module and establishes database connections. This method loads the configuration, validates connection settings, and establishes connections to all configured databases.
Initialization process:
- Load configuration from the "database" section
- Validate connection configurations
- Create database services for each connection
- Test initial connectivity
func (*Module) Name ¶
Name returns the name of the module. This name is used for dependency resolution and configuration section lookup.
func (*Module) ProvidesServices ¶
func (m *Module) ProvidesServices() []modular.ServiceProvider
ProvidesServices declares services provided by this module. The database module provides:
- database.manager: Module instance for direct database management
- database.service: Default database service for convenient access
Other modules can depend on these services to access database functionality.
func (*Module) RegisterConfig ¶
func (m *Module) RegisterConfig(app modular.Application) error
RegisterConfig registers the module's configuration structure. The database module uses instance-aware configuration to support environment-specific database connection settings.
Configuration structure:
- Default: name of the default connection to use
- Connections: map of connection names to their configurations
Environment variables:
DB_<CONNECTION_NAME>_DRIVER, DB_<CONNECTION_NAME>_DSN, etc.
func (*Module) RegisterObservers ¶ added in v1.2.0
RegisterObservers implements the ObservableModule interface. This allows the database module to register as an observer for events it's interested in.
func (*Module) RequiresServices ¶
func (m *Module) RequiresServices() []modular.ServiceDependency
RequiresServices declares services required by this module. The database module requires the logger service for structured logging.
type TokenRefreshCallback ¶ added in v1.2.4
TokenRefreshCallback is called when a token is refreshed