Skip to content

Commit 54087de

Browse files
authored
test(contrib/drivers/pgsql): add Builder/Subquery/Join/Struct tests (gogf#4680)
## Summary - Port MySQL test coverage for Builder, Subquery, Join, and Struct features to PgSQL driver - Add 4 new test files with 23 test functions covering builder patterns, subquery WHERE/HAVING/Model, all JOIN types, and struct scanning - PgSQL dialect adaptations: double-quoted identifiers, GROUP BY with HAVING, letter-prefixed table names, int64 id assertions, removed `Uid` field ## Test plan - [x] Builder tests pass: `go test -v -run "Test_Model_Builder|Test_Safe_Builder" -count=1` - [x] Subquery tests pass: `go test -v -run "Test_Model_SubQuery" -count=1` - [x] Join tests pass: `go test -v -run "Test_Model_.*Join.*|Test_Model_FieldsPrefix" -count=1` - [x] Struct tests pass: `go test -v -run "Test_Model_Embedded|Test_Struct|Test_Structs|Test_Model_Scan|Test_Scan_Auto" -count=1` - [x] Full PgSQL test suite: 113/113 PASS ref gogf#4689
1 parent fc39fff commit 54087de

4 files changed

Lines changed: 861 additions & 0 deletions
Lines changed: 141 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,141 @@
1+
// Copyright GoFrame Author(https://goframe.org). All Rights Reserved.
2+
//
3+
// This Source Code Form is subject to the terms of the MIT License.
4+
// If a copy of the MIT was not distributed with this file,
5+
// You can obtain one at https://github.com/gogf/gf.
6+
7+
package pgsql_test
8+
9+
import (
10+
"testing"
11+
12+
"github.com/gogf/gf/v2/encoding/gjson"
13+
"github.com/gogf/gf/v2/frame/g"
14+
"github.com/gogf/gf/v2/os/gtime"
15+
"github.com/gogf/gf/v2/test/gtest"
16+
"github.com/gogf/gf/v2/util/gmeta"
17+
)
18+
19+
func Test_Model_Builder(t *testing.T) {
20+
table := createInitTable()
21+
defer dropTable(table)
22+
23+
gtest.C(t, func(t *gtest.T) {
24+
m := db.Model(table)
25+
b := m.Builder()
26+
27+
all, err := m.Where(
28+
b.Where("id", g.Slice{1, 2, 3}).WhereOr("id", g.Slice{4, 5, 6}),
29+
).All()
30+
t.AssertNil(err)
31+
t.Assert(len(all), 6)
32+
})
33+
34+
// Where And
35+
gtest.C(t, func(t *gtest.T) {
36+
m := db.Model(table)
37+
b := m.Builder()
38+
39+
all, err := m.Where(
40+
b.Where("id", g.Slice{1, 2, 3}).WhereOr("id", g.Slice{4, 5, 6}),
41+
).Where(
42+
b.Where("id", g.Slice{2, 3}).WhereOr("id", g.Slice{5, 6}),
43+
).Where(
44+
b.Where("id", g.Slice{3}).Where("id", g.Slice{1, 2, 3}),
45+
).All()
46+
t.AssertNil(err)
47+
t.Assert(len(all), 1)
48+
})
49+
50+
// Where Or
51+
gtest.C(t, func(t *gtest.T) {
52+
m := db.Model(table)
53+
b := m.Builder()
54+
55+
all, err := m.WhereOr(
56+
b.Where("id", g.Slice{1, 2, 3}).WhereOr("id", g.Slice{4, 5, 6}),
57+
).WhereOr(
58+
b.Where("id", g.Slice{2, 3}).WhereOr("id", g.Slice{5, 6}),
59+
).WhereOr(
60+
b.Where("id", g.Slice{3}).Where("id", g.Slice{1, 2, 3}),
61+
).All()
62+
t.AssertNil(err)
63+
t.Assert(len(all), 6)
64+
})
65+
66+
// Where with struct which has a field type of *gtime.Time
67+
gtest.C(t, func(t *gtest.T) {
68+
m := db.Model(table)
69+
b := m.Builder()
70+
71+
type Query struct {
72+
Id any
73+
Nickname *gtime.Time
74+
}
75+
76+
where, args := b.Where(&Query{Id: 1}).Build()
77+
t.Assert(where, `"id"=? AND "nickname" IS NULL`)
78+
t.Assert(args, []any{1})
79+
})
80+
81+
// Where with struct which has a field type of *gjson.Json
82+
gtest.C(t, func(t *gtest.T) {
83+
m := db.Model(table)
84+
b := m.Builder()
85+
86+
type Query struct {
87+
Id any
88+
Nickname *gjson.Json
89+
}
90+
91+
where, args := b.Where(&Query{Id: 1}).Build()
92+
t.Assert(where, `"id"=? AND "nickname" IS NULL`)
93+
t.Assert(args, []any{1})
94+
})
95+
96+
// Where with do struct which has a field type of *gtime.Time and generated by gf cli
97+
gtest.C(t, func(t *gtest.T) {
98+
m := db.Model(table)
99+
b := m.Builder()
100+
101+
type Query struct {
102+
gmeta.Meta `orm:"do:true"`
103+
Id any
104+
Nickname *gtime.Time
105+
}
106+
107+
where, args := b.Where(&Query{Id: 1}).Build()
108+
t.Assert(where, `"id"=?`)
109+
t.Assert(args, []any{1})
110+
})
111+
112+
// Where with do struct which has a field type of *gjson.Json and generated by gf cli
113+
gtest.C(t, func(t *gtest.T) {
114+
m := db.Model(table)
115+
b := m.Builder()
116+
117+
type Query struct {
118+
gmeta.Meta `orm:"do:true"`
119+
Id any
120+
Nickname *gjson.Json
121+
}
122+
123+
where, args := b.Where(&Query{Id: 1}).Build()
124+
t.Assert(where, `"id"=?`)
125+
t.Assert(args, []any{1})
126+
})
127+
}
128+
129+
func Test_Safe_Builder(t *testing.T) {
130+
// test whether m.Builder() is chain safe
131+
gtest.C(t, func(t *gtest.T) {
132+
b := db.Model().Builder()
133+
b.Where("id", 1)
134+
_, args := b.Build()
135+
t.AssertNil(args)
136+
137+
b = b.Where("id", 1)
138+
_, args = b.Build()
139+
t.Assert(args, g.Slice{1})
140+
})
141+
}
Lines changed: 177 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,177 @@
1+
// Copyright GoFrame Author(https://goframe.org). All Rights Reserved.
2+
//
3+
// This Source Code Form is subject to the terms of the MIT License.
4+
// If a copy of the MIT was not distributed with this file,
5+
// You can obtain one at https://github.com/gogf/gf.
6+
7+
package pgsql_test
8+
9+
import (
10+
"testing"
11+
12+
"github.com/gogf/gf/v2/frame/g"
13+
"github.com/gogf/gf/v2/os/gtime"
14+
"github.com/gogf/gf/v2/test/gtest"
15+
)
16+
17+
func Test_Model_LeftJoinOnField(t *testing.T) {
18+
var (
19+
table1 = "t_" + gtime.TimestampNanoStr() + "_table1"
20+
table2 = "t_" + gtime.TimestampNanoStr() + "_table2"
21+
)
22+
createInitTable(table1)
23+
defer dropTable(table1)
24+
createInitTable(table2)
25+
defer dropTable(table2)
26+
27+
gtest.C(t, func(t *gtest.T) {
28+
r, err := db.Model(table1).
29+
FieldsPrefix(table1, "*").
30+
LeftJoinOnField(table2, "id").
31+
WhereIn("id", g.Slice{1, 2}).
32+
Order("id asc").All()
33+
t.AssertNil(err)
34+
t.Assert(len(r), 2)
35+
t.Assert(r[0]["id"], 1)
36+
t.Assert(r[1]["id"], 2)
37+
})
38+
}
39+
40+
func Test_Model_RightJoinOnField(t *testing.T) {
41+
var (
42+
table1 = "t_" + gtime.TimestampNanoStr() + "_table1"
43+
table2 = "t_" + gtime.TimestampNanoStr() + "_table2"
44+
)
45+
createInitTable(table1)
46+
defer dropTable(table1)
47+
createInitTable(table2)
48+
defer dropTable(table2)
49+
50+
gtest.C(t, func(t *gtest.T) {
51+
r, err := db.Model(table1).
52+
FieldsPrefix(table1, "*").
53+
RightJoinOnField(table2, "id").
54+
WhereIn("id", g.Slice{1, 2}).
55+
Order("id asc").All()
56+
t.AssertNil(err)
57+
t.Assert(len(r), 2)
58+
t.Assert(r[0]["id"], 1)
59+
t.Assert(r[1]["id"], 2)
60+
})
61+
}
62+
63+
func Test_Model_InnerJoinOnField(t *testing.T) {
64+
var (
65+
table1 = "t_" + gtime.TimestampNanoStr() + "_table1"
66+
table2 = "t_" + gtime.TimestampNanoStr() + "_table2"
67+
)
68+
createInitTable(table1)
69+
defer dropTable(table1)
70+
createInitTable(table2)
71+
defer dropTable(table2)
72+
73+
gtest.C(t, func(t *gtest.T) {
74+
r, err := db.Model(table1).
75+
FieldsPrefix(table1, "*").
76+
InnerJoinOnField(table2, "id").
77+
WhereIn("id", g.Slice{1, 2}).
78+
Order("id asc").All()
79+
t.AssertNil(err)
80+
t.Assert(len(r), 2)
81+
t.Assert(r[0]["id"], 1)
82+
t.Assert(r[1]["id"], 2)
83+
})
84+
}
85+
86+
func Test_Model_LeftJoinOnFields(t *testing.T) {
87+
var (
88+
table1 = "t_" + gtime.TimestampNanoStr() + "_table1"
89+
table2 = "t_" + gtime.TimestampNanoStr() + "_table2"
90+
)
91+
createInitTable(table1)
92+
defer dropTable(table1)
93+
createInitTable(table2)
94+
defer dropTable(table2)
95+
96+
gtest.C(t, func(t *gtest.T) {
97+
r, err := db.Model(table1).
98+
FieldsPrefix(table1, "*").
99+
LeftJoinOnFields(table2, "id", "=", "id").
100+
WhereIn("id", g.Slice{1, 2}).
101+
Order("id asc").All()
102+
t.AssertNil(err)
103+
t.Assert(len(r), 2)
104+
t.Assert(r[0]["id"], 1)
105+
t.Assert(r[1]["id"], 2)
106+
})
107+
}
108+
109+
func Test_Model_RightJoinOnFields(t *testing.T) {
110+
var (
111+
table1 = "t_" + gtime.TimestampNanoStr() + "_table1"
112+
table2 = "t_" + gtime.TimestampNanoStr() + "_table2"
113+
)
114+
createInitTable(table1)
115+
defer dropTable(table1)
116+
createInitTable(table2)
117+
defer dropTable(table2)
118+
119+
gtest.C(t, func(t *gtest.T) {
120+
r, err := db.Model(table1).
121+
FieldsPrefix(table1, "*").
122+
RightJoinOnFields(table2, "id", "=", "id").
123+
WhereIn("id", g.Slice{1, 2}).
124+
Order("id asc").All()
125+
t.AssertNil(err)
126+
t.Assert(len(r), 2)
127+
t.Assert(r[0]["id"], 1)
128+
t.Assert(r[1]["id"], 2)
129+
})
130+
}
131+
132+
func Test_Model_InnerJoinOnFields(t *testing.T) {
133+
var (
134+
table1 = "t_" + gtime.TimestampNanoStr() + "_table1"
135+
table2 = "t_" + gtime.TimestampNanoStr() + "_table2"
136+
)
137+
createInitTable(table1)
138+
defer dropTable(table1)
139+
createInitTable(table2)
140+
defer dropTable(table2)
141+
142+
gtest.C(t, func(t *gtest.T) {
143+
r, err := db.Model(table1).
144+
FieldsPrefix(table1, "*").
145+
InnerJoinOnFields(table2, "id", "=", "id").
146+
WhereIn("id", g.Slice{1, 2}).
147+
Order("id asc").All()
148+
t.AssertNil(err)
149+
t.Assert(len(r), 2)
150+
t.Assert(r[0]["id"], 1)
151+
t.Assert(r[1]["id"], 2)
152+
})
153+
}
154+
155+
func Test_Model_FieldsPrefix(t *testing.T) {
156+
var (
157+
table1 = "t_" + gtime.TimestampNanoStr() + "_table1"
158+
table2 = "t_" + gtime.TimestampNanoStr() + "_table2"
159+
)
160+
createInitTable(table1)
161+
defer dropTable(table1)
162+
createInitTable(table2)
163+
defer dropTable(table2)
164+
165+
gtest.C(t, func(t *gtest.T) {
166+
r, err := db.Model(table1).
167+
FieldsPrefix(table1, "id").
168+
FieldsPrefix(table2, "nickname").
169+
LeftJoinOnField(table2, "id").
170+
WhereIn("id", g.Slice{1, 2}).
171+
Order("id asc").All()
172+
t.AssertNil(err)
173+
t.Assert(len(r), 2)
174+
t.Assert(r[0]["id"], 1)
175+
t.Assert(r[0]["nickname"], "name_1")
176+
})
177+
}

0 commit comments

Comments
 (0)