pqb 0.4.5 → 0.4.7

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.
Files changed (51) hide show
  1. package/dist/index.d.ts +24 -13
  2. package/dist/index.esm.js +44 -33
  3. package/dist/index.esm.js.map +1 -1
  4. package/dist/index.js +44 -32
  5. package/dist/index.js.map +1 -1
  6. package/package.json +1 -1
  7. package/src/columnSchema/columnTypes.test.ts +55 -53
  8. package/src/columnSchema/timestamps.test.ts +3 -4
  9. package/src/columnSchema/timestamps.ts +1 -1
  10. package/src/columnsOperators.test.ts +18 -19
  11. package/src/columnsOperators.ts +1 -1
  12. package/src/common.ts +17 -30
  13. package/src/db.ts +19 -8
  14. package/src/errors.test.ts +2 -4
  15. package/src/index.ts +1 -1
  16. package/src/query.ts +7 -1
  17. package/src/queryMethods/aggregate.test.ts +9 -7
  18. package/src/queryMethods/create.test.ts +5 -5
  19. package/src/queryMethods/create.ts +1 -1
  20. package/src/queryMethods/delete.ts +2 -0
  21. package/src/queryMethods/for.test.ts +1 -2
  22. package/src/queryMethods/for.ts +1 -1
  23. package/src/queryMethods/from.test.ts +2 -3
  24. package/src/queryMethods/get.test.ts +5 -5
  25. package/src/queryMethods/having.test.ts +6 -5
  26. package/src/queryMethods/index.ts +1 -0
  27. package/src/queryMethods/json.ts +2 -2
  28. package/src/queryMethods/merge.test.ts +10 -4
  29. package/src/queryMethods/queryMethods.test.ts +10 -12
  30. package/src/queryMethods/queryMethods.ts +7 -4
  31. package/src/queryMethods/raw.test.ts +19 -0
  32. package/src/queryMethods/raw.ts +27 -0
  33. package/src/queryMethods/select.test.ts +5 -209
  34. package/src/queryMethods/then.test.ts +2 -4
  35. package/src/queryMethods/union.test.ts +11 -6
  36. package/src/queryMethods/update.test.ts +3 -3
  37. package/src/queryMethods/where.test.ts +65 -56
  38. package/src/queryMethods/where.ts +1 -1
  39. package/src/queryMethods/with.test.ts +5 -6
  40. package/src/relations.ts +15 -4
  41. package/src/sql/common.ts +0 -1
  42. package/src/sql/fromAndAs.ts +1 -1
  43. package/src/sql/insert.ts +1 -1
  44. package/src/sql/join.ts +1 -1
  45. package/src/sql/orderBy.ts +1 -1
  46. package/src/sql/select.ts +1 -2
  47. package/src/sql/toSql.ts +1 -1
  48. package/src/sql/update.ts +1 -1
  49. package/src/sql/where.ts +1 -1
  50. package/src/sql/window.ts +3 -4
  51. package/src/sql/with.ts +1 -1
@@ -0,0 +1,27 @@
1
+ import { ColumnType, ColumnTypesBase } from '../columnSchema';
2
+ import { Query } from '../query';
3
+ import { RawExpression } from '../common';
4
+
5
+ type RawArgs<CT extends ColumnTypesBase, C extends ColumnType> =
6
+ | [column: (types: CT) => C, sql: string, ...values: unknown[]]
7
+ | [sql: string, ...values: unknown[]];
8
+
9
+ export class RawMethods {
10
+ raw<T extends Query, C extends ColumnType>(
11
+ this: T,
12
+ ...args: RawArgs<T['columnTypes'], C>
13
+ ): RawExpression<C> {
14
+ if (typeof args[0] === 'string') {
15
+ return {
16
+ __raw: args[0],
17
+ __values: args.slice(1),
18
+ } as RawExpression<C>;
19
+ } else {
20
+ return {
21
+ __column: args[0](this.columnTypes),
22
+ __raw: args[1],
23
+ __values: args.slice(2),
24
+ } as RawExpression<C>;
25
+ }
26
+ }
27
+ }
@@ -1,25 +1,16 @@
1
1
  import {
2
2
  assertType,
3
- Chat,
4
- chatData,
3
+ db,
5
4
  expectQueryNotMutated,
6
5
  expectSql,
7
- Message,
8
- messageData,
9
- MessageRecord,
10
- now,
11
6
  Profile,
12
7
  profileData,
13
- ProfileRecord,
14
8
  User,
15
9
  userData,
16
10
  UserRecord,
17
11
  useTestDatabase,
18
12
  } from '../test-utils';
19
- import { raw } from '../common';
20
- import { columnTypes, DateColumn } from '../columnSchema';
21
- import { addQueryOn } from './join';
22
- import { RelationQuery, relationQueryKey } from '../relations';
13
+ import { DateColumn } from '../columnSchema';
23
14
 
24
15
  const insertUserAndProfile = async () => {
25
16
  const id = await User.get('id').create(userData);
@@ -115,201 +106,6 @@ describe('selectMethods', () => {
115
106
  expectQueryNotMutated(q);
116
107
  });
117
108
 
118
- describe('select relation', () => {
119
- const profileQuery = Profile.takeOptional();
120
- const profileRelationQuery = addQueryOn(
121
- profileQuery,
122
- User,
123
- profileQuery,
124
- 'userId',
125
- 'id',
126
- );
127
- profileRelationQuery.query[relationQueryKey] = 'profile';
128
-
129
- const profileRelation = new Proxy(() => undefined, {
130
- get(_, key) {
131
- return (
132
- profileRelationQuery as unknown as Record<string | symbol, unknown>
133
- )[key];
134
- },
135
- }) as unknown as RelationQuery<
136
- 'profile',
137
- Record<string, unknown>,
138
- never,
139
- typeof profileQuery
140
- >;
141
-
142
- it('should select relation which returns one record', () => {
143
- const q = User.all();
144
-
145
- const query = q.select('id', {
146
- profile: () => profileRelation.where({ bio: 'bio' }),
147
- });
148
-
149
- assertType<
150
- Awaited<typeof query>,
151
- { id: number; profile: typeof Profile['type'] | null }[]
152
- >();
153
-
154
- expectSql(
155
- query.toSql(),
156
- `
157
- SELECT
158
- "user"."id",
159
- (
160
- SELECT row_to_json("t".*)
161
- FROM (
162
- SELECT *
163
- FROM "profile"
164
- WHERE "profile"."userId" = "user"."id"
165
- AND "profile"."bio" = $1
166
- LIMIT $2
167
- ) AS "t"
168
- ) AS "profile"
169
- FROM "user"
170
- `,
171
- ['bio', 1],
172
- );
173
-
174
- expectQueryNotMutated(q);
175
- });
176
-
177
- it('should have proper type for required relation', () => {
178
- const q = User.all();
179
-
180
- const query = q.select('id', {
181
- profile: () =>
182
- profileRelation as unknown as RelationQuery<
183
- 'profile',
184
- Record<string, unknown>,
185
- never,
186
- typeof profileRelationQuery,
187
- true
188
- >,
189
- });
190
-
191
- assertType<
192
- Awaited<typeof query>,
193
- { id: number; profile: typeof Profile['type'] }[]
194
- >();
195
- });
196
-
197
- it('should parse columns in single relation record result', async () => {
198
- const userId = await User.get('id').create(userData);
199
- const now = new Date();
200
- await Profile.create({ userId, updatedAt: now, createdAt: now });
201
-
202
- const [record] = await User.select('id', {
203
- profile: () => profileRelation,
204
- });
205
-
206
- assertType<
207
- typeof record,
208
- { id: number; profile: ProfileRecord | null }
209
- >();
210
-
211
- expect(record.profile).toMatchObject({
212
- updatedAt: now,
213
- createdAt: now,
214
- });
215
- });
216
-
217
- const messagesQuery = Message.as('messages');
218
- const messageRelationQuery = addQueryOn(
219
- messagesQuery,
220
- User,
221
- messagesQuery,
222
- 'authorId',
223
- 'id',
224
- );
225
- messageRelationQuery.query[relationQueryKey] = 'messages';
226
-
227
- const messageRelation = new Proxy(() => undefined, {
228
- get(_, key) {
229
- return (
230
- messageRelationQuery as unknown as Record<string | symbol, unknown>
231
- )[key];
232
- },
233
- }) as unknown as RelationQuery<
234
- 'messages',
235
- Record<string, unknown>,
236
- never,
237
- typeof messageRelationQuery
238
- >;
239
-
240
- it('should select relation which returns many records', () => {
241
- const q = User.all();
242
-
243
- const query = q.select('id', {
244
- messages: () => messageRelation.where({ text: 'text' }),
245
- });
246
-
247
- assertType<
248
- Awaited<typeof query>,
249
- { id: number; messages: typeof Message['type'][] }[]
250
- >();
251
-
252
- expectSql(
253
- query.toSql(),
254
- `
255
- SELECT
256
- "user"."id",
257
- (
258
- SELECT COALESCE(json_agg(row_to_json("t".*)), '[]')
259
- FROM (
260
- SELECT *
261
- FROM "message" AS "messages"
262
- WHERE "messages"."authorId" = "user"."id"
263
- AND "messages"."text" = $1
264
- ) AS "t"
265
- ) AS "messages"
266
- FROM "user"
267
- `,
268
- ['text'],
269
- );
270
-
271
- expectQueryNotMutated(q);
272
- });
273
-
274
- it('should parse columns in multiple relation records result', async () => {
275
- const { id: authorId } = await User.select('id').create(userData);
276
- const { id: chatId } = await Chat.select('id').create(chatData);
277
- await Message.create({
278
- authorId,
279
- chatId,
280
- ...messageData,
281
- createdAt: now,
282
- updatedAt: now,
283
- });
284
-
285
- const [record] = await User.select('id', {
286
- messages: () => messageRelation,
287
- });
288
-
289
- assertType<typeof record, { id: number; messages: MessageRecord[] }>();
290
-
291
- expect(record.messages[0]).toMatchObject({
292
- updatedAt: now,
293
- createdAt: now,
294
- });
295
- });
296
-
297
- it('should have proper type for conditional sub queries', async () => {
298
- const condition = true;
299
-
300
- const query = User.select('id', {
301
- hasProfile: condition
302
- ? () => profileRelation.exists()
303
- : raw(columnTypes.boolean(), 'true'),
304
- });
305
-
306
- assertType<
307
- Awaited<typeof query>,
308
- { id: number; hasProfile: boolean }[]
309
- >();
310
- });
311
- });
312
-
313
109
  describe('parse columns', () => {
314
110
  beforeEach(insertUserAndProfile);
315
111
 
@@ -440,7 +236,7 @@ describe('selectMethods', () => {
440
236
 
441
237
  it('can select raw', () => {
442
238
  const q = User.all();
443
- const query = q.select({ one: raw('1') });
239
+ const query = q.select({ one: db.raw('1') });
444
240
 
445
241
  assertType<Awaited<typeof query>, { one: unknown }[]>();
446
242
 
@@ -549,8 +345,8 @@ describe('selectMethods', () => {
549
345
 
550
346
  it('should parse raw column', async () => {
551
347
  const q = User.select({
552
- date: raw(
553
- new DateColumn().parse((input) => new Date(input)),
348
+ date: db.raw(
349
+ () => new DateColumn().parse((input) => new Date(input)),
554
350
  '"createdAt"',
555
351
  ),
556
352
  });
@@ -1,6 +1,4 @@
1
- import { assertType, User, useTestDatabase } from '../test-utils';
2
- import { raw } from '../common';
3
- import { columnTypes } from '../columnSchema';
1
+ import { assertType, db, User, useTestDatabase } from '../test-utils';
4
2
 
5
3
  describe('then', () => {
6
4
  useTestDatabase();
@@ -8,7 +6,7 @@ describe('then', () => {
8
6
  describe('catch', () => {
9
7
  it('should catch error', (done) => {
10
8
  const query = User.select({
11
- column: raw(columnTypes.boolean(), 'koko'),
9
+ column: db.raw((t) => t.boolean(), 'koko'),
12
10
  }).catch((err) => {
13
11
  expect(err.message).toBe(`column "koko" does not exist`);
14
12
  done();
@@ -1,5 +1,10 @@
1
- import { Chat, expectQueryNotMutated, expectSql, User } from '../test-utils';
2
- import { raw } from '../common';
1
+ import {
2
+ Chat,
3
+ db,
4
+ expectQueryNotMutated,
5
+ expectSql,
6
+ User,
7
+ } from '../test-utils';
3
8
 
4
9
  ['union', 'intersect', 'except'].forEach((what) => {
5
10
  const upper = what.toUpperCase();
@@ -7,10 +12,10 @@ import { raw } from '../common';
7
12
  it(`adds ${what}`, () => {
8
13
  const q = User.all();
9
14
  let query = q.select('id');
10
- query = query[what as 'union']([Chat.select('id'), raw('SELECT 1')]);
15
+ query = query[what as 'union']([Chat.select('id'), db.raw('SELECT 1')]);
11
16
  query = query[
12
17
  (what + 'All') as 'unionAll' | 'intersectAll' | 'exceptAll'
13
- ]([raw('SELECT 2')], true);
18
+ ]([db.raw('SELECT 2')], true);
14
19
 
15
20
  const wrapped = query.wrap(User.select('id'));
16
21
 
@@ -34,7 +39,7 @@ import { raw } from '../common';
34
39
 
35
40
  it('has modifier', () => {
36
41
  const q = User.select('id');
37
- q[`_${what}` as '_union']([raw('SELECT 1')]);
42
+ q[`_${what}` as '_union']([db.raw('SELECT 1')]);
38
43
  expectSql(
39
44
  q.toSql(),
40
45
  `
@@ -43,7 +48,7 @@ import { raw } from '../common';
43
48
  SELECT 1
44
49
  `,
45
50
  );
46
- q[`_${what}All` as '_unionAll']([raw('SELECT 2')], true);
51
+ q[`_${what}All` as '_unionAll']([db.raw('SELECT 2')], true);
47
52
  expectSql(
48
53
  q.toSql({ clearCache: true }),
49
54
  `
@@ -1,12 +1,12 @@
1
1
  import {
2
2
  assertType,
3
+ db,
3
4
  expectQueryNotMutated,
4
5
  expectSql,
5
6
  User,
6
7
  userData,
7
8
  useTestDatabase,
8
9
  } from '../test-utils';
9
- import { raw } from '../common';
10
10
 
11
11
  describe('update', () => {
12
12
  useTestDatabase();
@@ -37,7 +37,7 @@ describe('update', () => {
37
37
  const count = 2;
38
38
  const users = await User.select('id').createMany([userData, userData]);
39
39
 
40
- const query = User.or(...users).updateRaw(raw(`name = 'name'`));
40
+ const query = User.or(...users).updateRaw(db.raw(`name = 'name'`));
41
41
  expectSql(
42
42
  query.toSql(),
43
43
  `
@@ -254,7 +254,7 @@ describe('update', () => {
254
254
 
255
255
  it('should support raw sql as a value', () => {
256
256
  const query = User.where({ id: 1 }).update({
257
- name: raw(`'raw sql'`),
257
+ name: db.raw(`'raw sql'`),
258
258
  });
259
259
  expectSql(
260
260
  query.toSql(),