Skip to content

Commit 295535f

Browse files
committed
Test functional query builders
1 parent 279942d commit 295535f

File tree

1 file changed

+163
-0
lines changed

1 file changed

+163
-0
lines changed

database/optionally_test.go

Lines changed: 163 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,163 @@
1+
package database
2+
3+
import (
4+
"github.com/creasty/defaults"
5+
"github.com/icinga/icinga-go-library/logging"
6+
"github.com/stretchr/testify/assert"
7+
"github.com/stretchr/testify/require"
8+
"go.uber.org/zap/zaptest"
9+
"testing"
10+
"time"
11+
)
12+
13+
// testEntity represents a mock structure for Entity.
14+
type testEntity struct {
15+
Id ID `db:"id"`
16+
Name string `db:"name"`
17+
}
18+
19+
func (t *testEntity) TableName() string { return "test_subject" }
20+
func (t *testEntity) PgsqlOnConflictConstraint() string { return "pgsql_constrainter" }
21+
22+
func TestFunctionalQueries(t *testing.T) {
23+
t.Parallel()
24+
25+
t.Run("MySQL/MariaDB", func(t *testing.T) {
26+
t.Parallel()
27+
28+
c := &Config{}
29+
require.NoError(t, defaults.Set(c), "applying config default should not fail")
30+
31+
db, err := NewDbFromConfig(c, logging.NewLogger(zaptest.NewLogger(t).Sugar(), time.Minute), RetryConnectorCallbacks{})
32+
require.NoError(t, err)
33+
require.Equal(t, MySQL, db.DriverName())
34+
35+
runFunctionalTests(t, db)
36+
})
37+
t.Run("PostgreSQL", func(t *testing.T) {
38+
t.Parallel()
39+
40+
c := &Config{Type: "pgsql"}
41+
require.NoError(t, defaults.Set(c), "applying config default should not fail")
42+
43+
db, err := NewDbFromConfig(c, logging.NewLogger(zaptest.NewLogger(t).Sugar(), time.Minute), RetryConnectorCallbacks{})
44+
require.NoError(t, err)
45+
require.Equal(t, PostgreSQL, db.DriverName())
46+
47+
runFunctionalTests(t, db)
48+
})
49+
}
50+
51+
func runFunctionalTests(t *testing.T, db *DB) {
52+
t.Run("WithStatement", func(t *testing.T) {
53+
t.Parallel()
54+
55+
subject := &testEntity{}
56+
57+
q := NewInsert(db, subject, WithStatement("INSERT INTO test_subject (id, name) VALUES (:id, :name)", 2)).(*queryable)
58+
stmt, placeholders := q.buildStmt()
59+
assert.Equal(t, 2, placeholders)
60+
assert.Equal(t, "INSERT INTO test_subject (id, name) VALUES (:id, :name)", stmt)
61+
62+
var upsert string
63+
if db.DriverName() == PostgreSQL {
64+
upsert = "INSERT INTO test_subject (id, name) VALUES (:id, :name) ON CONFLICT ON CONSTRAINT pgsql_constrainter DO UPDATE SET name = EXCLUDED.name"
65+
} else {
66+
upsert = "INSERT INTO test_subject (id, name) VALUES (:id, :name) ON DUPLICATE KEY UPDATE name = VALUES(name)"
67+
}
68+
q = NewUpsert(db, subject, WithStatement(upsert, 2)).(*queryable)
69+
stmt, placeholders = q.buildStmt()
70+
assert.Equal(t, 2, placeholders)
71+
assert.Equal(t, upsert, stmt)
72+
73+
q = NewUpdate(db, subject, WithStatement("UPDATE test_subject SET name = :name WHERE id = :id", 0)).(*queryable)
74+
stmt, placeholders = q.buildStmt()
75+
assert.Equal(t, 0, placeholders)
76+
assert.Equal(t, "UPDATE test_subject SET name = :name WHERE id = :id", stmt)
77+
78+
q = NewDelete(db, subject, WithStatement("DELETE FROM test_subject WHERE id = :id", 1)).(*queryable)
79+
stmt, placeholders = q.buildStmt()
80+
assert.Equal(t, 1, placeholders)
81+
assert.Equal(t, "DELETE FROM test_subject WHERE id = :id", stmt)
82+
})
83+
84+
t.Run("WithColumns", func(t *testing.T) {
85+
t.Parallel()
86+
87+
subject := &testEntity{}
88+
89+
q := NewInsert(db, subject, WithColumns("name")).(*queryable)
90+
stmt, placeholders := q.buildStmt()
91+
assert.Equal(t, 1, placeholders)
92+
assert.Equal(t, "INSERT INTO \"test_subject\" (\"name\") VALUES (:name)", stmt)
93+
94+
q = NewUpsert(db, subject, WithColumns("name")).(*queryable)
95+
stmt, placeholders = q.buildStmt()
96+
assert.Equal(t, 1, placeholders)
97+
if db.DriverName() == PostgreSQL {
98+
assert.Equal(t, "INSERT INTO \"test_subject\" (\"name\") VALUES (:name) ON CONFLICT ON CONSTRAINT pgsql_constrainter DO UPDATE SET \"name\" = EXCLUDED.\"name\"", stmt)
99+
} else {
100+
assert.Equal(t, "INSERT INTO \"test_subject\" (\"name\") VALUES (:name) ON DUPLICATE KEY UPDATE \"name\" = VALUES(\"name\")", stmt)
101+
}
102+
103+
q = NewUpdate(db, subject, WithColumns("name")).(*queryable)
104+
stmt, placeholders = q.buildStmt()
105+
assert.Equal(t, 0, placeholders)
106+
assert.Equal(t, "UPDATE \"test_subject\" SET \"name\" = :name WHERE \"id\" = :id", stmt)
107+
})
108+
109+
t.Run("WithoutColumns", func(t *testing.T) {
110+
t.Parallel()
111+
112+
subject := &testEntity{}
113+
114+
q := NewInsert(db, subject, WithoutColumns("id")).(*queryable)
115+
stmt, placeholders := q.buildStmt()
116+
assert.Equal(t, 1, placeholders)
117+
assert.Equal(t, "INSERT INTO \"test_subject\" (\"name\") VALUES (:name)", stmt)
118+
119+
q = NewUpsert(db, subject, WithoutColumns("id")).(*queryable)
120+
stmt, placeholders = q.buildStmt()
121+
assert.Equal(t, 1, placeholders)
122+
if db.DriverName() == PostgreSQL {
123+
assert.Equal(t, "INSERT INTO \"test_subject\" (\"name\") VALUES (:name) ON CONFLICT ON CONSTRAINT pgsql_constrainter DO UPDATE SET \"name\" = EXCLUDED.\"name\"", stmt)
124+
} else {
125+
assert.Equal(t, "INSERT INTO \"test_subject\" (\"name\") VALUES (:name) ON DUPLICATE KEY UPDATE \"name\" = VALUES(\"name\")", stmt)
126+
}
127+
128+
q = NewUpdate(db, subject, WithoutColumns("id")).(*queryable)
129+
stmt, placeholders = q.buildStmt()
130+
assert.Equal(t, 0, placeholders)
131+
assert.Equal(t, "UPDATE \"test_subject\" SET \"name\" = :name WHERE \"id\" = :id", stmt)
132+
})
133+
134+
t.Run("WithByColumns", func(t *testing.T) {
135+
t.Parallel()
136+
137+
subject := &testEntity{}
138+
139+
q := NewUpdate(db, subject, WithoutColumns("id"), WithByColumn("name")).(*queryable)
140+
stmt, placeholders := q.buildStmt()
141+
assert.Equal(t, 0, placeholders)
142+
assert.Equal(t, "UPDATE \"test_subject\" SET \"name\" = :name WHERE \"name\" = :name", stmt)
143+
144+
q = NewDelete(db, subject, WithByColumn("name")).(*queryable)
145+
stmt, placeholders = q.buildStmt()
146+
assert.Equal(t, 0, placeholders)
147+
assert.Equal(t, "DELETE FROM \"test_subject\" WHERE \"name\" IN (?)", stmt)
148+
})
149+
150+
t.Run("WithIgnoreOnError", func(t *testing.T) {
151+
t.Parallel()
152+
153+
if db.DriverName() != PostgreSQL {
154+
t.Skipf("Skipping IgnoreOnError test case for %q driver", db.DriverName())
155+
}
156+
157+
subject := &testEntity{}
158+
q := NewInsert(db, subject, WithColumns("id", "name"), WithIgnoreOnError()).(*queryable)
159+
stmt, placeholders := q.buildStmt()
160+
assert.Equal(t, 2, placeholders)
161+
assert.Equal(t, "INSERT INTO \"test_subject\" (\"id\", \"name\") VALUES (:id, :name) ON CONFLICT ON CONSTRAINT pgsql_constrainter DO NOTHING", stmt)
162+
})
163+
}

0 commit comments

Comments
 (0)