@cap-js/postgres 1.14.1 → 2.0.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 +36 -2
- package/lib/PostgresService.js +41 -34
- package/lib/cql-functions.js +1 -1
- package/package.json +5 -5
package/CHANGELOG.md
CHANGED
|
@@ -4,12 +4,46 @@
|
|
|
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
|
-
## [
|
|
7
|
+
## [2.0.1](https://github.com/cap-js/cds-dbs/compare/postgres-v2.0.0...postgres-v2.0.1) (2025-05-27)
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
### ⚠ BREAKING CHANGES
|
|
11
|
+
|
|
12
|
+
* remove PG `?` placeholder replacement ([#1180](https://github.com/cap-js/cds-dbs/issues/1180))
|
|
8
13
|
|
|
9
14
|
|
|
10
15
|
### Fixed
|
|
11
16
|
|
|
12
|
-
*
|
|
17
|
+
* Enable mixing stream and normal parameters in queries ([#1179](https://github.com/cap-js/cds-dbs/issues/1179)) ([7ee8083](https://github.com/cap-js/cds-dbs/commit/7ee808365426072250dd6de87abd11215f44561a))
|
|
18
|
+
* hierarchies in quoted mode ([3465cba](https://github.com/cap-js/cds-dbs/commit/3465cbab579d4560d12d3b230c55b746d4d3f5a5))
|
|
19
|
+
* only sort by locale if locale is set ([#1193](https://github.com/cap-js/cds-dbs/issues/1193)) ([3465cba](https://github.com/cap-js/cds-dbs/commit/3465cbab579d4560d12d3b230c55b746d4d3f5a5))
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
### Changed
|
|
23
|
+
|
|
24
|
+
* remove PG `?` placeholder replacement ([#1180](https://github.com/cap-js/cds-dbs/issues/1180)) ([a1e0bd9](https://github.com/cap-js/cds-dbs/commit/a1e0bd9fe8501c284d8cbfc8d79d4dddda34c087))
|
|
25
|
+
* remove stream_compat ([#1139](https://github.com/cap-js/cds-dbs/issues/1139)) ([#1144](https://github.com/cap-js/cds-dbs/issues/1144)) ([1b8b2d9](https://github.com/cap-js/cds-dbs/commit/1b8b2d9539cd97be2cef088c98d88ef9ec7dd1bf))
|
|
26
|
+
|
|
27
|
+
## [2.0.0](https://github.com/cap-js/cds-dbs/compare/postgres-v1.14.0...postgres-v2.0.0) (2025-05-07)
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
### ⚠ BREAKING CHANGES
|
|
31
|
+
|
|
32
|
+
* update peer dependency to @sap/cds@9 ([#1178](https://github.com/cap-js/cds-dbs/issues/1178))
|
|
33
|
+
* update dependency to @cap-js/db-service@2 ([#1178](https://github.com/cap-js/cds-dbs/issues/1178))
|
|
34
|
+
* Unfiltered db constraint errors ([#1165](https://github.com/cap-js/cds-dbs/issues/1165))
|
|
35
|
+
|
|
36
|
+
|
|
37
|
+
### Added
|
|
38
|
+
|
|
39
|
+
* Support for hierarchical queries ([#1093](https://github.com/cap-js/cds-dbs/issues/1093)) ([246e0b3](https://github.com/cap-js/cds-dbs/commit/246e0b38840f7e132ea49cae335b6be7a55354b3))
|
|
40
|
+
|
|
41
|
+
|
|
42
|
+
### Changed
|
|
43
|
+
|
|
44
|
+
* Unfiltered db constraint errors ([#1165](https://github.com/cap-js/cds-dbs/issues/1165)) ([ff39e22](https://github.com/cap-js/cds-dbs/commit/ff39e22ac6cd3f20c98bc31c1a6bb828aa009796))
|
|
45
|
+
* update peer dependency to @sap/cds@9 ([#1178](https://github.com/cap-js/cds-dbs/issues/1178)) ([#1178](https://github.com/cap-js/cds-dbs/issues/1178)) ([0507edd](https://github.com/cap-js/cds-dbs/commit/0507edd4e1dcb98983b1fb65ade1344d978b7524))
|
|
46
|
+
* update dependency to @cap-js/db-service@2 ([#1178](https://github.com/cap-js/cds-dbs/issues/1178)) ([#1178](https://github.com/cap-js/cds-dbs/issues/1178)) ([0507edd](https://github.com/cap-js/cds-dbs/commit/0507edd4e1dcb98983b1fb65ade1344d978b7524))
|
|
13
47
|
|
|
14
48
|
## [1.14.0](https://github.com/cap-js/cds-dbs/compare/postgres-v1.13.0...postgres-v1.14.0) (2025-04-17)
|
|
15
49
|
|
package/lib/PostgresService.js
CHANGED
|
@@ -4,7 +4,6 @@ const cds = require('@sap/cds')
|
|
|
4
4
|
const crypto = require('crypto')
|
|
5
5
|
const { Writable, Readable } = require('stream')
|
|
6
6
|
const sessionVariableMap = require('./session.json')
|
|
7
|
-
const SANITIZE_VALUES = process.env.NODE_ENV === 'production' && cds.env.log.sanitize_values !== false
|
|
8
7
|
|
|
9
8
|
class PostgresService extends SQLService {
|
|
10
9
|
init() {
|
|
@@ -213,7 +212,7 @@ GROUP BY k
|
|
|
213
212
|
if (isBinary) value.setEncoding('base64')
|
|
214
213
|
value.pipe(paramStream)
|
|
215
214
|
value.on('error', err => paramStream.emit('error', err))
|
|
216
|
-
streams
|
|
215
|
+
streams.push(paramStream)
|
|
217
216
|
newValues[i] = streamID
|
|
218
217
|
sql = sql.replace(
|
|
219
218
|
new RegExp(`\\$${i + 1}`, 'g'),
|
|
@@ -284,12 +283,7 @@ GROUP BY k
|
|
|
284
283
|
return target && this.run(cds.ql.CREATE(target))
|
|
285
284
|
}
|
|
286
285
|
}
|
|
287
|
-
|
|
288
|
-
if (/('|")(\1|[^\1]*?\1)|(\?)/.exec(query)?.[3]) {
|
|
289
|
-
let i = 1
|
|
290
|
-
// eslint-disable-next-line no-unused-vars
|
|
291
|
-
req.query = query.replace(/('|")(\1|[^\1]*?\1)|(\?)/g, (a, _b, _c, d, _e, _f, _g) => (d ? '$' + i++ : a))
|
|
292
|
-
}
|
|
286
|
+
|
|
293
287
|
try {
|
|
294
288
|
return await super.onPlainSQL(req, next)
|
|
295
289
|
}
|
|
@@ -327,23 +321,47 @@ GROUP BY k
|
|
|
327
321
|
return super.onSELECT(req)
|
|
328
322
|
}
|
|
329
323
|
|
|
330
|
-
async onINSERT(req) {
|
|
331
|
-
try {
|
|
332
|
-
return await super.onINSERT(req)
|
|
333
|
-
} catch (err) {
|
|
334
|
-
throw _not_unique(err, 'ENTITY_ALREADY_EXISTS', req.data)
|
|
335
|
-
}
|
|
336
|
-
}
|
|
337
324
|
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
325
|
+
static CQN2SQL = class CQN2Postgres extends SQLService.CQN2SQL {
|
|
326
|
+
|
|
327
|
+
render_with() {
|
|
328
|
+
const sql = this.sql
|
|
329
|
+
let recursive = false
|
|
330
|
+
const prefix = this._with.map(q => {
|
|
331
|
+
let sql
|
|
332
|
+
if ('SELECT' in q) sql = `${this.quote(q.as)} AS (${this.SELECT(q)})`
|
|
333
|
+
else if ('SET' in q) {
|
|
334
|
+
recursive = true
|
|
335
|
+
const { SET } = q
|
|
336
|
+
const isDepthFirst = SET.orderBy?.length && (SET.orderBy[0].sort?.toLowerCase() === 'desc' || SET.orderBy[0].sort === -1)
|
|
337
|
+
let alias = q.as
|
|
338
|
+
if (isDepthFirst) {
|
|
339
|
+
alias = alias + '_depth_first'
|
|
340
|
+
SET.args[1].SELECT.from.args.forEach(r => { if (r.ref[0] === q.as) r.ref[0] = alias })
|
|
341
|
+
}
|
|
342
|
+
|
|
343
|
+
sql = `${this.quote(alias)}(${SET.args[0].SELECT.columns?.map(c => this.quote(this.column_name(c))) || ''}) AS (${
|
|
344
|
+
// Root select
|
|
345
|
+
this.SELECT(SET.args[0])} ${
|
|
346
|
+
// Union clause
|
|
347
|
+
SET.op?.toUpperCase() || 'UNION'} ${SET.all ? 'ALL' : ''} ${
|
|
348
|
+
// Repeated join query
|
|
349
|
+
this.SELECT(SET.args[1])
|
|
350
|
+
})${
|
|
351
|
+
// Leverage Postgres specific depth first syntax
|
|
352
|
+
SET.orderBy?.length
|
|
353
|
+
? ` SEARCH DEPTH FIRST BY ${SET.orderBy.map(r => this.ref(r))} SET "$DEPTH$"`
|
|
354
|
+
: ''
|
|
355
|
+
}`
|
|
356
|
+
|
|
357
|
+
// Enforce depth sorting for consuming queries
|
|
358
|
+
if (isDepthFirst) sql += `,${this.quote(q.as)} AS (SELECT * FROM ${this.quote(q.as + '_depth_first')} ORDER BY "$DEPTH$")`
|
|
359
|
+
}
|
|
360
|
+
return { sql }
|
|
361
|
+
})
|
|
362
|
+
this.sql = `WITH${recursive ? ' RECURSIVE' : ''} ${prefix.map(p => p.sql)} ${sql}`
|
|
343
363
|
}
|
|
344
|
-
}
|
|
345
364
|
|
|
346
|
-
static CQN2SQL = class CQN2Postgres extends SQLService.CQN2SQL {
|
|
347
365
|
_orderBy(orderBy, localized, locale) {
|
|
348
366
|
return orderBy.map(c => {
|
|
349
367
|
const nulls = c.nulls || (c.sort?.toLowerCase() === 'desc' || c.sort === -1 ? 'LAST' : 'FIRST')
|
|
@@ -361,7 +379,7 @@ GROUP BY k
|
|
|
361
379
|
}
|
|
362
380
|
|
|
363
381
|
orderByICU(orderBy, localized) {
|
|
364
|
-
const locale = `${this.context.locale.replace('_', '-')}-x-icu`
|
|
382
|
+
const locale = this.context.locale ? `${this.context.locale.replace('_', '-')}-x-icu` : this.context.locale
|
|
365
383
|
return this._orderBy(orderBy, localized, locale)
|
|
366
384
|
}
|
|
367
385
|
|
|
@@ -877,15 +895,4 @@ class ParameterStream extends Writable {
|
|
|
877
895
|
}
|
|
878
896
|
}
|
|
879
897
|
|
|
880
|
-
function _not_unique(err, code, data) {
|
|
881
|
-
if (err.code === '23505')
|
|
882
|
-
return Object.assign(err, {
|
|
883
|
-
originalMessage: err.message, // FIXME: required because of next line
|
|
884
|
-
message: code, // FIXME: misusing message as code
|
|
885
|
-
code: 400, // FIXME: misusing code as (http) status
|
|
886
|
-
})
|
|
887
|
-
if (data) err.values = SANITIZE_VALUES ? ['***'] : data
|
|
888
|
-
return err
|
|
889
|
-
}
|
|
890
|
-
|
|
891
898
|
module.exports = PostgresService
|
package/lib/cql-functions.js
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@cap-js/postgres",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "2.0.1",
|
|
4
4
|
"description": "CDS database service for Postgres",
|
|
5
5
|
"homepage": "https://github.com/cap-js/cds-dbs/tree/main/postgres#cds-database-service-for-postgres",
|
|
6
6
|
"repository": {
|
|
@@ -27,12 +27,12 @@
|
|
|
27
27
|
"start": "docker compose -f pg-stack.yml up -d"
|
|
28
28
|
},
|
|
29
29
|
"dependencies": {
|
|
30
|
-
"@cap-js/db-service": "^
|
|
30
|
+
"@cap-js/db-service": "^2",
|
|
31
31
|
"pg": "^8"
|
|
32
32
|
},
|
|
33
33
|
"peerDependencies": {
|
|
34
|
-
"@sap/cds": ">=
|
|
35
|
-
"@sap/cds-dk": ">=
|
|
34
|
+
"@sap/cds": ">=9",
|
|
35
|
+
"@sap/cds-dk": ">=9"
|
|
36
36
|
},
|
|
37
37
|
"peerDependenciesMeta": {
|
|
38
38
|
"@sap/cds-dk": {
|
|
@@ -76,5 +76,5 @@
|
|
|
76
76
|
}
|
|
77
77
|
}
|
|
78
78
|
},
|
|
79
|
-
"license": "
|
|
79
|
+
"license": "Apache-2.0"
|
|
80
80
|
}
|