@carbonorm/carbonnode 6.0.19 → 6.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 +46 -1
- package/dist/constants/C6Constants.d.ts +342 -338
- package/dist/executors/SqlExecutor.d.ts +8 -0
- package/dist/index.cjs.js +751 -272
- package/dist/index.cjs.js.map +1 -1
- package/dist/index.d.ts +1 -0
- package/dist/index.esm.js +744 -273
- package/dist/index.esm.js.map +1 -1
- package/dist/orm/builders/AggregateBuilder.d.ts +5 -1
- package/dist/orm/builders/ConditionBuilder.d.ts +2 -3
- package/dist/orm/builders/ExpressionSerializer.d.ts +22 -0
- package/dist/orm/builders/PaginationBuilder.d.ts +4 -6
- package/dist/orm/queryHelpers.d.ts +12 -1
- package/dist/types/mysqlTypes.d.ts +6 -1
- package/dist/types/ormInterfaces.d.ts +7 -5
- package/dist/utils/cacheManager.d.ts +3 -2
- package/package.json +2 -2
- package/scripts/assets/handlebars/C6.test.ts.handlebars +4 -4
- package/src/__tests__/cacheManager.test.ts +28 -0
- package/src/__tests__/expressServer.e2e.test.ts +26 -17
- package/src/__tests__/httpExecutorSingular.e2e.test.ts +53 -14
- package/src/__tests__/normalizeSingularRequest.test.ts +26 -8
- package/src/__tests__/sakila-db/C6.js +1 -1
- package/src/__tests__/sakila-db/C6.mysqldump.json +1 -1
- package/src/__tests__/sakila-db/C6.mysqldump.sql +1 -1
- package/src/__tests__/sakila-db/C6.sqlAllowList.json +1 -1
- package/src/__tests__/sakila-db/C6.test.ts +4 -4
- package/src/__tests__/sakila-db/C6.ts +1 -1
- package/src/__tests__/sakila-db/sqlResponses/C6.actor.post.json +11 -4
- package/src/__tests__/sakila-db/sqlResponses/C6.actor.post.latest.json +3 -3
- package/src/__tests__/sakila-db/sqlResponses/C6.actor.put.json +1 -1
- package/src/__tests__/sakila-db/sqlResponses/C6.actor.put.lookup.json +3 -3
- package/src/__tests__/sakila-db/sqlResponses/C6.address.post.json +26 -7
- package/src/__tests__/sakila-db/sqlResponses/C6.address.post.latest.json +5 -5
- package/src/__tests__/sakila-db/sqlResponses/C6.address.put.json +1 -1
- package/src/__tests__/sakila-db/sqlResponses/C6.address.put.lookup.json +5 -5
- package/src/__tests__/sakila-db/sqlResponses/C6.category.post.json +9 -3
- package/src/__tests__/sakila-db/sqlResponses/C6.category.post.latest.json +2 -2
- package/src/__tests__/sakila-db/sqlResponses/C6.category.put.json +1 -1
- package/src/__tests__/sakila-db/sqlResponses/C6.category.put.lookup.json +2 -2
- package/src/__tests__/sakila-db/sqlResponses/C6.city.post.json +10 -3
- package/src/__tests__/sakila-db/sqlResponses/C6.city.post.latest.json +2 -2
- package/src/__tests__/sakila-db/sqlResponses/C6.city.put.json +1 -1
- package/src/__tests__/sakila-db/sqlResponses/C6.city.put.lookup.json +2 -2
- package/src/__tests__/sakila-db/sqlResponses/C6.country.post.json +9 -3
- package/src/__tests__/sakila-db/sqlResponses/C6.country.post.latest.json +2 -2
- package/src/__tests__/sakila-db/sqlResponses/C6.country.put.json +1 -1
- package/src/__tests__/sakila-db/sqlResponses/C6.country.put.lookup.json +2 -2
- package/src/__tests__/sakila-db/sqlResponses/C6.customer.post.json +18 -6
- package/src/__tests__/sakila-db/sqlResponses/C6.customer.post.latest.json +5 -5
- package/src/__tests__/sakila-db/sqlResponses/C6.customer.put.json +1 -1
- package/src/__tests__/sakila-db/sqlResponses/C6.customer.put.lookup.json +5 -5
- package/src/__tests__/sakila-db/sqlResponses/C6.film.post.json +18 -3
- package/src/__tests__/sakila-db/sqlResponses/C6.film.post.latest.json +2 -2
- package/src/__tests__/sakila-db/sqlResponses/C6.film.put.json +1 -1
- package/src/__tests__/sakila-db/sqlResponses/C6.film.put.lookup.json +2 -2
- package/src/__tests__/sakila-db/sqlResponses/C6.inventory.post.json +9 -2
- package/src/__tests__/sakila-db/sqlResponses/C6.inventory.post.latest.json +1 -1
- package/src/__tests__/sakila-db/sqlResponses/C6.inventory.put.json +1 -1
- package/src/__tests__/sakila-db/sqlResponses/C6.inventory.put.lookup.json +1 -1
- package/src/__tests__/sakila-db/sqlResponses/C6.language.post.json +9 -3
- package/src/__tests__/sakila-db/sqlResponses/C6.language.post.latest.json +2 -2
- package/src/__tests__/sakila-db/sqlResponses/C6.language.put.json +1 -1
- package/src/__tests__/sakila-db/sqlResponses/C6.language.put.lookup.json +2 -2
- package/src/__tests__/sakila-db/sqlResponses/C6.payment.post.json +13 -3
- package/src/__tests__/sakila-db/sqlResponses/C6.payment.post.latest.json +2 -2
- package/src/__tests__/sakila-db/sqlResponses/C6.payment.put.lookup.json +2 -2
- package/src/__tests__/sakila-db/sqlResponses/C6.rental.join.json +10 -10
- package/src/__tests__/sakila-db/sqlResponses/C6.rental.post.json +14 -4
- package/src/__tests__/sakila-db/sqlResponses/C6.rental.post.latest.json +3 -3
- package/src/__tests__/sakila-db/sqlResponses/C6.rental.put.json +1 -1
- package/src/__tests__/sakila-db/sqlResponses/C6.rental.put.lookup.json +3 -3
- package/src/__tests__/sqlBuilders.complex.test.ts +62 -74
- package/src/__tests__/sqlBuilders.expressions.test.ts +58 -30
- package/src/__tests__/sqlBuilders.test.ts +68 -4
- package/src/__tests__/sqlExecutorPostUuid.test.ts +185 -0
- package/src/constants/C6Constants.ts +3 -1
- package/src/executors/HttpExecutor.ts +35 -6
- package/src/executors/SqlExecutor.ts +232 -4
- package/src/index.ts +1 -0
- package/src/orm/builders/AggregateBuilder.ts +67 -106
- package/src/orm/builders/ConditionBuilder.ts +69 -93
- package/src/orm/builders/ExpressionSerializer.ts +275 -0
- package/src/orm/builders/PaginationBuilder.ts +24 -34
- package/src/orm/queryHelpers.ts +29 -0
- package/src/types/mysqlTypes.ts +130 -9
- package/src/types/ormInterfaces.ts +7 -7
- package/src/utils/cacheManager.ts +6 -4
- package/src/utils/normalizeSingularRequest.ts +11 -4
|
@@ -1,12 +1,18 @@
|
|
|
1
1
|
{
|
|
2
2
|
"affected": 1,
|
|
3
3
|
"insertId": 7,
|
|
4
|
-
"rest": [
|
|
4
|
+
"rest": [
|
|
5
|
+
{
|
|
6
|
+
"name": "name_1771106835139",
|
|
7
|
+
"last_update": "2026-02-14 22:07:15",
|
|
8
|
+
"language_id": 7
|
|
9
|
+
}
|
|
10
|
+
],
|
|
5
11
|
"sql": {
|
|
6
12
|
"sql": "INSERT INTO `language` (\n `name`, `last_update`\n ) VALUES\n (?, ?)",
|
|
7
13
|
"values": [
|
|
8
|
-
"
|
|
9
|
-
"2026-02-
|
|
14
|
+
"name_1771106835139",
|
|
15
|
+
"2026-02-14 22:07:15"
|
|
10
16
|
]
|
|
11
17
|
}
|
|
12
18
|
}
|
|
@@ -1,7 +1,17 @@
|
|
|
1
1
|
{
|
|
2
2
|
"affected": 1,
|
|
3
3
|
"insertId": 16050,
|
|
4
|
-
"rest": [
|
|
4
|
+
"rest": [
|
|
5
|
+
{
|
|
6
|
+
"customer_id": 2,
|
|
7
|
+
"staff_id": 1,
|
|
8
|
+
"rental_id": 1,
|
|
9
|
+
"amount": 1,
|
|
10
|
+
"payment_date": "2026-02-14 22:07:15",
|
|
11
|
+
"last_update": "2026-02-14 22:07:15",
|
|
12
|
+
"payment_id": 16050
|
|
13
|
+
}
|
|
14
|
+
],
|
|
5
15
|
"sql": {
|
|
6
16
|
"sql": "INSERT INTO `payment` (\n `customer_id`, `staff_id`, `rental_id`, `amount`, `payment_date`, `last_update`\n ) VALUES\n (?, ?, ?, ?, ?, ?)",
|
|
7
17
|
"values": [
|
|
@@ -9,8 +19,8 @@
|
|
|
9
19
|
1,
|
|
10
20
|
1,
|
|
11
21
|
1,
|
|
12
|
-
"2026-02-
|
|
13
|
-
"2026-02-
|
|
22
|
+
"2026-02-14 22:07:15",
|
|
23
|
+
"2026-02-14 22:07:15"
|
|
14
24
|
]
|
|
15
25
|
}
|
|
16
26
|
}
|
|
@@ -1,18 +1,18 @@
|
|
|
1
1
|
{
|
|
2
2
|
"rest": [
|
|
3
3
|
{
|
|
4
|
-
"rental_id":
|
|
5
|
-
"rental_date": "2005-05-
|
|
6
|
-
"inventory_id":
|
|
7
|
-
"customer_id":
|
|
8
|
-
"return_date": "2005-
|
|
9
|
-
"staff_id":
|
|
4
|
+
"rental_id": 76,
|
|
5
|
+
"rental_date": "2005-05-25T11:30:37.000Z",
|
|
6
|
+
"inventory_id": 3021,
|
|
7
|
+
"customer_id": 1,
|
|
8
|
+
"return_date": "2005-06-03T12:00:37.000Z",
|
|
9
|
+
"staff_id": 2,
|
|
10
10
|
"last_update": "2006-02-15T04:57:20.000Z",
|
|
11
11
|
"store_id": 1,
|
|
12
|
-
"first_name": "
|
|
13
|
-
"last_name": "
|
|
14
|
-
"email": "
|
|
15
|
-
"address_id":
|
|
12
|
+
"first_name": "MARY",
|
|
13
|
+
"last_name": "SMITH",
|
|
14
|
+
"email": "MARY.SMITH@sakilacustomer.org",
|
|
15
|
+
"address_id": 5,
|
|
16
16
|
"active": 1,
|
|
17
17
|
"create_date": "2006-02-14T22:04:36.000Z"
|
|
18
18
|
}
|
|
@@ -1,16 +1,26 @@
|
|
|
1
1
|
{
|
|
2
2
|
"affected": 1,
|
|
3
3
|
"insertId": 16050,
|
|
4
|
-
"rest": [
|
|
4
|
+
"rest": [
|
|
5
|
+
{
|
|
6
|
+
"rental_date": "2026-02-14 22:07:15",
|
|
7
|
+
"inventory_id": 1,
|
|
8
|
+
"customer_id": 1,
|
|
9
|
+
"return_date": "2026-02-14 22:07:15",
|
|
10
|
+
"staff_id": 1,
|
|
11
|
+
"last_update": "2026-02-14 22:07:15",
|
|
12
|
+
"rental_id": 16050
|
|
13
|
+
}
|
|
14
|
+
],
|
|
5
15
|
"sql": {
|
|
6
16
|
"sql": "INSERT INTO `rental` (\n `rental_date`, `inventory_id`, `customer_id`, `return_date`, `staff_id`, `last_update`\n ) VALUES\n (?, ?, ?, ?, ?, ?)",
|
|
7
17
|
"values": [
|
|
8
|
-
"2026-02-
|
|
18
|
+
"2026-02-14 22:07:15",
|
|
9
19
|
1,
|
|
10
20
|
1,
|
|
11
|
-
"2026-02-
|
|
21
|
+
"2026-02-14 22:07:15",
|
|
12
22
|
1,
|
|
13
|
-
"2026-02-
|
|
23
|
+
"2026-02-14 22:07:15"
|
|
14
24
|
]
|
|
15
25
|
}
|
|
16
26
|
}
|
|
@@ -2,12 +2,12 @@
|
|
|
2
2
|
"rest": [
|
|
3
3
|
{
|
|
4
4
|
"rental_id": 16050,
|
|
5
|
-
"rental_date": "2026-02-
|
|
5
|
+
"rental_date": "2026-02-14T22:07:15.000Z",
|
|
6
6
|
"inventory_id": 1,
|
|
7
7
|
"customer_id": 1,
|
|
8
|
-
"return_date": "2026-02-
|
|
8
|
+
"return_date": "2026-02-14T22:07:15.000Z",
|
|
9
9
|
"staff_id": 1,
|
|
10
|
-
"last_update": "2026-02-
|
|
10
|
+
"last_update": "2026-02-14T22:07:15.000Z"
|
|
11
11
|
}
|
|
12
12
|
],
|
|
13
13
|
"sql": {
|
|
@@ -2,12 +2,12 @@
|
|
|
2
2
|
"rest": [
|
|
3
3
|
{
|
|
4
4
|
"rental_id": 16050,
|
|
5
|
-
"rental_date": "2026-02-
|
|
5
|
+
"rental_date": "2026-02-14T22:07:15.000Z",
|
|
6
6
|
"inventory_id": 1,
|
|
7
7
|
"customer_id": 1,
|
|
8
|
-
"return_date": "2026-02-
|
|
8
|
+
"return_date": "2026-02-14T22:07:15.000Z",
|
|
9
9
|
"staff_id": 1,
|
|
10
|
-
"last_update": "2026-02-
|
|
10
|
+
"last_update": "2026-02-14T22:07:15.000Z"
|
|
11
11
|
}
|
|
12
12
|
],
|
|
13
13
|
"sql": {
|
|
@@ -38,7 +38,7 @@ describe('SQL Builders - Complex SELECTs', () => {
|
|
|
38
38
|
SELECT: ['actor.actor_id', 'actor.first_name'],
|
|
39
39
|
WHERE: {
|
|
40
40
|
// AND root with one direct condition
|
|
41
|
-
'actor.first_name': [C6C.LIKE, 'A%'],
|
|
41
|
+
'actor.first_name': [C6C.LIKE, [C6C.LIT, 'A%']],
|
|
42
42
|
// OR group #1
|
|
43
43
|
0: {
|
|
44
44
|
'actor.actor_id': [C6C.IN, [1, 2, 3]]
|
|
@@ -52,7 +52,7 @@ describe('SQL Builders - Complex SELECTs', () => {
|
|
|
52
52
|
'actor.last_name': [C6C.IS, null]
|
|
53
53
|
},
|
|
54
54
|
// AND with NOT IN
|
|
55
|
-
'actor.last_name': [C6C.NOT_IN, ['SMITH', 'DOE']]
|
|
55
|
+
'actor.last_name': [C6C.NOT_IN, [[C6C.LIT, 'SMITH'], [C6C.LIT, 'DOE']]]
|
|
56
56
|
}
|
|
57
57
|
} as any, false);
|
|
58
58
|
|
|
@@ -108,10 +108,10 @@ describe('SQL Builders - Complex SELECTs', () => {
|
|
|
108
108
|
SELECT: ['actor.actor_id', 'actor.first_name'],
|
|
109
109
|
WHERE: { 'actor.actor_id': [C6C.GREATER_THAN, 10] },
|
|
110
110
|
PAGINATION: {
|
|
111
|
-
[C6C.ORDER]:
|
|
112
|
-
'actor.last_name'
|
|
113
|
-
'actor.first_name'
|
|
114
|
-
|
|
111
|
+
[C6C.ORDER]: [
|
|
112
|
+
['actor.last_name', 'ASC'],
|
|
113
|
+
['actor.first_name', 'DESC'],
|
|
114
|
+
],
|
|
115
115
|
[C6C.LIMIT]: 10,
|
|
116
116
|
[C6C.PAGE]: 3
|
|
117
117
|
}
|
|
@@ -128,7 +128,7 @@ describe('SQL Builders - Complex SELECTs', () => {
|
|
|
128
128
|
const config = buildTestConfig();
|
|
129
129
|
|
|
130
130
|
const qb = new SelectQueryBuilder(config as any, {
|
|
131
|
-
SELECT: [[C6C.DISTINCT, 'actor.first_name'], [C6C.COUNT, 'actor.actor_id',
|
|
131
|
+
SELECT: [[C6C.DISTINCT, 'actor.first_name'], [C6C.AS, [C6C.COUNT, 'actor.actor_id'], 'cnt']],
|
|
132
132
|
GROUP_BY: 'actor.first_name',
|
|
133
133
|
HAVING: { 'cnt': [C6C.GREATER_THAN, 1] }
|
|
134
134
|
} as any, false);
|
|
@@ -148,7 +148,7 @@ describe('SQL Builders - Complex SELECTs', () => {
|
|
|
148
148
|
const qb = new SelectQueryBuilder(config as any, {
|
|
149
149
|
SELECT: ['actor.actor_id'],
|
|
150
150
|
WHERE: {
|
|
151
|
-
'actor.first_name': [C6C.MATCH_AGAINST, ['alpha beta', 'BOOLEAN']]
|
|
151
|
+
'actor.first_name': [C6C.MATCH_AGAINST, [[C6C.LIT, 'alpha beta'], 'BOOLEAN']]
|
|
152
152
|
}
|
|
153
153
|
} as any, false);
|
|
154
154
|
|
|
@@ -225,19 +225,21 @@ describe('SQL Builders - Complex SELECTs', () => {
|
|
|
225
225
|
[C6C.WHERE]: {
|
|
226
226
|
[Property_Units.UNIT_ID]: [C6C.NOT_EQUAL, unitIdParam],
|
|
227
227
|
[Parcel_Sales.SALE_PRICE]: [C6C.NOT_EQUAL, 0],
|
|
228
|
-
[Parcel_Sales.SALE_TYPE]: { [C6C.IN]: ALLOWED_SALE_TYPES },
|
|
228
|
+
[Parcel_Sales.SALE_TYPE]: { [C6C.IN]: ALLOWED_SALE_TYPES.map((saleType) => [C6C.LIT, saleType]) },
|
|
229
229
|
0: parsedDateRanges.map(({ start, end }) => ({
|
|
230
|
-
[Parcel_Sales.SALE_DATE]: [C6C.BETWEEN, [start, end]],
|
|
230
|
+
[Parcel_Sales.SALE_DATE]: [C6C.BETWEEN, [[C6C.LIT, start], [C6C.LIT, end]]],
|
|
231
231
|
})),
|
|
232
232
|
},
|
|
233
233
|
[C6C.PAGINATION]: {
|
|
234
234
|
[C6C.LIMIT]: 200,
|
|
235
|
-
[C6C.ORDER]:
|
|
236
|
-
[
|
|
235
|
+
[C6C.ORDER]: [[
|
|
236
|
+
[
|
|
237
|
+
C6C.ST_DISTANCE_SPHERE,
|
|
237
238
|
Property_Units.LOCATION,
|
|
238
239
|
F(Property_Units.LOCATION, 'pu_target'),
|
|
239
240
|
],
|
|
240
|
-
|
|
241
|
+
C6C.ASC,
|
|
242
|
+
]],
|
|
241
243
|
},
|
|
242
244
|
} as any, false);
|
|
243
245
|
|
|
@@ -250,7 +252,7 @@ describe('SQL Builders - Complex SELECTs', () => {
|
|
|
250
252
|
expect(sql).toMatch(/INNER JOIN \(\s+SELECT property_units\.location/);
|
|
251
253
|
expect(sql).toContain('WHERE (property_units.unit_id) <> ?');
|
|
252
254
|
expect(sql).toContain('AND (parcel_sales.sale_price) <> ?');
|
|
253
|
-
expect(sql).toContain('ORDER BY
|
|
255
|
+
expect(sql).toContain('ORDER BY ST_DISTANCE_SPHERE(property_units.location, pu_target.location) ASC');
|
|
254
256
|
expect(sql.trim().endsWith('LIMIT 200')).toBe(true);
|
|
255
257
|
|
|
256
258
|
expect(params).toEqual([
|
|
@@ -314,17 +316,15 @@ describe('SQL Builders - Complex SELECTs', () => {
|
|
|
314
316
|
[C6C.SELECT]: [Property_Units.UNIT_ID],
|
|
315
317
|
[C6C.PAGINATION]: {
|
|
316
318
|
[C6C.LIMIT]: 200,
|
|
317
|
-
[C6C.ORDER]:
|
|
318
|
-
[C6C.ST_DISTANCE_SPHERE
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
],
|
|
322
|
-
},
|
|
319
|
+
[C6C.ORDER]: [[
|
|
320
|
+
[C6C.ST_DISTANCE_SPHERE, Property_Units.LOCATION, [C6C.ST_POINT, -104.8967729, 39.3976764]],
|
|
321
|
+
C6C.ASC,
|
|
322
|
+
]],
|
|
323
323
|
},
|
|
324
324
|
} as any, false);
|
|
325
325
|
|
|
326
326
|
const { sql } = qb.build(Property_Units.TABLE_NAME);
|
|
327
|
-
expect(sql).toContain('ORDER BY
|
|
327
|
+
expect(sql).toContain('ORDER BY ST_DISTANCE_SPHERE(property_units.location, ST_POINT(-104.8967729, 39.3976764)) ASC');
|
|
328
328
|
});
|
|
329
329
|
|
|
330
330
|
it('orders by distance to ST_SRID(ST_Point(lng, lat), 4326)', () => {
|
|
@@ -334,17 +334,15 @@ describe('SQL Builders - Complex SELECTs', () => {
|
|
|
334
334
|
[C6C.SELECT]: [Property_Units.UNIT_ID],
|
|
335
335
|
[C6C.PAGINATION]: {
|
|
336
336
|
[C6C.LIMIT]: 50,
|
|
337
|
-
[C6C.ORDER]:
|
|
338
|
-
[C6C.ST_DISTANCE_SPHERE]
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
],
|
|
342
|
-
},
|
|
337
|
+
[C6C.ORDER]: [[
|
|
338
|
+
[C6C.ST_DISTANCE_SPHERE, Property_Units.LOCATION, [C6C.ST_SRID, [C6C.ST_POINT, 10, 20], 4326]],
|
|
339
|
+
C6C.ASC,
|
|
340
|
+
]],
|
|
343
341
|
},
|
|
344
342
|
} as any, false);
|
|
345
343
|
|
|
346
344
|
const { sql } = qb.build(Property_Units.TABLE_NAME);
|
|
347
|
-
expect(sql).toContain('ORDER BY
|
|
345
|
+
expect(sql).toContain('ORDER BY ST_DISTANCE_SPHERE(property_units.location, ST_SRID(ST_POINT(10, 20), 4326)) ASC');
|
|
348
346
|
});
|
|
349
347
|
|
|
350
348
|
it('orders by distance using placeholders via PARAM inside nested ST_Point', () => {
|
|
@@ -354,17 +352,15 @@ describe('SQL Builders - Complex SELECTs', () => {
|
|
|
354
352
|
[C6C.SELECT]: [Property_Units.UNIT_ID],
|
|
355
353
|
[C6C.PAGINATION]: {
|
|
356
354
|
[C6C.LIMIT]: 25,
|
|
357
|
-
[C6C.ORDER]:
|
|
358
|
-
[C6C.ST_DISTANCE_SPHERE]
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
],
|
|
362
|
-
},
|
|
355
|
+
[C6C.ORDER]: [[
|
|
356
|
+
[C6C.ST_DISTANCE_SPHERE, Property_Units.LOCATION, [C6C.ST_SRID, [C6C.ST_POINT, [C6C.PARAM, 10], [C6C.PARAM, 20]], 4326]],
|
|
357
|
+
C6C.ASC,
|
|
358
|
+
]],
|
|
363
359
|
},
|
|
364
360
|
} as any, false);
|
|
365
361
|
|
|
366
362
|
const { sql, params } = qb.build(Property_Units.TABLE_NAME);
|
|
367
|
-
expect(sql).toContain('ORDER BY
|
|
363
|
+
expect(sql).toContain('ORDER BY ST_DISTANCE_SPHERE(property_units.location, ST_SRID(ST_POINT(?, ?), 4326)) ASC');
|
|
368
364
|
expect(params.slice(-2)).toEqual([10, 20]);
|
|
369
365
|
});
|
|
370
366
|
|
|
@@ -375,12 +371,10 @@ describe('SQL Builders - Complex SELECTs', () => {
|
|
|
375
371
|
[C6C.SELECT]: [Property_Units.UNIT_ID],
|
|
376
372
|
[C6C.PAGINATION]: {
|
|
377
373
|
[C6C.LIMIT]: 25,
|
|
378
|
-
[C6C.ORDER]:
|
|
379
|
-
[C6C.ST_DISTANCE_SPHERE]
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
],
|
|
383
|
-
},
|
|
374
|
+
[C6C.ORDER]: [[
|
|
375
|
+
[C6C.ST_DISTANCE_SPHERE, Property_Units.LOCATION, [C6C.ST_SRID, [C6C.ST_POINT, [C6C.PARAM, 10], [C6C.PARAM, 20]], 4326]],
|
|
376
|
+
C6C.ASC,
|
|
377
|
+
]],
|
|
384
378
|
},
|
|
385
379
|
} as any, true);
|
|
386
380
|
|
|
@@ -396,17 +390,15 @@ describe('SQL Builders - Complex SELECTs', () => {
|
|
|
396
390
|
[C6C.SELECT]: [Property_Units.UNIT_ID],
|
|
397
391
|
[C6C.PAGINATION]: {
|
|
398
392
|
[C6C.LIMIT]: 10,
|
|
399
|
-
[C6C.ORDER]:
|
|
400
|
-
[C6C.ST_DISTANCE_SPHERE]
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
],
|
|
404
|
-
},
|
|
393
|
+
[C6C.ORDER]: [[
|
|
394
|
+
[C6C.ST_DISTANCE_SPHERE, Property_Units.LOCATION, [C6C.ST_GEOMFROMTEXT, [C6C.PARAM, 'POINT(-104.8967729 39.3976764)'], 4326]],
|
|
395
|
+
C6C.ASC,
|
|
396
|
+
]],
|
|
405
397
|
},
|
|
406
398
|
} as any, false);
|
|
407
399
|
|
|
408
400
|
const { sql, params } = qb.build(Property_Units.TABLE_NAME);
|
|
409
|
-
expect(sql).toContain('ORDER BY
|
|
401
|
+
expect(sql).toContain('ORDER BY ST_DISTANCE_SPHERE(property_units.location, ST_GEOMFROMTEXT(?, 4326)) ASC');
|
|
410
402
|
expect(params.slice(-1)[0]).toBe('POINT(-104.8967729 39.3976764)');
|
|
411
403
|
});
|
|
412
404
|
|
|
@@ -417,20 +409,16 @@ describe('SQL Builders - Complex SELECTs', () => {
|
|
|
417
409
|
[C6C.SELECT]: [Property_Units.UNIT_ID],
|
|
418
410
|
[C6C.PAGINATION]: {
|
|
419
411
|
[C6C.LIMIT]: 10,
|
|
420
|
-
[C6C.ORDER]:
|
|
421
|
-
[C6C.ST_DISTANCE_SPHERE]
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
],
|
|
425
|
-
},
|
|
412
|
+
[C6C.ORDER]: [[
|
|
413
|
+
[C6C.ST_DISTANCE_SPHERE, Property_Units.LOCATION, [C6C.ST_GEOMFROMTEXT, [C6C.LIT, 'POINT(-104.8967729 39.3976764)'], 4326]],
|
|
414
|
+
C6C.ASC,
|
|
415
|
+
]],
|
|
426
416
|
},
|
|
427
417
|
} as any, false);
|
|
428
418
|
|
|
429
419
|
const { sql, params } = qb.build(Property_Units.TABLE_NAME);
|
|
430
|
-
expect(sql).toContain(
|
|
431
|
-
|
|
432
|
-
);
|
|
433
|
-
expect(params).not.toContain('POINT(-104.8967729 39.3976764)');
|
|
420
|
+
expect(sql).toContain('ORDER BY ST_DISTANCE_SPHERE(property_units.location, ST_GEOMFROMTEXT(?, 4326))');
|
|
421
|
+
expect(params).toContain('POINT(-104.8967729 39.3976764)');
|
|
434
422
|
});
|
|
435
423
|
|
|
436
424
|
it('leaves normal table joins unaffected', () => {
|
|
@@ -455,16 +443,14 @@ describe('SQL Builders - Complex SELECTs', () => {
|
|
|
455
443
|
const qb = new SelectQueryBuilder(config as any, {
|
|
456
444
|
[C6C.SELECT]: [
|
|
457
445
|
Property_Units.UNIT_ID,
|
|
458
|
-
[
|
|
446
|
+
[C6C.AS, [
|
|
459
447
|
C6C.SUBSELECT,
|
|
460
448
|
{
|
|
461
449
|
[C6C.SELECT]: [[C6C.COUNT, Parcel_Sales.PARCEL_ID]],
|
|
462
450
|
[C6C.FROM]: Parcel_Sales.TABLE_NAME,
|
|
463
451
|
[C6C.WHERE]: { [Parcel_Sales.SALE_PRICE]: [C6C.GREATER_THAN, 0] },
|
|
464
452
|
},
|
|
465
|
-
|
|
466
|
-
'sale_count',
|
|
467
|
-
],
|
|
453
|
+
], 'sale_count'],
|
|
468
454
|
],
|
|
469
455
|
[C6C.WHERE]: {
|
|
470
456
|
[Property_Units.UNIT_ID]: [
|
|
@@ -491,7 +477,7 @@ describe('SQL Builders - Complex SELECTs', () => {
|
|
|
491
477
|
it('serializes spatial filtering with FORCE INDEX and correlated EXISTS subqueries', () => {
|
|
492
478
|
const config = buildParcelConfig();
|
|
493
479
|
const polygon = 'POLYGON((39.5185659 -105.0142915, 39.5401859 -105.0142915, 39.5401859 -104.9862115, 39.5185659 -104.9862115, 39.5185659 -105.0142915))';
|
|
494
|
-
const point = [C6C.ST_GEOMFROMTEXT, ['POINT(39.5293759 -105.0002515)', 4326]
|
|
480
|
+
const point = [C6C.ST_GEOMFROMTEXT, [C6C.LIT, 'POINT(39.5293759 -105.0002515)'], 4326];
|
|
495
481
|
const unitId = Buffer.from('11F0615D24861BE1ADD40AFFCF6A1F27', 'hex');
|
|
496
482
|
const countyId = Buffer.from('11F012CFF561A29DBB0E0AFFF25F1747', 'hex');
|
|
497
483
|
|
|
@@ -504,7 +490,7 @@ describe('SQL Builders - Complex SELECTs', () => {
|
|
|
504
490
|
[Property_Units.UNIT_ID]: [C6C.NOT_EQUAL, unitId],
|
|
505
491
|
[Property_Units.COUNTY_ID]: countyId,
|
|
506
492
|
[C6C.MBRCONTAINS]: [
|
|
507
|
-
[C6C.ST_GEOMFROMTEXT, [polygon, 4326]
|
|
493
|
+
[C6C.ST_GEOMFROMTEXT, [C6C.LIT, polygon], 4326],
|
|
508
494
|
Property_Units.LOCATION,
|
|
509
495
|
],
|
|
510
496
|
[C6C.LESS_THAN_OR_EQUAL_TO]: [
|
|
@@ -532,7 +518,7 @@ describe('SQL Builders - Complex SELECTs', () => {
|
|
|
532
518
|
[C6C.SELECT]: [Parcel_Sales.PARCEL_ID],
|
|
533
519
|
[C6C.FROM]: Parcel_Sales.TABLE_NAME,
|
|
534
520
|
[C6C.WHERE]: {
|
|
535
|
-
[Parcel_Sales.SALE_DATE]: [C6C.BETWEEN, ['2023-01-01', '2024-06-30']],
|
|
521
|
+
[Parcel_Sales.SALE_DATE]: [C6C.BETWEEN, [[C6C.LIT, '2023-01-01'], [C6C.LIT, '2024-06-30']]],
|
|
536
522
|
[Parcel_Sales.SALE_PRICE]: [C6C.NOT_EQUAL, 0],
|
|
537
523
|
},
|
|
538
524
|
},
|
|
@@ -542,26 +528,28 @@ describe('SQL Builders - Complex SELECTs', () => {
|
|
|
542
528
|
},
|
|
543
529
|
[C6C.PAGINATION]: {
|
|
544
530
|
[C6C.LIMIT]: 100,
|
|
545
|
-
[C6C.ORDER]:
|
|
546
|
-
[C6C.ST_DISTANCE_SPHERE
|
|
547
|
-
|
|
531
|
+
[C6C.ORDER]: [
|
|
532
|
+
[[C6C.ST_DISTANCE_SPHERE, Property_Units.LOCATION, point], C6C.ASC],
|
|
533
|
+
],
|
|
548
534
|
},
|
|
549
535
|
} as any, false);
|
|
550
536
|
|
|
551
537
|
const { sql, params } = qb.build(Property_Units.TABLE_NAME);
|
|
552
538
|
|
|
553
539
|
expect(sql).toContain('FORCE INDEX (`idx_county_id`, `idx_property_units_location`)');
|
|
554
|
-
expect(sql).toMatch(/MBRCONTAINS\(ST_GEOMFROMTEXT\(
|
|
555
|
-
expect(sql).toMatch(/ST_DISTANCE_SPHERE\(property_units\.location, ST_GEOMFROMTEXT\(
|
|
540
|
+
expect(sql).toMatch(/MBRCONTAINS\(ST_GEOMFROMTEXT\(\?, 4326\), property_units\.location\)/);
|
|
541
|
+
expect(sql).toMatch(/ST_DISTANCE_SPHERE\(property_units\.location, ST_GEOMFROMTEXT\(\?, 4326\)\) <= \?/);
|
|
556
542
|
expect(sql).toMatch(/\(parcel_building_details\.parcel_id\) = property_units\.parcel_id/);
|
|
557
543
|
expect(sql).toMatch(/\(parcel_sales\.parcel_id\) = property_units\.parcel_id/);
|
|
558
|
-
expect(sql).toMatch(/ORDER BY ST[_]
|
|
544
|
+
expect(sql).toMatch(/ORDER BY ST[_]DISTANCE[_]SPHERE\(property_units\.location, ST_GEOMFROMTEXT\(\?, 4326\)\) ASC/i);
|
|
559
545
|
|
|
560
|
-
expect(params).toHaveLength(
|
|
546
|
+
expect(params).toHaveLength(13);
|
|
561
547
|
expect(params[0]).toEqual(unitId);
|
|
562
548
|
expect(params[1]).toEqual(countyId);
|
|
549
|
+
expect(params[2]).toEqual(polygon);
|
|
550
|
+
expect(params[3]).toEqual('POINT(39.5293759 -105.0002515)');
|
|
563
551
|
expect(params).toContain(1200);
|
|
564
|
-
expect(params.slice(
|
|
565
|
-
expect(params.slice(
|
|
552
|
+
expect(params.slice(5, 9)).toEqual([1988, 2008, 1876.5, 3127.5]);
|
|
553
|
+
expect(params.slice(9)).toEqual(['2023-01-01', '2024-06-30', 0, 'POINT(39.5293759 -105.0002515)']);
|
|
566
554
|
});
|
|
567
555
|
});
|