@cap-js/sqlite 0.1.0 → 1.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/CHANGELOG.md +9 -0
- package/README.md +1 -184
- package/cds-plugin.js +5 -0
- package/index.js +1 -1
- package/lib/ReservedWords.json +149 -0
- package/lib/SQLiteService.js +215 -0
- package/package.json +23 -27
- package/cds.js +0 -39
- package/lib/db/DatabaseService.js +0 -101
- package/lib/db/sql/InsertResults.js +0 -87
- package/lib/db/sql/SQLService.js +0 -223
- package/lib/db/sql/copy.js +0 -17
- package/lib/db/sql/cqn2sql.js +0 -515
- package/lib/db/sql/cqn4sql.js +0 -1461
- package/lib/db/sql/deep.js +0 -233
- package/lib/db/sql/func.js +0 -146
- package/lib/db/sql/structuralComparisonOps.js +0 -16
- package/lib/db/sql/utils.js +0 -22
- package/lib/db/sql/workarounds.js +0 -73
- package/lib/db/sqlite/ReservedWords.json +0 -149
- package/lib/db/sqlite/SQLiteService.js +0 -170
- package/lib/ql/cds.infer.js +0 -786
- package/lib/ql/join-tree.js +0 -167
- package/lib/ql/pseudos.js +0 -23
package/lib/ql/join-tree.js
DELETED
|
@@ -1,167 +0,0 @@
|
|
|
1
|
-
'use strict';
|
|
2
|
-
|
|
3
|
-
class Node {
|
|
4
|
-
constructor($refLink, parent, where = null) {
|
|
5
|
-
this.$refLink = $refLink;
|
|
6
|
-
this.parent = parent;
|
|
7
|
-
this.where = where;
|
|
8
|
-
this.children = new Map();
|
|
9
|
-
}
|
|
10
|
-
}
|
|
11
|
-
|
|
12
|
-
class Root {
|
|
13
|
-
constructor(querySource) {
|
|
14
|
-
const [ alias, queryArtifact ] = querySource;
|
|
15
|
-
this.queryArtifact = queryArtifact;
|
|
16
|
-
this.alias = alias;
|
|
17
|
-
this.parent = null;
|
|
18
|
-
this.children = new Map();
|
|
19
|
-
}
|
|
20
|
-
}
|
|
21
|
-
|
|
22
|
-
class JoinTree {
|
|
23
|
-
constructor(sources) {
|
|
24
|
-
this._roots = new Map();
|
|
25
|
-
this.isInitial = true;
|
|
26
|
-
/**
|
|
27
|
-
* A map that holds query aliases which are used during the
|
|
28
|
-
* association to join translation. It is also considered during the
|
|
29
|
-
* where exists expansion.
|
|
30
|
-
*
|
|
31
|
-
* The table aliases are treated case insensitive. The index of each
|
|
32
|
-
* table alias entry, is the capitalized version of the alias.
|
|
33
|
-
*/
|
|
34
|
-
this._queryAliases = new Map();
|
|
35
|
-
Object.entries(sources).forEach( (entry) => {
|
|
36
|
-
const alias = this.addNextAvailableTableAlias(entry[0]);
|
|
37
|
-
this._roots.set(alias, new Root(entry));
|
|
38
|
-
if (entry[1].sources) // respect outer aliases
|
|
39
|
-
this.addAliasesOfSubqueryInFrom(entry[1].sources);
|
|
40
|
-
});
|
|
41
|
-
}
|
|
42
|
-
|
|
43
|
-
/**
|
|
44
|
-
* Recursively drills into subqueries in a query source and
|
|
45
|
-
* adds the aliases of those subqueries to the alias map.
|
|
46
|
-
*
|
|
47
|
-
* @param {object} sources of inferred subquery in from
|
|
48
|
-
*/
|
|
49
|
-
addAliasesOfSubqueryInFrom(sources) {
|
|
50
|
-
Object.entries(sources).forEach( (e) => {
|
|
51
|
-
this.addNextAvailableTableAlias(e[0]);
|
|
52
|
-
if (e[1].sources) // recurse
|
|
53
|
-
this.addAliasesOfSubqueryInFrom(e[1].sources);
|
|
54
|
-
});
|
|
55
|
-
}
|
|
56
|
-
|
|
57
|
-
/**
|
|
58
|
-
* Calculate the next available table alias and add it to
|
|
59
|
-
* the alias map. Returns the alias in original case, appended
|
|
60
|
-
* by an integer if necessary.
|
|
61
|
-
*
|
|
62
|
-
* @param {string} alias
|
|
63
|
-
* @returns the next un-ambigous table alias
|
|
64
|
-
*/
|
|
65
|
-
addNextAvailableTableAlias(alias) {
|
|
66
|
-
const upperAlias = alias.toUpperCase();
|
|
67
|
-
if (this._queryAliases.get(upperAlias)) {
|
|
68
|
-
let j = 2;
|
|
69
|
-
while (this._queryAliases.get(upperAlias + j))
|
|
70
|
-
j += 1;
|
|
71
|
-
alias += j;
|
|
72
|
-
}
|
|
73
|
-
this._queryAliases.set(alias.toUpperCase(), alias);
|
|
74
|
-
return alias;
|
|
75
|
-
}
|
|
76
|
-
|
|
77
|
-
/**
|
|
78
|
-
* Merge a column into the join tree.
|
|
79
|
-
*
|
|
80
|
-
* First, the source of the column is inferred, i.e. the table alias in which the `col` is resolvable.
|
|
81
|
-
* The table alias is the root of this column. Each of the following steps represents a `node` in the join tree.
|
|
82
|
-
* If a `node` is already present in the tree, the current step is replaced by the already merged `node`.
|
|
83
|
-
* This makes sure all references which follow the same path will have the same table alias in the end.
|
|
84
|
-
*
|
|
85
|
-
* @param {object} col the column which shall be merged into the existing join tree
|
|
86
|
-
* @returns {true}
|
|
87
|
-
*/
|
|
88
|
-
mergeColumn(col) {
|
|
89
|
-
if (this.isInitial)
|
|
90
|
-
this.isInitial = false;
|
|
91
|
-
const head = col.$refLinks[0];
|
|
92
|
-
let node = this._roots.get(head.alias);
|
|
93
|
-
let i = 0;
|
|
94
|
-
if (!node) {
|
|
95
|
-
this._roots.forEach( (r) => { // find the correct query source
|
|
96
|
-
if (
|
|
97
|
-
r.queryArtifact === head.target ||
|
|
98
|
-
r.queryArtifact === head.target.target /** might as well be a query for order by */
|
|
99
|
-
)
|
|
100
|
-
node = r;
|
|
101
|
-
});
|
|
102
|
-
}
|
|
103
|
-
else {
|
|
104
|
-
i += 1; // skip first step which is table alias
|
|
105
|
-
}
|
|
106
|
-
|
|
107
|
-
while (i < col.ref.length) {
|
|
108
|
-
const step = col.ref[i];
|
|
109
|
-
const { where } = step;
|
|
110
|
-
const id = where ? step.id + JSON.stringify(where) : step;
|
|
111
|
-
const next = node.children.get(id);
|
|
112
|
-
const $refLink = col.$refLinks[i];
|
|
113
|
-
if (next) { // step already seen before
|
|
114
|
-
node = next;
|
|
115
|
-
col.$refLinks[i] = node.$refLink; // re-set $refLink to point to already merged $refLink
|
|
116
|
-
}
|
|
117
|
-
else {
|
|
118
|
-
if (col.expand && !col.ref[i + 1]) {
|
|
119
|
-
node.$refLink.onlyForeignKeyAccess = false;
|
|
120
|
-
return true;
|
|
121
|
-
}
|
|
122
|
-
const child = new Node($refLink, node, where);
|
|
123
|
-
if (child.$refLink.definition.isAssociation) {
|
|
124
|
-
if (child.where) { // always join relevant
|
|
125
|
-
child.$refLink.onlyForeignKeyAccess = false;
|
|
126
|
-
}
|
|
127
|
-
else {
|
|
128
|
-
child.$refLink.onlyForeignKeyAccess = true;
|
|
129
|
-
}
|
|
130
|
-
child.$refLink.alias = this.addNextAvailableTableAlias($refLink.alias);
|
|
131
|
-
}
|
|
132
|
-
|
|
133
|
-
const foreignKeys = node.$refLink?.definition.foreignKeys;
|
|
134
|
-
if (node.$refLink && (!foreignKeys || !(child.$refLink.alias in foreignKeys)) ) // foreign key access
|
|
135
|
-
node.$refLink.onlyForeignKeyAccess = false;
|
|
136
|
-
|
|
137
|
-
node.children.set(id, child);
|
|
138
|
-
node = child;
|
|
139
|
-
}
|
|
140
|
-
i += 1;
|
|
141
|
-
}
|
|
142
|
-
|
|
143
|
-
return true;
|
|
144
|
-
}
|
|
145
|
-
|
|
146
|
-
/**
|
|
147
|
-
* Search depth-first for the next association in the children's of the given `node` which
|
|
148
|
-
* does not only access foreign keys.
|
|
149
|
-
*
|
|
150
|
-
* @param {Node} node the node from which to search for the next association
|
|
151
|
-
* @returns {Node|null} the node which represents an association. Or null if none was found.
|
|
152
|
-
*/
|
|
153
|
-
findNextAssoc(node) {
|
|
154
|
-
if (node.$refLink.definition.isAssociation && !node.$refLink.onlyForeignKeyAccess)
|
|
155
|
-
return node;
|
|
156
|
-
// recurse on each child node
|
|
157
|
-
for (const child of node.children.values()) {
|
|
158
|
-
const grandChild = this.findNextAssoc(child);
|
|
159
|
-
if (grandChild)
|
|
160
|
-
return grandChild;
|
|
161
|
-
}
|
|
162
|
-
|
|
163
|
-
return null;
|
|
164
|
-
}
|
|
165
|
-
}
|
|
166
|
-
|
|
167
|
-
module.exports = JoinTree;
|
package/lib/ql/pseudos.js
DELETED
|
@@ -1,23 +0,0 @@
|
|
|
1
|
-
'use strict';
|
|
2
|
-
|
|
3
|
-
// REVISIT: we should always return cds.linked elements
|
|
4
|
-
// > e.g. cds.linked({definitions:{pseudos}})
|
|
5
|
-
const pseudos = {
|
|
6
|
-
elements: {
|
|
7
|
-
$user: {
|
|
8
|
-
elements: {
|
|
9
|
-
id: { type: 'cds.String' },
|
|
10
|
-
locale: { type: 'cds.String' }, // deprecated
|
|
11
|
-
tenant: { type: 'cds.String' }, // deprecated
|
|
12
|
-
},
|
|
13
|
-
},
|
|
14
|
-
$now: { type: 'cds.Timestamp' },
|
|
15
|
-
$at: { type: 'cds.Timestamp' },
|
|
16
|
-
$from: { type: 'cds.Timestamp' },
|
|
17
|
-
$to: { type: 'cds.Timestamp' },
|
|
18
|
-
$locale: { type: 'cds.String' },
|
|
19
|
-
$tenant: { type: 'cds.String' },
|
|
20
|
-
},
|
|
21
|
-
};
|
|
22
|
-
|
|
23
|
-
module.exports = { pseudos };
|