@cap-js/postgres 1.8.0 → 1.10.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/CHANGELOG.md +21 -0
- package/README.md +6 -6
- package/cds-plugin.js +1 -1
- package/lib/PostgresService.js +20 -7
- package/lib/cql-functions.js +2 -2
- 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.0](https://github.com/cap-js/cds-dbs/compare/postgres-v1.9.1...postgres-v1.10.0) (2024-07-25)
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
### Changed
|
|
11
|
+
|
|
12
|
+
* build script generates cds8 dependency in deployer app ([#758](https://github.com/cap-js/cds-dbs/issues/758)) ([5c21a67](https://github.com/cap-js/cds-dbs/commit/5c21a6758ccc927cde857e98145c3f4393deb739))
|
|
13
|
+
|
|
14
|
+
## [1.9.1](https://github.com/cap-js/cds-dbs/compare/postgres-v1.9.0...postgres-v1.9.1) (2024-07-09)
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
### Fixed
|
|
18
|
+
|
|
19
|
+
* expand reach of `cds.features.ieee754compatible` to `int64` ([#722](https://github.com/cap-js/cds-dbs/issues/722)) ([7eef5e9](https://github.com/cap-js/cds-dbs/commit/7eef5e9c5ec286285b2552abd1e673175c59fdc1))
|
|
20
|
+
|
|
21
|
+
## [1.9.0](https://github.com/cap-js/cds-dbs/compare/postgres-v1.8.0...postgres-v1.9.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.8.0](https://github.com/cap-js/cds-dbs/compare/postgres-v1.7.0...postgres-v1.8.0) (2024-05-08)
|
|
8
29
|
|
|
9
30
|
|
package/README.md
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
# CDS database service for Postgres
|
|
2
2
|
|
|
3
|
-
Welcome to the
|
|
3
|
+
Welcome to the PostgreSQL database service for [SAP Cloud Application Programming Model](https://cap.cloud.sap) Node.js, based on streamlined database architecture and [*pg* driver](https://www.npmjs.com/package/pg) .
|
|
4
4
|
|
|
5
5
|
## Setup
|
|
6
6
|
|
|
7
|
-
In general, all you need to do is to install
|
|
7
|
+
In general, all you need to do is to install the database package, as follows:
|
|
8
8
|
|
|
9
9
|
```sh
|
|
10
10
|
npm add @cap-js/postgres
|
|
@@ -38,7 +38,7 @@ Copyright 2023 SAP SE or an SAP affiliate company and cds-dbs contributors. Plea
|
|
|
38
38
|
`@cap-js/postgres` works as a drop-in replacement for `cds-pg`.
|
|
39
39
|
However, some preliminary checks and cleanups help:
|
|
40
40
|
|
|
41
|
-
- for using the BTP Postgres Hyperscaler as database,
|
|
41
|
+
- for using the BTP Postgres Hyperscaler as database,
|
|
42
42
|
- know that the credentials are picked up automatically by from the enviornment (`VCAP_SERVICES.postgres`)
|
|
43
43
|
- the service binding label is `postgresql-db`
|
|
44
44
|
- `cds-dbm` is replaced by a hand-crafted "db-deployer" app → see below
|
|
@@ -47,7 +47,7 @@ However, some preliminary checks and cleanups help:
|
|
|
47
47
|
|
|
48
48
|
### schema migration
|
|
49
49
|
|
|
50
|
-
`@cap-js/postgres` brings the same schema evolution capabilities to PostgreSQL known from HANA and SQLite.
|
|
50
|
+
`@cap-js/postgres` brings the same schema evolution capabilities to PostgreSQL known from SAP HANA and SQLite.
|
|
51
51
|
Enabling schema migration in an existing `cds-pg`-based project consists of generating and deploying a "csn-snapshot" of your database structure.
|
|
52
52
|
|
|
53
53
|
#### local development
|
|
@@ -134,11 +134,11 @@ now, re-use the CDS definitions: `SELECT.from(Beers).columns('brewery_ID').group
|
|
|
134
134
|
|
|
135
135
|
So please adjust your `CQL` statements accordingly.
|
|
136
136
|
|
|
137
|
-
### timezones (potential
|
|
137
|
+
### timezones (potential **BREAKING CHANGE**)
|
|
138
138
|
|
|
139
139
|
any date- + time-type will get stored in [`UTC`](https://en.wikipedia.org/wiki/Coordinated_Universal_Time) **without any timezone identifier in the actual data field**.
|
|
140
140
|
CAP's inbound- and outbound adapters take care of converting incoming and outgoing data from/to the desired time zones.
|
|
141
|
-
So when a `
|
|
141
|
+
So when a `datetime` comes in being in [an ISO 8601](https://en.wikipedia.org/wiki/ISO_8601) compatible format
|
|
142
142
|
`2009-01-01T15:00:00+01:00` (15:00:00 on January 1 2009 in Vienna (CEST))
|
|
143
143
|
will get stored as
|
|
144
144
|
`2009-01-01T13:00:00` (13:00:00 on January 1 2009 in UTC).
|
package/cds-plugin.js
CHANGED
|
@@ -27,7 +27,7 @@ cds.build?.register?.('postgres', class PostgresBuildPlugin extends cds.build.Pl
|
|
|
27
27
|
} else {
|
|
28
28
|
promises.push(
|
|
29
29
|
this.write({
|
|
30
|
-
dependencies: { '@sap/cds': '^
|
|
30
|
+
dependencies: { '@sap/cds': '^8', '@cap-js/postgres': '^1' },
|
|
31
31
|
scripts: { start: 'cds-deploy' },
|
|
32
32
|
}).to('package.json'),
|
|
33
33
|
)
|
package/lib/PostgresService.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
const { SQLService } = require('@cap-js/db-service')
|
|
2
2
|
const { Client, Query } = require('pg')
|
|
3
|
-
const cds = require('@sap/cds
|
|
3
|
+
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')
|
|
@@ -370,7 +370,8 @@ GROUP BY k
|
|
|
370
370
|
return super.column_alias4(x, q)
|
|
371
371
|
}
|
|
372
372
|
|
|
373
|
-
SELECT_expand(
|
|
373
|
+
SELECT_expand(q, sql) {
|
|
374
|
+
const { SELECT } = q
|
|
374
375
|
if (!SELECT.columns) return sql
|
|
375
376
|
const queryAlias = this.quote(SELECT.from?.as || (SELECT.expand === 'root' && 'root'))
|
|
376
377
|
const cols = SELECT.columns.map(x => {
|
|
@@ -385,10 +386,22 @@ GROUP BY k
|
|
|
385
386
|
}
|
|
386
387
|
return col
|
|
387
388
|
})
|
|
389
|
+
const isRoot = SELECT.expand === 'root'
|
|
390
|
+
const isSimple = cds.env.features.sql_simple_queries &&
|
|
391
|
+
isRoot && // Simple queries are only allowed to have a root
|
|
392
|
+
!Object.keys(q.elements).some(e =>
|
|
393
|
+
q.elements[e].isAssociation || // Indicates columns contains an expand
|
|
394
|
+
q.elements[e].$assocExpand || // REVISIT: sometimes associations are structs
|
|
395
|
+
q.elements[e].items // Array types require to be inlined with a json result
|
|
396
|
+
)
|
|
397
|
+
|
|
398
|
+
const subQuery = `SELECT ${cols} FROM (${sql}) as ${queryAlias}`
|
|
399
|
+
if (isSimple) return subQuery
|
|
400
|
+
|
|
388
401
|
// REVISIT: Remove SELECT ${cols} by adjusting SELECT_columns
|
|
389
402
|
let obj = `to_jsonb(${queryAlias}.*)`
|
|
390
|
-
return `SELECT ${SELECT.one ||
|
|
391
|
-
} as _json_ FROM (
|
|
403
|
+
return `SELECT ${SELECT.one || isRoot ? obj : `coalesce(jsonb_agg (${obj}),'[]'::jsonb)`
|
|
404
|
+
} as _json_ FROM (${subQuery}) as ${queryAlias}`
|
|
392
405
|
}
|
|
393
406
|
|
|
394
407
|
doubleQuote(name) {
|
|
@@ -516,10 +529,10 @@ GROUP BY k
|
|
|
516
529
|
struct: e => `jsonb(${e})`,
|
|
517
530
|
array: e => `jsonb(${e})`,
|
|
518
531
|
// Reading int64 as string to not loose precision
|
|
519
|
-
Int64: expr => `cast(${expr} as varchar)
|
|
532
|
+
Int64: cds.env.features.ieee754compatible ? expr => `cast(${expr} as varchar)` : undefined,
|
|
520
533
|
// REVISIT: always cast to string in next major
|
|
521
534
|
// Reading decimal as string to not loose precision
|
|
522
|
-
Decimal: cds.env.features.
|
|
535
|
+
Decimal: cds.env.features.ieee754compatible ? expr => `cast(${expr} as varchar)` : undefined,
|
|
523
536
|
|
|
524
537
|
// Convert point back to json format
|
|
525
538
|
'cds.hana.ST_POINT': expr => `CASE WHEN (${expr}) IS NOT NULL THEN json_object('x':(${expr})[0],'y':(${expr})[1])::varchar END`,
|
|
@@ -553,7 +566,7 @@ GROUP BY k
|
|
|
553
566
|
GRANT "${creds.usergroup}" TO "${creds.user}" WITH ADMIN OPTION;
|
|
554
567
|
`)
|
|
555
568
|
await this.exec(`CREATE DATABASE "${creds.database}" OWNER="${creds.user}" TEMPLATE=template0`)
|
|
556
|
-
} catch
|
|
569
|
+
} catch {
|
|
557
570
|
// Failed to reset database
|
|
558
571
|
} finally {
|
|
559
572
|
await this.dbc.end()
|
package/lib/cql-functions.js
CHANGED
|
@@ -9,8 +9,8 @@ const StandardFunctions = {
|
|
|
9
9
|
count: x => `count(${x?.val || x || '*'})`,
|
|
10
10
|
countdistinct: x => `count(distinct ${x.val || x || '*'})`,
|
|
11
11
|
contains: (...args) => `(coalesce(strpos(${args}),0) > 0)`,
|
|
12
|
-
indexof: (x, y) => `strpos(${x},${y}) - 1`, //
|
|
13
|
-
startswith: (x, y) => `strpos(${x},${y}) = 1`, //
|
|
12
|
+
indexof: (x, y) => `strpos(${x},${y}) - 1`, // strpos is 1 indexed
|
|
13
|
+
startswith: (x, y) => `strpos(${x},${y}) = 1`, // strpos is 1 indexed
|
|
14
14
|
endswith: (x, y) => `substr(${x},length(${x}) + 1 - length(${y})) = ${y}`,
|
|
15
15
|
matchesPattern: (x, y) => `regexp_like(${x}, ${y})`,
|
|
16
16
|
matchespattern: (x, y) => `regexp_like(${x}, ${y})`,
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@cap-js/postgres",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.10.0",
|
|
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": {
|
|
@@ -22,10 +22,6 @@
|
|
|
22
22
|
"lib",
|
|
23
23
|
"CHANGELOG.md"
|
|
24
24
|
],
|
|
25
|
-
"engines": {
|
|
26
|
-
"node": ">=16",
|
|
27
|
-
"npm": ">=8"
|
|
28
|
-
},
|
|
29
25
|
"scripts": {
|
|
30
26
|
"test": "npm start && jest --silent",
|
|
31
27
|
"start": "docker-compose -f pg-stack.yml up -d"
|