@graffy/pg 0.16.20 → 0.16.21-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 +56 -24
- package/index.mjs +56 -24
- package/package.json +2 -2
- package/types/sql/format.d.ts +1 -0
package/index.cjs
CHANGED
|
@@ -79,6 +79,20 @@ const empty = raw("");
|
|
|
79
79
|
function sql(strings, ...values) {
|
|
80
80
|
return new Sql(strings, values);
|
|
81
81
|
}
|
|
82
|
+
function formatSql(sql2) {
|
|
83
|
+
const strings = sql2.strings.slice(0);
|
|
84
|
+
const values = sql2.values.slice(0);
|
|
85
|
+
const output = [];
|
|
86
|
+
while (strings.length) {
|
|
87
|
+
output.push(strings.shift().replace(/\s+/g, " "));
|
|
88
|
+
if (!values.length) break;
|
|
89
|
+
const value = values.shift();
|
|
90
|
+
output.push(
|
|
91
|
+
typeof value === "number" ? value.toString() : typeof value === "object" ? `'${JSON.stringify(value)}'` : `'${value}'`
|
|
92
|
+
);
|
|
93
|
+
}
|
|
94
|
+
return output.join("").trim();
|
|
95
|
+
}
|
|
82
96
|
const getJsonBuildTrusted = (variadic) => {
|
|
83
97
|
const args = join(
|
|
84
98
|
Object.entries(variadic).map(([name, value]) => {
|
|
@@ -157,23 +171,23 @@ const getSelectCols = (options, projection = null) => {
|
|
|
157
171
|
sqls.push(
|
|
158
172
|
sql`jsonb_build_object(${join(subSqls, ", ")}) AS "${raw(key)}"`
|
|
159
173
|
);
|
|
174
|
+
}
|
|
175
|
+
if (key[0] === "$") continue;
|
|
176
|
+
if (typeof projection[key] === "object") {
|
|
177
|
+
const optimisedJsonBuild = getOptimisedJsonBuild(
|
|
178
|
+
projection[key],
|
|
179
|
+
[],
|
|
180
|
+
key,
|
|
181
|
+
options
|
|
182
|
+
);
|
|
183
|
+
sqls.push(
|
|
184
|
+
sql`jsonb_build_object(${join(optimisedJsonBuild, ", ")}) AS "${raw(key)}"`
|
|
185
|
+
);
|
|
160
186
|
} 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
|
-
}
|
|
187
|
+
sqls.push(sql`"${raw(key)}"`);
|
|
174
188
|
}
|
|
175
189
|
}
|
|
176
|
-
return join(sqls, ", ")
|
|
190
|
+
return sqls.length ? join(sqls, ", ") : sql`TRUE AS "$"`;
|
|
177
191
|
};
|
|
178
192
|
function vertexSql(array, nullValue) {
|
|
179
193
|
return sql`array[${join(
|
|
@@ -754,7 +768,7 @@ class Db {
|
|
|
754
768
|
/*
|
|
755
769
|
Adds .schema to tableOptions if it doesn't exist yet.
|
|
756
770
|
It mutates the argument, to "persist" the results and
|
|
757
|
-
avoid this query in every operation.
|
|
771
|
+
avoid this query in every operation.
|
|
758
772
|
*/
|
|
759
773
|
async ensureSchema(tableOptions, typeOids) {
|
|
760
774
|
if (tableOptions.schema) return;
|
|
@@ -805,19 +819,33 @@ class Db {
|
|
|
805
819
|
const prefix = common.encodePath(rawPrefix);
|
|
806
820
|
await this.ensureSchema(tableOptions);
|
|
807
821
|
const getByArgs = async (args, projection) => {
|
|
808
|
-
const
|
|
809
|
-
|
|
810
|
-
tableOptions
|
|
811
|
-
);
|
|
822
|
+
const sql2 = selectByArgs(args, projection, tableOptions);
|
|
823
|
+
const result = await this.readSql(sql2, tableOptions);
|
|
812
824
|
const wrappedGraph = common.encodeGraph(common.wrapObject(result, rawPrefix));
|
|
813
825
|
log("getByArgs", wrappedGraph);
|
|
814
826
|
common.merge(results, wrappedGraph);
|
|
815
827
|
};
|
|
816
|
-
const
|
|
817
|
-
const
|
|
818
|
-
|
|
819
|
-
|
|
828
|
+
const explainArgs = async (args, projection) => {
|
|
829
|
+
const { $analyze, ...qArgs } = args.$explain;
|
|
830
|
+
const qSql = selectByArgs(qArgs, null, tableOptions);
|
|
831
|
+
const sql$1 = sql`EXPLAIN (${$analyze ? sql`ANALYZE, BUFFERS, TIMING, ` : sql``}COSTS, VERBOSE, FORMAT JSON) ${qSql}`;
|
|
832
|
+
const result = await this.readSql(sql$1, tableOptions);
|
|
833
|
+
const wrappedGraph = common.encodeGraph(
|
|
834
|
+
common.wrapObject(
|
|
835
|
+
{
|
|
836
|
+
$key: args,
|
|
837
|
+
sql: formatSql(qSql),
|
|
838
|
+
plan: result[0]["QUERY PLAN"][0]
|
|
839
|
+
},
|
|
840
|
+
rawPrefix
|
|
841
|
+
)
|
|
820
842
|
);
|
|
843
|
+
log("explainArgs", wrappedGraph);
|
|
844
|
+
common.merge(results, wrappedGraph);
|
|
845
|
+
};
|
|
846
|
+
const getByIds = async () => {
|
|
847
|
+
const sql2 = selectByIds(Object.keys(idQueries), null, tableOptions);
|
|
848
|
+
const result = await this.readSql(sql2, tableOptions);
|
|
821
849
|
for (const object of result) {
|
|
822
850
|
const wrappedGraph = common.encodeGraph(common.wrapObject(object, rawPrefix));
|
|
823
851
|
log("getByIds", wrappedGraph);
|
|
@@ -836,7 +864,11 @@ class Db {
|
|
|
836
864
|
}
|
|
837
865
|
} else {
|
|
838
866
|
const projection = node.children ? common.decodeQuery(node.children) : null;
|
|
839
|
-
|
|
867
|
+
if (args.$explain) {
|
|
868
|
+
promises.push(explainArgs(args));
|
|
869
|
+
} else {
|
|
870
|
+
promises.push(getByArgs(args, projection));
|
|
871
|
+
}
|
|
840
872
|
}
|
|
841
873
|
} else {
|
|
842
874
|
idQueries[args] = node.children;
|
package/index.mjs
CHANGED
|
@@ -77,6 +77,20 @@ const empty = raw("");
|
|
|
77
77
|
function sql(strings, ...values) {
|
|
78
78
|
return new Sql(strings, values);
|
|
79
79
|
}
|
|
80
|
+
function formatSql(sql2) {
|
|
81
|
+
const strings = sql2.strings.slice(0);
|
|
82
|
+
const values = sql2.values.slice(0);
|
|
83
|
+
const output = [];
|
|
84
|
+
while (strings.length) {
|
|
85
|
+
output.push(strings.shift().replace(/\s+/g, " "));
|
|
86
|
+
if (!values.length) break;
|
|
87
|
+
const value = values.shift();
|
|
88
|
+
output.push(
|
|
89
|
+
typeof value === "number" ? value.toString() : typeof value === "object" ? `'${JSON.stringify(value)}'` : `'${value}'`
|
|
90
|
+
);
|
|
91
|
+
}
|
|
92
|
+
return output.join("").trim();
|
|
93
|
+
}
|
|
80
94
|
const getJsonBuildTrusted = (variadic) => {
|
|
81
95
|
const args = join(
|
|
82
96
|
Object.entries(variadic).map(([name, value]) => {
|
|
@@ -155,23 +169,23 @@ const getSelectCols = (options, projection = null) => {
|
|
|
155
169
|
sqls.push(
|
|
156
170
|
sql`jsonb_build_object(${join(subSqls, ", ")}) AS "${raw(key)}"`
|
|
157
171
|
);
|
|
172
|
+
}
|
|
173
|
+
if (key[0] === "$") continue;
|
|
174
|
+
if (typeof projection[key] === "object") {
|
|
175
|
+
const optimisedJsonBuild = getOptimisedJsonBuild(
|
|
176
|
+
projection[key],
|
|
177
|
+
[],
|
|
178
|
+
key,
|
|
179
|
+
options
|
|
180
|
+
);
|
|
181
|
+
sqls.push(
|
|
182
|
+
sql`jsonb_build_object(${join(optimisedJsonBuild, ", ")}) AS "${raw(key)}"`
|
|
183
|
+
);
|
|
158
184
|
} 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
|
-
}
|
|
185
|
+
sqls.push(sql`"${raw(key)}"`);
|
|
172
186
|
}
|
|
173
187
|
}
|
|
174
|
-
return join(sqls, ", ")
|
|
188
|
+
return sqls.length ? join(sqls, ", ") : sql`TRUE AS "$"`;
|
|
175
189
|
};
|
|
176
190
|
function vertexSql(array, nullValue) {
|
|
177
191
|
return sql`array[${join(
|
|
@@ -752,7 +766,7 @@ class Db {
|
|
|
752
766
|
/*
|
|
753
767
|
Adds .schema to tableOptions if it doesn't exist yet.
|
|
754
768
|
It mutates the argument, to "persist" the results and
|
|
755
|
-
avoid this query in every operation.
|
|
769
|
+
avoid this query in every operation.
|
|
756
770
|
*/
|
|
757
771
|
async ensureSchema(tableOptions, typeOids) {
|
|
758
772
|
if (tableOptions.schema) return;
|
|
@@ -803,19 +817,33 @@ class Db {
|
|
|
803
817
|
const prefix = encodePath(rawPrefix);
|
|
804
818
|
await this.ensureSchema(tableOptions);
|
|
805
819
|
const getByArgs = async (args, projection) => {
|
|
806
|
-
const
|
|
807
|
-
|
|
808
|
-
tableOptions
|
|
809
|
-
);
|
|
820
|
+
const sql2 = selectByArgs(args, projection, tableOptions);
|
|
821
|
+
const result = await this.readSql(sql2, tableOptions);
|
|
810
822
|
const wrappedGraph = encodeGraph(wrapObject(result, rawPrefix));
|
|
811
823
|
log("getByArgs", wrappedGraph);
|
|
812
824
|
merge(results, wrappedGraph);
|
|
813
825
|
};
|
|
814
|
-
const
|
|
815
|
-
const
|
|
816
|
-
|
|
817
|
-
|
|
826
|
+
const explainArgs = async (args, projection) => {
|
|
827
|
+
const { $analyze, ...qArgs } = args.$explain;
|
|
828
|
+
const qSql = selectByArgs(qArgs, null, tableOptions);
|
|
829
|
+
const sql$1 = sql`EXPLAIN (${$analyze ? sql`ANALYZE, BUFFERS, TIMING, ` : sql``}COSTS, VERBOSE, FORMAT JSON) ${qSql}`;
|
|
830
|
+
const result = await this.readSql(sql$1, tableOptions);
|
|
831
|
+
const wrappedGraph = encodeGraph(
|
|
832
|
+
wrapObject(
|
|
833
|
+
{
|
|
834
|
+
$key: args,
|
|
835
|
+
sql: formatSql(qSql),
|
|
836
|
+
plan: result[0]["QUERY PLAN"][0]
|
|
837
|
+
},
|
|
838
|
+
rawPrefix
|
|
839
|
+
)
|
|
818
840
|
);
|
|
841
|
+
log("explainArgs", wrappedGraph);
|
|
842
|
+
merge(results, wrappedGraph);
|
|
843
|
+
};
|
|
844
|
+
const getByIds = async () => {
|
|
845
|
+
const sql2 = selectByIds(Object.keys(idQueries), null, tableOptions);
|
|
846
|
+
const result = await this.readSql(sql2, tableOptions);
|
|
819
847
|
for (const object of result) {
|
|
820
848
|
const wrappedGraph = encodeGraph(wrapObject(object, rawPrefix));
|
|
821
849
|
log("getByIds", wrappedGraph);
|
|
@@ -834,7 +862,11 @@ class Db {
|
|
|
834
862
|
}
|
|
835
863
|
} else {
|
|
836
864
|
const projection = node.children ? decodeQuery(node.children) : null;
|
|
837
|
-
|
|
865
|
+
if (args.$explain) {
|
|
866
|
+
promises.push(explainArgs(args));
|
|
867
|
+
} else {
|
|
868
|
+
promises.push(getByArgs(args, projection));
|
|
869
|
+
}
|
|
838
870
|
}
|
|
839
871
|
} else {
|
|
840
872
|
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.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.16.
|
|
19
|
+
"@graffy/common": "0.16.21-alpha.1",
|
|
20
20
|
"debug": "^4.3.3"
|
|
21
21
|
},
|
|
22
22
|
"peerDependencies": {
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export default function formatSql(sql: any): string;
|