@saltcorn/sql 0.3.3 → 0.3.5
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 +21 -7
- package/terminal.js +85 -0
package/index.js
CHANGED
package/package.json
CHANGED
package/table-provider.js
CHANGED
|
@@ -4,6 +4,7 @@ const Workflow = require("@saltcorn/data/models/workflow");
|
|
|
4
4
|
const Form = require("@saltcorn/data/models/form");
|
|
5
5
|
const FieldRepeat = require("@saltcorn/data/models/fieldrepeat");
|
|
6
6
|
const Field = require("@saltcorn/data/models/field");
|
|
7
|
+
const Table = require("@saltcorn/data/models/table");
|
|
7
8
|
const { getState } = require("@saltcorn/data/db/state");
|
|
8
9
|
const SqlString = require("sqlstring");
|
|
9
10
|
const { Parser } = require("node-sql-parser");
|
|
@@ -63,6 +64,14 @@ const configuration_workflow = (req) =>
|
|
|
63
64
|
const pkey_options = getState().type_names.filter(
|
|
64
65
|
(tnm) => getState().types[tnm]?.primaryKey
|
|
65
66
|
);
|
|
67
|
+
const tables = await Table.find({});
|
|
68
|
+
|
|
69
|
+
const fkey_opts = [
|
|
70
|
+
"File",
|
|
71
|
+
...tables
|
|
72
|
+
.filter((t) => !t.provider_name && !t.external)
|
|
73
|
+
.map((t) => `Key to ${t.name}`),
|
|
74
|
+
];
|
|
66
75
|
const theForm = new Form({
|
|
67
76
|
blurb: pre(code(qres.query)) + tbl,
|
|
68
77
|
fields: [
|
|
@@ -90,7 +99,9 @@ const configuration_workflow = (req) =>
|
|
|
90
99
|
label: "Type",
|
|
91
100
|
type: "String",
|
|
92
101
|
required: true,
|
|
93
|
-
attributes: {
|
|
102
|
+
attributes: {
|
|
103
|
+
options: getState().type_names.concat(fkey_opts || []),
|
|
104
|
+
},
|
|
94
105
|
},
|
|
95
106
|
{
|
|
96
107
|
name: "primary_key",
|
|
@@ -169,17 +180,19 @@ const runQuery = async (cfg, where, opts) => {
|
|
|
169
180
|
const { ast } = parser.parse(sql, opt);
|
|
170
181
|
|
|
171
182
|
const colNames = new Set((cfg?.columns || []).map((c) => c.name));
|
|
172
|
-
|
|
173
183
|
let phIndex = 1;
|
|
174
184
|
const phValues = [];
|
|
175
185
|
for (const k of Object.keys(where)) {
|
|
176
186
|
if (!colNames.has(k)) continue;
|
|
177
187
|
const sqlCol = (ast[0].columns || []).find((c) => k === c.as);
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
188
|
+
const sqlExprCol = (ast[0].columns || []).find((c) => c.expr?.as == k);
|
|
189
|
+
let left = sqlExprCol
|
|
190
|
+
? { ...sqlExprCol.expr, as: null }
|
|
191
|
+
: {
|
|
192
|
+
type: "column_ref",
|
|
193
|
+
table: sqlCol?.expr?.table,
|
|
194
|
+
column: db.sqlsanitize(k),
|
|
195
|
+
};
|
|
183
196
|
const newClause = {
|
|
184
197
|
type: "binary_expr",
|
|
185
198
|
operator: "=",
|
|
@@ -221,6 +234,7 @@ const runQuery = async (cfg, where, opts) => {
|
|
|
221
234
|
}
|
|
222
235
|
|
|
223
236
|
const sqlQ = parser.sqlify(ast, opt);
|
|
237
|
+
console.log(sqlQ, phValues);
|
|
224
238
|
const qres = await client.query(sqlQ, phValues);
|
|
225
239
|
qres.query = sqlQ;
|
|
226
240
|
await client.query(`ROLLBACK;`);
|
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
|
+
};
|