v2 / vlib / orm / orm_dynamic_test.v
317 lines · 275 sloc · 5.32 KB · ff1f157b0654ea116dd24a27aa1af126eae5e30b
Raw
1// vtest retry: 3
2import db.sqlite
3
4@[table: 'dynamic_members']
5struct DynamicMember {
6mut:
7 id int @[primary; sql: serial]
8 name string
9 email string
10 age int
11 status string
12}
13
14struct DynamicMemberFilter {
15 name ?string
16}
17
18@[table: 'dynamic_cast_members']
19struct DynamicCastMember {
20mut:
21 id int @[primary; sql: serial]
22 name string
23 is_required u8
24}
25
26fn test_dynamic_select_with_inline_where_block() {
27 mut db := sqlite.connect(':memory:')!
28 defer {
29 db.close() or { panic(err) }
30 }
31
32 sql db {
33 create table DynamicMember
34 }!
35
36 first := DynamicMember{
37 name: 'Alice'
38 email: '[email protected]'
39 age: 31
40 status: 'active'
41 }
42 second := DynamicMember{
43 name: 'Bob'
44 email: '[email protected]'
45 age: 24
46 status: 'pending'
47 }
48 third := DynamicMember{
49 name: 'Alice'
50 email: '[email protected]'
51 age: 19
52 status: 'inactive'
53 }
54
55 sql db {
56 insert first into DynamicMember
57 insert second into DynamicMember
58 insert third into DynamicMember
59 }!
60
61 name_filter := 'Alice'
62 min_age := 30
63 status_filter := ''
64
65 rows := sql db {
66 dynamic select from DynamicMember where {
67 if name_filter != '' {
68 name == name_filter
69 },
70 if min_age > 0 {
71 age >= min_age
72 },
73 if status_filter != '' {
74 status == status_filter
75 }
76 } order by id
77 }!
78
79 assert rows.len == 1
80 assert rows[0].name == 'Alice'
81 assert rows[0].email == '[email protected]'
82 assert rows[0].age == 31
83
84 filter := DynamicMemberFilter{
85 name: 'Alice'
86 }
87 where_expr := {
88 if name := filter.name {
89 name == name
90 }
91 }
92
93 guard_rows := sql db {
94 dynamic select from DynamicMember where where_expr
95 }!
96
97 assert guard_rows.len == 2
98}
99
100fn test_dynamic_update_with_alias_set_block() {
101 mut db := sqlite.connect(':memory:')!
102 defer {
103 db.close() or { panic(err) }
104 }
105
106 sql db {
107 create table DynamicMember
108 }!
109
110 member := DynamicMember{
111 name: 'Alice'
112 email: '[email protected]'
113 age: 31
114 status: 'active'
115 }
116
117 sql db {
118 insert member into DynamicMember
119 }!
120
121 id := db.last_id()
122 next_name := 'Alicia'
123 next_email := ''
124 next_status := 'inactive'
125 update_expr := {
126 if next_name != '' {
127 name == next_name
128 },
129 if next_email != '' {
130 email == next_email
131 },
132 status == next_status
133 }
134
135 sql db {
136 dynamic update DynamicMember set update_expr where id == id
137 }!
138
139 rows := sql db {
140 select from DynamicMember where id == id
141 }!
142
143 assert rows.len == 1
144 assert rows[0].name == next_name
145 assert rows[0].email == '[email protected]'
146 assert rows[0].status == next_status
147}
148
149fn test_dynamic_update_with_alias_set_block_cast_expr() {
150 mut db := sqlite.connect(':memory:')!
151 defer {
152 db.close() or { panic(err) }
153 }
154
155 sql db {
156 create table DynamicCastMember
157 }!
158
159 member := DynamicCastMember{
160 name: 'Alice'
161 is_required: 0
162 }
163
164 sql db {
165 insert member into DynamicCastMember
166 }!
167
168 id := db.last_id()
169 next_name := 'Alicia'
170 next_required := true
171 filter := DynamicMemberFilter{
172 name: next_name
173 }
174 update_expr := {
175 if name := filter.name {
176 name == name
177 },
178 is_required == u8(if next_required { 1 } else { 0 })
179 }
180
181 sql db {
182 dynamic update DynamicCastMember set update_expr where id == id
183 }!
184
185 rows := sql db {
186 select from DynamicCastMember where id == id
187 }!
188
189 assert rows.len == 1
190 assert rows[0].name == next_name
191 assert rows[0].is_required == 1
192}
193
194fn test_dynamic_select_with_in_operator_and_additional_condition() {
195 mut db := sqlite.connect(':memory:')!
196 defer {
197 db.close() or { panic(err) }
198 }
199
200 sql db {
201 create table DynamicMember
202 }!
203
204 members := [
205 DynamicMember{
206 name: 'Alice'
207 email: '[email protected]'
208 age: 31
209 status: 'active'
210 },
211 DynamicMember{
212 name: 'Bob'
213 email: '[email protected]'
214 age: 24
215 status: 'pending'
216 },
217 DynamicMember{
218 name: 'Charlie'
219 email: '[email protected]'
220 age: 29
221 status: 'active'
222 },
223 DynamicMember{
224 name: 'Diana'
225 email: '[email protected]'
226 age: 35
227 status: 'inactive'
228 },
229 DynamicMember{
230 name: 'Eve'
231 email: '[email protected]'
232 age: 22
233 status: 'pending'
234 },
235 ]
236
237 for member in members {
238 sql db {
239 insert member into DynamicMember
240 }!
241 }
242
243 valid_names := ['Alice', 'Charlie', 'Eve']
244 min_age := 25
245
246 rows := sql db {
247 dynamic select from DynamicMember where {
248 if valid_names.len > 0 {
249 name in valid_names
250 },
251 if min_age > 0 {
252 age >= min_age
253 }
254 } order by id
255 }!
256
257 assert rows.len == 2
258 assert rows[0].name == 'Alice'
259 assert rows[0].age == 31
260 assert rows[1].name == 'Charlie'
261 assert rows[1].age == 29
262}
263
264fn test_dynamic_select_with_explicit_order_by_asc() {
265 mut db := sqlite.connect(':memory:')!
266 defer {
267 db.close() or { panic(err) }
268 }
269
270 sql db {
271 create table DynamicMember
272 }!
273
274 members := [
275 DynamicMember{
276 name: 'Alice'
277 email: '[email protected]'
278 age: 31
279 status: 'active'
280 },
281 DynamicMember{
282 name: 'Bob'
283 email: '[email protected]'
284 age: 19
285 status: 'pending'
286 },
287 DynamicMember{
288 name: 'Charlie'
289 email: '[email protected]'
290 age: 44
291 status: 'inactive'
292 },
293 ]
294
295 for member in members {
296 sql db {
297 insert member into DynamicMember
298 }!
299 }
300
301 min_age := 19
302 // vfmt off
303 rows := sql db {
304 dynamic select from DynamicMember where {
305 if min_age > 0 {
306 age >= min_age
307 }
308 } order by age asc limit 2
309 }!
310 // vfmt on
311
312 assert rows.len == 2
313 assert rows[0].name == 'Bob'
314 assert rows[0].age == 19
315 assert rows[1].name == 'Alice'
316 assert rows[1].age == 31
317}
318