@balena/odata-to-abstract-sql 8.0.2 → 9.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/out/odata-to-abstract-sql.d.ts +3 -4
- package/out/odata-to-abstract-sql.js +71 -120
- package/out/odata-to-abstract-sql.js.map +1 -1
- package/package.json +13 -8
- package/.eslintrc.cjs +0 -10
- package/.github/workflows/flowzone.yml +0 -21
- package/.husky/pre-commit +0 -2
- package/.lintstagedrc +0 -5
- package/.versionbot/CHANGELOG.yml +0 -13398
- package/CHANGELOG.md +0 -4415
- package/repo.yml +0 -12
- package/src/odata-to-abstract-sql.ts +0 -2117
- package/test/chai-sql-types.d.ts +0 -25
- package/test/chai-sql.ts +0 -454
- package/test/expand.ts +0 -606
- package/test/filterby.ts +0 -2164
- package/test/model.sbvr +0 -79
- package/test/orderby.ts +0 -544
- package/test/paging.ts +0 -75
- package/test/resource_parsing.ts +0 -773
- package/test/select.ts +0 -418
- package/test/stress.ts +0 -14
- package/test/test.ts +0 -106
- package/tsconfig.js.json +0 -13
- package/tsconfig.json +0 -18
package/test/model.sbvr
DELETED
|
@@ -1,79 +0,0 @@
|
|
|
1
|
-
Term: name
|
|
2
|
-
Concept Type: Short Text (Type)
|
|
3
|
-
|
|
4
|
-
Term: age
|
|
5
|
-
Concept Type: Integer (Type)
|
|
6
|
-
|
|
7
|
-
Term: favourite colour
|
|
8
|
-
Concept Type: Color (Type)
|
|
9
|
-
|
|
10
|
-
Term: hire date
|
|
11
|
-
Concept Type: Date Time (Type)
|
|
12
|
-
|
|
13
|
-
Term: identification type
|
|
14
|
-
Concept Type: Short Text (Type)
|
|
15
|
-
|
|
16
|
-
Term: identification number
|
|
17
|
-
Concept Type: Short Text (Type)
|
|
18
|
-
|
|
19
|
-
Term: licence
|
|
20
|
-
|
|
21
|
-
Fact type: licence has name
|
|
22
|
-
Necessity: each licence has exactly one name
|
|
23
|
-
|
|
24
|
-
Term: team
|
|
25
|
-
Database ID Field: favourite colour
|
|
26
|
-
Fact type: team has favourite colour
|
|
27
|
-
Necessity: each team has exactly one favourite colour
|
|
28
|
-
|
|
29
|
-
Term: plane
|
|
30
|
-
Synonym: aircraft
|
|
31
|
-
|
|
32
|
-
Fact type: plane has name
|
|
33
|
-
Necessity: each plane has exactly one name
|
|
34
|
-
|
|
35
|
-
Term: person
|
|
36
|
-
|
|
37
|
-
Term: pilot
|
|
38
|
-
Concept Type: person
|
|
39
|
-
|
|
40
|
-
Fact type: pilot is experienced
|
|
41
|
-
|
|
42
|
-
Fact type: pilot has name
|
|
43
|
-
Necessity: each pilot has exactly one name
|
|
44
|
-
|
|
45
|
-
Fact type: pilot has age
|
|
46
|
-
Necessity: each pilot has exactly one age
|
|
47
|
-
|
|
48
|
-
Fact type: pilot has favourite colour
|
|
49
|
-
Necessity: each pilot has exactly one favourite colour
|
|
50
|
-
|
|
51
|
-
Fact type: pilot can fly plane
|
|
52
|
-
Synonymous Form: plane can be flown by pilot
|
|
53
|
-
|
|
54
|
-
Fact type: pilot is on team
|
|
55
|
-
Synonymous Form: team includes pilot
|
|
56
|
-
Necessity: each pilot is on exactly one team
|
|
57
|
-
|
|
58
|
-
Fact type: pilot has licence
|
|
59
|
-
Necessity: each pilot has exactly one licence
|
|
60
|
-
|
|
61
|
-
Fact type: pilot has hire date
|
|
62
|
-
Necessity: each pilot has exactly one hire date
|
|
63
|
-
|
|
64
|
-
Fact type: pilot has identification type
|
|
65
|
-
Term Form: identification method
|
|
66
|
-
Database Table Name: identification method
|
|
67
|
-
|
|
68
|
-
Fact type: identification method has identification number
|
|
69
|
-
Necessity: each identification method has exactly one identification number.
|
|
70
|
-
|
|
71
|
-
Fact type: pilot1 was trained by pilot2
|
|
72
|
-
Synonymous Form: pilot2 trained pilot1
|
|
73
|
-
Necessity: each pilot was trained by exactly one pilot
|
|
74
|
-
|
|
75
|
-
Term: copilot
|
|
76
|
-
Concept Type: pilot
|
|
77
|
-
|
|
78
|
-
Fact Type: copilot assists pilot
|
|
79
|
-
Necessity: each copilot assists at most one pilot
|
package/test/orderby.ts
DELETED
|
@@ -1,544 +0,0 @@
|
|
|
1
|
-
import { expect } from 'chai';
|
|
2
|
-
import {
|
|
3
|
-
operandToAbstractSQLFactory,
|
|
4
|
-
pilotFields,
|
|
5
|
-
teamFields,
|
|
6
|
-
} from './chai-sql';
|
|
7
|
-
import test, { itExpectsError } from './test';
|
|
8
|
-
|
|
9
|
-
const operandToAbstractSQL = operandToAbstractSQLFactory();
|
|
10
|
-
|
|
11
|
-
test('/pilot?$orderby=name', (result) => {
|
|
12
|
-
it('should order by name desc', () => {
|
|
13
|
-
expect(result)
|
|
14
|
-
.to.be.a.query.that.selects(pilotFields)
|
|
15
|
-
.from('pilot')
|
|
16
|
-
.orderby(['DESC', operandToAbstractSQL('name')]);
|
|
17
|
-
});
|
|
18
|
-
});
|
|
19
|
-
|
|
20
|
-
test('/pilot?$orderby=name,age', (result) => {
|
|
21
|
-
it('should order by name desc, age desc', () => {
|
|
22
|
-
expect(result)
|
|
23
|
-
.to.be.a.query.that.selects(pilotFields)
|
|
24
|
-
.from('pilot')
|
|
25
|
-
.orderby(
|
|
26
|
-
['DESC', operandToAbstractSQL('name')],
|
|
27
|
-
['DESC', operandToAbstractSQL('age')],
|
|
28
|
-
);
|
|
29
|
-
});
|
|
30
|
-
});
|
|
31
|
-
|
|
32
|
-
test('/pilot?$orderby=name desc', (result) => {
|
|
33
|
-
it('should order by name desc', () => {
|
|
34
|
-
expect(result)
|
|
35
|
-
.to.be.a.query.that.selects(pilotFields)
|
|
36
|
-
.from('pilot')
|
|
37
|
-
.orderby(['DESC', operandToAbstractSQL('name')]);
|
|
38
|
-
});
|
|
39
|
-
});
|
|
40
|
-
|
|
41
|
-
test('/pilot?$orderby=name asc', (result) => {
|
|
42
|
-
it('should order by name asc', () => {
|
|
43
|
-
expect(result)
|
|
44
|
-
.to.be.a.query.that.selects(pilotFields)
|
|
45
|
-
.from('pilot')
|
|
46
|
-
.orderby(['ASC', operandToAbstractSQL('name')]);
|
|
47
|
-
});
|
|
48
|
-
});
|
|
49
|
-
|
|
50
|
-
test('/pilot?$orderby=p/name asc', (result) => {
|
|
51
|
-
// TODO: This should fail
|
|
52
|
-
it('should order by name asc using a non-existing alias', () => {
|
|
53
|
-
expect(result)
|
|
54
|
-
.to.be.a.query.that.selects(pilotFields)
|
|
55
|
-
.from('pilot')
|
|
56
|
-
.orderby(['ASC', operandToAbstractSQL('name')]);
|
|
57
|
-
});
|
|
58
|
-
});
|
|
59
|
-
|
|
60
|
-
test('/pilot?$orderby=name asc,age desc', (result) => {
|
|
61
|
-
it('should order by name asc, age desc', () => {
|
|
62
|
-
expect(result)
|
|
63
|
-
.to.be.a.query.that.selects(pilotFields)
|
|
64
|
-
.from('pilot')
|
|
65
|
-
.orderby(
|
|
66
|
-
['ASC', operandToAbstractSQL('name')],
|
|
67
|
-
['DESC', operandToAbstractSQL('age')],
|
|
68
|
-
);
|
|
69
|
-
});
|
|
70
|
-
});
|
|
71
|
-
|
|
72
|
-
test('/pilot?$orderby=licence/id asc', (result) => {
|
|
73
|
-
it('should order by licence/id asc', () => {
|
|
74
|
-
expect(result)
|
|
75
|
-
.to.be.a.query.that.selects(pilotFields)
|
|
76
|
-
.from('pilot')
|
|
77
|
-
.leftJoin([
|
|
78
|
-
['licence', 'pilot.licence'],
|
|
79
|
-
[
|
|
80
|
-
'Equals',
|
|
81
|
-
['ReferencedField', 'pilot', 'licence'],
|
|
82
|
-
['ReferencedField', 'pilot.licence', 'id'],
|
|
83
|
-
],
|
|
84
|
-
])
|
|
85
|
-
.where()
|
|
86
|
-
.orderby(['ASC', operandToAbstractSQL('licence/id')]);
|
|
87
|
-
});
|
|
88
|
-
});
|
|
89
|
-
|
|
90
|
-
test('/pilot?$orderby=licence/name asc,licence/id desc', (result) => {
|
|
91
|
-
it('should order by licence/name asc, licence/id desc w/o JOINing the licence twice', () => {
|
|
92
|
-
expect(result)
|
|
93
|
-
.to.be.a.query.that.selects(pilotFields)
|
|
94
|
-
.from('pilot')
|
|
95
|
-
.leftJoin([
|
|
96
|
-
['licence', 'pilot.licence'],
|
|
97
|
-
[
|
|
98
|
-
'Equals',
|
|
99
|
-
['ReferencedField', 'pilot', 'licence'],
|
|
100
|
-
['ReferencedField', 'pilot.licence', 'id'],
|
|
101
|
-
],
|
|
102
|
-
])
|
|
103
|
-
.where()
|
|
104
|
-
.orderby(
|
|
105
|
-
['ASC', operandToAbstractSQL('licence/name')],
|
|
106
|
-
['DESC', operandToAbstractSQL('licence/id')],
|
|
107
|
-
);
|
|
108
|
-
});
|
|
109
|
-
});
|
|
110
|
-
|
|
111
|
-
test('/pilot?$orderby=can_fly__plane/plane/id asc', (result) => {
|
|
112
|
-
it('should order by can_fly__plane/plane/id asc', () => {
|
|
113
|
-
expect(result)
|
|
114
|
-
.to.be.a.query.that.selects(pilotFields)
|
|
115
|
-
.from('pilot')
|
|
116
|
-
.leftJoin(
|
|
117
|
-
[
|
|
118
|
-
['pilot-can fly-plane', 'pilot.pilot-can fly-plane'],
|
|
119
|
-
[
|
|
120
|
-
'Equals',
|
|
121
|
-
['ReferencedField', 'pilot', 'id'],
|
|
122
|
-
['ReferencedField', 'pilot.pilot-can fly-plane', 'pilot'],
|
|
123
|
-
],
|
|
124
|
-
],
|
|
125
|
-
[
|
|
126
|
-
['plane', 'pilot.pilot-can fly-plane.plane'],
|
|
127
|
-
[
|
|
128
|
-
'Equals',
|
|
129
|
-
['ReferencedField', 'pilot.pilot-can fly-plane', 'can fly-plane'],
|
|
130
|
-
['ReferencedField', 'pilot.pilot-can fly-plane.plane', 'id'],
|
|
131
|
-
],
|
|
132
|
-
],
|
|
133
|
-
)
|
|
134
|
-
.orderby(['ASC', operandToAbstractSQL('can_fly__plane/plane/id')]);
|
|
135
|
-
});
|
|
136
|
-
});
|
|
137
|
-
|
|
138
|
-
test('/pilot?$orderby=can_fly__plane/plane/name desc,can_fly__plane/plane/id asc', (result) => {
|
|
139
|
-
it('should order by can_fly__plane/plane/name desc, can_fly__plane/plane/id asc w/o JOINing the resources twice', () => {
|
|
140
|
-
expect(result)
|
|
141
|
-
.to.be.a.query.that.selects(pilotFields)
|
|
142
|
-
.from('pilot')
|
|
143
|
-
.leftJoin(
|
|
144
|
-
[
|
|
145
|
-
['pilot-can fly-plane', 'pilot.pilot-can fly-plane'],
|
|
146
|
-
[
|
|
147
|
-
'Equals',
|
|
148
|
-
['ReferencedField', 'pilot', 'id'],
|
|
149
|
-
['ReferencedField', 'pilot.pilot-can fly-plane', 'pilot'],
|
|
150
|
-
],
|
|
151
|
-
],
|
|
152
|
-
[
|
|
153
|
-
['plane', 'pilot.pilot-can fly-plane.plane'],
|
|
154
|
-
[
|
|
155
|
-
'Equals',
|
|
156
|
-
['ReferencedField', 'pilot.pilot-can fly-plane', 'can fly-plane'],
|
|
157
|
-
['ReferencedField', 'pilot.pilot-can fly-plane.plane', 'id'],
|
|
158
|
-
],
|
|
159
|
-
],
|
|
160
|
-
)
|
|
161
|
-
.where()
|
|
162
|
-
.orderby(
|
|
163
|
-
['DESC', operandToAbstractSQL('can_fly__plane/plane/name')],
|
|
164
|
-
['ASC', operandToAbstractSQL('can_fly__plane/plane/id')],
|
|
165
|
-
);
|
|
166
|
-
});
|
|
167
|
-
});
|
|
168
|
-
|
|
169
|
-
test.skip('/pilot?$orderby=favourite_colour/red', () => {
|
|
170
|
-
it("should order by how red the pilot's favourite colour is");
|
|
171
|
-
});
|
|
172
|
-
|
|
173
|
-
test('/pilot?$orderby=trained__pilot/$count asc', (result) => {
|
|
174
|
-
it('should order pilots by how many other pilots they have trained', () => {
|
|
175
|
-
expect(result)
|
|
176
|
-
.to.be.a.query.that.selects(pilotFields)
|
|
177
|
-
.from('pilot')
|
|
178
|
-
.orderby([
|
|
179
|
-
'ASC',
|
|
180
|
-
[
|
|
181
|
-
'SelectQuery',
|
|
182
|
-
['Select', [['Count', '*']]],
|
|
183
|
-
['From', ['Alias', ['Table', 'pilot'], 'pilot.trained-pilot']],
|
|
184
|
-
[
|
|
185
|
-
'Where',
|
|
186
|
-
[
|
|
187
|
-
'Equals',
|
|
188
|
-
['ReferencedField', 'pilot', 'id'],
|
|
189
|
-
[
|
|
190
|
-
'ReferencedField',
|
|
191
|
-
'pilot.trained-pilot',
|
|
192
|
-
'was trained by-pilot',
|
|
193
|
-
],
|
|
194
|
-
],
|
|
195
|
-
],
|
|
196
|
-
],
|
|
197
|
-
]);
|
|
198
|
-
});
|
|
199
|
-
});
|
|
200
|
-
|
|
201
|
-
test('/pilot?$orderby=trained__pilot/$count($filter=is_experienced eq true) asc', (result) => {
|
|
202
|
-
it('should order pilots by how many other pilots that they have trained are now experienced', () => {
|
|
203
|
-
expect(result)
|
|
204
|
-
.to.be.a.query.that.selects(pilotFields)
|
|
205
|
-
.from('pilot')
|
|
206
|
-
.orderby([
|
|
207
|
-
'ASC',
|
|
208
|
-
[
|
|
209
|
-
'SelectQuery',
|
|
210
|
-
['Select', [['Count', '*']]],
|
|
211
|
-
['From', ['Alias', ['Table', 'pilot'], 'pilot.trained-pilot']],
|
|
212
|
-
[
|
|
213
|
-
'Where',
|
|
214
|
-
[
|
|
215
|
-
'And',
|
|
216
|
-
[
|
|
217
|
-
'Equals',
|
|
218
|
-
['ReferencedField', 'pilot', 'id'],
|
|
219
|
-
[
|
|
220
|
-
'ReferencedField',
|
|
221
|
-
'pilot.trained-pilot',
|
|
222
|
-
'was trained by-pilot',
|
|
223
|
-
],
|
|
224
|
-
],
|
|
225
|
-
[
|
|
226
|
-
'IsNotDistinctFrom',
|
|
227
|
-
['ReferencedField', 'pilot.trained-pilot', 'is experienced'],
|
|
228
|
-
['Bind', 0],
|
|
229
|
-
],
|
|
230
|
-
],
|
|
231
|
-
],
|
|
232
|
-
],
|
|
233
|
-
]);
|
|
234
|
-
});
|
|
235
|
-
});
|
|
236
|
-
|
|
237
|
-
test('/team?$orderby=includes__pilot/$count desc', (result) => {
|
|
238
|
-
it('should order teams by the number of pilots', () => {
|
|
239
|
-
expect(result)
|
|
240
|
-
.to.be.a.query.that.selects(teamFields)
|
|
241
|
-
.from('team')
|
|
242
|
-
.orderby([
|
|
243
|
-
'DESC',
|
|
244
|
-
[
|
|
245
|
-
'SelectQuery',
|
|
246
|
-
['Select', [['Count', '*']]],
|
|
247
|
-
['From', ['Alias', ['Table', 'pilot'], 'team.includes-pilot']],
|
|
248
|
-
[
|
|
249
|
-
'Where',
|
|
250
|
-
[
|
|
251
|
-
'Equals',
|
|
252
|
-
[
|
|
253
|
-
'ReferencedField',
|
|
254
|
-
'team',
|
|
255
|
-
// That's b/c it's the team's `Database ID Field`
|
|
256
|
-
'favourite colour',
|
|
257
|
-
],
|
|
258
|
-
['ReferencedField', 'team.includes-pilot', 'is on-team'],
|
|
259
|
-
],
|
|
260
|
-
],
|
|
261
|
-
],
|
|
262
|
-
]);
|
|
263
|
-
});
|
|
264
|
-
});
|
|
265
|
-
|
|
266
|
-
test('/team?$orderby=includes__pilot/$count($filter=is_experienced eq true) desc', (result) => {
|
|
267
|
-
it('should order teams by the number of pilots that are experienced', () => {
|
|
268
|
-
expect(result)
|
|
269
|
-
.to.be.a.query.that.selects(teamFields)
|
|
270
|
-
.from('team')
|
|
271
|
-
.orderby([
|
|
272
|
-
'DESC',
|
|
273
|
-
[
|
|
274
|
-
'SelectQuery',
|
|
275
|
-
['Select', [['Count', '*']]],
|
|
276
|
-
['From', ['Alias', ['Table', 'pilot'], 'team.includes-pilot']],
|
|
277
|
-
[
|
|
278
|
-
'Where',
|
|
279
|
-
[
|
|
280
|
-
'And',
|
|
281
|
-
[
|
|
282
|
-
'Equals',
|
|
283
|
-
[
|
|
284
|
-
'ReferencedField',
|
|
285
|
-
'team',
|
|
286
|
-
// That's b/c it's the team's `Database ID Field`
|
|
287
|
-
'favourite colour',
|
|
288
|
-
],
|
|
289
|
-
['ReferencedField', 'team.includes-pilot', 'is on-team'],
|
|
290
|
-
],
|
|
291
|
-
[
|
|
292
|
-
'IsNotDistinctFrom',
|
|
293
|
-
['ReferencedField', 'team.includes-pilot', 'is experienced'],
|
|
294
|
-
['Bind', 0],
|
|
295
|
-
],
|
|
296
|
-
],
|
|
297
|
-
],
|
|
298
|
-
],
|
|
299
|
-
]);
|
|
300
|
-
});
|
|
301
|
-
});
|
|
302
|
-
|
|
303
|
-
test('/pilot?$select=name,licence/name&$orderby=name asc,licence/name desc', function (result) {
|
|
304
|
-
it('should select from pilot.name, licence.name, ordered by the pilot name asc and licence name desc w/o JOINing the licence twice', () => {
|
|
305
|
-
expect(result)
|
|
306
|
-
.to.be.a.query.that.selects([
|
|
307
|
-
operandToAbstractSQL('name'),
|
|
308
|
-
operandToAbstractSQL('licence/name'),
|
|
309
|
-
])
|
|
310
|
-
.from('pilot')
|
|
311
|
-
.leftJoin([
|
|
312
|
-
['licence', 'pilot.licence'],
|
|
313
|
-
[
|
|
314
|
-
'Equals',
|
|
315
|
-
['ReferencedField', 'pilot', 'licence'],
|
|
316
|
-
['ReferencedField', 'pilot.licence', 'id'],
|
|
317
|
-
],
|
|
318
|
-
])
|
|
319
|
-
.where()
|
|
320
|
-
.orderby(
|
|
321
|
-
['ASC', operandToAbstractSQL('name')],
|
|
322
|
-
['DESC', operandToAbstractSQL('licence/name')],
|
|
323
|
-
);
|
|
324
|
-
});
|
|
325
|
-
});
|
|
326
|
-
|
|
327
|
-
test(`/pilot?$orderby=identification_method(1)/identification_number desc`, (result) => {
|
|
328
|
-
it('should fail to order pilots by their passport number when using a primitive key', () => {
|
|
329
|
-
expect(result)
|
|
330
|
-
.to.be.instanceOf(SyntaxError)
|
|
331
|
-
.and.to.have.property(
|
|
332
|
-
'message',
|
|
333
|
-
'Using a key bind after a navigation expression is not supported.',
|
|
334
|
-
);
|
|
335
|
-
});
|
|
336
|
-
});
|
|
337
|
-
|
|
338
|
-
test(`/pilot?$orderby=identification_method(pilot=1)/identification_number desc`, (result) => {
|
|
339
|
-
it('should fail to order by an associated resource when providing the navigated FK of the associated resource as the only part of the alternate key', () => {
|
|
340
|
-
expect(result)
|
|
341
|
-
.to.be.instanceOf(SyntaxError)
|
|
342
|
-
.and.to.have.property(
|
|
343
|
-
'message',
|
|
344
|
-
'Specified already navigated field as part of key: pilot',
|
|
345
|
-
);
|
|
346
|
-
});
|
|
347
|
-
});
|
|
348
|
-
|
|
349
|
-
test(`/pilot?$orderby=identification_method(pilot=1,identification_type='passport')/identification_number desc`, (result) => {
|
|
350
|
-
it('should fail to order by an associated resource when providing the navigated FK of the associated resource as part of the alternate key', () => {
|
|
351
|
-
expect(result)
|
|
352
|
-
.to.be.instanceOf(SyntaxError)
|
|
353
|
-
.and.to.have.property(
|
|
354
|
-
'message',
|
|
355
|
-
'Specified already navigated field as part of key: pilot',
|
|
356
|
-
);
|
|
357
|
-
});
|
|
358
|
-
});
|
|
359
|
-
|
|
360
|
-
test(`/pilot?$orderby=identification_method(identification_type='passport') desc`, (result) => {
|
|
361
|
-
it('should fail to order by an associated resource when not defining the associated resource field', () => {
|
|
362
|
-
expect(result)
|
|
363
|
-
.to.be.instanceOf(SyntaxError)
|
|
364
|
-
.and.to.have.property(
|
|
365
|
-
'message',
|
|
366
|
-
'Attempted to directly fetch a virtual field: "identification_method"',
|
|
367
|
-
);
|
|
368
|
-
});
|
|
369
|
-
});
|
|
370
|
-
|
|
371
|
-
test(`/pilot?$orderby=identification_method(not_a_field='12345')/identification_number desc`, (result) => {
|
|
372
|
-
it('should fail to order pilots when the field provided as an alternate key does not exist', () => {
|
|
373
|
-
expect(result)
|
|
374
|
-
.to.be.instanceOf(SyntaxError)
|
|
375
|
-
.and.to.have.property(
|
|
376
|
-
'message',
|
|
377
|
-
'Specified non-existent field for path key',
|
|
378
|
-
);
|
|
379
|
-
});
|
|
380
|
-
});
|
|
381
|
-
|
|
382
|
-
test(`/pilot?$orderby=identification_method(identification_number='12345')/identification_number desc`, (result) => {
|
|
383
|
-
it('should fail to order pilots when the field provided as an alternate key does not complete a natural key when combined with the navigation field', () => {
|
|
384
|
-
expect(result)
|
|
385
|
-
.to.be.instanceOf(SyntaxError)
|
|
386
|
-
.and.to.have.property(
|
|
387
|
-
'message',
|
|
388
|
-
'Specified fields for path key that are not directly unique',
|
|
389
|
-
);
|
|
390
|
-
});
|
|
391
|
-
});
|
|
392
|
-
|
|
393
|
-
test(`/pilot?$orderby=identification_method(identification_type='passport',identification_number='12345')/identification_number desc`, (result) => {
|
|
394
|
-
it('should fail to order pilots when the field provided as an alternate key does not complete a natural key when combined with the navigation field', () => {
|
|
395
|
-
expect(result)
|
|
396
|
-
.to.be.instanceOf(SyntaxError)
|
|
397
|
-
.and.to.have.property(
|
|
398
|
-
'message',
|
|
399
|
-
'Specified fields for path key that are not directly unique',
|
|
400
|
-
);
|
|
401
|
-
});
|
|
402
|
-
});
|
|
403
|
-
|
|
404
|
-
test(`/pilot?$orderby=identification_method(identification_type='passport')/identification_number desc`, (result) => {
|
|
405
|
-
it('should order pilots by their passport number when using part of the alternate key and infering the rest from the navigation', () => {
|
|
406
|
-
expect(result)
|
|
407
|
-
.to.be.a.query.that.selects(pilotFields)
|
|
408
|
-
.from('pilot')
|
|
409
|
-
.leftJoin([
|
|
410
|
-
['identification method', 'pilot.identification method'],
|
|
411
|
-
[
|
|
412
|
-
'And',
|
|
413
|
-
[
|
|
414
|
-
'Equals',
|
|
415
|
-
['ReferencedField', 'pilot', 'id'],
|
|
416
|
-
['ReferencedField', 'pilot.identification method', 'pilot'],
|
|
417
|
-
],
|
|
418
|
-
[
|
|
419
|
-
'IsNotDistinctFrom',
|
|
420
|
-
[
|
|
421
|
-
'ReferencedField',
|
|
422
|
-
'pilot.identification method',
|
|
423
|
-
'identification type',
|
|
424
|
-
],
|
|
425
|
-
['Bind', 0],
|
|
426
|
-
],
|
|
427
|
-
],
|
|
428
|
-
])
|
|
429
|
-
.orderby([
|
|
430
|
-
'DESC',
|
|
431
|
-
[
|
|
432
|
-
'ReferencedField',
|
|
433
|
-
'pilot.identification method',
|
|
434
|
-
'identification number',
|
|
435
|
-
],
|
|
436
|
-
]);
|
|
437
|
-
});
|
|
438
|
-
});
|
|
439
|
-
|
|
440
|
-
test(`/pilot?$orderby=identification_method(identification_type='passport')/identification_number desc,identification_method(identification_type='id card')/identification_number desc`, (result) => {
|
|
441
|
-
it('should order pilots by their passport number & then their ID when using part of the alternate key and infering the rest from the navigation', () => {
|
|
442
|
-
expect(result)
|
|
443
|
-
.to.be.instanceOf(Error)
|
|
444
|
-
.and.to.have.property(
|
|
445
|
-
'message',
|
|
446
|
-
`Adding JOINs on the same resource with different ON clauses is not supported. Found pilot.identification method`,
|
|
447
|
-
);
|
|
448
|
-
});
|
|
449
|
-
});
|
|
450
|
-
|
|
451
|
-
test(`/pilot?$orderby=identification_method(identification_type='passport')/identification_number desc,identification_method(identification_type='passport')/created_at desc`, (result) => {
|
|
452
|
-
// TODO: This atm doens't work b/c the two JOINs are generated with differnet Bind numbers
|
|
453
|
-
itExpectsError(
|
|
454
|
-
`should order pilots by their passport's creation date and then by its number`,
|
|
455
|
-
() => {
|
|
456
|
-
expect(result)
|
|
457
|
-
.to.be.a.query.that.selects(pilotFields)
|
|
458
|
-
.from('pilot')
|
|
459
|
-
.leftJoin([
|
|
460
|
-
['identification method', 'pilot.identification method'],
|
|
461
|
-
[
|
|
462
|
-
'And',
|
|
463
|
-
[
|
|
464
|
-
'Equals',
|
|
465
|
-
['ReferencedField', 'pilot', 'id'],
|
|
466
|
-
['ReferencedField', 'pilot.identification method', 'pilot'],
|
|
467
|
-
],
|
|
468
|
-
[
|
|
469
|
-
'IsNotDistinctFrom',
|
|
470
|
-
[
|
|
471
|
-
'ReferencedField',
|
|
472
|
-
'pilot.identification method',
|
|
473
|
-
'identification type',
|
|
474
|
-
],
|
|
475
|
-
['Bind', 0],
|
|
476
|
-
],
|
|
477
|
-
],
|
|
478
|
-
])
|
|
479
|
-
.orderby(
|
|
480
|
-
[
|
|
481
|
-
'DESC',
|
|
482
|
-
[
|
|
483
|
-
'ReferencedField',
|
|
484
|
-
'pilot.identification method',
|
|
485
|
-
'identification number',
|
|
486
|
-
],
|
|
487
|
-
],
|
|
488
|
-
[
|
|
489
|
-
'DESC',
|
|
490
|
-
['ReferencedField', 'pilot.identification method', 'created at'],
|
|
491
|
-
],
|
|
492
|
-
);
|
|
493
|
-
},
|
|
494
|
-
'expected SyntaxError: Adding JOINs on the same res… to be an instance of Array',
|
|
495
|
-
);
|
|
496
|
-
});
|
|
497
|
-
|
|
498
|
-
test(`/pilot?$select=name,identification_method(identification_type='passport')/identification_number&$orderby=identification_method(identification_type='passport')/created_at desc`, (result) => {
|
|
499
|
-
// TODO: This atm doens't work b/c the two JOINs are generated with differnet Bind numbers
|
|
500
|
-
itExpectsError(
|
|
501
|
-
`should order pilots by their passport's creation date and select their passport number`,
|
|
502
|
-
() => {
|
|
503
|
-
expect(result)
|
|
504
|
-
.to.be.a.query.that.selects([
|
|
505
|
-
operandToAbstractSQL('name'),
|
|
506
|
-
[
|
|
507
|
-
'Alias',
|
|
508
|
-
[
|
|
509
|
-
'ReferencedField',
|
|
510
|
-
'pilot.identification method',
|
|
511
|
-
'identification number',
|
|
512
|
-
],
|
|
513
|
-
'identification_number',
|
|
514
|
-
],
|
|
515
|
-
])
|
|
516
|
-
.from('pilot')
|
|
517
|
-
.leftJoin([
|
|
518
|
-
['identification method', 'pilot.identification method'],
|
|
519
|
-
[
|
|
520
|
-
'And',
|
|
521
|
-
[
|
|
522
|
-
'Equals',
|
|
523
|
-
['ReferencedField', 'pilot', 'id'],
|
|
524
|
-
['ReferencedField', 'pilot.identification method', 'pilot'],
|
|
525
|
-
],
|
|
526
|
-
[
|
|
527
|
-
'IsNotDistinctFrom',
|
|
528
|
-
[
|
|
529
|
-
'ReferencedField',
|
|
530
|
-
'pilot.identification method',
|
|
531
|
-
'identification type',
|
|
532
|
-
],
|
|
533
|
-
['Bind', 0],
|
|
534
|
-
],
|
|
535
|
-
],
|
|
536
|
-
])
|
|
537
|
-
.orderby([
|
|
538
|
-
'DESC',
|
|
539
|
-
['ReferencedField', 'pilot.identification method', 'created at'],
|
|
540
|
-
]);
|
|
541
|
-
},
|
|
542
|
-
'expected SyntaxError: Adding JOINs on the same res… to be an instance of Array',
|
|
543
|
-
);
|
|
544
|
-
});
|
package/test/paging.ts
DELETED
|
@@ -1,75 +0,0 @@
|
|
|
1
|
-
import { expect } from 'chai';
|
|
2
|
-
import { pilotFields } from './chai-sql';
|
|
3
|
-
import test from './test';
|
|
4
|
-
|
|
5
|
-
test('/pilot?$top=5', (result) => {
|
|
6
|
-
it('should select from pilot limited by 5', () => {
|
|
7
|
-
expect(result)
|
|
8
|
-
.to.be.a.query.that.selects(pilotFields)
|
|
9
|
-
.from('pilot')
|
|
10
|
-
.limit(['Bind', 0]);
|
|
11
|
-
});
|
|
12
|
-
});
|
|
13
|
-
|
|
14
|
-
test('/pilot?$skip=100', (result) => {
|
|
15
|
-
it('should select from pilot offset by 100', () => {
|
|
16
|
-
expect(result)
|
|
17
|
-
.to.be.a.query.that.selects(pilotFields)
|
|
18
|
-
.from('pilot')
|
|
19
|
-
.offset(['Bind', 0]);
|
|
20
|
-
});
|
|
21
|
-
});
|
|
22
|
-
|
|
23
|
-
test('/pilot?$top=5&$skip=100', (result) => {
|
|
24
|
-
it('should select from pilot limited by 5 and offset by 100', () => {
|
|
25
|
-
expect(result)
|
|
26
|
-
.to.be.a.query.that.selects(pilotFields)
|
|
27
|
-
.from('pilot')
|
|
28
|
-
.limit(['Bind', 0])
|
|
29
|
-
.offset(['Bind', 1]);
|
|
30
|
-
});
|
|
31
|
-
});
|
|
32
|
-
|
|
33
|
-
const name = 'Peter';
|
|
34
|
-
test('/pilot?$top=5&$skip=100', 'PATCH', { name }, (result) => {
|
|
35
|
-
it('should update pilot limited by 5 and offset by 100', () => {
|
|
36
|
-
expect(result)
|
|
37
|
-
.to.be.a.query.that.updates.fields('name')
|
|
38
|
-
.values(['Bind', ['pilot', 'name']])
|
|
39
|
-
.from('pilot')
|
|
40
|
-
.where([
|
|
41
|
-
'In',
|
|
42
|
-
['ReferencedField', 'pilot', 'id'],
|
|
43
|
-
[
|
|
44
|
-
'SelectQuery',
|
|
45
|
-
[
|
|
46
|
-
'Select',
|
|
47
|
-
[['Alias', ['ReferencedField', 'pilot', 'id'], '$modifyid']],
|
|
48
|
-
],
|
|
49
|
-
['From', ['Table', 'pilot']],
|
|
50
|
-
['Limit', ['Bind', 0]],
|
|
51
|
-
['Offset', ['Bind', 1]],
|
|
52
|
-
],
|
|
53
|
-
]);
|
|
54
|
-
});
|
|
55
|
-
});
|
|
56
|
-
test('/pilot?$top=5&$skip=100', 'DELETE', (result) => {
|
|
57
|
-
it('should delete from pilot limited by 5 and offset by 100', () => {
|
|
58
|
-
expect(result)
|
|
59
|
-
.to.be.a.query.that.deletes.from('pilot')
|
|
60
|
-
.where([
|
|
61
|
-
'In',
|
|
62
|
-
['ReferencedField', 'pilot', 'id'],
|
|
63
|
-
[
|
|
64
|
-
'SelectQuery',
|
|
65
|
-
[
|
|
66
|
-
'Select',
|
|
67
|
-
[['Alias', ['ReferencedField', 'pilot', 'id'], '$modifyid']],
|
|
68
|
-
],
|
|
69
|
-
['From', ['Table', 'pilot']],
|
|
70
|
-
['Limit', ['Bind', 0]],
|
|
71
|
-
['Offset', ['Bind', 1]],
|
|
72
|
-
],
|
|
73
|
-
]);
|
|
74
|
-
});
|
|
75
|
-
});
|