json-fs-query 2.3.1 → 3.1.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 +79 -7
- package/browser/jsonFsQuery.js +12650 -13107
- package/browser/jsonFsQuery.min.js +1 -1
- package/dist/data/introspect/create.js +30 -1
- package/dist/data/introspect/create.min.js +1 -1
- package/dist/data/queries/groupBy.d.ts +20 -1
- package/dist/data/queries/groupBy.js +71 -9
- package/dist/data/queries/groupBy.min.js +1 -1
- package/dist/data/queries/limitOffset.d.ts +1 -1
- package/dist/data/queries/limitOffset.js +1 -1
- package/dist/data/queries/selectFields.d.ts +6 -4
- package/dist/data/queries/selectFields.js +15 -10
- package/dist/data/queries/selectFields.min.js +1 -1
- package/dist/data/utilities/databaseLock.js +2 -1
- package/dist/data/utilities/databaseLock.min.js +1 -1
- package/dist/data/utilities/parsers/findCommand.d.ts +2 -1
- package/dist/data/utilities/parsers/findCommand.js +4 -4
- package/dist/data/utilities/parsers/findCommand.min.js +1 -1
- package/dist/data/utilities/parsers/findConditions.d.ts +8 -9
- package/dist/data/utilities/parsers/findConditions.js +29 -41
- package/dist/data/utilities/parsers/findConditions.min.js +1 -1
- package/dist/data/utilities/parsers/findGroupBy.d.ts +6 -4
- package/dist/data/utilities/parsers/findGroupBy.js +17 -9
- package/dist/data/utilities/parsers/findGroupBy.min.js +1 -1
- package/dist/data/utilities/parsers/findInsertValues.d.ts +4 -3
- package/dist/data/utilities/parsers/findInsertValues.js +9 -9
- package/dist/data/utilities/parsers/findInsertValues.min.js +1 -1
- package/dist/data/utilities/parsers/findJoinClauses.d.ts +4 -3
- package/dist/data/utilities/parsers/findJoinClauses.js +20 -13
- package/dist/data/utilities/parsers/findJoinClauses.min.js +1 -1
- package/dist/data/utilities/parsers/findJoinEntity.d.ts +1 -1
- package/dist/data/utilities/parsers/findJoinEntity.js +3 -5
- package/dist/data/utilities/parsers/findJoinEntity.min.js +1 -1
- package/dist/data/utilities/parsers/findLimit.d.ts +4 -3
- package/dist/data/utilities/parsers/findLimit.js +8 -8
- package/dist/data/utilities/parsers/findLimit.min.js +1 -1
- package/dist/data/utilities/parsers/findMergeJoins.d.ts +4 -3
- package/dist/data/utilities/parsers/findMergeJoins.js +19 -12
- package/dist/data/utilities/parsers/findMergeJoins.min.js +1 -1
- package/dist/data/utilities/parsers/findOffset.d.ts +4 -3
- package/dist/data/utilities/parsers/findOffset.js +8 -8
- package/dist/data/utilities/parsers/findOffset.min.js +1 -1
- package/dist/data/utilities/parsers/findSelects.d.ts +4 -3
- package/dist/data/utilities/parsers/findSelects.js +13 -14
- package/dist/data/utilities/parsers/findSelects.min.js +1 -1
- package/dist/data/utilities/parsers/findSortClauses.d.ts +4 -3
- package/dist/data/utilities/parsers/findSortClauses.js +12 -12
- package/dist/data/utilities/parsers/findSortClauses.min.js +1 -1
- package/dist/data/utilities/parsers/findUpdateValues.d.ts +5 -7
- package/dist/data/utilities/parsers/findUpdateValues.js +10 -13
- package/dist/data/utilities/parsers/findUpdateValues.min.js +1 -1
- package/dist/data/utilities/parsers/parseQuery.js +83 -9
- package/dist/data/utilities/parsers/parseQuery.min.js +1 -1
- package/dist/data/utilities/parsers/splitClauses.d.ts +29 -0
- package/dist/data/utilities/parsers/splitClauses.js +139 -0
- package/dist/data/utilities/parsers/splitClauses.min.js +1 -0
- package/dist/data/utilities/retrieveFile.js +2 -1
- package/dist/data/utilities/retrieveFile.min.js +1 -1
- package/dist/data/utilities/runQuery.js +5 -4
- package/dist/data/utilities/runQuery.min.js +1 -1
- package/package.json +5 -3
- package/dist/data/utilities/parsers/removeFromQuery.d.ts +0 -2
- package/dist/data/utilities/parsers/removeFromQuery.js +0 -8
- package/dist/data/utilities/parsers/removeFromQuery.min.js +0 -1
|
@@ -4,6 +4,7 @@ Object.defineProperty(exports, "__esModule", {
|
|
|
4
4
|
value: true
|
|
5
5
|
});
|
|
6
6
|
exports.create = void 0;
|
|
7
|
+
require("core-js/modules/es.array.includes.js");
|
|
7
8
|
require("core-js/modules/es.json.stringify.js");
|
|
8
9
|
require("core-js/modules/esnext.iterator.constructor.js");
|
|
9
10
|
require("core-js/modules/esnext.iterator.find.js");
|
|
@@ -12,11 +13,28 @@ var _record = require("./definitions/record");
|
|
|
12
13
|
var _registerRecord = require("../utilities/registerRecord");
|
|
13
14
|
var _config = require("../utilities/config");
|
|
14
15
|
var _typeCheck = require("./policies/typeCheck");
|
|
16
|
+
const knownKeyProperties = ['type', 'fields', 'lookup', 'references'];
|
|
17
|
+
/**
|
|
18
|
+
* Reject a key with a property key() would ignore (a typo such as `keys` for `fields`), which has to be
|
|
19
|
+
* checked on the keys as given, before key() drops it.
|
|
20
|
+
* @param recordName
|
|
21
|
+
* @param keys
|
|
22
|
+
*/
|
|
23
|
+
const assertKnownKeyProperties = (recordName, keys) => {
|
|
24
|
+
for (const key of keys) {
|
|
25
|
+
for (const property of Object.keys(key)) {
|
|
26
|
+
if (!knownKeyProperties.includes(property)) {
|
|
27
|
+
throw new Error(`Unknown property "${property}" on ${key.type ?? 'index'} key of ${recordName}; must be ${knownKeyProperties.join(', ')}`);
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
};
|
|
15
32
|
/**
|
|
16
33
|
* Reject a definition that could never be written correctly, before anything is created: a
|
|
17
34
|
* default that fails its field's type check (otherwise every insert leaving that field out would
|
|
18
35
|
* fail instead), including a null default on a field that isn't nullable, and a nullable field in
|
|
19
|
-
* the primary key (an entry's file name comes from its primary key value).
|
|
36
|
+
* the primary key (an entry's file name comes from its primary key value). Also a key with no fields,
|
|
37
|
+
* or with a field that isn't in the definition.
|
|
20
38
|
* @param recordName
|
|
21
39
|
* @param recordContent
|
|
22
40
|
*/
|
|
@@ -31,6 +49,16 @@ const assertValidDefinition = (recordName, recordContent) => {
|
|
|
31
49
|
throw new Error(`Invalid default for field "${field.name}" of ${recordName}: ${err.message}`);
|
|
32
50
|
}
|
|
33
51
|
}
|
|
52
|
+
for (const key of recordContent.keys) {
|
|
53
|
+
if (key.fields.length < 1) {
|
|
54
|
+
throw new Error(`The ${key.type} key of ${recordName} must have at least one field`);
|
|
55
|
+
}
|
|
56
|
+
for (const fieldName of key.fields) {
|
|
57
|
+
if (!recordContent.definition.some(field => field.name === fieldName)) {
|
|
58
|
+
throw new Error(`The ${key.type} key of ${recordName} names field "${fieldName}", which isn't in the definition`);
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
}
|
|
34
62
|
const primaryKey = recordContent.keys.find(key => key.type === 'primary');
|
|
35
63
|
for (const fieldName of primaryKey ? primaryKey.fields : []) {
|
|
36
64
|
if (recordContent.definition.some(field => field.name === fieldName && field.nullable)) {
|
|
@@ -59,6 +87,7 @@ const create = async (recordName, definition = [], keys = []) => {
|
|
|
59
87
|
if (existsSync(`${databasePath}${recordName}.json`)) {
|
|
60
88
|
return null;
|
|
61
89
|
}
|
|
90
|
+
assertKnownKeyProperties(recordName, keys);
|
|
62
91
|
const recordContent = (0, _record.record)({
|
|
63
92
|
path: recordName,
|
|
64
93
|
definition,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
"use strict";Object.defineProperty(exports,"__esModule",{value:!0}),exports.create=void 0,require("core-js/modules/es.json.stringify.js"),require("core-js/modules/esnext.iterator.constructor.js"),require("core-js/modules/esnext.iterator.find.js"),require("core-js/modules/esnext.iterator.some.js");var _record=require("./definitions/record"),_registerRecord=require("../utilities/registerRecord"),_config=require("../utilities/config"),_typeCheck=require("./policies/typeCheck");const assertValidDefinition=(e,r)=>{for(const t of r.definition)if(Object.prototype.hasOwnProperty.call(t,"default"))try{(0,_typeCheck.typeCheck)(t.type,t.default,t.nullable)}catch(r){throw new Error(`Invalid default for field "${t.name}" of ${e}: ${r.message}`)}const t=r.keys.find((e=>"primary"===e.type));for(const i of t?t.fields:[])if(r.definition.some((e=>e.name===i&&e.nullable)))throw new Error(`Primary key field "${i}" of ${e} can't be nullable`)},create=async(e,r=[],t=[])=>{const{writeFile:i,mkdir:
|
|
1
|
+
"use strict";Object.defineProperty(exports,"__esModule",{value:!0}),exports.create=void 0,require("core-js/modules/es.array.includes.js"),require("core-js/modules/es.json.stringify.js"),require("core-js/modules/esnext.iterator.constructor.js"),require("core-js/modules/esnext.iterator.find.js"),require("core-js/modules/esnext.iterator.some.js");var _record=require("./definitions/record"),_registerRecord=require("../utilities/registerRecord"),_config=require("../utilities/config"),_typeCheck=require("./policies/typeCheck");const knownKeyProperties=["type","fields","lookup","references"],assertKnownKeyProperties=(e,r)=>{for(const t of r)for(const r of Object.keys(t))if(!knownKeyProperties.includes(r))throw new Error(`Unknown property "${r}" on ${t.type??"index"} key of ${e}; must be ${knownKeyProperties.join(", ")}`)},assertValidDefinition=(e,r)=>{for(const t of r.definition)if(Object.prototype.hasOwnProperty.call(t,"default"))try{(0,_typeCheck.typeCheck)(t.type,t.default,t.nullable)}catch(r){throw new Error(`Invalid default for field "${t.name}" of ${e}: ${r.message}`)}for(const t of r.keys){if(t.fields.length<1)throw new Error(`The ${t.type} key of ${e} must have at least one field`);for(const i of t.fields)if(!r.definition.some((e=>e.name===i)))throw new Error(`The ${t.type} key of ${e} names field "${i}", which isn't in the definition`)}const t=r.keys.find((e=>"primary"===e.type));for(const i of t?t.fields:[])if(r.definition.some((e=>e.name===i&&e.nullable)))throw new Error(`Primary key field "${i}" of ${e} can't be nullable`)},create=async(e,r=[],t=[])=>{const{writeFile:i,mkdir:o}=require("fs/promises"),{existsSync:s}=require("fs"),n=(0,_config.getSetting)("databasePath","database/");if("__RECORDS"===e)return null;if(s(`${n}${e}.json`))return null;assertKnownKeyProperties(e,t);const a=(0,_record.record)({path:e,definition:r,keys:t});return assertValidDefinition(e,a),await o(n,{recursive:!0}),await i(`${n}${e}.json`,JSON.stringify(a,null,2)),await o(`${n}${e}`,{recursive:!0}),await(0,_registerRecord.registerRecord)(e),a};exports.create=create;
|
|
@@ -1,2 +1,21 @@
|
|
|
1
|
-
|
|
1
|
+
/**
|
|
2
|
+
* One group of a grouped read: the field and the value its rows share, then either the rows themselves or, for
|
|
3
|
+
* `group by a, b`, the groups within it by the next field. A group of rows missing the field has `missing: true`
|
|
4
|
+
* and no value; `null` is a value of its own (see Null and missing fields in the README).
|
|
5
|
+
*/
|
|
6
|
+
export type Group = {
|
|
7
|
+
field: string;
|
|
8
|
+
value?: any;
|
|
9
|
+
missing?: true;
|
|
10
|
+
rows?: Object[];
|
|
11
|
+
groups?: Group[];
|
|
12
|
+
};
|
|
13
|
+
/**
|
|
14
|
+
* Group rows by each field in turn. The groups are a list in the order their first row came, so a sort before
|
|
15
|
+
* grouping orders the groups too (and the rows within each one).
|
|
16
|
+
* @param dataSet
|
|
17
|
+
* @param fields
|
|
18
|
+
* @returns The rows as they were when there's no field, otherwise the groups.
|
|
19
|
+
*/
|
|
20
|
+
export declare const groupBy: (dataSet?: Object[], fields?: string[]) => Object[] | Group[];
|
|
2
21
|
//# sourceMappingURL=groupBy.d.ts.map
|
|
@@ -4,19 +4,81 @@ Object.defineProperty(exports, "__esModule", {
|
|
|
4
4
|
value: true
|
|
5
5
|
});
|
|
6
6
|
exports.groupBy = void 0;
|
|
7
|
+
require("core-js/modules/es.json.stringify.js");
|
|
7
8
|
require("core-js/modules/esnext.iterator.constructor.js");
|
|
9
|
+
require("core-js/modules/esnext.iterator.map.js");
|
|
8
10
|
require("core-js/modules/esnext.iterator.reduce.js");
|
|
9
|
-
|
|
10
|
-
|
|
11
|
+
require("core-js/modules/esnext.map.delete-all.js");
|
|
12
|
+
require("core-js/modules/esnext.map.every.js");
|
|
13
|
+
require("core-js/modules/esnext.map.filter.js");
|
|
14
|
+
require("core-js/modules/esnext.map.find.js");
|
|
15
|
+
require("core-js/modules/esnext.map.find-key.js");
|
|
16
|
+
require("core-js/modules/esnext.map.includes.js");
|
|
17
|
+
require("core-js/modules/esnext.map.key-of.js");
|
|
18
|
+
require("core-js/modules/esnext.map.map-keys.js");
|
|
19
|
+
require("core-js/modules/esnext.map.map-values.js");
|
|
20
|
+
require("core-js/modules/esnext.map.merge.js");
|
|
21
|
+
require("core-js/modules/esnext.map.reduce.js");
|
|
22
|
+
require("core-js/modules/esnext.map.some.js");
|
|
23
|
+
require("core-js/modules/esnext.map.update.js");
|
|
24
|
+
// An object's keys in sorted order, at any depth, so { a, b } and { b, a } are the same value; arrays keep their order
|
|
25
|
+
const sortedKeys = value => {
|
|
26
|
+
if (Array.isArray(value)) {
|
|
27
|
+
return value.map(sortedKeys);
|
|
28
|
+
}
|
|
29
|
+
if (value !== null && typeof value === 'object') {
|
|
30
|
+
return Object.keys(value).sort().reduce((sorted, key) => {
|
|
31
|
+
sorted[key] = sortedKeys(value[key]);
|
|
32
|
+
return sorted;
|
|
33
|
+
}, {});
|
|
34
|
+
}
|
|
35
|
+
return value;
|
|
36
|
+
};
|
|
37
|
+
// Rows share a group when their values are the same, type included: 1 and '1' are two groups, as are null and missing
|
|
38
|
+
const groupKey = (row, field) => {
|
|
39
|
+
if (!Object.prototype.hasOwnProperty.call(row, field)) {
|
|
40
|
+
return 'missing';
|
|
41
|
+
}
|
|
42
|
+
const value = row[field];
|
|
43
|
+
return value !== null && typeof value === 'object' ? `json:${JSON.stringify(sortedKeys(value))}` : `${typeof value}:${String(value)}`;
|
|
44
|
+
};
|
|
45
|
+
/**
|
|
46
|
+
* Group rows by each field in turn. The groups are a list in the order their first row came, so a sort before
|
|
47
|
+
* grouping orders the groups too (and the rows within each one).
|
|
48
|
+
* @param dataSet
|
|
49
|
+
* @param fields
|
|
50
|
+
* @returns The rows as they were when there's no field, otherwise the groups.
|
|
51
|
+
*/
|
|
52
|
+
const groupBy = (dataSet = [], fields = []) => {
|
|
53
|
+
if (!fields.length) {
|
|
11
54
|
return dataSet;
|
|
12
55
|
}
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
56
|
+
const [field, ...rest] = fields;
|
|
57
|
+
const groups = new Map();
|
|
58
|
+
for (const row of dataSet) {
|
|
59
|
+
const key = groupKey(row, field);
|
|
60
|
+
if (!groups.has(key)) {
|
|
61
|
+
groups.set(key, key === 'missing' ? {
|
|
62
|
+
field,
|
|
63
|
+
missing: true,
|
|
64
|
+
rows: []
|
|
65
|
+
} : {
|
|
66
|
+
field,
|
|
67
|
+
value: row[field],
|
|
68
|
+
rows: []
|
|
69
|
+
});
|
|
17
70
|
}
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
71
|
+
groups.get(key).rows.push(row);
|
|
72
|
+
}
|
|
73
|
+
return [...groups.values()].map(({
|
|
74
|
+
rows,
|
|
75
|
+
...group
|
|
76
|
+
}) => rest.length ? {
|
|
77
|
+
...group,
|
|
78
|
+
groups: groupBy(rows, rest)
|
|
79
|
+
} : {
|
|
80
|
+
...group,
|
|
81
|
+
rows
|
|
82
|
+
});
|
|
21
83
|
};
|
|
22
84
|
exports.groupBy = groupBy;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
"use strict";Object.defineProperty(exports,"__esModule",{value:!0}),exports.groupBy=void 0,require("core-js/modules/esnext.iterator.constructor.js"),require("core-js/modules/esnext.iterator.reduce.js");const
|
|
1
|
+
"use strict";Object.defineProperty(exports,"__esModule",{value:!0}),exports.groupBy=void 0,require("core-js/modules/es.json.stringify.js"),require("core-js/modules/esnext.iterator.constructor.js"),require("core-js/modules/esnext.iterator.map.js"),require("core-js/modules/esnext.iterator.reduce.js"),require("core-js/modules/esnext.map.delete-all.js"),require("core-js/modules/esnext.map.every.js"),require("core-js/modules/esnext.map.filter.js"),require("core-js/modules/esnext.map.find.js"),require("core-js/modules/esnext.map.find-key.js"),require("core-js/modules/esnext.map.includes.js"),require("core-js/modules/esnext.map.key-of.js"),require("core-js/modules/esnext.map.map-keys.js"),require("core-js/modules/esnext.map.map-values.js"),require("core-js/modules/esnext.map.merge.js"),require("core-js/modules/esnext.map.reduce.js"),require("core-js/modules/esnext.map.some.js"),require("core-js/modules/esnext.map.update.js");const sortedKeys=e=>Array.isArray(e)?e.map(sortedKeys):null!==e&&"object"==typeof e?Object.keys(e).sort().reduce(((s,r)=>(s[r]=sortedKeys(e[r]),s)),{}):e,groupKey=(e,s)=>{if(!Object.prototype.hasOwnProperty.call(e,s))return"missing";const r=e[s];return null!==r&&"object"==typeof r?`json:${JSON.stringify(sortedKeys(r))}`:`${typeof r}:${String(r)}`},groupBy=(e=[],s=[])=>{if(!s.length)return e;const[r,...o]=s,t=new Map;for(const s of e){const e=groupKey(s,r);t.has(e)||t.set(e,"missing"===e?{field:r,missing:!0,rows:[]}:{field:r,value:s[r],rows:[]}),t.get(e).rows.push(s)}return[...t.values()].map((({rows:e,...s})=>o.length?{...s,groups:groupBy(e,o)}:{...s,rows:e}))};exports.groupBy=groupBy;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Slice a dataSet down to at most `limit` rows, starting after the first `offset` of them.
|
|
2
|
+
* Slice a dataSet down to at most `limit` rows (or groups, after group by), starting after the first `offset` of them.
|
|
3
3
|
* @param dataSet
|
|
4
4
|
* @param offset
|
|
5
5
|
* @param limit
|
|
@@ -5,7 +5,7 @@ Object.defineProperty(exports, "__esModule", {
|
|
|
5
5
|
});
|
|
6
6
|
exports.limitOffset = void 0;
|
|
7
7
|
/**
|
|
8
|
-
* Slice a dataSet down to at most `limit` rows, starting after the first `offset` of them.
|
|
8
|
+
* Slice a dataSet down to at most `limit` rows (or groups, after group by), starting after the first `offset` of them.
|
|
9
9
|
* @param dataSet
|
|
10
10
|
* @param offset
|
|
11
11
|
* @param limit
|
|
@@ -1,10 +1,12 @@
|
|
|
1
1
|
import { ParsedSelect } from '../utilities/parsers/findSelects';
|
|
2
|
+
import { Group } from './groupBy';
|
|
2
3
|
/**
|
|
3
|
-
* Shape each row down to only the selected properties (aliased, when given). dataSet is either a
|
|
4
|
-
*
|
|
5
|
-
*
|
|
4
|
+
* Shape each row down to only the selected properties (aliased, when given). dataSet is either a list of rows, or
|
|
5
|
+
* (once groupBy has run) a list of groups, whose rows are shaped the same way at any depth; the groups keep their
|
|
6
|
+
* field and value, selected or not.
|
|
6
7
|
* @param dataSet
|
|
7
8
|
* @param selectClauses
|
|
9
|
+
* @param grouped Whether dataSet is a list of groups (see groupBy)
|
|
8
10
|
*/
|
|
9
|
-
export declare const selectFields: (dataSet?: Object[] |
|
|
11
|
+
export declare const selectFields: (dataSet?: Object[] | Group[], selectClauses?: ParsedSelect[], grouped?: boolean) => Object[] | Group[];
|
|
10
12
|
//# sourceMappingURL=selectFields.d.ts.map
|
|
@@ -14,23 +14,28 @@ const shapeRow = (row, selectClauses) => selectClauses.reduce((shaped, {
|
|
|
14
14
|
shaped[alias || property] = row[property];
|
|
15
15
|
return shaped;
|
|
16
16
|
}, {});
|
|
17
|
+
const shapeGroup = (group, selectClauses) => group.groups ? {
|
|
18
|
+
...group,
|
|
19
|
+
groups: group.groups.map(inner => shapeGroup(inner, selectClauses))
|
|
20
|
+
} : {
|
|
21
|
+
...group,
|
|
22
|
+
rows: group.rows.map(row => shapeRow(row, selectClauses))
|
|
23
|
+
};
|
|
17
24
|
/**
|
|
18
|
-
* Shape each row down to only the selected properties (aliased, when given). dataSet is either a
|
|
19
|
-
*
|
|
20
|
-
*
|
|
25
|
+
* Shape each row down to only the selected properties (aliased, when given). dataSet is either a list of rows, or
|
|
26
|
+
* (once groupBy has run) a list of groups, whose rows are shaped the same way at any depth; the groups keep their
|
|
27
|
+
* field and value, selected or not.
|
|
21
28
|
* @param dataSet
|
|
22
29
|
* @param selectClauses
|
|
30
|
+
* @param grouped Whether dataSet is a list of groups (see groupBy)
|
|
23
31
|
*/
|
|
24
|
-
const selectFields = (dataSet = [], selectClauses = []) => {
|
|
32
|
+
const selectFields = (dataSet = [], selectClauses = [], grouped = false) => {
|
|
25
33
|
if (!selectClauses.length) {
|
|
26
34
|
return dataSet;
|
|
27
35
|
}
|
|
28
|
-
if (
|
|
29
|
-
return dataSet.map(
|
|
36
|
+
if (grouped) {
|
|
37
|
+
return dataSet.map(group => shapeGroup(group, selectClauses));
|
|
30
38
|
}
|
|
31
|
-
return
|
|
32
|
-
shaped[key] = dataSet[key].map(row => shapeRow(row, selectClauses));
|
|
33
|
-
return shaped;
|
|
34
|
-
}, {});
|
|
39
|
+
return dataSet.map(row => shapeRow(row, selectClauses));
|
|
35
40
|
};
|
|
36
41
|
exports.selectFields = selectFields;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
"use strict";Object.defineProperty(exports,"__esModule",{value:!0}),exports.selectFields=void 0,require("core-js/modules/esnext.iterator.constructor.js"),require("core-js/modules/esnext.iterator.map.js"),require("core-js/modules/esnext.iterator.reduce.js");const shapeRow=(e,s)=>s.reduce(((s,{property:r,alias:
|
|
1
|
+
"use strict";Object.defineProperty(exports,"__esModule",{value:!0}),exports.selectFields=void 0,require("core-js/modules/esnext.iterator.constructor.js"),require("core-js/modules/esnext.iterator.map.js"),require("core-js/modules/esnext.iterator.reduce.js");const shapeRow=(e,s)=>s.reduce(((s,{property:r,alias:o})=>(s[o||r]=e[r],s)),{}),shapeGroup=(e,s)=>e.groups?{...e,groups:e.groups.map((e=>shapeGroup(e,s)))}:{...e,rows:e.rows.map((e=>shapeRow(e,s)))},selectFields=(e=[],s=[],r=!1)=>s.length?r?e.map((e=>shapeGroup(e,s))):e.map((e=>shapeRow(e,s))):e;exports.selectFields=selectFields;
|
|
@@ -20,7 +20,8 @@ require("core-js/modules/esnext.map.some.js");
|
|
|
20
20
|
require("core-js/modules/esnext.map.update.js");
|
|
21
21
|
var jsEnv = _interopRequireWildcard(require("browser-or-node"));
|
|
22
22
|
var _config = require("./config");
|
|
23
|
-
|
|
23
|
+
var e;
|
|
24
|
+
function _interopRequireWildcard(t, r) { if (!r && t && t.__esModule) return t; var n, a, o = Object.defineProperty, f = { __proto__: null, default: t }; if (Object(t) !== t) return f; if (e || "function" != typeof WeakMap || (e = new WeakMap()), e) { if (e.has(t)) return e.get(t); e.set(t, f); } for (a in t) "default" !== a && {}.hasOwnProperty.call(t, a) && ((n = o && Object.getOwnPropertyDescriptor(t, a)) && (n.get || n.set) ? o(f, a, n) : f[a] = t[a]); return f; }
|
|
24
25
|
const queues = new Map();
|
|
25
26
|
/**
|
|
26
27
|
* Run `task` once every earlier task on the same database (the configured databasePath) has finished, so that calls
|
|
@@ -1 +1 @@
|
|
|
1
|
-
"use strict";require("core-js/modules/esnext.weak-map.delete-all.js"),Object.defineProperty(exports,"__esModule",{value:!0}),exports.withDatabaseLock=void 0,require("core-js/modules/esnext.map.delete-all.js"),require("core-js/modules/esnext.map.every.js"),require("core-js/modules/esnext.map.filter.js"),require("core-js/modules/esnext.map.find.js"),require("core-js/modules/esnext.map.find-key.js"),require("core-js/modules/esnext.map.includes.js"),require("core-js/modules/esnext.map.key-of.js"),require("core-js/modules/esnext.map.map-keys.js"),require("core-js/modules/esnext.map.map-values.js"),require("core-js/modules/esnext.map.merge.js"),require("core-js/modules/esnext.map.reduce.js"),require("core-js/modules/esnext.map.some.js"),require("core-js/modules/esnext.map.update.js");var jsEnv=_interopRequireWildcard(require("browser-or-node")),_config=require("./config");function _interopRequireWildcard(
|
|
1
|
+
"use strict";require("core-js/modules/esnext.weak-map.delete-all.js"),Object.defineProperty(exports,"__esModule",{value:!0}),exports.withDatabaseLock=void 0,require("core-js/modules/esnext.map.delete-all.js"),require("core-js/modules/esnext.map.every.js"),require("core-js/modules/esnext.map.filter.js"),require("core-js/modules/esnext.map.find.js"),require("core-js/modules/esnext.map.find-key.js"),require("core-js/modules/esnext.map.includes.js"),require("core-js/modules/esnext.map.key-of.js"),require("core-js/modules/esnext.map.map-keys.js"),require("core-js/modules/esnext.map.map-values.js"),require("core-js/modules/esnext.map.merge.js"),require("core-js/modules/esnext.map.reduce.js"),require("core-js/modules/esnext.map.some.js"),require("core-js/modules/esnext.map.update.js");var e,jsEnv=_interopRequireWildcard(require("browser-or-node")),_config=require("./config");function _interopRequireWildcard(s,r){if(!r&&s&&s.__esModule)return s;var t,a,o=Object.defineProperty,u={__proto__:null,default:s};if(Object(s)!==s)return u;if(e||"function"!=typeof WeakMap||(e=new WeakMap),e){if(e.has(s))return e.get(s);e.set(s,u)}for(a in s)"default"!==a&&{}.hasOwnProperty.call(s,a)&&((t=o&&Object.getOwnPropertyDescriptor(s,a))&&(t.get||t.set)?o(u,a,t):u[a]=s[a]);return u}const queues=new Map,withDatabaseLock=async e=>{if(!jsEnv.isNode)return e();const s=(0,_config.resolveDatabasePath)((0,_config.getSetting)("databasePath","database/")),r=(0,_config.trackDatabaseCall)(),t=queues.get(s)||Promise.resolve();let a;const o=new Promise((e=>{a=e})),u=t.then((()=>o));queues.set(s,u),await t;try{return await e()}finally{r(),a(),queues.get(s)===u&&queues.delete(s)}};exports.withDatabaseLock=withDatabaseLock;
|
|
@@ -2,9 +2,10 @@ import { ParsedQuery } from './parseQuery';
|
|
|
2
2
|
export type ParsedCommand = string | 'delete' | 'insert' | 'read' | 'update';
|
|
3
3
|
export type ParsedEntity = string;
|
|
4
4
|
/**
|
|
5
|
-
*
|
|
5
|
+
* Read the command and record name from the start of a query's head (see splitClauses).
|
|
6
6
|
* @param parsed
|
|
7
7
|
* @param query
|
|
8
|
+
* @returns The rest of the head (a joined record, `.joined`, for findJoinEntity).
|
|
8
9
|
*/
|
|
9
10
|
export declare const findCommand: (parsed: ParsedQuery, query: string) => string;
|
|
10
11
|
//# sourceMappingURL=findCommand.d.ts.map
|
|
@@ -4,12 +4,12 @@ Object.defineProperty(exports, "__esModule", {
|
|
|
4
4
|
value: true
|
|
5
5
|
});
|
|
6
6
|
exports.findCommand = void 0;
|
|
7
|
-
|
|
8
|
-
const commandMatch = /^(delete|insert|read|update)\s+([a-z0-9_-]+)[\w\n]*/i;
|
|
7
|
+
const commandMatch = /^(delete|insert|read|update)\s+([a-z0-9_-]+)/i;
|
|
9
8
|
/**
|
|
10
|
-
*
|
|
9
|
+
* Read the command and record name from the start of a query's head (see splitClauses).
|
|
11
10
|
* @param parsed
|
|
12
11
|
* @param query
|
|
12
|
+
* @returns The rest of the head (a joined record, `.joined`, for findJoinEntity).
|
|
13
13
|
*/
|
|
14
14
|
const findCommand = (parsed, query) => {
|
|
15
15
|
const commandFound = query.match(commandMatch);
|
|
@@ -18,7 +18,7 @@ const findCommand = (parsed, query) => {
|
|
|
18
18
|
if (commandFound) {
|
|
19
19
|
parsed['command'] = commandFound[1].toLowerCase();
|
|
20
20
|
parsed['entity'] = commandFound[2];
|
|
21
|
-
return
|
|
21
|
+
return query.slice(commandFound[0].length).trim();
|
|
22
22
|
}
|
|
23
23
|
return query;
|
|
24
24
|
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
"use strict";Object.defineProperty(exports,"__esModule",{value:!0}),exports.findCommand=void 0;
|
|
1
|
+
"use strict";Object.defineProperty(exports,"__esModule",{value:!0}),exports.findCommand=void 0;const commandMatch=/^(delete|insert|read|update)\s+([a-z0-9_-]+)/i,findCommand=(e,t)=>{const d=t.match(commandMatch);return e.command=void 0,e.entity=void 0,d?(e.command=d[1].toLowerCase(),e.entity=d[2],t.slice(d[0].length).trim()):t};exports.findCommand=findCommand;
|
|
@@ -8,15 +8,14 @@ export type ParsedCondition = {
|
|
|
8
8
|
type?: string;
|
|
9
9
|
};
|
|
10
10
|
/**
|
|
11
|
-
*
|
|
12
|
-
* `
|
|
13
|
-
*
|
|
14
|
-
*
|
|
15
|
-
* outside brackets, so clauses may come in any order; several separate `where`s (or `and where` after another clause)
|
|
16
|
-
* are joined with `and`, as before.
|
|
11
|
+
* Read a where clause body (see splitClauses) into a tree (see ConditionNode): conditions joined with `and` / `or`,
|
|
12
|
+
* `not`, and brackets, nested to any depth. Each condition is `<field> <comparator> <value>`, or `<field> is null`,
|
|
13
|
+
* `is not null`, `exists` or `does not exist`. A comparison with the literal null (`= null`) is refused: it would never
|
|
14
|
+
* match, as null equals nothing (see where).
|
|
17
15
|
* @param parsed
|
|
18
|
-
* @param
|
|
19
|
-
* @
|
|
16
|
+
* @param body
|
|
17
|
+
* @returns The rest of the body, after the expression.
|
|
18
|
+
* @throws {Error} For the errors readExpression and readCondition describe.
|
|
20
19
|
*/
|
|
21
|
-
export declare const findConditions: (parsed: ParsedQuery,
|
|
20
|
+
export declare const findConditions: (parsed: ParsedQuery, body: string) => string;
|
|
22
21
|
//# sourceMappingURL=findConditions.d.ts.map
|
|
@@ -10,15 +10,13 @@ require("core-js/modules/esnext.iterator.flat-map.js");
|
|
|
10
10
|
var _parseLiteralValue = require("./parseLiteralValue");
|
|
11
11
|
var _conditionTree = require("../conditionTree");
|
|
12
12
|
var _maskStrings = require("./maskStrings");
|
|
13
|
+
var _splitClauses = require("./splitClauses");
|
|
13
14
|
// Keywords count only as whole words: in `on t.x = u.color where ...` the `or` is part of the name `color`
|
|
14
15
|
const wordEnd = '(?![a-z0-9_.-])';
|
|
15
16
|
const keyword = words => new RegExp(`^(?:${words})${wordEnd}`, 'i');
|
|
16
17
|
// One condition, at the start of the text: a field, then `is [not] null` / `exists` / `does not exist`, or a comparator
|
|
17
18
|
// and a value (strings and arrays are placeholders by then, see maskStrings)
|
|
18
19
|
const conditionMatch = new RegExp(`^([a-z0-9_-]+\\.?[a-z0-9_-]*)\\s+(?:(is\\s+not\\s+null|is\\s+null|exists|does\\s+not\\s+exist)${wordEnd}|(<>|!=|>=|<=|=|>|<|in|between|like)\\s+(${_maskStrings.placeholderSource}|(${_parseLiteralValue.numberSource})|${_maskStrings.arraySource}|(null)|(true)|(false)))`, 'i');
|
|
19
|
-
// The clause keywords that end a where expression (outside brackets), and `and on` (a join clause's own `and`)
|
|
20
|
-
const expressionEnd = keyword('sort|group|limit|offset|select|merge|on|where|and\\s+on');
|
|
21
|
-
const whereMatch = new RegExp(`(^|[^a-z0-9._-])((?:(and|or)\\s+)?where)${wordEnd}`, 'i');
|
|
22
20
|
/**
|
|
23
21
|
* Read one condition from a match of conditionMatch.
|
|
24
22
|
* @param match
|
|
@@ -62,15 +60,15 @@ const join = (kind, nodes) => {
|
|
|
62
60
|
};
|
|
63
61
|
};
|
|
64
62
|
/**
|
|
65
|
-
* Read one where expression from the
|
|
66
|
-
* first: `or`, `and`, `not`; brackets group.
|
|
63
|
+
* Read one where expression from the start of a where clause body (masked, see maskStrings). Precedence, loosest
|
|
64
|
+
* first: `or`, `and`, `not`; brackets group.
|
|
67
65
|
* @param text
|
|
68
|
-
* @
|
|
69
|
-
* @
|
|
70
|
-
*
|
|
66
|
+
* @returns The expression's tree and where it ends (at the first text that can't carry it on, or the end).
|
|
67
|
+
* @throws {Error} For an unbalanced bracket, empty brackets, an operator with no condition after it, or two conditions
|
|
68
|
+
* with no and/or between them.
|
|
71
69
|
*/
|
|
72
|
-
const readExpression =
|
|
73
|
-
let at =
|
|
70
|
+
const readExpression = text => {
|
|
71
|
+
let at = 0;
|
|
74
72
|
const rest = () => text.slice(at);
|
|
75
73
|
const skipSpace = () => {
|
|
76
74
|
at += rest().length - rest().trimStart().length;
|
|
@@ -93,6 +91,10 @@ const readExpression = (text, start) => {
|
|
|
93
91
|
at += condition[0].length;
|
|
94
92
|
return readCondition(condition);
|
|
95
93
|
}
|
|
94
|
+
// The 2.x `and where` / `or where` inside brackets, where splitClauses doesn't look
|
|
95
|
+
if ((after === 'and' || after === 'or') && keyword('where').test(rest())) {
|
|
96
|
+
throw new Error(`"${after} where" is no longer supported: ${_splitClauses.whereHint}`);
|
|
97
|
+
}
|
|
96
98
|
if (take(keyword('not'))) {
|
|
97
99
|
return {
|
|
98
100
|
not: factor('not')
|
|
@@ -115,11 +117,7 @@ const readExpression = (text, start) => {
|
|
|
115
117
|
const term = after => {
|
|
116
118
|
const nodes = [factor(after)];
|
|
117
119
|
for (;;) {
|
|
118
|
-
|
|
119
|
-
if (keyword('and\\s+on').test(rest())) {
|
|
120
|
-
break;
|
|
121
|
-
}
|
|
122
|
-
const connector = take(keyword('and(?:\\s+where)?'));
|
|
120
|
+
const connector = take(keyword('and'));
|
|
123
121
|
if (!connector) {
|
|
124
122
|
break;
|
|
125
123
|
}
|
|
@@ -130,7 +128,7 @@ const readExpression = (text, start) => {
|
|
|
130
128
|
const expression = after => {
|
|
131
129
|
const nodes = [term(after)];
|
|
132
130
|
for (;;) {
|
|
133
|
-
const connector = take(keyword('or
|
|
131
|
+
const connector = take(keyword('or'));
|
|
134
132
|
if (!connector) {
|
|
135
133
|
break;
|
|
136
134
|
}
|
|
@@ -143,7 +141,7 @@ const readExpression = (text, start) => {
|
|
|
143
141
|
if (rest().startsWith(')')) {
|
|
144
142
|
throw new Error(`Unexpected ) in a where clause: ${shown()}`);
|
|
145
143
|
}
|
|
146
|
-
if (
|
|
144
|
+
if (conditionMatch.test(rest())) {
|
|
147
145
|
throw new Error(`Missing and/or before: ${shown()}`);
|
|
148
146
|
}
|
|
149
147
|
return {
|
|
@@ -152,31 +150,21 @@ const readExpression = (text, start) => {
|
|
|
152
150
|
};
|
|
153
151
|
};
|
|
154
152
|
/**
|
|
155
|
-
*
|
|
156
|
-
* `
|
|
157
|
-
*
|
|
158
|
-
*
|
|
159
|
-
* outside brackets, so clauses may come in any order; several separate `where`s (or `and where` after another clause)
|
|
160
|
-
* are joined with `and`, as before.
|
|
153
|
+
* Read a where clause body (see splitClauses) into a tree (see ConditionNode): conditions joined with `and` / `or`,
|
|
154
|
+
* `not`, and brackets, nested to any depth. Each condition is `<field> <comparator> <value>`, or `<field> is null`,
|
|
155
|
+
* `is not null`, `exists` or `does not exist`. A comparison with the literal null (`= null`) is refused: it would never
|
|
156
|
+
* match, as null equals nothing (see where).
|
|
161
157
|
* @param parsed
|
|
162
|
-
* @param
|
|
163
|
-
* @
|
|
158
|
+
* @param body
|
|
159
|
+
* @returns The rest of the body, after the expression.
|
|
160
|
+
* @throws {Error} For the errors readExpression and readCondition describe.
|
|
164
161
|
*/
|
|
165
|
-
const findConditions = (parsed,
|
|
166
|
-
const
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
const {
|
|
173
|
-
node,
|
|
174
|
-
end
|
|
175
|
-
} = readExpression(query, whereStart + found[2].length);
|
|
176
|
-
expressions.push(node);
|
|
177
|
-
query = `${query.slice(0, whereStart)} ${query.slice(end)}`.replace(/\s+/g, ' ').trim();
|
|
178
|
-
}
|
|
179
|
-
parsed['where'] = expressions.length ? join('and', expressions) : (0, _conditionTree.allOf)([]);
|
|
180
|
-
return query;
|
|
162
|
+
const findConditions = (parsed, body) => {
|
|
163
|
+
const {
|
|
164
|
+
node,
|
|
165
|
+
end
|
|
166
|
+
} = readExpression(body);
|
|
167
|
+
parsed['where'] = node;
|
|
168
|
+
return body.slice(end).trim();
|
|
181
169
|
};
|
|
182
170
|
exports.findConditions = findConditions;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
"use strict";Object.defineProperty(exports,"__esModule",{value:!0}),exports.findConditions=void 0,require("core-js/modules/es.array.includes.js"),require("core-js/modules/esnext.iterator.constructor.js"),require("core-js/modules/esnext.iterator.flat-map.js");var _parseLiteralValue=require("./parseLiteralValue"),_conditionTree=require("../conditionTree"),_maskStrings=require("./maskStrings");const wordEnd="(?![a-z0-9_.-])",keyword=e=>new RegExp(`^(?:${e})${wordEnd}`,"i"),conditionMatch=new RegExp(`^([a-z0-9_-]+\\.?[a-z0-9_-]*)\\s+(?:(is\\s+not\\s+null|is\\s+null|exists|does\\s+not\\s+exist)${wordEnd}|(<>|!=|>=|<=|=|>|<|in|between|like)\\s+(${_maskStrings.placeholderSource}|(${_parseLiteralValue.numberSource})|${_maskStrings.arraySource}|(null)|(true)|(false)))`,"i"),
|
|
1
|
+
"use strict";Object.defineProperty(exports,"__esModule",{value:!0}),exports.findConditions=void 0,require("core-js/modules/es.array.includes.js"),require("core-js/modules/esnext.iterator.constructor.js"),require("core-js/modules/esnext.iterator.flat-map.js");var _parseLiteralValue=require("./parseLiteralValue"),_conditionTree=require("../conditionTree"),_maskStrings=require("./maskStrings"),_splitClauses=require("./splitClauses");const wordEnd="(?![a-z0-9_.-])",keyword=e=>new RegExp(`^(?:${e})${wordEnd}`,"i"),conditionMatch=new RegExp(`^([a-z0-9_-]+\\.?[a-z0-9_-]*)\\s+(?:(is\\s+not\\s+null|is\\s+null|exists|does\\s+not\\s+exist)${wordEnd}|(<>|!=|>=|<=|=|>|<|in|between|like)\\s+(${_maskStrings.placeholderSource}|(${_parseLiteralValue.numberSource})|${_maskStrings.arraySource}|(null)|(true)|(false)))`,"i"),readCondition=e=>{const r=e[1];if(void 0!==e[2])return{property:r,comparator:e[2].toLowerCase().replace(/\s+/g," "),value:null};const n=e[3].toLowerCase(),t=(0,_parseLiteralValue.parseLiteralValue)(e,5);if(null===t)throw new Error(`\`${r} ${n} null\` never matches (null equals nothing, as in SQL): use \`${r} is null\` or \`${r} is not null\``);if("between"===n&&Array.isArray(t)&&t.includes(null))throw new Error(`\`${r} between\` can't have a null bound: it would never match`);return{property:r,comparator:n,value:t}},join=(e,r)=>{const n=r.flatMap((r=>!(0,_conditionTree.isCondition)(r)&&e in r?r[e]:[r]));return 1===n.length?n[0]:"and"===e?{and:n}:{or:n}},readExpression=e=>{let r=0;const n=()=>e.slice(r),t=()=>{r+=n().length-n().trimStart().length},o=e=>{t();const o=n().match(e);if(o)return r+=o[0].length,o[0]},s=()=>(0,_maskStrings.unmaskStrings)(n().trim(),"'"),i=e=>{t();const a=n().match(conditionMatch);if(a)return r+=a[0].length,readCondition(a);if(("and"===e||"or"===e)&&keyword("where").test(n()))throw new Error(`"${e} where" is no longer supported: ${_splitClauses.whereHint}`);if(o(keyword("not")))return{not:i("not")};if(o(/^\(/)){if(t(),n().startsWith(")"))throw new Error("Empty brackets in a where clause");const e=l("(");if(!o(/^\)/))throw new Error("Missing ) "+(n().trim()?`before: ${s()}`:"at the end of the where clause"));return e}throw new Error(`Missing a condition after ${e}${n().trim()?`: ${s()}`:""}`)},a=e=>{const r=[i(e)];for(;;){const e=o(keyword("and"));if(!e)break;r.push(i(e.toLowerCase().replace(/\s+/g," ")))}return join("and",r)},l=e=>{const r=[a(e)];for(;;){const e=o(keyword("or"));if(!e)break;r.push(a(e.toLowerCase().replace(/\s+/g," ")))}return join("or",r)},u=l("where");if(t(),n().startsWith(")"))throw new Error(`Unexpected ) in a where clause: ${s()}`);if(conditionMatch.test(n()))throw new Error(`Missing and/or before: ${s()}`);return{node:u,end:r}},findConditions=(e,r)=>{const{node:n,end:t}=readExpression(r);return e.where=n,r.slice(t).trim()};exports.findConditions=findConditions;
|
|
@@ -1,9 +1,11 @@
|
|
|
1
1
|
import { ParsedQuery } from './parseQuery';
|
|
2
|
-
export type ParsedGroupBy = string;
|
|
2
|
+
export type ParsedGroupBy = string[];
|
|
3
3
|
/**
|
|
4
|
-
*
|
|
4
|
+
* Read a group by clause body (`a, b`, see splitClauses).
|
|
5
5
|
* @param parsed
|
|
6
|
-
* @param
|
|
6
|
+
* @param body
|
|
7
|
+
* @returns The rest of the body, after the last field.
|
|
8
|
+
* @throws {Error} For a field named twice.
|
|
7
9
|
*/
|
|
8
|
-
export declare const findGroupBy: (parsed: ParsedQuery,
|
|
10
|
+
export declare const findGroupBy: (parsed: ParsedQuery, body: string) => string;
|
|
9
11
|
//# sourceMappingURL=findGroupBy.d.ts.map
|
|
@@ -4,19 +4,27 @@ Object.defineProperty(exports, "__esModule", {
|
|
|
4
4
|
value: true
|
|
5
5
|
});
|
|
6
6
|
exports.findGroupBy = void 0;
|
|
7
|
-
|
|
8
|
-
|
|
7
|
+
require("core-js/modules/esnext.iterator.constructor.js");
|
|
8
|
+
require("core-js/modules/esnext.iterator.find.js");
|
|
9
|
+
const groupMatch = /^[a-z0-9._-]+(?:\s*,\s*[a-z0-9._-]+)*/i;
|
|
9
10
|
/**
|
|
10
|
-
*
|
|
11
|
+
* Read a group by clause body (`a, b`, see splitClauses).
|
|
11
12
|
* @param parsed
|
|
12
|
-
* @param
|
|
13
|
+
* @param body
|
|
14
|
+
* @returns The rest of the body, after the last field.
|
|
15
|
+
* @throws {Error} For a field named twice.
|
|
13
16
|
*/
|
|
14
|
-
const findGroupBy = (parsed,
|
|
15
|
-
const groupFound =
|
|
17
|
+
const findGroupBy = (parsed, body) => {
|
|
18
|
+
const groupFound = body.match(groupMatch);
|
|
16
19
|
if (groupFound) {
|
|
17
|
-
|
|
18
|
-
|
|
20
|
+
const fields = groupFound[0].split(/\s*,\s*/);
|
|
21
|
+
const repeated = fields.find((field, index) => fields.indexOf(field) !== index);
|
|
22
|
+
if (repeated) {
|
|
23
|
+
throw new Error(`"${repeated}" is in group by twice`);
|
|
24
|
+
}
|
|
25
|
+
parsed['groupBy'] = fields;
|
|
26
|
+
return body.slice(groupFound[0].length).trim();
|
|
19
27
|
}
|
|
20
|
-
return
|
|
28
|
+
return body;
|
|
21
29
|
};
|
|
22
30
|
exports.findGroupBy = findGroupBy;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
"use strict";Object.defineProperty(exports,"__esModule",{value:!0}),exports.findGroupBy=void 0
|
|
1
|
+
"use strict";Object.defineProperty(exports,"__esModule",{value:!0}),exports.findGroupBy=void 0,require("core-js/modules/esnext.iterator.constructor.js"),require("core-js/modules/esnext.iterator.find.js");const groupMatch=/^[a-z0-9._-]+(?:\s*,\s*[a-z0-9._-]+)*/i,findGroupBy=(r,e)=>{const t=e.match(groupMatch);if(t){const o=t[0].split(/\s*,\s*/),s=o.find(((r,e)=>o.indexOf(r)!==e));if(s)throw new Error(`"${s}" is in group by twice`);return r.groupBy=o,e.slice(t[0].length).trim()}return e};exports.findGroupBy=findGroupBy;
|
|
@@ -3,11 +3,12 @@ export type ParsedInsertRow = {
|
|
|
3
3
|
[field: string]: any;
|
|
4
4
|
};
|
|
5
5
|
/**
|
|
6
|
-
*
|
|
6
|
+
* Read an insert's values clause body (`field = value, field2 = value2`, see splitClauses), the same way
|
|
7
7
|
* findUpdateValues() does for "set". insertEntity() accepts an array of rows for bulk inserts, but
|
|
8
8
|
* a query string only describes a single row for now - wrapped in a one-element array to match.
|
|
9
9
|
* @param parsed
|
|
10
|
-
* @param
|
|
10
|
+
* @param body
|
|
11
|
+
* @returns The rest of the body, after the last assignment.
|
|
11
12
|
*/
|
|
12
|
-
export declare const findInsertValues: (parsed: ParsedQuery,
|
|
13
|
+
export declare const findInsertValues: (parsed: ParsedQuery, body: string) => string;
|
|
13
14
|
//# sourceMappingURL=findInsertValues.d.ts.map
|