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
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
  };
@@ -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(columnTypes.boolean(), 'koko') });
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 { ColumnShapeOutput, ColumnsShape, ColumnType } from './columnSchema';
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'), { as: 'name' }).toSql(),
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,7 @@
1
1
  import { Query, SetQueryReturnsRowCount } from '../query';
2
2
 
3
+ export type DeleteMethodsNames = 'del' | '_del' | 'delete' | '_delete';
4
+
3
5
  type DeleteArgs<T extends Query> = T['hasWhere'] extends true
4
6
  ? [forceAll?: boolean]
5
7
  : [true];
@@ -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);
@@ -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(raw<NumberColumn>('count(*)::int'));
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<NumberColumn>('count(*)::int'),
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.havingOr(raw('count(*) = 1 + 2'), raw('count(*) = 2 + 3')).toSql(),
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
@@ -21,3 +21,4 @@ export * from './update';
21
21
  export * from './upsert';
22
22
  export * from './where';
23
23
  export * from './with';
24
+ export * from './raw';
@@ -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 { raw, StringKey } from '../common';
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 { assertType, expectSql, Message, Profile, User } from '../test-utils';
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<NumberColumn>('123'));
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, raw, RawExpression } from '../common';
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
+ });