@graffy/pg 0.16.19 → 0.16.20-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 +42 -84
- package/index.mjs +42 -84
- package/package.json +3 -3
- package/types/sql/getArgSql.d.ts +1 -1
package/index.cjs
CHANGED
|
@@ -88,16 +88,13 @@ const getJsonBuildTrusted = (variadic) => {
|
|
|
88
88
|
return sql`jsonb_build_object(${args})`;
|
|
89
89
|
};
|
|
90
90
|
const getJsonBuildValue = (value) => {
|
|
91
|
-
if (value instanceof Sql)
|
|
92
|
-
|
|
93
|
-
if (typeof value === "string")
|
|
94
|
-
return sql`${value}::text`;
|
|
91
|
+
if (value instanceof Sql) return value;
|
|
92
|
+
if (typeof value === "string") return sql`${value}::text`;
|
|
95
93
|
return sql`${JSON.stringify(stripAttributes(value))}::jsonb`;
|
|
96
94
|
};
|
|
97
95
|
const lookup = (prop, options) => {
|
|
98
96
|
const [prefix, ...suffix] = prop.split(".");
|
|
99
|
-
if (!suffix.length)
|
|
100
|
-
return sql`"${raw(prefix)}"`;
|
|
97
|
+
if (!suffix.length) return sql`"${raw(prefix)}"`;
|
|
101
98
|
const { types: types2 } = options.schema;
|
|
102
99
|
if (types2[prefix] === "jsonb") {
|
|
103
100
|
return sql`"${raw(prefix)}" #> ${suffix}`;
|
|
@@ -120,8 +117,7 @@ const aggSql = {
|
|
|
120
117
|
$min: (prop) => sql`min((${lookupNumeric(prop)})::numeric)`
|
|
121
118
|
};
|
|
122
119
|
const getSelectCols = (options, projection = null) => {
|
|
123
|
-
if (!projection)
|
|
124
|
-
return sql`*`;
|
|
120
|
+
if (!projection) return sql`*`;
|
|
125
121
|
const sqls = [];
|
|
126
122
|
for (const key in projection) {
|
|
127
123
|
if (key === "$count") {
|
|
@@ -155,17 +151,13 @@ function cubeLiteralSql(value) {
|
|
|
155
151
|
)})` : sql`cube(${vertexSql(value, 0)})`;
|
|
156
152
|
}
|
|
157
153
|
function castValue(value, type, name, isPut) {
|
|
158
|
-
if (!type)
|
|
159
|
-
|
|
160
|
-
if (value
|
|
161
|
-
return value;
|
|
162
|
-
if (value === null)
|
|
163
|
-
return sql`NULL`;
|
|
154
|
+
if (!type) throw Error(`pg.write_no_column ${name}`);
|
|
155
|
+
if (value instanceof Sql) return value;
|
|
156
|
+
if (value === null) return sql`NULL`;
|
|
164
157
|
if (type === "jsonb") {
|
|
165
158
|
return isPut ? JSON.stringify(stripAttributes(value)) : getJsonUpdate(value, name, [])[0];
|
|
166
159
|
}
|
|
167
|
-
if (type === "cube")
|
|
168
|
-
return cubeLiteralSql(value);
|
|
160
|
+
if (type === "cube") return cubeLiteralSql(value);
|
|
169
161
|
return value;
|
|
170
162
|
}
|
|
171
163
|
const getInsert = (rows, options) => {
|
|
@@ -185,8 +177,7 @@ const getInsert = (rows, options) => {
|
|
|
185
177
|
for (const row of rows) {
|
|
186
178
|
const rowVals = Array(cols.length).fill(sql`default`);
|
|
187
179
|
for (const col of cols) {
|
|
188
|
-
if (col === verCol || !(col in row))
|
|
189
|
-
continue;
|
|
180
|
+
if (col === verCol || !(col in row)) continue;
|
|
190
181
|
const ix = colIx[col];
|
|
191
182
|
colUsed[ix] = true;
|
|
192
183
|
rowVals[ix] = castValue(row[col], schema.types[col], col, row.$put);
|
|
@@ -229,8 +220,7 @@ function getJsonUpdate(object, col, path) {
|
|
|
229
220
|
return [sql`${JSON.stringify({ $val: value })}::jsonb`, false];
|
|
230
221
|
}
|
|
231
222
|
const curr = sql`"${raw(col)}"${path.length ? sql`#>${path}` : empty}`;
|
|
232
|
-
if (common.isEmpty(object))
|
|
233
|
-
return [curr, false];
|
|
223
|
+
if (common.isEmpty(object)) return [curr, false];
|
|
234
224
|
const baseSql = sql`case jsonb_typeof(${curr})
|
|
235
225
|
when 'object' then ${curr}
|
|
236
226
|
else '{}'::jsonb
|
|
@@ -254,17 +244,14 @@ function getJsonUpdate(object, col, path) {
|
|
|
254
244
|
return [clause, maybeNull];
|
|
255
245
|
}
|
|
256
246
|
function stripAttributes(object) {
|
|
257
|
-
if (typeof object !== "object" || !object)
|
|
258
|
-
return object;
|
|
247
|
+
if (typeof object !== "object" || !object) return object;
|
|
259
248
|
if (Array.isArray(object)) {
|
|
260
249
|
return object.map((item) => stripAttributes(item));
|
|
261
250
|
}
|
|
262
251
|
return Object.entries(object).reduce(
|
|
263
252
|
(out, [key, val]) => {
|
|
264
|
-
if (key === "$put" || val === null)
|
|
265
|
-
|
|
266
|
-
if (out === null)
|
|
267
|
-
out = {};
|
|
253
|
+
if (key === "$put" || val === null) return out;
|
|
254
|
+
if (out === null) out = {};
|
|
268
255
|
out[key] = stripAttributes(val);
|
|
269
256
|
return out;
|
|
270
257
|
},
|
|
@@ -304,27 +291,21 @@ function getAst(filter) {
|
|
|
304
291
|
return simplify(construct(filter));
|
|
305
292
|
}
|
|
306
293
|
function isValidSubQuery(node) {
|
|
307
|
-
if (!node || typeof node !== "object")
|
|
308
|
-
return false;
|
|
294
|
+
if (!node || typeof node !== "object") return false;
|
|
309
295
|
const keys = Object.keys(node);
|
|
310
296
|
for (const key of keys) {
|
|
311
|
-
if (key[0] === "$" && !["$and", "$or", "$not"].includes(key))
|
|
312
|
-
|
|
313
|
-
if (key[0] !== "$")
|
|
314
|
-
return true;
|
|
297
|
+
if (key[0] === "$" && !["$and", "$or", "$not"].includes(key)) return false;
|
|
298
|
+
if (key[0] !== "$") return true;
|
|
315
299
|
}
|
|
316
300
|
for (const key in node) {
|
|
317
|
-
if (!isValidSubQuery(node[key]))
|
|
318
|
-
return false;
|
|
301
|
+
if (!isValidSubQuery(node[key])) return false;
|
|
319
302
|
}
|
|
320
303
|
return false;
|
|
321
304
|
}
|
|
322
305
|
function construct(node, prop, op) {
|
|
323
306
|
if (!node || typeof node !== "object" || prop && op) {
|
|
324
|
-
if (op && prop)
|
|
325
|
-
|
|
326
|
-
if (prop)
|
|
327
|
-
return ["$eq", prop, node];
|
|
307
|
+
if (op && prop) return [op, prop, node];
|
|
308
|
+
if (prop) return ["$eq", prop, node];
|
|
328
309
|
throw Error(`pgast.expected_prop_before:${JSON.stringify(node)}`);
|
|
329
310
|
}
|
|
330
311
|
if (Array.isArray(node)) {
|
|
@@ -343,12 +324,9 @@ function construct(node, prop, op) {
|
|
|
343
324
|
return [key, construct(val, prop, op)];
|
|
344
325
|
}
|
|
345
326
|
if (key[0] === "$") {
|
|
346
|
-
if (!valid[key])
|
|
347
|
-
|
|
348
|
-
if (
|
|
349
|
-
throw Error(`pgast.unexpected_op:${op} before:${key}`);
|
|
350
|
-
if (!prop)
|
|
351
|
-
throw Error(`pgast.expected_prop_before:${key}`);
|
|
327
|
+
if (!valid[key]) throw Error(`pgast.invalid_op:${key}`);
|
|
328
|
+
if (op) throw Error(`pgast.unexpected_op:${op} before:${key}`);
|
|
329
|
+
if (!prop) throw Error(`pgast.expected_prop_before:${key}`);
|
|
352
330
|
return construct(val, prop, key);
|
|
353
331
|
}
|
|
354
332
|
return construct(val, key);
|
|
@@ -365,16 +343,12 @@ function simplify(node) {
|
|
|
365
343
|
node[2] = simplify(node[2]);
|
|
366
344
|
}
|
|
367
345
|
if (op === "$and") {
|
|
368
|
-
if (!node[1].length)
|
|
369
|
-
|
|
370
|
-
if (node[1].includes(false))
|
|
371
|
-
return false;
|
|
346
|
+
if (!node[1].length) return true;
|
|
347
|
+
if (node[1].includes(false)) return false;
|
|
372
348
|
node[1] = node[1].filter((item) => item !== true);
|
|
373
349
|
} else if (op === "$or") {
|
|
374
|
-
if (!node[1].length)
|
|
375
|
-
|
|
376
|
-
if (node[1].includes(true))
|
|
377
|
-
return true;
|
|
350
|
+
if (!node[1].length) return false;
|
|
351
|
+
if (node[1].includes(true)) return true;
|
|
378
352
|
node[1] = node[1].filter((item) => item !== false);
|
|
379
353
|
} else if (op === "$not" && typeof node[1] === "boolean") {
|
|
380
354
|
return !node[1];
|
|
@@ -435,16 +409,12 @@ const opSql = {
|
|
|
435
409
|
$keyctd: sql`?&`
|
|
436
410
|
};
|
|
437
411
|
function getBinarySql(lhs, type, op, value, textLhs) {
|
|
438
|
-
if (value === null && op === "$eq")
|
|
439
|
-
|
|
440
|
-
if (value === null && op === "$neq")
|
|
441
|
-
return sql`${lhs} IS NOT NULL`;
|
|
412
|
+
if (value === null && op === "$eq") return sql`${lhs} IS NULL`;
|
|
413
|
+
if (value === null && op === "$neq") return sql`${lhs} IS NOT NULL`;
|
|
442
414
|
const sqlOp = opSql[op];
|
|
443
|
-
if (!sqlOp)
|
|
444
|
-
throw Error(`pg.getSql_unknown_operator ${op}`);
|
|
415
|
+
if (!sqlOp) throw Error(`pg.getSql_unknown_operator ${op}`);
|
|
445
416
|
if (op === "$in" || op === "$nin") {
|
|
446
|
-
if (type === "jsonb" && typeof value[0] === "string")
|
|
447
|
-
lhs = textLhs;
|
|
417
|
+
if (type === "jsonb" && typeof value[0] === "string") lhs = textLhs;
|
|
448
418
|
return sql`${lhs} ${sqlOp} (${join(value)})`;
|
|
449
419
|
}
|
|
450
420
|
if (op === "$re" || op === "$ire") {
|
|
@@ -463,13 +433,11 @@ function getBinarySql(lhs, type, op, value, textLhs) {
|
|
|
463
433
|
return sql`${lhs} ${sqlOp} ${value}::text[]`;
|
|
464
434
|
return sql`${lhs} ${sqlOp} ${JSON.stringify(value)}::jsonb`;
|
|
465
435
|
}
|
|
466
|
-
if (type === "cube")
|
|
467
|
-
return sql`${lhs} ${sqlOp} ${cubeLiteralSql(value)}`;
|
|
436
|
+
if (type === "cube") return sql`${lhs} ${sqlOp} ${cubeLiteralSql(value)}`;
|
|
468
437
|
return sql`${lhs} ${sqlOp} ${value}`;
|
|
469
438
|
}
|
|
470
439
|
function getNodeSql(ast, options) {
|
|
471
|
-
if (typeof ast === "boolean")
|
|
472
|
-
return ast;
|
|
440
|
+
if (typeof ast === "boolean") return ast;
|
|
473
441
|
const op = ast[0];
|
|
474
442
|
if (op === "$and" || op === "$or") {
|
|
475
443
|
return sql`(${join(
|
|
@@ -482,8 +450,7 @@ function getNodeSql(ast, options) {
|
|
|
482
450
|
}
|
|
483
451
|
if (op === "$sub") {
|
|
484
452
|
const joinName = ast[1];
|
|
485
|
-
if (!options.joins[joinName])
|
|
486
|
-
throw Error(`pg.no_join ${joinName}`);
|
|
453
|
+
if (!options.joins[joinName]) throw Error(`pg.no_join ${joinName}`);
|
|
487
454
|
const { idCol, schema } = options;
|
|
488
455
|
const joinOptions = options.joins[joinName];
|
|
489
456
|
const { table: joinTable, refCol } = options.joins[joinName];
|
|
@@ -493,8 +460,7 @@ function getNodeSql(ast, options) {
|
|
|
493
460
|
}
|
|
494
461
|
const [prefix, ...suffix] = ast[1].split(".");
|
|
495
462
|
const { types: types2 = {} } = options.schema;
|
|
496
|
-
if (!types2[prefix])
|
|
497
|
-
throw Error(`pg.no_column ${prefix}`);
|
|
463
|
+
if (!types2[prefix]) throw Error(`pg.no_column ${prefix}`);
|
|
498
464
|
if (types2[prefix] === "jsonb") {
|
|
499
465
|
const [lhs, textLhs] = suffix.length ? [
|
|
500
466
|
sql`"${raw(prefix)}" #> ${suffix}`,
|
|
@@ -502,8 +468,7 @@ function getNodeSql(ast, options) {
|
|
|
502
468
|
] : [sql`"${raw(prefix)}"`, sql`"${raw(prefix)}" #>> '{}'`];
|
|
503
469
|
return getBinarySql(lhs, "jsonb", op, ast[2], textLhs);
|
|
504
470
|
}
|
|
505
|
-
if (suffix.length)
|
|
506
|
-
throw Error(`pg.lookup_not_jsonb ${prefix}`);
|
|
471
|
+
if (suffix.length) throw Error(`pg.lookup_not_jsonb ${prefix}`);
|
|
507
472
|
return getBinarySql(sql`"${raw(prefix)}"`, types2[prefix], op, ast[2]);
|
|
508
473
|
}
|
|
509
474
|
function getSql(filter, options) {
|
|
@@ -533,8 +498,7 @@ function getArgSql({ $first, $last, $after, $before, $since, $until, $all, $curs
|
|
|
533
498
|
}
|
|
534
499
|
const baseKey = sql`${JSON.stringify(rest)}::jsonb`;
|
|
535
500
|
const where = [];
|
|
536
|
-
if (!common.isEmpty(filter))
|
|
537
|
-
where.push(getSql(filter, options));
|
|
501
|
+
if (!common.isEmpty(filter)) where.push(getSql(filter, options));
|
|
538
502
|
if (!hasRangeArg)
|
|
539
503
|
return {
|
|
540
504
|
meta: meta(baseKey),
|
|
@@ -549,8 +513,7 @@ function getArgSql({ $first, $last, $after, $before, $since, $until, $all, $curs
|
|
|
549
513
|
);
|
|
550
514
|
Object.entries({ $after, $before, $since, $until }).forEach(
|
|
551
515
|
([name, value]) => {
|
|
552
|
-
if (value)
|
|
553
|
-
where.push(getBoundCond(orderCols, value, name));
|
|
516
|
+
if (value) where.push(getBoundCond(orderCols, value, name));
|
|
554
517
|
}
|
|
555
518
|
);
|
|
556
519
|
const order = !$group && join(
|
|
@@ -634,8 +597,7 @@ function getSingleSql(arg, options) {
|
|
|
634
597
|
};
|
|
635
598
|
}
|
|
636
599
|
const { where, meta } = getArgSql(arg, options);
|
|
637
|
-
if (!(where == null ? void 0 : where.length))
|
|
638
|
-
throw Error("pg_write.no_condition");
|
|
600
|
+
if (!(where == null ? void 0 : where.length)) throw Error("pg_write.no_condition");
|
|
639
601
|
return {
|
|
640
602
|
where: sql`"${raw(idCol)}" = (
|
|
641
603
|
SELECT "${raw(idCol)}"
|
|
@@ -756,8 +718,7 @@ class Db {
|
|
|
756
718
|
avoid this query in every operation.
|
|
757
719
|
*/
|
|
758
720
|
async ensureSchema(tableOptions, typeOids) {
|
|
759
|
-
if (tableOptions.schema)
|
|
760
|
-
return;
|
|
721
|
+
if (tableOptions.schema) return;
|
|
761
722
|
const { table, verCol, joins } = tableOptions;
|
|
762
723
|
const tableInfoSchema = (await this.query(sql`
|
|
763
724
|
SELECT table_schema, table_type
|
|
@@ -773,8 +734,7 @@ class Db {
|
|
|
773
734
|
WHERE
|
|
774
735
|
table_name = ${table} AND
|
|
775
736
|
table_schema = ${tableSchema}`)).rows[0].column_types;
|
|
776
|
-
if (!types2)
|
|
777
|
-
throw Error(`pg.missing_table ${table}`);
|
|
737
|
+
if (!types2) throw Error(`pg.missing_table ${table}`);
|
|
778
738
|
typeOids = typeOids || (await this.query(sql`
|
|
779
739
|
SELECT jsonb_object_agg(typname, oid) AS type_oids
|
|
780
740
|
FROM pg_type
|
|
@@ -843,8 +803,7 @@ class Db {
|
|
|
843
803
|
idQueries[args] = node.children;
|
|
844
804
|
}
|
|
845
805
|
}
|
|
846
|
-
if (!common.isEmpty(idQueries))
|
|
847
|
-
promises.push(getByIds());
|
|
806
|
+
if (!common.isEmpty(idQueries)) promises.push(getByIds());
|
|
848
807
|
await Promise.all(promises);
|
|
849
808
|
log("dbRead", rootQuery, results);
|
|
850
809
|
return common.finalize(results, common.wrap(query, prefix));
|
|
@@ -881,8 +840,7 @@ class Db {
|
|
|
881
840
|
sqls.push(patch(object, arg, tableOptions));
|
|
882
841
|
}
|
|
883
842
|
}
|
|
884
|
-
if (puts.length)
|
|
885
|
-
sqls.push(...put(puts, tableOptions));
|
|
843
|
+
if (puts.length) sqls.push(...put(puts, tableOptions));
|
|
886
844
|
const result = [];
|
|
887
845
|
await Promise.all(
|
|
888
846
|
sqls.map(
|
package/index.mjs
CHANGED
|
@@ -86,16 +86,13 @@ const getJsonBuildTrusted = (variadic) => {
|
|
|
86
86
|
return sql`jsonb_build_object(${args})`;
|
|
87
87
|
};
|
|
88
88
|
const getJsonBuildValue = (value) => {
|
|
89
|
-
if (value instanceof Sql)
|
|
90
|
-
|
|
91
|
-
if (typeof value === "string")
|
|
92
|
-
return sql`${value}::text`;
|
|
89
|
+
if (value instanceof Sql) return value;
|
|
90
|
+
if (typeof value === "string") return sql`${value}::text`;
|
|
93
91
|
return sql`${JSON.stringify(stripAttributes(value))}::jsonb`;
|
|
94
92
|
};
|
|
95
93
|
const lookup = (prop, options) => {
|
|
96
94
|
const [prefix, ...suffix] = prop.split(".");
|
|
97
|
-
if (!suffix.length)
|
|
98
|
-
return sql`"${raw(prefix)}"`;
|
|
95
|
+
if (!suffix.length) return sql`"${raw(prefix)}"`;
|
|
99
96
|
const { types: types2 } = options.schema;
|
|
100
97
|
if (types2[prefix] === "jsonb") {
|
|
101
98
|
return sql`"${raw(prefix)}" #> ${suffix}`;
|
|
@@ -118,8 +115,7 @@ const aggSql = {
|
|
|
118
115
|
$min: (prop) => sql`min((${lookupNumeric(prop)})::numeric)`
|
|
119
116
|
};
|
|
120
117
|
const getSelectCols = (options, projection = null) => {
|
|
121
|
-
if (!projection)
|
|
122
|
-
return sql`*`;
|
|
118
|
+
if (!projection) return sql`*`;
|
|
123
119
|
const sqls = [];
|
|
124
120
|
for (const key in projection) {
|
|
125
121
|
if (key === "$count") {
|
|
@@ -153,17 +149,13 @@ function cubeLiteralSql(value) {
|
|
|
153
149
|
)})` : sql`cube(${vertexSql(value, 0)})`;
|
|
154
150
|
}
|
|
155
151
|
function castValue(value, type, name, isPut) {
|
|
156
|
-
if (!type)
|
|
157
|
-
|
|
158
|
-
if (value
|
|
159
|
-
return value;
|
|
160
|
-
if (value === null)
|
|
161
|
-
return sql`NULL`;
|
|
152
|
+
if (!type) throw Error(`pg.write_no_column ${name}`);
|
|
153
|
+
if (value instanceof Sql) return value;
|
|
154
|
+
if (value === null) return sql`NULL`;
|
|
162
155
|
if (type === "jsonb") {
|
|
163
156
|
return isPut ? JSON.stringify(stripAttributes(value)) : getJsonUpdate(value, name, [])[0];
|
|
164
157
|
}
|
|
165
|
-
if (type === "cube")
|
|
166
|
-
return cubeLiteralSql(value);
|
|
158
|
+
if (type === "cube") return cubeLiteralSql(value);
|
|
167
159
|
return value;
|
|
168
160
|
}
|
|
169
161
|
const getInsert = (rows, options) => {
|
|
@@ -183,8 +175,7 @@ const getInsert = (rows, options) => {
|
|
|
183
175
|
for (const row of rows) {
|
|
184
176
|
const rowVals = Array(cols.length).fill(sql`default`);
|
|
185
177
|
for (const col of cols) {
|
|
186
|
-
if (col === verCol || !(col in row))
|
|
187
|
-
continue;
|
|
178
|
+
if (col === verCol || !(col in row)) continue;
|
|
188
179
|
const ix = colIx[col];
|
|
189
180
|
colUsed[ix] = true;
|
|
190
181
|
rowVals[ix] = castValue(row[col], schema.types[col], col, row.$put);
|
|
@@ -227,8 +218,7 @@ function getJsonUpdate(object, col, path) {
|
|
|
227
218
|
return [sql`${JSON.stringify({ $val: value })}::jsonb`, false];
|
|
228
219
|
}
|
|
229
220
|
const curr = sql`"${raw(col)}"${path.length ? sql`#>${path}` : empty}`;
|
|
230
|
-
if (isEmpty(object))
|
|
231
|
-
return [curr, false];
|
|
221
|
+
if (isEmpty(object)) return [curr, false];
|
|
232
222
|
const baseSql = sql`case jsonb_typeof(${curr})
|
|
233
223
|
when 'object' then ${curr}
|
|
234
224
|
else '{}'::jsonb
|
|
@@ -252,17 +242,14 @@ function getJsonUpdate(object, col, path) {
|
|
|
252
242
|
return [clause, maybeNull];
|
|
253
243
|
}
|
|
254
244
|
function stripAttributes(object) {
|
|
255
|
-
if (typeof object !== "object" || !object)
|
|
256
|
-
return object;
|
|
245
|
+
if (typeof object !== "object" || !object) return object;
|
|
257
246
|
if (Array.isArray(object)) {
|
|
258
247
|
return object.map((item) => stripAttributes(item));
|
|
259
248
|
}
|
|
260
249
|
return Object.entries(object).reduce(
|
|
261
250
|
(out, [key, val]) => {
|
|
262
|
-
if (key === "$put" || val === null)
|
|
263
|
-
|
|
264
|
-
if (out === null)
|
|
265
|
-
out = {};
|
|
251
|
+
if (key === "$put" || val === null) return out;
|
|
252
|
+
if (out === null) out = {};
|
|
266
253
|
out[key] = stripAttributes(val);
|
|
267
254
|
return out;
|
|
268
255
|
},
|
|
@@ -302,27 +289,21 @@ function getAst(filter) {
|
|
|
302
289
|
return simplify(construct(filter));
|
|
303
290
|
}
|
|
304
291
|
function isValidSubQuery(node) {
|
|
305
|
-
if (!node || typeof node !== "object")
|
|
306
|
-
return false;
|
|
292
|
+
if (!node || typeof node !== "object") return false;
|
|
307
293
|
const keys = Object.keys(node);
|
|
308
294
|
for (const key of keys) {
|
|
309
|
-
if (key[0] === "$" && !["$and", "$or", "$not"].includes(key))
|
|
310
|
-
|
|
311
|
-
if (key[0] !== "$")
|
|
312
|
-
return true;
|
|
295
|
+
if (key[0] === "$" && !["$and", "$or", "$not"].includes(key)) return false;
|
|
296
|
+
if (key[0] !== "$") return true;
|
|
313
297
|
}
|
|
314
298
|
for (const key in node) {
|
|
315
|
-
if (!isValidSubQuery(node[key]))
|
|
316
|
-
return false;
|
|
299
|
+
if (!isValidSubQuery(node[key])) return false;
|
|
317
300
|
}
|
|
318
301
|
return false;
|
|
319
302
|
}
|
|
320
303
|
function construct(node, prop, op) {
|
|
321
304
|
if (!node || typeof node !== "object" || prop && op) {
|
|
322
|
-
if (op && prop)
|
|
323
|
-
|
|
324
|
-
if (prop)
|
|
325
|
-
return ["$eq", prop, node];
|
|
305
|
+
if (op && prop) return [op, prop, node];
|
|
306
|
+
if (prop) return ["$eq", prop, node];
|
|
326
307
|
throw Error(`pgast.expected_prop_before:${JSON.stringify(node)}`);
|
|
327
308
|
}
|
|
328
309
|
if (Array.isArray(node)) {
|
|
@@ -341,12 +322,9 @@ function construct(node, prop, op) {
|
|
|
341
322
|
return [key, construct(val, prop, op)];
|
|
342
323
|
}
|
|
343
324
|
if (key[0] === "$") {
|
|
344
|
-
if (!valid[key])
|
|
345
|
-
|
|
346
|
-
if (
|
|
347
|
-
throw Error(`pgast.unexpected_op:${op} before:${key}`);
|
|
348
|
-
if (!prop)
|
|
349
|
-
throw Error(`pgast.expected_prop_before:${key}`);
|
|
325
|
+
if (!valid[key]) throw Error(`pgast.invalid_op:${key}`);
|
|
326
|
+
if (op) throw Error(`pgast.unexpected_op:${op} before:${key}`);
|
|
327
|
+
if (!prop) throw Error(`pgast.expected_prop_before:${key}`);
|
|
350
328
|
return construct(val, prop, key);
|
|
351
329
|
}
|
|
352
330
|
return construct(val, key);
|
|
@@ -363,16 +341,12 @@ function simplify(node) {
|
|
|
363
341
|
node[2] = simplify(node[2]);
|
|
364
342
|
}
|
|
365
343
|
if (op === "$and") {
|
|
366
|
-
if (!node[1].length)
|
|
367
|
-
|
|
368
|
-
if (node[1].includes(false))
|
|
369
|
-
return false;
|
|
344
|
+
if (!node[1].length) return true;
|
|
345
|
+
if (node[1].includes(false)) return false;
|
|
370
346
|
node[1] = node[1].filter((item) => item !== true);
|
|
371
347
|
} else if (op === "$or") {
|
|
372
|
-
if (!node[1].length)
|
|
373
|
-
|
|
374
|
-
if (node[1].includes(true))
|
|
375
|
-
return true;
|
|
348
|
+
if (!node[1].length) return false;
|
|
349
|
+
if (node[1].includes(true)) return true;
|
|
376
350
|
node[1] = node[1].filter((item) => item !== false);
|
|
377
351
|
} else if (op === "$not" && typeof node[1] === "boolean") {
|
|
378
352
|
return !node[1];
|
|
@@ -433,16 +407,12 @@ const opSql = {
|
|
|
433
407
|
$keyctd: sql`?&`
|
|
434
408
|
};
|
|
435
409
|
function getBinarySql(lhs, type, op, value, textLhs) {
|
|
436
|
-
if (value === null && op === "$eq")
|
|
437
|
-
|
|
438
|
-
if (value === null && op === "$neq")
|
|
439
|
-
return sql`${lhs} IS NOT NULL`;
|
|
410
|
+
if (value === null && op === "$eq") return sql`${lhs} IS NULL`;
|
|
411
|
+
if (value === null && op === "$neq") return sql`${lhs} IS NOT NULL`;
|
|
440
412
|
const sqlOp = opSql[op];
|
|
441
|
-
if (!sqlOp)
|
|
442
|
-
throw Error(`pg.getSql_unknown_operator ${op}`);
|
|
413
|
+
if (!sqlOp) throw Error(`pg.getSql_unknown_operator ${op}`);
|
|
443
414
|
if (op === "$in" || op === "$nin") {
|
|
444
|
-
if (type === "jsonb" && typeof value[0] === "string")
|
|
445
|
-
lhs = textLhs;
|
|
415
|
+
if (type === "jsonb" && typeof value[0] === "string") lhs = textLhs;
|
|
446
416
|
return sql`${lhs} ${sqlOp} (${join(value)})`;
|
|
447
417
|
}
|
|
448
418
|
if (op === "$re" || op === "$ire") {
|
|
@@ -461,13 +431,11 @@ function getBinarySql(lhs, type, op, value, textLhs) {
|
|
|
461
431
|
return sql`${lhs} ${sqlOp} ${value}::text[]`;
|
|
462
432
|
return sql`${lhs} ${sqlOp} ${JSON.stringify(value)}::jsonb`;
|
|
463
433
|
}
|
|
464
|
-
if (type === "cube")
|
|
465
|
-
return sql`${lhs} ${sqlOp} ${cubeLiteralSql(value)}`;
|
|
434
|
+
if (type === "cube") return sql`${lhs} ${sqlOp} ${cubeLiteralSql(value)}`;
|
|
466
435
|
return sql`${lhs} ${sqlOp} ${value}`;
|
|
467
436
|
}
|
|
468
437
|
function getNodeSql(ast, options) {
|
|
469
|
-
if (typeof ast === "boolean")
|
|
470
|
-
return ast;
|
|
438
|
+
if (typeof ast === "boolean") return ast;
|
|
471
439
|
const op = ast[0];
|
|
472
440
|
if (op === "$and" || op === "$or") {
|
|
473
441
|
return sql`(${join(
|
|
@@ -480,8 +448,7 @@ function getNodeSql(ast, options) {
|
|
|
480
448
|
}
|
|
481
449
|
if (op === "$sub") {
|
|
482
450
|
const joinName = ast[1];
|
|
483
|
-
if (!options.joins[joinName])
|
|
484
|
-
throw Error(`pg.no_join ${joinName}`);
|
|
451
|
+
if (!options.joins[joinName]) throw Error(`pg.no_join ${joinName}`);
|
|
485
452
|
const { idCol, schema } = options;
|
|
486
453
|
const joinOptions = options.joins[joinName];
|
|
487
454
|
const { table: joinTable, refCol } = options.joins[joinName];
|
|
@@ -491,8 +458,7 @@ function getNodeSql(ast, options) {
|
|
|
491
458
|
}
|
|
492
459
|
const [prefix, ...suffix] = ast[1].split(".");
|
|
493
460
|
const { types: types2 = {} } = options.schema;
|
|
494
|
-
if (!types2[prefix])
|
|
495
|
-
throw Error(`pg.no_column ${prefix}`);
|
|
461
|
+
if (!types2[prefix]) throw Error(`pg.no_column ${prefix}`);
|
|
496
462
|
if (types2[prefix] === "jsonb") {
|
|
497
463
|
const [lhs, textLhs] = suffix.length ? [
|
|
498
464
|
sql`"${raw(prefix)}" #> ${suffix}`,
|
|
@@ -500,8 +466,7 @@ function getNodeSql(ast, options) {
|
|
|
500
466
|
] : [sql`"${raw(prefix)}"`, sql`"${raw(prefix)}" #>> '{}'`];
|
|
501
467
|
return getBinarySql(lhs, "jsonb", op, ast[2], textLhs);
|
|
502
468
|
}
|
|
503
|
-
if (suffix.length)
|
|
504
|
-
throw Error(`pg.lookup_not_jsonb ${prefix}`);
|
|
469
|
+
if (suffix.length) throw Error(`pg.lookup_not_jsonb ${prefix}`);
|
|
505
470
|
return getBinarySql(sql`"${raw(prefix)}"`, types2[prefix], op, ast[2]);
|
|
506
471
|
}
|
|
507
472
|
function getSql(filter, options) {
|
|
@@ -531,8 +496,7 @@ function getArgSql({ $first, $last, $after, $before, $since, $until, $all, $curs
|
|
|
531
496
|
}
|
|
532
497
|
const baseKey = sql`${JSON.stringify(rest)}::jsonb`;
|
|
533
498
|
const where = [];
|
|
534
|
-
if (!isEmpty(filter))
|
|
535
|
-
where.push(getSql(filter, options));
|
|
499
|
+
if (!isEmpty(filter)) where.push(getSql(filter, options));
|
|
536
500
|
if (!hasRangeArg)
|
|
537
501
|
return {
|
|
538
502
|
meta: meta(baseKey),
|
|
@@ -547,8 +511,7 @@ function getArgSql({ $first, $last, $after, $before, $since, $until, $all, $curs
|
|
|
547
511
|
);
|
|
548
512
|
Object.entries({ $after, $before, $since, $until }).forEach(
|
|
549
513
|
([name, value]) => {
|
|
550
|
-
if (value)
|
|
551
|
-
where.push(getBoundCond(orderCols, value, name));
|
|
514
|
+
if (value) where.push(getBoundCond(orderCols, value, name));
|
|
552
515
|
}
|
|
553
516
|
);
|
|
554
517
|
const order = !$group && join(
|
|
@@ -632,8 +595,7 @@ function getSingleSql(arg, options) {
|
|
|
632
595
|
};
|
|
633
596
|
}
|
|
634
597
|
const { where, meta } = getArgSql(arg, options);
|
|
635
|
-
if (!(where == null ? void 0 : where.length))
|
|
636
|
-
throw Error("pg_write.no_condition");
|
|
598
|
+
if (!(where == null ? void 0 : where.length)) throw Error("pg_write.no_condition");
|
|
637
599
|
return {
|
|
638
600
|
where: sql`"${raw(idCol)}" = (
|
|
639
601
|
SELECT "${raw(idCol)}"
|
|
@@ -754,8 +716,7 @@ class Db {
|
|
|
754
716
|
avoid this query in every operation.
|
|
755
717
|
*/
|
|
756
718
|
async ensureSchema(tableOptions, typeOids) {
|
|
757
|
-
if (tableOptions.schema)
|
|
758
|
-
return;
|
|
719
|
+
if (tableOptions.schema) return;
|
|
759
720
|
const { table, verCol, joins } = tableOptions;
|
|
760
721
|
const tableInfoSchema = (await this.query(sql`
|
|
761
722
|
SELECT table_schema, table_type
|
|
@@ -771,8 +732,7 @@ class Db {
|
|
|
771
732
|
WHERE
|
|
772
733
|
table_name = ${table} AND
|
|
773
734
|
table_schema = ${tableSchema}`)).rows[0].column_types;
|
|
774
|
-
if (!types2)
|
|
775
|
-
throw Error(`pg.missing_table ${table}`);
|
|
735
|
+
if (!types2) throw Error(`pg.missing_table ${table}`);
|
|
776
736
|
typeOids = typeOids || (await this.query(sql`
|
|
777
737
|
SELECT jsonb_object_agg(typname, oid) AS type_oids
|
|
778
738
|
FROM pg_type
|
|
@@ -841,8 +801,7 @@ class Db {
|
|
|
841
801
|
idQueries[args] = node.children;
|
|
842
802
|
}
|
|
843
803
|
}
|
|
844
|
-
if (!isEmpty(idQueries))
|
|
845
|
-
promises.push(getByIds());
|
|
804
|
+
if (!isEmpty(idQueries)) promises.push(getByIds());
|
|
846
805
|
await Promise.all(promises);
|
|
847
806
|
log("dbRead", rootQuery, results);
|
|
848
807
|
return finalize(results, wrap(query, prefix));
|
|
@@ -879,8 +838,7 @@ class Db {
|
|
|
879
838
|
sqls.push(patch(object, arg, tableOptions));
|
|
880
839
|
}
|
|
881
840
|
}
|
|
882
|
-
if (puts.length)
|
|
883
|
-
sqls.push(...put(puts, tableOptions));
|
|
841
|
+
if (puts.length) sqls.push(...put(puts, tableOptions));
|
|
884
842
|
const result = [];
|
|
885
843
|
await Promise.all(
|
|
886
844
|
sqls.map(
|
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.16.
|
|
5
|
+
"version": "0.16.20-alpha.1",
|
|
6
6
|
"main": "./index.cjs",
|
|
7
7
|
"exports": {
|
|
8
8
|
"import": "./index.mjs",
|
|
@@ -16,8 +16,8 @@
|
|
|
16
16
|
},
|
|
17
17
|
"license": "Apache-2.0",
|
|
18
18
|
"dependencies": {
|
|
19
|
-
"@graffy/common": "0.16.
|
|
20
|
-
"debug": "^4.3.
|
|
19
|
+
"@graffy/common": "0.16.20-alpha.1",
|
|
20
|
+
"debug": "^4.3.7"
|
|
21
21
|
},
|
|
22
22
|
"peerDependencies": {
|
|
23
23
|
"pg": "^8.0.0"
|
package/types/sql/getArgSql.d.ts
CHANGED