@saltcorn/data 0.6.1-beta.1 → 0.6.2-beta.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/db/internal.js DELETED
@@ -1,302 +0,0 @@
1
- /**
2
- * @category saltcorn-data
3
- * @module db/internal
4
- * @subcategory db
5
- */
6
- const { footer } = require("@saltcorn/markup/tags");
7
- const { contract, is } = require("contractis");
8
- const { is_sqlite } = require("./connect");
9
-
10
- //https://stackoverflow.com/questions/15300704/regex-with-my-jquery-function-for-sql-variable-name-validation
11
- /**
12
- * Transform value to correct sql name.
13
- * Note! Dont use other symbols than ^A-Za-z_0-9
14
- * @function
15
- * @param {string} nm
16
- * @returns {string}
17
- */
18
- const sqlsanitize = contract(is.fun(is.str, is.str), (nm) => {
19
- const s = nm.replace(/[^A-Za-z_0-9]*/g, "");
20
- if (s[0] >= "0" && s[0] <= "9") return `_${s}`;
21
- else return s;
22
- });
23
- /**
24
- * Transform value to correct sql name.
25
- * Instead of sqlsanitize also allows .
26
- * For e.g. table name
27
- * Note! Dont use other symbols than ^A-Za-z_0-9.
28
- * @function
29
- * @param {string} nm
30
- * @returns {string}
31
- */
32
- const sqlsanitizeAllowDots = contract(is.fun(is.str, is.str), (nm) => {
33
- const s = nm.replace(/[^A-Za-z_0-9."]*/g, "");
34
- if (s[0] >= "0" && s[0] <= "9") return `_${s}`;
35
- else return s;
36
- });
37
- /**
38
- *
39
- * @param {object} v
40
- * @param {string} i
41
- * @param {boolean} is_sqlite
42
- * @returns {string}
43
- */
44
- const whereFTS = (v, i, is_sqlite) => {
45
- const { fields, table } = v;
46
- var flds = fields
47
- .filter((f) => f.type && f.type.sql_name === "text")
48
- .map(
49
- (f) =>
50
- "coalesce(" +
51
- (table
52
- ? `"${sqlsanitize(table)}"."${sqlsanitize(f.name)}"`
53
- : `"${sqlsanitize(f.name)}"`) +
54
- ",'')"
55
- )
56
- .join(" || ' ' || ");
57
- if (flds === "") flds = "''";
58
- if (is_sqlite) return `${flds} LIKE '%' || ? || '%'`;
59
- else
60
- return `to_tsvector('english', ${flds}) @@ plainto_tsquery('english', $${i})`;
61
- };
62
-
63
- /**
64
- * @param {boolean} is_sqlite
65
- * @param {string} i
66
- * @returns {string}
67
- */
68
- const placeHolder = (is_sqlite, i) => (is_sqlite ? `?` : `$${i}`);
69
-
70
- /**
71
- * @returns {number}
72
- */
73
- const mkCounter = () => {
74
- let i = 0;
75
- return () => {
76
- i += 1;
77
- return i;
78
- };
79
- };
80
- /**
81
- *
82
- * @param {boolean} is_sqlite
83
- * @param {string} i
84
- * @returns {function}
85
- */
86
- const subSelectWhere = (is_sqlite, i) => (k, v) => {
87
- const whereObj = v.inSelect.where;
88
- const wheres = whereObj ? Object.entries(whereObj) : [];
89
- const where =
90
- whereObj && wheres.length > 0
91
- ? "where " + wheres.map(whereClause(is_sqlite, i)).join(" and ")
92
- : "";
93
- return `${quote(sqlsanitizeAllowDots(k))} in (select ${
94
- v.inSelect.field
95
- } from ${v.inSelect.table} ${where})`;
96
- };
97
- /**
98
- * @param {object} v
99
- * @returns {object[]}
100
- */
101
- const subSelectVals = (v) => {
102
- const whereObj = v.inSelect.where;
103
- const wheres = whereObj ? Object.entries(whereObj) : [];
104
- const xs = wheres
105
- .map(getVal)
106
- .flat(1)
107
- .filter((v) => v !== null);
108
- return xs;
109
- };
110
- /**
111
- * @param {string} s
112
- * @returns {string}
113
- */
114
- const wrapParens = (s) => (s ? `(${s})` : s);
115
- /**
116
- * @param {string} s
117
- * @returns {string}
118
- */
119
- const quote = (s) => (s.includes(".") || s.includes('"') ? s : `"${s}"`);
120
- /**
121
- * @param {boolean} is_sqlite
122
- * @param {string} i
123
- * @returns {function}
124
- */
125
- const whereOr = (is_sqlite, i) => (ors) =>
126
- wrapParens(
127
- ors
128
- .map((vi) =>
129
- Object.entries(vi)
130
- .map((kv) => whereClause(is_sqlite, i)(kv))
131
- .join(" and ")
132
- )
133
- .join(" or ")
134
- );
135
-
136
- /**
137
- * @param {boolean} is_sqlite
138
- * @param {string} i
139
- * @returns {function}
140
- */
141
- const whereClause = (is_sqlite, i) => ([k, v]) =>
142
- k === "_fts"
143
- ? whereFTS(v, i(), is_sqlite)
144
- : typeof (v || {}).in !== "undefined"
145
- ? `${quote(sqlsanitizeAllowDots(k))} = ${
146
- is_sqlite ? "" : "ANY"
147
- } (${placeHolder(is_sqlite, i())})`
148
- : k === "or" && Array.isArray(v)
149
- ? whereOr(is_sqlite, i)(v)
150
- : k === "not" && typeof v === "object"
151
- ? `not (${Object.entries(v)
152
- .map((kv) => whereClause(is_sqlite, i)(kv))
153
- .join(" and ")})`
154
- : v && v.or && Array.isArray(v.or)
155
- ? wrapParens(
156
- v.or.map((vi) => whereClause(is_sqlite, i)([k, vi])).join(" or ")
157
- )
158
- : Array.isArray(v)
159
- ? v.map((vi) => whereClause(is_sqlite, i)([k, vi])).join(" and ")
160
- : typeof (v || {}).ilike !== "undefined"
161
- ? `${quote(sqlsanitizeAllowDots(k))} ${
162
- is_sqlite ? "LIKE" : "ILIKE"
163
- } '%' || ${placeHolder(is_sqlite, i())} || '%'`
164
- : typeof (v || {}).gt !== "undefined"
165
- ? `${quote(sqlsanitizeAllowDots(k))}>${v.equal ? "=" : ""}${placeHolder(
166
- is_sqlite,
167
- i()
168
- )}`
169
- : typeof (v || {}).lt !== "undefined"
170
- ? `${quote(sqlsanitizeAllowDots(k))}<${v.equal ? "=" : ""}${placeHolder(
171
- is_sqlite,
172
- i()
173
- )}`
174
- : typeof (v || {}).inSelect !== "undefined"
175
- ? subSelectWhere(is_sqlite, i)(k, v)
176
- : typeof (v || {}).json !== "undefined"
177
- ? is_sqlite
178
- ? `json_extract(${quote(
179
- sqlsanitizeAllowDots(k)
180
- )}, '$.${sqlsanitizeAllowDots(v.json[0])}')=${placeHolder(
181
- is_sqlite,
182
- i()
183
- )}`
184
- : `${quote(sqlsanitizeAllowDots(k))}->>'${sqlsanitizeAllowDots(
185
- v.json[0]
186
- )}'=${placeHolder(is_sqlite, i())}`
187
- : v === null
188
- ? `${quote(sqlsanitizeAllowDots(k))} is null`
189
- : `${quote(sqlsanitizeAllowDots(k))}=${placeHolder(is_sqlite, i())}`;
190
-
191
- /**
192
- * @param {object[]} opts
193
- * @param {object} opts.k
194
- * @param {object} opts.v
195
- * @returns {boolean|object}
196
- */
197
- const getVal = ([k, v]) =>
198
- k === "_fts"
199
- ? v.searchTerm
200
- : typeof (v || {}).in !== "undefined"
201
- ? [v.in]
202
- : k === "not" && typeof v === "object"
203
- ? Object.entries(v).map(getVal).flat(1)
204
- : k === "or" && Array.isArray(v)
205
- ? v.map((vi) => Object.entries(vi).map(getVal)).flat(1)
206
- : v && v.or && Array.isArray(v.or)
207
- ? v.or.map((vi) => getVal([k, vi])).flat(1)
208
- : Array.isArray(v)
209
- ? v.map((vi) => getVal([k, vi])).flat(1)
210
- : typeof (v || {}).ilike !== "undefined"
211
- ? v.ilike
212
- : typeof (v || {}).inSelect !== "undefined"
213
- ? subSelectVals(v)
214
- : typeof (v || {}).lt !== "undefined"
215
- ? v.lt
216
- : typeof (v || {}).gt !== "undefined"
217
- ? v.gt
218
- : typeof (v || {}).sql !== "undefined"
219
- ? null
220
- : typeof (v || {}).json !== "undefined"
221
- ? v.json[1]
222
- : v;
223
-
224
- /**
225
- * @param {object} whereObj
226
- * @param {boolean} is_sqlite
227
- * @returns {object}
228
- */
229
- const mkWhere = (whereObj, is_sqlite) => {
230
- const wheres = whereObj ? Object.entries(whereObj) : [];
231
- //console.log({ wheres });
232
- const where =
233
- whereObj && wheres.length > 0
234
- ? "where " + wheres.map(whereClause(is_sqlite, mkCounter())).join(" and ")
235
- : "";
236
- const values = wheres
237
- .map(getVal)
238
- .flat(1)
239
- .filter((v) => v !== null);
240
- return { where, values };
241
- };
242
-
243
- /**
244
- * @param {number|string} x
245
- * @returns {number|null}
246
- */
247
- const toInt = (x) =>
248
- typeof x === "number"
249
- ? Math.round(x)
250
- : typeof x === "string"
251
- ? parseInt(x)
252
- : null;
253
-
254
- /**
255
- * @param {object} opts
256
- * @param {string} opts.latField
257
- * @param {string} opts.longField
258
- * @param {number} opts.lat
259
- * @param {number} opts.long
260
- * @returns {string}
261
- */
262
- const getDistanceOrder = ({ latField, longField, lat, long }) => {
263
- const cos_lat_2 = Math.pow(Math.cos((+lat * Math.PI) / 180), 2);
264
- return `((${sqlsanitizeAllowDots(
265
- latField
266
- )} - ${+lat})*(${sqlsanitizeAllowDots(
267
- latField
268
- )} - ${+lat})) + ((${sqlsanitizeAllowDots(
269
- longField
270
- )} - ${+long})*(${sqlsanitizeAllowDots(longField)} - ${+long})*${cos_lat_2})`;
271
- };
272
-
273
- /**
274
- * @param {object} selopts
275
- * @returns {string[]}
276
- */
277
- const mkSelectOptions = (selopts) => {
278
- const orderby =
279
- selopts.orderBy === "RANDOM()"
280
- ? "order by RANDOM()"
281
- : selopts.orderBy && selopts.orderBy.distance
282
- ? `order by ${getDistanceOrder(selopts.orderBy.distance)}`
283
- : selopts.orderBy && selopts.nocase
284
- ? `order by lower(${sqlsanitizeAllowDots(selopts.orderBy)})${
285
- selopts.orderDesc ? " DESC" : ""
286
- }`
287
- : selopts.orderBy
288
- ? `order by ${sqlsanitizeAllowDots(selopts.orderBy)}${
289
- selopts.orderDesc ? " DESC" : ""
290
- }`
291
- : "";
292
- const limit = selopts.limit ? `limit ${toInt(selopts.limit)}` : "";
293
- const offset = selopts.offset ? `offset ${toInt(selopts.offset)}` : "";
294
- return [orderby, limit, offset].filter((s) => s).join(" ");
295
- };
296
-
297
- module.exports = {
298
- sqlsanitize,
299
- mkWhere,
300
- mkSelectOptions,
301
- sqlsanitizeAllowDots,
302
- };
@@ -1,44 +0,0 @@
1
- /**
2
- * @category saltcorn-data
3
- * @module db/multi-tenant
4
- * @subcategory db
5
- */
6
- const { AsyncLocalStorage } = require("async_hooks");
7
- const { sqlsanitize } = require("./internal");
8
-
9
- var is_multi_tenant = true;
10
-
11
- /**
12
- * @returns {boolean}
13
- */
14
- const is_it_multi_tenant = () => is_multi_tenant;
15
-
16
- const tenantNamespace = new AsyncLocalStorage();
17
-
18
- /**
19
- * @returns {object}
20
- */
21
- const enable_multi_tenant = () => {};
22
-
23
- /**
24
- * @param {object} tenant
25
- * @param {function} f
26
- * @returns {object}
27
- */
28
- const runWithTenant = (tenant, f) => {
29
- if (!is_multi_tenant) return f();
30
- else return tenantNamespace.run(sqlsanitize(tenant).toLowerCase(), f);
31
- };
32
-
33
- module.exports = (connObj) => ({
34
- /**
35
- * @returns {object}
36
- */
37
- getTenantSchema() {
38
- const storeVal = tenantNamespace.getStore();
39
- return storeVal || connObj.default_schema;
40
- },
41
- enable_multi_tenant,
42
- runWithTenant,
43
- is_it_multi_tenant,
44
- });