pqb 0.3.9 → 0.4.1

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 (37) hide show
  1. package/dist/index.d.ts +104 -84
  2. package/dist/index.esm.js +150 -121
  3. package/dist/index.esm.js.map +1 -1
  4. package/dist/index.js +150 -121
  5. package/dist/index.js.map +1 -1
  6. package/package.json +1 -1
  7. package/src/columnSchema/columnType.test.ts +1 -1
  8. package/src/db.test.ts +2 -2
  9. package/src/db.ts +9 -1
  10. package/src/errors.test.ts +79 -0
  11. package/src/errors.ts +43 -5
  12. package/src/query.ts +6 -0
  13. package/src/queryMethods/aggregate.test.ts +11 -11
  14. package/src/queryMethods/aggregate.ts +5 -3
  15. package/src/queryMethods/callbacks.test.ts +6 -6
  16. package/src/queryMethods/callbacks.ts +8 -8
  17. package/src/queryMethods/columnInfo.ts +13 -19
  18. package/src/queryMethods/{insert.test.ts → create.test.ts} +106 -98
  19. package/src/queryMethods/{insert.ts → create.ts} +129 -113
  20. package/src/queryMethods/delete.test.ts +2 -2
  21. package/src/queryMethods/get.test.ts +2 -2
  22. package/src/queryMethods/index.ts +1 -1
  23. package/src/queryMethods/json.test.ts +1 -1
  24. package/src/queryMethods/log.test.ts +29 -8
  25. package/src/queryMethods/merge.test.ts +3 -3
  26. package/src/queryMethods/queryMethods.test.ts +4 -4
  27. package/src/queryMethods/queryMethods.ts +3 -3
  28. package/src/queryMethods/select.test.ts +7 -7
  29. package/src/queryMethods/then.test.ts +1 -73
  30. package/src/queryMethods/then.ts +8 -7
  31. package/src/queryMethods/update.test.ts +8 -8
  32. package/src/queryMethods/update.ts +7 -7
  33. package/src/queryMethods/upsert.ts +3 -3
  34. package/src/queryMethods/window.test.ts +2 -2
  35. package/src/sql/insert.ts +31 -19
  36. package/src/sql/types.ts +3 -2
  37. package/src/test-utils.ts +4 -1
package/dist/index.js CHANGED
@@ -795,8 +795,9 @@ class QueryError extends pg.DatabaseError {
795
795
  if (this.detail) {
796
796
  const list = (_a = this.detail.match(/\((.*)\)=/)) == null ? void 0 : _a[1];
797
797
  if (list) {
798
- list.split(", ").forEach((column) => {
799
- columns[column.startsWith('"') ? column.slice(1, -1) : column] = true;
798
+ list.split(", ").forEach((item) => {
799
+ const column = item.startsWith('"') ? item.slice(1, -1) : item;
800
+ columns[column] = true;
800
801
  });
801
802
  }
802
803
  }
@@ -1120,15 +1121,49 @@ const getFrom = (model, query, values) => {
1120
1121
  return quoteSchemaAndTable(query.schema, model.table);
1121
1122
  };
1122
1123
 
1124
+ const pushQueryArray = (q, key, value) => {
1125
+ if (!q.query[key])
1126
+ q.query[key] = value;
1127
+ else
1128
+ q.query[key].push(
1129
+ ...value
1130
+ );
1131
+ return q;
1132
+ };
1133
+ const pushQueryValue = (q, key, value) => {
1134
+ pushOrNewArrayToObject(
1135
+ q.query,
1136
+ key,
1137
+ value
1138
+ );
1139
+ return q;
1140
+ };
1141
+ const setQueryObjectValue = (q, object, key, value) => {
1142
+ if (!q.query[object])
1143
+ q.query[object] = {
1144
+ [key]: value
1145
+ };
1146
+ else
1147
+ q.query[object][key] = value;
1148
+ return q;
1149
+ };
1150
+
1123
1151
  const pushInsertSql = (ctx, model, query, quotedAs) => {
1124
1152
  const quotedColumns = query.columns.map(q);
1125
- ctx.sql.push(
1126
- `INSERT INTO ${quotedAs}(${quotedColumns.join(", ")}) VALUES ${isRaw(query.values) ? getRaw(query.values, ctx.values) : query.values.map(
1127
- (row) => `(${row.map(
1128
- (value) => value === void 0 ? "DEFAULT" : addValue(ctx.values, value)
1129
- ).join(", ")})`
1130
- ).join(", ")}`
1131
- );
1153
+ ctx.sql.push(`INSERT INTO ${quotedAs}(${quotedColumns.join(", ")})`);
1154
+ if (query.fromQuery) {
1155
+ const q2 = query.fromQuery.clone();
1156
+ pushQueryValue(
1157
+ q2,
1158
+ "select",
1159
+ isRaw(query.values) ? query.values : raw(encodeRow(ctx, query.values[0]))
1160
+ );
1161
+ ctx.sql.push(q2.toSql({ values: ctx.values }).text);
1162
+ } else {
1163
+ ctx.sql.push(
1164
+ `VALUES ${isRaw(query.values) ? getRaw(query.values, ctx.values) : query.values.map((row) => `(${encodeRow(ctx, row)})`).join(", ")}`
1165
+ );
1166
+ }
1132
1167
  if (query.onConflict) {
1133
1168
  ctx.sql.push("ON CONFLICT");
1134
1169
  const { expr, type } = query.onConflict;
@@ -1171,6 +1206,11 @@ const pushInsertSql = (ctx, model, query, quotedAs) => {
1171
1206
  pushWhereStatementSql(ctx, model, query, quotedAs);
1172
1207
  pushReturningSql(ctx, model, query, quotedAs);
1173
1208
  };
1209
+ const encodeRow = (ctx, row) => {
1210
+ return row.map(
1211
+ (value) => value === void 0 ? "DEFAULT" : addValue(ctx.values, value)
1212
+ ).join(", ");
1213
+ };
1174
1214
  const pushReturningSql = (ctx, model, query, quotedAs) => {
1175
1215
  if (query.select) {
1176
1216
  ctx.sql.push(`RETURNING ${selectToSql(ctx, model, query, quotedAs)}`);
@@ -3144,33 +3184,6 @@ class TransactionAdapter {
3144
3184
  }
3145
3185
  }
3146
3186
 
3147
- const pushQueryArray = (q, key, value) => {
3148
- if (!q.query[key])
3149
- q.query[key] = value;
3150
- else
3151
- q.query[key].push(
3152
- ...value
3153
- );
3154
- return q;
3155
- };
3156
- const pushQueryValue = (q, key, value) => {
3157
- pushOrNewArrayToObject(
3158
- q.query,
3159
- key,
3160
- value
3161
- );
3162
- return q;
3163
- };
3164
- const setQueryObjectValue = (q, object, key, value) => {
3165
- if (!q.query[object])
3166
- q.query[object] = {
3167
- [key]: value
3168
- };
3169
- else
3170
- q.query[object][key] = value;
3171
- return q;
3172
- };
3173
-
3174
3187
  const getValueKey = Symbol("get");
3175
3188
  const _get = (q, returnType, arg) => {
3176
3189
  q.query.returnType = returnType;
@@ -3218,7 +3231,7 @@ const queryMethodByReturnType = {
3218
3231
  let queryError = void 0;
3219
3232
  class Then {
3220
3233
  get then() {
3221
- queryError = new QueryError();
3234
+ queryError = new Error();
3222
3235
  return maybeWrappedThen;
3223
3236
  }
3224
3237
  async catch(fn) {
@@ -3242,8 +3255,8 @@ const then = async (q, resolve, reject) => {
3242
3255
  let beforeCallbacks;
3243
3256
  let afterCallbacks;
3244
3257
  if (q.query.type === "insert") {
3245
- beforeCallbacks = q.query.beforeInsert;
3246
- afterCallbacks = q.query.afterInsert;
3258
+ beforeCallbacks = q.query.beforeCreate;
3259
+ afterCallbacks = q.query.afterCreate;
3247
3260
  } else if (q.query.type === "update") {
3248
3261
  beforeCallbacks = q.query.beforeUpdate;
3249
3262
  afterCallbacks = q.query.afterUpdate;
@@ -3275,14 +3288,16 @@ const then = async (q, resolve, reject) => {
3275
3288
  }
3276
3289
  resolve == null ? void 0 : resolve(result);
3277
3290
  } catch (err) {
3278
- const error = err instanceof pg.DatabaseError ? assignError(queryError, err) : err;
3291
+ const error = err instanceof pg.DatabaseError ? assignError(q, err) : err;
3279
3292
  if (q.query.log && sql && logData) {
3280
3293
  q.query.log.onError(error, sql, logData);
3281
3294
  }
3282
3295
  reject == null ? void 0 : reject(error);
3283
3296
  }
3284
3297
  };
3285
- const assignError = (to, from) => {
3298
+ const assignError = (q, from) => {
3299
+ const to = new q.error();
3300
+ to.stack = queryError.stack;
3286
3301
  to.message = from.message;
3287
3302
  to.length = from.length;
3288
3303
  to.name = from.name;
@@ -3602,7 +3617,9 @@ class Aggregate {
3602
3617
  return this.clone()._count(arg, options);
3603
3618
  }
3604
3619
  _count(arg = "*", options) {
3605
- return get(this._selectCount(arg, options));
3620
+ return get(
3621
+ this._selectCount(arg, options)
3622
+ );
3606
3623
  }
3607
3624
  selectCount(arg, options) {
3608
3625
  return this.clone()._selectCount(arg, options);
@@ -3848,17 +3865,17 @@ class QueryCallbacks {
3848
3865
  _afterQuery(cb) {
3849
3866
  return pushQueryValue(this, "afterQuery", cb);
3850
3867
  }
3851
- beforeInsert(cb) {
3852
- return this.clone()._beforeInsert(cb);
3868
+ beforeCreate(cb) {
3869
+ return this.clone()._beforeCreate(cb);
3853
3870
  }
3854
- _beforeInsert(cb) {
3855
- return pushQueryValue(this, "beforeInsert", cb);
3871
+ _beforeCreate(cb) {
3872
+ return pushQueryValue(this, "beforeCreate", cb);
3856
3873
  }
3857
- afterInsert(cb) {
3858
- return this.clone()._afterInsert(cb);
3874
+ afterCreate(cb) {
3875
+ return this.clone()._afterCreate(cb);
3859
3876
  }
3860
- _afterInsert(cb) {
3861
- return pushQueryValue(this, "afterInsert", cb);
3877
+ _afterCreate(cb) {
3878
+ return pushQueryValue(this, "afterCreate", cb);
3862
3879
  }
3863
3880
  beforeUpdate(cb) {
3864
3881
  return this.clone()._beforeUpdate(cb);
@@ -3941,22 +3958,16 @@ class ColumnInfoMethods {
3941
3958
  if (column) {
3942
3959
  this.query.column = column;
3943
3960
  }
3944
- this.then = function(resolve, reject) {
3945
- new Then().then.call(
3946
- this,
3947
- (rows) => {
3948
- if (column) {
3949
- resolve == null ? void 0 : resolve(rowToColumnInfo(rows[0]));
3950
- } else {
3951
- const info = {};
3952
- rows.forEach((row) => {
3953
- info[row.column_name] = rowToColumnInfo(row);
3954
- });
3955
- resolve == null ? void 0 : resolve(info);
3956
- }
3957
- },
3958
- reject
3959
- );
3961
+ this.query.handleResult = async (_, result) => {
3962
+ if (column) {
3963
+ return rowToColumnInfo(result.rows[0]);
3964
+ } else {
3965
+ const info = {};
3966
+ result.rows.forEach((row) => {
3967
+ info[row.column_name] = rowToColumnInfo(row);
3968
+ });
3969
+ return info;
3970
+ }
3960
3971
  };
3961
3972
  return this;
3962
3973
  }
@@ -4154,7 +4165,17 @@ var __spreadValues$4 = (a, b) => {
4154
4165
  }
4155
4166
  return a;
4156
4167
  };
4157
- const processInsertItem = (item, rowIndex, ctx, columns, columnsMap) => {
4168
+ const handleSelect = (q) => {
4169
+ var _a;
4170
+ const select = (_a = q.query.select) == null ? void 0 : _a[0];
4171
+ const isCount = typeof select === "object" && "function" in select && select.function === "count";
4172
+ if (isCount) {
4173
+ q.query.select = void 0;
4174
+ } else if (isCount || !q.query.select) {
4175
+ q.query.select = ["*"];
4176
+ }
4177
+ };
4178
+ const processCreateItem = (item, rowIndex, ctx, columns, columnsMap) => {
4158
4179
  Object.keys(item).forEach((key) => {
4159
4180
  if (ctx.relations[key]) {
4160
4181
  if (ctx.relations[key].type === "belongsTo") {
@@ -4186,13 +4207,13 @@ const processInsertItem = (item, rowIndex, ctx, columns, columnsMap) => {
4186
4207
  }
4187
4208
  });
4188
4209
  };
4189
- const createInsertCtx = (q) => ({
4210
+ const createCtx = (q) => ({
4190
4211
  prependRelations: {},
4191
4212
  appendRelations: {},
4192
4213
  requiredReturning: {},
4193
4214
  relations: q.relations
4194
4215
  });
4195
- const getInsertSingleReturnType = (q) => {
4216
+ const getSingleReturnType = (q) => {
4196
4217
  const { select, returnType = "all" } = q.query;
4197
4218
  if (select) {
4198
4219
  return returnType === "all" ? "one" : returnType;
@@ -4200,7 +4221,7 @@ const getInsertSingleReturnType = (q) => {
4200
4221
  return "rowCount";
4201
4222
  }
4202
4223
  };
4203
- const getInsertManyReturnType = (q) => {
4224
+ const getManyReturnType = (q) => {
4204
4225
  const { select, returnType } = q.query;
4205
4226
  if (select) {
4206
4227
  return returnType === "one" || returnType === "oneOrThrow" ? "all" : returnType;
@@ -4208,18 +4229,18 @@ const getInsertManyReturnType = (q) => {
4208
4229
  return "rowCount";
4209
4230
  }
4210
4231
  };
4211
- const handleInsertOneData = (q, data, ctx) => {
4232
+ const handleOneData = (q, data, ctx) => {
4212
4233
  const columns = [];
4213
4234
  const columnsMap = {};
4214
4235
  const defaults = q.query.defaults;
4215
4236
  if (defaults) {
4216
4237
  data = __spreadValues$4(__spreadValues$4({}, defaults), data);
4217
4238
  }
4218
- processInsertItem(data, 0, ctx, columns, columnsMap);
4239
+ processCreateItem(data, 0, ctx, columns, columnsMap);
4219
4240
  const values = [columns.map((key) => data[key])];
4220
4241
  return { columns, values };
4221
4242
  };
4222
- const handleInsertManyData = (q, data, ctx) => {
4243
+ const handleManyData = (q, data, ctx) => {
4223
4244
  const columns = [];
4224
4245
  const columnsMap = {};
4225
4246
  const defaults = q.query.defaults;
@@ -4227,7 +4248,7 @@ const handleInsertManyData = (q, data, ctx) => {
4227
4248
  data = data.map((item) => __spreadValues$4(__spreadValues$4({}, defaults), item));
4228
4249
  }
4229
4250
  data.forEach((item, i) => {
4230
- processInsertItem(item, i, ctx, columns, columnsMap);
4251
+ processCreateItem(item, i, ctx, columns, columnsMap);
4231
4252
  });
4232
4253
  const values = Array(data.length);
4233
4254
  data.forEach((item, i) => {
@@ -4238,7 +4259,7 @@ const handleInsertManyData = (q, data, ctx) => {
4238
4259
  const insert = (self, {
4239
4260
  columns,
4240
4261
  values
4241
- }, returnType, ctx) => {
4262
+ }, returnType, ctx, fromQuery) => {
4242
4263
  const q = self;
4243
4264
  const returning = q.query.select;
4244
4265
  delete q.query.and;
@@ -4246,6 +4267,7 @@ const insert = (self, {
4246
4267
  q.query.type = "insert";
4247
4268
  q.query.columns = columns;
4248
4269
  q.query.values = values;
4270
+ q.query.fromQuery = fromQuery;
4249
4271
  if (!ctx) {
4250
4272
  q.query.returnType = returnType;
4251
4273
  return q;
@@ -4321,67 +4343,72 @@ const insert = (self, {
4321
4343
  q.query.returnType = appendRelationsKeys.length ? "all" : returnType;
4322
4344
  return q;
4323
4345
  };
4324
- class Insert {
4325
- insert(data) {
4326
- return this.clone()._insert(data);
4346
+ class Create {
4347
+ create(data) {
4348
+ return this.clone()._create(data);
4327
4349
  }
4328
- _insert(data) {
4329
- const ctx = createInsertCtx(this);
4350
+ _create(data) {
4351
+ handleSelect(this);
4352
+ const ctx = createCtx(this);
4330
4353
  return insert(
4331
4354
  this,
4332
- handleInsertOneData(this, data, ctx),
4333
- getInsertSingleReturnType(this),
4355
+ handleOneData(this, data, ctx),
4356
+ getSingleReturnType(this),
4334
4357
  ctx
4335
4358
  );
4336
4359
  }
4337
- insertMany(data) {
4338
- return this.clone()._insertMany(data);
4360
+ createMany(data) {
4361
+ return this.clone()._createMany(data);
4339
4362
  }
4340
- _insertMany(data) {
4341
- const ctx = createInsertCtx(this);
4363
+ _createMany(data) {
4364
+ handleSelect(this);
4365
+ const ctx = createCtx(this);
4342
4366
  return insert(
4343
4367
  this,
4344
- handleInsertManyData(this, data, ctx),
4345
- getInsertManyReturnType(this),
4368
+ handleManyData(this, data, ctx),
4369
+ getManyReturnType(this),
4346
4370
  ctx
4347
4371
  );
4348
4372
  }
4349
- insertRaw(data) {
4350
- return this.clone()._insertRaw(data);
4351
- }
4352
- _insertRaw(data) {
4353
- return insert(
4354
- this,
4355
- data,
4356
- getInsertManyReturnType(this)
4357
- );
4358
- }
4359
- create(data) {
4360
- return this.clone()._create(data);
4361
- }
4362
- _create(data) {
4363
- if (!this.query.select) {
4364
- this.query.select = ["*"];
4365
- }
4366
- return this.clone()._insert(data);
4367
- }
4368
- createMany(data) {
4369
- return this.clone()._createMany(data);
4370
- }
4371
- _createMany(data) {
4372
- if (!this.query.select) {
4373
- this.query.select = ["*"];
4374
- }
4375
- return this.clone()._insertMany(data);
4376
- }
4377
4373
  createRaw(data) {
4378
4374
  return this.clone()._createRaw(data);
4379
4375
  }
4380
4376
  _createRaw(data) {
4377
+ handleSelect(this);
4378
+ return insert(this, data, getManyReturnType(this));
4379
+ }
4380
+ createFrom(query, data) {
4381
+ return this.clone()._createFrom(query, data);
4382
+ }
4383
+ _createFrom(query, data) {
4384
+ var _a;
4385
+ if (!queryTypeWithLimitOne[query.query.returnType]) {
4386
+ throw new Error(
4387
+ "createFrom accepts only a query which returns one record"
4388
+ );
4389
+ }
4381
4390
  if (!this.query.select) {
4382
4391
  this.query.select = ["*"];
4383
4392
  }
4384
- return this.clone()._insertRaw(data);
4393
+ const ctx = createCtx(this);
4394
+ const queryColumns = [];
4395
+ (_a = query.query.select) == null ? void 0 : _a.forEach((item) => {
4396
+ if (typeof item === "string") {
4397
+ const index = item.indexOf(".");
4398
+ queryColumns.push(index === -1 ? item : item.slice(index + 1));
4399
+ } else if ("selectAs" in item) {
4400
+ queryColumns.push(...Object.keys(item.selectAs));
4401
+ }
4402
+ });
4403
+ const { columns, values } = handleOneData(this, data, ctx);
4404
+ queryColumns.push(...columns);
4405
+ return insert(
4406
+ this,
4407
+ { columns: queryColumns, values },
4408
+ "one",
4409
+ ctx,
4410
+ query
4411
+ );
4385
4412
  }
4386
4413
  defaults(data) {
4387
4414
  return this.clone()._defaults(data);
@@ -5324,7 +5351,7 @@ class QueryUpsert {
5324
5351
  const { handleResult } = this.query;
5325
5352
  this.query.handleResult = async (q, queryResult) => {
5326
5353
  if (queryResult.rowCount === 0) {
5327
- return q.insert(data.create);
5354
+ return q.create(data.create);
5328
5355
  } else if (queryResult.rowCount > 1) {
5329
5356
  throw new MoreThanOneRowError(
5330
5357
  `Only one row was expected to find for upsert, found ${queryResult.rowCount} rows.`
@@ -5510,7 +5537,7 @@ applyMixins(QueryMethods, [
5510
5537
  With,
5511
5538
  Union,
5512
5539
  Json,
5513
- Insert,
5540
+ Create,
5514
5541
  Update,
5515
5542
  Delete,
5516
5543
  Transaction,
@@ -5592,7 +5619,7 @@ class Db {
5592
5619
  const defaultSelect = this.defaultSelectColumns.length === columns.length ? void 0 : this.defaultSelectColumns;
5593
5620
  const columnsParsers = {};
5594
5621
  let hasParsers = false;
5595
- let modifyQuery;
5622
+ let modifyQuery = void 0;
5596
5623
  for (const key in shape) {
5597
5624
  const column = shape[key];
5598
5625
  if (column.parseFn) {
@@ -5613,6 +5640,8 @@ class Db {
5613
5640
  } : toSql;
5614
5641
  this.relations = {};
5615
5642
  modifyQuery == null ? void 0 : modifyQuery.forEach((cb) => cb(this));
5643
+ this.error = class extends QueryError {
5644
+ };
5616
5645
  }
5617
5646
  }
5618
5647
  applyMixins(Db, [QueryMethods]);
@@ -5677,6 +5706,7 @@ exports.Clear = Clear;
5677
5706
  exports.ColumnInfoMethods = ColumnInfoMethods;
5678
5707
  exports.ColumnType = ColumnType;
5679
5708
  exports.ColumnsObject = ColumnsObject;
5709
+ exports.Create = Create;
5680
5710
  exports.DateBaseColumn = DateBaseColumn;
5681
5711
  exports.DateColumn = DateColumn;
5682
5712
  exports.DateTimeBaseClass = DateTimeBaseClass;
@@ -5692,7 +5722,6 @@ exports.For = For;
5692
5722
  exports.From = From;
5693
5723
  exports.Having = Having;
5694
5724
  exports.InetColumn = InetColumn;
5695
- exports.Insert = Insert;
5696
5725
  exports.IntegerBaseColumn = IntegerBaseColumn;
5697
5726
  exports.IntegerColumn = IntegerColumn;
5698
5727
  exports.IntervalColumn = IntervalColumn;