@graffy/pg 0.16.20 → 0.16.21-alpha.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/index.cjs +57 -24
- package/index.mjs +59 -26
- package/package.json +4 -3
- package/types/sql/format.d.ts +5 -0
package/index.cjs
CHANGED
|
@@ -3,6 +3,7 @@ Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
|
3
3
|
const common = require("@graffy/common");
|
|
4
4
|
const debug = require("debug");
|
|
5
5
|
const pg$1 = require("pg");
|
|
6
|
+
const sqlFormatter = require("sql-formatter");
|
|
6
7
|
class Sql {
|
|
7
8
|
constructor(rawStrings, rawValues) {
|
|
8
9
|
if (rawStrings.length - 1 !== rawValues.length) {
|
|
@@ -79,6 +80,20 @@ const empty = raw("");
|
|
|
79
80
|
function sql(strings, ...values) {
|
|
80
81
|
return new Sql(strings, values);
|
|
81
82
|
}
|
|
83
|
+
function formatSql(sql2) {
|
|
84
|
+
const strings = sql2.strings.slice(0);
|
|
85
|
+
const values = sql2.values.slice(0);
|
|
86
|
+
const output = [];
|
|
87
|
+
while (strings.length) {
|
|
88
|
+
output.push(strings.shift().replace(/\s+/g, " "));
|
|
89
|
+
if (!values.length) break;
|
|
90
|
+
const value = values.shift();
|
|
91
|
+
output.push(
|
|
92
|
+
typeof value === "number" ? value.toString() : typeof value === "object" ? `'${JSON.stringify(value)}'` : `'${value}'`
|
|
93
|
+
);
|
|
94
|
+
}
|
|
95
|
+
return sqlFormatter.format(output.join("").trim(), { language: "postgresql" });
|
|
96
|
+
}
|
|
82
97
|
const getJsonBuildTrusted = (variadic) => {
|
|
83
98
|
const args = join(
|
|
84
99
|
Object.entries(variadic).map(([name, value]) => {
|
|
@@ -157,23 +172,23 @@ const getSelectCols = (options, projection = null) => {
|
|
|
157
172
|
sqls.push(
|
|
158
173
|
sql`jsonb_build_object(${join(subSqls, ", ")}) AS "${raw(key)}"`
|
|
159
174
|
);
|
|
175
|
+
}
|
|
176
|
+
if (key[0] === "$") continue;
|
|
177
|
+
if (typeof projection[key] === "object") {
|
|
178
|
+
const optimisedJsonBuild = getOptimisedJsonBuild(
|
|
179
|
+
projection[key],
|
|
180
|
+
[],
|
|
181
|
+
key,
|
|
182
|
+
options
|
|
183
|
+
);
|
|
184
|
+
sqls.push(
|
|
185
|
+
sql`jsonb_build_object(${join(optimisedJsonBuild, ", ")}) AS "${raw(key)}"`
|
|
186
|
+
);
|
|
160
187
|
} else {
|
|
161
|
-
|
|
162
|
-
const optimisedJsonBuild = getOptimisedJsonBuild(
|
|
163
|
-
projection[key],
|
|
164
|
-
[],
|
|
165
|
-
key,
|
|
166
|
-
options
|
|
167
|
-
);
|
|
168
|
-
sqls.push(
|
|
169
|
-
sql`jsonb_build_object(${join(optimisedJsonBuild, ", ")}) AS "${raw(key)}"`
|
|
170
|
-
);
|
|
171
|
-
} else {
|
|
172
|
-
sqls.push(sql`"${raw(key)}"`);
|
|
173
|
-
}
|
|
188
|
+
sqls.push(sql`"${raw(key)}"`);
|
|
174
189
|
}
|
|
175
190
|
}
|
|
176
|
-
return join(sqls, ", ")
|
|
191
|
+
return sqls.length ? join(sqls, ", ") : sql`TRUE AS "$"`;
|
|
177
192
|
};
|
|
178
193
|
function vertexSql(array, nullValue) {
|
|
179
194
|
return sql`array[${join(
|
|
@@ -754,7 +769,7 @@ class Db {
|
|
|
754
769
|
/*
|
|
755
770
|
Adds .schema to tableOptions if it doesn't exist yet.
|
|
756
771
|
It mutates the argument, to "persist" the results and
|
|
757
|
-
avoid this query in every operation.
|
|
772
|
+
avoid this query in every operation.
|
|
758
773
|
*/
|
|
759
774
|
async ensureSchema(tableOptions, typeOids) {
|
|
760
775
|
if (tableOptions.schema) return;
|
|
@@ -805,19 +820,33 @@ class Db {
|
|
|
805
820
|
const prefix = common.encodePath(rawPrefix);
|
|
806
821
|
await this.ensureSchema(tableOptions);
|
|
807
822
|
const getByArgs = async (args, projection) => {
|
|
808
|
-
const
|
|
809
|
-
|
|
810
|
-
tableOptions
|
|
811
|
-
);
|
|
823
|
+
const sql2 = selectByArgs(args, projection, tableOptions);
|
|
824
|
+
const result = await this.readSql(sql2, tableOptions);
|
|
812
825
|
const wrappedGraph = common.encodeGraph(common.wrapObject(result, rawPrefix));
|
|
813
826
|
log("getByArgs", wrappedGraph);
|
|
814
827
|
common.merge(results, wrappedGraph);
|
|
815
828
|
};
|
|
816
|
-
const
|
|
817
|
-
const
|
|
818
|
-
|
|
819
|
-
|
|
829
|
+
const explainArgs = async (args, projection) => {
|
|
830
|
+
const { analyze, $explain: qArgs } = args;
|
|
831
|
+
const qSql = selectByArgs(qArgs, null, tableOptions);
|
|
832
|
+
const sql$1 = sql`EXPLAIN (${analyze ? sql`ANALYZE, BUFFERS, TIMING, ` : sql``}COSTS, VERBOSE, FORMAT JSON) ${qSql}`;
|
|
833
|
+
const result = await this.readSql(sql$1, tableOptions);
|
|
834
|
+
const wrappedGraph = common.encodeGraph(
|
|
835
|
+
common.wrapObject(
|
|
836
|
+
{
|
|
837
|
+
$key: args,
|
|
838
|
+
sql: formatSql(qSql),
|
|
839
|
+
plan: result[0]["QUERY PLAN"][0]
|
|
840
|
+
},
|
|
841
|
+
rawPrefix
|
|
842
|
+
)
|
|
820
843
|
);
|
|
844
|
+
log("explainArgs", wrappedGraph);
|
|
845
|
+
common.merge(results, wrappedGraph);
|
|
846
|
+
};
|
|
847
|
+
const getByIds = async () => {
|
|
848
|
+
const sql2 = selectByIds(Object.keys(idQueries), null, tableOptions);
|
|
849
|
+
const result = await this.readSql(sql2, tableOptions);
|
|
821
850
|
for (const object of result) {
|
|
822
851
|
const wrappedGraph = common.encodeGraph(common.wrapObject(object, rawPrefix));
|
|
823
852
|
log("getByIds", wrappedGraph);
|
|
@@ -836,7 +865,11 @@ class Db {
|
|
|
836
865
|
}
|
|
837
866
|
} else {
|
|
838
867
|
const projection = node.children ? common.decodeQuery(node.children) : null;
|
|
839
|
-
|
|
868
|
+
if (args.$explain) {
|
|
869
|
+
promises.push(explainArgs(args));
|
|
870
|
+
} else {
|
|
871
|
+
promises.push(getByArgs(args, projection));
|
|
872
|
+
}
|
|
840
873
|
}
|
|
841
874
|
} else {
|
|
842
875
|
idQueries[args] = node.children;
|
package/index.mjs
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { isEmpty, isPlainObject, encodePath, unwrap, decodeArgs, decodeQuery, finalize, wrap, isRange, cmp, decodeGraph, mergeObject, wrapObject, merge, encodeGraph, remove } from "@graffy/common";
|
|
2
2
|
import debug from "debug";
|
|
3
3
|
import pg$1 from "pg";
|
|
4
|
+
import { format } from "sql-formatter";
|
|
4
5
|
class Sql {
|
|
5
6
|
constructor(rawStrings, rawValues) {
|
|
6
7
|
if (rawStrings.length - 1 !== rawValues.length) {
|
|
@@ -77,6 +78,20 @@ const empty = raw("");
|
|
|
77
78
|
function sql(strings, ...values) {
|
|
78
79
|
return new Sql(strings, values);
|
|
79
80
|
}
|
|
81
|
+
function formatSql(sql2) {
|
|
82
|
+
const strings = sql2.strings.slice(0);
|
|
83
|
+
const values = sql2.values.slice(0);
|
|
84
|
+
const output = [];
|
|
85
|
+
while (strings.length) {
|
|
86
|
+
output.push(strings.shift().replace(/\s+/g, " "));
|
|
87
|
+
if (!values.length) break;
|
|
88
|
+
const value = values.shift();
|
|
89
|
+
output.push(
|
|
90
|
+
typeof value === "number" ? value.toString() : typeof value === "object" ? `'${JSON.stringify(value)}'` : `'${value}'`
|
|
91
|
+
);
|
|
92
|
+
}
|
|
93
|
+
return format(output.join("").trim(), { language: "postgresql" });
|
|
94
|
+
}
|
|
80
95
|
const getJsonBuildTrusted = (variadic) => {
|
|
81
96
|
const args = join(
|
|
82
97
|
Object.entries(variadic).map(([name, value]) => {
|
|
@@ -155,23 +170,23 @@ const getSelectCols = (options, projection = null) => {
|
|
|
155
170
|
sqls.push(
|
|
156
171
|
sql`jsonb_build_object(${join(subSqls, ", ")}) AS "${raw(key)}"`
|
|
157
172
|
);
|
|
173
|
+
}
|
|
174
|
+
if (key[0] === "$") continue;
|
|
175
|
+
if (typeof projection[key] === "object") {
|
|
176
|
+
const optimisedJsonBuild = getOptimisedJsonBuild(
|
|
177
|
+
projection[key],
|
|
178
|
+
[],
|
|
179
|
+
key,
|
|
180
|
+
options
|
|
181
|
+
);
|
|
182
|
+
sqls.push(
|
|
183
|
+
sql`jsonb_build_object(${join(optimisedJsonBuild, ", ")}) AS "${raw(key)}"`
|
|
184
|
+
);
|
|
158
185
|
} else {
|
|
159
|
-
|
|
160
|
-
const optimisedJsonBuild = getOptimisedJsonBuild(
|
|
161
|
-
projection[key],
|
|
162
|
-
[],
|
|
163
|
-
key,
|
|
164
|
-
options
|
|
165
|
-
);
|
|
166
|
-
sqls.push(
|
|
167
|
-
sql`jsonb_build_object(${join(optimisedJsonBuild, ", ")}) AS "${raw(key)}"`
|
|
168
|
-
);
|
|
169
|
-
} else {
|
|
170
|
-
sqls.push(sql`"${raw(key)}"`);
|
|
171
|
-
}
|
|
186
|
+
sqls.push(sql`"${raw(key)}"`);
|
|
172
187
|
}
|
|
173
188
|
}
|
|
174
|
-
return join(sqls, ", ")
|
|
189
|
+
return sqls.length ? join(sqls, ", ") : sql`TRUE AS "$"`;
|
|
175
190
|
};
|
|
176
191
|
function vertexSql(array, nullValue) {
|
|
177
192
|
return sql`array[${join(
|
|
@@ -708,7 +723,7 @@ class Db {
|
|
|
708
723
|
const cubeOid = Number.parseInt(((_b = (_a = tableOptions == null ? void 0 : tableOptions.schema) == null ? void 0 : _a.typeOids) == null ? void 0 : _b.cube) || "0") || null;
|
|
709
724
|
try {
|
|
710
725
|
sql2.types = {
|
|
711
|
-
getTypeParser: (oid,
|
|
726
|
+
getTypeParser: (oid, format2) => {
|
|
712
727
|
if (oid === types.builtins.INT8) {
|
|
713
728
|
return (value) => Number.parseInt(value, 10);
|
|
714
729
|
}
|
|
@@ -720,7 +735,7 @@ class Db {
|
|
|
720
735
|
return array.length > 1 ? array : array[0];
|
|
721
736
|
};
|
|
722
737
|
}
|
|
723
|
-
return types.getTypeParser(oid,
|
|
738
|
+
return types.getTypeParser(oid, format2);
|
|
724
739
|
}
|
|
725
740
|
};
|
|
726
741
|
return await this.client.query(sql2);
|
|
@@ -752,7 +767,7 @@ class Db {
|
|
|
752
767
|
/*
|
|
753
768
|
Adds .schema to tableOptions if it doesn't exist yet.
|
|
754
769
|
It mutates the argument, to "persist" the results and
|
|
755
|
-
avoid this query in every operation.
|
|
770
|
+
avoid this query in every operation.
|
|
756
771
|
*/
|
|
757
772
|
async ensureSchema(tableOptions, typeOids) {
|
|
758
773
|
if (tableOptions.schema) return;
|
|
@@ -803,19 +818,33 @@ class Db {
|
|
|
803
818
|
const prefix = encodePath(rawPrefix);
|
|
804
819
|
await this.ensureSchema(tableOptions);
|
|
805
820
|
const getByArgs = async (args, projection) => {
|
|
806
|
-
const
|
|
807
|
-
|
|
808
|
-
tableOptions
|
|
809
|
-
);
|
|
821
|
+
const sql2 = selectByArgs(args, projection, tableOptions);
|
|
822
|
+
const result = await this.readSql(sql2, tableOptions);
|
|
810
823
|
const wrappedGraph = encodeGraph(wrapObject(result, rawPrefix));
|
|
811
824
|
log("getByArgs", wrappedGraph);
|
|
812
825
|
merge(results, wrappedGraph);
|
|
813
826
|
};
|
|
814
|
-
const
|
|
815
|
-
const
|
|
816
|
-
|
|
817
|
-
|
|
827
|
+
const explainArgs = async (args, projection) => {
|
|
828
|
+
const { analyze, $explain: qArgs } = args;
|
|
829
|
+
const qSql = selectByArgs(qArgs, null, tableOptions);
|
|
830
|
+
const sql$1 = sql`EXPLAIN (${analyze ? sql`ANALYZE, BUFFERS, TIMING, ` : sql``}COSTS, VERBOSE, FORMAT JSON) ${qSql}`;
|
|
831
|
+
const result = await this.readSql(sql$1, tableOptions);
|
|
832
|
+
const wrappedGraph = encodeGraph(
|
|
833
|
+
wrapObject(
|
|
834
|
+
{
|
|
835
|
+
$key: args,
|
|
836
|
+
sql: formatSql(qSql),
|
|
837
|
+
plan: result[0]["QUERY PLAN"][0]
|
|
838
|
+
},
|
|
839
|
+
rawPrefix
|
|
840
|
+
)
|
|
818
841
|
);
|
|
842
|
+
log("explainArgs", wrappedGraph);
|
|
843
|
+
merge(results, wrappedGraph);
|
|
844
|
+
};
|
|
845
|
+
const getByIds = async () => {
|
|
846
|
+
const sql2 = selectByIds(Object.keys(idQueries), null, tableOptions);
|
|
847
|
+
const result = await this.readSql(sql2, tableOptions);
|
|
819
848
|
for (const object of result) {
|
|
820
849
|
const wrappedGraph = encodeGraph(wrapObject(object, rawPrefix));
|
|
821
850
|
log("getByIds", wrappedGraph);
|
|
@@ -834,7 +863,11 @@ class Db {
|
|
|
834
863
|
}
|
|
835
864
|
} else {
|
|
836
865
|
const projection = node.children ? decodeQuery(node.children) : null;
|
|
837
|
-
|
|
866
|
+
if (args.$explain) {
|
|
867
|
+
promises.push(explainArgs(args));
|
|
868
|
+
} else {
|
|
869
|
+
promises.push(getByArgs(args, projection));
|
|
870
|
+
}
|
|
838
871
|
}
|
|
839
872
|
} else {
|
|
840
873
|
idQueries[args] = node.children;
|
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.21-alpha.2",
|
|
6
6
|
"main": "./index.cjs",
|
|
7
7
|
"exports": {
|
|
8
8
|
"import": "./index.mjs",
|
|
@@ -16,8 +16,9 @@
|
|
|
16
16
|
},
|
|
17
17
|
"license": "Apache-2.0",
|
|
18
18
|
"dependencies": {
|
|
19
|
-
"@graffy/common": "0.16.
|
|
20
|
-
"debug": "^4.3.3"
|
|
19
|
+
"@graffy/common": "0.16.21-alpha.2",
|
|
20
|
+
"debug": "^4.3.3",
|
|
21
|
+
"sql-formatter": "^15.6.2"
|
|
21
22
|
},
|
|
22
23
|
"peerDependencies": {
|
|
23
24
|
"pg": "^8.0.0"
|