@cap-js/db-service 1.2.0 → 1.2.1
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 +6 -0
- package/lib/cqn2sql.js +7 -6
- package/lib/cqn4sql.js +15 -4
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -4,6 +4,12 @@
|
|
|
4
4
|
- The format is based on [Keep a Changelog](http://keepachangelog.com/).
|
|
5
5
|
- This project adheres to [Semantic Versioning](http://semver.org/).
|
|
6
6
|
|
|
7
|
+
## Version 1.2.1 - 2023-09-08
|
|
8
|
+
|
|
9
|
+
### Fixed
|
|
10
|
+
|
|
11
|
+
- Association expansion in infix filters. #213
|
|
12
|
+
|
|
7
13
|
## Version 1.2.0 - 2023-09-06
|
|
8
14
|
|
|
9
15
|
### Added
|
package/lib/cqn2sql.js
CHANGED
|
@@ -235,19 +235,20 @@ class CQN2SQLRenderer {
|
|
|
235
235
|
if (!elements) return sql // REVISIT: Above we say this is an error condition, but here we say it's ok?
|
|
236
236
|
let cols = SELECT.columns.map(x => {
|
|
237
237
|
const name = this.column_name(x)
|
|
238
|
-
let col = `'
|
|
238
|
+
let col = `'${name}',${this.output_converter4(x.element, this.quote(name))}`
|
|
239
239
|
if (x.SELECT?.count) {
|
|
240
240
|
// Return both the sub select and the count for @odata.count
|
|
241
241
|
const qc = cds.ql.clone(x, { columns: [{ func: 'count' }], one: 1, limit: 0, orderBy: 0 })
|
|
242
|
-
col
|
|
242
|
+
return [col, `'${name}@odata.count',${this.expr(qc)}`]
|
|
243
243
|
}
|
|
244
244
|
return col
|
|
245
|
-
})
|
|
245
|
+
}).flat()
|
|
246
246
|
|
|
247
247
|
// Prevent SQLite from hitting function argument limit of 100
|
|
248
|
-
let obj =
|
|
249
|
-
for (let i = 0; i < cols.length; i +=
|
|
250
|
-
|
|
248
|
+
let obj = ''
|
|
249
|
+
for (let i = 0; i < cols.length; i += 50) {
|
|
250
|
+
const n = `json_object(${cols.slice(i, i + 50)})`
|
|
251
|
+
obj = obj ? `json_patch(${obj},${n})` : n
|
|
251
252
|
}
|
|
252
253
|
return `SELECT ${SELECT.one || SELECT.expand === 'root' ? obj : `json_group_array(${obj})`} as _json_ FROM (${sql})`
|
|
253
254
|
}
|
package/lib/cqn4sql.js
CHANGED
|
@@ -548,7 +548,10 @@ function cqn4sql(originalQuery, model = cds.context?.model || cds.model) {
|
|
|
548
548
|
dollarSelfColumn.ref = [...referencedColumn.ref, ...dollarSelfColumn.ref.slice(2)]
|
|
549
549
|
Object.defineProperties(dollarSelfColumn, {
|
|
550
550
|
flatName: {
|
|
551
|
-
value:
|
|
551
|
+
value:
|
|
552
|
+
referencedColumn.$refLinks[0].definition.kind === 'entity'
|
|
553
|
+
? dollarSelfColumn.ref.slice(1).join('_')
|
|
554
|
+
: dollarSelfColumn.ref.join('_'),
|
|
552
555
|
},
|
|
553
556
|
isJoinRelevant: {
|
|
554
557
|
value: referencedColumn.isJoinRelevant,
|
|
@@ -1242,7 +1245,7 @@ function cqn4sql(originalQuery, model = cds.context?.model || cds.model) {
|
|
|
1242
1245
|
) {
|
|
1243
1246
|
if (notSupportedOps.some(([firstOp]) => firstOp === next))
|
|
1244
1247
|
cds.error(`The operator "${next}" is not supported for structure comparison`)
|
|
1245
|
-
const newTokens = expandComparison(token, ops, rhs)
|
|
1248
|
+
const newTokens = expandComparison(token, ops, rhs, $baseLink)
|
|
1246
1249
|
const needXpr = Boolean(tokenStream[i - 1] || tokenStream[indexRhs + 1])
|
|
1247
1250
|
transformedTokenStream.push(...(needXpr ? [asXpr(newTokens)] : newTokens))
|
|
1248
1251
|
i = indexRhs // jump to next relevant index
|
|
@@ -1301,9 +1304,14 @@ function cqn4sql(originalQuery, model = cds.context?.model || cds.model) {
|
|
|
1301
1304
|
* @param {object} token with $refLinks
|
|
1302
1305
|
* @param {string} operator one of allOps
|
|
1303
1306
|
* @param {object} value either `null` or a column (with `ref` and `$refLinks`)
|
|
1307
|
+
* @param {object} $baseLink optional base `$refLink`, e.g. for infix filters of scoped queries.
|
|
1308
|
+
* In the following example, we must pass `bookshop:Reproduce` as $baseLink for `author`:
|
|
1309
|
+
*
|
|
1310
|
+
* `DELETE.from('bookshop.Reproduce[author = null]:accessGroup')`
|
|
1311
|
+
* ^^^^^^
|
|
1304
1312
|
* @returns {array}
|
|
1305
1313
|
*/
|
|
1306
|
-
function expandComparison(token, operator, value) {
|
|
1314
|
+
function expandComparison(token, operator, value, $baseLink = null) {
|
|
1307
1315
|
const { definition } = token.$refLinks[token.$refLinks.length - 1]
|
|
1308
1316
|
let flatRhs
|
|
1309
1317
|
const result = []
|
|
@@ -1366,7 +1374,10 @@ function cqn4sql(originalQuery, model = cds.context?.model || cds.model) {
|
|
|
1366
1374
|
if (!def.$refLinks) return def
|
|
1367
1375
|
const leaf = def.$refLinks[def.$refLinks.length - 1]
|
|
1368
1376
|
const first = def.$refLinks[0]
|
|
1369
|
-
const tableAlias = getQuerySourceName(
|
|
1377
|
+
const tableAlias = getQuerySourceName(
|
|
1378
|
+
def,
|
|
1379
|
+
def.ref.length > 1 && first.definition.isAssociation ? first : $baseLink,
|
|
1380
|
+
)
|
|
1370
1381
|
if (leaf.definition.parent.kind !== 'entity')
|
|
1371
1382
|
// we need the base name
|
|
1372
1383
|
return getFlatColumnsFor(leaf.definition, {
|
package/package.json
CHANGED