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
package/src/common.ts
CHANGED
|
@@ -16,6 +16,23 @@ export type RawExpression<C extends ColumnType = ColumnType> = {
|
|
|
16
16
|
__column: C;
|
|
17
17
|
};
|
|
18
18
|
|
|
19
|
+
export const raw = (sql: string, ...values: unknown[]): RawExpression =>
|
|
20
|
+
({
|
|
21
|
+
__raw: sql,
|
|
22
|
+
__values: values,
|
|
23
|
+
} as RawExpression);
|
|
24
|
+
|
|
25
|
+
export const isRaw = (obj: object): obj is RawExpression => '__raw' in obj;
|
|
26
|
+
|
|
27
|
+
export const getRaw = (raw: RawExpression, values: unknown[]) => {
|
|
28
|
+
values.push(...raw.__values);
|
|
29
|
+
return raw.__raw;
|
|
30
|
+
};
|
|
31
|
+
|
|
32
|
+
export const getRawSql = (raw: RawExpression) => {
|
|
33
|
+
return raw.__raw;
|
|
34
|
+
};
|
|
35
|
+
|
|
19
36
|
export type Expression<
|
|
20
37
|
T extends Query = Query,
|
|
21
38
|
C extends ColumnType = ColumnType,
|
|
@@ -55,36 +72,6 @@ export type ExpressionOutput<
|
|
|
55
72
|
? ColumnType
|
|
56
73
|
: never;
|
|
57
74
|
|
|
58
|
-
export const raw = <C extends ColumnType>(
|
|
59
|
-
...args:
|
|
60
|
-
| [column: C, sql: string, ...values: unknown[]]
|
|
61
|
-
| [sql: string, ...values: unknown[]]
|
|
62
|
-
) => {
|
|
63
|
-
if (typeof args[0] === 'string') {
|
|
64
|
-
return {
|
|
65
|
-
__raw: args[0],
|
|
66
|
-
__values: args.slice(1),
|
|
67
|
-
} as RawExpression<C>;
|
|
68
|
-
} else {
|
|
69
|
-
return {
|
|
70
|
-
__column: args[0],
|
|
71
|
-
__raw: args[1],
|
|
72
|
-
__values: args.slice(2),
|
|
73
|
-
} as RawExpression<C>;
|
|
74
|
-
}
|
|
75
|
-
};
|
|
76
|
-
|
|
77
|
-
export const isRaw = (obj: object): obj is RawExpression => '__raw' in obj;
|
|
78
|
-
|
|
79
|
-
export const getRaw = (raw: RawExpression, values: unknown[]) => {
|
|
80
|
-
values.push(...raw.__values);
|
|
81
|
-
return raw.__raw;
|
|
82
|
-
};
|
|
83
|
-
|
|
84
|
-
export const getRawSql = (raw: RawExpression) => {
|
|
85
|
-
return raw.__raw;
|
|
86
|
-
};
|
|
87
|
-
|
|
88
75
|
export const EMPTY_OBJECT = {};
|
|
89
76
|
|
|
90
77
|
export const getQueryParsers = (q: Query) => {
|
package/src/db.ts
CHANGED
|
@@ -35,10 +35,11 @@ export interface Db<
|
|
|
35
35
|
Table extends string | undefined = undefined,
|
|
36
36
|
Shape extends ColumnsShape = Record<string, never>,
|
|
37
37
|
Relations extends Query['relations'] = Query['relations'],
|
|
38
|
+
CT extends ColumnTypesBase = ColumnTypesBase,
|
|
38
39
|
> extends QueryMethods {
|
|
39
40
|
new (
|
|
40
41
|
adapter: Adapter,
|
|
41
|
-
queryBuilder: Db,
|
|
42
|
+
queryBuilder: Db<Table, Shape, Relations, CT>,
|
|
42
43
|
table?: Table,
|
|
43
44
|
shape?: Shape,
|
|
44
45
|
options?: DbTableOptions,
|
|
@@ -48,6 +49,7 @@ export interface Db<
|
|
|
48
49
|
columns: (keyof ColumnShapeOutput<Shape>)[];
|
|
49
50
|
|
|
50
51
|
queryBuilder: Db;
|
|
52
|
+
columnTypes: CT;
|
|
51
53
|
whereQueryBuilder: Query['whereQueryBuilder'];
|
|
52
54
|
onQueryBuilder: Query['onQueryBuilder'];
|
|
53
55
|
table: Table;
|
|
@@ -95,6 +97,7 @@ export class Db<
|
|
|
95
97
|
Table extends string | undefined = undefined,
|
|
96
98
|
Shape extends ColumnsShape = Record<string, never>,
|
|
97
99
|
Relations extends Query['relations'] = Query['relations'],
|
|
100
|
+
CT extends ColumnTypesBase = ColumnTypesBase,
|
|
98
101
|
> implements Query
|
|
99
102
|
{
|
|
100
103
|
whereQueryBuilder = WhereQueryBuilder;
|
|
@@ -105,9 +108,10 @@ export class Db<
|
|
|
105
108
|
public queryBuilder: Db,
|
|
106
109
|
public table: Table = undefined as Table,
|
|
107
110
|
public shape: Shape = {} as Shape,
|
|
111
|
+
public columnTypes: CT,
|
|
108
112
|
options: DbTableOptions,
|
|
109
113
|
) {
|
|
110
|
-
this.__model = this;
|
|
114
|
+
this.__model = this as Query;
|
|
111
115
|
|
|
112
116
|
const logger = options.logger || console;
|
|
113
117
|
this.query = {
|
|
@@ -181,7 +185,12 @@ export class Db<
|
|
|
181
185
|
applyMixins(Db, [QueryMethods]);
|
|
182
186
|
Db.prototype.constructor = Db;
|
|
183
187
|
|
|
184
|
-
type DbResult<CT extends ColumnTypesBase> = Db
|
|
188
|
+
type DbResult<CT extends ColumnTypesBase> = Db<
|
|
189
|
+
string,
|
|
190
|
+
Record<string, never>,
|
|
191
|
+
Query['relations'],
|
|
192
|
+
CT
|
|
193
|
+
> & {
|
|
185
194
|
<Table extends string, Shape extends ColumnsShape = ColumnsShape>(
|
|
186
195
|
table: Table,
|
|
187
196
|
shape?: ((t: CT) => Shape) | Shape,
|
|
@@ -214,21 +223,23 @@ export const createDb = <CT extends ColumnTypesBase>({
|
|
|
214
223
|
undefined as unknown as Db,
|
|
215
224
|
undefined,
|
|
216
225
|
{},
|
|
226
|
+
ct,
|
|
217
227
|
commonOptions,
|
|
218
228
|
);
|
|
219
|
-
qb.queryBuilder = qb;
|
|
229
|
+
qb.queryBuilder = qb as unknown as Db;
|
|
220
230
|
|
|
221
231
|
const db = Object.assign(
|
|
222
232
|
<Table extends string, Shape extends ColumnsShape = ColumnsShape>(
|
|
223
233
|
table: Table,
|
|
224
234
|
shape?: ((t: CT) => Shape) | Shape,
|
|
225
235
|
options?: DbTableOptions,
|
|
226
|
-
): Db<Table, Shape> => {
|
|
227
|
-
return new Db<Table, Shape>(
|
|
236
|
+
): Db<Table, Shape, Query['relations'], CT> => {
|
|
237
|
+
return new Db<Table, Shape, Query['relations'], CT>(
|
|
228
238
|
adapter,
|
|
229
|
-
qb,
|
|
239
|
+
qb as unknown as Db,
|
|
230
240
|
table as Table,
|
|
231
241
|
typeof shape === 'function' ? getColumnTypes(ct, shape) : shape,
|
|
242
|
+
ct,
|
|
232
243
|
{ ...commonOptions, ...options },
|
|
233
244
|
);
|
|
234
245
|
},
|
|
@@ -242,5 +253,5 @@ export const createDb = <CT extends ColumnTypesBase>({
|
|
|
242
253
|
Db.prototype[name as keyof typeof Db.prototype];
|
|
243
254
|
});
|
|
244
255
|
|
|
245
|
-
return db as DbResult<CT>;
|
|
256
|
+
return db as unknown as DbResult<CT>;
|
|
246
257
|
};
|
package/src/errors.test.ts
CHANGED
|
@@ -1,6 +1,4 @@
|
|
|
1
|
-
import { UniqueTable, User, useTestDatabase } from './test-utils';
|
|
2
|
-
import { raw } from './common';
|
|
3
|
-
import { columnTypes } from './columnSchema';
|
|
1
|
+
import { db, UniqueTable, User, useTestDatabase } from './test-utils';
|
|
4
2
|
import { QueryError } from './errors';
|
|
5
3
|
|
|
6
4
|
describe('errors', () => {
|
|
@@ -10,7 +8,7 @@ describe('errors', () => {
|
|
|
10
8
|
let err: Error | undefined;
|
|
11
9
|
|
|
12
10
|
try {
|
|
13
|
-
await User.select({ column: raw(
|
|
11
|
+
await User.select({ column: db.raw((t) => t.boolean(), 'koko') });
|
|
14
12
|
} catch (error) {
|
|
15
13
|
err = error as Error;
|
|
16
14
|
}
|
package/src/index.ts
CHANGED
|
@@ -3,7 +3,6 @@ export * from './sql';
|
|
|
3
3
|
export * from './adapter';
|
|
4
4
|
export * from './common';
|
|
5
5
|
export * from './db';
|
|
6
|
-
export * from './columnsOperators';
|
|
7
6
|
export * from './query';
|
|
8
7
|
export * from './queryMethods';
|
|
9
8
|
export * from './quote';
|
|
@@ -11,3 +10,4 @@ export * from './utils';
|
|
|
11
10
|
export * from './queryDataUtils';
|
|
12
11
|
export * from './errors';
|
|
13
12
|
export * from './relations';
|
|
13
|
+
export * from './columnsOperators';
|
package/src/query.ts
CHANGED
|
@@ -8,7 +8,12 @@ import {
|
|
|
8
8
|
getValueKey,
|
|
9
9
|
} from './queryMethods';
|
|
10
10
|
import { QueryData } from './sql';
|
|
11
|
-
import {
|
|
11
|
+
import {
|
|
12
|
+
ColumnShapeOutput,
|
|
13
|
+
ColumnsShape,
|
|
14
|
+
ColumnType,
|
|
15
|
+
ColumnTypesBase,
|
|
16
|
+
} from './columnSchema';
|
|
12
17
|
import { EmptyObject, Spread } from './utils';
|
|
13
18
|
import { AliasOrTable, RawExpression, StringKey } from './common';
|
|
14
19
|
import { Db } from './db';
|
|
@@ -43,6 +48,7 @@ export const defaultsKey: unique symbol = Symbol('defaults');
|
|
|
43
48
|
|
|
44
49
|
export type Query = QueryMethods & {
|
|
45
50
|
queryBuilder: Db;
|
|
51
|
+
columnTypes: ColumnTypesBase;
|
|
46
52
|
whereQueryBuilder: typeof WhereQueryBuilder;
|
|
47
53
|
onQueryBuilder: typeof OnQueryBuilder;
|
|
48
54
|
table?: string;
|
|
@@ -5,8 +5,8 @@ import {
|
|
|
5
5
|
useTestDatabase,
|
|
6
6
|
userData,
|
|
7
7
|
assertType,
|
|
8
|
+
db,
|
|
8
9
|
} from '../test-utils';
|
|
9
|
-
import { raw } from '../common';
|
|
10
10
|
|
|
11
11
|
describe('aggregate', () => {
|
|
12
12
|
useTestDatabase();
|
|
@@ -340,7 +340,7 @@ describe('aggregate', () => {
|
|
|
340
340
|
|
|
341
341
|
it('should support raw sql parameter', () => {
|
|
342
342
|
const q = User.all();
|
|
343
|
-
expectSql(q[method as 'count'](raw('name')).toSql(), getSql('name'));
|
|
343
|
+
expectSql(q[method as 'count'](db.raw('name')).toSql(), getSql('name'));
|
|
344
344
|
expectQueryNotMutated(q);
|
|
345
345
|
});
|
|
346
346
|
|
|
@@ -359,7 +359,9 @@ describe('aggregate', () => {
|
|
|
359
359
|
const q = User.all();
|
|
360
360
|
const expectedSql = getSql('name', 'name');
|
|
361
361
|
expectSql(
|
|
362
|
-
q[selectMethod as 'selectCount'](raw('name'), {
|
|
362
|
+
q[selectMethod as 'selectCount'](db.raw('name'), {
|
|
363
|
+
as: 'name',
|
|
364
|
+
}).toSql(),
|
|
363
365
|
expectedSql,
|
|
364
366
|
);
|
|
365
367
|
expectQueryNotMutated(q);
|
|
@@ -436,7 +438,7 @@ describe('aggregate', () => {
|
|
|
436
438
|
const q = User.clone();
|
|
437
439
|
expectSql(
|
|
438
440
|
q[method as 'jsonObjectAgg']({
|
|
439
|
-
alias: raw('name'),
|
|
441
|
+
alias: db.raw('name'),
|
|
440
442
|
}).toSql(),
|
|
441
443
|
`SELECT ${functionName}($1::text, name) FROM "user"`,
|
|
442
444
|
['alias'],
|
|
@@ -463,7 +465,7 @@ describe('aggregate', () => {
|
|
|
463
465
|
const expectedSql = `SELECT ${functionName}($1::text, name) AS "name" FROM "user"`;
|
|
464
466
|
expectSql(
|
|
465
467
|
q[selectMethod as 'jsonObjectAgg'](
|
|
466
|
-
{ alias: raw('name') },
|
|
468
|
+
{ alias: db.raw('name') },
|
|
467
469
|
{ as: 'name' },
|
|
468
470
|
).toSql(),
|
|
469
471
|
expectedSql,
|
|
@@ -525,7 +527,7 @@ describe('aggregate', () => {
|
|
|
525
527
|
it('should support raw sql parameter', async () => {
|
|
526
528
|
const q = User.all();
|
|
527
529
|
expectSql(
|
|
528
|
-
q.stringAgg(raw('name'), ' & ').toSql(),
|
|
530
|
+
q.stringAgg(db.raw('name'), ' & ').toSql(),
|
|
529
531
|
`SELECT string_agg(name, $1) FROM "user"`,
|
|
530
532
|
[' & '],
|
|
531
533
|
);
|
|
@@ -547,7 +549,7 @@ describe('aggregate', () => {
|
|
|
547
549
|
const q = User.all();
|
|
548
550
|
const expectedSql = `SELECT string_agg(name, $1) AS "name" FROM "user"`;
|
|
549
551
|
expectSql(
|
|
550
|
-
q.stringAgg(raw('name'), ' & ', { as: 'name' }).toSql(),
|
|
552
|
+
q.stringAgg(db.raw('name'), ' & ', { as: 'name' }).toSql(),
|
|
551
553
|
expectedSql,
|
|
552
554
|
[' & '],
|
|
553
555
|
);
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import {
|
|
2
2
|
assertType,
|
|
3
3
|
Chat,
|
|
4
|
+
db,
|
|
4
5
|
expectQueryNotMutated,
|
|
5
6
|
expectSql,
|
|
6
7
|
Message,
|
|
@@ -10,7 +11,6 @@ import {
|
|
|
10
11
|
UserRecord,
|
|
11
12
|
useTestDatabase,
|
|
12
13
|
} from '../test-utils';
|
|
13
|
-
import { raw } from '../common';
|
|
14
14
|
import { OnConflictQueryBuilder } from './create';
|
|
15
15
|
|
|
16
16
|
describe('create functions', () => {
|
|
@@ -22,7 +22,7 @@ describe('create functions', () => {
|
|
|
22
22
|
|
|
23
23
|
const query = q.createRaw({
|
|
24
24
|
columns: ['name', 'password'],
|
|
25
|
-
values: raw('raw sql'),
|
|
25
|
+
values: db.raw('raw sql'),
|
|
26
26
|
});
|
|
27
27
|
expectSql(
|
|
28
28
|
query.toSql(),
|
|
@@ -414,7 +414,7 @@ describe('create functions', () => {
|
|
|
414
414
|
const query = q
|
|
415
415
|
.count()
|
|
416
416
|
.create(userData)
|
|
417
|
-
.onConflict(raw('raw query'))
|
|
417
|
+
.onConflict(db.raw('raw query'))
|
|
418
418
|
.ignore();
|
|
419
419
|
expectSql(
|
|
420
420
|
query.toSql(),
|
|
@@ -527,8 +527,8 @@ describe('create functions', () => {
|
|
|
527
527
|
const query = q
|
|
528
528
|
.count()
|
|
529
529
|
.create(userData)
|
|
530
|
-
.onConflict(raw('on conflict raw'))
|
|
531
|
-
.merge(raw('merge raw'));
|
|
530
|
+
.onConflict(db.raw('on conflict raw'))
|
|
531
|
+
.merge(db.raw('merge raw'));
|
|
532
532
|
|
|
533
533
|
expectSql(
|
|
534
534
|
query.toSql(),
|
|
@@ -8,7 +8,6 @@ import {
|
|
|
8
8
|
SetQueryReturnsOne,
|
|
9
9
|
} from '../query';
|
|
10
10
|
import { pushQueryArray } from '../queryDataUtils';
|
|
11
|
-
import { RawExpression } from '../common';
|
|
12
11
|
import {
|
|
13
12
|
BelongsToNestedInsert,
|
|
14
13
|
BelongsToRelation,
|
|
@@ -26,6 +25,7 @@ import { InsertQueryData, OnConflictItem, OnConflictMergeUpdate } from '../sql';
|
|
|
26
25
|
import { WhereArg } from './where';
|
|
27
26
|
import { parseResult, queryMethodByReturnType } from './then';
|
|
28
27
|
import { NotFoundError } from '../errors';
|
|
28
|
+
import { RawExpression } from '../common';
|
|
29
29
|
|
|
30
30
|
export type CreateData<
|
|
31
31
|
T extends Query,
|
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
import { expectQueryNotMutated, expectSql, User } from '../test-utils';
|
|
2
|
-
import { raw } from '../common';
|
|
3
2
|
|
|
4
3
|
describe('for', () => {
|
|
5
4
|
describe.each`
|
|
@@ -30,7 +29,7 @@ describe('for', () => {
|
|
|
30
29
|
it('should accept raw sql', () => {
|
|
31
30
|
const q = User.all();
|
|
32
31
|
expectSql(
|
|
33
|
-
q[method as 'forUpdate'](raw('raw sql')).toSql(),
|
|
32
|
+
q[method as 'forUpdate'](User.raw('raw sql')).toSql(),
|
|
34
33
|
`SELECT * FROM "user" FOR ${sql} OF raw sql`,
|
|
35
34
|
);
|
|
36
35
|
expectQueryNotMutated(q);
|
package/src/queryMethods/for.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { Query } from '../query';
|
|
2
|
-
import { RawExpression } from '../common';
|
|
3
2
|
import { SelectQueryData } from '../sql';
|
|
3
|
+
import { RawExpression } from '../common';
|
|
4
4
|
|
|
5
5
|
type ForQueryBuilder<Q extends Query> = Q & {
|
|
6
6
|
noWait<T extends ForQueryBuilder<Q>>(this: T): T;
|
|
@@ -1,5 +1,4 @@
|
|
|
1
|
-
import { expectQueryNotMutated, expectSql, User } from '../test-utils';
|
|
2
|
-
import { raw } from '../common';
|
|
1
|
+
import { db, expectQueryNotMutated, expectSql, User } from '../test-utils';
|
|
3
2
|
|
|
4
3
|
describe('from', () => {
|
|
5
4
|
it('should accept string parameter', () => {
|
|
@@ -20,7 +19,7 @@ describe('from', () => {
|
|
|
20
19
|
it('should accept raw parameter', () => {
|
|
21
20
|
const q = User.all();
|
|
22
21
|
expectSql(
|
|
23
|
-
q.as('t').from(raw('profile')).toSql(),
|
|
22
|
+
q.as('t').from(db.raw('profile')).toSql(),
|
|
24
23
|
`SELECT * FROM profile AS "t"`,
|
|
25
24
|
);
|
|
26
25
|
expectQueryNotMutated(q);
|
|
@@ -1,7 +1,5 @@
|
|
|
1
|
-
import { assertType, User, userData, useTestDatabase } from '../test-utils';
|
|
2
|
-
import { NumberColumn } from '../columnSchema';
|
|
1
|
+
import { assertType, db, User, userData, useTestDatabase } from '../test-utils';
|
|
3
2
|
import { NotFoundError } from '../errors';
|
|
4
|
-
import { raw } from '../common';
|
|
5
3
|
|
|
6
4
|
describe('get', () => {
|
|
7
5
|
useTestDatabase();
|
|
@@ -18,7 +16,9 @@ describe('get', () => {
|
|
|
18
16
|
});
|
|
19
17
|
|
|
20
18
|
it('should select raw and return a single value', async () => {
|
|
21
|
-
const received = await User.get(
|
|
19
|
+
const received = await User.get(
|
|
20
|
+
db.raw((t) => t.integer(), 'count(*)::int'),
|
|
21
|
+
);
|
|
22
22
|
|
|
23
23
|
assertType<typeof received, number>();
|
|
24
24
|
|
|
@@ -43,7 +43,7 @@ describe('get', () => {
|
|
|
43
43
|
|
|
44
44
|
it('should select raw and return a single value when exists', async () => {
|
|
45
45
|
const received = await User.getOptional(
|
|
46
|
-
raw
|
|
46
|
+
db.raw((t) => t.integer(), 'count(*)::int'),
|
|
47
47
|
);
|
|
48
48
|
|
|
49
49
|
assertType<typeof received, number | undefined>();
|
|
@@ -1,5 +1,4 @@
|
|
|
1
|
-
import { expectQueryNotMutated, expectSql, User } from '../test-utils';
|
|
2
|
-
import { raw } from '../common';
|
|
1
|
+
import { db, expectQueryNotMutated, expectSql, User } from '../test-utils';
|
|
3
2
|
|
|
4
3
|
describe('having', () => {
|
|
5
4
|
it('should support { count: value } object', () => {
|
|
@@ -196,12 +195,12 @@ describe('having', () => {
|
|
|
196
195
|
`;
|
|
197
196
|
|
|
198
197
|
expectSql(
|
|
199
|
-
q.having(raw('count(*) = 1'), raw('sum(id) = 2')).toSql(),
|
|
198
|
+
q.having(db.raw('count(*) = 1'), db.raw('sum(id) = 2')).toSql(),
|
|
200
199
|
expectedSql,
|
|
201
200
|
);
|
|
202
201
|
expectQueryNotMutated(q);
|
|
203
202
|
|
|
204
|
-
q._having(raw('count(*) = 1'), raw('sum(id) = 2'));
|
|
203
|
+
q._having(db.raw('count(*) = 1'), db.raw('sum(id) = 2'));
|
|
205
204
|
expectSql(q.toSql({ clearCache: true }), expectedSql);
|
|
206
205
|
});
|
|
207
206
|
|
|
@@ -235,7 +234,9 @@ describe('having', () => {
|
|
|
235
234
|
it('should accept raw sql', () => {
|
|
236
235
|
const q = User.all();
|
|
237
236
|
expectSql(
|
|
238
|
-
q
|
|
237
|
+
q
|
|
238
|
+
.havingOr(db.raw('count(*) = 1 + 2'), db.raw('count(*) = 2 + 3'))
|
|
239
|
+
.toSql(),
|
|
239
240
|
`
|
|
240
241
|
SELECT * FROM "user"
|
|
241
242
|
HAVING count(*) = 1 + 2 OR count(*) = 2 + 3
|
package/src/queryMethods/json.ts
CHANGED
|
@@ -7,7 +7,7 @@ import {
|
|
|
7
7
|
import { pushQueryValue } from '../queryDataUtils';
|
|
8
8
|
import { ColumnType, StringColumn } from '../columnSchema';
|
|
9
9
|
import { JsonItem } from '../sql';
|
|
10
|
-
import {
|
|
10
|
+
import { StringKey } from '../common';
|
|
11
11
|
|
|
12
12
|
type JsonColumnName<T extends Pick<Query, 'selectable'>> = StringKey<
|
|
13
13
|
{
|
|
@@ -55,7 +55,7 @@ export class Json {
|
|
|
55
55
|
): SetQueryReturnsValueOptional<T, StringColumn> {
|
|
56
56
|
const q = this._wrap(this.__model.clone()) as T;
|
|
57
57
|
q._getOptional(
|
|
58
|
-
raw<StringColumn>(
|
|
58
|
+
this.raw<Query, StringColumn>(
|
|
59
59
|
queryTypeWithLimitOne[this.query.returnType]
|
|
60
60
|
? `row_to_json("t".*)`
|
|
61
61
|
: `COALESCE(json_agg(row_to_json("t".*)), '[]')`,
|
|
@@ -1,4 +1,11 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import {
|
|
2
|
+
assertType,
|
|
3
|
+
db,
|
|
4
|
+
expectSql,
|
|
5
|
+
Message,
|
|
6
|
+
Profile,
|
|
7
|
+
User,
|
|
8
|
+
} from '../test-utils';
|
|
2
9
|
import { QueryReturnType } from '../query';
|
|
3
10
|
import { IntegerColumn, TextColumn } from '../columnSchema';
|
|
4
11
|
import { getValueKey } from './get';
|
|
@@ -11,7 +18,6 @@ import {
|
|
|
11
18
|
TruncateQueryData,
|
|
12
19
|
UpdateQueryData,
|
|
13
20
|
} from '../sql';
|
|
14
|
-
import { raw } from '../common';
|
|
15
21
|
|
|
16
22
|
describe('merge queries', () => {
|
|
17
23
|
describe('select', () => {
|
|
@@ -350,8 +356,8 @@ describe('merge queries', () => {
|
|
|
350
356
|
s2.having = [{ b: { b: 2 } }];
|
|
351
357
|
s1.havingOr = [[{ a: { a: 1 } }]];
|
|
352
358
|
s2.havingOr = [[{ b: { b: 2 } }]];
|
|
353
|
-
s1.union = [{ arg: raw('a'), kind: 'UNION' }];
|
|
354
|
-
s2.union = [{ arg: raw('b'), kind: 'EXCEPT' }];
|
|
359
|
+
s1.union = [{ arg: db.raw('a'), kind: 'UNION' }];
|
|
360
|
+
s2.union = [{ arg: db.raw('b'), kind: 'EXCEPT' }];
|
|
355
361
|
s1.order = [{ id: 'ASC' }];
|
|
356
362
|
s2.order = [{ name: 'DESC' }];
|
|
357
363
|
s1.limit = 1;
|
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
import { raw } from '../common';
|
|
2
1
|
import {
|
|
3
2
|
expectQueryNotMutated,
|
|
4
3
|
adapter,
|
|
@@ -12,7 +11,6 @@ import {
|
|
|
12
11
|
assertType,
|
|
13
12
|
UserRecord,
|
|
14
13
|
} from '../test-utils';
|
|
15
|
-
import { NumberColumn } from '../columnSchema';
|
|
16
14
|
import { NotFoundError } from '../errors';
|
|
17
15
|
|
|
18
16
|
describe('queryMethods', () => {
|
|
@@ -126,7 +124,7 @@ describe('queryMethods', () => {
|
|
|
126
124
|
});
|
|
127
125
|
|
|
128
126
|
it('should support raw expression', async () => {
|
|
129
|
-
const result = await User.pluck(raw
|
|
127
|
+
const result = await User.pluck(db.raw((t) => t.integer(), '123'));
|
|
130
128
|
expect(result).toEqual([123, 123, 123]);
|
|
131
129
|
|
|
132
130
|
assertType<typeof result, number[]>();
|
|
@@ -206,7 +204,7 @@ describe('queryMethods', () => {
|
|
|
206
204
|
it('should add distinct on raw sql', () => {
|
|
207
205
|
const q = User.all();
|
|
208
206
|
expectSql(
|
|
209
|
-
q.distinct(raw('"user".id')).toSql(),
|
|
207
|
+
q.distinct(db.raw('"user".id')).toSql(),
|
|
210
208
|
`
|
|
211
209
|
SELECT DISTINCT ON ("user".id) * FROM "user"
|
|
212
210
|
`,
|
|
@@ -236,7 +234,7 @@ describe('queryMethods', () => {
|
|
|
236
234
|
|
|
237
235
|
it('should accept raw sql', () => {
|
|
238
236
|
const q = User.all();
|
|
239
|
-
const query = q.find(raw('$1 + $2', 1, 2));
|
|
237
|
+
const query = q.find(db.raw('$1 + $2', 1, 2));
|
|
240
238
|
|
|
241
239
|
assertType<Awaited<typeof query>, UserRecord>();
|
|
242
240
|
|
|
@@ -274,7 +272,7 @@ describe('queryMethods', () => {
|
|
|
274
272
|
|
|
275
273
|
it('should accept raw sql', () => {
|
|
276
274
|
const q = User.all();
|
|
277
|
-
const query = q.findOptional(raw('$1 + $2', 1, 2));
|
|
275
|
+
const query = q.findOptional(db.raw('$1 + $2', 1, 2));
|
|
278
276
|
|
|
279
277
|
assertType<Awaited<typeof query>, UserRecord | undefined>();
|
|
280
278
|
|
|
@@ -305,7 +303,7 @@ describe('queryMethods', () => {
|
|
|
305
303
|
it('should accept raw', () => {
|
|
306
304
|
const q = User.all();
|
|
307
305
|
expectSql(
|
|
308
|
-
q.findBy({ name: raw(`'string'`) }).toSql(),
|
|
306
|
+
q.findBy({ name: db.raw(`'string'`) }).toSql(),
|
|
309
307
|
`SELECT * FROM "user" WHERE "user"."name" = 'string' LIMIT $1`,
|
|
310
308
|
[1],
|
|
311
309
|
);
|
|
@@ -330,7 +328,7 @@ describe('queryMethods', () => {
|
|
|
330
328
|
|
|
331
329
|
it('should accept raw', () => {
|
|
332
330
|
const q = User.all();
|
|
333
|
-
const query = q.findByOptional({ name: raw(`'string'`) });
|
|
331
|
+
const query = q.findByOptional({ name: db.raw(`'string'`) });
|
|
334
332
|
|
|
335
333
|
assertType<Awaited<typeof query>, UserRecord | undefined>();
|
|
336
334
|
|
|
@@ -431,10 +429,10 @@ describe('queryMethods', () => {
|
|
|
431
429
|
SELECT * FROM "user"
|
|
432
430
|
GROUP BY id, name
|
|
433
431
|
`;
|
|
434
|
-
expectSql(q.group(raw('id'), raw('name')).toSql(), expectedSql);
|
|
432
|
+
expectSql(q.group(db.raw('id'), db.raw('name')).toSql(), expectedSql);
|
|
435
433
|
expectQueryNotMutated(q);
|
|
436
434
|
|
|
437
|
-
q._group(raw('id'), raw('name'));
|
|
435
|
+
q._group(db.raw('id'), db.raw('name'));
|
|
438
436
|
expectSql(q.toSql({ clearCache: true }), expectedSql);
|
|
439
437
|
});
|
|
440
438
|
});
|
|
@@ -471,7 +469,7 @@ describe('queryMethods', () => {
|
|
|
471
469
|
const windowSql = 'PARTITION BY id ORDER BY name DESC';
|
|
472
470
|
expectSql(
|
|
473
471
|
q
|
|
474
|
-
.window({ w: raw(windowSql) })
|
|
472
|
+
.window({ w: db.raw(windowSql) })
|
|
475
473
|
.selectAvg('id', {
|
|
476
474
|
over: 'w',
|
|
477
475
|
})
|
|
@@ -527,7 +525,7 @@ describe('queryMethods', () => {
|
|
|
527
525
|
it('adds order with raw sql', () => {
|
|
528
526
|
const q = User.all();
|
|
529
527
|
expectSql(
|
|
530
|
-
q.order(raw('id ASC NULLS FIRST')).toSql(),
|
|
528
|
+
q.order(db.raw('id ASC NULLS FIRST')).toSql(),
|
|
531
529
|
`
|
|
532
530
|
SELECT * FROM "user"
|
|
533
531
|
ORDER BY id ASC NULLS FIRST
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { Expression,
|
|
1
|
+
import { Expression, RawExpression } from '../common';
|
|
2
2
|
import {
|
|
3
3
|
Query,
|
|
4
4
|
QueryBase,
|
|
@@ -48,6 +48,7 @@ import { QueryCallbacks } from './callbacks';
|
|
|
48
48
|
import { QueryUpsert } from './upsert';
|
|
49
49
|
import { QueryGet } from './get';
|
|
50
50
|
import { MergeQueryMethods } from './merge';
|
|
51
|
+
import { RawMethods } from './raw';
|
|
51
52
|
|
|
52
53
|
export type WindowArg<T extends Query> = Record<
|
|
53
54
|
string,
|
|
@@ -96,7 +97,8 @@ export interface QueryMethods
|
|
|
96
97
|
QueryCallbacks,
|
|
97
98
|
QueryUpsert,
|
|
98
99
|
QueryGet,
|
|
99
|
-
MergeQueryMethods
|
|
100
|
+
MergeQueryMethods,
|
|
101
|
+
RawMethods {}
|
|
100
102
|
|
|
101
103
|
export class QueryMethods {
|
|
102
104
|
windows!: EmptyObject;
|
|
@@ -309,7 +311,7 @@ export class QueryMethods {
|
|
|
309
311
|
return query
|
|
310
312
|
.as(as ?? 't')
|
|
311
313
|
._from(
|
|
312
|
-
raw(`(${sql.text})`, ...sql.values),
|
|
314
|
+
this.raw(`(${sql.text})`, ...sql.values),
|
|
313
315
|
) as unknown as SetQueryTableAlias<Q, As>;
|
|
314
316
|
}
|
|
315
317
|
|
|
@@ -344,7 +346,7 @@ export class QueryMethods {
|
|
|
344
346
|
}
|
|
345
347
|
|
|
346
348
|
_exists<T extends Query>(this: T): SetQueryReturnsValue<T, BooleanColumn> {
|
|
347
|
-
const q = this._getOptional(raw<BooleanColumn>('true'));
|
|
349
|
+
const q = this._getOptional(this.raw<Query, BooleanColumn>('true'));
|
|
348
350
|
q.query.notFoundDefault = false;
|
|
349
351
|
q.query.coalesceValue = false;
|
|
350
352
|
return q as unknown as SetQueryReturnsValue<T, BooleanColumn>;
|
|
@@ -397,4 +399,5 @@ applyMixins(QueryMethods, [
|
|
|
397
399
|
QueryUpsert,
|
|
398
400
|
QueryGet,
|
|
399
401
|
MergeQueryMethods,
|
|
402
|
+
RawMethods,
|
|
400
403
|
]);
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { ColumnType } from '../columnSchema';
|
|
2
|
+
import { createDb } from '../db';
|
|
3
|
+
import { adapter } from '../test-utils';
|
|
4
|
+
|
|
5
|
+
describe('raw', () => {
|
|
6
|
+
it('should use column types in callback from a db instance', () => {
|
|
7
|
+
const type = {} as unknown as ColumnType;
|
|
8
|
+
const db = createDb({
|
|
9
|
+
adapter,
|
|
10
|
+
columnTypes: {
|
|
11
|
+
type: () => type,
|
|
12
|
+
},
|
|
13
|
+
});
|
|
14
|
+
|
|
15
|
+
const value = db.raw((t) => t.type(), 'sql');
|
|
16
|
+
|
|
17
|
+
expect(value.__column).toBe(type);
|
|
18
|
+
});
|
|
19
|
+
});
|