@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 +1 -0
- package/package.json +1 -1
- package/table-provider.js +6 -4
- package/terminal.js +85 -0
package/index.js
CHANGED
package/package.json
CHANGED
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 (
|
|
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
|
+
};
|