@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 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
- if (typeof projection[key] === "object") {
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 result = await this.readSql(
809
- selectByArgs(args, projection, tableOptions),
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 getByIds = async () => {
817
- const result = await this.readSql(
818
- selectByIds(Object.keys(idQueries), null, tableOptions),
819
- tableOptions
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
- promises.push(getByArgs(args, projection));
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
- if (typeof projection[key] === "object") {
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 result = await this.readSql(
807
- selectByArgs(args, projection, tableOptions),
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 getByIds = async () => {
815
- const result = await this.readSql(
816
- selectByIds(Object.keys(idQueries), null, tableOptions),
817
- tableOptions
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
- promises.push(getByArgs(args, projection));
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.20",
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.20",
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;