@reventlessdev/reventless-postgres 3.0.0-alpha.87 → 3.0.0-alpha.89
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 +15 -0
- package/lib/bs/.compiler.log +2 -2
- package/lib/bs/compiler-info.json +1 -1
- 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_Ops-ReventlessPostgres.cmi +0 -0
- package/lib/bs/src/DcbEventLogStorage_Postgres_Ops-ReventlessPostgres.cmt +0 -0
- package/lib/bs/src/EventLogChangeFeed-ReventlessPostgres.cmi +0 -0
- package/lib/bs/src/EventLogChangeFeed-ReventlessPostgres.cmt +0 -0
- 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_Ops-ReventlessPostgres.cmi +0 -0
- package/lib/bs/src/EventLogStorage_Postgres_Ops-ReventlessPostgres.cmt +0 -0
- package/lib/bs/src/PgChangeFeed-ReventlessPostgres.cmi +0 -0
- package/lib/bs/src/PgChangeFeed-ReventlessPostgres.cmt +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_Ops-ReventlessPostgres.cmi +0 -0
- package/lib/bs/src/QueryDbStorage_Postgres_Ops-ReventlessPostgres.cmt +0 -0
- 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 +17 -0
- package/lib/bs/src/QueryEnginePostgres.res.mjs +8 -2
- package/lib/bs/tests/PostgresIntegrationTest-ReventlessPostgres.cmi +0 -0
- package/lib/bs/tests/PostgresIntegrationTest-ReventlessPostgres.cmt +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.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_Ops-ReventlessPostgres.cmi +0 -0
- package/lib/ocaml/DcbEventLogStorage_Postgres_Ops-ReventlessPostgres.cmt +0 -0
- package/lib/ocaml/EventLogChangeFeed-ReventlessPostgres.cmi +0 -0
- package/lib/ocaml/EventLogChangeFeed-ReventlessPostgres.cmt +0 -0
- package/lib/ocaml/EventLogStorage_Postgres-ReventlessPostgres.cmi +0 -0
- package/lib/ocaml/EventLogStorage_Postgres-ReventlessPostgres.cmt +0 -0
- package/lib/ocaml/EventLogStorage_Postgres_Ops-ReventlessPostgres.cmi +0 -0
- package/lib/ocaml/EventLogStorage_Postgres_Ops-ReventlessPostgres.cmt +0 -0
- package/lib/ocaml/PgChangeFeed-ReventlessPostgres.cmi +0 -0
- package/lib/ocaml/PgChangeFeed-ReventlessPostgres.cmt +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_Ops-ReventlessPostgres.cmi +0 -0
- package/lib/ocaml/QueryDbStorage_Postgres_Ops-ReventlessPostgres.cmt +0 -0
- 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 +17 -0
- package/package.json +4 -4
- package/src/QueryEnginePostgres.res +17 -0
- package/src/QueryEnginePostgres.res.mjs +8 -2
package/CHANGELOG.md
CHANGED
|
@@ -3,6 +3,21 @@
|
|
|
3
3
|
All notable changes to this project will be documented in this file.
|
|
4
4
|
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
|
5
5
|
|
|
6
|
+
# 3.0.0-alpha.89 (2026-08-12)
|
|
7
|
+
|
|
8
|
+
### Features
|
|
9
|
+
|
|
10
|
+
* **queries:** narrow owner-bearing reads to the caller ([ba9cc3d](https://github.com/ReventlessDev/reventless-core/commit/ba9cc3d58d7914a9e4827bda90a704a74b1b82dd))
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
# 3.0.0-alpha.88 (2026-08-11)
|
|
14
|
+
|
|
15
|
+
**Note:** Version bump only for package @reventlessdev/reventless-postgres
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
|
|
6
21
|
# 3.0.0-alpha.87 (2026-08-10)
|
|
7
22
|
|
|
8
23
|
**Note:** Version bump only for package @reventlessdev/reventless-postgres
|
package/lib/bs/.compiler.log
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
#Start(
|
|
2
|
-
#Done(
|
|
1
|
+
#Start(1786519558375)
|
|
2
|
+
#Done(1786519562738)
|
|
@@ -4,5 +4,5 @@
|
|
|
4
4
|
"bsc_hash": "75e3a59c95cc953608fd3dd6ea6ed68141bba4414a20a52f114261b8a48385fa",
|
|
5
5
|
"rescript_config_hash": "af2af60a0fa33b8249a96ff2758f36482843126dc4e07b9302842d011e0ad8c6",
|
|
6
6
|
"runtime_path": "/home/runner/work/reventless-core/reventless-core/node_modules/@rescript/runtime",
|
|
7
|
-
"generated_at": "
|
|
7
|
+
"generated_at": "1786519562743"
|
|
8
8
|
}
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
@@ -183,6 +183,7 @@ module Make = (P: {let pool: PgDriver.pool}) => {
|
|
|
183
183
|
~argsDict: dict<JSON.t>,
|
|
184
184
|
~capability: GraphQL_FragmentGenerator.serverCapability,
|
|
185
185
|
~labelField as _,
|
|
186
|
+
~ownerScope: option<(string, string)>=?,
|
|
186
187
|
): option<JSON.t> => {
|
|
187
188
|
let table = QueryDbStorage_Postgres_Ops.tableName(readModelName)
|
|
188
189
|
let filterDict =
|
|
@@ -210,6 +211,15 @@ module Make = (P: {let pool: PgDriver.pool}) => {
|
|
|
210
211
|
} else {
|
|
211
212
|
let b = {params: []}
|
|
212
213
|
let whereParts = [notExpired]
|
|
214
|
+
// Into the SQL, before the LIMIT — narrowing the returned page instead
|
|
215
|
+
// would hand back fewer rows than asked for while still claiming a next
|
|
216
|
+
// page. Mirrors the SQLite push-down; the parity harness holds the two
|
|
217
|
+
// and the shared spec to the same answer.
|
|
218
|
+
switch ownerScope {
|
|
219
|
+
| Some((field, required)) =>
|
|
220
|
+
whereParts->Array.push(`${jsonTextC(field)} = ${b->param(JSON.Encode.string(required))}`)
|
|
221
|
+
| None => ()
|
|
222
|
+
}
|
|
213
223
|
let valString = v =>
|
|
214
224
|
switch v->JSON.Decode.string {
|
|
215
225
|
| Some(s) => Some(s)
|
|
@@ -309,6 +319,7 @@ module Make = (P: {let pool: PgDriver.pool}) => {
|
|
|
309
319
|
~subIdField as _: string,
|
|
310
320
|
~id: string,
|
|
311
321
|
~argsDict: dict<JSON.t>,
|
|
322
|
+
~ownerScope: option<(string, string)>=?,
|
|
312
323
|
): JSON.t => {
|
|
313
324
|
let table = QueryDbStorage_Postgres_Ops.tableName(readModelName)
|
|
314
325
|
let filterDict =
|
|
@@ -324,6 +335,12 @@ module Make = (P: {let pool: PgDriver.pool}) => {
|
|
|
324
335
|
let sk = `sub_key COLLATE "C"`
|
|
325
336
|
let b = {params: []}
|
|
326
337
|
let where = [`partition_key = ${b->param(JSON.Encode.string(id))}`, notExpired]
|
|
338
|
+
// Before the keyset window and the LIMIT, for the same reason as `listPage`.
|
|
339
|
+
switch ownerScope {
|
|
340
|
+
| Some((field, required)) =>
|
|
341
|
+
where->Array.push(`${jsonTextC(field)} = ${b->param(JSON.Encode.string(required))}`)
|
|
342
|
+
| None => ()
|
|
343
|
+
}
|
|
327
344
|
fstr("prefix")->Option.forEach(p =>
|
|
328
345
|
where->Array.push(`starts_with(sub_key, ${b->param(JSON.Encode.string(p))})`)
|
|
329
346
|
)
|
|
@@ -169,7 +169,7 @@ function Make(P) {
|
|
|
169
169
|
};
|
|
170
170
|
let idExprC = `COALESCE(item->>'id', partition_key) COLLATE "C"`;
|
|
171
171
|
let jsonTextC = field => col(field) + ` COLLATE "C"`;
|
|
172
|
-
let listPage = async (readModelName, argsDict, capability, param$1) => {
|
|
172
|
+
let listPage = async (readModelName, argsDict, capability, param$1, ownerScope) => {
|
|
173
173
|
let table = QueryDbStorage_Postgres_Ops$ReventlessPostgres.tableName(readModelName);
|
|
174
174
|
let filterDict = Stdlib_Option.getOr(Stdlib_Option.flatMap(argsDict["filter"], Stdlib_JSON.Decode.object), {});
|
|
175
175
|
let strNonEmpty = k => Stdlib_Option.mapOr(Stdlib_Option.flatMap(filterDict[k], Stdlib_JSON.Decode.string), false, s => s.length > 0);
|
|
@@ -183,6 +183,9 @@ function Make(P) {
|
|
|
183
183
|
params: []
|
|
184
184
|
};
|
|
185
185
|
let whereParts = [QueryDbStorage_Postgres_Ops$ReventlessPostgres.notExpiredClause];
|
|
186
|
+
if (ownerScope !== undefined) {
|
|
187
|
+
whereParts.push(jsonTextC(ownerScope[0]) + ` = ` + param(b, ownerScope[1]));
|
|
188
|
+
}
|
|
186
189
|
let valString = v => {
|
|
187
190
|
let s = Stdlib_JSON.Decode.string(v);
|
|
188
191
|
if (s !== undefined) {
|
|
@@ -231,7 +234,7 @@ function Make(P) {
|
|
|
231
234
|
let cursorValueOf = item => Stdlib_Option.getOr(QueryDbListQuery$ReventlessCore.getFieldString(item, cursorField), QueryDbListQuery$ReventlessCore.getId(item));
|
|
232
235
|
return QueryDbListQuery$ReventlessCore.buildConnection(pageItems, hasMore, false, cursorValueOf);
|
|
233
236
|
};
|
|
234
|
-
let itemsPage = async (readModelName, param$1, id, argsDict) => {
|
|
237
|
+
let itemsPage = async (readModelName, param$1, id, argsDict, ownerScope) => {
|
|
235
238
|
let table = QueryDbStorage_Postgres_Ops$ReventlessPostgres.tableName(readModelName);
|
|
236
239
|
let filterDict = Stdlib_Option.getOr(Stdlib_Option.flatMap(argsDict["filter"], Stdlib_JSON.Decode.object), {});
|
|
237
240
|
let fstr = k => Stdlib_Option.flatMap(filterDict[k], Stdlib_JSON.Decode.string);
|
|
@@ -249,6 +252,9 @@ function Make(P) {
|
|
|
249
252
|
`partition_key = ` + param(b, id),
|
|
250
253
|
QueryDbStorage_Postgres_Ops$ReventlessPostgres.notExpiredClause
|
|
251
254
|
];
|
|
255
|
+
if (ownerScope !== undefined) {
|
|
256
|
+
where.push(jsonTextC(ownerScope[0]) + ` = ` + param(b, ownerScope[1]));
|
|
257
|
+
}
|
|
252
258
|
Stdlib_Option.forEach(fstr("prefix"), p => {
|
|
253
259
|
where.push(`starts_with(sub_key, ` + param(b, p) + `)`);
|
|
254
260
|
});
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
@@ -122,7 +122,7 @@ function orderBy(f, dir) {
|
|
|
122
122
|
}
|
|
123
123
|
|
|
124
124
|
function expectedFor(argsDict) {
|
|
125
|
-
return norm(QueryDbListQuery$ReventlessCore.run(seededItems, argsDict, capability, "name", param => {}));
|
|
125
|
+
return norm(QueryDbListQuery$ReventlessCore.run(seededItems, argsDict, capability, "name", param => {}, undefined));
|
|
126
126
|
}
|
|
127
127
|
|
|
128
128
|
let url = process.env["PG_URL"];
|
|
@@ -148,7 +148,7 @@ if (url !== undefined) {
|
|
|
148
148
|
});
|
|
149
149
|
let checkPushed = async (label, args) => {
|
|
150
150
|
let argsDict = Object.fromEntries(args);
|
|
151
|
-
let actual = await Eng.listPage(name, argsDict, capability, "name");
|
|
151
|
+
let actual = await Eng.listPage(name, argsDict, capability, "name", undefined);
|
|
152
152
|
if (actual !== undefined) {
|
|
153
153
|
globalThis.expect(norm(actual)).toEqual(expectedFor(argsDict));
|
|
154
154
|
} else {
|
|
@@ -156,7 +156,7 @@ if (url !== undefined) {
|
|
|
156
156
|
}
|
|
157
157
|
};
|
|
158
158
|
let checkFallback = async args => {
|
|
159
|
-
let r = await Eng.listPage(name, Object.fromEntries(args), capability, "name");
|
|
159
|
+
let r = await Eng.listPage(name, Object.fromEntries(args), capability, "name", undefined);
|
|
160
160
|
globalThis.expect(Stdlib_Option.isSome(r)).toBe(false);
|
|
161
161
|
};
|
|
162
162
|
globalThis.describe("QueryDb list push-down parity (Postgres ≡ QueryDbListQuery spec)", () => {
|
|
@@ -322,7 +322,7 @@ if (url !== undefined) {
|
|
|
322
322
|
});
|
|
323
323
|
let itemSeqs = conn => Stdlib_Array.filterMap(Stdlib_Option.getOr(Stdlib_Option.flatMap(field(conn, "edges"), Stdlib_JSON.Decode.array), []), e => Stdlib_Option.flatMap(field(e, "node"), n => str(n, "seq")));
|
|
324
324
|
let pageInfoBool = (conn, key) => Stdlib_Option.getOr(Stdlib_Option.flatMap(field(Stdlib_Option.getOr(field(conn, "pageInfo"), null), key), Stdlib_JSON.Decode.bool), false);
|
|
325
|
-
let itemsPage = args => Eng.itemsPage(itemsName, "seq", "order-1", Object.fromEntries(args));
|
|
325
|
+
let itemsPage = args => Eng.itemsPage(itemsName, "seq", "order-1", Object.fromEntries(args), undefined);
|
|
326
326
|
globalThis.describe("QueryEnginePostgres itemsPage (sub-id keyset)", () => {
|
|
327
327
|
globalThis.test("bare → all lines ASC, no next page", async () => {
|
|
328
328
|
let r = await itemsPage([]);
|
package/lib/ocaml/.compiler.log
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
#Start(
|
|
2
|
-
#Done(
|
|
1
|
+
#Start(1786519558375)
|
|
2
|
+
#Done(1786519562738)
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
@@ -183,6 +183,7 @@ module Make = (P: {let pool: PgDriver.pool}) => {
|
|
|
183
183
|
~argsDict: dict<JSON.t>,
|
|
184
184
|
~capability: GraphQL_FragmentGenerator.serverCapability,
|
|
185
185
|
~labelField as _,
|
|
186
|
+
~ownerScope: option<(string, string)>=?,
|
|
186
187
|
): option<JSON.t> => {
|
|
187
188
|
let table = QueryDbStorage_Postgres_Ops.tableName(readModelName)
|
|
188
189
|
let filterDict =
|
|
@@ -210,6 +211,15 @@ module Make = (P: {let pool: PgDriver.pool}) => {
|
|
|
210
211
|
} else {
|
|
211
212
|
let b = {params: []}
|
|
212
213
|
let whereParts = [notExpired]
|
|
214
|
+
// Into the SQL, before the LIMIT — narrowing the returned page instead
|
|
215
|
+
// would hand back fewer rows than asked for while still claiming a next
|
|
216
|
+
// page. Mirrors the SQLite push-down; the parity harness holds the two
|
|
217
|
+
// and the shared spec to the same answer.
|
|
218
|
+
switch ownerScope {
|
|
219
|
+
| Some((field, required)) =>
|
|
220
|
+
whereParts->Array.push(`${jsonTextC(field)} = ${b->param(JSON.Encode.string(required))}`)
|
|
221
|
+
| None => ()
|
|
222
|
+
}
|
|
213
223
|
let valString = v =>
|
|
214
224
|
switch v->JSON.Decode.string {
|
|
215
225
|
| Some(s) => Some(s)
|
|
@@ -309,6 +319,7 @@ module Make = (P: {let pool: PgDriver.pool}) => {
|
|
|
309
319
|
~subIdField as _: string,
|
|
310
320
|
~id: string,
|
|
311
321
|
~argsDict: dict<JSON.t>,
|
|
322
|
+
~ownerScope: option<(string, string)>=?,
|
|
312
323
|
): JSON.t => {
|
|
313
324
|
let table = QueryDbStorage_Postgres_Ops.tableName(readModelName)
|
|
314
325
|
let filterDict =
|
|
@@ -324,6 +335,12 @@ module Make = (P: {let pool: PgDriver.pool}) => {
|
|
|
324
335
|
let sk = `sub_key COLLATE "C"`
|
|
325
336
|
let b = {params: []}
|
|
326
337
|
let where = [`partition_key = ${b->param(JSON.Encode.string(id))}`, notExpired]
|
|
338
|
+
// Before the keyset window and the LIMIT, for the same reason as `listPage`.
|
|
339
|
+
switch ownerScope {
|
|
340
|
+
| Some((field, required)) =>
|
|
341
|
+
where->Array.push(`${jsonTextC(field)} = ${b->param(JSON.Encode.string(required))}`)
|
|
342
|
+
| None => ()
|
|
343
|
+
}
|
|
327
344
|
fstr("prefix")->Option.forEach(p =>
|
|
328
345
|
where->Array.push(`starts_with(sub_key, ${b->param(JSON.Encode.string(p))})`)
|
|
329
346
|
)
|
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.89",
|
|
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": {
|
|
@@ -25,9 +25,9 @@
|
|
|
25
25
|
"@reventlessdev/rescript-effect": "0.1.0-alpha.32",
|
|
26
26
|
"@reventlessdev/rescript-jest": "1.0.0-alpha.10",
|
|
27
27
|
"@reventlessdev/rescript-pulumi-pulumi": "2.3.0-alpha.18",
|
|
28
|
-
"@reventlessdev/reventless-core": "3.0.0-alpha.
|
|
29
|
-
"@reventlessdev/reventless-infra": "3.0.0-alpha.
|
|
30
|
-
"@reventlessdev/reventless-spec": "3.0.0-alpha.
|
|
28
|
+
"@reventlessdev/reventless-core": "3.0.0-alpha.225",
|
|
29
|
+
"@reventlessdev/reventless-infra": "3.0.0-alpha.135",
|
|
30
|
+
"@reventlessdev/reventless-spec": "3.0.0-alpha.109"
|
|
31
31
|
},
|
|
32
32
|
"devDependencies": {
|
|
33
33
|
"@types/pg": "^8.11.10",
|
|
@@ -183,6 +183,7 @@ module Make = (P: {let pool: PgDriver.pool}) => {
|
|
|
183
183
|
~argsDict: dict<JSON.t>,
|
|
184
184
|
~capability: GraphQL_FragmentGenerator.serverCapability,
|
|
185
185
|
~labelField as _,
|
|
186
|
+
~ownerScope: option<(string, string)>=?,
|
|
186
187
|
): option<JSON.t> => {
|
|
187
188
|
let table = QueryDbStorage_Postgres_Ops.tableName(readModelName)
|
|
188
189
|
let filterDict =
|
|
@@ -210,6 +211,15 @@ module Make = (P: {let pool: PgDriver.pool}) => {
|
|
|
210
211
|
} else {
|
|
211
212
|
let b = {params: []}
|
|
212
213
|
let whereParts = [notExpired]
|
|
214
|
+
// Into the SQL, before the LIMIT — narrowing the returned page instead
|
|
215
|
+
// would hand back fewer rows than asked for while still claiming a next
|
|
216
|
+
// page. Mirrors the SQLite push-down; the parity harness holds the two
|
|
217
|
+
// and the shared spec to the same answer.
|
|
218
|
+
switch ownerScope {
|
|
219
|
+
| Some((field, required)) =>
|
|
220
|
+
whereParts->Array.push(`${jsonTextC(field)} = ${b->param(JSON.Encode.string(required))}`)
|
|
221
|
+
| None => ()
|
|
222
|
+
}
|
|
213
223
|
let valString = v =>
|
|
214
224
|
switch v->JSON.Decode.string {
|
|
215
225
|
| Some(s) => Some(s)
|
|
@@ -309,6 +319,7 @@ module Make = (P: {let pool: PgDriver.pool}) => {
|
|
|
309
319
|
~subIdField as _: string,
|
|
310
320
|
~id: string,
|
|
311
321
|
~argsDict: dict<JSON.t>,
|
|
322
|
+
~ownerScope: option<(string, string)>=?,
|
|
312
323
|
): JSON.t => {
|
|
313
324
|
let table = QueryDbStorage_Postgres_Ops.tableName(readModelName)
|
|
314
325
|
let filterDict =
|
|
@@ -324,6 +335,12 @@ module Make = (P: {let pool: PgDriver.pool}) => {
|
|
|
324
335
|
let sk = `sub_key COLLATE "C"`
|
|
325
336
|
let b = {params: []}
|
|
326
337
|
let where = [`partition_key = ${b->param(JSON.Encode.string(id))}`, notExpired]
|
|
338
|
+
// Before the keyset window and the LIMIT, for the same reason as `listPage`.
|
|
339
|
+
switch ownerScope {
|
|
340
|
+
| Some((field, required)) =>
|
|
341
|
+
where->Array.push(`${jsonTextC(field)} = ${b->param(JSON.Encode.string(required))}`)
|
|
342
|
+
| None => ()
|
|
343
|
+
}
|
|
327
344
|
fstr("prefix")->Option.forEach(p =>
|
|
328
345
|
where->Array.push(`starts_with(sub_key, ${b->param(JSON.Encode.string(p))})`)
|
|
329
346
|
)
|
|
@@ -169,7 +169,7 @@ function Make(P) {
|
|
|
169
169
|
};
|
|
170
170
|
let idExprC = `COALESCE(item->>'id', partition_key) COLLATE "C"`;
|
|
171
171
|
let jsonTextC = field => col(field) + ` COLLATE "C"`;
|
|
172
|
-
let listPage = async (readModelName, argsDict, capability, param$1) => {
|
|
172
|
+
let listPage = async (readModelName, argsDict, capability, param$1, ownerScope) => {
|
|
173
173
|
let table = QueryDbStorage_Postgres_Ops$ReventlessPostgres.tableName(readModelName);
|
|
174
174
|
let filterDict = Stdlib_Option.getOr(Stdlib_Option.flatMap(argsDict["filter"], Stdlib_JSON.Decode.object), {});
|
|
175
175
|
let strNonEmpty = k => Stdlib_Option.mapOr(Stdlib_Option.flatMap(filterDict[k], Stdlib_JSON.Decode.string), false, s => s.length > 0);
|
|
@@ -183,6 +183,9 @@ function Make(P) {
|
|
|
183
183
|
params: []
|
|
184
184
|
};
|
|
185
185
|
let whereParts = [QueryDbStorage_Postgres_Ops$ReventlessPostgres.notExpiredClause];
|
|
186
|
+
if (ownerScope !== undefined) {
|
|
187
|
+
whereParts.push(jsonTextC(ownerScope[0]) + ` = ` + param(b, ownerScope[1]));
|
|
188
|
+
}
|
|
186
189
|
let valString = v => {
|
|
187
190
|
let s = Stdlib_JSON.Decode.string(v);
|
|
188
191
|
if (s !== undefined) {
|
|
@@ -231,7 +234,7 @@ function Make(P) {
|
|
|
231
234
|
let cursorValueOf = item => Stdlib_Option.getOr(QueryDbListQuery$ReventlessCore.getFieldString(item, cursorField), QueryDbListQuery$ReventlessCore.getId(item));
|
|
232
235
|
return QueryDbListQuery$ReventlessCore.buildConnection(pageItems, hasMore, false, cursorValueOf);
|
|
233
236
|
};
|
|
234
|
-
let itemsPage = async (readModelName, param$1, id, argsDict) => {
|
|
237
|
+
let itemsPage = async (readModelName, param$1, id, argsDict, ownerScope) => {
|
|
235
238
|
let table = QueryDbStorage_Postgres_Ops$ReventlessPostgres.tableName(readModelName);
|
|
236
239
|
let filterDict = Stdlib_Option.getOr(Stdlib_Option.flatMap(argsDict["filter"], Stdlib_JSON.Decode.object), {});
|
|
237
240
|
let fstr = k => Stdlib_Option.flatMap(filterDict[k], Stdlib_JSON.Decode.string);
|
|
@@ -249,6 +252,9 @@ function Make(P) {
|
|
|
249
252
|
`partition_key = ` + param(b, id),
|
|
250
253
|
QueryDbStorage_Postgres_Ops$ReventlessPostgres.notExpiredClause
|
|
251
254
|
];
|
|
255
|
+
if (ownerScope !== undefined) {
|
|
256
|
+
where.push(jsonTextC(ownerScope[0]) + ` = ` + param(b, ownerScope[1]));
|
|
257
|
+
}
|
|
252
258
|
Stdlib_Option.forEach(fstr("prefix"), p => {
|
|
253
259
|
where.push(`starts_with(sub_key, ` + param(b, p) + `)`);
|
|
254
260
|
});
|