@saltcorn/sql 0.3.2 → 0.3.4

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.js CHANGED
@@ -142,5 +142,6 @@ module.exports = {
142
142
  configuration_workflow,
143
143
  run,
144
144
  },
145
+ require("./terminal"),
145
146
  ],
146
147
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@saltcorn/sql",
3
- "version": "0.3.2",
3
+ "version": "0.3.4",
4
4
  "description": "Actions and views based on SQL",
5
5
  "main": "index.js",
6
6
  "dependencies": {
package/table-provider.js CHANGED
@@ -145,7 +145,7 @@ const sqlEscapeObject = (o) => {
145
145
  return r;
146
146
  };
147
147
 
148
- const runQuery = async (cfg, where) => {
148
+ const runQuery = async (cfg, where, opts) => {
149
149
  const sqlTmpl = cfg?.sql || "";
150
150
  const template = _.template(sqlTmpl || "", {
151
151
  evaluate: /\{\{#(.+?)\}\}/g,
@@ -154,7 +154,9 @@ const runQuery = async (cfg, where) => {
154
154
 
155
155
  const qctx = {};
156
156
 
157
- if (where.forUser) qctx.user = sqlEscapeObject(where.forUser);
157
+ if (opts?.forUser) qctx.user = sqlEscapeObject(opts.forUser);
158
+ else if (where?.forUser)
159
+ qctx.user = sqlEscapeObject(where.forUser); //workaround legacy bug
158
160
  else qctx.user = null;
159
161
 
160
162
  const sql = template(qctx);
@@ -233,8 +235,8 @@ module.exports = {
233
235
  fields: (cfg) => cfg?.columns || [],
234
236
  get_table: (cfg) => {
235
237
  return {
236
- getRows: async (where) => {
237
- const qres = await runQuery(cfg, where);
238
+ getRows: async (where, opts) => {
239
+ const qres = await runQuery(cfg, where, opts);
238
240
  return qres.rows;
239
241
  },
240
242
  };
package/terminal.js ADDED
@@ -0,0 +1,85 @@
1
+ const Field = require("@saltcorn/data/models/field");
2
+ const Table = require("@saltcorn/data/models/table");
3
+ const Form = require("@saltcorn/data/models/form");
4
+ const View = require("@saltcorn/data/models/view");
5
+ const Trigger = require("@saltcorn/data/models/trigger");
6
+ const { findType } = require("@saltcorn/data/models/discovery");
7
+ const { save_menu_items } = require("@saltcorn/data/models/config");
8
+ const db = require("@saltcorn/data/db");
9
+ const Workflow = require("@saltcorn/data/models/workflow");
10
+ const { renderForm } = require("@saltcorn/markup");
11
+ const { div, script, domReady, pre, code } = require("@saltcorn/markup/tags");
12
+ const { getState } = require("@saltcorn/data/db/state");
13
+ const { mkTable } = require("@saltcorn/markup");
14
+
15
+ const get_state_fields = () => [];
16
+
17
+ const getForm = async (viewname) => {
18
+ const fields = [
19
+ {
20
+ name: "sql",
21
+ label: "SQL",
22
+ input_type: "code",
23
+ attributes: { mode: "text/x-sql" },
24
+ },
25
+ ];
26
+
27
+ const form = new Form({
28
+ action: `/view/${viewname}`,
29
+ fields,
30
+ submitLabel: "Run query",
31
+ });
32
+ return form;
33
+ };
34
+
35
+ const run = async (table_id, viewname, cfg, state, { res, req }) => {
36
+ const form = await getForm(viewname);
37
+ return renderForm(form, req.csrfToken());
38
+ };
39
+
40
+ const runPost = async (
41
+ table_id,
42
+ viewname,
43
+ config,
44
+ state,
45
+ body,
46
+ { req, res }
47
+ ) => {
48
+ const form = await getForm(viewname);
49
+ form.validate(body);
50
+
51
+ const is_sqlite = db.isSQLite;
52
+ const client = is_sqlite ? db : await db.getClient();
53
+ await client.query(`BEGIN;`);
54
+ if (!is_sqlite) {
55
+ await client.query(`SET LOCAL search_path TO "${db.getTenantSchema()}";`);
56
+ await client.query(`SET SESSION CHARACTERISTICS AS TRANSACTION READ ONLY;`);
57
+ }
58
+
59
+ let sqlResult;
60
+ try {
61
+ const qres = await client.query(form.values.sql, []);
62
+
63
+ await client.query(`ROLLBACK;`);
64
+
65
+ if (!is_sqlite) client.release(true);
66
+ sqlResult = mkTable(
67
+ qres.fields.map((field) => ({ label: field.name, key: field.name })),
68
+ qres.rows
69
+ );
70
+ } catch (error) {
71
+ sqlResult = error.message;
72
+ }
73
+
74
+ res.sendWrap("SQL Terminal", [renderForm(form, req.csrfToken()), sqlResult]);
75
+ };
76
+
77
+ module.exports = {
78
+ name: "SQL Terminal",
79
+ display_state_form: false,
80
+ tableless: true,
81
+ singleton: true,
82
+ get_state_fields,
83
+ run,
84
+ runPost,
85
+ };