json-fs-query 2.3.1 → 3.0.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 +77 -6
- package/browser/jsonFsQuery.js +485 -208
- package/browser/jsonFsQuery.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/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/runQuery.js +5 -4
- package/dist/data/utilities/runQuery.min.js +1 -1
- package/package.json +1 -1
- 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
|
@@ -1 +1 @@
|
|
|
1
|
-
"use strict";Object.defineProperty(exports,"__esModule",{value:!0}),exports.findJoinClauses=void 0;
|
|
1
|
+
"use strict";Object.defineProperty(exports,"__esModule",{value:!0}),exports.findJoinClauses=void 0;const joinClauseMatch=/^([a-z0-9_-]+\.[a-z0-9_-]+)\s+(=|!=|>|<|>=|<=|in|between|like)\s+([a-z0-9_-]+\.[a-z0-9_-]+)(?![a-z0-9._-])/i,nextMatch=/^and\s+on\s+/i,findJoinClauses=(e,t)=>{let s=t;for(let t=s.match(joinClauseMatch);t;t=s.match(joinClauseMatch)){e.joinClauses.push({propertyA:t[1],comparator:t[2],propertyB:t[3]}),s=s.slice(t[0].length).trim();const a=s.match(nextMatch);if(!a||!joinClauseMatch.test(s.slice(a[0].length)))break;s=s.slice(a[0].length)}return s};exports.findJoinClauses=findJoinClauses;
|
|
@@ -4,12 +4,10 @@ Object.defineProperty(exports, "__esModule", {
|
|
|
4
4
|
value: true
|
|
5
5
|
});
|
|
6
6
|
exports.findJoinEntity = void 0;
|
|
7
|
-
|
|
8
|
-
// Only straight after the entity (findCommand leaves `.joined ...`): a `.` later on is a number's (`1.5`) or a
|
|
9
|
-
// condition's `entity.field`, not the join
|
|
7
|
+
// What findCommand leaves of the head: `.joined`
|
|
10
8
|
const joinEntityMatch = /^\.([a-z0-9_-]+)/i;
|
|
11
9
|
/**
|
|
12
|
-
*
|
|
10
|
+
* Read the joined record from what findCommand left of the head.
|
|
13
11
|
* @param parsed
|
|
14
12
|
* @param query
|
|
15
13
|
*/
|
|
@@ -17,7 +15,7 @@ const findJoinEntity = (parsed, query) => {
|
|
|
17
15
|
const joinEntityFound = query.match(joinEntityMatch);
|
|
18
16
|
if (joinEntityFound) {
|
|
19
17
|
parsed['joinEntity'] = joinEntityFound ? joinEntityFound[1] : undefined;
|
|
20
|
-
return
|
|
18
|
+
return query.slice(joinEntityFound[0].length).trim();
|
|
21
19
|
}
|
|
22
20
|
return query;
|
|
23
21
|
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
"use strict";Object.defineProperty(exports,"__esModule",{value:!0}),exports.findJoinEntity=void 0;
|
|
1
|
+
"use strict";Object.defineProperty(exports,"__esModule",{value:!0}),exports.findJoinEntity=void 0;const joinEntityMatch=/^\.([a-z0-9_-]+)/i,findJoinEntity=(t,i)=>{const n=i.match(joinEntityMatch);return n?(t.joinEntity=n?n[1]:void 0,i.slice(n[0].length).trim()):i};exports.findJoinEntity=findJoinEntity;
|
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
import { ParsedQuery } from './parseQuery';
|
|
2
2
|
export type ParsedLimit = number;
|
|
3
3
|
/**
|
|
4
|
-
*
|
|
4
|
+
* Read a limit clause body (a whole number, see splitClauses).
|
|
5
5
|
* @param parsed
|
|
6
|
-
* @param
|
|
6
|
+
* @param body
|
|
7
|
+
* @returns The rest of the body, after the number.
|
|
7
8
|
*/
|
|
8
|
-
export declare const findLimit: (parsed: ParsedQuery,
|
|
9
|
+
export declare const findLimit: (parsed: ParsedQuery, body: string) => string;
|
|
9
10
|
//# sourceMappingURL=findLimit.d.ts.map
|
|
@@ -4,19 +4,19 @@ Object.defineProperty(exports, "__esModule", {
|
|
|
4
4
|
value: true
|
|
5
5
|
});
|
|
6
6
|
exports.findLimit = void 0;
|
|
7
|
-
|
|
8
|
-
const limitMatch = /limit\s*(\d+)/i;
|
|
7
|
+
const limitMatch = /^(\d+)/;
|
|
9
8
|
/**
|
|
10
|
-
*
|
|
9
|
+
* Read a limit clause body (a whole number, see splitClauses).
|
|
11
10
|
* @param parsed
|
|
12
|
-
* @param
|
|
11
|
+
* @param body
|
|
12
|
+
* @returns The rest of the body, after the number.
|
|
13
13
|
*/
|
|
14
|
-
const findLimit = (parsed,
|
|
15
|
-
const limitFound =
|
|
14
|
+
const findLimit = (parsed, body) => {
|
|
15
|
+
const limitFound = body.match(limitMatch);
|
|
16
16
|
if (limitFound) {
|
|
17
17
|
parsed['limit'] = limitFound ? parseInt(limitFound[1]) : undefined;
|
|
18
|
-
return
|
|
18
|
+
return body.slice(limitFound[0].length).trim();
|
|
19
19
|
}
|
|
20
|
-
return
|
|
20
|
+
return body;
|
|
21
21
|
};
|
|
22
22
|
exports.findLimit = findLimit;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
"use strict";Object.defineProperty(exports,"__esModule",{value:!0}),exports.findLimit=void 0;
|
|
1
|
+
"use strict";Object.defineProperty(exports,"__esModule",{value:!0}),exports.findLimit=void 0;const limitMatch=/^(\d+)/,findLimit=(i,t)=>{const e=t.match(limitMatch);return e?(i.limit=e?parseInt(e[1]):void 0,t.slice(e[0].length).trim()):t};exports.findLimit=findLimit;
|
|
@@ -4,9 +4,10 @@ export type ParsedMergeJoin = {
|
|
|
4
4
|
propertyB: string;
|
|
5
5
|
};
|
|
6
6
|
/**
|
|
7
|
-
*
|
|
7
|
+
* Read a merge clause body (`a.x with b.y merge c.z with d.w`, see splitClauses).
|
|
8
8
|
* @param parsed
|
|
9
|
-
* @param
|
|
9
|
+
* @param body
|
|
10
|
+
* @returns The rest of the body, after the last merge.
|
|
10
11
|
*/
|
|
11
|
-
export declare const findMergeJoins: (parsed: ParsedQuery,
|
|
12
|
+
export declare const findMergeJoins: (parsed: ParsedQuery, body: string) => string;
|
|
12
13
|
//# sourceMappingURL=findMergeJoins.d.ts.map
|
|
@@ -4,23 +4,30 @@ Object.defineProperty(exports, "__esModule", {
|
|
|
4
4
|
value: true
|
|
5
5
|
});
|
|
6
6
|
exports.findMergeJoins = void 0;
|
|
7
|
-
|
|
8
|
-
const mergeJoinMatch =
|
|
7
|
+
// One merge, at the start of the text; every one after the first starts with `merge` or `and merge` (see splitClauses)
|
|
8
|
+
const mergeJoinMatch = /^([a-z0-9_-]+\.[a-z0-9_-]+)\s+with\s+([a-z0-9_-]+\.[a-z0-9_-]+)(?![a-z0-9._-])/i;
|
|
9
|
+
const nextMatch = /^(?:and\s+)?merge\s+/i;
|
|
9
10
|
/**
|
|
10
|
-
*
|
|
11
|
+
* Read a merge clause body (`a.x with b.y merge c.z with d.w`, see splitClauses).
|
|
11
12
|
* @param parsed
|
|
12
|
-
* @param
|
|
13
|
+
* @param body
|
|
14
|
+
* @returns The rest of the body, after the last merge.
|
|
13
15
|
*/
|
|
14
|
-
const findMergeJoins = (parsed,
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
for (const mergeJoin of mergeJoinsFound) {
|
|
16
|
+
const findMergeJoins = (parsed, body) => {
|
|
17
|
+
let rest = body;
|
|
18
|
+
for (let mergeJoin = rest.match(mergeJoinMatch); mergeJoin; mergeJoin = rest.match(mergeJoinMatch)) {
|
|
18
19
|
parsed['mergeJoins'].push({
|
|
19
|
-
propertyA: mergeJoin[
|
|
20
|
-
propertyB: mergeJoin[
|
|
20
|
+
propertyA: mergeJoin[1],
|
|
21
|
+
propertyB: mergeJoin[2]
|
|
21
22
|
});
|
|
22
|
-
|
|
23
|
+
rest = rest.slice(mergeJoin[0].length).trim();
|
|
24
|
+
// The connector only with another one after it, so a bad one is shown with its connector
|
|
25
|
+
const next = rest.match(nextMatch);
|
|
26
|
+
if (!next || !mergeJoinMatch.test(rest.slice(next[0].length))) {
|
|
27
|
+
break;
|
|
28
|
+
}
|
|
29
|
+
rest = rest.slice(next[0].length);
|
|
23
30
|
}
|
|
24
|
-
return
|
|
31
|
+
return rest;
|
|
25
32
|
};
|
|
26
33
|
exports.findMergeJoins = findMergeJoins;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
"use strict";Object.defineProperty(exports,"__esModule",{value:!0}),exports.findMergeJoins=void 0;
|
|
1
|
+
"use strict";Object.defineProperty(exports,"__esModule",{value:!0}),exports.findMergeJoins=void 0;const mergeJoinMatch=/^([a-z0-9_-]+\.[a-z0-9_-]+)\s+with\s+([a-z0-9_-]+\.[a-z0-9_-]+)(?![a-z0-9._-])/i,nextMatch=/^(?:and\s+)?merge\s+/i,findMergeJoins=(e,t)=>{let r=t;for(let t=r.match(mergeJoinMatch);t;t=r.match(mergeJoinMatch)){e.mergeJoins.push({propertyA:t[1],propertyB:t[2]}),r=r.slice(t[0].length).trim();const i=r.match(nextMatch);if(!i||!mergeJoinMatch.test(r.slice(i[0].length)))break;r=r.slice(i[0].length)}return r};exports.findMergeJoins=findMergeJoins;
|
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
import { ParsedQuery } from './parseQuery';
|
|
2
2
|
export type ParsedOffset = number;
|
|
3
3
|
/**
|
|
4
|
-
*
|
|
4
|
+
* Read a offset clause body (a whole number, see splitClauses).
|
|
5
5
|
* @param parsed
|
|
6
|
-
* @param
|
|
6
|
+
* @param body
|
|
7
|
+
* @returns The rest of the body, after the number.
|
|
7
8
|
*/
|
|
8
|
-
export declare const findOffset: (parsed: ParsedQuery,
|
|
9
|
+
export declare const findOffset: (parsed: ParsedQuery, body: string) => string;
|
|
9
10
|
//# sourceMappingURL=findOffset.d.ts.map
|
|
@@ -4,19 +4,19 @@ Object.defineProperty(exports, "__esModule", {
|
|
|
4
4
|
value: true
|
|
5
5
|
});
|
|
6
6
|
exports.findOffset = void 0;
|
|
7
|
-
|
|
8
|
-
const offsetMatch = /offset\s*(\d+)/i;
|
|
7
|
+
const offsetMatch = /^(\d+)/;
|
|
9
8
|
/**
|
|
10
|
-
*
|
|
9
|
+
* Read a offset clause body (a whole number, see splitClauses).
|
|
11
10
|
* @param parsed
|
|
12
|
-
* @param
|
|
11
|
+
* @param body
|
|
12
|
+
* @returns The rest of the body, after the number.
|
|
13
13
|
*/
|
|
14
|
-
const findOffset = (parsed,
|
|
15
|
-
const offsetFound =
|
|
14
|
+
const findOffset = (parsed, body) => {
|
|
15
|
+
const offsetFound = body.match(offsetMatch);
|
|
16
16
|
if (offsetFound) {
|
|
17
17
|
parsed['offset'] = offsetFound ? parseInt(offsetFound[1]) : undefined;
|
|
18
|
-
return
|
|
18
|
+
return body.slice(offsetFound[0].length).trim();
|
|
19
19
|
}
|
|
20
|
-
return
|
|
20
|
+
return body;
|
|
21
21
|
};
|
|
22
22
|
exports.findOffset = findOffset;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
"use strict";Object.defineProperty(exports,"__esModule",{value:!0}),exports.findOffset=void 0;
|
|
1
|
+
"use strict";Object.defineProperty(exports,"__esModule",{value:!0}),exports.findOffset=void 0;const offsetMatch=/^(\d+)/,findOffset=(t,e)=>{const f=e.match(offsetMatch);return f?(t.offset=f?parseInt(f[1]):void 0,e.slice(f[0].length).trim()):e};exports.findOffset=findOffset;
|
|
@@ -4,9 +4,10 @@ export type ParsedSelect = {
|
|
|
4
4
|
alias: string | undefined;
|
|
5
5
|
};
|
|
6
6
|
/**
|
|
7
|
-
*
|
|
7
|
+
* Read a select clause body (`a, b as c`, see splitClauses).
|
|
8
8
|
* @param parsed
|
|
9
|
-
* @param
|
|
9
|
+
* @param body
|
|
10
|
+
* @returns The rest of the body, after the last field.
|
|
10
11
|
*/
|
|
11
|
-
export declare const findSelects: (parsed: ParsedQuery,
|
|
12
|
+
export declare const findSelects: (parsed: ParsedQuery, body: string) => string;
|
|
12
13
|
//# sourceMappingURL=findSelects.d.ts.map
|
|
@@ -4,30 +4,29 @@ Object.defineProperty(exports, "__esModule", {
|
|
|
4
4
|
value: true
|
|
5
5
|
});
|
|
6
6
|
exports.findSelects = void 0;
|
|
7
|
-
|
|
8
|
-
// One field is a name, then optionally `as <alias>` (`as` as a whole word); fields are separated by commas. The first
|
|
9
|
-
// field used to accept an alias without `as`, so in `select name where a = 1` the word `where` became the alias.
|
|
7
|
+
// One field is a name, then optionally `as <alias>` (`as` as a whole word); fields are separated by commas
|
|
10
8
|
const selectField = '[a-z0-9=._-]+(?:\\s+as\\s+[a-z0-9_-]+)?';
|
|
11
|
-
const
|
|
12
|
-
const
|
|
9
|
+
const selectsMatch = new RegExp(`^${selectField}(?:\\s*,\\s*${selectField})*`, 'i');
|
|
10
|
+
const selectFieldMatch = /,?\s*([a-z0-9=._-]+)(?:\s+as\s+([a-z0-9_-]+))?/ig;
|
|
13
11
|
/**
|
|
14
|
-
*
|
|
12
|
+
* Read a select clause body (`a, b as c`, see splitClauses).
|
|
15
13
|
* @param parsed
|
|
16
|
-
* @param
|
|
14
|
+
* @param body
|
|
15
|
+
* @returns The rest of the body, after the last field.
|
|
17
16
|
*/
|
|
18
|
-
const findSelects = (parsed,
|
|
19
|
-
const selectsFound =
|
|
17
|
+
const findSelects = (parsed, body) => {
|
|
18
|
+
const selectsFound = body.match(selectsMatch);
|
|
20
19
|
if (selectsFound) {
|
|
21
|
-
const selectClausesFound = selectsFound[0].matchAll(
|
|
20
|
+
const selectClausesFound = selectsFound[0].matchAll(selectFieldMatch);
|
|
22
21
|
// @ts-ignore
|
|
23
22
|
for (const selectClause of selectClausesFound) {
|
|
24
23
|
parsed['selectClauses'].push({
|
|
25
|
-
property: selectClause[
|
|
26
|
-
alias: selectClause[
|
|
24
|
+
property: selectClause[1],
|
|
25
|
+
alias: selectClause[2]
|
|
27
26
|
});
|
|
28
27
|
}
|
|
29
|
-
return
|
|
28
|
+
return body.slice(selectsFound[0].length).trim();
|
|
30
29
|
}
|
|
31
|
-
return
|
|
30
|
+
return body;
|
|
32
31
|
};
|
|
33
32
|
exports.findSelects = findSelects;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
"use strict";Object.defineProperty(exports,"__esModule",{value:!0}),exports.findSelects=void 0;
|
|
1
|
+
"use strict";Object.defineProperty(exports,"__esModule",{value:!0}),exports.findSelects=void 0;const selectField="[a-z0-9=._-]+(?:\\s+as\\s+[a-z0-9_-]+)?",selectsMatch=new RegExp(`^${selectField}(?:\\s*,\\s*${selectField})*`,"i"),selectFieldMatch=/,?\s*([a-z0-9=._-]+)(?:\s+as\s+([a-z0-9_-]+))?/gi,findSelects=(e,s)=>{const t=s.match(selectsMatch);if(t){const c=t[0].matchAll(selectFieldMatch);for(const s of c)e.selectClauses.push({property:s[1],alias:s[2]});return s.slice(t[0].length).trim()}return s};exports.findSelects=findSelects;
|
|
@@ -5,9 +5,10 @@ export type ParsedSortClause = {
|
|
|
5
5
|
type?: string;
|
|
6
6
|
};
|
|
7
7
|
/**
|
|
8
|
-
*
|
|
8
|
+
* Read a sort clause body (`a, b desc`, see splitClauses).
|
|
9
9
|
* @param parsed
|
|
10
|
-
* @param
|
|
10
|
+
* @param body
|
|
11
|
+
* @returns The rest of the body, after the last rule.
|
|
11
12
|
*/
|
|
12
|
-
export declare const findSortClauses: (parsed: ParsedQuery,
|
|
13
|
+
export declare const findSortClauses: (parsed: ParsedQuery, body: string) => string;
|
|
13
14
|
//# sourceMappingURL=findSortClauses.d.ts.map
|
|
@@ -4,30 +4,30 @@ Object.defineProperty(exports, "__esModule", {
|
|
|
4
4
|
value: true
|
|
5
5
|
});
|
|
6
6
|
exports.findSortClauses = void 0;
|
|
7
|
-
var _removeFromQuery = require("./removeFromQuery");
|
|
8
7
|
// One rule is a field, then optionally asc or desc as a whole word. Rules are separated by commas, so the list ends
|
|
9
|
-
// at the first word that doesn't follow a comma: in `sort a
|
|
8
|
+
// at the first word that doesn't follow a comma: in `sort a b`, `b` is left over.
|
|
10
9
|
const sortRule = '[a-z0-9._-]+(?:\\s+(?:asc|desc)(?![a-z0-9._-]))?';
|
|
11
|
-
const sortMatch = new RegExp(
|
|
12
|
-
const sortRuleMatch =
|
|
10
|
+
const sortMatch = new RegExp(`^${sortRule}(?:\\s*,\\s*${sortRule})*`, 'i');
|
|
11
|
+
const sortRuleMatch = /,?\s*([a-z0-9._-]+)(?:\s+(asc|desc)(?![a-z0-9._-]))?/ig;
|
|
13
12
|
/**
|
|
14
|
-
*
|
|
13
|
+
* Read a sort clause body (`a, b desc`, see splitClauses).
|
|
15
14
|
* @param parsed
|
|
16
|
-
* @param
|
|
15
|
+
* @param body
|
|
16
|
+
* @returns The rest of the body, after the last rule.
|
|
17
17
|
*/
|
|
18
|
-
const findSortClauses = (parsed,
|
|
19
|
-
const sortFound =
|
|
18
|
+
const findSortClauses = (parsed, body) => {
|
|
19
|
+
const sortFound = body.match(sortMatch);
|
|
20
20
|
if (sortFound) {
|
|
21
21
|
const sortRulesFound = sortFound[0].matchAll(sortRuleMatch);
|
|
22
22
|
// @ts-ignore
|
|
23
23
|
for (const sortClause of sortRulesFound) {
|
|
24
24
|
parsed['sortClauses'].push({
|
|
25
|
-
property: sortClause[
|
|
26
|
-
direction: (sortClause[
|
|
25
|
+
property: sortClause[1],
|
|
26
|
+
direction: (sortClause[2] || 'asc').toLowerCase()
|
|
27
27
|
});
|
|
28
28
|
}
|
|
29
|
-
return
|
|
29
|
+
return body.slice(sortFound[0].length).trim();
|
|
30
30
|
}
|
|
31
|
-
return
|
|
31
|
+
return body;
|
|
32
32
|
};
|
|
33
33
|
exports.findSortClauses = findSortClauses;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
"use strict";Object.defineProperty(exports,"__esModule",{value:!0}),exports.findSortClauses=void 0;
|
|
1
|
+
"use strict";Object.defineProperty(exports,"__esModule",{value:!0}),exports.findSortClauses=void 0;const sortRule="[a-z0-9._-]+(?:\\s+(?:asc|desc)(?![a-z0-9._-]))?",sortMatch=new RegExp(`^${sortRule}(?:\\s*,\\s*${sortRule})*`,"i"),sortRuleMatch=/,?\s*([a-z0-9._-]+)(?:\s+(asc|desc)(?![a-z0-9._-]))?/gi,findSortClauses=(s,t)=>{const e=t.match(sortMatch);if(e){const o=e[0].matchAll(sortRuleMatch);for(const t of o)s.sortClauses.push({property:t[1],direction:(t[2]||"asc").toLowerCase()});return t.slice(e[0].length).trim()}return t};exports.findSortClauses=findSortClauses;
|
|
@@ -3,13 +3,11 @@ export type ParsedUpdateValues = {
|
|
|
3
3
|
[field: string]: any;
|
|
4
4
|
};
|
|
5
5
|
/**
|
|
6
|
-
*
|
|
7
|
-
*
|
|
8
|
-
* be removed from the query as a whole, and so the comma-separated list doesn't get confused with
|
|
9
|
-
* anything that follows, like a where clause), then each individual assignment is parsed out of
|
|
10
|
-
* that captured substring.
|
|
6
|
+
* Read an update's set clause body (`field = value, field2 = value2`, see splitClauses). Uses a two-pass match: the
|
|
7
|
+
* whole comma-separated list first, so anything after it is left over, then each assignment out of that list.
|
|
11
8
|
* @param parsed
|
|
12
|
-
* @param
|
|
9
|
+
* @param body
|
|
10
|
+
* @returns The rest of the body, after the last assignment.
|
|
13
11
|
*/
|
|
14
|
-
export declare const findUpdateValues: (parsed: ParsedQuery,
|
|
12
|
+
export declare const findUpdateValues: (parsed: ParsedQuery, body: string) => string;
|
|
15
13
|
//# sourceMappingURL=findUpdateValues.d.ts.map
|
|
@@ -4,32 +4,29 @@ Object.defineProperty(exports, "__esModule", {
|
|
|
4
4
|
value: true
|
|
5
5
|
});
|
|
6
6
|
exports.findUpdateValues = void 0;
|
|
7
|
-
var _removeFromQuery = require("./removeFromQuery");
|
|
8
7
|
var _parseLiteralValue = require("./parseLiteralValue");
|
|
9
8
|
var _maskStrings = require("./maskStrings");
|
|
10
9
|
const literal = `(?:${_maskStrings.placeholderSource.replace('(', '(?:')}|${_parseLiteralValue.numberSource}|${_maskStrings.arraySource.replace('(', '(?:')}|null|true|false)`;
|
|
11
|
-
const
|
|
10
|
+
const setMatch = new RegExp(`^([a-z0-9_-]+\\s*=\\s*${literal}(?:\\s*,\\s*[a-z0-9_-]+\\s*=\\s*${literal})*)`, 'i');
|
|
12
11
|
const assignmentMatch = new RegExp(`([a-z0-9_-]+)\\s*=\\s*(${_maskStrings.placeholderSource}|(${_parseLiteralValue.numberSource})|${_maskStrings.arraySource}|(null)|(true)|(false))`, 'ig');
|
|
13
12
|
/**
|
|
14
|
-
*
|
|
15
|
-
*
|
|
16
|
-
* be removed from the query as a whole, and so the comma-separated list doesn't get confused with
|
|
17
|
-
* anything that follows, like a where clause), then each individual assignment is parsed out of
|
|
18
|
-
* that captured substring.
|
|
13
|
+
* Read an update's set clause body (`field = value, field2 = value2`, see splitClauses). Uses a two-pass match: the
|
|
14
|
+
* whole comma-separated list first, so anything after it is left over, then each assignment out of that list.
|
|
19
15
|
* @param parsed
|
|
20
|
-
* @param
|
|
16
|
+
* @param body
|
|
17
|
+
* @returns The rest of the body, after the last assignment.
|
|
21
18
|
*/
|
|
22
|
-
const findUpdateValues = (parsed,
|
|
23
|
-
const clauseFound =
|
|
19
|
+
const findUpdateValues = (parsed, body) => {
|
|
20
|
+
const clauseFound = body.match(setMatch);
|
|
24
21
|
parsed['updateValues'] = {};
|
|
25
22
|
if (!clauseFound) {
|
|
26
|
-
return
|
|
23
|
+
return body;
|
|
27
24
|
}
|
|
28
|
-
const assignmentsFound = clauseFound[
|
|
25
|
+
const assignmentsFound = clauseFound[1].matchAll(assignmentMatch);
|
|
29
26
|
// @ts-ignore
|
|
30
27
|
for (const assignment of assignmentsFound) {
|
|
31
28
|
parsed['updateValues'][assignment[1]] = (0, _parseLiteralValue.parseLiteralValue)(assignment, 3);
|
|
32
29
|
}
|
|
33
|
-
return
|
|
30
|
+
return body.slice(clauseFound[0].length).trim();
|
|
34
31
|
};
|
|
35
32
|
exports.findUpdateValues = findUpdateValues;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
"use strict";Object.defineProperty(exports,"__esModule",{value:!0}),exports.findUpdateValues=void 0;var
|
|
1
|
+
"use strict";Object.defineProperty(exports,"__esModule",{value:!0}),exports.findUpdateValues=void 0;var _parseLiteralValue=require("./parseLiteralValue"),_maskStrings=require("./maskStrings");const literal=`(?:${_maskStrings.placeholderSource.replace("(","(?:")}|${_parseLiteralValue.numberSource}|${_maskStrings.arraySource.replace("(","(?:")}|null|true|false)`,setMatch=new RegExp(`^([a-z0-9_-]+\\s*=\\s*${literal}(?:\\s*,\\s*[a-z0-9_-]+\\s*=\\s*${literal})*)`,"i"),assignmentMatch=new RegExp(`([a-z0-9_-]+)\\s*=\\s*(${_maskStrings.placeholderSource}|(${_parseLiteralValue.numberSource})|${_maskStrings.arraySource}|(null)|(true)|(false))`,"ig"),findUpdateValues=(e,a)=>{const r=a.match(setMatch);if(e.updateValues={},!r)return a;const s=r[1].matchAll(assignmentMatch);for(const a of s)e.updateValues[a[1]]=(0,_parseLiteralValue.parseLiteralValue)(a,3);return a.slice(r[0].length).trim()};exports.findUpdateValues=findUpdateValues;
|
|
@@ -4,13 +4,13 @@ Object.defineProperty(exports, "__esModule", {
|
|
|
4
4
|
value: true
|
|
5
5
|
});
|
|
6
6
|
exports.parseQuery = void 0;
|
|
7
|
-
var _siFunciona = _interopRequireDefault(require("si-funciona"));
|
|
8
7
|
var _findCommand = require("./findCommand");
|
|
9
8
|
var _findInsertValues = require("./findInsertValues");
|
|
10
9
|
var _findUpdateValues = require("./findUpdateValues");
|
|
11
10
|
var _findJoinEntity = require("./findJoinEntity");
|
|
12
11
|
var _findSelects = require("./findSelects");
|
|
13
12
|
var _findConditions = require("./findConditions");
|
|
13
|
+
var _conditionTree = require("../conditionTree");
|
|
14
14
|
var _findJoinClauses = require("./findJoinClauses");
|
|
15
15
|
var _findMergeJoins = require("./findMergeJoins");
|
|
16
16
|
var _findSortClauses = require("./findSortClauses");
|
|
@@ -20,8 +20,63 @@ var _findOffset = require("./findOffset");
|
|
|
20
20
|
var _maskStrings = require("./maskStrings");
|
|
21
21
|
var _parseCreate = require("./parseCreate");
|
|
22
22
|
var _parseSchemaStatement = require("./parseSchemaStatement");
|
|
23
|
+
var _splitClauses = require("./splitClauses");
|
|
23
24
|
var _startsQuery = require("./startsQuery");
|
|
24
|
-
|
|
25
|
+
// Each clause's own step, and what its body must start with (for the error when it doesn't)
|
|
26
|
+
const clauseSteps = {
|
|
27
|
+
values: {
|
|
28
|
+
step: _findInsertValues.findInsertValues,
|
|
29
|
+
expected: 'an assignment (field = value)'
|
|
30
|
+
},
|
|
31
|
+
set: {
|
|
32
|
+
step: _findUpdateValues.findUpdateValues,
|
|
33
|
+
expected: 'an assignment (field = value)'
|
|
34
|
+
},
|
|
35
|
+
select: {
|
|
36
|
+
step: _findSelects.findSelects,
|
|
37
|
+
expected: 'a field'
|
|
38
|
+
},
|
|
39
|
+
on: {
|
|
40
|
+
step: _findJoinClauses.findJoinClauses,
|
|
41
|
+
expected: 'a join condition (a.x = b.y)'
|
|
42
|
+
},
|
|
43
|
+
merge: {
|
|
44
|
+
step: _findMergeJoins.findMergeJoins,
|
|
45
|
+
expected: 'a merge (a.x with b.y)'
|
|
46
|
+
},
|
|
47
|
+
where: {
|
|
48
|
+
step: _findConditions.findConditions,
|
|
49
|
+
expected: 'a condition'
|
|
50
|
+
},
|
|
51
|
+
'group by': {
|
|
52
|
+
step: _findGroupBy.findGroupBy,
|
|
53
|
+
expected: 'a field'
|
|
54
|
+
},
|
|
55
|
+
sort: {
|
|
56
|
+
step: _findSortClauses.findSortClauses,
|
|
57
|
+
expected: 'a field'
|
|
58
|
+
},
|
|
59
|
+
limit: {
|
|
60
|
+
step: _findLimit.findLimit,
|
|
61
|
+
expected: 'a whole number'
|
|
62
|
+
},
|
|
63
|
+
offset: {
|
|
64
|
+
step: _findOffset.findOffset,
|
|
65
|
+
expected: 'a whole number'
|
|
66
|
+
}
|
|
67
|
+
};
|
|
68
|
+
/**
|
|
69
|
+
* The error for text a step couldn't read: another query run on without a `;`, or text that doesn't belong.
|
|
70
|
+
* @param rest The text left over, masked
|
|
71
|
+
* @param after What was read before it, masked
|
|
72
|
+
*/
|
|
73
|
+
const leftoverError = (rest, after) => {
|
|
74
|
+
const shown = text => (0, _maskStrings.unmaskStrings)(text, '\'');
|
|
75
|
+
if (_startsQuery.startsQueryMatch.test(rest)) {
|
|
76
|
+
return new Error(`Missing ; before: ${shown(rest)}`);
|
|
77
|
+
}
|
|
78
|
+
return new Error(`Unexpected "${shown(rest)}" after "${shown(after)}"`);
|
|
79
|
+
};
|
|
25
80
|
/**
|
|
26
81
|
* Break a query down into its components.
|
|
27
82
|
* @param query
|
|
@@ -44,10 +99,6 @@ const parseQuery = query => {
|
|
|
44
99
|
create: undefined,
|
|
45
100
|
ifExists: undefined
|
|
46
101
|
};
|
|
47
|
-
const {
|
|
48
|
-
curry,
|
|
49
|
-
pipe
|
|
50
|
-
} = _siFunciona.default;
|
|
51
102
|
// No find* step may see inside a string or an array: each one becomes a placeholder holding its value
|
|
52
103
|
query = (0, _maskStrings.maskArrays)((0, _maskStrings.maskStrings)(query));
|
|
53
104
|
// A create statement has its own shape (a bracketed list of fields and keys), so it gets its own parser
|
|
@@ -65,13 +116,36 @@ const parseQuery = query => {
|
|
|
65
116
|
if (_parseSchemaStatement.schemaStatementMatch.test(query)) {
|
|
66
117
|
return Object.assign(parsedQuery, (0, _parseSchemaStatement.parseSchemaStatement)(query));
|
|
67
118
|
}
|
|
68
|
-
|
|
69
|
-
|
|
119
|
+
// Clauses come at most once each, in a fixed order (see clauseOrder); each step reads only its own clause's body
|
|
120
|
+
const split = (0, _splitClauses.splitClauses)(query);
|
|
121
|
+
if (!split) {
|
|
122
|
+
query = query.trim();
|
|
70
123
|
if (_startsQuery.startsQueryMatch.test(query)) {
|
|
71
|
-
throw new Error(`Missing ; before: ${(0, _maskStrings.unmaskStrings)(query
|
|
124
|
+
throw new Error(`Missing ; before: ${(0, _maskStrings.unmaskStrings)(query, '\'')}`);
|
|
72
125
|
}
|
|
73
126
|
throw new Error(`Unrecognized query value: ${(0, _maskStrings.unmaskStrings)(query, '\'')}`);
|
|
74
127
|
}
|
|
128
|
+
(0, _findJoinEntity.findJoinEntity)(parsedQuery, (0, _findCommand.findCommand)(parsedQuery, split.head));
|
|
129
|
+
parsedQuery.where = (0, _conditionTree.allOf)([]);
|
|
130
|
+
if (split.leading) {
|
|
131
|
+
throw leftoverError(split.leading, split.head);
|
|
132
|
+
}
|
|
133
|
+
for (const {
|
|
134
|
+
keyword,
|
|
135
|
+
body
|
|
136
|
+
} of split.clauses) {
|
|
137
|
+
const {
|
|
138
|
+
step,
|
|
139
|
+
expected
|
|
140
|
+
} = clauseSteps[keyword];
|
|
141
|
+
const rest = step(parsedQuery, body);
|
|
142
|
+
if (rest === body) {
|
|
143
|
+
throw new Error(`Missing ${expected} after ${keyword}${body ? `: ${(0, _maskStrings.unmaskStrings)(body, '\'')}` : ''}`);
|
|
144
|
+
}
|
|
145
|
+
if (rest) {
|
|
146
|
+
throw leftoverError(rest, `${keyword} ${body.slice(0, body.length - rest.length).trim()}`);
|
|
147
|
+
}
|
|
148
|
+
}
|
|
75
149
|
return parsedQuery;
|
|
76
150
|
};
|
|
77
151
|
exports.parseQuery = parseQuery;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
"use strict";Object.defineProperty(exports,"__esModule",{value:!0}),exports.parseQuery=void 0;var
|
|
1
|
+
"use strict";Object.defineProperty(exports,"__esModule",{value:!0}),exports.parseQuery=void 0;var _findCommand=require("./findCommand"),_findInsertValues=require("./findInsertValues"),_findUpdateValues=require("./findUpdateValues"),_findJoinEntity=require("./findJoinEntity"),_findSelects=require("./findSelects"),_findConditions=require("./findConditions"),_conditionTree=require("../conditionTree"),_findJoinClauses=require("./findJoinClauses"),_findMergeJoins=require("./findMergeJoins"),_findSortClauses=require("./findSortClauses"),_findGroupBy=require("./findGroupBy"),_findLimit=require("./findLimit"),_findOffset=require("./findOffset"),_maskStrings=require("./maskStrings"),_parseCreate=require("./parseCreate"),_parseSchemaStatement=require("./parseSchemaStatement"),_splitClauses=require("./splitClauses"),_startsQuery=require("./startsQuery");const clauseSteps={values:{step:_findInsertValues.findInsertValues,expected:"an assignment (field = value)"},set:{step:_findUpdateValues.findUpdateValues,expected:"an assignment (field = value)"},select:{step:_findSelects.findSelects,expected:"a field"},on:{step:_findJoinClauses.findJoinClauses,expected:"a join condition (a.x = b.y)"},merge:{step:_findMergeJoins.findMergeJoins,expected:"a merge (a.x with b.y)"},where:{step:_findConditions.findConditions,expected:"a condition"},"group by":{step:_findGroupBy.findGroupBy,expected:"a field"},sort:{step:_findSortClauses.findSortClauses,expected:"a field"},limit:{step:_findLimit.findLimit,expected:"a whole number"},offset:{step:_findOffset.findOffset,expected:"a whole number"}},leftoverError=(e,t)=>{const i=e=>(0,_maskStrings.unmaskStrings)(e,"'");return _startsQuery.startsQueryMatch.test(e)?new Error(`Missing ; before: ${i(e)}`):new Error(`Unexpected "${i(e)}" after "${i(t)}"`)},parseQuery=e=>{const t={command:void 0,entity:void 0,joinEntity:void 0,selectClauses:[],insertValues:[],updateValues:{},where:void 0,joinClauses:[],mergeJoins:[],sortClauses:[],groupBy:void 0,limit:void 0,offset:void 0,create:void 0,ifExists:void 0};if(e=(0,_maskStrings.maskArrays)((0,_maskStrings.maskStrings)(e)),_parseCreate.createMatch.test(e)){const{entity:i,create:r}=(0,_parseCreate.parseCreate)(e);return Object.assign(t,{command:"create",entity:i,create:r})}if(_parseSchemaStatement.schemaStatementMatch.test(e))return Object.assign(t,(0,_parseSchemaStatement.parseSchemaStatement)(e));const i=(0,_splitClauses.splitClauses)(e);if(!i){if(e=e.trim(),_startsQuery.startsQueryMatch.test(e))throw new Error(`Missing ; before: ${(0,_maskStrings.unmaskStrings)(e,"'")}`);throw new Error(`Unrecognized query value: ${(0,_maskStrings.unmaskStrings)(e,"'")}`)}if((0,_findJoinEntity.findJoinEntity)(t,(0,_findCommand.findCommand)(t,i.head)),t.where=(0,_conditionTree.allOf)([]),i.leading)throw leftoverError(i.leading,i.head);for(const{keyword:e,body:r}of i.clauses){const{step:i,expected:s}=clauseSteps[e],n=i(t,r);if(n===r)throw new Error(`Missing ${s} after ${e}${r?`: ${(0,_maskStrings.unmaskStrings)(r,"'")}`:""}`);if(n)throw leftoverError(n,`${e} ${r.slice(0,r.length-n.length).trim()}`)}return t};exports.parseQuery=parseQuery;
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The clauses each command allows, in the order they must come. create, drop, describe and show have their own
|
|
3
|
+
* parsers and never get here.
|
|
4
|
+
*/
|
|
5
|
+
export declare const clauseOrder: {
|
|
6
|
+
[command: string]: string[];
|
|
7
|
+
};
|
|
8
|
+
export declare const whereHint = "use and / or inside one where clause (where a = 1 and b = 2)";
|
|
9
|
+
export type SplitClause = {
|
|
10
|
+
keyword: string;
|
|
11
|
+
body: string;
|
|
12
|
+
};
|
|
13
|
+
export type SplitQuery = {
|
|
14
|
+
command: string;
|
|
15
|
+
head: string;
|
|
16
|
+
leading: string;
|
|
17
|
+
clauses: SplitClause[];
|
|
18
|
+
};
|
|
19
|
+
/**
|
|
20
|
+
* Split a masked query (see maskStrings) into its clauses, reading its top-level words once, left to right. A clause
|
|
21
|
+
* word counts only as a whole word outside brackets, and not where it must be a name: as a clause's first word
|
|
22
|
+
* (`sort limit`), after a comma or `as`, or before a comparator (`where limit = 1`).
|
|
23
|
+
* @param query
|
|
24
|
+
* @returns undefined when the query doesn't start with read, insert, update or delete (left to the find* steps).
|
|
25
|
+
* @throws {Error} For a joined record outside read, a clause the command doesn't allow, a repeated clause, a clause out
|
|
26
|
+
* of order, or the 2.x forms of a second where (`and where`, `or where`, or a plain repeat).
|
|
27
|
+
*/
|
|
28
|
+
export declare const splitClauses: (query: string) => SplitQuery | undefined;
|
|
29
|
+
//# sourceMappingURL=splitClauses.d.ts.map
|