130 lines
3.1 KiB
Go
130 lines
3.1 KiB
Go
package database
|
|
|
|
import (
|
|
"testing"
|
|
)
|
|
|
|
func TestQArgs_Postgres(t *testing.T) {
|
|
// Force Postgres dialect for test
|
|
CurrentDialect = DialectPostgres
|
|
defer func() { CurrentDialect = DialectSQLite }()
|
|
|
|
q, args := QArgs("SELECT * FROM t WHERE a = $1 AND b = $1", "val1")
|
|
if q != "SELECT * FROM t WHERE a = $1 AND b = $1" {
|
|
t.Errorf("Postgres: query should be unchanged, got %q", q)
|
|
}
|
|
if len(args) != 1 {
|
|
t.Errorf("Postgres: args should be unchanged, got %d", len(args))
|
|
}
|
|
}
|
|
|
|
func TestQArgs_SQLite_ReusedPlaceholder(t *testing.T) {
|
|
CurrentDialect = DialectSQLite
|
|
defer func() { CurrentDialect = DialectPostgres }()
|
|
|
|
// $1 appears twice — must be expanded to two ? with the same arg value
|
|
q, args := QArgs(
|
|
"SELECT COUNT(*) FROM channels c WHERE c.user_id = $1 OR c.id IN (SELECT channel_id FROM cp WHERE cp.user_id = $1) AND c.is_archived = $2",
|
|
"user-123", false,
|
|
)
|
|
|
|
// Should have 3 ? placeholders
|
|
qCount := 0
|
|
for _, c := range q {
|
|
if c == '?' {
|
|
qCount++
|
|
}
|
|
}
|
|
if qCount != 3 {
|
|
t.Errorf("expected 3 ? placeholders, got %d in %q", qCount, q)
|
|
}
|
|
|
|
// Should have 3 args: user-123, user-123, false
|
|
if len(args) != 3 {
|
|
t.Fatalf("expected 3 args, got %d: %v", len(args), args)
|
|
}
|
|
if args[0] != "user-123" {
|
|
t.Errorf("args[0] = %v, want user-123", args[0])
|
|
}
|
|
if args[1] != "user-123" {
|
|
t.Errorf("args[1] = %v, want user-123 (expanded from reused $1)", args[1])
|
|
}
|
|
if args[2] != false {
|
|
t.Errorf("args[2] = %v, want false", args[2])
|
|
}
|
|
|
|
// Should not contain $N
|
|
if contains(q, "$") {
|
|
t.Errorf("query still contains $: %q", q)
|
|
}
|
|
}
|
|
|
|
func TestQArgs_SQLite_NoReuse(t *testing.T) {
|
|
CurrentDialect = DialectSQLite
|
|
defer func() { CurrentDialect = DialectPostgres }()
|
|
|
|
q, args := QArgs("SELECT * FROM t WHERE a = $1 AND b = $2", "a", "b")
|
|
|
|
qCount := 0
|
|
for _, c := range q {
|
|
if c == '?' {
|
|
qCount++
|
|
}
|
|
}
|
|
if qCount != 2 {
|
|
t.Errorf("expected 2 ? placeholders, got %d", qCount)
|
|
}
|
|
if len(args) != 2 {
|
|
t.Errorf("expected 2 args, got %d", len(args))
|
|
}
|
|
}
|
|
|
|
func TestQArgs_SQLite_ILIKE(t *testing.T) {
|
|
CurrentDialect = DialectSQLite
|
|
defer func() { CurrentDialect = DialectPostgres }()
|
|
|
|
q, _ := QArgs("SELECT * FROM t WHERE name ILIKE $1", "%test%")
|
|
if contains(q, "ILIKE") {
|
|
t.Errorf("ILIKE should be rewritten to LIKE: %q", q)
|
|
}
|
|
if !contains(q, "LIKE") {
|
|
t.Errorf("should contain LIKE: %q", q)
|
|
}
|
|
}
|
|
|
|
func TestQArgs_SQLite_HighPlaceholders(t *testing.T) {
|
|
CurrentDialect = DialectSQLite
|
|
defer func() { CurrentDialect = DialectPostgres }()
|
|
|
|
q, args := QArgs(
|
|
"INSERT INTO t (a,b,c,d,e,f,g,h,i,j,k) VALUES ($1,$2,$3,$4,$5,$6,$7,$8,$9,$10,$11)",
|
|
1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11,
|
|
)
|
|
|
|
qCount := 0
|
|
for _, c := range q {
|
|
if c == '?' {
|
|
qCount++
|
|
}
|
|
}
|
|
if qCount != 11 {
|
|
t.Errorf("expected 11 ?, got %d in %q", qCount, q)
|
|
}
|
|
if len(args) != 11 {
|
|
t.Errorf("expected 11 args, got %d", len(args))
|
|
}
|
|
// $10 and $11 should not be mangled
|
|
if contains(q, "$") {
|
|
t.Errorf("still contains $: %q", q)
|
|
}
|
|
}
|
|
|
|
func contains(s, substr string) bool {
|
|
for i := 0; i <= len(s)-len(substr); i++ {
|
|
if s[i:i+len(substr)] == substr {
|
|
return true
|
|
}
|
|
}
|
|
return false
|
|
}
|