@saltcorn/sql 0.1.0 → 0.2.0

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/README.md CHANGED
@@ -10,5 +10,5 @@ Use this view to create HTML code views of the results of arbitrary SQL queries
10
10
  2. Set output type = Table or JSON to begin with
11
11
  3. Start by creating your SQL query with no qualifiers (which will come from the URL query state). The preview table should update as you type
12
12
  4. When you are happy with the SQL query, switch to output type = HTML
13
- 5. Create your HTML cod, use `{{ rows }}` to access rows. For instance if your query is an aggregation with a single row result (e.g. `SELECT COUNT(*) FROM...`), access this with `{{ rows[0].count }}`, for example `<h2>{{ rows[0].count }}</h2>`. You can also loop, e.g. `{{# for(const row of rows) { }}`
13
+ 5. Create your HTML code, use `{{ rows }}` to access rows. For instance if your query is an aggregation with a single row result (e.g. `SELECT COUNT(*) FROM...`), access this with `{{ rows[0].count }}`, for example `<h2>{{ rows[0].count }}</h2>`. You can also loop, e.g. `{{# for(const row of rows) { }}`
14
14
  6. When you are happy with both you are SQL and HTML code, Think about whether you need any parameters from the state. List these comma-separated, in order and use in the SQL code as `$1`, `$2` etc. Example SQL code: `select * from _sc_config where key = $1;`
package/action.js ADDED
@@ -0,0 +1,55 @@
1
+ const db = require("@saltcorn/data/db");
2
+ const { eval_expression } = require("@saltcorn/data/models/expression");
3
+
4
+ module.exports = {
5
+ run_sql_code: {
6
+ configFields: [
7
+ {
8
+ name: "sql",
9
+ label: "SQL",
10
+ input_type: "code",
11
+ attributes: { mode: "text/x-sql" },
12
+ sublabel:
13
+ "Refer to row parameters in the order below with <code>$1</code>, <code>$2</code> etc",
14
+ },
15
+ {
16
+ name: "row_parameters",
17
+ label: "Row parameters",
18
+ sublabel:
19
+ "Comma separated list of row variables to use as SQL query parameters. User variables can be used as <code>user.id</code> etc",
20
+ type: "String",
21
+ },
22
+ ],
23
+ run: async ({ row, configuration: { sql, row_parameters }, user }) => {
24
+ const is_sqlite = db.isSQLite;
25
+
26
+ const phValues = [];
27
+ (row_parameters || "")
28
+ .split(",")
29
+ .filter((s) => s)
30
+ .forEach((sp0) => {
31
+ const sp = sp0.trim();
32
+ if (sp.startsWith("user.")) {
33
+ phValues.push(eval_expression(sp, {}, user));
34
+ } else if (typeof row[sp] === "undefined") phValues.push(null);
35
+ else phValues.push(row[sp]);
36
+ });
37
+
38
+ const client = is_sqlite ? db : await db.getClient();
39
+ await client.query(`BEGIN;`);
40
+ if (!is_sqlite) {
41
+ await client.query(
42
+ `SET LOCAL search_path TO "${db.getTenantSchema()}";`
43
+ );
44
+ await client.query(
45
+ `SET SESSION CHARACTERISTICS AS TRANSACTION READ ONLY;`
46
+ );
47
+ }
48
+ const qres = await client.query(sql, phValues);
49
+
50
+ await client.query(`COMMIT;`);
51
+
52
+ if (!is_sqlite) client.release(true);
53
+ },
54
+ },
55
+ };
package/index.js CHANGED
@@ -35,12 +35,14 @@ const configuration_workflow = () =>
35
35
  label: "SQL",
36
36
  input_type: "code",
37
37
  attributes: { mode: "text/x-sql" },
38
+ sublabel:
39
+ "Refer to state parameters in the order below with <code>$1</code>, <code>$2</code> etc",
38
40
  },
39
41
  {
40
42
  name: "state_parameters",
41
43
  label: "State parameters",
42
44
  sublabel:
43
- "Comma separated list of state variables from URL querystring to use as SQL query parameters",
45
+ "Comma separated list of state variables from URL querystring to use as SQL query parameters. User variables can be used as <code>user.id</code> etc",
44
46
  type: "String",
45
47
  },
46
48
  {
@@ -79,7 +81,7 @@ const run = async (
79
81
  viewname,
80
82
  { sql, output_type, state_parameters, html_code },
81
83
  state,
82
- extraArgs
84
+ { req }
83
85
  ) => {
84
86
  const is_sqlite = db.isSQLite;
85
87
 
@@ -89,7 +91,9 @@ const run = async (
89
91
  .filter((s) => s)
90
92
  .forEach((sp0) => {
91
93
  const sp = sp0.trim();
92
- if (typeof state[sp] === "undefined") phValues.push(null);
94
+ if (sp.startsWith("user.")) {
95
+ phValues.push(eval_expression(sp, {}, req.user));
96
+ } else if (typeof state[sp] === "undefined") phValues.push(null);
93
97
  else phValues.push(state[sp]);
94
98
  });
95
99
 
@@ -101,7 +105,7 @@ const run = async (
101
105
  }
102
106
  const qres = await client.query(sql, phValues);
103
107
 
104
- await client.query(`ROLLBACK`);
108
+ await client.query(`ROLLBACK;`);
105
109
 
106
110
  if (!is_sqlite) client.release(true);
107
111
  switch (output_type) {
@@ -127,6 +131,7 @@ const run = async (
127
131
  module.exports = {
128
132
  sc_plugin_api_version: 1,
129
133
  plugin_name: "sql",
134
+ actions: require("./action.js"),
130
135
  viewtemplates: [
131
136
  {
132
137
  name: "SQLView",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@saltcorn/sql",
3
- "version": "0.1.0",
3
+ "version": "0.2.0",
4
4
  "description": "Actions and views based on SQL",
5
5
  "main": "index.js",
6
6
  "dependencies": {