feat: PostgreSQL driver support

This commit is contained in:
fsylvain committed 2026-10-06 13:35:10 +02:00
1 parent eb9bfabed5
commit dc5d12348c
24 files changed
+1585 -75

No files matched your search

@@ -13,9 +13,14 @@ const (
DatabaseDriverSQLite = "sqlite"
DatabaseDriverMySQL = "mysql"
DatabaseDriverPostgres = "postgres"
databaseDriverPostgresAlias = "postgresql"
DefaultDatabaseDriver = DatabaseDriverSQLite
DefaultDatabasePort = "3306"
DefaultPostgresPort = "5432"
DefaultDatabaseTLS = "false"
DefaultDatabaseSSLMode = "disable"
DefaultMaxOpenConns = "10"
DefaultMaxIdleConns = "5"
DefaultConnMaxLifetimeSeconds = "300"
@@ -26,6 +31,7 @@ const (
envDatabasePassword = "DB_PASSWORD"
envDatabaseName = "DB_NAME"
envDatabaseTLS = "DB_TLS"
envDatabaseSSLMode = "DB_SSLMODE"
envDatabaseMaxOpenConns = "DB_MAX_OPEN_CONNS"
envDatabaseMaxIdleConns = "DB_MAX_IDLE_CONNS"
envDatabaseConnMaxLifetimeSecs = "DB_CONN_MAX_LIFETIME_SECONDS"
@@ -35,6 +41,8 @@ var mysqlRequiredEnvVars = []string{envDatabaseHost, envDatabaseUser, envDatabas
var DatabaseTLSModes = []string{"false", "true", "skip-verify", "preferred"}
var DatabaseSSLModes = []string{"disable", "require", "verify-ca", "verify-full"}
type DatabaseSettings struct {
Driver string
Host string
@@ -43,13 +51,22 @@ type DatabaseSettings struct {
Password string
Name string
TLS string
SSLMode string
MaxOpenConns int
MaxIdleConns int
ConnMaxLifetime time.Duration
}
func NormalizeDatabaseDriver(driver string) string {
if driver == databaseDriverPostgresAlias {
return DatabaseDriverPostgres
}
return driver
}
func DatabaseRequiredEnvVars(driver string) []string {
if driver == DatabaseDriverMySQL {
switch NormalizeDatabaseDriver(driver) {
case DatabaseDriverMySQL, DatabaseDriverPostgres:
return slices.Clone(mysqlRequiredEnvVars)
}
return nil
@@ -65,18 +82,27 @@ func MissingEnvVarError(names []string, lookup func(string) (string, bool)) erro
}
func databaseDriverFromEnv() string {
return envOrDefault(EnvDatabaseDriver, DefaultDatabaseDriver)
return NormalizeDatabaseDriver(envOrDefault(EnvDatabaseDriver, DefaultDatabaseDriver))
}
func databaseSettingsFromEnv() (DatabaseSettings, error) {
driver := databaseDriverFromEnv()
if driver != DatabaseDriverMySQL {
if driver != DatabaseDriverMySQL && driver != DatabaseDriverPostgres {
return DatabaseSettings{Driver: driver}, nil
}
tls := envOrDefault(envDatabaseTLS, DefaultDatabaseTLS)
if !slices.Contains(DatabaseTLSModes, tls) {
return DatabaseSettings{}, fmt.Errorf("%s must be one of %s, got %q", envDatabaseTLS, strings.Join(DatabaseTLSModes, ", "), tls)
defaultPort, tls, sslMode := DefaultDatabasePort, "", ""
if driver == DatabaseDriverPostgres {
defaultPort = DefaultPostgresPort
sslMode = envOrDefault(envDatabaseSSLMode, DefaultDatabaseSSLMode)
if !slices.Contains(DatabaseSSLModes, sslMode) {
return DatabaseSettings{}, fmt.Errorf("%s must be one of %s, got %q", envDatabaseSSLMode, strings.Join(DatabaseSSLModes, ", "), sslMode)
}
} else {
tls = envOrDefault(envDatabaseTLS, DefaultDatabaseTLS)
if !slices.Contains(DatabaseTLSModes, tls) {
return DatabaseSettings{}, fmt.Errorf("%s must be one of %s, got %q", envDatabaseTLS, strings.Join(DatabaseTLSModes, ", "), tls)
}
}
maxOpen, err := nonNegativeIntEnv(envDatabaseMaxOpenConns, DefaultMaxOpenConns)
if err != nil {
@@ -94,11 +120,12 @@ func databaseSettingsFromEnv() (DatabaseSettings, error) {
return DatabaseSettings{
Driver: driver,
Host: os.Getenv(envDatabaseHost),
Port: envOrDefault(envDatabasePort, DefaultDatabasePort),
Port: envOrDefault(envDatabasePort, defaultPort),
User: os.Getenv(envDatabaseUser),
Password: os.Getenv(envDatabasePassword),
Name: os.Getenv(envDatabaseName),
TLS: tls,
SSLMode: sslMode,
MaxOpenConns: maxOpen,
MaxIdleConns: maxIdle,
ConnMaxLifetime: time.Duration(lifetimeSeconds) * time.Second,