package db import "testing" // These pin the exact SQL each dialect generates. The MySQL side is the part we // can't exercise against a live server without docker, so asserting the strings // here proves MySQL output is byte-for-byte what the store layer used before the // refactor (the SQLite half is additionally exercised against a real engine). func TestMySQLDialect_SQL(t *testing.T) { d := MySQLDialect{} if got := d.LockForUpdate(); got != "FOR UPDATE" { t.Errorf("LockForUpdate = %q, want %q", got, "FOR UPDATE") } // No-op upsert (insert-or-ignore) — matches the old provision_idempotency SQL. if got := d.Upsert([]string{"idempotency_key"}); got != "ON DUPLICATE KEY UPDATE idempotency_key = idempotency_key" { t.Errorf("noop upsert = %q", got) } // Accumulate upsert — EXCLUDED.col must rewrite to VALUES(col). got := d.Upsert([]string{"user_id", "date"}, "bytes_up = bytes_up + EXCLUDED.bytes_up", "minutes_used = minutes_used + EXCLUDED.minutes_used") want := "ON DUPLICATE KEY UPDATE bytes_up = bytes_up + VALUES(bytes_up), minutes_used = minutes_used + VALUES(minutes_used)" if got != want { t.Errorf("accumulate upsert:\n got=%q\nwant=%q", got, want) } // version bump if got := d.Upsert([]string{"id"}, "version = version + 1"); got != "ON DUPLICATE KEY UPDATE version = version + 1" { t.Errorf("bump upsert = %q", got) } } func TestSQLiteDialect_SQL(t *testing.T) { d := SQLiteDialect{} if got := d.LockForUpdate(); got != "" { t.Errorf("LockForUpdate = %q, want empty (BEGIN IMMEDIATE handles locking)", got) } if got := d.Upsert([]string{"idempotency_key"}); got != "ON CONFLICT(idempotency_key) DO NOTHING" { t.Errorf("noop upsert = %q", got) } got := d.Upsert([]string{"user_id", "date"}, "bytes_up = bytes_up + EXCLUDED.bytes_up", "minutes_used = minutes_used + EXCLUDED.minutes_used") want := "ON CONFLICT(user_id, date) DO UPDATE SET bytes_up = bytes_up + EXCLUDED.bytes_up, minutes_used = minutes_used + EXCLUDED.minutes_used" if got != want { t.Errorf("accumulate upsert:\n got=%q\nwant=%q", got, want) } if got := d.Upsert([]string{"id"}, "version = version + 1"); got != "ON CONFLICT(id) DO UPDATE SET version = version + 1" { t.Errorf("bump upsert = %q", got) } } func TestDialectFor(t *testing.T) { if DialectFor("mysql").Name() != "mysql" { t.Error("DialectFor(mysql)") } if DialectFor("sqlite").Name() != "sqlite" { t.Error("DialectFor(sqlite)") } if DialectFor("").Name() != "mysql" { t.Error("DialectFor(empty) should default to mysql") } }