pqb 0.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.d.ts +3630 -0
- package/dist/index.esm.js +4587 -0
- package/dist/index.esm.js.map +1 -0
- package/dist/index.js +4691 -0
- package/dist/index.js.map +1 -0
- package/package.json +59 -0
- package/rollup.config.js +35 -0
- package/src/adapter.test.ts +10 -0
- package/src/adapter.ts +171 -0
- package/src/columnSchema/array.ts +21 -0
- package/src/columnSchema/boolean.ts +10 -0
- package/src/columnSchema/columnType.test.ts +129 -0
- package/src/columnSchema/columnType.ts +77 -0
- package/src/columnSchema/columnTypes.ts +145 -0
- package/src/columnSchema/columnsSchema.test.ts +32 -0
- package/src/columnSchema/columnsSchema.ts +100 -0
- package/src/columnSchema/commonMethods.ts +130 -0
- package/src/columnSchema/dateTime.ts +104 -0
- package/src/columnSchema/enum.ts +13 -0
- package/src/columnSchema/index.ts +11 -0
- package/src/columnSchema/json/array.ts +55 -0
- package/src/columnSchema/json/discriminatedUnion.ts +91 -0
- package/src/columnSchema/json/enum.ts +29 -0
- package/src/columnSchema/json/instanceOf.ts +16 -0
- package/src/columnSchema/json/intersection.ts +23 -0
- package/src/columnSchema/json/lazy.ts +22 -0
- package/src/columnSchema/json/literal.ts +12 -0
- package/src/columnSchema/json/map.ts +29 -0
- package/src/columnSchema/json/nativeEnum.ts +30 -0
- package/src/columnSchema/json/nullable.ts +33 -0
- package/src/columnSchema/json/nullish.ts +30 -0
- package/src/columnSchema/json/object.ts +206 -0
- package/src/columnSchema/json/optional.ts +28 -0
- package/src/columnSchema/json/record.ts +40 -0
- package/src/columnSchema/json/scalarTypes.ts +117 -0
- package/src/columnSchema/json/set.ts +34 -0
- package/src/columnSchema/json/tuple.ts +40 -0
- package/src/columnSchema/json/typeBase.ts +202 -0
- package/src/columnSchema/json/union.ts +16 -0
- package/src/columnSchema/json.ts +64 -0
- package/src/columnSchema/number.ts +122 -0
- package/src/columnSchema/string.ts +222 -0
- package/src/columnSchema/utils.ts +27 -0
- package/src/common.ts +86 -0
- package/src/db.test.ts +67 -0
- package/src/db.ts +212 -0
- package/src/errors.ts +7 -0
- package/src/index.ts +18 -0
- package/src/operators.test.ts +608 -0
- package/src/operators.ts +177 -0
- package/src/query.ts +292 -0
- package/src/queryDataUtils.ts +50 -0
- package/src/queryMethods/aggregate.test.ts +583 -0
- package/src/queryMethods/aggregate.ts +878 -0
- package/src/queryMethods/callbacks.test.ts +69 -0
- package/src/queryMethods/callbacks.ts +55 -0
- package/src/queryMethods/clear.test.ts +64 -0
- package/src/queryMethods/clear.ts +58 -0
- package/src/queryMethods/columnInfo.test.ts +45 -0
- package/src/queryMethods/columnInfo.ts +67 -0
- package/src/queryMethods/delete.test.ts +135 -0
- package/src/queryMethods/delete.ts +50 -0
- package/src/queryMethods/for.test.ts +57 -0
- package/src/queryMethods/for.ts +99 -0
- package/src/queryMethods/from.test.ts +66 -0
- package/src/queryMethods/from.ts +58 -0
- package/src/queryMethods/get.test.ts +66 -0
- package/src/queryMethods/get.ts +88 -0
- package/src/queryMethods/having.test.ts +247 -0
- package/src/queryMethods/having.ts +99 -0
- package/src/queryMethods/insert.test.ts +555 -0
- package/src/queryMethods/insert.ts +453 -0
- package/src/queryMethods/join.test.ts +150 -0
- package/src/queryMethods/join.ts +508 -0
- package/src/queryMethods/json.test.ts +398 -0
- package/src/queryMethods/json.ts +259 -0
- package/src/queryMethods/log.test.ts +172 -0
- package/src/queryMethods/log.ts +123 -0
- package/src/queryMethods/queryMethods.test.ts +629 -0
- package/src/queryMethods/queryMethods.ts +428 -0
- package/src/queryMethods/select.test.ts +479 -0
- package/src/queryMethods/select.ts +249 -0
- package/src/queryMethods/then.ts +236 -0
- package/src/queryMethods/transaction.test.ts +66 -0
- package/src/queryMethods/transaction.ts +66 -0
- package/src/queryMethods/union.test.ts +59 -0
- package/src/queryMethods/union.ts +89 -0
- package/src/queryMethods/update.test.ts +417 -0
- package/src/queryMethods/update.ts +350 -0
- package/src/queryMethods/upsert.test.ts +56 -0
- package/src/queryMethods/upsert.ts +43 -0
- package/src/queryMethods/where.test.ts +1594 -0
- package/src/queryMethods/where.ts +450 -0
- package/src/queryMethods/window.test.ts +66 -0
- package/src/queryMethods/window.ts +108 -0
- package/src/queryMethods/with.test.ts +191 -0
- package/src/queryMethods/with.ts +92 -0
- package/src/quote.ts +36 -0
- package/src/relations.ts +194 -0
- package/src/sql/aggregate.ts +80 -0
- package/src/sql/columnInfo.ts +22 -0
- package/src/sql/common.ts +42 -0
- package/src/sql/delete.ts +41 -0
- package/src/sql/distinct.ts +19 -0
- package/src/sql/fromAndAs.ts +51 -0
- package/src/sql/having.ts +140 -0
- package/src/sql/index.ts +2 -0
- package/src/sql/insert.ts +102 -0
- package/src/sql/join.ts +242 -0
- package/src/sql/orderBy.ts +41 -0
- package/src/sql/select.ts +153 -0
- package/src/sql/toSql.ts +153 -0
- package/src/sql/truncate.ts +13 -0
- package/src/sql/types.ts +355 -0
- package/src/sql/update.ts +62 -0
- package/src/sql/where.ts +314 -0
- package/src/sql/window.ts +38 -0
- package/src/sql/with.ts +32 -0
- package/src/test-utils.ts +172 -0
- package/src/utils.ts +140 -0
- package/tsconfig.build.json +6 -0
- package/tsconfig.json +8 -0
|
@@ -0,0 +1,555 @@
|
|
|
1
|
+
import {
|
|
2
|
+
AssertEqual,
|
|
3
|
+
expectMatchObjectWithTimestamps,
|
|
4
|
+
expectQueryNotMutated,
|
|
5
|
+
expectSql,
|
|
6
|
+
now,
|
|
7
|
+
User,
|
|
8
|
+
userData,
|
|
9
|
+
useTestDatabase,
|
|
10
|
+
} from '../test-utils';
|
|
11
|
+
import { raw } from '../common';
|
|
12
|
+
import { OnConflictQueryBuilder } from './insert';
|
|
13
|
+
|
|
14
|
+
describe('insert', () => {
|
|
15
|
+
useTestDatabase();
|
|
16
|
+
|
|
17
|
+
it('should insert with raw sql and list of columns', () => {
|
|
18
|
+
const q = User.all();
|
|
19
|
+
|
|
20
|
+
const query = q.insert({
|
|
21
|
+
columns: ['name', 'password'],
|
|
22
|
+
values: raw('raw sql'),
|
|
23
|
+
});
|
|
24
|
+
expectSql(
|
|
25
|
+
query.toSql(),
|
|
26
|
+
`
|
|
27
|
+
INSERT INTO "user"("name", "password")
|
|
28
|
+
VALUES raw sql
|
|
29
|
+
`,
|
|
30
|
+
);
|
|
31
|
+
|
|
32
|
+
const eq: AssertEqual<Awaited<typeof query>, number> = true;
|
|
33
|
+
expect(eq).toBe(true);
|
|
34
|
+
|
|
35
|
+
expectQueryNotMutated(q);
|
|
36
|
+
});
|
|
37
|
+
|
|
38
|
+
it('should insert one record, returning rows count', async () => {
|
|
39
|
+
const q = User.all();
|
|
40
|
+
|
|
41
|
+
const query = q.insert(userData);
|
|
42
|
+
expectSql(
|
|
43
|
+
query.toSql(),
|
|
44
|
+
`
|
|
45
|
+
INSERT INTO "user"("name", "password", "createdAt", "updatedAt")
|
|
46
|
+
VALUES ($1, $2, $3, $4)
|
|
47
|
+
`,
|
|
48
|
+
['name', 'password', now, now],
|
|
49
|
+
);
|
|
50
|
+
|
|
51
|
+
const result = await query;
|
|
52
|
+
expect(result).toBe(1);
|
|
53
|
+
|
|
54
|
+
const eq: AssertEqual<typeof result, number> = true;
|
|
55
|
+
expect(eq).toBe(true);
|
|
56
|
+
|
|
57
|
+
const inserted = await User.take();
|
|
58
|
+
expectMatchObjectWithTimestamps(inserted, userData);
|
|
59
|
+
|
|
60
|
+
expectQueryNotMutated(q);
|
|
61
|
+
});
|
|
62
|
+
|
|
63
|
+
it('should insert one record, returning value', async () => {
|
|
64
|
+
const q = User.all();
|
|
65
|
+
|
|
66
|
+
const query = q.get('id').insert(userData);
|
|
67
|
+
expectSql(
|
|
68
|
+
query.toSql(),
|
|
69
|
+
`
|
|
70
|
+
INSERT INTO "user"("name", "password", "createdAt", "updatedAt")
|
|
71
|
+
VALUES ($1, $2, $3, $4)
|
|
72
|
+
RETURNING "user"."id"
|
|
73
|
+
`,
|
|
74
|
+
['name', 'password', now, now],
|
|
75
|
+
);
|
|
76
|
+
|
|
77
|
+
const result = await query;
|
|
78
|
+
const eq: AssertEqual<typeof result, number> = true;
|
|
79
|
+
expect(eq).toBe(true);
|
|
80
|
+
|
|
81
|
+
expect(typeof result).toBe('number');
|
|
82
|
+
|
|
83
|
+
expectQueryNotMutated(q);
|
|
84
|
+
});
|
|
85
|
+
|
|
86
|
+
it('should insert one record, returning columns', async () => {
|
|
87
|
+
const q = User.all();
|
|
88
|
+
|
|
89
|
+
const query = q
|
|
90
|
+
.select('id', 'name', 'createdAt', 'updatedAt')
|
|
91
|
+
.insert(userData);
|
|
92
|
+
expectSql(
|
|
93
|
+
query.toSql(),
|
|
94
|
+
`
|
|
95
|
+
INSERT INTO "user"("name", "password", "createdAt", "updatedAt")
|
|
96
|
+
VALUES ($1, $2, $3, $4)
|
|
97
|
+
RETURNING "user"."id", "user"."name", "user"."createdAt", "user"."updatedAt"
|
|
98
|
+
`,
|
|
99
|
+
['name', 'password', now, now],
|
|
100
|
+
);
|
|
101
|
+
|
|
102
|
+
const result = await query;
|
|
103
|
+
const eq: AssertEqual<
|
|
104
|
+
typeof result,
|
|
105
|
+
{ id: number; name: string; createdAt: Date; updatedAt: Date }
|
|
106
|
+
> = true;
|
|
107
|
+
expect(eq).toBe(true);
|
|
108
|
+
|
|
109
|
+
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
110
|
+
const { password, ...other } = userData;
|
|
111
|
+
expectMatchObjectWithTimestamps(result, other);
|
|
112
|
+
|
|
113
|
+
expectQueryNotMutated(q);
|
|
114
|
+
});
|
|
115
|
+
|
|
116
|
+
it('should insert one record, returning all columns', async () => {
|
|
117
|
+
const q = User.all();
|
|
118
|
+
|
|
119
|
+
const query = q.selectAll().insert(userData);
|
|
120
|
+
expectSql(
|
|
121
|
+
query.toSql(),
|
|
122
|
+
`
|
|
123
|
+
INSERT INTO "user"("name", "password", "createdAt", "updatedAt")
|
|
124
|
+
VALUES ($1, $2, $3, $4)
|
|
125
|
+
RETURNING *
|
|
126
|
+
`,
|
|
127
|
+
['name', 'password', now, now],
|
|
128
|
+
);
|
|
129
|
+
|
|
130
|
+
const result = await query;
|
|
131
|
+
const eq: AssertEqual<typeof result, typeof User['type']> = true;
|
|
132
|
+
expect(eq).toBe(true);
|
|
133
|
+
|
|
134
|
+
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
135
|
+
const { password, ...other } = userData;
|
|
136
|
+
expectMatchObjectWithTimestamps(result, other);
|
|
137
|
+
|
|
138
|
+
expectQueryNotMutated(q);
|
|
139
|
+
});
|
|
140
|
+
|
|
141
|
+
it('should insert many records, returning void', async () => {
|
|
142
|
+
const q = User.all();
|
|
143
|
+
|
|
144
|
+
const arr = [
|
|
145
|
+
{
|
|
146
|
+
...userData,
|
|
147
|
+
picture: null,
|
|
148
|
+
},
|
|
149
|
+
userData,
|
|
150
|
+
];
|
|
151
|
+
|
|
152
|
+
const query = q.insert(arr);
|
|
153
|
+
|
|
154
|
+
expectSql(
|
|
155
|
+
query.toSql(),
|
|
156
|
+
`
|
|
157
|
+
INSERT INTO "user"("name", "password", "createdAt", "updatedAt", "picture")
|
|
158
|
+
VALUES
|
|
159
|
+
($1, $2, $3, $4, $5),
|
|
160
|
+
($6, $7, $8, $9, DEFAULT)
|
|
161
|
+
`,
|
|
162
|
+
['name', 'password', now, now, null, 'name', 'password', now, now],
|
|
163
|
+
);
|
|
164
|
+
|
|
165
|
+
const result = await query;
|
|
166
|
+
expect(result).toBe(2);
|
|
167
|
+
|
|
168
|
+
const eq: AssertEqual<typeof result, number> = true;
|
|
169
|
+
expect(eq).toBe(true);
|
|
170
|
+
|
|
171
|
+
const inserted = await User.all();
|
|
172
|
+
inserted.forEach((item, i) => {
|
|
173
|
+
expectMatchObjectWithTimestamps(item, arr[i]);
|
|
174
|
+
});
|
|
175
|
+
|
|
176
|
+
expectQueryNotMutated(q);
|
|
177
|
+
});
|
|
178
|
+
|
|
179
|
+
it('should insert many records, returning columns', async () => {
|
|
180
|
+
const q = User.all();
|
|
181
|
+
|
|
182
|
+
const arr = [
|
|
183
|
+
{
|
|
184
|
+
...userData,
|
|
185
|
+
picture: null,
|
|
186
|
+
},
|
|
187
|
+
userData,
|
|
188
|
+
];
|
|
189
|
+
|
|
190
|
+
const query = q.select('id', 'name', 'createdAt', 'updatedAt').insert(arr);
|
|
191
|
+
|
|
192
|
+
expectSql(
|
|
193
|
+
query.toSql(),
|
|
194
|
+
`
|
|
195
|
+
INSERT INTO "user"("name", "password", "createdAt", "updatedAt", "picture")
|
|
196
|
+
VALUES
|
|
197
|
+
($1, $2, $3, $4, $5),
|
|
198
|
+
($6, $7, $8, $9, DEFAULT)
|
|
199
|
+
RETURNING "user"."id", "user"."name", "user"."createdAt", "user"."updatedAt"
|
|
200
|
+
`,
|
|
201
|
+
['name', 'password', now, now, null, 'name', 'password', now, now],
|
|
202
|
+
);
|
|
203
|
+
|
|
204
|
+
const result = await query;
|
|
205
|
+
const eq: AssertEqual<
|
|
206
|
+
typeof result,
|
|
207
|
+
{ id: number; name: string; createdAt: Date; updatedAt: Date }[]
|
|
208
|
+
> = true;
|
|
209
|
+
expect(eq).toBe(true);
|
|
210
|
+
|
|
211
|
+
const inserted = await User.all();
|
|
212
|
+
inserted.forEach((item, i) => {
|
|
213
|
+
expectMatchObjectWithTimestamps(item, arr[i]);
|
|
214
|
+
});
|
|
215
|
+
|
|
216
|
+
expectQueryNotMutated(q);
|
|
217
|
+
});
|
|
218
|
+
|
|
219
|
+
it('should insert many records, returning all columns', async () => {
|
|
220
|
+
const q = User.all();
|
|
221
|
+
|
|
222
|
+
const arr = [
|
|
223
|
+
{
|
|
224
|
+
...userData,
|
|
225
|
+
picture: null,
|
|
226
|
+
},
|
|
227
|
+
userData,
|
|
228
|
+
];
|
|
229
|
+
|
|
230
|
+
const query = q.selectAll().insert(arr);
|
|
231
|
+
|
|
232
|
+
expectSql(
|
|
233
|
+
query.toSql(),
|
|
234
|
+
`
|
|
235
|
+
INSERT INTO "user"("name", "password", "createdAt", "updatedAt", "picture")
|
|
236
|
+
VALUES
|
|
237
|
+
($1, $2, $3, $4, $5),
|
|
238
|
+
($6, $7, $8, $9, DEFAULT)
|
|
239
|
+
RETURNING *
|
|
240
|
+
`,
|
|
241
|
+
['name', 'password', now, now, null, 'name', 'password', now, now],
|
|
242
|
+
);
|
|
243
|
+
|
|
244
|
+
const result = await query;
|
|
245
|
+
result.forEach((item, i) => {
|
|
246
|
+
expectMatchObjectWithTimestamps(item, arr[i]);
|
|
247
|
+
});
|
|
248
|
+
|
|
249
|
+
const eq: AssertEqual<typeof result, typeof User['type'][]> = true;
|
|
250
|
+
expect(eq).toBe(true);
|
|
251
|
+
|
|
252
|
+
const inserted = await User.all();
|
|
253
|
+
inserted.forEach((item, i) => {
|
|
254
|
+
expectMatchObjectWithTimestamps(item, arr[i]);
|
|
255
|
+
});
|
|
256
|
+
|
|
257
|
+
expectQueryNotMutated(q);
|
|
258
|
+
});
|
|
259
|
+
|
|
260
|
+
it('should insert record with provided defaults', () => {
|
|
261
|
+
const query = User.defaults({
|
|
262
|
+
name: 'name',
|
|
263
|
+
password: 'password',
|
|
264
|
+
}).insert({
|
|
265
|
+
password: 'override',
|
|
266
|
+
updatedAt: now,
|
|
267
|
+
createdAt: now,
|
|
268
|
+
});
|
|
269
|
+
|
|
270
|
+
expectSql(
|
|
271
|
+
query.toSql(),
|
|
272
|
+
`
|
|
273
|
+
INSERT INTO "user"("name", "password", "updatedAt", "createdAt")
|
|
274
|
+
VALUES ($1, $2, $3, $4)
|
|
275
|
+
`,
|
|
276
|
+
['name', 'override', now, now],
|
|
277
|
+
);
|
|
278
|
+
});
|
|
279
|
+
|
|
280
|
+
describe('onConflict', () => {
|
|
281
|
+
it('should return special query builder and return previous after ignore or merge', () => {
|
|
282
|
+
const q = User.all();
|
|
283
|
+
|
|
284
|
+
const originalQuery = q.insert(userData);
|
|
285
|
+
const onConflictQuery = q.onConflict();
|
|
286
|
+
expect(originalQuery instanceof OnConflictQueryBuilder).not.toBe(true);
|
|
287
|
+
expect(onConflictQuery instanceof OnConflictQueryBuilder).toBe(true);
|
|
288
|
+
expect(onConflictQuery instanceof OnConflictQueryBuilder).toBe(true);
|
|
289
|
+
expect(
|
|
290
|
+
onConflictQuery.ignore() instanceof OnConflictQueryBuilder,
|
|
291
|
+
).not.toBe(true);
|
|
292
|
+
expect(
|
|
293
|
+
onConflictQuery.merge() instanceof OnConflictQueryBuilder,
|
|
294
|
+
).not.toBe(true);
|
|
295
|
+
|
|
296
|
+
expectQueryNotMutated(q);
|
|
297
|
+
});
|
|
298
|
+
|
|
299
|
+
it('should accept where condition', () => {
|
|
300
|
+
const q = User.all();
|
|
301
|
+
|
|
302
|
+
const query = q
|
|
303
|
+
.select('id')
|
|
304
|
+
.insert(userData)
|
|
305
|
+
.onConflict('name')
|
|
306
|
+
.ignore()
|
|
307
|
+
.where({ name: 'where name' });
|
|
308
|
+
|
|
309
|
+
expectSql(
|
|
310
|
+
query.toSql(),
|
|
311
|
+
`
|
|
312
|
+
INSERT INTO "user"("name", "password", "createdAt", "updatedAt")
|
|
313
|
+
VALUES ($1, $2, $3, $4)
|
|
314
|
+
ON CONFLICT ("name")
|
|
315
|
+
DO NOTHING
|
|
316
|
+
WHERE "user"."name" = $5
|
|
317
|
+
RETURNING "user"."id"
|
|
318
|
+
`,
|
|
319
|
+
['name', 'password', now, now, 'where name'],
|
|
320
|
+
);
|
|
321
|
+
|
|
322
|
+
expectQueryNotMutated(q);
|
|
323
|
+
});
|
|
324
|
+
|
|
325
|
+
describe('ignore', () => {
|
|
326
|
+
it('should set `ON CONFLICT` to all columns if no arguments provided', () => {
|
|
327
|
+
const q = User.all();
|
|
328
|
+
|
|
329
|
+
const query = q.insert(userData).onConflict().ignore();
|
|
330
|
+
expectSql(
|
|
331
|
+
query.toSql(),
|
|
332
|
+
`
|
|
333
|
+
INSERT INTO "user"("name", "password", "createdAt", "updatedAt")
|
|
334
|
+
VALUES ($1, $2, $3, $4)
|
|
335
|
+
ON CONFLICT ("name", "password", "createdAt", "updatedAt")
|
|
336
|
+
DO NOTHING
|
|
337
|
+
`,
|
|
338
|
+
['name', 'password', now, now],
|
|
339
|
+
);
|
|
340
|
+
|
|
341
|
+
expectQueryNotMutated(q);
|
|
342
|
+
});
|
|
343
|
+
|
|
344
|
+
it('should accept single column', () => {
|
|
345
|
+
const q = User.all();
|
|
346
|
+
|
|
347
|
+
const query = q.insert(userData).onConflict('id').ignore();
|
|
348
|
+
expectSql(
|
|
349
|
+
query.toSql(),
|
|
350
|
+
`
|
|
351
|
+
INSERT INTO "user"("name", "password", "createdAt", "updatedAt")
|
|
352
|
+
VALUES ($1, $2, $3, $4)
|
|
353
|
+
ON CONFLICT ("id") DO NOTHING
|
|
354
|
+
`,
|
|
355
|
+
['name', 'password', now, now],
|
|
356
|
+
);
|
|
357
|
+
|
|
358
|
+
expectQueryNotMutated(q);
|
|
359
|
+
});
|
|
360
|
+
|
|
361
|
+
it('should accept multiple columns', () => {
|
|
362
|
+
const q = User.all();
|
|
363
|
+
|
|
364
|
+
const query = q.insert(userData).onConflict(['id', 'name']).ignore();
|
|
365
|
+
expectSql(
|
|
366
|
+
query.toSql(),
|
|
367
|
+
`
|
|
368
|
+
INSERT INTO "user"("name", "password", "createdAt", "updatedAt")
|
|
369
|
+
VALUES ($1, $2, $3, $4)
|
|
370
|
+
ON CONFLICT ("id", "name") DO NOTHING
|
|
371
|
+
`,
|
|
372
|
+
['name', 'password', now, now],
|
|
373
|
+
);
|
|
374
|
+
|
|
375
|
+
expectQueryNotMutated(q);
|
|
376
|
+
});
|
|
377
|
+
|
|
378
|
+
it('can accept raw query', () => {
|
|
379
|
+
const q = User.all();
|
|
380
|
+
|
|
381
|
+
const query = q.insert(userData).onConflict(raw('raw query')).ignore();
|
|
382
|
+
expectSql(
|
|
383
|
+
query.toSql(),
|
|
384
|
+
`
|
|
385
|
+
INSERT INTO "user"("name", "password", "createdAt", "updatedAt")
|
|
386
|
+
VALUES ($1, $2, $3, $4)
|
|
387
|
+
ON CONFLICT raw query DO NOTHING
|
|
388
|
+
`,
|
|
389
|
+
['name', 'password', now, now],
|
|
390
|
+
);
|
|
391
|
+
|
|
392
|
+
expectQueryNotMutated(q);
|
|
393
|
+
});
|
|
394
|
+
});
|
|
395
|
+
|
|
396
|
+
describe('merge', () => {
|
|
397
|
+
it('should update all columns when calling without arguments', () => {
|
|
398
|
+
const q = User.all();
|
|
399
|
+
|
|
400
|
+
const query = q.insert(userData).onConflict().merge();
|
|
401
|
+
expectSql(
|
|
402
|
+
query.toSql(),
|
|
403
|
+
`
|
|
404
|
+
INSERT INTO "user"("name", "password", "createdAt", "updatedAt")
|
|
405
|
+
VALUES ($1, $2, $3, $4)
|
|
406
|
+
ON CONFLICT ("name", "password", "createdAt", "updatedAt")
|
|
407
|
+
DO UPDATE SET
|
|
408
|
+
"name" = excluded."name",
|
|
409
|
+
"password" = excluded."password",
|
|
410
|
+
"createdAt" = excluded."createdAt",
|
|
411
|
+
"updatedAt" = excluded."updatedAt"
|
|
412
|
+
`,
|
|
413
|
+
['name', 'password', now, now],
|
|
414
|
+
);
|
|
415
|
+
|
|
416
|
+
expectQueryNotMutated(q);
|
|
417
|
+
});
|
|
418
|
+
|
|
419
|
+
it('should accept single column', () => {
|
|
420
|
+
const q = User.all();
|
|
421
|
+
|
|
422
|
+
const query = q.insert(userData).onConflict('name').merge('name');
|
|
423
|
+
expectSql(
|
|
424
|
+
query.toSql(),
|
|
425
|
+
`
|
|
426
|
+
INSERT INTO "user"("name", "password", "createdAt", "updatedAt")
|
|
427
|
+
VALUES ($1, $2, $3, $4)
|
|
428
|
+
ON CONFLICT ("name")
|
|
429
|
+
DO UPDATE SET "name" = excluded."name"
|
|
430
|
+
`,
|
|
431
|
+
['name', 'password', now, now],
|
|
432
|
+
);
|
|
433
|
+
|
|
434
|
+
expectQueryNotMutated(q);
|
|
435
|
+
});
|
|
436
|
+
|
|
437
|
+
it('should accept multiple columns', () => {
|
|
438
|
+
const q = User.all();
|
|
439
|
+
|
|
440
|
+
const query = q
|
|
441
|
+
.insert(userData)
|
|
442
|
+
.onConflict(['name', 'password'])
|
|
443
|
+
.merge(['name', 'password']);
|
|
444
|
+
|
|
445
|
+
expectSql(
|
|
446
|
+
query.toSql(),
|
|
447
|
+
`
|
|
448
|
+
INSERT INTO "user"("name", "password", "createdAt", "updatedAt")
|
|
449
|
+
VALUES ($1, $2, $3, $4)
|
|
450
|
+
ON CONFLICT ("name", "password")
|
|
451
|
+
DO UPDATE SET
|
|
452
|
+
"name" = excluded."name",
|
|
453
|
+
"password" = excluded."password"
|
|
454
|
+
`,
|
|
455
|
+
['name', 'password', now, now],
|
|
456
|
+
);
|
|
457
|
+
|
|
458
|
+
expectQueryNotMutated(q);
|
|
459
|
+
});
|
|
460
|
+
|
|
461
|
+
it('should accept object with values to update', () => {
|
|
462
|
+
const q = User.all();
|
|
463
|
+
|
|
464
|
+
const query = q
|
|
465
|
+
.insert(userData)
|
|
466
|
+
.onConflict('name')
|
|
467
|
+
.merge({ name: 'new name' });
|
|
468
|
+
|
|
469
|
+
expectSql(
|
|
470
|
+
query.toSql(),
|
|
471
|
+
`
|
|
472
|
+
INSERT INTO "user"("name", "password", "createdAt", "updatedAt")
|
|
473
|
+
VALUES ($1, $2, $3, $4)
|
|
474
|
+
ON CONFLICT ("name")
|
|
475
|
+
DO UPDATE SET "name" = $5
|
|
476
|
+
`,
|
|
477
|
+
['name', 'password', now, now, 'new name'],
|
|
478
|
+
);
|
|
479
|
+
|
|
480
|
+
expectQueryNotMutated(q);
|
|
481
|
+
});
|
|
482
|
+
|
|
483
|
+
it('should accept raw sql', () => {
|
|
484
|
+
const q = User.all();
|
|
485
|
+
|
|
486
|
+
const query = q
|
|
487
|
+
.insert(userData)
|
|
488
|
+
.onConflict(raw('on conflict raw'))
|
|
489
|
+
.merge(raw('merge raw'));
|
|
490
|
+
|
|
491
|
+
expectSql(
|
|
492
|
+
query.toSql(),
|
|
493
|
+
`
|
|
494
|
+
INSERT INTO "user"("name", "password", "createdAt", "updatedAt")
|
|
495
|
+
VALUES ($1, $2, $3, $4)
|
|
496
|
+
ON CONFLICT on conflict raw
|
|
497
|
+
DO UPDATE SET merge raw
|
|
498
|
+
`,
|
|
499
|
+
['name', 'password', now, now],
|
|
500
|
+
);
|
|
501
|
+
|
|
502
|
+
expectQueryNotMutated(q);
|
|
503
|
+
});
|
|
504
|
+
});
|
|
505
|
+
});
|
|
506
|
+
|
|
507
|
+
describe('create', () => {
|
|
508
|
+
it('should return full record', async () => {
|
|
509
|
+
const result = await User.create(userData);
|
|
510
|
+
expectMatchObjectWithTimestamps(result, userData);
|
|
511
|
+
|
|
512
|
+
const eq: AssertEqual<typeof result, typeof User.type> = true;
|
|
513
|
+
expect(eq).toBe(true);
|
|
514
|
+
});
|
|
515
|
+
|
|
516
|
+
it('should return columns from select', async () => {
|
|
517
|
+
const result = await User.select('id', 'name').create(userData);
|
|
518
|
+
expect(result).toEqual({
|
|
519
|
+
id: result.id,
|
|
520
|
+
name: userData.name,
|
|
521
|
+
});
|
|
522
|
+
|
|
523
|
+
const eq: AssertEqual<typeof result, { id: number; name: string }> = true;
|
|
524
|
+
expect(eq).toBe(true);
|
|
525
|
+
});
|
|
526
|
+
|
|
527
|
+
it('should return full records when creating many', async () => {
|
|
528
|
+
const result = await User.create([userData, userData]);
|
|
529
|
+
expectMatchObjectWithTimestamps(result[0], userData);
|
|
530
|
+
expectMatchObjectWithTimestamps(result[1], userData);
|
|
531
|
+
|
|
532
|
+
const eq: AssertEqual<typeof result, typeof User.type[]> = true;
|
|
533
|
+
expect(eq).toBe(true);
|
|
534
|
+
});
|
|
535
|
+
|
|
536
|
+
it('should return columns from select when creating many', async () => {
|
|
537
|
+
const result = await User.select('id', 'name').create([
|
|
538
|
+
userData,
|
|
539
|
+
userData,
|
|
540
|
+
]);
|
|
541
|
+
expect(result[0]).toEqual({
|
|
542
|
+
id: result[0].id,
|
|
543
|
+
name: userData.name,
|
|
544
|
+
});
|
|
545
|
+
expect(result[1]).toEqual({
|
|
546
|
+
id: result[1].id,
|
|
547
|
+
name: userData.name,
|
|
548
|
+
});
|
|
549
|
+
|
|
550
|
+
const eq: AssertEqual<typeof result, { id: number; name: string }[]> =
|
|
551
|
+
true;
|
|
552
|
+
expect(eq).toBe(true);
|
|
553
|
+
});
|
|
554
|
+
});
|
|
555
|
+
});
|