@reventlessdev/reventless-postgres 3.0.0-alpha.11 → 3.0.0-alpha.110
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 +798 -0
- package/README.md +83 -0
- package/lib/bs/.compiler.log +2 -2
- package/lib/bs/ReventlessPostgres.cmt +0 -0
- package/lib/bs/ReventlessPostgres.mlmap +0 -2
- package/lib/bs/compiler-info.json +2 -2
- package/lib/bs/src/DcbEventLogStorage_Postgres-ReventlessPostgres.cmi +0 -0
- package/lib/bs/src/DcbEventLogStorage_Postgres-ReventlessPostgres.cmt +0 -0
- package/lib/bs/src/DcbEventLogStorage_Postgres.ast +0 -0
- package/lib/bs/src/DcbEventLogStorage_Postgres.res +1 -1
- package/lib/bs/src/DcbEventLogStorage_Postgres_Ops-ReventlessPostgres.cmi +0 -0
- package/lib/bs/src/DcbEventLogStorage_Postgres_Ops-ReventlessPostgres.cmt +0 -0
- package/lib/bs/src/DcbEventLogStorage_Postgres_Ops.ast +0 -0
- package/lib/bs/src/DcbEventLogStorage_Postgres_Ops.res +3 -3
- package/lib/bs/src/DcbEventLogStorage_Postgres_Ops.res.mjs +4 -4
- package/lib/bs/src/EventLogChangeFeed-ReventlessPostgres.cmi +0 -0
- package/lib/bs/src/EventLogChangeFeed-ReventlessPostgres.cmt +0 -0
- package/lib/bs/src/EventLogChangeFeed.ast +0 -0
- package/lib/bs/src/EventLogChangeFeed.res +5 -2
- package/lib/bs/src/EventLogChangeFeed.res.mjs +3 -3
- package/lib/bs/src/EventLogStorage_Postgres-ReventlessPostgres.cmi +0 -0
- package/lib/bs/src/EventLogStorage_Postgres-ReventlessPostgres.cmt +0 -0
- package/lib/bs/src/EventLogStorage_Postgres.ast +0 -0
- package/lib/bs/src/EventLogStorage_Postgres.res +1 -1
- package/lib/bs/src/EventLogStorage_Postgres_Ops-ReventlessPostgres.cmi +0 -0
- package/lib/bs/src/EventLogStorage_Postgres_Ops-ReventlessPostgres.cmt +0 -0
- package/lib/bs/src/EventLogStorage_Postgres_Ops.ast +0 -0
- package/lib/bs/src/EventLogStorage_Postgres_Ops.res +1 -1
- package/lib/bs/src/PgChangeFeed-ReventlessPostgres.cmi +0 -0
- package/lib/bs/src/PgChangeFeed-ReventlessPostgres.cmt +0 -0
- package/lib/bs/src/PgChangeFeed.ast +0 -0
- package/lib/bs/src/PgChangeFeed.res +6 -1
- package/lib/bs/src/PgChangeFeed.res.mjs +6 -6
- package/lib/bs/src/PgDriver-ReventlessPostgres.cmi +0 -0
- package/lib/bs/src/PgDriver-ReventlessPostgres.cmt +0 -0
- package/lib/bs/src/PgDriver-ReventlessPostgres.cmti +0 -0
- package/lib/bs/src/PgDriver.ast +0 -0
- package/lib/bs/src/PgDriver.iast +0 -0
- package/lib/bs/src/PgSchema-ReventlessPostgres.cmi +0 -0
- package/lib/bs/src/PgSchema-ReventlessPostgres.cmt +0 -0
- package/lib/bs/src/PgSchema.ast +0 -0
- package/lib/bs/src/QueryDbStorage_Postgres-ReventlessPostgres.cmi +0 -0
- package/lib/bs/src/QueryDbStorage_Postgres-ReventlessPostgres.cmt +0 -0
- package/lib/bs/src/QueryDbStorage_Postgres.ast +0 -0
- package/lib/bs/src/QueryDbStorage_Postgres.res +2 -2
- package/lib/bs/src/QueryDbStorage_Postgres.res.mjs +1 -1
- package/lib/bs/src/QueryDbStorage_Postgres_Ops-ReventlessPostgres.cmi +0 -0
- package/lib/bs/src/QueryDbStorage_Postgres_Ops-ReventlessPostgres.cmt +0 -0
- package/lib/bs/src/QueryDbStorage_Postgres_Ops.ast +0 -0
- package/lib/bs/src/QueryDbStorage_Postgres_Ops.res +1 -1
- package/lib/bs/src/QueryEnginePostgres-ReventlessPostgres.cmi +0 -0
- package/lib/bs/src/QueryEnginePostgres-ReventlessPostgres.cmt +0 -0
- package/lib/bs/src/QueryEnginePostgres.ast +0 -0
- package/lib/bs/src/QueryEnginePostgres.res +69 -12
- package/lib/bs/src/QueryEnginePostgres.res.mjs +49 -26
- package/lib/bs/tests/PostgresIntegrationTest-ReventlessPostgres.cmi +0 -0
- package/lib/bs/tests/PostgresIntegrationTest-ReventlessPostgres.cmt +0 -0
- package/lib/bs/tests/PostgresIntegrationTest.ast +0 -0
- package/lib/bs/tests/QueryEnginePostgresListPageTest-ReventlessPostgres.cmi +0 -0
- package/lib/bs/tests/QueryEnginePostgresListPageTest-ReventlessPostgres.cmt +0 -0
- package/lib/bs/tests/QueryEnginePostgresListPageTest.ast +0 -0
- package/lib/bs/tests/QueryEnginePostgresListPageTest.res.mjs +4 -4
- package/lib/ocaml/.compiler.log +2 -2
- package/lib/ocaml/DcbEventLogStorage_Postgres-ReventlessPostgres.cmi +0 -0
- package/lib/ocaml/DcbEventLogStorage_Postgres-ReventlessPostgres.cmt +0 -0
- package/lib/ocaml/DcbEventLogStorage_Postgres.ast +0 -0
- package/lib/ocaml/DcbEventLogStorage_Postgres.res +1 -1
- package/lib/ocaml/DcbEventLogStorage_Postgres_Ops-ReventlessPostgres.cmi +0 -0
- package/lib/ocaml/DcbEventLogStorage_Postgres_Ops-ReventlessPostgres.cmt +0 -0
- package/lib/ocaml/DcbEventLogStorage_Postgres_Ops.ast +0 -0
- package/lib/ocaml/DcbEventLogStorage_Postgres_Ops.res +3 -3
- package/lib/ocaml/EventLogChangeFeed-ReventlessPostgres.cmi +0 -0
- package/lib/ocaml/EventLogChangeFeed-ReventlessPostgres.cmt +0 -0
- package/lib/ocaml/EventLogChangeFeed.ast +0 -0
- package/lib/ocaml/EventLogChangeFeed.res +5 -2
- package/lib/ocaml/EventLogStorage_Postgres-ReventlessPostgres.cmi +0 -0
- package/lib/ocaml/EventLogStorage_Postgres-ReventlessPostgres.cmt +0 -0
- package/lib/ocaml/EventLogStorage_Postgres.ast +0 -0
- package/lib/ocaml/EventLogStorage_Postgres.res +1 -1
- package/lib/ocaml/EventLogStorage_Postgres_Ops-ReventlessPostgres.cmi +0 -0
- package/lib/ocaml/EventLogStorage_Postgres_Ops-ReventlessPostgres.cmt +0 -0
- package/lib/ocaml/EventLogStorage_Postgres_Ops.ast +0 -0
- package/lib/ocaml/EventLogStorage_Postgres_Ops.res +1 -1
- package/lib/ocaml/PgChangeFeed-ReventlessPostgres.cmi +0 -0
- package/lib/ocaml/PgChangeFeed-ReventlessPostgres.cmt +0 -0
- package/lib/ocaml/PgChangeFeed.ast +0 -0
- package/lib/ocaml/PgChangeFeed.res +6 -1
- package/lib/ocaml/PgDriver-ReventlessPostgres.cmi +0 -0
- package/lib/ocaml/PgDriver-ReventlessPostgres.cmt +0 -0
- package/lib/ocaml/PgDriver-ReventlessPostgres.cmti +0 -0
- package/lib/ocaml/PgDriver.ast +0 -0
- package/lib/ocaml/PgDriver.iast +0 -0
- package/lib/ocaml/PgSchema-ReventlessPostgres.cmi +0 -0
- package/lib/ocaml/PgSchema-ReventlessPostgres.cmt +0 -0
- package/lib/ocaml/PgSchema.ast +0 -0
- package/lib/ocaml/QueryDbStorage_Postgres-ReventlessPostgres.cmi +0 -0
- package/lib/ocaml/QueryDbStorage_Postgres-ReventlessPostgres.cmt +0 -0
- package/lib/ocaml/QueryDbStorage_Postgres.ast +0 -0
- package/lib/ocaml/QueryDbStorage_Postgres.res +2 -2
- package/lib/ocaml/QueryDbStorage_Postgres_Ops-ReventlessPostgres.cmi +0 -0
- package/lib/ocaml/QueryDbStorage_Postgres_Ops-ReventlessPostgres.cmt +0 -0
- package/lib/ocaml/QueryDbStorage_Postgres_Ops.ast +0 -0
- package/lib/ocaml/QueryDbStorage_Postgres_Ops.res +1 -1
- package/lib/ocaml/QueryEnginePostgres-ReventlessPostgres.cmi +0 -0
- package/lib/ocaml/QueryEnginePostgres-ReventlessPostgres.cmt +0 -0
- package/lib/ocaml/QueryEnginePostgres.ast +0 -0
- package/lib/ocaml/QueryEnginePostgres.res +69 -12
- package/lib/ocaml/ReventlessPostgres.cmt +0 -0
- package/package.json +13 -13
- package/rescript.json +2 -1
- package/src/DcbEventLogStorage_Postgres.res +1 -1
- package/src/DcbEventLogStorage_Postgres_Ops.res +3 -3
- package/src/DcbEventLogStorage_Postgres_Ops.res.mjs +4 -4
- package/src/EventLogChangeFeed.res +5 -2
- package/src/EventLogChangeFeed.res.mjs +3 -3
- package/src/EventLogStorage_Postgres.res +1 -1
- package/src/EventLogStorage_Postgres_Ops.res +1 -1
- package/src/PgChangeFeed.res +6 -1
- package/src/PgChangeFeed.res.mjs +6 -6
- package/src/QueryDbStorage_Postgres.res +2 -2
- package/src/QueryDbStorage_Postgres.res.mjs +1 -1
- package/src/QueryDbStorage_Postgres_Ops.res +1 -1
- package/src/QueryEnginePostgres.res +69 -12
- package/src/QueryEnginePostgres.res.mjs +49 -26
- package/lib/ocaml/PostgresIntegrationTest-ReventlessPostgres.cmi +0 -0
- package/lib/ocaml/PostgresIntegrationTest-ReventlessPostgres.cmj +0 -0
- package/lib/ocaml/PostgresIntegrationTest-ReventlessPostgres.cmt +0 -0
- package/lib/ocaml/PostgresIntegrationTest.ast +0 -0
- package/lib/ocaml/QueryEnginePostgresListPageTest-ReventlessPostgres.cmi +0 -0
- package/lib/ocaml/QueryEnginePostgresListPageTest-ReventlessPostgres.cmj +0 -0
- package/lib/ocaml/QueryEnginePostgresListPageTest-ReventlessPostgres.cmt +0 -0
- package/lib/ocaml/QueryEnginePostgresListPageTest.ast +0 -0
- package/tests/PostgresIntegrationTest.res.mjs +0 -377
- package/tests/QueryEnginePostgresListPageTest.res.mjs +0 -461
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@reventlessdev/reventless-postgres",
|
|
3
|
-
"version": "3.0.0-alpha.
|
|
3
|
+
"version": "3.0.0-alpha.110",
|
|
4
4
|
"description": "Postgres storage backend for Reventless (classic + DCB event logs, query DB, change feed). Connection-string only — RDS/Aurora, any managed provider, or a local container.",
|
|
5
5
|
"license": "Apache-2.0",
|
|
6
6
|
"jest": {
|
|
@@ -21,22 +21,22 @@
|
|
|
21
21
|
},
|
|
22
22
|
"dependencies": {
|
|
23
23
|
"pg": "^8.13.1",
|
|
24
|
-
"sury": "11.0.0-
|
|
25
|
-
"@reventlessdev/rescript-effect": "0.1.0-alpha.
|
|
26
|
-
"@reventlessdev/
|
|
27
|
-
"@reventlessdev/
|
|
28
|
-
"@reventlessdev/rescript-
|
|
29
|
-
"@reventlessdev/reventless-infra": "3.0.0-alpha.
|
|
30
|
-
"@reventlessdev/reventless-spec": "3.0.0-alpha.
|
|
24
|
+
"sury": "11.0.0-rc.2",
|
|
25
|
+
"@reventlessdev/rescript-effect": "0.1.0-alpha.32",
|
|
26
|
+
"@reventlessdev/rescript-pulumi-pulumi": "2.3.0-alpha.19",
|
|
27
|
+
"@reventlessdev/reventless-core": "3.0.0-alpha.246",
|
|
28
|
+
"@reventlessdev/rescript-jest": "1.0.0-alpha.10",
|
|
29
|
+
"@reventlessdev/reventless-infra": "3.0.0-alpha.149",
|
|
30
|
+
"@reventlessdev/reventless-spec": "3.0.0-alpha.121"
|
|
31
31
|
},
|
|
32
32
|
"devDependencies": {
|
|
33
33
|
"@types/pg": "^8.11.10",
|
|
34
|
-
"rescript": "
|
|
35
|
-
"sury-ppx": "11.0.0-
|
|
36
|
-
"@reventlessdev/reventless-ppx": "1.0.0-alpha.
|
|
34
|
+
"rescript": "12.3.0",
|
|
35
|
+
"sury-ppx": "11.0.0-rc.2",
|
|
36
|
+
"@reventlessdev/reventless-ppx": "1.0.0-alpha.72"
|
|
37
37
|
},
|
|
38
38
|
"peerDependencies": {
|
|
39
|
-
"rescript": "
|
|
39
|
+
"rescript": "12.3.0"
|
|
40
40
|
},
|
|
41
41
|
"publishConfig": {
|
|
42
42
|
"registry": "https://registry.npmjs.org"
|
|
@@ -44,7 +44,7 @@
|
|
|
44
44
|
"repository": {
|
|
45
45
|
"type": "git",
|
|
46
46
|
"url": "git+https://github.com/ReventlessDev/reventless-core.git",
|
|
47
|
-
"directory": "reventless/
|
|
47
|
+
"directory": "reventless/postgres"
|
|
48
48
|
},
|
|
49
49
|
"scripts": {
|
|
50
50
|
"build": "rescript build",
|
package/rescript.json
CHANGED
|
@@ -8,7 +8,7 @@
|
|
|
8
8
|
// existing `DcbEventLogStorage_Postgres.*` reference keeps working) and adds only
|
|
9
9
|
// the deploy-time `DcbEventLog_Adapter` shape, keeping the historic `makeStorage`
|
|
10
10
|
// 3-tuple `(name, ops, adapter)` API unchanged.
|
|
11
|
-
// See docs/plans/deployed-lambda-esm-self-containment.md (Rung-3 finding).
|
|
11
|
+
// See docs/plans/done/deployed-lambda-esm-self-containment.md (Rung-3 finding).
|
|
12
12
|
|
|
13
13
|
open ReventlessCore
|
|
14
14
|
include DcbEventLogStorage_Postgres_Ops
|
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
// would leak into the Lambda import graph and fail resolution on real Lambda. The
|
|
7
7
|
// thin `DcbEventLogStorage_Postgres` wrapper `include`s this and adds the
|
|
8
8
|
// deploy-time `Pulumi.Output`-shaped adapter for local/deploy consumers.
|
|
9
|
-
// See docs/plans/deployed-lambda-esm-self-containment.md (Rung-3 finding).
|
|
9
|
+
// See docs/plans/done/deployed-lambda-esm-self-containment.md (Rung-3 finding).
|
|
10
10
|
|
|
11
11
|
open ReventlessCore
|
|
12
12
|
open Reventless
|
|
@@ -67,7 +67,7 @@ let rowToEvent = (row: dict<JSON.t>): DcbEventLog_Adapter.rawSequencedEvent => {
|
|
|
67
67
|
| _ => ""
|
|
68
68
|
}
|
|
69
69
|
let meta = switch row->Dict.get("meta") {
|
|
70
|
-
| Some(metaJson) => metaJson->
|
|
70
|
+
| Some(metaJson) => metaJson->Reventless.Util_Sury.fromJson(Reventless.Message.metaSchema)
|
|
71
71
|
| None => JsError.throwWithMessage("missing meta column in dcb_event row")
|
|
72
72
|
}
|
|
73
73
|
{
|
|
@@ -236,7 +236,7 @@ let makeOps = (
|
|
|
236
236
|
JSON.Array(ev.tags->Array.map(t => JSON.Encode.string(t.key ++ "=" ++ t.value))),
|
|
237
237
|
),
|
|
238
238
|
("data", ev.data),
|
|
239
|
-
("meta", ev.meta->
|
|
239
|
+
("meta", ev.meta->Reventless.Util_Sury.toJson(Reventless.Message.metaSchema)),
|
|
240
240
|
]),
|
|
241
241
|
)
|
|
242
242
|
),
|
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
// Generated by ReScript, PLEASE EDIT WITH CARE
|
|
2
2
|
|
|
3
|
-
import * as S from "sury/src/S.res.mjs";
|
|
4
3
|
import * as Stream from "@reventlessdev/rescript-effect/src/Stream.res.mjs";
|
|
5
4
|
import * as Stdlib_Int from "@rescript/runtime/lib/es6/Stdlib_Int.js";
|
|
6
5
|
import * as Stdlib_Array from "@rescript/runtime/lib/es6/Stdlib_Array.js";
|
|
@@ -11,6 +10,7 @@ import * as Stdlib_JsError from "@rescript/runtime/lib/es6/Stdlib_JsError.js";
|
|
|
11
10
|
import * as Primitive_option from "@rescript/runtime/lib/es6/Primitive_option.js";
|
|
12
11
|
import * as Message$Reventless from "@reventlessdev/reventless-spec/src/types/Message.res.mjs";
|
|
13
12
|
import * as Primitive_exceptions from "@rescript/runtime/lib/es6/Primitive_exceptions.js";
|
|
13
|
+
import * as Util_Sury$Reventless from "@reventlessdev/reventless-spec/src/util/Util_Sury.res.mjs";
|
|
14
14
|
import * as PgDriver$ReventlessPostgres from "./PgDriver.res.mjs";
|
|
15
15
|
|
|
16
16
|
function strategyParam(s) {
|
|
@@ -68,7 +68,7 @@ function rowToEvent(row) {
|
|
|
68
68
|
}
|
|
69
69
|
};
|
|
70
70
|
let metaJson = row["meta"];
|
|
71
|
-
let meta = metaJson !== undefined ?
|
|
71
|
+
let meta = metaJson !== undefined ? Util_Sury$Reventless.fromJson(metaJson, Message$Reventless.metaSchema) : Stdlib_JsError.throwWithMessage("missing meta column in dcb_event row");
|
|
72
72
|
return {
|
|
73
73
|
position: str("cursor"),
|
|
74
74
|
eventType: str("event_type"),
|
|
@@ -226,7 +226,7 @@ function makeOps(pool, name, param, param$1, param$2, param$3, lockStrategyOpt,
|
|
|
226
226
|
],
|
|
227
227
|
[
|
|
228
228
|
"meta",
|
|
229
|
-
|
|
229
|
+
Util_Sury$Reventless.toJson(ev.meta, Message$Reventless.metaSchema)
|
|
230
230
|
]
|
|
231
231
|
])));
|
|
232
232
|
let conditionParam;
|
|
@@ -377,4 +377,4 @@ export {
|
|
|
377
377
|
countAll,
|
|
378
378
|
makeOps,
|
|
379
379
|
}
|
|
380
|
-
/*
|
|
380
|
+
/* Stream Not a pure module */
|
|
@@ -15,8 +15,11 @@
|
|
|
15
15
|
// later commit) is never skipped by a checkpointing reader. `global_seq` alone,
|
|
16
16
|
// being an IDENTITY assigned at INSERT, could NOT provide that guarantee.
|
|
17
17
|
|
|
18
|
-
// Reuse the shared `<a>:<b>` cursor codec from the DCB storage — identical
|
|
19
|
-
module
|
|
18
|
+
// Reuse the shared `<a>:<b>` cursor codec from the DCB storage — identical
|
|
19
|
+
// format. Point at the runtime-pure `_Ops` module (no `@pulumi/pulumi`): this
|
|
20
|
+
// feed is drained by the deployed change-feed relay Lambda, whose cold-start
|
|
21
|
+
// graph must stay Pulumi-free.
|
|
22
|
+
module Dcb = DcbEventLogStorage_Postgres_Ops
|
|
20
23
|
|
|
21
24
|
// One classic event as the feed surfaces it. `payload` is the stored event JSON
|
|
22
25
|
// verbatim; a bus/topic relay transforms it into its target shape (e.g. the AWS
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
import * as Stdlib_Int from "@rescript/runtime/lib/es6/Stdlib_Int.js";
|
|
4
4
|
import * as Stdlib_Option from "@rescript/runtime/lib/es6/Stdlib_Option.js";
|
|
5
5
|
import * as PgDriver$ReventlessPostgres from "./PgDriver.res.mjs";
|
|
6
|
-
import * as
|
|
6
|
+
import * as DcbEventLogStorage_Postgres_Ops$ReventlessPostgres from "./DcbEventLogStorage_Postgres_Ops.res.mjs";
|
|
7
7
|
|
|
8
8
|
let selectColumns = "\n lpad(transaction_id::text, 20, '0') || ':' || lpad(global_seq::text, 20, '0') AS cursor,\n aggregate_id,\n seq_nr,\n payload,\n msg_id\n";
|
|
9
9
|
|
|
@@ -43,7 +43,7 @@ async function readBatch(pool, logName, after, limitOpt) {
|
|
|
43
43
|
let limit = limitOpt !== undefined ? limitOpt : 500;
|
|
44
44
|
let params = [logName];
|
|
45
45
|
let where = "log_name = $1 AND transaction_id < pg_snapshot_xmin(pg_current_snapshot())";
|
|
46
|
-
let match = Stdlib_Option.flatMap(after,
|
|
46
|
+
let match = Stdlib_Option.flatMap(after, DcbEventLogStorage_Postgres_Ops$ReventlessPostgres.decodeCursor);
|
|
47
47
|
if (match !== undefined) {
|
|
48
48
|
params.push(match[0]);
|
|
49
49
|
params.push(match[1]);
|
|
@@ -72,7 +72,7 @@ async function loadCheckpoint(pool, subscriber) {
|
|
|
72
72
|
}
|
|
73
73
|
|
|
74
74
|
async function saveCheckpoint(pool, subscriber, cursor) {
|
|
75
|
-
let match =
|
|
75
|
+
let match = DcbEventLogStorage_Postgres_Ops$ReventlessPostgres.decodeCursor(cursor);
|
|
76
76
|
if (match !== undefined) {
|
|
77
77
|
await PgDriver$ReventlessPostgres.query(pool, "INSERT INTO event_log_subscription(subscriber, last_tx, last_global_seq)\n VALUES ($1, $2::xid8, $3::bigint)\n ON CONFLICT (subscriber)\n DO UPDATE SET last_tx = EXCLUDED.last_tx, last_global_seq = EXCLUDED.last_global_seq", [
|
|
78
78
|
subscriber,
|
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
// real Lambda). This module `include`s that pure module and adds only the
|
|
8
8
|
// deploy-time `EventLog_Adapter` shape (`operations` wrapped in `Pulumi.Output`),
|
|
9
9
|
// keeping the historic `makeStorage` 3-tuple `(name, ops, adapter)` API unchanged.
|
|
10
|
-
// See docs/plans/deployed-lambda-esm-self-containment.md (Rung-3 finding).
|
|
10
|
+
// See docs/plans/done/deployed-lambda-esm-self-containment.md (Rung-3 finding).
|
|
11
11
|
|
|
12
12
|
open ReventlessCore
|
|
13
13
|
include EventLogStorage_Postgres_Ops
|
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
// in no Lambda — not the layer, not `/var/runtime`). The thin
|
|
8
8
|
// `EventLogStorage_Postgres` wrapper adds the deploy-time `Pulumi.Output`-shaped
|
|
9
9
|
// adapter on top for local/deploy consumers; the runtime imports `makeOps` here.
|
|
10
|
-
// See docs/plans/deployed-lambda-esm-self-containment.md (Rung-3 finding).
|
|
10
|
+
// See docs/plans/done/deployed-lambda-esm-self-containment.md (Rung-3 finding).
|
|
11
11
|
|
|
12
12
|
open ReventlessCore
|
|
13
13
|
|
package/src/PgChangeFeed.res
CHANGED
|
@@ -18,7 +18,12 @@
|
|
|
18
18
|
open ReventlessCore
|
|
19
19
|
open Reventless
|
|
20
20
|
|
|
21
|
-
module
|
|
21
|
+
// Runtime-pure ops module (no `@pulumi/pulumi`) — this feed is drained by the
|
|
22
|
+
// deployed change-feed relay Lambda, so its cold-start graph must stay
|
|
23
|
+
// Pulumi-free. `_Ops` carries every helper used below (mkBuilder,
|
|
24
|
+
// buildReadWhere, decodeCursor, selectColumns, rowToEvent); the deploy-time
|
|
25
|
+
// DcbEventLogStorage_Postgres only `include`s it and adds the Pulumi adapter.
|
|
26
|
+
module Dcb = DcbEventLogStorage_Postgres_Ops
|
|
22
27
|
|
|
23
28
|
// One page of the feed. `events` are in (transaction_id, position) order;
|
|
24
29
|
// `cursor` is the checkpoint to persist and to pass as the next `after` (None
|
package/src/PgChangeFeed.res.mjs
CHANGED
|
@@ -2,15 +2,15 @@
|
|
|
2
2
|
|
|
3
3
|
import * as Stdlib_Option from "@rescript/runtime/lib/es6/Stdlib_Option.js";
|
|
4
4
|
import * as PgDriver$ReventlessPostgres from "./PgDriver.res.mjs";
|
|
5
|
-
import * as
|
|
5
|
+
import * as DcbEventLogStorage_Postgres_Ops$ReventlessPostgres from "./DcbEventLogStorage_Postgres_Ops.res.mjs";
|
|
6
6
|
|
|
7
7
|
async function readBatch(pool, logName, after, limitOpt) {
|
|
8
8
|
let limit = limitOpt !== undefined ? limitOpt : 500;
|
|
9
|
-
let b =
|
|
10
|
-
let where =
|
|
11
|
-
let sql = `SELECT ` +
|
|
9
|
+
let b = DcbEventLogStorage_Postgres_Ops$ReventlessPostgres.mkBuilder();
|
|
10
|
+
let where = DcbEventLogStorage_Postgres_Ops$ReventlessPostgres.buildReadWhere(b, logName, [], Stdlib_Option.flatMap(after, DcbEventLogStorage_Postgres_Ops$ReventlessPostgres.decodeCursor), true);
|
|
11
|
+
let sql = `SELECT ` + DcbEventLogStorage_Postgres_Ops$ReventlessPostgres.selectColumns + ` FROM dcb_event WHERE ` + where + ` ORDER BY transaction_id ASC, position ASC LIMIT ` + limit.toString();
|
|
12
12
|
let rows = await PgDriver$ReventlessPostgres.query(pool, sql, b.params);
|
|
13
|
-
let events = rows.map(
|
|
13
|
+
let events = rows.map(DcbEventLogStorage_Postgres_Ops$ReventlessPostgres.rowToEvent);
|
|
14
14
|
let last = events[events.length - 1 | 0];
|
|
15
15
|
let cursor = last !== undefined ? last.position : undefined;
|
|
16
16
|
return {
|
|
@@ -31,7 +31,7 @@ async function loadCheckpoint(pool, subscriber) {
|
|
|
31
31
|
}
|
|
32
32
|
|
|
33
33
|
async function saveCheckpoint(pool, subscriber, cursor) {
|
|
34
|
-
let match =
|
|
34
|
+
let match = DcbEventLogStorage_Postgres_Ops$ReventlessPostgres.decodeCursor(cursor);
|
|
35
35
|
if (match !== undefined) {
|
|
36
36
|
await PgDriver$ReventlessPostgres.query(pool, "INSERT INTO dcb_subscription(subscriber, last_tx, last_position)\n VALUES ($1, $2::xid8, $3::bigint)\n ON CONFLICT (subscriber)\n DO UPDATE SET last_tx = EXCLUDED.last_tx, last_position = EXCLUDED.last_position", [
|
|
37
37
|
subscriber,
|
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
// that pure module (so every existing `QueryDbStorage_Postgres.*` reference keeps
|
|
7
7
|
// working) and adds only the deploy-time `Pulumi.Output`-shaped `storage` record
|
|
8
8
|
// and the `Make` provider functor.
|
|
9
|
-
// See docs/plans/deployed-lambda-esm-self-containment.md (Rung-3 finding).
|
|
9
|
+
// See docs/plans/done/deployed-lambda-esm-self-containment.md (Rung-3 finding).
|
|
10
10
|
|
|
11
11
|
open ReventlessCore
|
|
12
12
|
open Reventless.ReadModel
|
|
@@ -37,6 +37,6 @@ module Make = (P: {let pool: PgDriver.pool}) => {
|
|
|
37
37
|
~ttl as _=?,
|
|
38
38
|
~api as _,
|
|
39
39
|
~apiRole as _,
|
|
40
|
-
~opts as _,
|
|
40
|
+
~owner as _, ~opts as _,
|
|
41
41
|
) => makeStorage(~pool=P.pool, ~name, ~indexes, ~subIdField)
|
|
42
42
|
}
|
|
@@ -12,7 +12,7 @@ function makeStorage(pool, name, indexes, subIdField) {
|
|
|
12
12
|
}
|
|
13
13
|
|
|
14
14
|
function Make(P) {
|
|
15
|
-
let make = (name, indexes, subIdField, param, param$1, param$2, param$3) => makeStorage(P.pool, name, indexes, subIdField);
|
|
15
|
+
let make = (name, indexes, subIdField, param, param$1, param$2, param$3, param$4) => makeStorage(P.pool, name, indexes, subIdField);
|
|
16
16
|
return {
|
|
17
17
|
make: make
|
|
18
18
|
};
|
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
// a deploy-time dep into its ESM import graph (which fails resolution on real
|
|
7
7
|
// Lambda). The thin `QueryDbStorage_Postgres` wrapper `include`s this and adds the
|
|
8
8
|
// deploy-time `Pulumi.Output`-shaped `storage` record + the `Make` functor.
|
|
9
|
-
// See docs/plans/deployed-lambda-esm-self-containment.md (Rung-3 finding).
|
|
9
|
+
// See docs/plans/done/deployed-lambda-esm-self-containment.md (Rung-3 finding).
|
|
10
10
|
|
|
11
11
|
open ReventlessCore
|
|
12
12
|
open Reventless.ReadModel
|
|
@@ -63,18 +63,18 @@ let subIdSql = (b: paramBuilder, field: string, cmp: QueryEngine.SubId.comparato
|
|
|
63
63
|
}
|
|
64
64
|
}
|
|
65
65
|
|
|
66
|
-
let notExpired =
|
|
66
|
+
let notExpired = QueryDbStorage_Postgres_Ops.notExpiredClause
|
|
67
67
|
|
|
68
68
|
// Add `id` (from partition_key) when absent — matches allRows/scan in the SQLite
|
|
69
69
|
// engine; partition-key queries return items as stored.
|
|
70
70
|
let decodeRow = (~withId, row: dict<JSON.t>): JSON.t => {
|
|
71
|
-
let item =
|
|
71
|
+
let item = QueryDbStorage_Postgres_Ops.decodeItem(row)
|
|
72
72
|
if withId {
|
|
73
73
|
let pk = switch row->Dict.get("partition_key") {
|
|
74
74
|
| Some(JSON.String(s)) => s
|
|
75
75
|
| _ => ""
|
|
76
76
|
}
|
|
77
|
-
|
|
77
|
+
QueryDbStorage_Postgres_Ops.withId(item, pk)
|
|
78
78
|
} else {
|
|
79
79
|
item
|
|
80
80
|
}
|
|
@@ -90,7 +90,7 @@ module Make = (P: {let pool: PgDriver.pool}) => {
|
|
|
90
90
|
~ascending=?,
|
|
91
91
|
~limit=?,
|
|
92
92
|
): array<JSON.t> => {
|
|
93
|
-
let table =
|
|
93
|
+
let table = QueryDbStorage_Postgres_Ops.tableName(readModelName)
|
|
94
94
|
let keyStr = switch key {
|
|
95
95
|
| Some(k) => k
|
|
96
96
|
| None => valueToText(id)
|
|
@@ -114,7 +114,7 @@ module Make = (P: {let pool: PgDriver.pool}) => {
|
|
|
114
114
|
}
|
|
115
115
|
|
|
116
116
|
let scan = async (~readModelName, ~filterConfigs, ~limit): array<JSON.t> => {
|
|
117
|
-
let table =
|
|
117
|
+
let table = QueryDbStorage_Postgres_Ops.tableName(readModelName)
|
|
118
118
|
let b = {params: []}
|
|
119
119
|
let where = [notExpired]
|
|
120
120
|
filterConfigs->Array.forEach(((field, cmp, v)) => where->Array.push(filterSql(b, field, cmp, v)))
|
|
@@ -138,7 +138,7 @@ module Make = (P: {let pool: PgDriver.pool}) => {
|
|
|
138
138
|
// (`ensureIndexes`) instead of scanning. String comparison mirrors the
|
|
139
139
|
// resolver's JS path (which only matched string-typed fields).
|
|
140
140
|
let indexLookup = async (~readModelName, field: string, value: string): array<JSON.t> => {
|
|
141
|
-
let table =
|
|
141
|
+
let table = QueryDbStorage_Postgres_Ops.tableName(readModelName)
|
|
142
142
|
let b = {params: []}
|
|
143
143
|
let sql = `SELECT partition_key, item FROM ${table} WHERE ${col(field)} = ${b->param(
|
|
144
144
|
JSON.Encode.string(value),
|
|
@@ -154,7 +154,7 @@ module Make = (P: {let pool: PgDriver.pool}) => {
|
|
|
154
154
|
if ids->Array.length == 0 {
|
|
155
155
|
[]
|
|
156
156
|
} else {
|
|
157
|
-
let table =
|
|
157
|
+
let table = QueryDbStorage_Postgres_Ops.tableName(readModelName)
|
|
158
158
|
let b = {params: []}
|
|
159
159
|
let idsJson = JSON.Encode.array(ids->Array.map(JSON.Encode.string))
|
|
160
160
|
let sql = `SELECT partition_key, item FROM ${table} WHERE partition_key = ANY(${b->param(
|
|
@@ -168,6 +168,39 @@ module Make = (P: {let pool: PgDriver.pool}) => {
|
|
|
168
168
|
let idExprC = `COALESCE(item->>'id', partition_key) COLLATE "C"`
|
|
169
169
|
let jsonTextC = (field: string): string => `${col(field)} COLLATE "C"`
|
|
170
170
|
|
|
171
|
+
// "not retired", as jsonb rather than text. `->` keeps the value typed, so a
|
|
172
|
+
// JSON boolean true is distinguishable from the JSON string "true"; `->>`
|
|
173
|
+
// would render both as 'true' and hide a row the shared spec keeps, since that
|
|
174
|
+
// spec decodes strictly and reads a non-boolean as "no flag". `IS DISTINCT
|
|
175
|
+
// FROM` rather than `<>` so an absent key — NULL — keeps the row instead of
|
|
176
|
+
// making the whole predicate NULL and dropping it.
|
|
177
|
+
//
|
|
178
|
+
// The state form compares against JSON strings instead of `true`, one
|
|
179
|
+
// `IS DISTINCT FROM` per state, ANDed. Not `NOT IN`: that is ordinary
|
|
180
|
+
// equality, so an absent key makes the predicate NULL and drops a row this
|
|
181
|
+
// spec keeps. Same shape and same index behaviour as the single-state form —
|
|
182
|
+
// a handful of equality predicates over an enum-valued attribute cost what one
|
|
183
|
+
// over a boolean does — so the `@index` guidance carries over unchanged.
|
|
184
|
+
//
|
|
185
|
+
// A set naming no states withdraws nothing, so the predicate is vacuously
|
|
186
|
+
// true, matching what `isRetiredValue` answers for it.
|
|
187
|
+
let notRetiredC = (scope: Reventless.OwnerScope.retiredScope): string => {
|
|
188
|
+
let key = scope.field->String.replaceAll("'", "''")
|
|
189
|
+
let distinctFrom = lit => `(item->'${key}') IS DISTINCT FROM ${lit}`
|
|
190
|
+
switch scope.values {
|
|
191
|
+
| None => distinctFrom("'true'::jsonb")
|
|
192
|
+
| Some([]) => "TRUE"
|
|
193
|
+
| Some(states) =>
|
|
194
|
+
// Parenthesised though every caller ANDs these together already: a clause
|
|
195
|
+
// that is safe only because of where it is spliced is a clause that breaks
|
|
196
|
+
// the first time it is spliced somewhere else.
|
|
197
|
+
"(" ++
|
|
198
|
+
states
|
|
199
|
+
->Array.map(state => distinctFrom(`'"${state->String.replaceAll("'", "''")}"'::jsonb`))
|
|
200
|
+
->Array.join(" AND ") ++ ")"
|
|
201
|
+
}
|
|
202
|
+
}
|
|
203
|
+
|
|
171
204
|
// Connection-list push-down. Builds `item->>'field'` predicates + keyset
|
|
172
205
|
// WHERE + `ORDER BY … LIMIT pageSize+1` so a page reads only what it returns
|
|
173
206
|
// rather than the whole read model. Reproduces `QueryDbListQuery` semantics
|
|
@@ -183,8 +216,10 @@ module Make = (P: {let pool: PgDriver.pool}) => {
|
|
|
183
216
|
~argsDict: dict<JSON.t>,
|
|
184
217
|
~capability: GraphQL_FragmentGenerator.serverCapability,
|
|
185
218
|
~labelField as _,
|
|
219
|
+
~ownerScope: option<(string, string)>=?,
|
|
220
|
+
~retiredScope: option<Reventless.OwnerScope.retiredScope>=?,
|
|
186
221
|
): option<JSON.t> => {
|
|
187
|
-
let table =
|
|
222
|
+
let table = QueryDbStorage_Postgres_Ops.tableName(readModelName)
|
|
188
223
|
let filterDict =
|
|
189
224
|
argsDict->Dict.get("filter")->Option.flatMap(JSON.Decode.object)->Option.getOr(Dict.make())
|
|
190
225
|
let strNonEmpty = k =>
|
|
@@ -210,6 +245,19 @@ module Make = (P: {let pool: PgDriver.pool}) => {
|
|
|
210
245
|
} else {
|
|
211
246
|
let b = {params: []}
|
|
212
247
|
let whereParts = [notExpired]
|
|
248
|
+
// Into the SQL, before the LIMIT — narrowing the returned page instead
|
|
249
|
+
// would hand back fewer rows than asked for while still claiming a next
|
|
250
|
+
// page. Mirrors the SQLite push-down; the parity harness holds the two
|
|
251
|
+
// and the shared spec to the same answer.
|
|
252
|
+
switch ownerScope {
|
|
253
|
+
| Some((field, required)) =>
|
|
254
|
+
whereParts->Array.push(`${jsonTextC(field)} = ${b->param(JSON.Encode.string(required))}`)
|
|
255
|
+
| None => ()
|
|
256
|
+
}
|
|
257
|
+
switch retiredScope {
|
|
258
|
+
| Some(scope) => whereParts->Array.push(notRetiredC(scope))
|
|
259
|
+
| None => ()
|
|
260
|
+
}
|
|
213
261
|
let valString = v =>
|
|
214
262
|
switch v->JSON.Decode.string {
|
|
215
263
|
| Some(s) => Some(s)
|
|
@@ -309,8 +357,10 @@ module Make = (P: {let pool: PgDriver.pool}) => {
|
|
|
309
357
|
~subIdField as _: string,
|
|
310
358
|
~id: string,
|
|
311
359
|
~argsDict: dict<JSON.t>,
|
|
360
|
+
~ownerScope: option<(string, string)>=?,
|
|
361
|
+
~retiredScope: option<Reventless.OwnerScope.retiredScope>=?,
|
|
312
362
|
): JSON.t => {
|
|
313
|
-
let table =
|
|
363
|
+
let table = QueryDbStorage_Postgres_Ops.tableName(readModelName)
|
|
314
364
|
let filterDict =
|
|
315
365
|
argsDict->Dict.get("filter")->Option.flatMap(JSON.Decode.object)->Option.getOr(Dict.make())
|
|
316
366
|
let fstr = k => filterDict->Dict.get(k)->Option.flatMap(JSON.Decode.string)
|
|
@@ -324,6 +374,16 @@ module Make = (P: {let pool: PgDriver.pool}) => {
|
|
|
324
374
|
let sk = `sub_key COLLATE "C"`
|
|
325
375
|
let b = {params: []}
|
|
326
376
|
let where = [`partition_key = ${b->param(JSON.Encode.string(id))}`, notExpired]
|
|
377
|
+
// Before the keyset window and the LIMIT, for the same reason as `listPage`.
|
|
378
|
+
switch ownerScope {
|
|
379
|
+
| Some((field, required)) =>
|
|
380
|
+
where->Array.push(`${jsonTextC(field)} = ${b->param(JSON.Encode.string(required))}`)
|
|
381
|
+
| None => ()
|
|
382
|
+
}
|
|
383
|
+
switch retiredScope {
|
|
384
|
+
| Some(scope) => where->Array.push(notRetiredC(scope))
|
|
385
|
+
| None => ()
|
|
386
|
+
}
|
|
327
387
|
fstr("prefix")->Option.forEach(p =>
|
|
328
388
|
where->Array.push(`starts_with(sub_key, ${b->param(JSON.Encode.string(p))})`)
|
|
329
389
|
)
|
|
@@ -380,7 +440,4 @@ module Make = (P: {let pool: PgDriver.pool}) => {
|
|
|
380
440
|
},
|
|
381
441
|
})
|
|
382
442
|
}
|
|
383
|
-
|
|
384
|
-
let make: QueryDb_Adapter.queryEngineMaker = _allQueryDbs =>
|
|
385
|
-
Pulumi.Output.make({QueryEngine.scan, query})
|
|
386
443
|
}
|
|
@@ -2,11 +2,10 @@
|
|
|
2
2
|
|
|
3
3
|
import * as Stdlib_JSON from "@rescript/runtime/lib/es6/Stdlib_JSON.js";
|
|
4
4
|
import * as Stdlib_Option from "@rescript/runtime/lib/es6/Stdlib_Option.js";
|
|
5
|
-
import * as Pulumi from "@pulumi/pulumi";
|
|
6
5
|
import * as Stdlib_Nullable from "@rescript/runtime/lib/es6/Stdlib_Nullable.js";
|
|
7
6
|
import * as PgDriver$ReventlessPostgres from "./PgDriver.res.mjs";
|
|
8
7
|
import * as QueryDbListQuery$ReventlessCore from "@reventlessdev/reventless-core/src/components/Api/QueryDbListQuery.res.mjs";
|
|
9
|
-
import * as
|
|
8
|
+
import * as QueryDbStorage_Postgres_Ops$ReventlessPostgres from "./QueryDbStorage_Postgres_Ops.res.mjs";
|
|
10
9
|
|
|
11
10
|
function valueToText(v) {
|
|
12
11
|
switch (v.TAG) {
|
|
@@ -105,25 +104,25 @@ function subIdSql(b, field, cmp, v) {
|
|
|
105
104
|
}
|
|
106
105
|
|
|
107
106
|
function decodeRow(withId, row) {
|
|
108
|
-
let item =
|
|
107
|
+
let item = QueryDbStorage_Postgres_Ops$ReventlessPostgres.decodeItem(row);
|
|
109
108
|
if (!withId) {
|
|
110
109
|
return item;
|
|
111
110
|
}
|
|
112
111
|
let match = row["partition_key"];
|
|
113
112
|
let pk = typeof match === "string" ? match : "";
|
|
114
|
-
return
|
|
113
|
+
return QueryDbStorage_Postgres_Ops$ReventlessPostgres.withId(item, pk);
|
|
115
114
|
}
|
|
116
115
|
|
|
117
116
|
function Make(P) {
|
|
118
117
|
let query = async (readModelName, key, id, subIdConfig, filterConfigs, ascending, limit) => {
|
|
119
|
-
let table =
|
|
118
|
+
let table = QueryDbStorage_Postgres_Ops$ReventlessPostgres.tableName(readModelName);
|
|
120
119
|
let keyStr = key !== undefined ? key : valueToText(id);
|
|
121
120
|
let b = {
|
|
122
121
|
params: []
|
|
123
122
|
};
|
|
124
123
|
let where = [
|
|
125
124
|
`partition_key = ` + param(b, keyStr),
|
|
126
|
-
|
|
125
|
+
QueryDbStorage_Postgres_Ops$ReventlessPostgres.notExpiredClause
|
|
127
126
|
];
|
|
128
127
|
if (subIdConfig !== undefined) {
|
|
129
128
|
where.push(subIdSql(b, subIdConfig[0], subIdConfig[1], subIdConfig[2]));
|
|
@@ -137,11 +136,11 @@ function Make(P) {
|
|
|
137
136
|
return (await PgDriver$ReventlessPostgres.query(P.pool, sql, b.params)).map(extra => decodeRow(false, extra));
|
|
138
137
|
};
|
|
139
138
|
let scan = async (readModelName, filterConfigs, limit) => {
|
|
140
|
-
let table =
|
|
139
|
+
let table = QueryDbStorage_Postgres_Ops$ReventlessPostgres.tableName(readModelName);
|
|
141
140
|
let b = {
|
|
142
141
|
params: []
|
|
143
142
|
};
|
|
144
|
-
let where = [
|
|
143
|
+
let where = [QueryDbStorage_Postgres_Ops$ReventlessPostgres.notExpiredClause];
|
|
145
144
|
filterConfigs.forEach(param => {
|
|
146
145
|
where.push(filterSql(b, param[0], param[1], param[2]));
|
|
147
146
|
});
|
|
@@ -149,29 +148,45 @@ function Make(P) {
|
|
|
149
148
|
return (await PgDriver$ReventlessPostgres.query(P.pool, sql, b.params)).map(extra => decodeRow(true, extra));
|
|
150
149
|
};
|
|
151
150
|
let indexLookup = async (readModelName, field, value) => {
|
|
152
|
-
let table =
|
|
151
|
+
let table = QueryDbStorage_Postgres_Ops$ReventlessPostgres.tableName(readModelName);
|
|
153
152
|
let b = {
|
|
154
153
|
params: []
|
|
155
154
|
};
|
|
156
|
-
let sql = `SELECT partition_key, item FROM ` + table + ` WHERE ` + col(field) + ` = ` + param(b, value) + ` AND ` +
|
|
155
|
+
let sql = `SELECT partition_key, item FROM ` + table + ` WHERE ` + col(field) + ` = ` + param(b, value) + ` AND ` + QueryDbStorage_Postgres_Ops$ReventlessPostgres.notExpiredClause;
|
|
157
156
|
return (await PgDriver$ReventlessPostgres.query(P.pool, sql, b.params)).map(extra => decodeRow(true, extra));
|
|
158
157
|
};
|
|
159
158
|
let byIds = async (readModelName, ids) => {
|
|
160
159
|
if (ids.length === 0) {
|
|
161
160
|
return [];
|
|
162
161
|
}
|
|
163
|
-
let table =
|
|
162
|
+
let table = QueryDbStorage_Postgres_Ops$ReventlessPostgres.tableName(readModelName);
|
|
164
163
|
let b = {
|
|
165
164
|
params: []
|
|
166
165
|
};
|
|
167
166
|
let idsJson = ids.map(prim => prim);
|
|
168
|
-
let sql = `SELECT partition_key, item FROM ` + table + ` WHERE partition_key = ANY(` + param(b, idsJson) + `::text[]) AND ` +
|
|
167
|
+
let sql = `SELECT partition_key, item FROM ` + table + ` WHERE partition_key = ANY(` + param(b, idsJson) + `::text[]) AND ` + QueryDbStorage_Postgres_Ops$ReventlessPostgres.notExpiredClause;
|
|
169
168
|
return (await PgDriver$ReventlessPostgres.query(P.pool, sql, b.params)).map(extra => decodeRow(true, extra));
|
|
170
169
|
};
|
|
171
170
|
let idExprC = `COALESCE(item->>'id', partition_key) COLLATE "C"`;
|
|
172
171
|
let jsonTextC = field => col(field) + ` COLLATE "C"`;
|
|
173
|
-
let
|
|
174
|
-
let
|
|
172
|
+
let notRetiredC = scope => {
|
|
173
|
+
let key = scope.field.replaceAll("'", "''");
|
|
174
|
+
let states = scope.values;
|
|
175
|
+
if (states !== undefined) {
|
|
176
|
+
if (states.length !== 0) {
|
|
177
|
+
return "(" + states.map(state => {
|
|
178
|
+
let lit = `'"` + state.replaceAll("'", "''") + `"'::jsonb`;
|
|
179
|
+
return `(item->'` + key + `') IS DISTINCT FROM ` + lit;
|
|
180
|
+
}).join(" AND ") + ")";
|
|
181
|
+
} else {
|
|
182
|
+
return "TRUE";
|
|
183
|
+
}
|
|
184
|
+
} else {
|
|
185
|
+
return `(item->'` + key + `') IS DISTINCT FROM ` + "'true'::jsonb";
|
|
186
|
+
}
|
|
187
|
+
};
|
|
188
|
+
let listPage = async (readModelName, argsDict, capability, param$1, ownerScope, retiredScope) => {
|
|
189
|
+
let table = QueryDbStorage_Postgres_Ops$ReventlessPostgres.tableName(readModelName);
|
|
175
190
|
let filterDict = Stdlib_Option.getOr(Stdlib_Option.flatMap(argsDict["filter"], Stdlib_JSON.Decode.object), {});
|
|
176
191
|
let strNonEmpty = k => Stdlib_Option.mapOr(Stdlib_Option.flatMap(filterDict[k], Stdlib_JSON.Decode.string), false, s => s.length > 0);
|
|
177
192
|
let hasIds = Stdlib_Option.mapOr(Stdlib_Option.flatMap(filterDict["ids"], Stdlib_JSON.Decode.array), false, a => a.length !== 0);
|
|
@@ -183,7 +198,13 @@ function Make(P) {
|
|
|
183
198
|
let b = {
|
|
184
199
|
params: []
|
|
185
200
|
};
|
|
186
|
-
let whereParts = [
|
|
201
|
+
let whereParts = [QueryDbStorage_Postgres_Ops$ReventlessPostgres.notExpiredClause];
|
|
202
|
+
if (ownerScope !== undefined) {
|
|
203
|
+
whereParts.push(jsonTextC(ownerScope[0]) + ` = ` + param(b, ownerScope[1]));
|
|
204
|
+
}
|
|
205
|
+
if (retiredScope !== undefined) {
|
|
206
|
+
whereParts.push(notRetiredC(retiredScope));
|
|
207
|
+
}
|
|
187
208
|
let valString = v => {
|
|
188
209
|
let s = Stdlib_JSON.Decode.string(v);
|
|
189
210
|
if (s !== undefined) {
|
|
@@ -232,8 +253,8 @@ function Make(P) {
|
|
|
232
253
|
let cursorValueOf = item => Stdlib_Option.getOr(QueryDbListQuery$ReventlessCore.getFieldString(item, cursorField), QueryDbListQuery$ReventlessCore.getId(item));
|
|
233
254
|
return QueryDbListQuery$ReventlessCore.buildConnection(pageItems, hasMore, false, cursorValueOf);
|
|
234
255
|
};
|
|
235
|
-
let itemsPage = async (readModelName, param$1, id, argsDict) => {
|
|
236
|
-
let table =
|
|
256
|
+
let itemsPage = async (readModelName, param$1, id, argsDict, ownerScope, retiredScope) => {
|
|
257
|
+
let table = QueryDbStorage_Postgres_Ops$ReventlessPostgres.tableName(readModelName);
|
|
237
258
|
let filterDict = Stdlib_Option.getOr(Stdlib_Option.flatMap(argsDict["filter"], Stdlib_JSON.Decode.object), {});
|
|
238
259
|
let fstr = k => Stdlib_Option.flatMap(filterDict[k], Stdlib_JSON.Decode.string);
|
|
239
260
|
let orderDesc = Stdlib_Option.mapOr(fstr("order"), false, o => o === "DESC");
|
|
@@ -248,8 +269,14 @@ function Make(P) {
|
|
|
248
269
|
};
|
|
249
270
|
let where = [
|
|
250
271
|
`partition_key = ` + param(b, id),
|
|
251
|
-
|
|
272
|
+
QueryDbStorage_Postgres_Ops$ReventlessPostgres.notExpiredClause
|
|
252
273
|
];
|
|
274
|
+
if (ownerScope !== undefined) {
|
|
275
|
+
where.push(jsonTextC(ownerScope[0]) + ` = ` + param(b, ownerScope[1]));
|
|
276
|
+
}
|
|
277
|
+
if (retiredScope !== undefined) {
|
|
278
|
+
where.push(notRetiredC(retiredScope));
|
|
279
|
+
}
|
|
253
280
|
Stdlib_Option.forEach(fstr("prefix"), p => {
|
|
254
281
|
where.push(`starts_with(sub_key, ` + param(b, p) + `)`);
|
|
255
282
|
});
|
|
@@ -304,10 +331,6 @@ function Make(P) {
|
|
|
304
331
|
}
|
|
305
332
|
};
|
|
306
333
|
};
|
|
307
|
-
let make = _allQueryDbs => Pulumi.output({
|
|
308
|
-
scan: scan,
|
|
309
|
-
query: query
|
|
310
|
-
});
|
|
311
334
|
return {
|
|
312
335
|
query: query,
|
|
313
336
|
scan: scan,
|
|
@@ -315,13 +338,13 @@ function Make(P) {
|
|
|
315
338
|
byIds: byIds,
|
|
316
339
|
idExprC: idExprC,
|
|
317
340
|
jsonTextC: jsonTextC,
|
|
341
|
+
notRetiredC: notRetiredC,
|
|
318
342
|
listPage: listPage,
|
|
319
|
-
itemsPage: itemsPage
|
|
320
|
-
make: make
|
|
343
|
+
itemsPage: itemsPage
|
|
321
344
|
};
|
|
322
345
|
}
|
|
323
346
|
|
|
324
|
-
let notExpired =
|
|
347
|
+
let notExpired = QueryDbStorage_Postgres_Ops$ReventlessPostgres.notExpiredClause;
|
|
325
348
|
|
|
326
349
|
export {
|
|
327
350
|
valueToText,
|
|
@@ -334,4 +357,4 @@ export {
|
|
|
334
357
|
decodeRow,
|
|
335
358
|
Make,
|
|
336
359
|
}
|
|
337
|
-
/*
|
|
360
|
+
/* PgDriver-ReventlessPostgres Not a pure module */
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|