@effect-app/infra 4.0.0-beta.22 → 4.0.0-beta.220
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 +1640 -0
- package/_check.sh +1 -1
- package/dist/CUPS.d.ts +7 -7
- package/dist/CUPS.d.ts.map +1 -1
- package/dist/CUPS.js +10 -12
- package/dist/Emailer/Sendgrid.d.ts +14 -14
- package/dist/Emailer/Sendgrid.d.ts.map +1 -1
- package/dist/Emailer/Sendgrid.js +16 -15
- package/dist/Emailer/fake.d.ts +1 -1
- package/dist/Emailer/service.d.ts +10 -4
- package/dist/Emailer/service.d.ts.map +1 -1
- package/dist/Emailer/service.js +3 -3
- package/dist/Emailer.d.ts +1 -1
- package/dist/MainFiberSet.d.ts +9 -9
- package/dist/MainFiberSet.d.ts.map +1 -1
- package/dist/MainFiberSet.js +3 -3
- package/dist/Model/Repository/Registry.d.ts +20 -0
- package/dist/Model/Repository/Registry.d.ts.map +1 -0
- package/dist/Model/Repository/Registry.js +17 -0
- package/dist/Model/Repository/ext.d.ts +33 -15
- package/dist/Model/Repository/ext.d.ts.map +1 -1
- package/dist/Model/Repository/ext.js +54 -2
- package/dist/Model/Repository/internal/internal.d.ts +6 -6
- package/dist/Model/Repository/internal/internal.d.ts.map +1 -1
- package/dist/Model/Repository/internal/internal.js +103 -51
- package/dist/Model/Repository/legacy.d.ts +1 -1
- package/dist/Model/Repository/makeRepo.d.ts +7 -6
- package/dist/Model/Repository/makeRepo.d.ts.map +1 -1
- package/dist/Model/Repository/makeRepo.js +5 -1
- package/dist/Model/Repository/service.d.ts +28 -23
- package/dist/Model/Repository/service.d.ts.map +1 -1
- package/dist/Model/Repository/validation.d.ts +46 -17
- package/dist/Model/Repository/validation.d.ts.map +1 -1
- package/dist/Model/Repository/validation.js +5 -5
- package/dist/Model/Repository.d.ts +2 -1
- package/dist/Model/Repository.d.ts.map +1 -1
- package/dist/Model/Repository.js +2 -1
- package/dist/Model/dsl.d.ts +4 -4
- package/dist/Model/dsl.d.ts.map +1 -1
- package/dist/Model/filter/filterApi.d.ts +5 -5
- package/dist/Model/filter/filterApi.d.ts.map +1 -1
- package/dist/Model/filter/types/errors.d.ts +1 -1
- package/dist/Model/filter/types/fields.d.ts +1 -1
- package/dist/Model/filter/types/path/common.d.ts +1 -1
- package/dist/Model/filter/types/path/eager.d.ts +1 -1
- package/dist/Model/filter/types/path/eager.d.ts.map +1 -1
- package/dist/Model/filter/types/path/eager.js +1 -1
- package/dist/Model/filter/types/path/index.d.ts +1 -1
- package/dist/Model/filter/types/utils.d.ts +1 -1
- package/dist/Model/filter/types/validator.d.ts +1 -1
- package/dist/Model/filter/types.d.ts +1 -1
- package/dist/Model/query/dsl.d.ts +139 -16
- package/dist/Model/query/dsl.d.ts.map +1 -1
- package/dist/Model/query/dsl.js +187 -1
- package/dist/Model/query/new-kid-interpreter.d.ts +76 -7
- package/dist/Model/query/new-kid-interpreter.d.ts.map +1 -1
- package/dist/Model/query/new-kid-interpreter.js +122 -6
- package/dist/Model/query.d.ts +1 -1
- package/dist/Model.d.ts +2 -1
- package/dist/Model.d.ts.map +1 -1
- package/dist/Model.js +2 -1
- package/dist/QueueMaker/SQLQueue.d.ts +5 -7
- package/dist/QueueMaker/SQLQueue.d.ts.map +1 -1
- package/dist/QueueMaker/SQLQueue.js +130 -116
- package/dist/QueueMaker/errors.d.ts +2 -2
- package/dist/QueueMaker/errors.d.ts.map +1 -1
- package/dist/QueueMaker/memQueue.d.ts +7 -4
- package/dist/QueueMaker/memQueue.d.ts.map +1 -1
- package/dist/QueueMaker/memQueue.js +75 -63
- package/dist/QueueMaker/sbqueue.d.ts +6 -3
- package/dist/QueueMaker/sbqueue.d.ts.map +1 -1
- package/dist/QueueMaker/sbqueue.js +52 -53
- package/dist/QueueMaker/service.d.ts +1 -1
- package/dist/RequestContext.d.ts +74 -35
- package/dist/RequestContext.d.ts.map +1 -1
- package/dist/RequestContext.js +13 -14
- package/dist/RequestFiberSet.d.ts +7 -7
- package/dist/RequestFiberSet.d.ts.map +1 -1
- package/dist/RequestFiberSet.js +3 -3
- package/dist/Store/ContextMapContainer.d.ts +19 -3
- package/dist/Store/ContextMapContainer.d.ts.map +1 -1
- package/dist/Store/ContextMapContainer.js +13 -3
- package/dist/Store/Cosmos/query.d.ts +5 -1
- package/dist/Store/Cosmos/query.d.ts.map +1 -1
- package/dist/Store/Cosmos/query.js +113 -34
- package/dist/Store/Cosmos.d.ts +1 -1
- package/dist/Store/Cosmos.d.ts.map +1 -1
- package/dist/Store/Cosmos.js +335 -243
- package/dist/Store/Disk.d.ts +2 -2
- package/dist/Store/Disk.d.ts.map +1 -1
- package/dist/Store/Disk.js +72 -35
- package/dist/Store/Memory.d.ts +6 -4
- package/dist/Store/Memory.d.ts.map +1 -1
- package/dist/Store/Memory.js +242 -58
- package/dist/Store/SQL/Pg.d.ts +4 -0
- package/dist/Store/SQL/Pg.d.ts.map +1 -0
- package/dist/Store/SQL/Pg.js +231 -0
- package/dist/Store/SQL/query.d.ts +42 -0
- package/dist/Store/SQL/query.d.ts.map +1 -0
- package/dist/Store/SQL/query.js +479 -0
- package/dist/Store/SQL.d.ts +20 -0
- package/dist/Store/SQL.d.ts.map +1 -0
- package/dist/Store/SQL.js +446 -0
- package/dist/Store/codeFilter.d.ts +1 -1
- package/dist/Store/codeFilter.d.ts.map +1 -1
- package/dist/Store/codeFilter.js +4 -2
- package/dist/Store/index.d.ts +5 -2
- package/dist/Store/index.d.ts.map +1 -1
- package/dist/Store/index.js +15 -3
- package/dist/Store/service.d.ts +22 -8
- package/dist/Store/service.d.ts.map +1 -1
- package/dist/Store/service.js +24 -6
- package/dist/Store/utils.d.ts +1 -1
- package/dist/Store/utils.d.ts.map +1 -1
- package/dist/Store/utils.js +3 -4
- package/dist/Store.d.ts +1 -1
- package/dist/adapters/SQL/Model.d.ts +31 -42
- package/dist/adapters/SQL/Model.d.ts.map +1 -1
- package/dist/adapters/SQL/Model.js +29 -38
- package/dist/adapters/SQL.d.ts +1 -1
- package/dist/adapters/ServiceBus.d.ts +11 -11
- package/dist/adapters/ServiceBus.d.ts.map +1 -1
- package/dist/adapters/ServiceBus.js +25 -21
- package/dist/adapters/cosmos-client.d.ts +3 -3
- package/dist/adapters/cosmos-client.d.ts.map +1 -1
- package/dist/adapters/cosmos-client.js +3 -3
- package/dist/adapters/index.d.ts +8 -2
- package/dist/adapters/index.d.ts.map +1 -1
- package/dist/adapters/index.js +8 -2
- package/dist/adapters/logger.d.ts +1 -1
- package/dist/adapters/logger.d.ts.map +1 -1
- package/dist/adapters/memQueue.d.ts +3 -3
- package/dist/adapters/memQueue.d.ts.map +1 -1
- package/dist/adapters/memQueue.js +3 -3
- package/dist/adapters/mongo-client.d.ts +3 -3
- package/dist/adapters/mongo-client.d.ts.map +1 -1
- package/dist/adapters/mongo-client.js +3 -3
- package/dist/adapters/redis-client.d.ts +3 -3
- package/dist/adapters/redis-client.d.ts.map +1 -1
- package/dist/adapters/redis-client.js +3 -3
- package/dist/api/ContextProvider.d.ts +8 -8
- package/dist/api/ContextProvider.d.ts.map +1 -1
- package/dist/api/ContextProvider.js +6 -6
- package/dist/api/codec.d.ts +1 -1
- package/dist/api/internal/RequestContextMiddleware.d.ts +2 -2
- package/dist/api/internal/RequestContextMiddleware.d.ts.map +1 -1
- package/dist/api/internal/RequestContextMiddleware.js +9 -6
- package/dist/api/internal/auth.d.ts +44 -6
- package/dist/api/internal/auth.d.ts.map +1 -1
- package/dist/api/internal/auth.js +160 -29
- package/dist/api/internal/events.d.ts +3 -3
- package/dist/api/internal/events.d.ts.map +1 -1
- package/dist/api/internal/events.js +10 -8
- package/dist/api/internal/health.d.ts +1 -1
- package/dist/api/layerUtils.d.ts +6 -6
- package/dist/api/layerUtils.d.ts.map +1 -1
- package/dist/api/layerUtils.js +5 -5
- package/dist/api/middlewares.d.ts +1 -1
- package/dist/api/reportError.d.ts +1 -1
- package/dist/api/routing/middleware/RouterMiddleware.d.ts +4 -4
- package/dist/api/routing/middleware/RouterMiddleware.d.ts.map +1 -1
- package/dist/api/routing/middleware/middleware.d.ts +39 -3
- package/dist/api/routing/middleware/middleware.d.ts.map +1 -1
- package/dist/api/routing/middleware/middleware.js +48 -16
- package/dist/api/routing/middleware.d.ts +1 -2
- package/dist/api/routing/middleware.d.ts.map +1 -1
- package/dist/api/routing/middleware.js +1 -2
- package/dist/api/routing/schema/jwt.d.ts +1 -1
- package/dist/api/routing/schema/jwt.d.ts.map +1 -1
- package/dist/api/routing/tsort.d.ts +1 -1
- package/dist/api/routing/tsort.d.ts.map +1 -1
- package/dist/api/routing/utils.d.ts +3 -3
- package/dist/api/routing/utils.d.ts.map +1 -1
- package/dist/api/routing.d.ts +80 -37
- package/dist/api/routing.d.ts.map +1 -1
- package/dist/api/routing.js +109 -41
- package/dist/api/setupRequest.d.ts +8 -5
- package/dist/api/setupRequest.d.ts.map +1 -1
- package/dist/api/setupRequest.js +12 -7
- package/dist/api/util.d.ts +1 -1
- package/dist/arbs.d.ts +1 -1
- package/dist/arbs.d.ts.map +1 -1
- package/dist/arbs.js +5 -3
- package/dist/errorReporter.d.ts +4 -4
- package/dist/errorReporter.d.ts.map +1 -1
- package/dist/errorReporter.js +20 -25
- package/dist/errors.d.ts +1 -1
- package/dist/fileUtil.d.ts +1 -1
- package/dist/fileUtil.d.ts.map +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/logger/jsonLogger.d.ts +1 -1
- package/dist/logger/logFmtLogger.d.ts +1 -1
- package/dist/logger/shared.d.ts +1 -1
- package/dist/logger/shared.js +2 -2
- package/dist/logger.d.ts +1 -1
- package/dist/logger.d.ts.map +1 -1
- package/dist/otel.d.ts +75 -0
- package/dist/otel.d.ts.map +1 -0
- package/dist/otel.js +65 -0
- package/dist/rateLimit.d.ts +9 -3
- package/dist/rateLimit.d.ts.map +1 -1
- package/dist/rateLimit.js +5 -11
- package/dist/test.d.ts +2 -2
- package/dist/test.d.ts.map +1 -1
- package/dist/test.js +1 -1
- package/dist/vitest.d.ts +1 -1
- package/examples/query.ts +42 -38
- package/package.json +46 -37
- package/src/CUPS.ts +9 -11
- package/src/Emailer/Sendgrid.ts +17 -14
- package/src/Emailer/service.ts +9 -3
- package/src/MainFiberSet.ts +5 -6
- package/src/Model/Repository/Registry.ts +33 -0
- package/src/Model/Repository/ext.ts +96 -10
- package/src/Model/Repository/internal/internal.ts +218 -149
- package/src/Model/Repository/makeRepo.ts +12 -10
- package/src/Model/Repository/service.ts +31 -22
- package/src/Model/Repository/validation.ts +4 -4
- package/src/Model/Repository.ts +1 -0
- package/src/Model/dsl.ts +3 -3
- package/src/Model/filter/types/path/eager.ts +1 -2
- package/src/Model/query/dsl.ts +348 -18
- package/src/Model/query/new-kid-interpreter.ts +206 -6
- package/src/Model.ts +1 -0
- package/src/QueueMaker/SQLQueue.ts +144 -152
- package/src/QueueMaker/memQueue.ts +104 -103
- package/src/QueueMaker/sbqueue.ts +70 -86
- package/src/RequestContext.ts +14 -16
- package/src/RequestFiberSet.ts +2 -2
- package/src/Store/ContextMapContainer.ts +41 -2
- package/src/Store/Cosmos/query.ts +140 -43
- package/src/Store/Cosmos.ts +482 -349
- package/src/Store/Disk.ts +102 -65
- package/src/Store/Memory.ts +275 -87
- package/src/Store/SQL/Pg.ts +361 -0
- package/src/Store/SQL/query.ts +539 -0
- package/src/Store/SQL.ts +731 -0
- package/src/Store/codeFilter.ts +3 -1
- package/src/Store/index.ts +17 -2
- package/src/Store/service.ts +41 -10
- package/src/Store/utils.ts +23 -22
- package/src/adapters/SQL/Model.ts +41 -40
- package/src/adapters/ServiceBus.ts +125 -121
- package/src/adapters/cosmos-client.ts +2 -2
- package/src/adapters/index.ts +7 -0
- package/src/adapters/memQueue.ts +2 -2
- package/src/adapters/mongo-client.ts +2 -2
- package/src/adapters/redis-client.ts +2 -2
- package/src/api/ContextProvider.ts +12 -13
- package/src/api/internal/RequestContextMiddleware.ts +15 -5
- package/src/api/internal/auth.ts +246 -44
- package/src/api/internal/events.ts +13 -9
- package/src/api/layerUtils.ts +8 -8
- package/src/api/routing/middleware/RouterMiddleware.ts +4 -4
- package/src/api/routing/middleware/middleware.ts +55 -14
- package/src/api/routing/middleware.ts +0 -2
- package/src/api/routing.ts +296 -131
- package/src/api/setupRequest.ts +28 -8
- package/src/arbs.ts +4 -2
- package/src/errorReporter.ts +62 -74
- package/src/logger/shared.ts +1 -1
- package/src/otel.ts +152 -0
- package/src/rateLimit.ts +30 -22
- package/src/test.ts +1 -1
- package/test/auth.test.ts +101 -0
- package/test/contextProvider.test.ts +11 -11
- package/test/controller.test.ts +21 -30
- package/test/dist/auth.test.d.ts.map +1 -0
- package/test/dist/contextProvider.test.d.ts.map +1 -1
- package/test/dist/controller.test.d.ts.map +1 -1
- package/test/dist/date-query.test.d.ts.map +1 -0
- package/test/dist/fixtures.d.ts +26 -12
- package/test/dist/fixtures.d.ts.map +1 -1
- package/test/dist/fixtures.js +12 -10
- package/test/dist/query.test.d.ts.map +1 -1
- package/test/dist/rawQuery.test.d.ts.map +1 -1
- package/test/dist/repository-ext.test.d.ts.map +1 -0
- package/test/dist/requires.test.d.ts.map +1 -1
- package/test/dist/router-generator.test.d.ts.map +1 -0
- package/test/dist/routing-interruptibility.test.d.ts.map +1 -0
- package/test/dist/rpc-e2e-invalidation.test.d.ts.map +1 -0
- package/test/dist/rpc-multi-middleware.test.d.ts.map +1 -1
- package/test/dist/rpc-stream-fullstack.test.d.ts.map +1 -0
- package/test/dist/sql-store.test.d.ts.map +1 -0
- package/test/fixtures.ts +11 -9
- package/test/query.test.ts +813 -38
- package/test/rawQuery.test.ts +301 -20
- package/test/repository-ext.test.ts +60 -0
- package/test/requires.test.ts +6 -6
- package/test/router-generator.test.ts +183 -0
- package/test/routing-interruptibility.test.ts +63 -0
- package/test/rpc-e2e-invalidation.test.ts +251 -0
- package/test/rpc-multi-middleware.test.ts +78 -9
- package/test/rpc-stream-fullstack.test.ts +300 -0
- package/test/sql-store.test.ts +1592 -0
- package/test/validateSample.test.ts +15 -12
- package/tsconfig.examples.json +1 -1
- package/tsconfig.json +0 -1
- package/tsconfig.json.bak +2 -2
- package/tsconfig.src.json +35 -35
- package/tsconfig.test.json +2 -2
- package/dist/Operations.d.ts +0 -55
- package/dist/Operations.d.ts.map +0 -1
- package/dist/Operations.js +0 -102
- package/dist/OperationsRepo.d.ts +0 -41
- package/dist/OperationsRepo.d.ts.map +0 -1
- package/dist/OperationsRepo.js +0 -14
- package/eslint.config.mjs +0 -24
- package/src/Operations.ts +0 -235
- package/src/OperationsRepo.ts +0 -16
|
@@ -4,6 +4,7 @@ import { Array, Effect, type NonEmptyReadonlyArray } from "effect-app"
|
|
|
4
4
|
import { assertUnreachable } from "effect-app/utils"
|
|
5
5
|
import { InfraLogger } from "../../logger.js"
|
|
6
6
|
import type { FilterR, FilterResult, Ops } from "../../Model/filter/filterApi.js"
|
|
7
|
+
import type { ComputedProjectionIrExpression, ComputedProjectionMathIrExpression } from "../../Model/query.js"
|
|
7
8
|
import { isRelationCheck } from "../codeFilter.js"
|
|
8
9
|
import type { SupportedValues } from "../service.js"
|
|
9
10
|
|
|
@@ -40,12 +41,20 @@ export function buildWhereCosmosQuery3(
|
|
|
40
41
|
filter: readonly FilterResult[],
|
|
41
42
|
name: string,
|
|
42
43
|
defaultValues: Record<string, unknown>,
|
|
43
|
-
select?: NonEmptyReadonlyArray<
|
|
44
|
+
select?: NonEmptyReadonlyArray<
|
|
45
|
+
string | {
|
|
46
|
+
key: string
|
|
47
|
+
subKeys: readonly string[]
|
|
48
|
+
} | {
|
|
49
|
+
key: string
|
|
50
|
+
computed: ComputedProjectionIrExpression
|
|
51
|
+
}
|
|
52
|
+
>,
|
|
44
53
|
order?: NonEmptyReadonlyArray<{ key: string; direction: "ASC" | "DESC" }>,
|
|
45
54
|
skip?: number,
|
|
46
55
|
limit?: number
|
|
47
56
|
) {
|
|
48
|
-
const statement = (x: FilterR, i: number
|
|
57
|
+
const statement = (x: FilterR, i: number) => {
|
|
49
58
|
if (x.path === idKey) {
|
|
50
59
|
x = { ...x, path: "id" }
|
|
51
60
|
}
|
|
@@ -60,8 +69,6 @@ export function buildWhereCosmosQuery3(
|
|
|
60
69
|
|
|
61
70
|
const v = "@v" + i
|
|
62
71
|
|
|
63
|
-
const realValue = values[i]
|
|
64
|
-
|
|
65
72
|
switch (x.op) {
|
|
66
73
|
case "in":
|
|
67
74
|
return `ARRAY_CONTAINS(${v}, ${k})`
|
|
@@ -74,14 +81,22 @@ export function buildWhereCosmosQuery3(
|
|
|
74
81
|
return `(NOT ARRAY_CONTAINS(${k}, ${v}))`
|
|
75
82
|
|
|
76
83
|
case "includes-any":
|
|
77
|
-
return `ARRAY_CONTAINS_ANY(${k}, ${
|
|
84
|
+
return `ARRAY_CONTAINS_ANY(${k}, ${
|
|
85
|
+
(x.value as unknown as readonly unknown[]).map((_, i) => `${v}__${i}`).join(", ")
|
|
86
|
+
})`
|
|
78
87
|
case "notIncludes-any":
|
|
79
|
-
return `(NOT ARRAY_CONTAINS_ANY(${k}, ${
|
|
88
|
+
return `(NOT ARRAY_CONTAINS_ANY(${k}, ${
|
|
89
|
+
(x.value as unknown as readonly unknown[]).map((_, i) => `${v}__${i}`).join(", ")
|
|
90
|
+
}))`
|
|
80
91
|
|
|
81
92
|
case "includes-all":
|
|
82
|
-
return `ARRAY_CONTAINS_ALL(${k}, ${
|
|
93
|
+
return `ARRAY_CONTAINS_ALL(${k}, ${
|
|
94
|
+
(x.value as unknown as readonly unknown[]).map((_, i) => `${v}__${i}`).join(", ")
|
|
95
|
+
})`
|
|
83
96
|
case "notIncludes-all":
|
|
84
|
-
return `(NOT ARRAY_CONTAINS_ALL(${k}, ${
|
|
97
|
+
return `(NOT ARRAY_CONTAINS_ALL(${k}, ${
|
|
98
|
+
(x.value as unknown as readonly unknown[]).map((_, i) => `${v}__${i}`).join(", ")
|
|
99
|
+
}))`
|
|
85
100
|
|
|
86
101
|
case "contains":
|
|
87
102
|
return `CONTAINS(${k}, ${v}, true)`
|
|
@@ -165,7 +180,7 @@ export function buildWhereCosmosQuery3(
|
|
|
165
180
|
: _
|
|
166
181
|
: _
|
|
167
182
|
|
|
168
|
-
const print = (state: readonly FilterResult[],
|
|
183
|
+
const print = (state: readonly FilterResult[], isRelation: string | null, every: boolean) => {
|
|
169
184
|
let s = ""
|
|
170
185
|
let l = 0
|
|
171
186
|
const printN = (n: number) => {
|
|
@@ -174,13 +189,13 @@ export function buildWhereCosmosQuery3(
|
|
|
174
189
|
for (const e of state) {
|
|
175
190
|
switch (e.t) {
|
|
176
191
|
case "where":
|
|
177
|
-
s += statement(e, i
|
|
192
|
+
s += statement(e, i++)
|
|
178
193
|
break
|
|
179
194
|
case "or":
|
|
180
|
-
s += ` OR ${statement(e, i
|
|
195
|
+
s += ` OR ${statement(e, i++)}`
|
|
181
196
|
break
|
|
182
197
|
case "and":
|
|
183
|
-
s += ` AND ${statement(e, i
|
|
198
|
+
s += ` AND ${statement(e, i++)}`
|
|
184
199
|
break
|
|
185
200
|
case "or-scope": {
|
|
186
201
|
++l
|
|
@@ -189,7 +204,7 @@ export function buildWhereCosmosQuery3(
|
|
|
189
204
|
if (rel) {
|
|
190
205
|
const rel = (e.result[0]! as { path: string }).path.split(".-1.")[0]
|
|
191
206
|
s += isRelation
|
|
192
|
-
? ` OR (\n${printN(l + 1)}${print(e.result,
|
|
207
|
+
? ` OR (\n${printN(l + 1)}${print(e.result, rel, every)}\n${printN(l)})`
|
|
193
208
|
: ` OR (\n${printN(l + 1)}${
|
|
194
209
|
every ? "NOT " : ""
|
|
195
210
|
}EXISTS(SELECT VALUE ${rel} FROM ${rel} IN f.${rel} WHERE ${
|
|
@@ -197,13 +212,12 @@ export function buildWhereCosmosQuery3(
|
|
|
197
212
|
e
|
|
198
213
|
.result
|
|
199
214
|
.map(flip(every)),
|
|
200
|
-
values,
|
|
201
215
|
rel,
|
|
202
216
|
every
|
|
203
217
|
)
|
|
204
218
|
}))`
|
|
205
219
|
} else {
|
|
206
|
-
s += ` OR (\n${printN(l + 1)}${print(e.result,
|
|
220
|
+
s += ` OR (\n${printN(l + 1)}${print(e.result, null, every)}\n${printN(l)})`
|
|
207
221
|
}
|
|
208
222
|
--l
|
|
209
223
|
break
|
|
@@ -215,14 +229,14 @@ export function buildWhereCosmosQuery3(
|
|
|
215
229
|
if (rel) {
|
|
216
230
|
const rel = (e.result[0]! as { path: string }).path.split(".-1.")[0]
|
|
217
231
|
s += isRelation
|
|
218
|
-
? ` AND (\n${printN(l + 1)}${print(e.result,
|
|
232
|
+
? ` AND (\n${printN(l + 1)}${print(e.result, rel, every)}\n${printN(l)})`
|
|
219
233
|
: ` AND (\n${printN(l + 1)}${
|
|
220
234
|
every ? "NOT " : ""
|
|
221
235
|
}EXISTS(SELECT VALUE ${rel} FROM ${rel} IN f.${rel} WHERE ${
|
|
222
|
-
print(e.result.map(flip(every)),
|
|
236
|
+
print(e.result.map(flip(every)), rel, every)
|
|
223
237
|
}))`
|
|
224
238
|
} else {
|
|
225
|
-
s += ` AND (\n${printN(l + 1)}${print(e.result,
|
|
239
|
+
s += ` AND (\n${printN(l + 1)}${print(e.result, null, every)}\n${printN(l)})`
|
|
226
240
|
}
|
|
227
241
|
--l
|
|
228
242
|
break
|
|
@@ -234,12 +248,12 @@ export function buildWhereCosmosQuery3(
|
|
|
234
248
|
if (rel) {
|
|
235
249
|
const rel = (e.result[0]! as { path: string }).path.split(".-1.")[0]
|
|
236
250
|
s += isRelation
|
|
237
|
-
? `(\n${printN(l + 1)}${print(e.result,
|
|
251
|
+
? `(\n${printN(l + 1)}${print(e.result, rel, every)}\n${printN(l)})`
|
|
238
252
|
: `(\n${printN(l + 1)}${every ? "NOT " : ""}EXISTS(SELECT VALUE ${rel} FROM ${rel} IN f.${rel} WHERE ${
|
|
239
|
-
print(e.result.map(flip(every)),
|
|
253
|
+
print(e.result.map(flip(every)), rel, every)
|
|
240
254
|
}))`
|
|
241
255
|
} else {
|
|
242
|
-
s += `(\n${printN(l + 1)}${print(e.result,
|
|
256
|
+
s += `(\n${printN(l + 1)}${print(e.result, null, every)}\n${printN(l)})`
|
|
243
257
|
}
|
|
244
258
|
// ;--l
|
|
245
259
|
break
|
|
@@ -272,40 +286,123 @@ export function buildWhereCosmosQuery3(
|
|
|
272
286
|
? getValues(_.result)
|
|
273
287
|
: [_]
|
|
274
288
|
)
|
|
275
|
-
const
|
|
289
|
+
const computedFilters = select
|
|
290
|
+
? select.flatMap((_) => typeof _ === "object" && "computed" in _ ? getValues(_.computed.filter) : [])
|
|
291
|
+
: []
|
|
292
|
+
const values = [...computedFilters, ...getValues(filter)]
|
|
293
|
+
|
|
294
|
+
const computedSelectExpr = (key: string, computed: ComputedProjectionIrExpression) => {
|
|
295
|
+
const relationPath = computed.path
|
|
296
|
+
const relationAlias = relationPath
|
|
297
|
+
const relationSource = dottedToAccess(`f.${relationPath}`)
|
|
298
|
+
const compileExpr = (expression: ComputedProjectionMathIrExpression): string => {
|
|
299
|
+
switch (expression._tag) {
|
|
300
|
+
case "field":
|
|
301
|
+
return dottedToAccess(`${relationAlias}.${expression.field}`)
|
|
302
|
+
case "mul":
|
|
303
|
+
return `(${compileExpr(expression.left)} * ${compileExpr(expression.right)})`
|
|
304
|
+
default:
|
|
305
|
+
return assertUnreachable(expression)
|
|
306
|
+
}
|
|
307
|
+
}
|
|
308
|
+
const factorExpr = (unitExpr: string, toBase: string, factors: Readonly<Record<string, number>>) => {
|
|
309
|
+
const entries = Object.entries(factors).filter(([, factor]) => Number.isFinite(factor))
|
|
310
|
+
return entries.reduceRight<string>(
|
|
311
|
+
(acc, [unit, factor]) => `IIF(${unitExpr} = ${JSON.stringify(unit)}, ${factor}, ${acc})`,
|
|
312
|
+
`IIF(${unitExpr} = ${JSON.stringify(toBase)}, 1, 0)`
|
|
313
|
+
)
|
|
314
|
+
}
|
|
315
|
+
const where = computed.filter.length > 0
|
|
316
|
+
? ` WHERE ${print(computed.filter, relationPath, false)}`
|
|
317
|
+
: ""
|
|
318
|
+
switch (computed._tag) {
|
|
319
|
+
case "relation-count":
|
|
320
|
+
return `(SELECT VALUE COUNT(1) FROM ${relationAlias} IN ${relationSource}${where}) AS ${key}`
|
|
321
|
+
case "relation-any":
|
|
322
|
+
return `EXISTS(SELECT VALUE ${relationAlias} FROM ${relationAlias} IN ${relationSource}${where}) AS ${key}`
|
|
323
|
+
case "relation-every": {
|
|
324
|
+
// ∀x.P(x) ≡ ¬∃x.¬P(x). Cosmos has no NOT(...) on EXISTS subqueries directly,
|
|
325
|
+
// but we can flip via NOT EXISTS(... WHERE NOT (filter)).
|
|
326
|
+
if (computed.filter.length === 0) return `true AS ${key}`
|
|
327
|
+
return `NOT EXISTS(SELECT VALUE ${relationAlias} FROM ${relationAlias} IN ${relationSource} WHERE NOT (${
|
|
328
|
+
print(computed.filter, relationPath, false)
|
|
329
|
+
})) AS ${key}`
|
|
330
|
+
}
|
|
331
|
+
case "relation-distinct-count": {
|
|
332
|
+
const fieldRef = dottedToAccess(`${relationAlias}.${computed.field}`)
|
|
333
|
+
return `(SELECT VALUE COUNT(1) FROM (SELECT DISTINCT VALUE ${fieldRef} FROM ${relationAlias} IN ${relationSource}${where})) AS ${key}`
|
|
334
|
+
}
|
|
335
|
+
case "relation-sum": {
|
|
336
|
+
const fieldRef = dottedToAccess(`${relationAlias}.${computed.field}`)
|
|
337
|
+
return `(SELECT VALUE SUM(${fieldRef}) FROM ${relationAlias} IN ${relationSource}${where}) AS ${key}`
|
|
338
|
+
}
|
|
339
|
+
case "relation-sum-expr": {
|
|
340
|
+
const expression = compileExpr(computed.expression)
|
|
341
|
+
return `(SELECT VALUE SUM(${expression}) FROM ${relationAlias} IN ${relationSource}${where}) AS ${key}`
|
|
342
|
+
}
|
|
343
|
+
case "relation-sum-expr-by": {
|
|
344
|
+
const unitRef = dottedToAccess(`${relationAlias}.${computed.unit}`)
|
|
345
|
+
const expression = compileExpr(computed.expression)
|
|
346
|
+
return `ARRAY(SELECT VALUE { "unit": ${unitRef}, "total": SUM(${expression}) } FROM ${relationAlias} IN ${relationSource}${where} GROUP BY ${unitRef}) AS ${key}`
|
|
347
|
+
}
|
|
348
|
+
case "relation-sum-expr-normalized": {
|
|
349
|
+
const unitRef = dottedToAccess(`${relationAlias}.${computed.unit}`)
|
|
350
|
+
const expression = compileExpr(computed.expression)
|
|
351
|
+
const factor = factorExpr(unitRef, computed.toBase, computed.factors)
|
|
352
|
+
return `(SELECT VALUE SUM((${expression}) * (${factor})) FROM ${relationAlias} IN ${relationSource}${where}) AS ${key}`
|
|
353
|
+
}
|
|
354
|
+
case "relation-collect": {
|
|
355
|
+
const fieldRef = dottedToAccess(`${relationAlias}.${computed.field}`)
|
|
356
|
+
if (computed.distinct) {
|
|
357
|
+
return `ARRAY(SELECT DISTINCT VALUE ${fieldRef} FROM ${relationAlias} IN ${relationSource}${where}) AS ${key}`
|
|
358
|
+
}
|
|
359
|
+
return `ARRAY(SELECT VALUE ${fieldRef} FROM ${relationAlias} IN ${relationSource}${where}) AS ${key}`
|
|
360
|
+
}
|
|
361
|
+
case "relation-collect-fields": {
|
|
362
|
+
const subqueries = computed.fields.map((field) => {
|
|
363
|
+
const fieldRef = dottedToAccess(`${relationAlias}.${field}`)
|
|
364
|
+
return computed.distinct
|
|
365
|
+
? `ARRAY(SELECT DISTINCT VALUE ${fieldRef} FROM ${relationAlias} IN ${relationSource}${where})`
|
|
366
|
+
: `ARRAY(SELECT VALUE ${fieldRef} FROM ${relationAlias} IN ${relationSource}${where})`
|
|
367
|
+
})
|
|
368
|
+
const combined = computed.distinct
|
|
369
|
+
? subqueries.reduce((acc, sq) => `SetUnion(${acc}, ${sq})`)
|
|
370
|
+
: subqueries.reduce((acc, sq) => `ARRAY_CONCAT(${acc}, ${sq})`)
|
|
371
|
+
return `${combined} AS ${key}`
|
|
372
|
+
}
|
|
373
|
+
}
|
|
374
|
+
}
|
|
276
375
|
// with joins, you should use DISTINCT
|
|
277
376
|
// or you can end up with duplicates
|
|
278
377
|
return {
|
|
279
378
|
query: `
|
|
280
379
|
SELECT ${
|
|
281
380
|
select
|
|
282
|
-
?
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
381
|
+
? select
|
|
382
|
+
.map((s) =>
|
|
383
|
+
typeof s === "string"
|
|
384
|
+
? dottedToAccess(s === idKey ? "f.id" : `f.${s}`) // x["y"} vs x.y, helps with reserved keywords like "value"
|
|
385
|
+
: "computed" in s
|
|
386
|
+
? computedSelectExpr(s.key, s.computed)
|
|
387
|
+
: `ARRAY (SELECT ${s.subKeys.map((_) => dottedToAccess(`t.${_}`)).join(",")}
|
|
288
388
|
FROM t in ${dottedToAccess(`f.${s.key}`)}) AS ${s.key}`
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
}`
|
|
389
|
+
)
|
|
390
|
+
.join(", ")
|
|
292
391
|
: "f"
|
|
293
392
|
}
|
|
294
393
|
FROM ${name} f
|
|
295
394
|
|
|
296
|
-
${filter.length ? `WHERE (${print(filter,
|
|
395
|
+
${filter.length ? `WHERE (${print(filter, null, false)})` : ""}
|
|
297
396
|
${order ? `ORDER BY ${order.map((_) => `${dottedToAccess(`f.${_.key}`)} ${_.direction}`).join(", ")}` : ""}
|
|
298
397
|
${skip !== undefined || limit !== undefined ? `OFFSET ${skip ?? 0} LIMIT ${limit ?? 999999}` : ""}`,
|
|
299
|
-
parameters:
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
)
|
|
309
|
-
]
|
|
398
|
+
parameters: values
|
|
399
|
+
.flatMap((x, i) =>
|
|
400
|
+
[{
|
|
401
|
+
name: `@v${i}`,
|
|
402
|
+
value: x.value as any
|
|
403
|
+
}]
|
|
404
|
+
// TODO: only for arrays that are used with _ANY or _ALL
|
|
405
|
+
.concat(Array.isArray(x.value) ? x.value.map((_, i2) => ({ name: `@v${i}__${i2}`, value: _ as any })) : [])
|
|
406
|
+
)
|
|
310
407
|
}
|
|
311
408
|
}
|