feat(lagoon): per-query collation for OrderBy, drop the database locale check
- lagoon.OrderBy takes variadic lagoon.OrderOption values; lagoon.Collate(name) emits a validated, double-quoted COLLATE clause (e.g. "pl-x-icu") - remove the exported CheckLocale and the ICU pl-PL check from Open and Use - framework test containers and per-test databases are plain PostgreSQL - lagoon README, root README and docs pages drop the locale requirement; queries-and-pagination gains a "Sorting with a collation" section backed by ExampleCollate
This commit is contained in:
@@ -13,13 +13,8 @@ import (
|
||||
"gorm.io/gorm"
|
||||
)
|
||||
|
||||
const (
|
||||
requiredLocaleProvider = "i"
|
||||
requiredICULocale = "pl-PL"
|
||||
)
|
||||
|
||||
// Open pings dsn through pgx stdlib, requires Postgres 16 ICU pl-PL, and
|
||||
// returns that exact *sql.DB plus a GORM handle opened on it.
|
||||
// Open pings dsn through pgx stdlib and returns that exact *sql.DB plus a
|
||||
// GORM handle opened on it.
|
||||
//
|
||||
// The job worker in the conga module opens its own single-connection
|
||||
// pgxpool.Pool for River LISTEN/NOTIFY. Do not create that listener pool
|
||||
@@ -37,10 +32,6 @@ func Open(ctx context.Context, dsn string) (*sql.DB, *gorm.DB, error) {
|
||||
_ = sqlDB.Close()
|
||||
return nil, nil, fmt.Errorf("lagoon: ping postgres: %w", err)
|
||||
}
|
||||
if err := CheckLocale(ctx, sqlDB); err != nil {
|
||||
_ = sqlDB.Close()
|
||||
return nil, nil, err
|
||||
}
|
||||
gdb, err := gormFromSQL(sqlDB)
|
||||
if err != nil {
|
||||
_ = sqlDB.Close()
|
||||
@@ -49,9 +40,9 @@ func Open(ctx context.Context, dsn string) (*sql.DB, *gorm.DB, error) {
|
||||
return sqlDB, gdb, nil
|
||||
}
|
||||
|
||||
// Use pings an existing pool, requires ICU pl-PL, and returns a GORM handle
|
||||
// opened on that exact *sql.DB. Callers that already hold a pool (tests,
|
||||
// the app boot seam) must not open a second connection.
|
||||
// Use pings an existing pool and returns a GORM handle opened on that exact
|
||||
// *sql.DB. Callers that already hold a pool (tests, the app boot seam) must
|
||||
// not open a second connection.
|
||||
func Use(ctx context.Context, sqlDB *sql.DB) (*gorm.DB, error) {
|
||||
if sqlDB == nil {
|
||||
return nil, fmt.Errorf("lagoon: sql db is nil")
|
||||
@@ -59,9 +50,6 @@ func Use(ctx context.Context, sqlDB *sql.DB) (*gorm.DB, error) {
|
||||
if err := sqlDB.PingContext(ctx); err != nil {
|
||||
return nil, fmt.Errorf("lagoon: ping postgres: %w", err)
|
||||
}
|
||||
if err := CheckLocale(ctx, sqlDB); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return gormFromSQL(sqlDB)
|
||||
}
|
||||
|
||||
@@ -127,28 +115,3 @@ func Publish(app *backpack.App, sqlDB *sql.DB, gdb *gorm.DB) error {
|
||||
}
|
||||
return runDatabaseHooks(app, sqlDB, gdb)
|
||||
}
|
||||
|
||||
// CheckLocale fails unless the connected database uses ICU locale pl-PL.
|
||||
func CheckLocale(ctx context.Context, db *sql.DB) error {
|
||||
if db == nil {
|
||||
return fmt.Errorf("lagoon: sql db is nil")
|
||||
}
|
||||
var provider, icu string
|
||||
err := db.QueryRowContext(ctx, `
|
||||
SELECT datlocprovider::text, COALESCE(daticulocale, '')
|
||||
FROM pg_database
|
||||
WHERE datname = current_database()`).Scan(&provider, &icu)
|
||||
if err != nil {
|
||||
return fmt.Errorf("lagoon: read database locale: %w", err)
|
||||
}
|
||||
return checkLocale(provider, icu)
|
||||
}
|
||||
|
||||
func checkLocale(provider, icu string) error {
|
||||
provider = strings.TrimSpace(provider)
|
||||
icu = strings.TrimSpace(icu)
|
||||
if provider == requiredLocaleProvider && icu == requiredICULocale {
|
||||
return nil
|
||||
}
|
||||
return fmt.Errorf("lagoon: database locale must be ICU pl-PL (datlocprovider=%q, daticulocale=%q); got provider %q locale %q. Create the database with: CREATE DATABASE ... TEMPLATE template0 ENCODING 'UTF8' LOCALE_PROVIDER icu ICU_LOCALE 'pl-PL'", requiredLocaleProvider, requiredICULocale, provider, icu)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user