@reventlessdev/reventless-postgres 3.0.0-alpha.15 → 3.0.0-alpha.150

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.
Files changed (143) hide show
  1. package/CHANGELOG.md +1085 -0
  2. package/README.md +83 -0
  3. package/lib/bs/.compiler.log +2 -2
  4. package/lib/bs/ReventlessPostgres.cmt +0 -0
  5. package/lib/bs/ReventlessPostgres.mlmap +0 -2
  6. package/lib/bs/compiler-info.json +4 -4
  7. package/lib/bs/src/DcbEventLogStorage_Postgres-ReventlessPostgres.cmi +0 -0
  8. package/lib/bs/src/DcbEventLogStorage_Postgres-ReventlessPostgres.cmt +0 -0
  9. package/lib/bs/src/DcbEventLogStorage_Postgres.ast +0 -0
  10. package/lib/bs/src/DcbEventLogStorage_Postgres.res +1 -1
  11. package/lib/bs/src/DcbEventLogStorage_Postgres_Ops-ReventlessPostgres.cmi +0 -0
  12. package/lib/bs/src/DcbEventLogStorage_Postgres_Ops-ReventlessPostgres.cmt +0 -0
  13. package/lib/bs/src/DcbEventLogStorage_Postgres_Ops.ast +0 -0
  14. package/lib/bs/src/DcbEventLogStorage_Postgres_Ops.res +43 -42
  15. package/lib/bs/src/DcbEventLogStorage_Postgres_Ops.res.mjs +4 -4
  16. package/lib/bs/src/EventLogChangeFeed-ReventlessPostgres.cmi +0 -0
  17. package/lib/bs/src/EventLogChangeFeed-ReventlessPostgres.cmt +0 -0
  18. package/lib/bs/src/EventLogChangeFeed.ast +0 -0
  19. package/lib/bs/src/EventLogChangeFeed.res +15 -6
  20. package/lib/bs/src/EventLogChangeFeed.res.mjs +3 -3
  21. package/lib/bs/src/EventLogStorage_Postgres-ReventlessPostgres.cmi +0 -0
  22. package/lib/bs/src/EventLogStorage_Postgres-ReventlessPostgres.cmt +0 -0
  23. package/lib/bs/src/EventLogStorage_Postgres.ast +0 -0
  24. package/lib/bs/src/EventLogStorage_Postgres.res +1 -1
  25. package/lib/bs/src/EventLogStorage_Postgres_Ops-ReventlessPostgres.cmi +0 -0
  26. package/lib/bs/src/EventLogStorage_Postgres_Ops-ReventlessPostgres.cmt +0 -0
  27. package/lib/bs/src/EventLogStorage_Postgres_Ops.ast +0 -0
  28. package/lib/bs/src/EventLogStorage_Postgres_Ops.res +24 -14
  29. package/lib/bs/src/PgChangeFeed-ReventlessPostgres.cmi +0 -0
  30. package/lib/bs/src/PgChangeFeed-ReventlessPostgres.cmt +0 -0
  31. package/lib/bs/src/PgChangeFeed.ast +0 -0
  32. package/lib/bs/src/PgChangeFeed.res +21 -9
  33. package/lib/bs/src/PgChangeFeed.res.mjs +6 -6
  34. package/lib/bs/src/PgDriver-ReventlessPostgres.cmi +0 -0
  35. package/lib/bs/src/PgDriver-ReventlessPostgres.cmt +0 -0
  36. package/lib/bs/src/PgDriver-ReventlessPostgres.cmti +0 -0
  37. package/lib/bs/src/PgDriver.ast +0 -0
  38. package/lib/bs/src/PgDriver.iast +0 -0
  39. package/lib/bs/src/PgDriver.res +1 -2
  40. package/lib/bs/src/PgSchema-ReventlessPostgres.cmi +0 -0
  41. package/lib/bs/src/PgSchema-ReventlessPostgres.cmt +0 -0
  42. package/lib/bs/src/PgSchema.ast +0 -0
  43. package/lib/bs/src/QueryDbStorage_Postgres-ReventlessPostgres.cmi +0 -0
  44. package/lib/bs/src/QueryDbStorage_Postgres-ReventlessPostgres.cmt +0 -0
  45. package/lib/bs/src/QueryDbStorage_Postgres.ast +0 -0
  46. package/lib/bs/src/QueryDbStorage_Postgres.res +7 -2
  47. package/lib/bs/src/QueryDbStorage_Postgres.res.mjs +1 -1
  48. package/lib/bs/src/QueryDbStorage_Postgres_Ops-ReventlessPostgres.cmi +0 -0
  49. package/lib/bs/src/QueryDbStorage_Postgres_Ops-ReventlessPostgres.cmt +0 -0
  50. package/lib/bs/src/QueryDbStorage_Postgres_Ops.ast +0 -0
  51. package/lib/bs/src/QueryDbStorage_Postgres_Ops.res +14 -14
  52. package/lib/bs/src/QueryEnginePostgres-ReventlessPostgres.cmi +0 -0
  53. package/lib/bs/src/QueryEnginePostgres-ReventlessPostgres.cmt +0 -0
  54. package/lib/bs/src/QueryEnginePostgres.ast +0 -0
  55. package/lib/bs/src/QueryEnginePostgres.res +141 -42
  56. package/lib/bs/src/QueryEnginePostgres.res.mjs +53 -30
  57. package/lib/bs/tests/PostgresIntegrationTest-ReventlessPostgres.cmi +0 -0
  58. package/lib/bs/tests/PostgresIntegrationTest-ReventlessPostgres.cmt +0 -0
  59. package/lib/bs/tests/PostgresIntegrationTest.ast +0 -0
  60. package/lib/bs/tests/PostgresIntegrationTest.res +157 -104
  61. package/lib/bs/tests/QueryEnginePostgresListPageTest-ReventlessPostgres.cmi +0 -0
  62. package/lib/bs/tests/QueryEnginePostgresListPageTest-ReventlessPostgres.cmt +0 -0
  63. package/lib/bs/tests/QueryEnginePostgresListPageTest.ast +0 -0
  64. package/lib/bs/tests/QueryEnginePostgresListPageTest.res +29 -6
  65. package/lib/bs/tests/QueryEnginePostgresListPageTest.res.mjs +4 -4
  66. package/lib/ocaml/.compiler.log +2 -2
  67. package/lib/ocaml/DcbEventLogStorage_Postgres-ReventlessPostgres.cmi +0 -0
  68. package/lib/ocaml/DcbEventLogStorage_Postgres-ReventlessPostgres.cmt +0 -0
  69. package/lib/ocaml/DcbEventLogStorage_Postgres.ast +0 -0
  70. package/lib/ocaml/DcbEventLogStorage_Postgres.res +1 -1
  71. package/lib/ocaml/DcbEventLogStorage_Postgres_Ops-ReventlessPostgres.cmi +0 -0
  72. package/lib/ocaml/DcbEventLogStorage_Postgres_Ops-ReventlessPostgres.cmt +0 -0
  73. package/lib/ocaml/DcbEventLogStorage_Postgres_Ops.ast +0 -0
  74. package/lib/ocaml/DcbEventLogStorage_Postgres_Ops.res +43 -42
  75. package/lib/ocaml/EventLogChangeFeed-ReventlessPostgres.cmi +0 -0
  76. package/lib/ocaml/EventLogChangeFeed-ReventlessPostgres.cmt +0 -0
  77. package/lib/ocaml/EventLogChangeFeed.ast +0 -0
  78. package/lib/ocaml/EventLogChangeFeed.res +15 -6
  79. package/lib/ocaml/EventLogStorage_Postgres-ReventlessPostgres.cmi +0 -0
  80. package/lib/ocaml/EventLogStorage_Postgres-ReventlessPostgres.cmt +0 -0
  81. package/lib/ocaml/EventLogStorage_Postgres.ast +0 -0
  82. package/lib/ocaml/EventLogStorage_Postgres.res +1 -1
  83. package/lib/ocaml/EventLogStorage_Postgres_Ops-ReventlessPostgres.cmi +0 -0
  84. package/lib/ocaml/EventLogStorage_Postgres_Ops-ReventlessPostgres.cmt +0 -0
  85. package/lib/ocaml/EventLogStorage_Postgres_Ops.ast +0 -0
  86. package/lib/ocaml/EventLogStorage_Postgres_Ops.res +24 -14
  87. package/lib/ocaml/PgChangeFeed-ReventlessPostgres.cmi +0 -0
  88. package/lib/ocaml/PgChangeFeed-ReventlessPostgres.cmt +0 -0
  89. package/lib/ocaml/PgChangeFeed.ast +0 -0
  90. package/lib/ocaml/PgChangeFeed.res +21 -9
  91. package/lib/ocaml/PgDriver-ReventlessPostgres.cmi +0 -0
  92. package/lib/ocaml/PgDriver-ReventlessPostgres.cmt +0 -0
  93. package/lib/ocaml/PgDriver-ReventlessPostgres.cmti +0 -0
  94. package/lib/ocaml/PgDriver.ast +0 -0
  95. package/lib/ocaml/PgDriver.iast +0 -0
  96. package/lib/ocaml/PgDriver.res +1 -2
  97. package/lib/ocaml/PgSchema-ReventlessPostgres.cmi +0 -0
  98. package/lib/ocaml/PgSchema-ReventlessPostgres.cmt +0 -0
  99. package/lib/ocaml/PgSchema.ast +0 -0
  100. package/lib/ocaml/PostgresIntegrationTest.res +157 -104
  101. package/lib/ocaml/QueryDbStorage_Postgres-ReventlessPostgres.cmi +0 -0
  102. package/lib/ocaml/QueryDbStorage_Postgres-ReventlessPostgres.cmt +0 -0
  103. package/lib/ocaml/QueryDbStorage_Postgres.ast +0 -0
  104. package/lib/ocaml/QueryDbStorage_Postgres.res +7 -2
  105. package/lib/ocaml/QueryDbStorage_Postgres_Ops-ReventlessPostgres.cmi +0 -0
  106. package/lib/ocaml/QueryDbStorage_Postgres_Ops-ReventlessPostgres.cmt +0 -0
  107. package/lib/ocaml/QueryDbStorage_Postgres_Ops.ast +0 -0
  108. package/lib/ocaml/QueryDbStorage_Postgres_Ops.res +14 -14
  109. package/lib/ocaml/QueryEnginePostgres-ReventlessPostgres.cmi +0 -0
  110. package/lib/ocaml/QueryEnginePostgres-ReventlessPostgres.cmt +0 -0
  111. package/lib/ocaml/QueryEnginePostgres.ast +0 -0
  112. package/lib/ocaml/QueryEnginePostgres.res +141 -42
  113. package/lib/ocaml/QueryEnginePostgresListPageTest.res +29 -6
  114. package/lib/ocaml/ReventlessPostgres.cmt +0 -0
  115. package/package.json +13 -13
  116. package/rescript.json +2 -1
  117. package/src/DcbEventLogStorage_Postgres.res +1 -1
  118. package/src/DcbEventLogStorage_Postgres_Ops.res +43 -42
  119. package/src/DcbEventLogStorage_Postgres_Ops.res.mjs +4 -4
  120. package/src/EventLogChangeFeed.res +15 -6
  121. package/src/EventLogChangeFeed.res.mjs +3 -3
  122. package/src/EventLogStorage_Postgres.res +1 -1
  123. package/src/EventLogStorage_Postgres_Ops.res +24 -14
  124. package/src/PgChangeFeed.res +21 -9
  125. package/src/PgChangeFeed.res.mjs +6 -6
  126. package/src/PgDriver.res +1 -2
  127. package/src/QueryDbStorage_Postgres.res +7 -2
  128. package/src/QueryDbStorage_Postgres.res.mjs +1 -1
  129. package/src/QueryDbStorage_Postgres_Ops.res +14 -14
  130. package/src/QueryEnginePostgres.res +141 -42
  131. package/src/QueryEnginePostgres.res.mjs +53 -30
  132. package/tests/PostgresIntegrationTest.res +157 -104
  133. package/tests/QueryEnginePostgresListPageTest.res +29 -6
  134. package/lib/ocaml/PostgresIntegrationTest-ReventlessPostgres.cmi +0 -0
  135. package/lib/ocaml/PostgresIntegrationTest-ReventlessPostgres.cmj +0 -0
  136. package/lib/ocaml/PostgresIntegrationTest-ReventlessPostgres.cmt +0 -0
  137. package/lib/ocaml/PostgresIntegrationTest.ast +0 -0
  138. package/lib/ocaml/QueryEnginePostgresListPageTest-ReventlessPostgres.cmi +0 -0
  139. package/lib/ocaml/QueryEnginePostgresListPageTest-ReventlessPostgres.cmj +0 -0
  140. package/lib/ocaml/QueryEnginePostgresListPageTest-ReventlessPostgres.cmt +0 -0
  141. package/lib/ocaml/QueryEnginePostgresListPageTest.ast +0 -0
  142. package/tests/PostgresIntegrationTest.res.mjs +0 -377
  143. package/tests/QueryEnginePostgresListPageTest.res.mjs +0 -461
@@ -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 QueryDbStorage_Postgres$ReventlessPostgres from "./QueryDbStorage_Postgres.res.mjs";
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 = QueryDbStorage_Postgres$ReventlessPostgres.decodeItem(row);
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 QueryDbStorage_Postgres$ReventlessPostgres.withId(item, pk);
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 = QueryDbStorage_Postgres$ReventlessPostgres.tableName(readModelName);
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
- QueryDbStorage_Postgres$ReventlessPostgres.notExpiredClause
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 = QueryDbStorage_Postgres$ReventlessPostgres.tableName(readModelName);
139
+ let table = QueryDbStorage_Postgres_Ops$ReventlessPostgres.tableName(readModelName);
141
140
  let b = {
142
141
  params: []
143
142
  };
144
- let where = [QueryDbStorage_Postgres$ReventlessPostgres.notExpiredClause];
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 = QueryDbStorage_Postgres$ReventlessPostgres.tableName(readModelName);
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 ` + QueryDbStorage_Postgres$ReventlessPostgres.notExpiredClause;
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 = QueryDbStorage_Postgres$ReventlessPostgres.tableName(readModelName);
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 ` + QueryDbStorage_Postgres$ReventlessPostgres.notExpiredClause;
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 listPage = async (readModelName, argsDict, capability, param$1) => {
174
- let table = QueryDbStorage_Postgres$ReventlessPostgres.tableName(readModelName);
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 = [QueryDbStorage_Postgres$ReventlessPostgres.notExpiredClause];
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) {
@@ -214,11 +235,11 @@ function Make(P) {
214
235
  let orderByField = Stdlib_Option.flatMap(Stdlib_Option.flatMap(orderByDict, ob => ob["field"]), Stdlib_JSON.Decode.string);
215
236
  let isDesc = Stdlib_Option.getOr(Stdlib_Option.flatMap(Stdlib_Option.flatMap(orderByDict, ob => ob["direction"]), Stdlib_JSON.Decode.string), "ASC") === "DESC";
216
237
  let cursorExpr = orderByField !== undefined ? jsonTextC(orderByField) : idExprC;
217
- let c = Stdlib_Option.flatMap(argsDict["after"], Stdlib_JSON.Decode.string);
218
- if (c !== undefined) {
238
+ let afterCursor = Stdlib_Option.flatMap(argsDict["after"], Stdlib_JSON.Decode.string);
239
+ if (afterCursor !== undefined) {
219
240
  whereParts.push(cursorExpr + ` ` + (
220
241
  isDesc ? "<" : ">"
221
- ) + ` ` + param(b, QueryDbListQuery$ReventlessCore.decodeCursor(c)));
242
+ ) + ` ` + param(b, QueryDbListQuery$ReventlessCore.decodeCursor(afterCursor)));
222
243
  }
223
244
  let orderClause = orderByField !== undefined ? jsonTextC(orderByField) + ` ` + (
224
245
  isDesc ? "DESC" : "ASC"
@@ -230,10 +251,10 @@ function Make(P) {
230
251
  let pageItems = rows.slice(0, pageSize);
231
252
  let cursorField = Stdlib_Option.getOr(orderByField, "id");
232
253
  let cursorValueOf = item => Stdlib_Option.getOr(QueryDbListQuery$ReventlessCore.getFieldString(item, cursorField), QueryDbListQuery$ReventlessCore.getId(item));
233
- return QueryDbListQuery$ReventlessCore.buildConnection(pageItems, hasMore, false, cursorValueOf);
254
+ return QueryDbListQuery$ReventlessCore.buildConnection(pageItems, hasMore, Stdlib_Option.isSome(afterCursor), cursorValueOf);
234
255
  };
235
- let itemsPage = async (readModelName, param$1, id, argsDict) => {
236
- let table = QueryDbStorage_Postgres$ReventlessPostgres.tableName(readModelName);
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
- QueryDbStorage_Postgres$ReventlessPostgres.notExpiredClause
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 = QueryDbStorage_Postgres$ReventlessPostgres.notExpiredClause;
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
- /* @pulumi/pulumi Not a pure module */
360
+ /* PgDriver-ReventlessPostgres Not a pure module */
@@ -100,7 +100,11 @@ switch processEnv->Dict.get("PG_URL") {
100
100
 
101
101
  testPromise("append + read round-trips events with tags", async () => {
102
102
  let (_n, ops, _s) = makeLog("dcb-rt")
103
- let e1 = stored("ItemAdded", [{key: "itemId", value: "x1"}], jsonObj([("n", JSON.Encode.string("w"))]))
103
+ let e1 = stored(
104
+ "ItemAdded",
105
+ [{key: "itemId", value: "x1"}],
106
+ jsonObj([("n", JSON.Encode.string("w"))]),
107
+ )
104
108
  let r = await ops.append([e1])
105
109
  switch r {
106
110
  | Ok(_) => expect(true)->toBe(true)
@@ -116,7 +120,12 @@ switch processEnv->Dict.get("PG_URL") {
116
120
 
117
121
  testPromise("conditional append conflicts when the boundary already has an event", async () => {
118
122
  let (_n, ops, _s) = makeLog("dcb-cond")
119
- let mk = who => stored("Reserved", [{key: "seatId", value: "s1"}], jsonObj([("who", JSON.Encode.string(who))]))
123
+ let mk = who =>
124
+ stored(
125
+ "Reserved",
126
+ [{key: "seatId", value: "s1"}],
127
+ jsonObj([("who", JSON.Encode.string(who))]),
128
+ )
120
129
  let r1 = await ops.append([mk("a")])
121
130
  switch r1 {
122
131
  | Ok(_) => expect(true)->toBe(true)
@@ -134,37 +143,46 @@ switch processEnv->Dict.get("PG_URL") {
134
143
  })
135
144
 
136
145
  let writeSkew = (strategy, logName) =>
137
- testPromise(`write-skew: exactly one of two concurrent appends wins (${logName})`, async () => {
138
- let (_n, ops, _s) = DcbEventLogStorage_Postgres.makeStorage(
139
- ~pool,
140
- ~name=logName,
141
- ~indexes=[],
142
- ~partitionTag=DcbTag.Simple({key: "k"}),
143
- ~opts,
144
- ~lockStrategy=strategy,
145
- )
146
- let cond: DcbTag.appendCondition = {
147
- query: [{eventTypes: ["Reserved"], tags: [{key: "seatId", value: "hot"}]}],
148
- }
149
- let mk = who => stored("Reserved", [{key: "seatId", value: "hot"}], jsonObj([("who", JSON.Encode.string(who))]))
150
- // Dispatch BOTH before awaiting either — genuinely concurrent on the pool.
151
- let p1 = ops.append([mk("a")], ~condition=cond)
152
- let p2 = ops.append([mk("b")], ~condition=cond)
153
- let r1 = await p1
154
- let r2 = await p2
155
- let isOk = r => switch r {
156
- | Ok(_) => true
157
- | _ => false
158
- }
159
- let isConflict = r => r == Error(ReventlessInfra.DcbEventLog.Conflict)
160
- let oks = [r1, r2]->Array.filter(isOk)->Array.length
161
- let conflicts = [r1, r2]->Array.filter(isConflict)->Array.length
162
- expect(oks)->toBe(1)
163
- expect(conflicts)->toBe(1)
164
- // And only one event actually landed on the boundary.
165
- let read = await ops.read(~query=[{tags: [{key: "seatId", value: "hot"}]}])
166
- expect(read.events->Array.length)->toBe(1)
167
- })
146
+ testPromise(
147
+ `write-skew: exactly one of two concurrent appends wins (${logName})`,
148
+ async () => {
149
+ let (_n, ops, _s) = DcbEventLogStorage_Postgres.makeStorage(
150
+ ~pool,
151
+ ~name=logName,
152
+ ~indexes=[],
153
+ ~partitionTag=DcbTag.Simple({key: "k"}),
154
+ ~opts,
155
+ ~lockStrategy=strategy,
156
+ )
157
+ let cond: DcbTag.appendCondition = {
158
+ query: [{eventTypes: ["Reserved"], tags: [{key: "seatId", value: "hot"}]}],
159
+ }
160
+ let mk = who =>
161
+ stored(
162
+ "Reserved",
163
+ [{key: "seatId", value: "hot"}],
164
+ jsonObj([("who", JSON.Encode.string(who))]),
165
+ )
166
+ // Dispatch BOTH before awaiting either — genuinely concurrent on the pool.
167
+ let p1 = ops.append([mk("a")], ~condition=cond)
168
+ let p2 = ops.append([mk("b")], ~condition=cond)
169
+ let r1 = await p1
170
+ let r2 = await p2
171
+ let isOk = r =>
172
+ switch r {
173
+ | Ok(_) => true
174
+ | _ => false
175
+ }
176
+ let isConflict = r => r == Error(ReventlessInfra.DcbEventLog.Conflict)
177
+ let oks = [r1, r2]->Array.filter(isOk)->Array.length
178
+ let conflicts = [r1, r2]->Array.filter(isConflict)->Array.length
179
+ expect(oks)->toBe(1)
180
+ expect(conflicts)->toBe(1)
181
+ // And only one event actually landed on the boundary.
182
+ let read = await ops.read(~query=[{tags: [{key: "seatId", value: "hot"}]}])
183
+ expect(read.events->Array.length)->toBe(1)
184
+ },
185
+ )
168
186
 
169
187
  writeSkew(#AdvisoryLocks, "dcb-skew-advisory")
170
188
  writeSkew(#RowLocks, "dcb-skew-rows")
@@ -176,17 +194,31 @@ switch processEnv->Dict.get("PG_URL") {
176
194
  }
177
195
  let n = 12
178
196
  // Dispatch all N before awaiting any — genuinely concurrent on the pool.
179
- let promises = Array.make(~length=n, 0)->Array.mapWithIndex((_, i) =>
180
- ops.append(
181
- [stored("Claimed", [{key: "prizeId", value: "p1"}], jsonObj([("who", JSON.Encode.int(i))]))],
182
- ~condition=cond,
197
+ let promises =
198
+ Array.make(~length=n, 0)->Array.mapWithIndex(
199
+ (_, i) =>
200
+ ops.append(
201
+ [
202
+ stored(
203
+ "Claimed",
204
+ [{key: "prizeId", value: "p1"}],
205
+ jsonObj([("who", JSON.Encode.int(i))]),
206
+ ),
207
+ ],
208
+ ~condition=cond,
209
+ ),
183
210
  )
184
- )
185
211
  let results = await Promise.all(promises)
186
- let oks = results->Array.filter(r => switch r {
187
- | Ok(_) => true
188
- | _ => false
189
- })->Array.length
212
+ let oks =
213
+ results
214
+ ->Array.filter(
215
+ r =>
216
+ switch r {
217
+ | Ok(_) => true
218
+ | _ => false
219
+ },
220
+ )
221
+ ->Array.length
190
222
  expect(oks)->toBe(1)
191
223
  // No lost updates: exactly one Claimed landed on the boundary.
192
224
  let read = await ops.read(~query=[{tags: [{key: "prizeId", value: "p1"}]}])
@@ -195,7 +227,8 @@ switch processEnv->Dict.get("PG_URL") {
195
227
 
196
228
  testPromise("cursors are monotonic and usable as `after`", async () => {
197
229
  let (_n, ops, _s) = makeLog("dcb-cursor")
198
- let mk = i => stored("Tick", [{key: "streamId", value: "c1"}], jsonObj([("i", JSON.Encode.int(i))]))
230
+ let mk = i =>
231
+ stored("Tick", [{key: "streamId", value: "c1"}], jsonObj([("i", JSON.Encode.int(i))]))
199
232
  let _ = await ops.append([mk(0)])
200
233
  let mid = switch await ops.append([mk(1)]) {
201
234
  | Ok(pos) => pos
@@ -222,83 +255,103 @@ switch processEnv->Dict.get("PG_URL") {
222
255
  let _ = await ops.append([mk(0), mk(1), mk(2)])
223
256
 
224
257
  let collected = ref(0)
225
- let processed = await PgChangeFeed.drain(pool, ~logName="feed-log", ~subscriber="sub-1", ~handle=async evs => {
226
- collected := collected.contents + evs->Array.length
227
- })
258
+ let processed = await PgChangeFeed.drain(
259
+ pool,
260
+ ~logName="feed-log",
261
+ ~subscriber="sub-1",
262
+ ~handle=async evs => {
263
+ collected := collected.contents + evs->Array.length
264
+ },
265
+ )
228
266
  expect(processed)->toBe(3)
229
267
  expect(collected.contents)->toBe(3)
230
268
 
231
269
  // A second drain from the saved checkpoint sees nothing new.
232
- let again = await PgChangeFeed.drain(pool, ~logName="feed-log", ~subscriber="sub-1", ~handle=async _ => ())
270
+ let again = await PgChangeFeed.drain(
271
+ pool,
272
+ ~logName="feed-log",
273
+ ~subscriber="sub-1",
274
+ ~handle=async _ => (),
275
+ )
233
276
  expect(again)->toBe(0)
234
277
  })
235
278
  })
236
279
 
237
280
  describe("classic change feed (event_log, B2.5)", () => {
238
- testPromise("drains classic events in commit order, with fields, then checkpoints", async () => {
239
- let (_n, ops, _s) = EventLogStorage_Postgres.makeStorage(~pool, ~name="cf-orders", ~opts)
240
- let _ = await ops.append(0, "agg-1", [evJson("m0", 1), evJson("m1", 2)])
241
- let _ = await ops.append(0, "agg-2", [evJson("m2", 3)])
281
+ testPromise(
282
+ "drains classic events in commit order, with fields, then checkpoints",
283
+ async () => {
284
+ let (_n, ops, _s) = EventLogStorage_Postgres.makeStorage(~pool, ~name="cf-orders", ~opts)
285
+ let _ = await ops.append(0, "agg-1", [evJson("m0", 1), evJson("m1", 2)])
286
+ let _ = await ops.append(0, "agg-2", [evJson("m2", 3)])
242
287
 
243
- let collected = ref([])
244
- let processed = await EventLogChangeFeed.drain(
245
- pool,
246
- ~logName="cf-orders",
247
- ~subscriber="cf-sub",
248
- ~handle=async evs => collected := collected.contents->Array.concat(evs),
249
- )
250
- expect(processed)->toBe(3)
251
- expect(collected.contents->Array.length)->toBe(3)
288
+ let collected = ref([])
289
+ let processed = await EventLogChangeFeed.drain(
290
+ pool,
291
+ ~logName="cf-orders",
292
+ ~subscriber="cf-sub",
293
+ ~handle=async evs => collected := collected.contents->Array.concat(evs),
294
+ )
295
+ expect(processed)->toBe(3)
296
+ expect(collected.contents->Array.length)->toBe(3)
252
297
 
253
- // Fields round-trip from the stored row.
254
- let first = collected.contents->Array.getUnsafe(0)
255
- expect(first.aggregateId)->toBe("agg-1")
256
- expect(first.seqNr)->toBe(0)
257
- expect(first.msgId)->toEqual(Some("m0"))
298
+ // Fields round-trip from the stored row.
299
+ let first = collected.contents->Array.getUnsafe(0)
300
+ expect(first.aggregateId)->toBe("agg-1")
301
+ expect(first.seqNr)->toBe(0)
302
+ expect(first.msgId)->toEqual(Some("m0"))
258
303
 
259
- // Cursors are strictly increasing in drain order.
260
- let cursors = collected.contents->Array.map(e => e.cursor)
261
- let increasing = ref(true)
262
- for i in 1 to cursors->Array.length - 1 {
263
- if cursors->Array.getUnsafe(i) <= cursors->Array.getUnsafe(i - 1) {
264
- increasing := false
304
+ // Cursors are strictly increasing in drain order.
305
+ let cursors = collected.contents->Array.map(e => e.cursor)
306
+ let increasing = ref(true)
307
+ for i in 1 to cursors->Array.length - 1 {
308
+ if cursors->Array.getUnsafe(i) <= cursors->Array.getUnsafe(i - 1) {
309
+ increasing := false
310
+ }
265
311
  }
266
- }
267
- expect(increasing.contents)->toBe(true)
312
+ expect(increasing.contents)->toBe(true)
268
313
 
269
- // Second drain from the saved checkpoint sees nothing new.
270
- let again = await EventLogChangeFeed.drain(
271
- pool,
272
- ~logName="cf-orders",
273
- ~subscriber="cf-sub",
274
- ~handle=async _ => (),
275
- )
276
- expect(again)->toBe(0)
277
- })
314
+ // Second drain from the saved checkpoint sees nothing new.
315
+ let again = await EventLogChangeFeed.drain(
316
+ pool,
317
+ ~logName="cf-orders",
318
+ ~subscriber="cf-sub",
319
+ ~handle=async _ => (),
320
+ )
321
+ expect(again)->toBe(0)
322
+ },
323
+ )
278
324
 
279
- testPromise("concurrent appends across aggregates: every event drained exactly once", async () => {
280
- let (_n, ops, _s) = EventLogStorage_Postgres.makeStorage(~pool, ~name="cf-concurrent", ~opts)
281
- let n = 20
282
- // One event per aggregate, all dispatched before awaiting — genuinely
283
- // concurrent on the pool, so global_seq is assigned in interleaved/undefined
284
- // commit order. The xmin fence must still drain every event exactly once.
285
- let promises =
286
- Array.make(~length=n, 0)->Array.mapWithIndex((_, i) =>
287
- ops.append(0, "agg-" ++ Int.toString(i), [evJson("m" ++ Int.toString(i), i)])
325
+ testPromise(
326
+ "concurrent appends across aggregates: every event drained exactly once",
327
+ async () => {
328
+ let (_n, ops, _s) = EventLogStorage_Postgres.makeStorage(
329
+ ~pool,
330
+ ~name="cf-concurrent",
331
+ ~opts,
288
332
  )
289
- let _ = await Promise.all(promises)
333
+ let n = 20
334
+ // One event per aggregate, all dispatched before awaiting — genuinely
335
+ // concurrent on the pool, so global_seq is assigned in interleaved/undefined
336
+ // commit order. The xmin fence must still drain every event exactly once.
337
+ let promises =
338
+ Array.make(~length=n, 0)->Array.mapWithIndex(
339
+ (_, i) => ops.append(0, "agg-" ++ Int.toString(i), [evJson("m" ++ Int.toString(i), i)]),
340
+ )
341
+ let _ = await Promise.all(promises)
290
342
 
291
- let collected = ref([])
292
- let _ = await EventLogChangeFeed.drain(
293
- pool,
294
- ~logName="cf-concurrent",
295
- ~subscriber="cf-conc-sub",
296
- ~handle=async evs => collected := collected.contents->Array.concat(evs),
297
- )
298
- // No skips: all N events present. No dupes: N distinct cursors.
299
- expect(collected.contents->Array.length)->toBe(n)
300
- let distinctCursors = collected.contents->Array.map(e => e.cursor)->Set.fromArray
301
- expect(distinctCursors->Set.size)->toBe(n)
302
- })
343
+ let collected = ref([])
344
+ let _ = await EventLogChangeFeed.drain(
345
+ pool,
346
+ ~logName="cf-concurrent",
347
+ ~subscriber="cf-conc-sub",
348
+ ~handle=async evs => collected := collected.contents->Array.concat(evs),
349
+ )
350
+ // No skips: all N events present. No dupes: N distinct cursors.
351
+ expect(collected.contents->Array.length)->toBe(n)
352
+ let distinctCursors = collected.contents->Array.map(e => e.cursor)->Set.fromArray
353
+ expect(distinctCursors->Set.size)->toBe(n)
354
+ },
355
+ )
303
356
  })
304
357
  }
@@ -135,7 +135,12 @@ switch processEnv->Dict.get("PG_URL") {
135
135
 
136
136
  // Assert the push-down declines this shape (resolver falls back to the spec).
137
137
  let checkFallback = async args => {
138
- let r = await Eng.listPage(~readModelName=name, ~argsDict=argsOf(args), ~capability, ~labelField="name")
138
+ let r = await Eng.listPage(
139
+ ~readModelName=name,
140
+ ~argsDict=argsOf(args),
141
+ ~capability,
142
+ ~labelField="name",
143
+ )
139
144
  expect(r->Option.isSome)->toBe(false)
140
145
  }
141
146
 
@@ -204,7 +209,9 @@ switch processEnv->Dict.get("PG_URL") {
204
209
  checkFallback([("filter", filterOf([("searchPrefix", JSON.Encode.string("A"))]))])
205
210
  )
206
211
  testPromise("ids → fallback", () =>
207
- checkFallback([("filter", filterOf([("ids", JSON.Encode.array([JSON.Encode.string("p-1")]))]))])
212
+ checkFallback([
213
+ ("filter", filterOf([("ids", JSON.Encode.array([JSON.Encode.string("p-1")]))])),
214
+ ])
208
215
  )
209
216
  testPromise("backward (last/before) → fallback", () =>
210
217
  checkFallback([("last", JSON.Encode.int(2)), ("before", JSON.Encode.string(cur("p-4")))])
@@ -265,10 +272,20 @@ switch processEnv->Dict.get("PG_URL") {
265
272
  ->Array.filterMap(e => e->field("node")->Option.flatMap(n => n->str("seq")))
266
273
 
267
274
  let pageInfoBool = (conn, key) =>
268
- conn->field("pageInfo")->Option.getOr(JSON.Encode.null)->field(key)->Option.flatMap(JSON.Decode.bool)->Option.getOr(false)
275
+ conn
276
+ ->field("pageInfo")
277
+ ->Option.getOr(JSON.Encode.null)
278
+ ->field(key)
279
+ ->Option.flatMap(JSON.Decode.bool)
280
+ ->Option.getOr(false)
269
281
 
270
282
  let itemsPage = args =>
271
- Eng.itemsPage(~readModelName=itemsName, ~subIdField="seq", ~id="order-1", ~argsDict=argsOf(args))
283
+ Eng.itemsPage(
284
+ ~readModelName=itemsName,
285
+ ~subIdField="seq",
286
+ ~id="order-1",
287
+ ~argsDict=argsOf(args),
288
+ )
272
289
 
273
290
  describe("QueryEnginePostgres itemsPage (sub-id keyset)", () => {
274
291
  testPromise("bare → all lines ASC, no next page", async () => {
@@ -282,7 +299,10 @@ switch processEnv->Dict.get("PG_URL") {
282
299
  expect(pageInfoBool(r, "hasNextPage"))->toBe(true)
283
300
  })
284
301
  testPromise("first:2 after b → [c,d]", async () => {
285
- let r = await itemsPage([("first", JSON.Encode.int(2)), ("after", JSON.Encode.string(cur("b")))])
302
+ let r = await itemsPage([
303
+ ("first", JSON.Encode.int(2)),
304
+ ("after", JSON.Encode.string(cur("b"))),
305
+ ])
286
306
  expect(r->itemSeqs)->toEqual(["c", "d"])
287
307
  })
288
308
  testPromise("order DESC → [e..a]", async () => {
@@ -304,7 +324,10 @@ switch processEnv->Dict.get("PG_URL") {
304
324
  expect(r->itemSeqs)->toEqual(["c"])
305
325
  })
306
326
  testPromise("backward last:2 before d → [b,c] (logical ASC)", async () => {
307
- let r = await itemsPage([("last", JSON.Encode.int(2)), ("before", JSON.Encode.string(cur("d")))])
327
+ let r = await itemsPage([
328
+ ("last", JSON.Encode.int(2)),
329
+ ("before", JSON.Encode.string(cur("d"))),
330
+ ])
308
331
  expect(r->itemSeqs)->toEqual(["b", "c"])
309
332
  expect(pageInfoBool(r, "hasPreviousPage"))->toBe(true)
310
333
  })
@@ -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, 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, 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, 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, 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([]);
@@ -1,2 +1,2 @@
1
- #Start(1783671208398)
2
- #Done(1783671210443)
1
+ #Start(1790854954084)
2
+ #Done(1790854955201)