@cap-js/db-service 1.9.2 → 1.10.2
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 +21 -0
- package/lib/SQLService.js +6 -4
- package/lib/cqn2sql.js +35 -10
- package/lib/cqn4sql.js +2 -3
- package/package.json +1 -5
package/CHANGELOG.md
CHANGED
|
@@ -4,6 +4,27 @@
|
|
|
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
|
+
## [1.10.2](https://github.com/cap-js/cds-dbs/compare/db-service-v1.10.1...db-service-v1.10.2) (2024-06-25)
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
### Fixed
|
|
11
|
+
|
|
12
|
+
* **`expand`:** enable expanding from subquery ([#709](https://github.com/cap-js/cds-dbs/issues/709)) ([5ed03e5](https://github.com/cap-js/cds-dbs/commit/5ed03e5ed64eb46e6f22af120d7285fbcb127a7c)), closes [#708](https://github.com/cap-js/cds-dbs/issues/708)
|
|
13
|
+
|
|
14
|
+
## [1.10.1](https://github.com/cap-js/cds-dbs/compare/db-service-v1.10.0...db-service-v1.10.1) (2024-06-19)
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
### Fixed
|
|
18
|
+
|
|
19
|
+
* Only check first row if no changes required ([#552](https://github.com/cap-js/cds-dbs/issues/552)) ([39b0b85](https://github.com/cap-js/cds-dbs/commit/39b0b85d5cb4807f63f10acea13fb4d688fa1dcd))
|
|
20
|
+
|
|
21
|
+
## [1.10.0](https://github.com/cap-js/cds-dbs/compare/db-service-v1.9.2...db-service-v1.10.0) (2024-05-29)
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
### Added
|
|
25
|
+
|
|
26
|
+
* Add simple queries feature flag ([#660](https://github.com/cap-js/cds-dbs/issues/660)) ([3335202](https://github.com/cap-js/cds-dbs/commit/33352024201a96cc6bdfa30a0fe3fff4227dee10))
|
|
27
|
+
|
|
7
28
|
## [1.9.2](https://github.com/cap-js/cds-dbs/compare/db-service-v1.9.1...db-service-v1.9.2) (2024-05-28)
|
|
8
29
|
|
|
9
30
|
|
package/lib/SQLService.js
CHANGED
|
@@ -65,21 +65,22 @@ class SQLService extends DatabaseService {
|
|
|
65
65
|
return
|
|
66
66
|
}
|
|
67
67
|
|
|
68
|
+
let changes = false
|
|
68
69
|
for (let col of columns) {
|
|
69
70
|
const name = col.as || col.ref?.[col.ref.length - 1] || (typeof col === 'string' && col)
|
|
70
71
|
if (col.element?.isAssociation) {
|
|
71
72
|
if (one) this._changeToStreams(col.SELECT.columns, rows[0][name], false, compat)
|
|
72
73
|
else
|
|
73
|
-
rows.
|
|
74
|
-
this._changeToStreams(col.SELECT.columns, row[name], false, compat)
|
|
75
|
-
})
|
|
74
|
+
changes = rows.some(row => !this._changeToStreams(col.SELECT.columns, row[name], false, compat))
|
|
76
75
|
} else if (col.element?.type === 'cds.LargeBinary') {
|
|
76
|
+
changes = true
|
|
77
77
|
if (one) rows[0][name] = this._stream(rows[0][name])
|
|
78
78
|
else
|
|
79
79
|
rows.forEach(row => {
|
|
80
80
|
row[name] = this._stream(row[name])
|
|
81
81
|
})
|
|
82
82
|
} else if (col.element?.type in BINARY_TYPES) {
|
|
83
|
+
changes = true
|
|
83
84
|
if (one) rows[0][name] = this._buffer(rows[0][name])
|
|
84
85
|
else
|
|
85
86
|
rows.forEach(row => {
|
|
@@ -87,6 +88,7 @@ class SQLService extends DatabaseService {
|
|
|
87
88
|
})
|
|
88
89
|
}
|
|
89
90
|
}
|
|
91
|
+
return changes
|
|
90
92
|
}
|
|
91
93
|
|
|
92
94
|
_stream(val) {
|
|
@@ -115,7 +117,7 @@ class SQLService extends DatabaseService {
|
|
|
115
117
|
*/
|
|
116
118
|
async onSELECT({ query, data }) {
|
|
117
119
|
if (!query.target) {
|
|
118
|
-
try { this.infer(query) } catch
|
|
120
|
+
try { this.infer(query) } catch { /**/ }
|
|
119
121
|
}
|
|
120
122
|
if (query.target && !query.target._unresolved) {
|
|
121
123
|
// Will return multiple rows with objects inside
|
package/lib/cqn2sql.js
CHANGED
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
const cds = require('@sap/cds')
|
|
2
2
|
const cds_infer = require('./infer')
|
|
3
3
|
const cqn4sql = require('./cqn4sql')
|
|
4
|
+
const _simple_queries = cds.env.features.sql_simple_queries
|
|
5
|
+
const _strict_booleans = _simple_queries < 2
|
|
4
6
|
|
|
5
7
|
const BINARY_TYPES = {
|
|
6
8
|
'cds.Binary': 1,
|
|
@@ -257,18 +259,41 @@ class CQN2SQLRenderer {
|
|
|
257
259
|
const SELECT = q.SELECT
|
|
258
260
|
if (!SELECT.columns) return sql
|
|
259
261
|
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
262
|
+
const isRoot = SELECT.expand === 'root'
|
|
263
|
+
const isSimple = _simple_queries &&
|
|
264
|
+
isRoot && // Simple queries are only allowed to have a root
|
|
265
|
+
!ObjectKeys(q.elements).some(e =>
|
|
266
|
+
_strict_booleans && q.elements[e].type === 'cds.Boolean' || // REVISIT: Booleans require json for sqlite
|
|
267
|
+
q.elements[e].isAssociation || // Indicates columns contains an expand
|
|
268
|
+
q.elements[e].$assocExpand || // REVISIT: sometimes associations are structs
|
|
269
|
+
q.elements[e].items // Array types require to be inlined with a json result
|
|
270
|
+
)
|
|
271
|
+
|
|
272
|
+
let cols = SELECT.columns.map(isSimple
|
|
273
|
+
? x => {
|
|
274
|
+
const name = this.column_name(x)
|
|
275
|
+
const escaped = `${name.replace(/"/g, '""')}`
|
|
276
|
+
let col = `${this.output_converter4(x.element, this.quote(name))} AS "${escaped}"`
|
|
277
|
+
if (x.SELECT?.count) {
|
|
278
|
+
// Return both the sub select and the count for @odata.count
|
|
279
|
+
const qc = cds.ql.clone(x, { columns: [{ func: 'count' }], one: 1, limit: 0, orderBy: 0 })
|
|
280
|
+
return [col, `${this.expr(qc)} AS "${escaped}@odata.count"`]
|
|
281
|
+
}
|
|
282
|
+
return col
|
|
267
283
|
}
|
|
268
|
-
|
|
269
|
-
|
|
284
|
+
: x => {
|
|
285
|
+
const name = this.column_name(x)
|
|
286
|
+
const escaped = `${name.replace(/"/g, '""')}`
|
|
287
|
+
let col = `'$."${escaped}"',${this.output_converter4(x.element, this.quote(name))}`
|
|
288
|
+
if (x.SELECT?.count) {
|
|
289
|
+
// Return both the sub select and the count for @odata.count
|
|
290
|
+
const qc = cds.ql.clone(x, { columns: [{ func: 'count' }], one: 1, limit: 0, orderBy: 0 })
|
|
291
|
+
return [col, `'$."${escaped}@odata.count"',${this.expr(qc)}`]
|
|
292
|
+
}
|
|
293
|
+
return col
|
|
294
|
+
}).flat()
|
|
270
295
|
|
|
271
|
-
|
|
296
|
+
if (isSimple) return `SELECT ${cols} FROM (${sql})`
|
|
272
297
|
|
|
273
298
|
// Prevent SQLite from hitting function argument limit of 100
|
|
274
299
|
let obj = "'{}'"
|
package/lib/cqn4sql.js
CHANGED
|
@@ -787,7 +787,7 @@ function cqn4sql(originalQuery, model) {
|
|
|
787
787
|
} else {
|
|
788
788
|
outerAlias = transformedQuery.SELECT.from.as
|
|
789
789
|
subqueryFromRef = [
|
|
790
|
-
...transformedQuery.SELECT.from.ref,
|
|
790
|
+
...(transformedQuery.SELECT.from.ref || /* subq in from */ [transformedQuery.SELECT.from.target.name]),
|
|
791
791
|
...(column.$refLinks[0].definition.kind === 'entity' ? column.ref.slice(1) : column.ref),
|
|
792
792
|
]
|
|
793
793
|
}
|
|
@@ -1911,8 +1911,7 @@ function cqn4sql(originalQuery, model) {
|
|
|
1911
1911
|
result[i].ref = [targetSideRefLink.alias, lhs.ref.join('_')]
|
|
1912
1912
|
}
|
|
1913
1913
|
}
|
|
1914
|
-
} else if (lhs.ref.length === 1)
|
|
1915
|
-
result[i].ref.unshift(targetSideRefLink.alias)
|
|
1914
|
+
} else if (lhs.ref.length === 1) result[i].ref.unshift(targetSideRefLink.alias)
|
|
1916
1915
|
}
|
|
1917
1916
|
}
|
|
1918
1917
|
return result
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@cap-js/db-service",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.10.2",
|
|
4
4
|
"description": "CDS base database service",
|
|
5
5
|
"homepage": "https://github.com/cap-js/cds-dbs/tree/main/db-service#cds-base-database-service",
|
|
6
6
|
"repository": {
|
|
@@ -21,10 +21,6 @@
|
|
|
21
21
|
"lib",
|
|
22
22
|
"CHANGELOG.md"
|
|
23
23
|
],
|
|
24
|
-
"engines": {
|
|
25
|
-
"node": ">=16",
|
|
26
|
-
"npm": ">=8"
|
|
27
|
-
},
|
|
28
24
|
"scripts": {
|
|
29
25
|
"test": "jest --silent"
|
|
30
26
|
},
|