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:
Jakub Zych
2026-10-01 09:51:03 +02:00
parent 565ce982d9
commit 037dc53030
22 changed files with 344 additions and 168 deletions

View File

@@ -100,10 +100,9 @@ func stopPostgres() {
}
}
// icuDatabase creates a database for one test with the ICU pl-PL locale
// lagoon requires, and drops it when the test ends. It returns the pool
// opened on it and its DSN.
func icuDatabase(t *testing.T) (*sql.DB, string) {
// testDatabase creates a database for one test and drops it when the test
// ends. It returns the pool opened on it and its DSN.
func testDatabase(t *testing.T) (*sql.DB, string) {
t.Helper()
if testing.Short() {
t.Skip("requires testcontainers postgres")
@@ -113,7 +112,7 @@ func icuDatabase(t *testing.T) (*sql.DB, string) {
}
name := "blog_" + strings.ToLower(strings.NewReplacer("/", "_", "-", "_").Replace(t.Name()))
quoted := `"` + strings.ReplaceAll(name, `"`, `""`) + `"`
if _, err := pgAdmin.ExecContext(t.Context(), `CREATE DATABASE `+quoted+` TEMPLATE template0 ENCODING 'UTF8' LOCALE_PROVIDER icu ICU_LOCALE 'pl-PL'`); err != nil {
if _, err := pgAdmin.ExecContext(t.Context(), `CREATE DATABASE `+quoted+` TEMPLATE template0 ENCODING 'UTF8'`); err != nil {
t.Fatalf("create %s: %v", name, err)
}
u, err := url.Parse(pgDSN)
@@ -133,11 +132,11 @@ func icuDatabase(t *testing.T) (*sql.DB, string) {
return db, dsn
}
// migrated activates acme.blog, migrates a fresh ICU database and publishes
// migrated activates acme.blog, migrates a fresh database and publishes
// it on the application, as the serve command does at start-up.
func migrated(t *testing.T) (*backpack.App, party.Plugin, *gorm.DB) {
t.Helper()
sqlDB, _ := icuDatabase(t)
sqlDB, _ := testDatabase(t)
gdb, err := lagoon.Use(t.Context(), sqlDB)
if err != nil {
t.Fatalf("lagoon.Use: %v", err)