pqb 0.5.0 → 0.5.2

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "pqb",
3
- "version": "0.5.0",
3
+ "version": "0.5.2",
4
4
  "description": "Postgres query builder",
5
5
  "homepage": "https://porm.netlify.app/guide/query-builder.html",
6
6
  "repository": {
@@ -165,15 +165,18 @@ describe('column base', () => {
165
165
  columnTypes.timestamp().parse(Date.parse).as(columnTypes.integer());
166
166
  });
167
167
 
168
- it('should return same column with overridden type', () => {
168
+ it('should return same column with `as` property in data', () => {
169
169
  const timestamp = columnTypes
170
170
  .timestamp()
171
171
  .encode((input: number) => new Date(input))
172
172
  .parse(Date.parse);
173
173
 
174
- const column = timestamp.as(columnTypes.integer());
174
+ const integer = columnTypes.integer();
175
175
 
176
- expect(column).toBe(timestamp);
176
+ const column = timestamp.as(integer);
177
+
178
+ expect(column.dataType).toBe(timestamp.dataType);
179
+ expect(column.data.as).toBe(integer);
177
180
  });
178
181
 
179
182
  it('should parse correctly', async () => {
@@ -219,14 +219,23 @@ const processCreateItem = (
219
219
  item[key] as Record<string, unknown>,
220
220
  ]);
221
221
  } else {
222
+ const value = item[key] as NestedInsertItem;
223
+ if (
224
+ (!value.create ||
225
+ (Array.isArray(value.create) && value.create.length === 0)) &&
226
+ (!value.connect ||
227
+ (Array.isArray(value.connect) && value.connect.length === 0)) &&
228
+ (!value.connectOrCreate ||
229
+ (Array.isArray(value.connectOrCreate) &&
230
+ value.connectOrCreate.length === 0))
231
+ )
232
+ return;
233
+
222
234
  ctx.requiredReturning[ctx.relations[key].primaryKey] = true;
223
235
 
224
236
  if (!ctx.appendRelations[key]) ctx.appendRelations[key] = [];
225
237
 
226
- ctx.appendRelations[key].push([
227
- rowIndex,
228
- item[key] as NestedInsertItem,
229
- ]);
238
+ ctx.appendRelations[key].push([rowIndex, value]);
230
239
  }
231
240
  } else if (
232
241
  columnsMap[key] === undefined &&
@@ -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 { StringKey } from '../common';
10
+ import { raw, 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
- this.raw<Query, StringColumn>(
58
+ raw(
59
59
  queryTypeWithLimitOne[this.query.returnType]
60
60
  ? `row_to_json("t".*)`
61
61
  : `COALESCE(json_agg(row_to_json("t".*)), '[]')`,
@@ -304,15 +304,9 @@ export class QueryMethods {
304
304
  _wrap<T extends Query, Q extends Query, As extends string = 't'>(
305
305
  this: T,
306
306
  query: Q,
307
- as?: As,
307
+ as: As = 't' as As,
308
308
  ): SetQueryTableAlias<Q, As> {
309
- const sql = this.toSql();
310
-
311
- return query
312
- .as(as ?? 't')
313
- ._from(
314
- this.raw(`(${sql.text})`, ...sql.values),
315
- ) as unknown as SetQueryTableAlias<Q, As>;
309
+ return query.as(as)._from(this, as) as unknown as SetQueryTableAlias<Q, As>;
316
310
  }
317
311
 
318
312
  order<T extends Query>(this: T, ...args: OrderArg<T>[]): T {
@@ -261,7 +261,7 @@ describe('selectMethods', () => {
261
261
  SELECT
262
262
  (
263
263
  SELECT COALESCE(json_agg(row_to_json("t".*)), '[]')
264
- FROM (SELECT * FROM "user") AS "t"
264
+ FROM "user" AS "t"
265
265
  ) AS "subquery"
266
266
  FROM "user"
267
267
  `,
@@ -8,6 +8,7 @@ import {
8
8
  HasManyRelation,
9
9
  HasOneNestedUpdate,
10
10
  HasOneRelation,
11
+ NestedUpdateItem,
11
12
  NestedUpdateOneItem,
12
13
  Relation,
13
14
  } from '../relations';
@@ -192,6 +193,24 @@ export class Update {
192
193
  if (relations[key].type === 'belongsTo') {
193
194
  prependRelations[key] = data[key] as Record<string, unknown>;
194
195
  } else {
196
+ const value = data[key] as NestedUpdateItem;
197
+
198
+ if (
199
+ !value.set &&
200
+ !('upsert' in value) &&
201
+ (!value.disconnect ||
202
+ (Array.isArray(value.disconnect) &&
203
+ value.disconnect.length === 0)) &&
204
+ (!value.delete ||
205
+ (Array.isArray(value.delete) && value.delete.length === 0)) &&
206
+ (!value.update ||
207
+ (Array.isArray(value.update.where) &&
208
+ value.update.where.length === 0)) &&
209
+ (!value.create ||
210
+ (Array.isArray(value.create) && value.create.length === 0))
211
+ )
212
+ continue;
213
+
195
214
  if (!query.select?.includes('*')) {
196
215
  const primaryKey = relations[key].primaryKey;
197
216
  if (!query.select?.includes(primaryKey)) {
@@ -1,7 +1,7 @@
1
1
  import { quoteSchemaAndTable } from './common';
2
2
  import { QueryBase } from '../query';
3
3
  import { checkIfASimpleQuery, SelectQueryData } from './types';
4
- import { ToSqlCtx } from './toSql';
4
+ import { makeSql, ToSqlCtx } from './toSql';
5
5
  import { getRaw, isRaw } from '../common';
6
6
 
7
7
  export const pushFromAndAs = (
@@ -33,14 +33,14 @@ const getFrom = (
33
33
  }
34
34
 
35
35
  if (!query.from.table) {
36
- const sql = query.from.toSql({ values });
36
+ const sql = makeSql(query.from, { values });
37
37
  return `(${sql.text})`;
38
38
  }
39
39
 
40
40
  const q = query.from.query;
41
41
  // if query contains more than just schema return (SELECT ...)
42
42
  if (!checkIfASimpleQuery(q)) {
43
- const sql = query.from.toSql({ values });
43
+ const sql = makeSql(query.from, { values });
44
44
  return `(${sql.text})`;
45
45
  }
46
46
 
package/src/sql/insert.ts CHANGED
@@ -3,7 +3,7 @@ import { addValue, q } from './common';
3
3
  import { pushWhereStatementSql } from './where';
4
4
  import { QueryBase } from '../query';
5
5
  import { selectToSql } from './select';
6
- import { ToSqlCtx } from './toSql';
6
+ import { makeSql, ToSqlCtx } from './toSql';
7
7
  import { pushQueryValue } from '../queryDataUtils';
8
8
  import { getRaw, isRaw, raw } from '../common';
9
9
 
@@ -26,7 +26,7 @@ export const pushInsertSql = (
26
26
  isRaw(query.values) ? query.values : raw(encodeRow(ctx, query.values[0])),
27
27
  );
28
28
 
29
- ctx.sql.push(q.toSql({ values: ctx.values }).text);
29
+ ctx.sql.push(makeSql(q, { values: ctx.values }).text);
30
30
  } else {
31
31
  ctx.sql.push(
32
32
  `VALUES ${
package/src/sql/select.ts CHANGED
@@ -10,7 +10,7 @@ import { addValue, q, quoteFullColumn } from './common';
10
10
  import { aggregateToSql } from './aggregate';
11
11
  import { PormInternalError, UnhandledTypeError } from '../errors';
12
12
  import { quote } from '../quote';
13
- import { ToSqlCtx } from './toSql';
13
+ import { makeSql, ToSqlCtx } from './toSql';
14
14
  import { relationQueryKey } from '../relations';
15
15
 
16
16
  const jsonColumnOrMethodToSql = (
@@ -178,7 +178,7 @@ const pushSubQuerySql = (
178
178
  throw new UnhandledTypeError(returnType);
179
179
  }
180
180
 
181
- let subQuerySql = `(${query.toSql({ values }).text})`;
181
+ let subQuerySql = `(${makeSql(query, { values }).text})`;
182
182
  const { coalesceValue } = query.query;
183
183
  if (coalesceValue !== undefined) {
184
184
  const value =
package/src/sql/toSql.ts CHANGED
@@ -40,7 +40,10 @@ export const toSql = (model: Query, options?: ToSqlOptions): Sql => {
40
40
  );
41
41
  };
42
42
 
43
- const makeSql = (model: Query, { values = [] }: ToSqlOptions = {}): Sql => {
43
+ export const makeSql = (
44
+ model: Query,
45
+ { values = [] }: ToSqlOptions = {},
46
+ ): Sql => {
44
47
  const query = model.query;
45
48
  const sql: string[] = [];
46
49
  const ctx: ToSqlCtx = {
@@ -145,7 +148,7 @@ const makeSql = (model: Query, { values = [] }: ToSqlOptions = {}): Sql => {
145
148
  if (isRaw(item.arg)) {
146
149
  itemSql = getRaw(item.arg, values);
147
150
  } else {
148
- const argSql = item.arg.toSql({ values });
151
+ const argSql = makeSql(item.arg, { values });
149
152
  itemSql = argSql.text;
150
153
  }
151
154
  sql.push(`${item.kind} ${item.wrap ? `(${itemSql})` : itemSql}`);
package/src/sql/where.ts CHANGED
@@ -11,7 +11,7 @@ import {
11
11
  import { addValue, q, qc, quoteFullColumn } from './common';
12
12
  import { getQueryAs, MaybeArray, toArray } from '../utils';
13
13
  import { processJoinItem } from './join';
14
- import { ToSqlCtx } from './toSql';
14
+ import { makeSql, ToSqlCtx } from './toSql';
15
15
  import { getRaw, isRaw, RawExpression } from '../common';
16
16
 
17
17
  export const pushWhereStatementSql = (
@@ -252,7 +252,7 @@ const pushIn = (
252
252
  } else if (isRaw(arg.values)) {
253
253
  value = getRaw(arg.values, values);
254
254
  } else {
255
- const sql = arg.values.toSql({ values });
255
+ const sql = makeSql(arg.values, { values });
256
256
  value = `(${sql.text})`;
257
257
  }
258
258
 
package/src/sql/with.ts CHANGED
@@ -1,6 +1,6 @@
1
1
  import { QueryData } from './types';
2
2
  import { q } from './common';
3
- import { ToSqlCtx } from './toSql';
3
+ import { makeSql, ToSqlCtx } from './toSql';
4
4
  import { getRaw, isRaw } from '../common';
5
5
 
6
6
  export const pushWithSql = (
@@ -19,7 +19,7 @@ export const pushWithSql = (
19
19
  if (isRaw(query)) {
20
20
  inner = getRaw(query, ctx.values);
21
21
  } else {
22
- inner = query.toSql({ values: ctx.values }).text;
22
+ inner = makeSql(query, { values: ctx.values }).text;
23
23
  }
24
24
 
25
25
  return `${options.recursive ? 'RECURSIVE ' : ''}${q(name)}${