@graffy/pg 0.15.23 → 0.15.25-alpha.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.
package/index.cjs CHANGED
@@ -27,7 +27,8 @@ var __objRest = (source, exclude) => {
27
27
  }
28
28
  return target;
29
29
  };
30
- Object.defineProperties(exports, { __esModule: { value: true }, [Symbol.toStringTag]: { value: "Module" } });
30
+ Object.defineProperty(exports, "__esModule", { value: true });
31
+ exports[Symbol.toStringTag] = "Module";
31
32
  var common = require("@graffy/common");
32
33
  var pg$1 = require("pg");
33
34
  var sql = require("sql-template-tag");
@@ -174,31 +175,35 @@ const lookup = (prop) => {
174
175
  const [prefix, ...suffix] = common.encodePath(prop);
175
176
  return suffix.length ? sql__default["default"]`"${sql.raw(prefix)}" #> ${suffix}` : sql__default["default"]`"${sql.raw(prefix)}"`;
176
177
  };
178
+ const lookupNumeric = (prop) => {
179
+ const [prefix, ...suffix] = common.encodePath(prop);
180
+ return suffix.length ? sql__default["default"]`CASE WHEN "${sql.raw(prefix)}" #> ${suffix} = 'null'::jsonb THEN 0 ELSE ("${sql.raw(prefix)}" #> ${suffix})::numeric END` : sql__default["default"]`"${sql.raw(prefix)}"`;
181
+ };
177
182
  const aggSql = {
178
- $sum: (prop) => sql__default["default"]`sum((${lookup(prop)})::numeric)`,
183
+ $sum: (prop) => sql__default["default"]`sum((${lookupNumeric(prop)})::numeric)`,
179
184
  $card: (prop) => sql__default["default"]`count(distinct(${lookup(prop)}))`,
180
- $avg: (prop) => sql__default["default"]`sum((${lookup(prop)})::numeric)`,
181
- $max: (prop) => sql__default["default"]`sum((${lookup(prop)})::numeric)`,
182
- $min: (prop) => sql__default["default"]`sum((${lookup(prop)})::numeric)`
185
+ $avg: (prop) => sql__default["default"]`avg((${lookupNumeric(prop)})::numeric)`,
186
+ $max: (prop) => sql__default["default"]`max((${lookupNumeric(prop)})::numeric)`,
187
+ $min: (prop) => sql__default["default"]`min((${lookupNumeric(prop)})::numeric)`
183
188
  };
184
189
  const getSelectCols = (table, projection = null) => {
185
190
  if (!projection)
186
- return sql__default["default"]`to_jsonb("${sql.raw(table)}")`;
191
+ return sql__default["default"]`*`;
187
192
  const sqls = [];
188
193
  for (const key in projection) {
189
194
  if (key === "$count") {
190
- sqls.push(sql__default["default"]`'$count', count(*)`);
195
+ sqls.push(sql__default["default"]`count(*) AS "$count"`);
191
196
  } else if (aggSql[key]) {
192
197
  const subSqls = [];
193
198
  for (const prop in projection[key]) {
194
199
  subSqls.push(sql__default["default"]`${prop}::text, ${aggSql[key](prop)}`);
195
200
  }
196
- sqls.push(sql__default["default"]`${key}::text, jsonb_build_object(${sql.join(subSqls, ", ")})`);
201
+ sqls.push(sql__default["default"]`jsonb_build_object(${sql.join(subSqls, ", ")}) AS "${sql.raw(key)}"`);
197
202
  } else {
198
- sqls.push(sql__default["default"]`${key}::text, "${sql.raw(key)}"`);
203
+ sqls.push(sql__default["default"]`"${sql.raw(key)}"`);
199
204
  }
200
205
  }
201
- return sql__default["default"]`jsonb_build_object(${sql.join(sqls, ", ")})`;
206
+ return sql.join(sqls, ", ");
202
207
  };
203
208
  function vertexSql(array, nullValue) {
204
209
  return sql__default["default"]`array[${sql.join(array.map((num) => num === null ? nullValue : num))}]::float8[]`;
@@ -336,49 +341,46 @@ function getSql(filter, options) {
336
341
  }
337
342
  return getNodeSql(getAst(filter));
338
343
  }
339
- const getIdMeta = ({ idCol, verDefault }) => getJsonBuildTrusted({
340
- $key: sql__default["default"]`"${sql.raw(idCol)}"`,
341
- $ver: sql.raw(verDefault)
342
- });
343
- const getArgMeta = (key, { prefix, idCol, verDefault }) => getJsonBuildTrusted({
344
- $key: key,
345
- $ref: sql__default["default"]`jsonb_build_array(${sql.join(prefix.map((k) => sql__default["default"]`${k}::text`))}, "${sql.raw(idCol)}")`,
346
- $ver: sql.raw(verDefault)
347
- });
348
- const getAggMeta = (key, $group, { verDefault }) => getJsonBuildTrusted({
349
- $key: sql.join([key, getJsonBuildTrusted({ $group })].filter(Boolean), " || "),
350
- $ver: sql.raw(verDefault)
351
- });
344
+ const getIdMeta = ({ idCol, verDefault }) => sql__default["default"]`"${sql.raw(idCol)}" AS "$key", ${sql.raw(verDefault)} AS "$ver"`;
345
+ const getArgMeta = (key, { prefix, idCol, verDefault }) => sql__default["default"]`
346
+ ${key} AS "$key",
347
+ ${sql.raw(verDefault)} AS "$ver",
348
+ array[
349
+ ${sql.join(prefix.map((k) => sql__default["default"]`${k}::text`))},
350
+ "${sql.raw(idCol)}"
351
+ ]::text[] AS "$ref"
352
+ `;
353
+ const getAggMeta = (key, { verDefault }) => sql__default["default"]`${key} AS "$key", ${sql.raw(verDefault)} AS "$ver"`;
352
354
  function getArgSql(_a, options) {
353
355
  var _b = _a, { $first, $last, $after, $before, $since, $until, $all, $cursor: _ } = _b, rest = __objRest(_b, ["$first", "$last", "$after", "$before", "$since", "$until", "$all", "$cursor"]);
354
356
  const _a2 = rest, { $order, $group } = _a2, filter = __objRest(_a2, ["$order", "$group"]);
355
357
  const { prefix, idCol } = options;
358
+ const meta = (key2) => $group ? getAggMeta(key2, options) : getArgMeta(key2, options);
359
+ const hasRangeArg = $before || $after || $since || $until || $first || $last || $all;
356
360
  if ($order && $group) {
357
361
  throw Error("pg_arg.order_and_group_unsupported in " + prefix);
358
362
  }
359
- const meta = (key2) => $group ? getAggMeta(key2, $group, options) : getArgMeta(key2, options);
360
- const groupCols = Array.isArray($group) && $group.length && $group.map(lookup);
361
- const group = groupCols ? sql.join(groupCols, ", ") : void 0;
362
- const hasRangeArg = $before || $after || $since || $until || $first || $last || $all || $order;
363
- let key;
363
+ if (($order || $group && $group !== true) && !hasRangeArg) {
364
+ throw Error("pg_arg.range_arg_expected in " + prefix);
365
+ }
366
+ const baseKey = sql__default["default"]`${JSON.stringify(rest)}::jsonb`;
364
367
  const where = [];
365
- if (!common.isEmpty(filter)) {
368
+ if (!common.isEmpty(filter))
366
369
  where.push(getSql(filter, options));
367
- key = sql__default["default"]`${JSON.stringify(filter)}::jsonb`;
368
- }
369
370
  if (!hasRangeArg)
370
- return { meta: meta(key), where, group, limit: 1 };
371
+ return { meta: meta(baseKey), where, limit: 1 };
372
+ const groupCols = Array.isArray($group) && $group.length && $group.map(lookup);
373
+ const group = groupCols ? sql.join(groupCols, ", ") : void 0;
371
374
  const orderCols = ($order || [idCol]).map((orderItem) => orderItem[0] === "!" ? sql__default["default"]`-(${lookup(orderItem.slice(1))})::float8` : lookup(orderItem));
372
375
  Object.entries({ $after, $before, $since, $until }).forEach(([name, value]) => {
373
376
  if (value)
374
377
  where.push(getBoundCond(orderCols, value, name));
375
378
  });
376
379
  const order = !$group && sql.join(($order || [idCol]).map((orderItem) => orderItem[0] === "!" ? sql__default["default"]`${lookup(orderItem.slice(1))} ${$last ? sql__default["default"]`ASC` : sql__default["default"]`DESC`}` : sql__default["default"]`${lookup(orderItem)} ${$last ? sql__default["default"]`DESC` : sql__default["default"]`ASC`}`), `, `);
377
- const orderKey = $order && getJsonBuildTrusted({ $order: sql__default["default"]`${JSON.stringify($order)}::jsonb` });
378
380
  const cursorKey = getJsonBuildTrusted({
379
- $cursor: sql__default["default"]`jsonb_build_array(${sql.join(groupCols || orderCols)})`
381
+ $cursor: $group === true ? sql__default["default"]`''` : sql__default["default"]`jsonb_build_array(${sql.join(groupCols || orderCols)})`
380
382
  });
381
- key = sql__default["default"]`(${sql.join([key, orderKey, cursorKey].filter(Boolean), ` || `)})`;
383
+ const key = sql__default["default"]`(${baseKey} || ${cursorKey})`;
382
384
  return {
383
385
  meta: meta(key),
384
386
  where,
@@ -423,7 +425,7 @@ function selectByArgs(args, projection, options) {
423
425
  const clampedLimit = Math.min(MAX_LIMIT, limit || MAX_LIMIT);
424
426
  return sql__default["default"]`
425
427
  SELECT
426
- ${getSelectCols(table, projection)} || ${meta}
428
+ ${getSelectCols(table, projection)}, ${meta}
427
429
  FROM "${sql.raw(table)}"
428
430
  ${where.length ? sql__default["default"]`WHERE ${sql.join(where, ` AND `)}` : sql.empty}
429
431
  ${group ? sql__default["default"]`GROUP BY ${group}` : sql.empty}
@@ -435,7 +437,7 @@ function selectByIds(ids, projection, options) {
435
437
  const { table, idCol } = options;
436
438
  return sql__default["default"]`
437
439
  SELECT
438
- ${getSelectCols(table, projection)} || ${getIdMeta(options)}
440
+ ${getSelectCols(table, projection)}, ${getIdMeta(options)}
439
441
  FROM "${sql.raw(table)}"
440
442
  WHERE "${sql.raw(idCol)}" IN (${sql.join(ids)})
441
443
  `;
@@ -468,7 +470,7 @@ function patch(object, arg, options) {
468
470
  return sql__default["default"]`
469
471
  UPDATE "${sql.raw(table)}" SET ${getUpdates(row, options)}
470
472
  WHERE ${where}
471
- RETURNING (${getSelectCols(table)} || ${meta})`;
473
+ RETURNING ${getSelectCols(table)}, ${meta}`;
472
474
  }
473
475
  function put(object, arg, options) {
474
476
  const { idCol, table } = options;
@@ -485,7 +487,7 @@ function put(object, arg, options) {
485
487
  return sql__default["default"]`
486
488
  INSERT INTO "${sql.raw(table)}" (${cols}) VALUES (${vals})
487
489
  ON CONFLICT (${conflictTarget}) DO UPDATE SET (${cols}) = (${vals})
488
- RETURNING (${getSelectCols(table)} || ${meta})`;
490
+ RETURNING ${getSelectCols(table)}, ${meta}`;
489
491
  }
490
492
  function del(arg, options) {
491
493
  const { table } = options;
@@ -493,7 +495,7 @@ function del(arg, options) {
493
495
  return sql__default["default"]`
494
496
  DELETE FROM "${sql.raw(table)}"
495
497
  WHERE ${where}
496
- RETURNING (${getJsonBuildTrusted({ $key: arg })})`;
498
+ RETURNING ${arg} "$key"`;
497
499
  }
498
500
  const log = debug__default["default"]("graffy:pg:db");
499
501
  class Db {
@@ -505,9 +507,16 @@ class Db {
505
507
  }
506
508
  }
507
509
  async query(sql2) {
508
- sql2.rowMode = "array";
509
510
  log("Making SQL query: " + sql2.text, sql2.values);
510
511
  try {
512
+ sql2.types = {
513
+ getTypeParser: (oid, format) => {
514
+ if (oid === pg$1.types.builtins.INT8) {
515
+ return (value) => parseInt(value, 10);
516
+ }
517
+ return pg$1.types.getTypeParser(oid, format);
518
+ }
519
+ };
511
520
  return await this.client.query(sql2);
512
521
  } catch (e) {
513
522
  const message = [
@@ -522,7 +531,7 @@ class Db {
522
531
  }
523
532
  }
524
533
  async readSql(sql2) {
525
- const result = (await this.query(sql2)).rows.flat();
534
+ const result = (await this.query(sql2)).rows;
526
535
  log("Read result", result);
527
536
  return result;
528
537
  }
@@ -532,7 +541,7 @@ class Db {
532
541
  if (!res.rowCount) {
533
542
  throw Error("pg.nothing_written " + sql2.text + " with " + sql2.values);
534
543
  }
535
- return res.rows[0][0];
544
+ return res.rows[0];
536
545
  }
537
546
  async ensureSchema(tableOptions) {
538
547
  if (tableOptions.schema)
@@ -543,13 +552,13 @@ class Db {
543
552
  FROM information_schema.tables
544
553
  WHERE table_name = ${table}
545
554
  ORDER BY array_position(current_schemas(false)::text[], table_schema::text) ASC
546
- LIMIT 1`)).rows[0][0];
555
+ LIMIT 1`)).rows[0].table_schema;
547
556
  const types = (await this.query(sql__default["default"]`
548
- SELECT jsonb_object_agg(column_name, udt_name)
557
+ SELECT jsonb_object_agg(column_name, udt_name) AS column_types
549
558
  FROM information_schema.columns
550
559
  WHERE
551
560
  table_name = ${table} AND
552
- table_schema = ${tableSchema}`)).rows[0][0];
561
+ table_schema = ${tableSchema}`)).rows[0].column_types;
553
562
  if (!types)
554
563
  throw Error(`pg.missing_table ${table}`);
555
564
  const verDefault = (await this.query(sql__default["default"]`
@@ -558,7 +567,7 @@ class Db {
558
567
  WHERE
559
568
  table_name = ${table} AND
560
569
  table_schema = ${tableSchema} AND
561
- column_name = ${verCol}`)).rows[0][0];
570
+ column_name = ${verCol}`)).rows[0].column_default;
562
571
  if (!verDefault) {
563
572
  throw Error(`pg.verCol_without_default ${verCol}`);
564
573
  }
package/index.mjs CHANGED
@@ -27,7 +27,7 @@ var __objRest = (source, exclude) => {
27
27
  return target;
28
28
  };
29
29
  import { isEmpty, encodePath, isPlainObject, unwrap, decodeArgs, decodeQuery, finalize, wrap, isRange, decodeGraph, mergeObject, merge, encodeGraph, wrapObject, remove } from "@graffy/common";
30
- import { Pool, Client } from "pg";
30
+ import { Pool, Client, types } from "pg";
31
31
  import sql, { join, raw, Sql, empty } from "sql-template-tag";
32
32
  import debug from "debug";
33
33
  const valid = {
@@ -167,31 +167,35 @@ const lookup = (prop) => {
167
167
  const [prefix, ...suffix] = encodePath(prop);
168
168
  return suffix.length ? sql`"${raw(prefix)}" #> ${suffix}` : sql`"${raw(prefix)}"`;
169
169
  };
170
+ const lookupNumeric = (prop) => {
171
+ const [prefix, ...suffix] = encodePath(prop);
172
+ return suffix.length ? sql`CASE WHEN "${raw(prefix)}" #> ${suffix} = 'null'::jsonb THEN 0 ELSE ("${raw(prefix)}" #> ${suffix})::numeric END` : sql`"${raw(prefix)}"`;
173
+ };
170
174
  const aggSql = {
171
- $sum: (prop) => sql`sum((${lookup(prop)})::numeric)`,
175
+ $sum: (prop) => sql`sum((${lookupNumeric(prop)})::numeric)`,
172
176
  $card: (prop) => sql`count(distinct(${lookup(prop)}))`,
173
- $avg: (prop) => sql`sum((${lookup(prop)})::numeric)`,
174
- $max: (prop) => sql`sum((${lookup(prop)})::numeric)`,
175
- $min: (prop) => sql`sum((${lookup(prop)})::numeric)`
177
+ $avg: (prop) => sql`avg((${lookupNumeric(prop)})::numeric)`,
178
+ $max: (prop) => sql`max((${lookupNumeric(prop)})::numeric)`,
179
+ $min: (prop) => sql`min((${lookupNumeric(prop)})::numeric)`
176
180
  };
177
181
  const getSelectCols = (table, projection = null) => {
178
182
  if (!projection)
179
- return sql`to_jsonb("${raw(table)}")`;
183
+ return sql`*`;
180
184
  const sqls = [];
181
185
  for (const key in projection) {
182
186
  if (key === "$count") {
183
- sqls.push(sql`'$count', count(*)`);
187
+ sqls.push(sql`count(*) AS "$count"`);
184
188
  } else if (aggSql[key]) {
185
189
  const subSqls = [];
186
190
  for (const prop in projection[key]) {
187
191
  subSqls.push(sql`${prop}::text, ${aggSql[key](prop)}`);
188
192
  }
189
- sqls.push(sql`${key}::text, jsonb_build_object(${join(subSqls, ", ")})`);
193
+ sqls.push(sql`jsonb_build_object(${join(subSqls, ", ")}) AS "${raw(key)}"`);
190
194
  } else {
191
- sqls.push(sql`${key}::text, "${raw(key)}"`);
195
+ sqls.push(sql`"${raw(key)}"`);
192
196
  }
193
197
  }
194
- return sql`jsonb_build_object(${join(sqls, ", ")})`;
198
+ return join(sqls, ", ");
195
199
  };
196
200
  function vertexSql(array, nullValue) {
197
201
  return sql`array[${join(array.map((num) => num === null ? nullValue : num))}]::float8[]`;
@@ -312,10 +316,10 @@ function getSql(filter, options) {
312
316
  return sql`${opSql[op]} (${getNodeSql(ast[1])})`;
313
317
  }
314
318
  const [prefix, ...suffix] = encodePath(ast[1]);
315
- const { types } = options.schema;
316
- if (!types[prefix])
319
+ const { types: types2 } = options.schema;
320
+ if (!types2[prefix])
317
321
  throw Error("pg.no_column " + prefix);
318
- if (types[prefix] === "jsonb") {
322
+ if (types2[prefix] === "jsonb") {
319
323
  const [lhs, textLhs] = suffix.length ? [
320
324
  sql`"${raw(prefix)}" #> ${suffix}`,
321
325
  sql`"${raw(prefix)}" #>> ${suffix}`
@@ -324,54 +328,51 @@ function getSql(filter, options) {
324
328
  } else {
325
329
  if (suffix.length)
326
330
  throw Error("pg.lookup_not_jsonb " + prefix);
327
- return getBinarySql(sql`"${raw(prefix)}"`, types[prefix], op, ast[2]);
331
+ return getBinarySql(sql`"${raw(prefix)}"`, types2[prefix], op, ast[2]);
328
332
  }
329
333
  }
330
334
  return getNodeSql(getAst(filter));
331
335
  }
332
- const getIdMeta = ({ idCol, verDefault }) => getJsonBuildTrusted({
333
- $key: sql`"${raw(idCol)}"`,
334
- $ver: raw(verDefault)
335
- });
336
- const getArgMeta = (key, { prefix, idCol, verDefault }) => getJsonBuildTrusted({
337
- $key: key,
338
- $ref: sql`jsonb_build_array(${join(prefix.map((k) => sql`${k}::text`))}, "${raw(idCol)}")`,
339
- $ver: raw(verDefault)
340
- });
341
- const getAggMeta = (key, $group, { verDefault }) => getJsonBuildTrusted({
342
- $key: join([key, getJsonBuildTrusted({ $group })].filter(Boolean), " || "),
343
- $ver: raw(verDefault)
344
- });
336
+ const getIdMeta = ({ idCol, verDefault }) => sql`"${raw(idCol)}" AS "$key", ${raw(verDefault)} AS "$ver"`;
337
+ const getArgMeta = (key, { prefix, idCol, verDefault }) => sql`
338
+ ${key} AS "$key",
339
+ ${raw(verDefault)} AS "$ver",
340
+ array[
341
+ ${join(prefix.map((k) => sql`${k}::text`))},
342
+ "${raw(idCol)}"
343
+ ]::text[] AS "$ref"
344
+ `;
345
+ const getAggMeta = (key, { verDefault }) => sql`${key} AS "$key", ${raw(verDefault)} AS "$ver"`;
345
346
  function getArgSql(_a, options) {
346
347
  var _b = _a, { $first, $last, $after, $before, $since, $until, $all, $cursor: _ } = _b, rest = __objRest(_b, ["$first", "$last", "$after", "$before", "$since", "$until", "$all", "$cursor"]);
347
348
  const _a2 = rest, { $order, $group } = _a2, filter = __objRest(_a2, ["$order", "$group"]);
348
349
  const { prefix, idCol } = options;
350
+ const meta = (key2) => $group ? getAggMeta(key2, options) : getArgMeta(key2, options);
351
+ const hasRangeArg = $before || $after || $since || $until || $first || $last || $all;
349
352
  if ($order && $group) {
350
353
  throw Error("pg_arg.order_and_group_unsupported in " + prefix);
351
354
  }
352
- const meta = (key2) => $group ? getAggMeta(key2, $group, options) : getArgMeta(key2, options);
353
- const groupCols = Array.isArray($group) && $group.length && $group.map(lookup);
354
- const group = groupCols ? join(groupCols, ", ") : void 0;
355
- const hasRangeArg = $before || $after || $since || $until || $first || $last || $all || $order;
356
- let key;
355
+ if (($order || $group && $group !== true) && !hasRangeArg) {
356
+ throw Error("pg_arg.range_arg_expected in " + prefix);
357
+ }
358
+ const baseKey = sql`${JSON.stringify(rest)}::jsonb`;
357
359
  const where = [];
358
- if (!isEmpty(filter)) {
360
+ if (!isEmpty(filter))
359
361
  where.push(getSql(filter, options));
360
- key = sql`${JSON.stringify(filter)}::jsonb`;
361
- }
362
362
  if (!hasRangeArg)
363
- return { meta: meta(key), where, group, limit: 1 };
363
+ return { meta: meta(baseKey), where, limit: 1 };
364
+ const groupCols = Array.isArray($group) && $group.length && $group.map(lookup);
365
+ const group = groupCols ? join(groupCols, ", ") : void 0;
364
366
  const orderCols = ($order || [idCol]).map((orderItem) => orderItem[0] === "!" ? sql`-(${lookup(orderItem.slice(1))})::float8` : lookup(orderItem));
365
367
  Object.entries({ $after, $before, $since, $until }).forEach(([name, value]) => {
366
368
  if (value)
367
369
  where.push(getBoundCond(orderCols, value, name));
368
370
  });
369
371
  const order = !$group && join(($order || [idCol]).map((orderItem) => orderItem[0] === "!" ? sql`${lookup(orderItem.slice(1))} ${$last ? sql`ASC` : sql`DESC`}` : sql`${lookup(orderItem)} ${$last ? sql`DESC` : sql`ASC`}`), `, `);
370
- const orderKey = $order && getJsonBuildTrusted({ $order: sql`${JSON.stringify($order)}::jsonb` });
371
372
  const cursorKey = getJsonBuildTrusted({
372
- $cursor: sql`jsonb_build_array(${join(groupCols || orderCols)})`
373
+ $cursor: $group === true ? sql`''` : sql`jsonb_build_array(${join(groupCols || orderCols)})`
373
374
  });
374
- key = sql`(${join([key, orderKey, cursorKey].filter(Boolean), ` || `)})`;
375
+ const key = sql`(${baseKey} || ${cursorKey})`;
375
376
  return {
376
377
  meta: meta(key),
377
378
  where,
@@ -416,7 +417,7 @@ function selectByArgs(args, projection, options) {
416
417
  const clampedLimit = Math.min(MAX_LIMIT, limit || MAX_LIMIT);
417
418
  return sql`
418
419
  SELECT
419
- ${getSelectCols(table, projection)} || ${meta}
420
+ ${getSelectCols(table, projection)}, ${meta}
420
421
  FROM "${raw(table)}"
421
422
  ${where.length ? sql`WHERE ${join(where, ` AND `)}` : empty}
422
423
  ${group ? sql`GROUP BY ${group}` : empty}
@@ -428,7 +429,7 @@ function selectByIds(ids, projection, options) {
428
429
  const { table, idCol } = options;
429
430
  return sql`
430
431
  SELECT
431
- ${getSelectCols(table, projection)} || ${getIdMeta(options)}
432
+ ${getSelectCols(table, projection)}, ${getIdMeta(options)}
432
433
  FROM "${raw(table)}"
433
434
  WHERE "${raw(idCol)}" IN (${join(ids)})
434
435
  `;
@@ -461,7 +462,7 @@ function patch(object, arg, options) {
461
462
  return sql`
462
463
  UPDATE "${raw(table)}" SET ${getUpdates(row, options)}
463
464
  WHERE ${where}
464
- RETURNING (${getSelectCols(table)} || ${meta})`;
465
+ RETURNING ${getSelectCols(table)}, ${meta}`;
465
466
  }
466
467
  function put(object, arg, options) {
467
468
  const { idCol, table } = options;
@@ -478,7 +479,7 @@ function put(object, arg, options) {
478
479
  return sql`
479
480
  INSERT INTO "${raw(table)}" (${cols}) VALUES (${vals})
480
481
  ON CONFLICT (${conflictTarget}) DO UPDATE SET (${cols}) = (${vals})
481
- RETURNING (${getSelectCols(table)} || ${meta})`;
482
+ RETURNING ${getSelectCols(table)}, ${meta}`;
482
483
  }
483
484
  function del(arg, options) {
484
485
  const { table } = options;
@@ -486,7 +487,7 @@ function del(arg, options) {
486
487
  return sql`
487
488
  DELETE FROM "${raw(table)}"
488
489
  WHERE ${where}
489
- RETURNING (${getJsonBuildTrusted({ $key: arg })})`;
490
+ RETURNING ${arg} "$key"`;
490
491
  }
491
492
  const log = debug("graffy:pg:db");
492
493
  class Db {
@@ -498,9 +499,16 @@ class Db {
498
499
  }
499
500
  }
500
501
  async query(sql2) {
501
- sql2.rowMode = "array";
502
502
  log("Making SQL query: " + sql2.text, sql2.values);
503
503
  try {
504
+ sql2.types = {
505
+ getTypeParser: (oid, format) => {
506
+ if (oid === types.builtins.INT8) {
507
+ return (value) => parseInt(value, 10);
508
+ }
509
+ return types.getTypeParser(oid, format);
510
+ }
511
+ };
504
512
  return await this.client.query(sql2);
505
513
  } catch (e) {
506
514
  const message = [
@@ -515,7 +523,7 @@ class Db {
515
523
  }
516
524
  }
517
525
  async readSql(sql2) {
518
- const result = (await this.query(sql2)).rows.flat();
526
+ const result = (await this.query(sql2)).rows;
519
527
  log("Read result", result);
520
528
  return result;
521
529
  }
@@ -525,7 +533,7 @@ class Db {
525
533
  if (!res.rowCount) {
526
534
  throw Error("pg.nothing_written " + sql2.text + " with " + sql2.values);
527
535
  }
528
- return res.rows[0][0];
536
+ return res.rows[0];
529
537
  }
530
538
  async ensureSchema(tableOptions) {
531
539
  if (tableOptions.schema)
@@ -536,14 +544,14 @@ class Db {
536
544
  FROM information_schema.tables
537
545
  WHERE table_name = ${table}
538
546
  ORDER BY array_position(current_schemas(false)::text[], table_schema::text) ASC
539
- LIMIT 1`)).rows[0][0];
540
- const types = (await this.query(sql`
541
- SELECT jsonb_object_agg(column_name, udt_name)
547
+ LIMIT 1`)).rows[0].table_schema;
548
+ const types2 = (await this.query(sql`
549
+ SELECT jsonb_object_agg(column_name, udt_name) AS column_types
542
550
  FROM information_schema.columns
543
551
  WHERE
544
552
  table_name = ${table} AND
545
- table_schema = ${tableSchema}`)).rows[0][0];
546
- if (!types)
553
+ table_schema = ${tableSchema}`)).rows[0].column_types;
554
+ if (!types2)
547
555
  throw Error(`pg.missing_table ${table}`);
548
556
  const verDefault = (await this.query(sql`
549
557
  SELECT column_default
@@ -551,12 +559,12 @@ class Db {
551
559
  WHERE
552
560
  table_name = ${table} AND
553
561
  table_schema = ${tableSchema} AND
554
- column_name = ${verCol}`)).rows[0][0];
562
+ column_name = ${verCol}`)).rows[0].column_default;
555
563
  if (!verDefault) {
556
564
  throw Error(`pg.verCol_without_default ${verCol}`);
557
565
  }
558
- log("ensureSchema", types);
559
- tableOptions.schema = { types };
566
+ log("ensureSchema", types2);
567
+ tableOptions.schema = { types: types2 };
560
568
  tableOptions.verDefault = verDefault;
561
569
  }
562
570
  async read(rootQuery, tableOptions) {
package/package.json CHANGED
@@ -2,7 +2,7 @@
2
2
  "name": "@graffy/pg",
3
3
  "description": "The standard Postgres module for Graffy. Each instance this module mounts a Postgres table as a Graffy subtree.",
4
4
  "author": "aravind (https://github.com/aravindet)",
5
- "version": "0.15.23",
5
+ "version": "0.15.25-alpha.1",
6
6
  "main": "./index.cjs",
7
7
  "exports": {
8
8
  "import": "./index.mjs",
@@ -16,7 +16,7 @@
16
16
  },
17
17
  "license": "Apache-2.0",
18
18
  "dependencies": {
19
- "@graffy/common": "0.15.23",
19
+ "@graffy/common": "0.15.25-alpha.1",
20
20
  "sql-template-tag": "^4.1.0",
21
21
  "debug": "^4.3.3"
22
22
  },
@@ -1,6 +1,7 @@
1
1
  export function cubeLiteralSql(value: any): Sql;
2
2
  export function getJsonBuildTrusted(variadic: any): Sql;
3
3
  export function lookup(prop: any): Sql;
4
+ export function lookupNumeric(prop: any): Sql;
4
5
  export function getSelectCols(table: any, projection?: any): Sql;
5
6
  export function getInsert(row: any, options: any): {
6
7
  cols: Sql;
@@ -2,7 +2,7 @@
2
2
  Uses the args object (typically passed in the $key attribute)
3
3
 
4
4
  @param {object} args
5
- @param {{prefix: string, idCol: string}} options
5
+ @param {{prefix: string, idCol: string, verDefault: string}} options
6
6
 
7
7
  @typedef { import('sql-template-tag').Sql } Sql
8
8
  @return {{ meta: Sql, where: Sql[], order?: Sql, group?: Sql, limit: number }}
@@ -10,6 +10,7 @@
10
10
  export default function getArgSql({ $first, $last, $after, $before, $since, $until, $all, $cursor: _, ...rest }: object, options: {
11
11
  prefix: string;
12
12
  idCol: string;
13
+ verDefault: string;
13
14
  }): {
14
15
  meta: Sql;
15
16
  where: Sql[];
@@ -7,6 +7,6 @@ export function getArgMeta(key: any, { prefix, idCol, verDefault }: {
7
7
  idCol: any;
8
8
  verDefault: any;
9
9
  }): import("sql-template-tag").Sql;
10
- export function getAggMeta(key: any, $group: any, { verDefault }: {
10
+ export function getAggMeta(key: any, { verDefault }: {
11
11
  verDefault: any;
12
12
  }): import("sql-template-tag").Sql;