@graffy/pg 0.15.21 → 0.15.22-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
@@ -201,8 +201,14 @@ const getSelectCols = (table, projection = null) => {
201
201
  }
202
202
  return sql__default["default"]`jsonb_build_object(${sql.join(sqls, ", ")})`;
203
203
  };
204
- function vertexSql(array) {
205
- return sql__default["default"]`array[${sql.join(array.map((num) => num === Infinity ? sql__default["default"]`'Infinity'` : num === -Infinity ? sql__default["default"]`'-Infinity'` : num))}]::float8[]`;
204
+ function vertexSql(array, nullValue) {
205
+ return sql__default["default"]`array[${sql.join(array.map((num) => num === null ? nullValue : num))}]::float8[]`;
206
+ }
207
+ function cubeLiteralSql(value) {
208
+ if (!Array.isArray(value) || !value.length || Array.isArray(value[0]) && value.length !== 2) {
209
+ throw Error("pg.castValue_bad_cube" + JSON.stringify(value));
210
+ }
211
+ return Array.isArray(value[0]) ? sql__default["default"]`cube(${vertexSql(value[0], sql__default["default"]`'-Infinity'`)}, ${vertexSql(value[1], sql__default["default"]`'Infinity'`)})` : sql__default["default"]`cube(${vertexSql(value, 0)})`;
206
212
  }
207
213
  function castValue(value, type, name, isPut) {
208
214
  if (!type)
@@ -214,12 +220,8 @@ function castValue(value, type, name, isPut) {
214
220
  if (type === "jsonb") {
215
221
  return isPut ? JSON.stringify(stripAttributes(value)) : sql__default["default"]`jsonb_strip_nulls(${getJsonUpdate(value, name, [])})`;
216
222
  }
217
- if (type === "cube") {
218
- if (!Array.isArray(value) || !value.length || Array.isArray(value[0]) && value.length !== 2) {
219
- throw Error("pg.castValue_bad_cube" + JSON.stringify(value));
220
- }
221
- return Array.isArray(value[0]) ? sql__default["default"]`cube(${vertexSql(value[0])}, ${vertexSql(value[1])})` : sql__default["default"]`cube(${vertexSql(value)})`;
222
- }
223
+ if (type === "cube")
224
+ return cubeLiteralSql(value);
223
225
  return value;
224
226
  }
225
227
  const getInsert = (row, options) => {
@@ -276,7 +278,7 @@ const opSql = {
276
278
  $cts: sql__default["default"]`@>`,
277
279
  $ctd: sql__default["default"]`<@`
278
280
  };
279
- function getBinarySql(lhs, type, op, value) {
281
+ function getBinarySql(lhs, type, op, value, textLhs) {
280
282
  if (value === null && op === "$eq")
281
283
  return sql__default["default"]`${lhs} IS NULL`;
282
284
  if (value === null && op === "$neq")
@@ -285,21 +287,23 @@ function getBinarySql(lhs, type, op, value) {
285
287
  if (!sqlOp)
286
288
  throw Error("pg.getSql_unknown_operator " + op);
287
289
  if (op === "$in" || op === "$nin") {
290
+ if (type === "jsonb" && typeof value[0] === "string")
291
+ lhs = textLhs;
288
292
  return sql__default["default"]`${lhs} ${sqlOp} (${sql.join(value)})`;
289
293
  }
290
294
  if (op === "$re" || op === "$ire") {
291
- const castLhs = type === "text" ? lhs : type === "jsonb" ? sql__default["default"]`(${lhs})#>>'{}'` : sql__default["default"]`(${lhs})::text`;
292
- return sql__default["default"]`${castLhs} ${sqlOp} ${String(value)}`;
295
+ if (type === "jsonb") {
296
+ lhs = textLhs;
297
+ } else if (type !== "text") {
298
+ lhs = sql__default["default"]`(${lhs})::text`;
299
+ }
300
+ return sql__default["default"]`${lhs} ${sqlOp} ${String(value)}`;
293
301
  }
294
302
  if (type === "jsonb") {
295
303
  return sql__default["default"]`${lhs} ${sqlOp} ${JSON.stringify(value)}::jsonb`;
296
304
  }
297
- if (type === "cube") {
298
- if (!Array.isArray(value) || !value.length || Array.isArray(value[0]) && value.length !== 2) {
299
- throw Error("pg.getBinarySql_bad_cube" + JSON.stringify(value));
300
- }
301
- return Array.isArray(value[0]) ? sql__default["default"]`${lhs} ${sqlOp} cube(${vertexSql(value[0])}, ${vertexSql(value[1])})` : sql__default["default"]`${lhs} ${sqlOp} cube(${vertexSql(value)})`;
302
- }
305
+ if (type === "cube")
306
+ return sql__default["default"]`${lhs} ${sqlOp} ${cubeLiteralSql(value)}`;
303
307
  return sql__default["default"]`${lhs} ${sqlOp} ${value}`;
304
308
  }
305
309
  function getSql(filter, options) {
@@ -316,11 +320,17 @@ function getSql(filter, options) {
316
320
  const { types } = options.schema;
317
321
  if (!types[prefix])
318
322
  throw Error("pg.no_column " + prefix);
319
- if (suffix.length && types[prefix] !== "jsonb") {
320
- throw Error("pg.lookup_not_jsonb " + prefix);
323
+ if (types[prefix] === "jsonb") {
324
+ const [lhs, textLhs] = suffix.length ? [
325
+ sql__default["default"]`"${sql.raw(prefix)}" #> ${suffix}`,
326
+ sql__default["default"]`"${sql.raw(prefix)}" #>> ${suffix}`
327
+ ] : [sql__default["default"]`"${sql.raw(prefix)}"`, sql__default["default"]`"${sql.raw(prefix)}" #>> '{}'`];
328
+ return getBinarySql(lhs, "jsonb", op, ast[2], textLhs);
329
+ } else {
330
+ if (suffix.length)
331
+ throw Error("pg.lookup_not_jsonb " + prefix);
332
+ return getBinarySql(sql__default["default"]`"${sql.raw(prefix)}"`, types[prefix], op, ast[2]);
321
333
  }
322
- const [lhs, type] = suffix.length ? [sql__default["default"]`"${sql.raw(prefix)}" #> ${suffix}`, "jsonb"] : [sql__default["default"]`"${sql.raw(prefix)}"`, types[prefix]];
323
- return getBinarySql(lhs, type, op, ast[2]);
324
334
  }
325
335
  return getNodeSql(getAst(filter));
326
336
  }
@@ -356,14 +366,12 @@ function getArgSql(_a, options) {
356
366
  }
357
367
  if (!hasRangeArg)
358
368
  return { meta: meta(key), where, group, limit: 1 };
359
- if (common.isEmpty(rest)) {
360
- throw Error("pg_arg.pagination_only_unsupported in " + prefix);
361
- }
362
369
  const orderCols = ($order || [idCol]).map((orderItem) => orderItem[0] === "!" ? sql__default["default"]`-(${lookup(orderItem.slice(1))})::float8` : lookup(orderItem));
363
370
  Object.entries({ $after, $before, $since, $until }).forEach(([name, value]) => {
364
371
  if (value)
365
372
  where.push(getBoundCond(orderCols, value, name));
366
373
  });
374
+ 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`}`), `, `);
367
375
  const orderKey = $order && getJsonBuildTrusted({ $order: sql__default["default"]`${JSON.stringify($order)}::jsonb` });
368
376
  const cursorKey = getJsonBuildTrusted({
369
377
  $cursor: sql__default["default"]`jsonb_build_array(${sql.join(groupCols || orderCols)})`
@@ -372,7 +380,7 @@ function getArgSql(_a, options) {
372
380
  return {
373
381
  meta: meta(key),
374
382
  where,
375
- order: $order && sql.join(orderCols.map((col) => sql__default["default"]`${col} ${$last ? sql__default["default"]`DESC` : sql__default["default"]`ASC`}`), `, `),
383
+ order,
376
384
  group,
377
385
  limit: $first || $last
378
386
  };
@@ -598,7 +606,7 @@ class Db {
598
606
  promises.push(getByIds());
599
607
  await Promise.all(promises);
600
608
  log("dbRead", rootQuery, results);
601
- return common.slice(common.finalize(results, common.wrap(query, prefix)), rootQuery).known || [];
609
+ return common.finalize(results, common.wrap(query, prefix));
602
610
  }
603
611
  async write(rootChange, tableOptions) {
604
612
  const { prefix } = tableOptions;
package/index.mjs CHANGED
@@ -26,7 +26,7 @@ var __objRest = (source, exclude) => {
26
26
  }
27
27
  return target;
28
28
  };
29
- import { isEmpty, encodePath, isPlainObject, unwrap, decodeArgs, decodeQuery, slice, finalize, wrap, isRange, decodeGraph, mergeObject, merge, encodeGraph, wrapObject, remove } from "@graffy/common";
29
+ import { isEmpty, encodePath, isPlainObject, unwrap, decodeArgs, decodeQuery, finalize, wrap, isRange, decodeGraph, mergeObject, merge, encodeGraph, wrapObject, remove } from "@graffy/common";
30
30
  import { Pool, Client } from "pg";
31
31
  import sql, { join, raw, Sql, empty } from "sql-template-tag";
32
32
  import debug from "debug";
@@ -193,8 +193,14 @@ const getSelectCols = (table, projection = null) => {
193
193
  }
194
194
  return sql`jsonb_build_object(${join(sqls, ", ")})`;
195
195
  };
196
- function vertexSql(array) {
197
- return sql`array[${join(array.map((num) => num === Infinity ? sql`'Infinity'` : num === -Infinity ? sql`'-Infinity'` : num))}]::float8[]`;
196
+ function vertexSql(array, nullValue) {
197
+ return sql`array[${join(array.map((num) => num === null ? nullValue : num))}]::float8[]`;
198
+ }
199
+ function cubeLiteralSql(value) {
200
+ if (!Array.isArray(value) || !value.length || Array.isArray(value[0]) && value.length !== 2) {
201
+ throw Error("pg.castValue_bad_cube" + JSON.stringify(value));
202
+ }
203
+ return Array.isArray(value[0]) ? sql`cube(${vertexSql(value[0], sql`'-Infinity'`)}, ${vertexSql(value[1], sql`'Infinity'`)})` : sql`cube(${vertexSql(value, 0)})`;
198
204
  }
199
205
  function castValue(value, type, name, isPut) {
200
206
  if (!type)
@@ -206,12 +212,8 @@ function castValue(value, type, name, isPut) {
206
212
  if (type === "jsonb") {
207
213
  return isPut ? JSON.stringify(stripAttributes(value)) : sql`jsonb_strip_nulls(${getJsonUpdate(value, name, [])})`;
208
214
  }
209
- if (type === "cube") {
210
- if (!Array.isArray(value) || !value.length || Array.isArray(value[0]) && value.length !== 2) {
211
- throw Error("pg.castValue_bad_cube" + JSON.stringify(value));
212
- }
213
- return Array.isArray(value[0]) ? sql`cube(${vertexSql(value[0])}, ${vertexSql(value[1])})` : sql`cube(${vertexSql(value)})`;
214
- }
215
+ if (type === "cube")
216
+ return cubeLiteralSql(value);
215
217
  return value;
216
218
  }
217
219
  const getInsert = (row, options) => {
@@ -268,7 +270,7 @@ const opSql = {
268
270
  $cts: sql`@>`,
269
271
  $ctd: sql`<@`
270
272
  };
271
- function getBinarySql(lhs, type, op, value) {
273
+ function getBinarySql(lhs, type, op, value, textLhs) {
272
274
  if (value === null && op === "$eq")
273
275
  return sql`${lhs} IS NULL`;
274
276
  if (value === null && op === "$neq")
@@ -277,21 +279,23 @@ function getBinarySql(lhs, type, op, value) {
277
279
  if (!sqlOp)
278
280
  throw Error("pg.getSql_unknown_operator " + op);
279
281
  if (op === "$in" || op === "$nin") {
282
+ if (type === "jsonb" && typeof value[0] === "string")
283
+ lhs = textLhs;
280
284
  return sql`${lhs} ${sqlOp} (${join(value)})`;
281
285
  }
282
286
  if (op === "$re" || op === "$ire") {
283
- const castLhs = type === "text" ? lhs : type === "jsonb" ? sql`(${lhs})#>>'{}'` : sql`(${lhs})::text`;
284
- return sql`${castLhs} ${sqlOp} ${String(value)}`;
287
+ if (type === "jsonb") {
288
+ lhs = textLhs;
289
+ } else if (type !== "text") {
290
+ lhs = sql`(${lhs})::text`;
291
+ }
292
+ return sql`${lhs} ${sqlOp} ${String(value)}`;
285
293
  }
286
294
  if (type === "jsonb") {
287
295
  return sql`${lhs} ${sqlOp} ${JSON.stringify(value)}::jsonb`;
288
296
  }
289
- if (type === "cube") {
290
- if (!Array.isArray(value) || !value.length || Array.isArray(value[0]) && value.length !== 2) {
291
- throw Error("pg.getBinarySql_bad_cube" + JSON.stringify(value));
292
- }
293
- return Array.isArray(value[0]) ? sql`${lhs} ${sqlOp} cube(${vertexSql(value[0])}, ${vertexSql(value[1])})` : sql`${lhs} ${sqlOp} cube(${vertexSql(value)})`;
294
- }
297
+ if (type === "cube")
298
+ return sql`${lhs} ${sqlOp} ${cubeLiteralSql(value)}`;
295
299
  return sql`${lhs} ${sqlOp} ${value}`;
296
300
  }
297
301
  function getSql(filter, options) {
@@ -308,11 +312,17 @@ function getSql(filter, options) {
308
312
  const { types } = options.schema;
309
313
  if (!types[prefix])
310
314
  throw Error("pg.no_column " + prefix);
311
- if (suffix.length && types[prefix] !== "jsonb") {
312
- throw Error("pg.lookup_not_jsonb " + prefix);
315
+ if (types[prefix] === "jsonb") {
316
+ const [lhs, textLhs] = suffix.length ? [
317
+ sql`"${raw(prefix)}" #> ${suffix}`,
318
+ sql`"${raw(prefix)}" #>> ${suffix}`
319
+ ] : [sql`"${raw(prefix)}"`, sql`"${raw(prefix)}" #>> '{}'`];
320
+ return getBinarySql(lhs, "jsonb", op, ast[2], textLhs);
321
+ } else {
322
+ if (suffix.length)
323
+ throw Error("pg.lookup_not_jsonb " + prefix);
324
+ return getBinarySql(sql`"${raw(prefix)}"`, types[prefix], op, ast[2]);
313
325
  }
314
- const [lhs, type] = suffix.length ? [sql`"${raw(prefix)}" #> ${suffix}`, "jsonb"] : [sql`"${raw(prefix)}"`, types[prefix]];
315
- return getBinarySql(lhs, type, op, ast[2]);
316
326
  }
317
327
  return getNodeSql(getAst(filter));
318
328
  }
@@ -348,14 +358,12 @@ function getArgSql(_a, options) {
348
358
  }
349
359
  if (!hasRangeArg)
350
360
  return { meta: meta(key), where, group, limit: 1 };
351
- if (isEmpty(rest)) {
352
- throw Error("pg_arg.pagination_only_unsupported in " + prefix);
353
- }
354
361
  const orderCols = ($order || [idCol]).map((orderItem) => orderItem[0] === "!" ? sql`-(${lookup(orderItem.slice(1))})::float8` : lookup(orderItem));
355
362
  Object.entries({ $after, $before, $since, $until }).forEach(([name, value]) => {
356
363
  if (value)
357
364
  where.push(getBoundCond(orderCols, value, name));
358
365
  });
366
+ 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`}`), `, `);
359
367
  const orderKey = $order && getJsonBuildTrusted({ $order: sql`${JSON.stringify($order)}::jsonb` });
360
368
  const cursorKey = getJsonBuildTrusted({
361
369
  $cursor: sql`jsonb_build_array(${join(groupCols || orderCols)})`
@@ -364,7 +372,7 @@ function getArgSql(_a, options) {
364
372
  return {
365
373
  meta: meta(key),
366
374
  where,
367
- order: $order && join(orderCols.map((col) => sql`${col} ${$last ? sql`DESC` : sql`ASC`}`), `, `),
375
+ order,
368
376
  group,
369
377
  limit: $first || $last
370
378
  };
@@ -590,7 +598,7 @@ class Db {
590
598
  promises.push(getByIds());
591
599
  await Promise.all(promises);
592
600
  log("dbRead", rootQuery, results);
593
- return slice(finalize(results, wrap(query, prefix)), rootQuery).known || [];
601
+ return finalize(results, wrap(query, prefix));
594
602
  }
595
603
  async write(rootChange, tableOptions) {
596
604
  const { prefix } = 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.21",
5
+ "version": "0.15.22-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.21",
19
+ "@graffy/common": "0.15.22-alpha.1",
20
20
  "sql-template-tag": "^4.1.0",
21
21
  "debug": "^4.3.3"
22
22
  },
@@ -1,4 +1,5 @@
1
- export function vertexSql(array: any): Sql;
1
+ export function vertexSql(array: any, nullValue: any): Sql;
2
+ export function cubeLiteralSql(value: any): Sql;
2
3
  export function getJsonBuildTrusted(variadic: any): Sql;
3
4
  export function lookup(prop: any): Sql;
4
5
  export function getSelectCols(table: any, projection?: any): Sql;
@@ -2,12 +2,15 @@
2
2
  Uses the args object (typically passed in the $key attribute)
3
3
 
4
4
  @param {object} args
5
- @param {object} options
5
+ @param {{prefix: string, idCol: 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 }}
9
9
  */
10
- export default function getArgSql({ $first, $last, $after, $before, $since, $until, $all, $cursor: _, ...rest }: object, options: object): {
10
+ export default function getArgSql({ $first, $last, $after, $before, $since, $until, $all, $cursor: _, ...rest }: object, options: {
11
+ prefix: string;
12
+ idCol: string;
13
+ }): {
11
14
  meta: Sql;
12
15
  where: Sql[];
13
16
  order?: Sql;