pqb 0.2.2 → 0.2.3

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "pqb",
3
- "version": "0.2.2",
3
+ "version": "0.2.3",
4
4
  "description": "Postgres query builder",
5
5
  "homepage": "https://porm.netlify.app/guide/query-builder.html",
6
6
  "repository": {
@@ -1,6 +1,6 @@
1
1
  import { ColumnInput, ColumnOutput, ColumnType } from './columnType';
2
2
  import { Operators } from '../columnsOperators';
3
- import { UnionToIntersection } from '../utils';
3
+ import { SetOptional, SomeIsTrue, UnionToIntersection } from '../utils';
4
4
 
5
5
  export type ColumnsShape = Record<string, ColumnType>;
6
6
 
@@ -8,9 +8,20 @@ export type ColumnShapeOutput<Shape extends ColumnsShape> = {
8
8
  [K in keyof Shape]: ColumnOutput<Shape[K]>;
9
9
  };
10
10
 
11
- export type ColumnShapeInput<Shape extends ColumnsShape> = {
12
- [K in keyof Shape]: ColumnInput<Shape[K]>;
13
- };
11
+ type OptionalColumnsForInput<Shape extends ColumnsShape> = {
12
+ [K in keyof Shape]: SomeIsTrue<
13
+ [Shape[K]['isNullable'], Shape[K]['hasDefault']]
14
+ > extends true
15
+ ? K
16
+ : never;
17
+ }[keyof Shape];
18
+
19
+ export type ColumnShapeInput<Shape extends ColumnsShape> = SetOptional<
20
+ {
21
+ [K in keyof Shape]: ColumnInput<Shape[K]>;
22
+ },
23
+ OptionalColumnsForInput<Shape>
24
+ >;
14
25
 
15
26
  export class ColumnsObject<Shape extends ColumnsShape> extends ColumnType<
16
27
  { [K in keyof Shape]: Shape[K]['type'] },
@@ -119,15 +119,18 @@ export class DoublePrecisionColumn extends NumberAsStringBaseColumn {
119
119
  export class SmallSerialColumn extends IntegerBaseColumn {
120
120
  dataType = 'smallserial' as const;
121
121
  parseItem = parseInt;
122
+ hasDefault = true as const;
122
123
  }
123
124
 
124
125
  // autoincrementing four-byte integer
125
126
  export class SerialColumn extends IntegerBaseColumn {
126
127
  dataType = 'serial' as const;
127
128
  parseItem = parseInt;
129
+ hasDefault = true as const;
128
130
  }
129
131
 
130
132
  // autoincrementing eight-byte integer
131
133
  export class BigSerialColumn extends NumberAsStringBaseColumn {
132
134
  dataType = 'bigserial' as const;
135
+ hasDefault = true as const;
133
136
  }
@@ -504,7 +504,7 @@ describe('aggregate', () => {
504
504
  });
505
505
 
506
506
  it('should return json object when have records', async () => {
507
- await User.insert([userData, userData]);
507
+ await User.insertMany([userData, userData]);
508
508
 
509
509
  const value = await User.stringAgg('name', ', ');
510
510
 
@@ -526,7 +526,7 @@ describe('aggregate', () => {
526
526
  });
527
527
 
528
528
  it('should return json object when have records', async () => {
529
- await User.insert([userData, userData]);
529
+ await User.insertMany([userData, userData]);
530
530
 
531
531
  const value = await User.selectStringAgg('name', ', ').take();
532
532
 
@@ -9,260 +9,267 @@ import {
9
9
  import { raw } from '../common';
10
10
  import { OnConflictQueryBuilder } from './insert';
11
11
 
12
- describe('insert', () => {
12
+ describe('insert functions', () => {
13
13
  useTestDatabase();
14
14
 
15
- it('should insert with raw sql and list of columns', () => {
16
- const q = User.all();
15
+ describe('insertRaw', () => {
16
+ it('should insert with raw sql and list of columns', () => {
17
+ const q = User.all();
17
18
 
18
- const query = q.insert({
19
- columns: ['name', 'password'],
20
- values: raw('raw sql'),
21
- });
22
- expectSql(
23
- query.toSql(),
24
- `
19
+ const query = q.insertRaw({
20
+ columns: ['name', 'password'],
21
+ values: raw('raw sql'),
22
+ });
23
+ expectSql(
24
+ query.toSql(),
25
+ `
25
26
  INSERT INTO "user"("name", "password")
26
27
  VALUES raw sql
27
28
  `,
28
- );
29
+ );
29
30
 
30
- const eq: AssertEqual<Awaited<typeof query>, number> = true;
31
- expect(eq).toBe(true);
31
+ const eq: AssertEqual<Awaited<typeof query>, number> = true;
32
+ expect(eq).toBe(true);
32
33
 
33
- expectQueryNotMutated(q);
34
+ expectQueryNotMutated(q);
35
+ });
34
36
  });
35
37
 
36
- it('should insert one record, returning rows count', async () => {
37
- const q = User.all();
38
+ describe('insert', () => {
39
+ it('should insert one record, returning rows count', async () => {
40
+ const q = User.all();
38
41
 
39
- const query = q.insert(userData);
40
- expectSql(
41
- query.toSql(),
42
- `
42
+ const query = q.insert(userData);
43
+ expectSql(
44
+ query.toSql(),
45
+ `
43
46
  INSERT INTO "user"("name", "password")
44
47
  VALUES ($1, $2)
45
48
  `,
46
- ['name', 'password'],
47
- );
49
+ ['name', 'password'],
50
+ );
48
51
 
49
- const result = await query;
50
- expect(result).toBe(1);
52
+ const result = await query;
53
+ expect(result).toBe(1);
51
54
 
52
- const eq: AssertEqual<typeof result, number> = true;
53
- expect(eq).toBe(true);
55
+ const eq: AssertEqual<typeof result, number> = true;
56
+ expect(eq).toBe(true);
54
57
 
55
- const inserted = await User.take();
56
- expect(inserted).toMatchObject(userData);
58
+ const inserted = await User.take();
59
+ expect(inserted).toMatchObject(userData);
57
60
 
58
- expectQueryNotMutated(q);
59
- });
61
+ expectQueryNotMutated(q);
62
+ });
60
63
 
61
- it('should insert one record, returning value', async () => {
62
- const q = User.all();
64
+ it('should insert one record, returning value', async () => {
65
+ const q = User.all();
63
66
 
64
- const query = q.get('id').insert(userData);
65
- expectSql(
66
- query.toSql(),
67
- `
67
+ const query = q.get('id').insert(userData);
68
+ expectSql(
69
+ query.toSql(),
70
+ `
68
71
  INSERT INTO "user"("name", "password")
69
72
  VALUES ($1, $2)
70
73
  RETURNING "user"."id"
71
74
  `,
72
- ['name', 'password'],
73
- );
75
+ ['name', 'password'],
76
+ );
74
77
 
75
- const result = await query;
76
- const eq: AssertEqual<typeof result, number> = true;
77
- expect(eq).toBe(true);
78
+ const result = await query;
79
+ const eq: AssertEqual<typeof result, number> = true;
80
+ expect(eq).toBe(true);
78
81
 
79
- expect(typeof result).toBe('number');
82
+ expect(typeof result).toBe('number');
80
83
 
81
- expectQueryNotMutated(q);
82
- });
84
+ expectQueryNotMutated(q);
85
+ });
83
86
 
84
- it('should insert one record, returning columns', async () => {
85
- const q = User.all();
87
+ it('should insert one record, returning columns', async () => {
88
+ const q = User.all();
86
89
 
87
- const query = q.select('id', 'name').insert(userData);
88
- expectSql(
89
- query.toSql(),
90
- `
90
+ const query = q.select('id', 'name').insert(userData);
91
+ expectSql(
92
+ query.toSql(),
93
+ `
91
94
  INSERT INTO "user"("name", "password")
92
95
  VALUES ($1, $2)
93
96
  RETURNING "user"."id", "user"."name"
94
97
  `,
95
- ['name', 'password'],
96
- );
98
+ ['name', 'password'],
99
+ );
97
100
 
98
- const result = await query;
99
- const eq: AssertEqual<typeof result, { id: number; name: string }> = true;
100
- expect(eq).toBe(true);
101
+ const result = await query;
102
+ const eq: AssertEqual<typeof result, { id: number; name: string }> = true;
103
+ expect(eq).toBe(true);
101
104
 
102
- // eslint-disable-next-line @typescript-eslint/no-unused-vars
103
- const { password, ...other } = userData;
104
- expect(result).toMatchObject(other);
105
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
106
+ const { password, ...other } = userData;
107
+ expect(result).toMatchObject(other);
105
108
 
106
- expectQueryNotMutated(q);
107
- });
109
+ expectQueryNotMutated(q);
110
+ });
108
111
 
109
- it('should insert one record, returning all columns', async () => {
110
- const q = User.all();
112
+ it('should insert one record, returning all columns', async () => {
113
+ const q = User.all();
111
114
 
112
- const query = q.selectAll().insert(userData);
113
- expectSql(
114
- query.toSql(),
115
- `
115
+ const query = q.selectAll().insert(userData);
116
+ expectSql(
117
+ query.toSql(),
118
+ `
116
119
  INSERT INTO "user"("name", "password")
117
120
  VALUES ($1, $2)
118
121
  RETURNING *
119
122
  `,
120
- ['name', 'password'],
121
- );
123
+ ['name', 'password'],
124
+ );
122
125
 
123
- const result = await query;
124
- const eq: AssertEqual<typeof result, typeof User['type']> = true;
125
- expect(eq).toBe(true);
126
+ const result = await query;
127
+ const eq: AssertEqual<typeof result, typeof User['type']> = true;
128
+ expect(eq).toBe(true);
126
129
 
127
- // eslint-disable-next-line @typescript-eslint/no-unused-vars
128
- const { password, ...other } = userData;
129
- expect(result).toMatchObject(other);
130
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
131
+ const { password, ...other } = userData;
132
+ expect(result).toMatchObject(other);
130
133
 
131
- expectQueryNotMutated(q);
134
+ expectQueryNotMutated(q);
135
+ });
136
+
137
+ it('should insert record with provided defaults', () => {
138
+ const query = User.defaults({
139
+ name: 'name',
140
+ password: 'password',
141
+ }).insert({
142
+ password: 'override',
143
+ });
144
+
145
+ expectSql(
146
+ query.toSql(),
147
+ `
148
+ INSERT INTO "user"("name", "password")
149
+ VALUES ($1, $2)
150
+ `,
151
+ ['name', 'override'],
152
+ );
153
+ });
132
154
  });
133
155
 
134
- it('should insert many records, returning void', async () => {
135
- const q = User.all();
156
+ describe('insertMany', () => {
157
+ it('should insert many records, returning void', async () => {
158
+ const q = User.all();
136
159
 
137
- const arr = [
138
- {
139
- ...userData,
140
- picture: null,
141
- },
142
- userData,
143
- ];
160
+ const arr = [
161
+ {
162
+ ...userData,
163
+ picture: null,
164
+ },
165
+ userData,
166
+ ];
144
167
 
145
- const query = q.insert(arr);
168
+ const query = q.insertMany(arr);
146
169
 
147
- expectSql(
148
- query.toSql(),
149
- `
170
+ expectSql(
171
+ query.toSql(),
172
+ `
150
173
  INSERT INTO "user"("name", "password", "picture")
151
174
  VALUES
152
175
  ($1, $2, $3),
153
176
  ($4, $5, DEFAULT)
154
177
  `,
155
- ['name', 'password', null, 'name', 'password'],
156
- );
178
+ ['name', 'password', null, 'name', 'password'],
179
+ );
157
180
 
158
- const result = await query;
159
- expect(result).toBe(2);
181
+ const result = await query;
182
+ expect(result).toBe(2);
160
183
 
161
- const eq: AssertEqual<typeof result, number> = true;
162
- expect(eq).toBe(true);
184
+ const eq: AssertEqual<typeof result, number> = true;
185
+ expect(eq).toBe(true);
163
186
 
164
- const inserted = await User.all();
165
- inserted.forEach((item, i) => {
166
- expect(item).toMatchObject(arr[i]);
167
- });
187
+ const inserted = await User.all();
188
+ inserted.forEach((item, i) => {
189
+ expect(item).toMatchObject(arr[i]);
190
+ });
168
191
 
169
- expectQueryNotMutated(q);
170
- });
192
+ expectQueryNotMutated(q);
193
+ });
171
194
 
172
- it('should insert many records, returning columns', async () => {
173
- const q = User.all();
195
+ it('should insert many records, returning columns', async () => {
196
+ const q = User.all();
174
197
 
175
- const arr = [
176
- {
177
- ...userData,
178
- picture: null,
179
- },
180
- userData,
181
- ];
198
+ const arr = [
199
+ {
200
+ ...userData,
201
+ picture: null,
202
+ },
203
+ userData,
204
+ ];
182
205
 
183
- const query = q.select('id', 'name').insert(arr);
206
+ const query = q.select('id', 'name').insertMany(arr);
184
207
 
185
- expectSql(
186
- query.toSql(),
187
- `
208
+ expectSql(
209
+ query.toSql(),
210
+ `
188
211
  INSERT INTO "user"("name", "password", "picture")
189
212
  VALUES
190
213
  ($1, $2, $3),
191
214
  ($4, $5, DEFAULT)
192
215
  RETURNING "user"."id", "user"."name"
193
216
  `,
194
- ['name', 'password', null, 'name', 'password'],
195
- );
217
+ ['name', 'password', null, 'name', 'password'],
218
+ );
196
219
 
197
- const result = await query;
198
- const eq: AssertEqual<typeof result, { id: number; name: string }[]> = true;
199
- expect(eq).toBe(true);
220
+ const result = await query;
221
+ const eq: AssertEqual<typeof result, { id: number; name: string }[]> =
222
+ true;
223
+ expect(eq).toBe(true);
200
224
 
201
- const inserted = await User.all();
202
- inserted.forEach((item, i) => {
203
- expect(item).toMatchObject(arr[i]);
204
- });
225
+ const inserted = await User.all();
226
+ inserted.forEach((item, i) => {
227
+ expect(item).toMatchObject(arr[i]);
228
+ });
205
229
 
206
- expectQueryNotMutated(q);
207
- });
230
+ expectQueryNotMutated(q);
231
+ });
208
232
 
209
- it('should insert many records, returning all columns', async () => {
210
- const q = User.all();
233
+ it('should insert many records, returning all columns', async () => {
234
+ const q = User.all();
211
235
 
212
- const arr = [
213
- {
214
- ...userData,
215
- picture: null,
216
- },
217
- userData,
218
- ];
236
+ const arr = [
237
+ {
238
+ ...userData,
239
+ picture: null,
240
+ },
241
+ userData,
242
+ ];
219
243
 
220
- const query = q.selectAll().insert(arr);
244
+ const query = q.selectAll().insertMany(arr);
221
245
 
222
- expectSql(
223
- query.toSql(),
224
- `
246
+ expectSql(
247
+ query.toSql(),
248
+ `
225
249
  INSERT INTO "user"("name", "password", "picture")
226
250
  VALUES
227
251
  ($1, $2, $3),
228
252
  ($4, $5, DEFAULT)
229
253
  RETURNING *
230
254
  `,
231
- ['name', 'password', null, 'name', 'password'],
232
- );
233
-
234
- const result = await query;
235
- result.forEach((item, i) => {
236
- expect(item).toMatchObject(arr[i]);
237
- });
255
+ ['name', 'password', null, 'name', 'password'],
256
+ );
238
257
 
239
- const eq: AssertEqual<typeof result, typeof User['type'][]> = true;
240
- expect(eq).toBe(true);
258
+ const result = await query;
259
+ result.forEach((item, i) => {
260
+ expect(item).toMatchObject(arr[i]);
261
+ });
241
262
 
242
- const inserted = await User.all();
243
- inserted.forEach((item, i) => {
244
- expect(item).toMatchObject(arr[i]);
245
- });
263
+ const eq: AssertEqual<typeof result, typeof User['type'][]> = true;
264
+ expect(eq).toBe(true);
246
265
 
247
- expectQueryNotMutated(q);
248
- });
266
+ const inserted = await User.all();
267
+ inserted.forEach((item, i) => {
268
+ expect(item).toMatchObject(arr[i]);
269
+ });
249
270
 
250
- it('should insert record with provided defaults', () => {
251
- const query = User.defaults({
252
- name: 'name',
253
- password: 'password',
254
- }).insert({
255
- password: 'override',
271
+ expectQueryNotMutated(q);
256
272
  });
257
-
258
- expectSql(
259
- query.toSql(),
260
- `
261
- INSERT INTO "user"("name", "password")
262
- VALUES ($1, $2)
263
- `,
264
- ['name', 'override'],
265
- );
266
273
  });
267
274
 
268
275
  describe('onConflict', () => {
@@ -490,52 +497,57 @@ describe('insert', () => {
490
497
  });
491
498
  });
492
499
 
493
- describe('create', () => {
494
- it('should return full record', async () => {
495
- const result = await User.create(userData);
496
- expect(result).toMatchObject(userData);
497
-
498
- const eq: AssertEqual<typeof result, typeof User.type> = true;
499
- expect(eq).toBe(true);
500
- });
500
+ describe('create functions', () => {
501
+ describe('create', () => {
502
+ it('should return full record', async () => {
503
+ const result = await User.create(userData);
504
+ expect(result).toMatchObject(userData);
501
505
 
502
- it('should return columns from select', async () => {
503
- const result = await User.select('id', 'name').create(userData);
504
- expect(result).toEqual({
505
- id: result.id,
506
- name: userData.name,
506
+ const eq: AssertEqual<typeof result, typeof User.type> = true;
507
+ expect(eq).toBe(true);
507
508
  });
508
509
 
509
- const eq: AssertEqual<typeof result, { id: number; name: string }> = true;
510
- expect(eq).toBe(true);
511
- });
512
-
513
- it('should return full records when creating many', async () => {
514
- const result = await User.create([userData, userData]);
515
- expect(result[0]).toMatchObject(userData);
516
- expect(result[1]).toMatchObject(userData);
510
+ it('should return columns from select', async () => {
511
+ const result = await User.select('id', 'name').create(userData);
512
+ expect(result).toEqual({
513
+ id: result.id,
514
+ name: userData.name,
515
+ });
517
516
 
518
- const eq: AssertEqual<typeof result, typeof User.type[]> = true;
519
- expect(eq).toBe(true);
517
+ const eq: AssertEqual<typeof result, { id: number; name: string }> =
518
+ true;
519
+ expect(eq).toBe(true);
520
+ });
520
521
  });
521
522
 
522
- it('should return columns from select when creating many', async () => {
523
- const result = await User.select('id', 'name').create([
524
- userData,
525
- userData,
526
- ]);
527
- expect(result[0]).toEqual({
528
- id: result[0].id,
529
- name: userData.name,
530
- });
531
- expect(result[1]).toEqual({
532
- id: result[1].id,
533
- name: userData.name,
523
+ describe('createMany', () => {
524
+ it('should return full records', async () => {
525
+ const result = await User.createMany([userData, userData]);
526
+ expect(result[0]).toMatchObject(userData);
527
+ expect(result[1]).toMatchObject(userData);
528
+
529
+ const eq: AssertEqual<typeof result, typeof User.type[]> = true;
530
+ expect(eq).toBe(true);
534
531
  });
535
532
 
536
- const eq: AssertEqual<typeof result, { id: number; name: string }[]> =
537
- true;
538
- expect(eq).toBe(true);
533
+ it('should return columns from select', async () => {
534
+ const result = await User.select('id', 'name').createMany([
535
+ userData,
536
+ userData,
537
+ ]);
538
+ expect(result[0]).toEqual({
539
+ id: result[0].id,
540
+ name: userData.name,
541
+ });
542
+ expect(result[1]).toEqual({
543
+ id: result[1].id,
544
+ name: userData.name,
545
+ });
546
+
547
+ const eq: AssertEqual<typeof result, { id: number; name: string }[]> =
548
+ true;
549
+ expect(eq).toBe(true);
550
+ });
539
551
  });
540
552
  });
541
553
  });