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.
- package/dist/index.d.ts +24 -13
- package/dist/index.esm.js +44 -33
- package/dist/index.esm.js.map +1 -1
- package/dist/index.js +44 -32
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
- package/src/columnSchema/columnTypes.test.ts +55 -53
- package/src/columnSchema/timestamps.test.ts +3 -4
- package/src/columnSchema/timestamps.ts +1 -1
- package/src/columnsOperators.test.ts +18 -19
- package/src/columnsOperators.ts +1 -1
- package/src/common.ts +17 -30
- package/src/db.ts +19 -8
- package/src/errors.test.ts +2 -4
- package/src/index.ts +1 -1
- package/src/query.ts +7 -1
- package/src/queryMethods/aggregate.test.ts +9 -7
- package/src/queryMethods/create.test.ts +5 -5
- package/src/queryMethods/create.ts +1 -1
- package/src/queryMethods/delete.ts +2 -0
- package/src/queryMethods/for.test.ts +1 -2
- package/src/queryMethods/for.ts +1 -1
- package/src/queryMethods/from.test.ts +2 -3
- package/src/queryMethods/get.test.ts +5 -5
- package/src/queryMethods/having.test.ts +6 -5
- package/src/queryMethods/index.ts +1 -0
- package/src/queryMethods/json.ts +2 -2
- package/src/queryMethods/merge.test.ts +10 -4
- package/src/queryMethods/queryMethods.test.ts +10 -12
- package/src/queryMethods/queryMethods.ts +7 -4
- package/src/queryMethods/raw.test.ts +19 -0
- package/src/queryMethods/raw.ts +27 -0
- package/src/queryMethods/select.test.ts +5 -209
- package/src/queryMethods/then.test.ts +2 -4
- package/src/queryMethods/union.test.ts +11 -6
- package/src/queryMethods/update.test.ts +3 -3
- package/src/queryMethods/where.test.ts +65 -56
- package/src/queryMethods/where.ts +1 -1
- package/src/queryMethods/with.test.ts +5 -6
- package/src/relations.ts +15 -4
- package/src/sql/common.ts +0 -1
- package/src/sql/fromAndAs.ts +1 -1
- package/src/sql/insert.ts +1 -1
- package/src/sql/join.ts +1 -1
- package/src/sql/orderBy.ts +1 -1
- package/src/sql/select.ts +1 -2
- package/src/sql/toSql.ts +1 -1
- package/src/sql/update.ts +1 -1
- package/src/sql/where.ts +1 -1
- package/src/sql/window.ts +3 -4
- 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
|
-
|
|
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 {
|
|
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(
|
|
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 {
|
|
2
|
-
|
|
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(),
|