26bf26fc20
Co-authored-by: nova28 <17953305+nova28@users.noreply.github.com> Co-authored-by: Carlos Florencio <carlosmflorencio@gmail.com>
103 lines
3.5 KiB
Go
103 lines
3.5 KiB
Go
package dialect
|
|
|
|
import (
|
|
"context"
|
|
"path/filepath"
|
|
"testing"
|
|
|
|
"github.com/jmoiron/sqlx"
|
|
|
|
"github.com/kandev/kandev/internal/db"
|
|
"github.com/kandev/kandev/internal/testutil"
|
|
)
|
|
|
|
func TestOrderedIDConcat_FragmentShape(t *testing.T) {
|
|
got := OrderedIDConcat(SQLite3, "parent_id = p.id")
|
|
want := "(SELECT GROUP_CONCAT(w.id, ',') FROM (SELECT id FROM tasks WHERE parent_id = p.id ORDER BY id) w)"
|
|
if got != want {
|
|
t.Errorf("sqlite: got %q, want %q", got, want)
|
|
}
|
|
|
|
got = OrderedIDConcat(PGX, "parent_id = p.id")
|
|
want = "(SELECT string_agg(w.id, ',' ORDER BY w.id) FROM (SELECT id FROM tasks WHERE parent_id = p.id) w)"
|
|
if got != want {
|
|
t.Errorf("pgx: got %q, want %q", got, want)
|
|
}
|
|
}
|
|
|
|
// TestOrderedIDConcat_SQLite_OrdersAscendingByID proves the fragment
|
|
// actually orders ascending by id when executed, not just that its text
|
|
// looks right: ids are inserted out of order (and lexicographically
|
|
// non-sequential, UUID-shaped) so an unordered GROUP_CONCAT would produce a
|
|
// different string.
|
|
func TestOrderedIDConcat_SQLite_OrdersAscendingByID(t *testing.T) {
|
|
tmpDir := t.TempDir()
|
|
rawDB, err := db.OpenSQLite(filepath.Join(tmpDir, "test.db"))
|
|
if err != nil {
|
|
t.Fatalf("open: %v", err)
|
|
}
|
|
sqlxDB := sqlx.NewDb(rawDB, SQLite3)
|
|
t.Cleanup(func() { _ = sqlxDB.Close() })
|
|
|
|
if _, err := sqlxDB.Exec(`CREATE TABLE tasks (id TEXT PRIMARY KEY, parent_id TEXT)`); err != nil {
|
|
t.Fatalf("create table: %v", err)
|
|
}
|
|
// Insertion order deliberately disagrees with ascending id order.
|
|
for _, id := range []string{
|
|
"f47ac10b-58cc-4372-a567-0e02b2c3d479",
|
|
"0e02b2c3-58cc-4372-a567-f47ac10bd479",
|
|
"a567f47a-58cc-4372-0e02-c10bb2c3d479",
|
|
} {
|
|
if _, err := sqlxDB.Exec(`INSERT INTO tasks (id, parent_id) VALUES (?, 'parent-1')`, id); err != nil {
|
|
t.Fatalf("insert %s: %v", id, err)
|
|
}
|
|
}
|
|
|
|
frag := OrderedIDConcat(SQLite3, "parent_id = 'parent-1'")
|
|
var got string
|
|
if err := sqlxDB.QueryRowxContext(context.Background(), "SELECT "+frag).Scan(&got); err != nil {
|
|
t.Fatalf("query: %v", err)
|
|
}
|
|
|
|
want := "0e02b2c3-58cc-4372-a567-f47ac10bd479,a567f47a-58cc-4372-0e02-c10bb2c3d479,f47ac10b-58cc-4372-a567-0e02b2c3d479"
|
|
if got != want {
|
|
t.Fatalf("got %q, want %q", got, want)
|
|
}
|
|
}
|
|
|
|
// TestOrderedIDConcat_Postgres_OrdersAscendingByID is the PostgreSQL twin:
|
|
// AC-OFFICE-WAKE-WAVE-IDENTITY-001.13 names cross-dialect ordering
|
|
// divergence as a silent failure mode, so this asserts byte-identical
|
|
// ordering against the same UUID-shaped fixture the SQLite test uses, not
|
|
// sequential ids that would happen to sort the same under any collation.
|
|
// Skips unless KANDEV_TEST_POSTGRES_DSN is set.
|
|
func TestOrderedIDConcat_Postgres_OrdersAscendingByID(t *testing.T) {
|
|
dsn := testutil.PostgresDSNFromEnv(t)
|
|
sqlxDB := testutil.OpenIsolatedPostgres(t, dsn)
|
|
|
|
if _, err := sqlxDB.Exec(`CREATE TABLE tasks (id TEXT PRIMARY KEY, parent_id TEXT)`); err != nil {
|
|
t.Fatalf("create table: %v", err)
|
|
}
|
|
for _, id := range []string{
|
|
"f47ac10b-58cc-4372-a567-0e02b2c3d479",
|
|
"0e02b2c3-58cc-4372-a567-f47ac10bd479",
|
|
"a567f47a-58cc-4372-0e02-c10bb2c3d479",
|
|
} {
|
|
if _, err := sqlxDB.Exec(sqlxDB.Rebind(
|
|
`INSERT INTO tasks (id, parent_id) VALUES (?, 'parent-1')`), id); err != nil {
|
|
t.Fatalf("insert %s: %v", id, err)
|
|
}
|
|
}
|
|
|
|
frag := OrderedIDConcat(PGX, "parent_id = 'parent-1'")
|
|
var got string
|
|
if err := sqlxDB.QueryRowxContext(context.Background(), "SELECT "+frag).Scan(&got); err != nil {
|
|
t.Fatalf("query: %v", err)
|
|
}
|
|
|
|
want := "0e02b2c3-58cc-4372-a567-f47ac10bd479,a567f47a-58cc-4372-0e02-c10bb2c3d479,f47ac10b-58cc-4372-a567-0e02b2c3d479"
|
|
if got != want {
|
|
t.Fatalf("got %q, want %q", got, want)
|
|
}
|
|
}
|