pqb 0.3.2 → 0.3.4

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.
@@ -1,17 +1,16 @@
1
1
  import { raw } from '../common';
2
- import { SelectQueryData } from '../sql';
3
2
  import {
4
3
  expectQueryNotMutated,
5
4
  adapter,
6
5
  User,
7
6
  Profile,
8
- AssertEqual,
9
7
  useTestDatabase,
10
8
  db,
11
9
  expectSql,
12
10
  userData,
13
11
  now,
14
12
  assertType,
13
+ UserRecord,
15
14
  } from '../test-utils';
16
15
  import { NumberColumn } from '../columnSchema';
17
16
  import { NotFoundError } from '../errors';
@@ -26,8 +25,7 @@ describe('queryMethods', () => {
26
25
  expect(cloned.table).toBe(User.table);
27
26
  expect(cloned.shape).toBe(User.shape);
28
27
 
29
- const eq: AssertEqual<typeof User, typeof cloned> = true;
30
- expect(eq).toBe(true);
28
+ assertType<typeof User, typeof cloned>();
31
29
  });
32
30
  });
33
31
 
@@ -36,19 +34,11 @@ describe('queryMethods', () => {
36
34
  const sql = User.toSql();
37
35
  expectSql(sql, `SELECT * FROM "user"`);
38
36
 
39
- const eq: AssertEqual<typeof sql, { text: string; values: unknown[] }> =
40
- true;
41
- expect(eq).toBe(true);
37
+ assertType<typeof sql, { text: string; values: unknown[] }>();
42
38
  });
43
39
  });
44
40
 
45
41
  describe('.all', () => {
46
- it('should remove `take` from query if it is set', () => {
47
- const q = User.take();
48
- expect((q.query as SelectQueryData)?.take).toBe(true);
49
- expect((q.all().query as SelectQueryData)?.take).toBe(undefined);
50
- });
51
-
52
42
  it('should produce correct sql', () => {
53
43
  expectSql(User.all().toSql(), `SELECT * FROM "user"`);
54
44
  });
@@ -67,8 +57,7 @@ describe('queryMethods', () => {
67
57
  .then((res) => res.rows[0]);
68
58
 
69
59
  const user = await q.take();
70
- const eq: AssertEqual<typeof user, typeof User.type> = true;
71
- expect(eq).toBe(true);
60
+ assertType<typeof user, UserRecord>();
72
61
 
73
62
  expect(user).toEqual({
74
63
  ...expected,
@@ -95,8 +84,7 @@ describe('queryMethods', () => {
95
84
  .then((res) => res.rows[0]);
96
85
 
97
86
  const user = await q.takeOptional();
98
- const eq: AssertEqual<typeof user, typeof User.type | undefined> = true;
99
- expect(eq).toBe(true);
87
+ assertType<typeof user, UserRecord | undefined>();
100
88
 
101
89
  expect(user).toEqual({
102
90
  ...expected,
@@ -107,8 +95,7 @@ describe('queryMethods', () => {
107
95
 
108
96
  it('should return undefined if not found', async () => {
109
97
  const user = await User.takeOptional();
110
- const eq: AssertEqual<typeof user, typeof User.type | undefined> = true;
111
- expect(eq).toBe(true);
98
+ assertType<typeof user, UserRecord | undefined>();
112
99
 
113
100
  expect(user).toBe(undefined);
114
101
  });
@@ -122,12 +109,6 @@ describe('queryMethods', () => {
122
109
  const received = await User.rows();
123
110
  expect(received).toEqual(expected);
124
111
  });
125
-
126
- it('removes `take` from query data', () => {
127
- expect((User.take().rows().query as SelectQueryData)?.take).toBe(
128
- undefined,
129
- );
130
- });
131
112
  });
132
113
 
133
114
  describe('pluck', () => {
@@ -141,16 +122,14 @@ describe('queryMethods', () => {
141
122
  const result = await User.pluck('createdAt');
142
123
  expect(result).toEqual([now, now, now]);
143
124
 
144
- const eq: AssertEqual<typeof result, Date[]> = true;
145
- expect(eq).toBe(true);
125
+ assertType<typeof result, Date[]>();
146
126
  });
147
127
 
148
128
  it('should support raw expression', async () => {
149
129
  const result = await User.pluck(raw<NumberColumn>('123'));
150
130
  expect(result).toEqual([123, 123, 123]);
151
131
 
152
- const eq: AssertEqual<typeof result, number[]> = true;
153
- expect(eq).toBe(true);
132
+ assertType<typeof result, number[]>();
154
133
  });
155
134
  });
156
135
 
@@ -159,12 +138,6 @@ describe('queryMethods', () => {
159
138
  const received = await User.exec();
160
139
  expect(received).toEqual(undefined);
161
140
  });
162
-
163
- it('removes `take` from query data', () => {
164
- expect((User.take().exec().query as SelectQueryData)?.take).toBe(
165
- undefined,
166
- );
167
- });
168
141
  });
169
142
 
170
143
  describe('distinct', () => {
@@ -247,8 +220,7 @@ describe('queryMethods', () => {
247
220
  const q = User.all();
248
221
  const query = q.find(1);
249
222
 
250
- const eq: AssertEqual<Awaited<typeof query>, typeof User.type> = true;
251
- expect(eq).toBe(true);
223
+ assertType<Awaited<typeof query>, UserRecord>();
252
224
 
253
225
  expectSql(
254
226
  query.toSql(),
@@ -266,8 +238,7 @@ describe('queryMethods', () => {
266
238
  const q = User.all();
267
239
  const query = q.find(raw('$1 + $2', 1, 2));
268
240
 
269
- const eq: AssertEqual<Awaited<typeof query>, typeof User.type> = true;
270
- expect(eq).toBe(true);
241
+ assertType<Awaited<typeof query>, UserRecord>();
271
242
 
272
243
  expectSql(
273
244
  query.toSql(),
@@ -287,11 +258,7 @@ describe('queryMethods', () => {
287
258
  const q = User.all();
288
259
  const query = q.findOptional(1);
289
260
 
290
- const eq: AssertEqual<
291
- Awaited<typeof query>,
292
- typeof User.type | undefined
293
- > = true;
294
- expect(eq).toBe(true);
261
+ assertType<Awaited<typeof query>, UserRecord | undefined>();
295
262
 
296
263
  expectSql(
297
264
  query.toSql(),
@@ -309,11 +276,7 @@ describe('queryMethods', () => {
309
276
  const q = User.all();
310
277
  const query = q.findOptional(raw('$1 + $2', 1, 2));
311
278
 
312
- const eq: AssertEqual<
313
- Awaited<typeof query>,
314
- typeof User.type | undefined
315
- > = true;
316
- expect(eq).toBe(true);
279
+ assertType<Awaited<typeof query>, UserRecord | undefined>();
317
280
 
318
281
  expectSql(
319
282
  query.toSql(),
@@ -355,11 +318,7 @@ describe('queryMethods', () => {
355
318
  const q = User.all();
356
319
  const query = q.findByOptional({ name: 's' });
357
320
 
358
- const eq: AssertEqual<
359
- Awaited<typeof query>,
360
- typeof User.type | undefined
361
- > = true;
362
- expect(eq).toBe(true);
321
+ assertType<Awaited<typeof query>, UserRecord | undefined>();
363
322
 
364
323
  expectSql(
365
324
  query.toSql(),
@@ -373,11 +332,7 @@ describe('queryMethods', () => {
373
332
  const q = User.all();
374
333
  const query = q.findByOptional({ name: raw(`'string'`) });
375
334
 
376
- const eq: AssertEqual<
377
- Awaited<typeof query>,
378
- typeof User.type | undefined
379
- > = true;
380
- expect(eq).toBe(true);
335
+ assertType<Awaited<typeof query>, UserRecord | undefined>();
381
336
 
382
337
  expectSql(
383
338
  query.toSql(),
@@ -13,12 +13,7 @@ import {
13
13
  SetQueryTableAlias,
14
14
  SetQueryWindows,
15
15
  } from '../query';
16
- import {
17
- applyMixins,
18
- getClonedQueryData,
19
- GetTypesOrRaw,
20
- PropertyKeyUnionToArray,
21
- } from '../utils';
16
+ import { applyMixins, EmptyObject, getClonedQueryData } from '../utils';
22
17
  import {
23
18
  SelectItem,
24
19
  SelectQueryData,
@@ -28,11 +23,7 @@ import {
28
23
  ToSqlOptions,
29
24
  TruncateQueryData,
30
25
  } from '../sql';
31
- import {
32
- pushQueryArray,
33
- pushQueryValue,
34
- removeFromQuery,
35
- } from '../queryDataUtils';
26
+ import { pushQueryArray, pushQueryValue } from '../queryDataUtils';
36
27
  import { Then } from './then';
37
28
  import { BooleanColumn } from '../columnSchema';
38
29
  import { Aggregate } from './aggregate';
@@ -56,6 +47,7 @@ import { QueryLog } from './log';
56
47
  import { QueryCallbacks } from './callbacks';
57
48
  import { QueryUpsert } from './upsert';
58
49
  import { QueryGet } from './get';
50
+ import { MergeQueryMethods } from './merge';
59
51
 
60
52
  export type WindowArg<T extends Query> = Record<
61
53
  string,
@@ -69,7 +61,7 @@ export type WindowArgDeclaration<T extends Query = Query> = {
69
61
 
70
62
  type WindowResult<T extends Query, W extends WindowArg<T>> = SetQueryWindows<
71
63
  T,
72
- PropertyKeyUnionToArray<keyof W>
64
+ Record<keyof W, true>
73
65
  >;
74
66
 
75
67
  export type OrderArg<T extends Query> =
@@ -103,10 +95,11 @@ export interface QueryMethods
103
95
  QueryLog,
104
96
  QueryCallbacks,
105
97
  QueryUpsert,
106
- QueryGet {}
98
+ QueryGet,
99
+ MergeQueryMethods {}
107
100
 
108
101
  export class QueryMethods {
109
- windows!: PropertyKey[];
102
+ windows!: EmptyObject;
110
103
  __model!: Query;
111
104
 
112
105
  all<T extends Query>(this: T): SetQueryReturnsAll<T> {
@@ -115,7 +108,6 @@ export class QueryMethods {
115
108
 
116
109
  _all<T extends Query>(this: T): SetQueryReturnsAll<T> {
117
110
  this.query.returnType = 'all';
118
- removeFromQuery(this, 'take');
119
111
  return this as unknown as SetQueryReturnsAll<T>;
120
112
  }
121
113
 
@@ -125,7 +117,6 @@ export class QueryMethods {
125
117
 
126
118
  _take<T extends Query>(this: T): SetQueryReturnsOne<T> {
127
119
  this.query.returnType = 'oneOrThrow';
128
- this.query.take = true;
129
120
  return this as unknown as SetQueryReturnsOne<T>;
130
121
  }
131
122
 
@@ -135,7 +126,6 @@ export class QueryMethods {
135
126
 
136
127
  _takeOptional<T extends Query>(this: T): SetQueryReturnsOneOptional<T> {
137
128
  this.query.returnType = 'one';
138
- this.query.take = true;
139
129
  return this as unknown as SetQueryReturnsOneOptional<T>;
140
130
  }
141
131
 
@@ -145,7 +135,6 @@ export class QueryMethods {
145
135
 
146
136
  _rows<T extends Query>(this: T): SetQueryReturnsRows<T> {
147
137
  this.query.returnType = 'rows';
148
- removeFromQuery(this, 'take');
149
138
  return this as unknown as SetQueryReturnsRows<T>;
150
139
  }
151
140
 
@@ -161,7 +150,6 @@ export class QueryMethods {
161
150
  select: S,
162
151
  ): SetQueryReturnsPluck<T, S> {
163
152
  this.query.returnType = 'pluck';
164
- removeFromQuery(this, 'take');
165
153
  (this.query as SelectQueryData).select = [select as SelectItem];
166
154
  addParserForSelectItem(this, this.query.as || this.table, 'pluck', select);
167
155
  return this as unknown as SetQueryReturnsPluck<T, S>;
@@ -173,7 +161,6 @@ export class QueryMethods {
173
161
 
174
162
  _exec<T extends Query>(this: T): SetQueryReturnsVoid<T> {
175
163
  this.query.returnType = 'void';
176
- removeFromQuery(this, 'take');
177
164
  return this as unknown as SetQueryReturnsVoid<T>;
178
165
  }
179
166
 
@@ -197,35 +184,33 @@ export class QueryMethods {
197
184
 
198
185
  find<T extends Query>(
199
186
  this: T,
200
- ...args: GetTypesOrRaw<T['schema']['primaryTypes']>
187
+ value: T['shape'][T['singlePrimaryKey']]['type'] | RawExpression,
201
188
  ): SetQueryReturnsOne<WhereResult<T>> {
202
- return this.clone()._find(...args);
189
+ return this.clone()._find(value);
203
190
  }
204
191
 
205
192
  _find<T extends Query>(
206
193
  this: T,
207
- ...args: GetTypesOrRaw<T['schema']['primaryTypes']>
194
+ value: T['shape'][T['singlePrimaryKey']]['type'] | RawExpression,
208
195
  ): SetQueryReturnsOne<WhereResult<T>> {
209
- const conditions: Partial<T['type']> = {};
210
- this.schema.primaryKeys.forEach((key: string, i: number) => {
211
- conditions[key as keyof T['type']] = args[i];
212
- });
213
- return this._where(conditions as WhereArg<T>)._take();
196
+ return this._where({
197
+ [this.singlePrimaryKey]: value,
198
+ } as WhereArg<T>)._take();
214
199
  }
215
200
 
216
201
  findOptional<T extends Query>(
217
202
  this: T,
218
- ...args: GetTypesOrRaw<T['schema']['primaryTypes']>
203
+ value: T['shape'][T['singlePrimaryKey']]['type'] | RawExpression,
219
204
  ): SetQueryReturnsOneOptional<WhereResult<T>> {
220
- return this.clone()._findOptional(...args);
205
+ return this.clone()._findOptional(value);
221
206
  }
222
207
 
223
208
  _findOptional<T extends Query>(
224
209
  this: T,
225
- ...args: GetTypesOrRaw<T['schema']['primaryTypes']>
210
+ value: T['shape'][T['singlePrimaryKey']]['type'] | RawExpression,
226
211
  ): SetQueryReturnsOneOptional<WhereResult<T>> {
227
212
  return this._find(
228
- ...args,
213
+ value,
229
214
  ).takeOptional() as unknown as SetQueryReturnsOneOptional<WhereResult<T>>;
230
215
  }
231
216
 
@@ -362,7 +347,6 @@ export class QueryMethods {
362
347
  const q = this._getOptional(raw<BooleanColumn>('true'));
363
348
  q.query.notFoundDefault = false;
364
349
  q.query.coalesceValue = false;
365
- delete q.query.take;
366
350
  return q as unknown as SetQueryReturnsValue<T, BooleanColumn>;
367
351
  }
368
352
 
@@ -412,4 +396,5 @@ applyMixins(QueryMethods, [
412
396
  QueryCallbacks,
413
397
  QueryUpsert,
414
398
  QueryGet,
399
+ MergeQueryMethods,
415
400
  ]);
@@ -29,6 +29,10 @@ const insertUserAndProfile = async () => {
29
29
  describe('selectMethods', () => {
30
30
  useTestDatabase();
31
31
 
32
+ it('table should have all columns selected if select was not applied', () => {
33
+ assertType<Awaited<typeof User>, UserRecord[]>();
34
+ });
35
+
32
36
  describe('select', () => {
33
37
  it('should have no effect if no columns provided', () => {
34
38
  const q = User.all();
@@ -4,7 +4,9 @@ import {
4
4
  ColumnsParsers,
5
5
  Query,
6
6
  QueryBase,
7
+ QueryReturnsAll,
7
8
  QuerySelectAll,
9
+ queryTypeWithLimitOne,
8
10
  } from '../query';
9
11
  import {
10
12
  ArrayOfColumnsObjects,
@@ -75,7 +77,7 @@ type SelectResult<
75
77
 
76
78
  type SelectSubQueryResult<
77
79
  Arg extends Query & { [isRequiredRelationKey]?: boolean },
78
- > = Arg['returnType'] extends 'all'
80
+ > = QueryReturnsAll<Arg['returnType']> extends true
79
81
  ? ArrayOfColumnsObjects<Arg['result']>
80
82
  : Arg['returnType'] extends 'valueOrThrow'
81
83
  ? Arg['result']['value']
@@ -107,7 +109,7 @@ export const addParserForSelectItem = <T extends Query>(
107
109
  const rel = arg(q);
108
110
  const parsers = getQueryParsers(rel);
109
111
  if (parsers) {
110
- if (rel.query.take) {
112
+ if (queryTypeWithLimitOne[rel.query.returnType]) {
111
113
  addParserToQuery(q.query, key, (item) => parseRecord(parsers, item));
112
114
  } else {
113
115
  addParserToQuery(q.query, key, (items) =>
@@ -49,7 +49,7 @@ export const handleResult: CommonQueryData['handleResult'] = async (
49
49
  q,
50
50
  result: QueryResult,
51
51
  ) => {
52
- return parseResult(q, q.query.returnType, result);
52
+ return parseResult(q, q.query.returnType || 'all', result);
53
53
  };
54
54
 
55
55
  const then = async (
@@ -89,7 +89,7 @@ const then = async (
89
89
  }
90
90
 
91
91
  const queryResult = await q.query.adapter[
92
- queryMethodByReturnType[q.query.returnType] as 'query'
92
+ queryMethodByReturnType[q.query.returnType || 'all'] as 'query'
93
93
  ](sql);
94
94
 
95
95
  if (q.query.log) {
@@ -119,7 +119,7 @@ const then = async (
119
119
 
120
120
  export const parseResult = (
121
121
  q: Query,
122
- returnType: QueryReturnType,
122
+ returnType: QueryReturnType | undefined = 'all',
123
123
  result: QueryResult,
124
124
  ): unknown => {
125
125
  switch (returnType) {
@@ -1,4 +1,4 @@
1
- import { Query, SetQueryReturnsRowCount } from '../query';
1
+ import { Query, QueryReturnsAll, SetQueryReturnsRowCount } from '../query';
2
2
  import { pushQueryArray, pushQueryValue } from '../queryDataUtils';
3
3
  import { isRaw, RawExpression, StringKey } from '../common';
4
4
  import {
@@ -43,7 +43,7 @@ type UpdateBelongsToData<T extends Query, Rel extends BelongsToRelation> =
43
43
  | {
44
44
  create: InsertData<Rel['nestedCreateQuery']>;
45
45
  }
46
- | (T['returnType'] extends 'all'
46
+ | (QueryReturnsAll<T['returnType']> extends true
47
47
  ? never
48
48
  : {
49
49
  upsert: {
@@ -56,7 +56,7 @@ type UpdateHasOneData<T extends Query, Rel extends HasOneRelation> =
56
56
  | { disconnect: boolean }
57
57
  | { delete: boolean }
58
58
  | { update: UpdateData<Rel['model']> }
59
- | (T['returnType'] extends 'all'
59
+ | (QueryReturnsAll<T['returnType']> extends true
60
60
  ? never
61
61
  :
62
62
  | { set: WhereArg<Rel['model']> }
@@ -77,7 +77,7 @@ type UpdateHasManyData<T extends Query, Rel extends HasManyRelation> = {
77
77
  where: MaybeArray<WhereArg<Rel['model']>>;
78
78
  data: UpdateData<Rel['model']>;
79
79
  };
80
- } & (T['returnType'] extends 'all'
80
+ } & (QueryReturnsAll<T['returnType']> extends true
81
81
  ? EmptyObject
82
82
  : {
83
83
  set?: MaybeArray<WhereArg<Rel['model']>>;
@@ -107,9 +107,9 @@ type UpdateRawArgs<T extends Query, ForceAll extends boolean> = (
107
107
  ? [update: RawExpression]
108
108
  : [update: RawExpression, forceAll: true];
109
109
 
110
- type UpdateResult<T extends Query> = T['hasSelect'] extends false
111
- ? SetQueryReturnsRowCount<T>
112
- : T;
110
+ type UpdateResult<T extends Query> = T['hasSelect'] extends true
111
+ ? T
112
+ : SetQueryReturnsRowCount<T>;
113
113
 
114
114
  type ChangeCountArg<T extends Query> =
115
115
  | keyof T['shape']
@@ -179,7 +179,7 @@ export class Update {
179
179
  const prependRelations: Record<string, Record<string, unknown>> = {};
180
180
  const appendRelations: Record<string, Record<string, unknown>> = {};
181
181
 
182
- const originalReturnType = query.returnType;
182
+ const originalReturnType = query.returnType || 'all';
183
183
 
184
184
  for (const key in data) {
185
185
  if (relations[key]) {
@@ -232,11 +232,13 @@ export class Update {
232
232
  query.returnType = 'all';
233
233
 
234
234
  if (state?.updateLater) {
235
- this.schema.primaryKeys.forEach((key: string) => {
236
- if (!query.select?.includes('*') && !query.select?.includes(key)) {
237
- this._select(key as StringKey<keyof T['selectable']>);
238
- }
239
- });
235
+ if (!query.select?.includes('*')) {
236
+ this.primaryKeys.forEach((key) => {
237
+ if (!query.select?.includes(key)) {
238
+ this._select(key as StringKey<keyof T['selectable']>);
239
+ }
240
+ });
241
+ }
240
242
  }
241
243
 
242
244
  const { handleResult } = query;
@@ -250,7 +252,7 @@ export class Update {
250
252
  await Promise.all(state.updateLaterPromises as Promise<void>[]);
251
253
 
252
254
  const t = this.__model.clone().transacting(q);
253
- const keys = this.schema.primaryKeys as string[];
255
+ const keys = this.primaryKeys;
254
256
  (
255
257
  t._whereIn as unknown as (
256
258
  keys: string[],
@@ -287,6 +289,11 @@ export class Update {
287
289
  appendRelationKeys.map((relationName) => {
288
290
  return (q: Query, result: Record<string, unknown>[]) => {
289
291
  const all = resultOfTypeAll || result;
292
+
293
+ if (q.query.returnType !== originalReturnType) {
294
+ q.query.returnType = originalReturnType;
295
+ }
296
+
290
297
  return (
291
298
  relations[relationName].nestedUpdate as HasOneNestedUpdate
292
299
  )?.(q, all, appendRelations[relationName] as NestedUpdateOneItem);
@@ -1,7 +1,7 @@
1
1
  import { getRaw, isRaw } from '../common';
2
2
  import { quoteSchemaAndTable } from './common';
3
3
  import { QueryBase } from '../query';
4
- import { queryKeysOfNotSimpleQuery, SelectQueryData } from './types';
4
+ import { checkIfASimpleQuery, SelectQueryData } from './types';
5
5
  import { ToSqlCtx } from './toSql';
6
6
 
7
7
  export const pushFromAndAs = (
@@ -38,9 +38,8 @@ const getFrom = (
38
38
  }
39
39
 
40
40
  const q = query.from.query;
41
- const keys = Object.keys(q) as (keyof SelectQueryData)[];
42
41
  // if query contains more than just schema return (SELECT ...)
43
- if (keys.some((key) => queryKeysOfNotSimpleQuery.includes(key))) {
42
+ if (!checkIfASimpleQuery(q)) {
44
43
  const sql = query.from.toSql({ values });
45
44
  return `(${sql.text})`;
46
45
  }
package/src/sql/select.ts CHANGED
@@ -142,7 +142,7 @@ const pushSubQuerySql = (
142
142
  values: unknown[],
143
143
  list: string[],
144
144
  ) => {
145
- const { returnType } = query.query;
145
+ const { returnType = 'all' } = query.query;
146
146
  switch (returnType) {
147
147
  case 'all':
148
148
  case 'one':
@@ -160,7 +160,6 @@ const pushSubQuerySql = (
160
160
  select[0] = { selectAs: { c: first } } as SelectItem;
161
161
  query = query._wrap(query.__model.clone()) as unknown as typeof query;
162
162
  query._getOptional(raw<StringColumn>(`COALESCE(json_agg("c"), '[]')`));
163
- delete query.query.take;
164
163
  break;
165
164
  }
166
165
  case 'rows':
package/src/sql/toSql.ts CHANGED
@@ -1,5 +1,5 @@
1
1
  import { getRaw, isRaw } from '../common';
2
- import { Query } from '../query';
2
+ import { Query, queryTypeWithLimitOne } from '../query';
3
3
  import { addValue, q, qc } from './common';
4
4
  import { JoinItem, QueryData, Sql } from './types';
5
5
  import { pushDistinctSql } from './distinct';
@@ -156,8 +156,9 @@ const makeSql = (model: Query, { values = [] }: ToSqlOptions = {}): Sql => {
156
156
  pushOrderBySql(ctx, quotedAs, query.order);
157
157
  }
158
158
 
159
- if (query.take || query.limit !== undefined) {
160
- sql.push(`LIMIT ${addValue(values, query.take ? 1 : query.limit)}`);
159
+ const limit = queryTypeWithLimitOne[query.returnType] ? 1 : query.limit;
160
+ if (limit) {
161
+ sql.push(`LIMIT ${addValue(values, limit)}`);
161
162
  }
162
163
 
163
164
  if (query.offset) {
package/src/sql/types.ts CHANGED
@@ -21,8 +21,13 @@ export type Sql = {
21
21
  };
22
22
 
23
23
  // used in `from` logic to decide if convert query to sql or just write table name
24
- export const queryKeysOfNotSimpleQuery: (keyof SelectQueryData)[] = [
25
- 'take',
24
+ export const checkIfASimpleQuery = (q: QueryData) => {
25
+ if (q.returnType && q.returnType !== 'all') return false;
26
+ const keys = Object.keys(q) as (keyof SelectQueryData)[];
27
+ return !keys.some((key) => queryKeysOfNotSimpleQuery.includes(key));
28
+ };
29
+
30
+ const queryKeysOfNotSimpleQuery: (keyof SelectQueryData)[] = [
26
31
  'with',
27
32
  'as',
28
33
  'from',
@@ -51,7 +56,6 @@ export type CommonQueryData = {
51
56
  inTransaction?: boolean;
52
57
  wrapInTransaction?: boolean;
53
58
  throwOnNotFound?: boolean;
54
- take?: boolean;
55
59
  with?: WithItem[];
56
60
  withShapes?: Record<string, ColumnsShape>;
57
61
  schema?: string;
package/src/sql/window.ts CHANGED
@@ -5,7 +5,7 @@ import { expressionToSql, q } from './common';
5
5
  import { orderByToSql } from './orderBy';
6
6
 
7
7
  export const windowToSql = <T extends Query>(
8
- window: T['windows'][number] | WindowDeclaration | RawExpression,
8
+ window: keyof T['windows'] | WindowDeclaration | RawExpression,
9
9
  values: unknown[],
10
10
  quotedAs?: string,
11
11
  ) => {
package/src/sql/with.ts CHANGED
@@ -7,26 +7,31 @@ export const pushWithSql = (
7
7
  ctx: ToSqlCtx,
8
8
  withData: Exclude<QueryData['with'], undefined>,
9
9
  ) => {
10
- withData.forEach((withItem) => {
11
- const [name, options, query] = withItem;
10
+ if (!withData.length) return;
12
11
 
13
- let inner: string;
14
- if (isRaw(query)) {
15
- inner = getRaw(query, ctx.values);
16
- } else {
17
- inner = query.toSql({ values: ctx.values }).text;
18
- }
12
+ ctx.sql.push(
13
+ 'WITH',
14
+ withData
15
+ .map((withItem) => {
16
+ const [name, options, query] = withItem;
19
17
 
20
- ctx.sql.push(
21
- `WITH ${options.recursive ? 'RECURSIVE ' : ''}${q(name)}${
22
- options.columns ? `(${options.columns.map(q).join(', ')})` : ''
23
- } AS ${
24
- options.materialized
25
- ? 'MATERIALIZED '
26
- : options.notMaterialized
27
- ? 'NOT MATERIALIZED '
28
- : ''
29
- }(${inner})`,
30
- );
31
- });
18
+ let inner: string;
19
+ if (isRaw(query)) {
20
+ inner = getRaw(query, ctx.values);
21
+ } else {
22
+ inner = query.toSql({ values: ctx.values }).text;
23
+ }
24
+
25
+ return `${options.recursive ? 'RECURSIVE ' : ''}${q(name)}${
26
+ options.columns ? `(${options.columns.map(q).join(', ')})` : ''
27
+ } AS ${
28
+ options.materialized
29
+ ? 'MATERIALIZED '
30
+ : options.notMaterialized
31
+ ? 'NOT MATERIALIZED '
32
+ : ''
33
+ }(${inner})`;
34
+ })
35
+ .join(', '),
36
+ );
32
37
  };