v / vlib / orm / orm_upsert_test.v
145 lines · 122 sloc · 2.48 KB · 7c20003ef32da0d40f84be5e732cee05fd17b263
Raw
1// vtest retry: 3
2// vtest build: present_sqlite3?
3import db.sqlite
4
5@[table: 'upsert_users']
6struct UpsertUser {
7mut:
8 id int @[primary; sql: serial]
9 username string @[unique]
10 age int
11}
12
13@[table: 'upsert_configs']
14@[unique_key: 'scope, key']
15struct UpsertConfig {
16mut:
17 id int @[primary; sql: serial]
18 scope string
19 key string
20 value string
21}
22
23@[table: 'ambiguous_upsert_users']
24struct AmbiguousUpsertUser {
25mut:
26 id int @[primary]
27 username string @[unique]
28 note string
29}
30
31fn test_upsert_updates_existing_row_using_unique_field() {
32 mut db := sqlite.connect(':memory:') or { panic(err) }
33 defer {
34 db.close() or {}
35 }
36
37 sql db {
38 create table UpsertUser
39 }!
40
41 first := UpsertUser{
42 username: 'alice'
43 age: 30
44 }
45 second := UpsertUser{
46 username: 'alice'
47 age: 31
48 }
49
50 sql db {
51 upsert first into UpsertUser
52 upsert second into UpsertUser
53 }!
54
55 rows := sql db {
56 select from UpsertUser where username == 'alice'
57 }!
58
59 assert rows.len == 1
60 assert rows[0].username == 'alice'
61 assert rows[0].age == 31
62 assert rows[0].id == 1
63}
64
65fn test_upsert_updates_existing_row_using_composite_unique_key() {
66 mut db := sqlite.connect(':memory:') or { panic(err) }
67 defer {
68 db.close() or {}
69 }
70
71 sql db {
72 create table UpsertConfig
73 }!
74
75 first := UpsertConfig{
76 scope: 'web'
77 key: 'theme'
78 value: 'light'
79 }
80 second := UpsertConfig{
81 scope: 'web'
82 key: 'theme'
83 value: 'dark'
84 }
85
86 sql db {
87 upsert first into UpsertConfig
88 upsert second into UpsertConfig
89 }!
90
91 rows := sql db {
92 select from UpsertConfig where scope == 'web' && key == 'theme'
93 }!
94
95 assert rows.len == 1
96 assert rows[0].value == 'dark'
97 assert rows[0].id == 1
98}
99
100fn test_upsert_errors_when_conflict_groups_match_multiple_rows() {
101 mut db := sqlite.connect(':memory:') or { panic(err) }
102 defer {
103 db.close() or {}
104 }
105
106 sql db {
107 create table AmbiguousUpsertUser
108 }!
109
110 first := AmbiguousUpsertUser{
111 id: 1
112 username: 'alice'
113 note: 'first'
114 }
115 second := AmbiguousUpsertUser{
116 id: 2
117 username: 'bob'
118 note: 'second'
119 }
120
121 sql db {
122 insert first into AmbiguousUpsertUser
123 insert second into AmbiguousUpsertUser
124 }!
125
126 ambiguous := AmbiguousUpsertUser{
127 id: 1
128 username: 'bob'
129 note: 'updated'
130 }
131
132 mut got_error := false
133 sql db {
134 upsert ambiguous into AmbiguousUpsertUser
135 } or { got_error = true }
136
137 assert got_error
138
139 rows := sql db {
140 select from AmbiguousUpsertUser order by id
141 }!
142 assert rows.len == 2
143 assert rows[0].note == 'first'
144 assert rows[1].note == 'second'
145}
146