@tanstack/db 0.0.14 → 0.0.15
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/dist/cjs/collection.cjs +117 -104
- package/dist/cjs/collection.cjs.map +1 -1
- package/dist/cjs/collection.d.cts +18 -21
- package/dist/cjs/index.cjs +35 -13
- package/dist/cjs/index.cjs.map +1 -1
- package/dist/cjs/index.d.cts +0 -1
- package/dist/cjs/query/builder/functions.cjs +107 -0
- package/dist/cjs/query/builder/functions.cjs.map +1 -0
- package/dist/cjs/query/builder/functions.d.cts +38 -0
- package/dist/cjs/query/builder/index.cjs +499 -0
- package/dist/cjs/query/builder/index.cjs.map +1 -0
- package/dist/cjs/query/builder/index.d.cts +324 -0
- package/dist/cjs/query/builder/ref-proxy.cjs +96 -0
- package/dist/cjs/query/builder/ref-proxy.cjs.map +1 -0
- package/dist/cjs/query/builder/ref-proxy.d.cts +28 -0
- package/dist/cjs/query/builder/types.d.cts +80 -0
- package/dist/cjs/query/compiler/evaluators.cjs +261 -0
- package/dist/cjs/query/compiler/evaluators.cjs.map +1 -0
- package/dist/cjs/query/compiler/evaluators.d.cts +11 -0
- package/dist/cjs/query/compiler/group-by.cjs +271 -0
- package/dist/cjs/query/compiler/group-by.cjs.map +1 -0
- package/dist/cjs/query/compiler/group-by.d.cts +7 -0
- package/dist/cjs/query/compiler/index.cjs +181 -0
- package/dist/cjs/query/compiler/index.cjs.map +1 -0
- package/dist/cjs/query/compiler/index.d.cts +15 -0
- package/dist/cjs/query/compiler/joins.cjs +116 -0
- package/dist/cjs/query/compiler/joins.cjs.map +1 -0
- package/dist/cjs/query/compiler/joins.d.cts +11 -0
- package/dist/cjs/query/compiler/order-by.cjs +89 -0
- package/dist/cjs/query/compiler/order-by.cjs.map +1 -0
- package/dist/cjs/query/compiler/order-by.d.cts +9 -0
- package/dist/cjs/query/compiler/select.cjs +57 -0
- package/dist/cjs/query/compiler/select.cjs.map +1 -0
- package/dist/cjs/query/compiler/select.d.cts +15 -0
- package/dist/cjs/query/index.d.cts +6 -5
- package/dist/cjs/query/ir.cjs +57 -0
- package/dist/cjs/query/ir.cjs.map +1 -0
- package/dist/cjs/query/ir.d.cts +81 -0
- package/dist/cjs/query/live-query-collection.cjs +224 -0
- package/dist/cjs/query/live-query-collection.cjs.map +1 -0
- package/dist/cjs/query/live-query-collection.d.cts +124 -0
- package/dist/cjs/transactions.cjs +20 -13
- package/dist/cjs/transactions.cjs.map +1 -1
- package/dist/cjs/transactions.d.cts +10 -1
- package/dist/cjs/types.d.cts +13 -0
- package/dist/esm/collection.d.ts +18 -21
- package/dist/esm/collection.js +118 -105
- package/dist/esm/collection.js.map +1 -1
- package/dist/esm/index.d.ts +0 -1
- package/dist/esm/index.js +34 -12
- package/dist/esm/index.js.map +1 -1
- package/dist/esm/query/builder/functions.d.ts +38 -0
- package/dist/esm/query/builder/functions.js +107 -0
- package/dist/esm/query/builder/functions.js.map +1 -0
- package/dist/esm/query/builder/index.d.ts +324 -0
- package/dist/esm/query/builder/index.js +499 -0
- package/dist/esm/query/builder/index.js.map +1 -0
- package/dist/esm/query/builder/ref-proxy.d.ts +28 -0
- package/dist/esm/query/builder/ref-proxy.js +96 -0
- package/dist/esm/query/builder/ref-proxy.js.map +1 -0
- package/dist/esm/query/builder/types.d.ts +80 -0
- package/dist/esm/query/compiler/evaluators.d.ts +11 -0
- package/dist/esm/query/compiler/evaluators.js +261 -0
- package/dist/esm/query/compiler/evaluators.js.map +1 -0
- package/dist/esm/query/compiler/group-by.d.ts +7 -0
- package/dist/esm/query/compiler/group-by.js +271 -0
- package/dist/esm/query/compiler/group-by.js.map +1 -0
- package/dist/esm/query/compiler/index.d.ts +15 -0
- package/dist/esm/query/compiler/index.js +181 -0
- package/dist/esm/query/compiler/index.js.map +1 -0
- package/dist/esm/query/compiler/joins.d.ts +11 -0
- package/dist/esm/query/compiler/joins.js +116 -0
- package/dist/esm/query/compiler/joins.js.map +1 -0
- package/dist/esm/query/compiler/order-by.d.ts +9 -0
- package/dist/esm/query/compiler/order-by.js +89 -0
- package/dist/esm/query/compiler/order-by.js.map +1 -0
- package/dist/esm/query/compiler/select.d.ts +15 -0
- package/dist/esm/query/compiler/select.js +57 -0
- package/dist/esm/query/compiler/select.js.map +1 -0
- package/dist/esm/query/index.d.ts +6 -5
- package/dist/esm/query/ir.d.ts +81 -0
- package/dist/esm/query/ir.js +57 -0
- package/dist/esm/query/ir.js.map +1 -0
- package/dist/esm/query/live-query-collection.d.ts +124 -0
- package/dist/esm/query/live-query-collection.js +224 -0
- package/dist/esm/query/live-query-collection.js.map +1 -0
- package/dist/esm/transactions.d.ts +10 -1
- package/dist/esm/transactions.js +20 -13
- package/dist/esm/transactions.js.map +1 -1
- package/dist/esm/types.d.ts +13 -0
- package/package.json +3 -4
- package/src/collection.ts +152 -129
- package/src/index.ts +0 -1
- package/src/query/builder/functions.ts +267 -0
- package/src/query/builder/index.ts +648 -0
- package/src/query/builder/ref-proxy.ts +156 -0
- package/src/query/builder/types.ts +278 -0
- package/src/query/compiler/evaluators.ts +315 -0
- package/src/query/compiler/group-by.ts +428 -0
- package/src/query/compiler/index.ts +276 -0
- package/src/query/compiler/joins.ts +228 -0
- package/src/query/compiler/order-by.ts +139 -0
- package/src/query/compiler/select.ts +173 -0
- package/src/query/index.ts +64 -5
- package/src/query/ir.ts +128 -0
- package/src/query/live-query-collection.ts +509 -0
- package/src/transactions.ts +27 -16
- package/src/types.ts +15 -0
- package/dist/cjs/query/compiled-query.cjs +0 -160
- package/dist/cjs/query/compiled-query.cjs.map +0 -1
- package/dist/cjs/query/compiled-query.d.cts +0 -20
- package/dist/cjs/query/evaluators.cjs +0 -161
- package/dist/cjs/query/evaluators.cjs.map +0 -1
- package/dist/cjs/query/evaluators.d.cts +0 -14
- package/dist/cjs/query/extractors.cjs +0 -122
- package/dist/cjs/query/extractors.cjs.map +0 -1
- package/dist/cjs/query/extractors.d.cts +0 -22
- package/dist/cjs/query/functions.cjs +0 -152
- package/dist/cjs/query/functions.cjs.map +0 -1
- package/dist/cjs/query/functions.d.cts +0 -21
- package/dist/cjs/query/group-by.cjs +0 -88
- package/dist/cjs/query/group-by.cjs.map +0 -1
- package/dist/cjs/query/group-by.d.cts +0 -40
- package/dist/cjs/query/joins.cjs +0 -141
- package/dist/cjs/query/joins.cjs.map +0 -1
- package/dist/cjs/query/joins.d.cts +0 -14
- package/dist/cjs/query/order-by.cjs +0 -185
- package/dist/cjs/query/order-by.cjs.map +0 -1
- package/dist/cjs/query/order-by.d.cts +0 -3
- package/dist/cjs/query/pipeline-compiler.cjs +0 -89
- package/dist/cjs/query/pipeline-compiler.cjs.map +0 -1
- package/dist/cjs/query/pipeline-compiler.d.cts +0 -10
- package/dist/cjs/query/query-builder.cjs +0 -307
- package/dist/cjs/query/query-builder.cjs.map +0 -1
- package/dist/cjs/query/query-builder.d.cts +0 -225
- package/dist/cjs/query/schema.d.cts +0 -100
- package/dist/cjs/query/select.cjs +0 -130
- package/dist/cjs/query/select.cjs.map +0 -1
- package/dist/cjs/query/select.d.cts +0 -3
- package/dist/cjs/query/types.d.cts +0 -189
- package/dist/cjs/query/utils.cjs +0 -154
- package/dist/cjs/query/utils.cjs.map +0 -1
- package/dist/cjs/query/utils.d.cts +0 -37
- package/dist/cjs/utils.cjs +0 -17
- package/dist/cjs/utils.cjs.map +0 -1
- package/dist/cjs/utils.d.cts +0 -3
- package/dist/esm/query/compiled-query.d.ts +0 -20
- package/dist/esm/query/compiled-query.js +0 -160
- package/dist/esm/query/compiled-query.js.map +0 -1
- package/dist/esm/query/evaluators.d.ts +0 -14
- package/dist/esm/query/evaluators.js +0 -161
- package/dist/esm/query/evaluators.js.map +0 -1
- package/dist/esm/query/extractors.d.ts +0 -22
- package/dist/esm/query/extractors.js +0 -122
- package/dist/esm/query/extractors.js.map +0 -1
- package/dist/esm/query/functions.d.ts +0 -21
- package/dist/esm/query/functions.js +0 -152
- package/dist/esm/query/functions.js.map +0 -1
- package/dist/esm/query/group-by.d.ts +0 -40
- package/dist/esm/query/group-by.js +0 -88
- package/dist/esm/query/group-by.js.map +0 -1
- package/dist/esm/query/joins.d.ts +0 -14
- package/dist/esm/query/joins.js +0 -141
- package/dist/esm/query/joins.js.map +0 -1
- package/dist/esm/query/order-by.d.ts +0 -3
- package/dist/esm/query/order-by.js +0 -185
- package/dist/esm/query/order-by.js.map +0 -1
- package/dist/esm/query/pipeline-compiler.d.ts +0 -10
- package/dist/esm/query/pipeline-compiler.js +0 -89
- package/dist/esm/query/pipeline-compiler.js.map +0 -1
- package/dist/esm/query/query-builder.d.ts +0 -225
- package/dist/esm/query/query-builder.js +0 -307
- package/dist/esm/query/query-builder.js.map +0 -1
- package/dist/esm/query/schema.d.ts +0 -100
- package/dist/esm/query/select.d.ts +0 -3
- package/dist/esm/query/select.js +0 -130
- package/dist/esm/query/select.js.map +0 -1
- package/dist/esm/query/types.d.ts +0 -189
- package/dist/esm/query/utils.d.ts +0 -37
- package/dist/esm/query/utils.js +0 -154
- package/dist/esm/query/utils.js.map +0 -1
- package/dist/esm/utils.d.ts +0 -3
- package/dist/esm/utils.js +0 -17
- package/dist/esm/utils.js.map +0 -1
- package/src/query/compiled-query.ts +0 -234
- package/src/query/evaluators.ts +0 -250
- package/src/query/extractors.ts +0 -214
- package/src/query/functions.ts +0 -297
- package/src/query/group-by.ts +0 -139
- package/src/query/joins.ts +0 -260
- package/src/query/order-by.ts +0 -264
- package/src/query/pipeline-compiler.ts +0 -149
- package/src/query/query-builder.ts +0 -902
- package/src/query/schema.ts +0 -268
- package/src/query/select.ts +0 -208
- package/src/query/types.ts +0 -418
- package/src/query/utils.ts +0 -245
- package/src/utils.ts +0 -15
package/src/query/schema.ts
DELETED
|
@@ -1,268 +0,0 @@
|
|
|
1
|
-
import type {
|
|
2
|
-
Context,
|
|
3
|
-
InputReference,
|
|
4
|
-
PropertyReference,
|
|
5
|
-
PropertyReferenceString,
|
|
6
|
-
Schema,
|
|
7
|
-
WildcardReferenceString,
|
|
8
|
-
} from "./types.js"
|
|
9
|
-
import type { Collection } from "../collection"
|
|
10
|
-
|
|
11
|
-
// Identifiers
|
|
12
|
-
export type ColumnName<TColumnNames extends string> = TColumnNames
|
|
13
|
-
|
|
14
|
-
// JSONLike supports any JSON-compatible value plus Date objects.
|
|
15
|
-
export type JSONLike =
|
|
16
|
-
| string
|
|
17
|
-
| number
|
|
18
|
-
| boolean
|
|
19
|
-
| Date
|
|
20
|
-
| null
|
|
21
|
-
| Array<JSONLike>
|
|
22
|
-
| { [key: string]: JSONLike }
|
|
23
|
-
|
|
24
|
-
// LiteralValue supports common primitives, JS Date, or undefined.
|
|
25
|
-
// We exclude strings that start with "@" because they are property references.
|
|
26
|
-
export type LiteralValue =
|
|
27
|
-
| (string & {})
|
|
28
|
-
| number
|
|
29
|
-
| boolean
|
|
30
|
-
| Date
|
|
31
|
-
| null
|
|
32
|
-
| undefined
|
|
33
|
-
|
|
34
|
-
// `in` and `not in` operators require an array of values
|
|
35
|
-
// the other operators require a single literal value
|
|
36
|
-
export type ComparatorValue<
|
|
37
|
-
T extends Comparator,
|
|
38
|
-
TContext extends Context<Schema>,
|
|
39
|
-
> = T extends `in` | `not in`
|
|
40
|
-
? Array<LiteralValue>
|
|
41
|
-
: PropertyReferenceString<TContext> | LiteralValue
|
|
42
|
-
|
|
43
|
-
// These versions are for use with methods on the query builder where we want to
|
|
44
|
-
// ensure that the argument is a string that does not start with "@".
|
|
45
|
-
// Can be combined with PropertyReference for validating references.
|
|
46
|
-
export type SafeString<T extends string> = T extends `@${string}` ? never : T
|
|
47
|
-
export type OptionalSafeString<T extends any> = T extends string
|
|
48
|
-
? SafeString<T>
|
|
49
|
-
: never
|
|
50
|
-
export type LiteralValueWithSafeString<T extends any> =
|
|
51
|
-
| (OptionalSafeString<T> & {})
|
|
52
|
-
| number
|
|
53
|
-
| boolean
|
|
54
|
-
| Date
|
|
55
|
-
| null
|
|
56
|
-
| undefined
|
|
57
|
-
|
|
58
|
-
// To force a literal value (which may be arbitrary JSON or a Date), wrap it in an object with the "value" key.
|
|
59
|
-
export interface ExplicitLiteral {
|
|
60
|
-
value: JSONLike
|
|
61
|
-
}
|
|
62
|
-
|
|
63
|
-
// Allowed function names (common SQL functions)
|
|
64
|
-
export type AllowedFunctionName =
|
|
65
|
-
| `DATE`
|
|
66
|
-
| `JSON_EXTRACT`
|
|
67
|
-
| `JSON_EXTRACT_PATH`
|
|
68
|
-
| `UPPER`
|
|
69
|
-
| `LOWER`
|
|
70
|
-
| `COALESCE`
|
|
71
|
-
| `CONCAT`
|
|
72
|
-
| `LENGTH`
|
|
73
|
-
| `ORDER_INDEX`
|
|
74
|
-
|
|
75
|
-
// A function call is represented as a union of objects—each having exactly one key that is one of the allowed function names.
|
|
76
|
-
export type FunctionCall<TContext extends Context = Context> = {
|
|
77
|
-
[K in AllowedFunctionName]: {
|
|
78
|
-
[key in K]: ConditionOperand<TContext> | Array<ConditionOperand<TContext>>
|
|
79
|
-
}
|
|
80
|
-
}[AllowedFunctionName]
|
|
81
|
-
|
|
82
|
-
export type AggregateFunctionName =
|
|
83
|
-
| `SUM`
|
|
84
|
-
| `COUNT`
|
|
85
|
-
| `AVG`
|
|
86
|
-
| `MIN`
|
|
87
|
-
| `MAX`
|
|
88
|
-
| `MEDIAN`
|
|
89
|
-
| `MODE`
|
|
90
|
-
|
|
91
|
-
export type AggregateFunctionCall<TContext extends Context = Context> = {
|
|
92
|
-
[K in AggregateFunctionName]: {
|
|
93
|
-
[key in K]: ConditionOperand<TContext> | Array<ConditionOperand<TContext>>
|
|
94
|
-
}
|
|
95
|
-
}[AggregateFunctionName]
|
|
96
|
-
|
|
97
|
-
/**
|
|
98
|
-
* An operand in a condition may be:
|
|
99
|
-
* - A literal value (LiteralValue)
|
|
100
|
-
* - A column reference (a string starting with "@" or an explicit { col: string } object)
|
|
101
|
-
* - An explicit literal (to wrap arbitrary JSON or Date values) as { value: ... }
|
|
102
|
-
* - A function call (as defined above)
|
|
103
|
-
* - An array of operands (for example, for "in" clauses)
|
|
104
|
-
*/
|
|
105
|
-
export type ConditionOperand<
|
|
106
|
-
TContext extends Context = Context,
|
|
107
|
-
T extends any = any,
|
|
108
|
-
> =
|
|
109
|
-
| LiteralValue
|
|
110
|
-
| PropertyReference<TContext>
|
|
111
|
-
| ExplicitLiteral
|
|
112
|
-
| FunctionCall<TContext>
|
|
113
|
-
| Array<ConditionOperand<TContext, T>>
|
|
114
|
-
|
|
115
|
-
// Allowed SQL comparators.
|
|
116
|
-
export type Comparator =
|
|
117
|
-
| `=`
|
|
118
|
-
| `!=`
|
|
119
|
-
| `<`
|
|
120
|
-
| `<=`
|
|
121
|
-
| `>`
|
|
122
|
-
| `>=`
|
|
123
|
-
| `like`
|
|
124
|
-
| `not like`
|
|
125
|
-
| `in`
|
|
126
|
-
| `not in`
|
|
127
|
-
| `is`
|
|
128
|
-
| `is not`
|
|
129
|
-
|
|
130
|
-
// Logical operators.
|
|
131
|
-
export type LogicalOperator = `and` | `or`
|
|
132
|
-
|
|
133
|
-
// A simple condition is a tuple: [left operand, comparator, right operand].
|
|
134
|
-
export type SimpleCondition<
|
|
135
|
-
TContext extends Context = Context,
|
|
136
|
-
T extends any = any,
|
|
137
|
-
> = [ConditionOperand<TContext, T>, Comparator, ConditionOperand<TContext, T>]
|
|
138
|
-
|
|
139
|
-
// A flat composite condition allows all elements to be at the same level:
|
|
140
|
-
// [left1, op1, right1, 'and'/'or', left2, op2, right2, ...]
|
|
141
|
-
export type FlatCompositeCondition<
|
|
142
|
-
TContext extends Context = Context,
|
|
143
|
-
T extends any = any,
|
|
144
|
-
> = [
|
|
145
|
-
ConditionOperand<TContext, T>,
|
|
146
|
-
Comparator,
|
|
147
|
-
ConditionOperand<TContext, T>,
|
|
148
|
-
...Array<LogicalOperator | ConditionOperand<TContext, T> | Comparator>,
|
|
149
|
-
]
|
|
150
|
-
|
|
151
|
-
// A nested composite condition combines conditions with logical operators
|
|
152
|
-
// The first element can be a SimpleCondition or FlatCompositeCondition
|
|
153
|
-
// followed by logical operators and more conditions
|
|
154
|
-
export type NestedCompositeCondition<
|
|
155
|
-
TContext extends Context = Context,
|
|
156
|
-
T extends any = any,
|
|
157
|
-
> = [
|
|
158
|
-
SimpleCondition<TContext, T> | FlatCompositeCondition<TContext, T>,
|
|
159
|
-
...Array<
|
|
160
|
-
| LogicalOperator
|
|
161
|
-
| SimpleCondition<TContext, T>
|
|
162
|
-
| FlatCompositeCondition<TContext, T>
|
|
163
|
-
>,
|
|
164
|
-
]
|
|
165
|
-
|
|
166
|
-
// A condition is either a simple condition or a composite condition (flat or nested).
|
|
167
|
-
export type Condition<
|
|
168
|
-
TContext extends Context = Context,
|
|
169
|
-
T extends any = any,
|
|
170
|
-
> =
|
|
171
|
-
| SimpleCondition<TContext, T>
|
|
172
|
-
| FlatCompositeCondition<TContext, T>
|
|
173
|
-
| NestedCompositeCondition<TContext, T>
|
|
174
|
-
|
|
175
|
-
// A join clause includes a join type, the table to join, an optional alias,
|
|
176
|
-
// an "on" condition, and an optional "where" clause specific to the join.
|
|
177
|
-
export interface JoinClause<TContext extends Context = Context> {
|
|
178
|
-
type: `inner` | `left` | `right` | `full` | `cross`
|
|
179
|
-
from: string
|
|
180
|
-
as?: string
|
|
181
|
-
on: Condition<TContext>
|
|
182
|
-
}
|
|
183
|
-
|
|
184
|
-
// The orderBy clause can be a string, an object mapping a column to "asc" or "desc",
|
|
185
|
-
// or an array of such items.
|
|
186
|
-
export type OrderBy<TContext extends Context = Context> =
|
|
187
|
-
| PropertyReferenceString<TContext>
|
|
188
|
-
| { [column in PropertyReferenceString<TContext>]?: `asc` | `desc` }
|
|
189
|
-
| Record<PropertyReferenceString<TContext>, `asc` | `desc`>
|
|
190
|
-
| Array<
|
|
191
|
-
| PropertyReferenceString<TContext>
|
|
192
|
-
| { [column in PropertyReferenceString<TContext>]?: `asc` | `desc` }
|
|
193
|
-
>
|
|
194
|
-
|
|
195
|
-
export type Select<TContext extends Context = Context> =
|
|
196
|
-
| PropertyReferenceString<TContext>
|
|
197
|
-
| {
|
|
198
|
-
[alias: string]:
|
|
199
|
-
| PropertyReference<TContext>
|
|
200
|
-
| FunctionCall<TContext>
|
|
201
|
-
| AggregateFunctionCall<TContext>
|
|
202
|
-
}
|
|
203
|
-
| WildcardReferenceString<TContext>
|
|
204
|
-
| SelectCallback<TContext>
|
|
205
|
-
|
|
206
|
-
export type SelectCallback<TContext extends Context = Context> = (
|
|
207
|
-
context: TContext extends { schema: infer S } ? S : any
|
|
208
|
-
) => any
|
|
209
|
-
|
|
210
|
-
export type As<_TContext extends Context = Context> = string
|
|
211
|
-
|
|
212
|
-
export type From<TContext extends Context = Context> = InputReference<{
|
|
213
|
-
baseSchema: TContext[`baseSchema`]
|
|
214
|
-
schema: TContext[`baseSchema`]
|
|
215
|
-
}>
|
|
216
|
-
|
|
217
|
-
export type WhereCallback<TContext extends Context = Context> = (
|
|
218
|
-
context: TContext extends { schema: infer S } ? S : any
|
|
219
|
-
) => boolean
|
|
220
|
-
|
|
221
|
-
export type Where<TContext extends Context = Context> = Array<
|
|
222
|
-
Condition<TContext> | WhereCallback<TContext>
|
|
223
|
-
>
|
|
224
|
-
|
|
225
|
-
// Having is the same implementation as a where clause, its just run after the group by
|
|
226
|
-
export type Having<TContext extends Context = Context> = Where<TContext>
|
|
227
|
-
|
|
228
|
-
export type GroupBy<TContext extends Context = Context> =
|
|
229
|
-
| PropertyReference<TContext>
|
|
230
|
-
| Array<PropertyReference<TContext>>
|
|
231
|
-
|
|
232
|
-
export type Limit<_TContext extends Context = Context> = number
|
|
233
|
-
|
|
234
|
-
export type Offset<_TContext extends Context = Context> = number
|
|
235
|
-
|
|
236
|
-
export interface BaseQuery<TContext extends Context = Context> {
|
|
237
|
-
// The select clause is an array of either plain strings or objects mapping alias names
|
|
238
|
-
// to expressions. Plain strings starting with "@" denote column references.
|
|
239
|
-
// Plain string "@*" denotes all columns from all tables.
|
|
240
|
-
// Plain string "@table.*" denotes all columns from a specific table.
|
|
241
|
-
select?: Array<Select<TContext>>
|
|
242
|
-
as?: As<TContext>
|
|
243
|
-
from: From<TContext>
|
|
244
|
-
join?: Array<JoinClause<TContext>>
|
|
245
|
-
where?: Where<TContext>
|
|
246
|
-
groupBy?: GroupBy<TContext>
|
|
247
|
-
having?: Having<TContext>
|
|
248
|
-
orderBy?: OrderBy<TContext>
|
|
249
|
-
limit?: Limit<TContext>
|
|
250
|
-
offset?: Offset<TContext>
|
|
251
|
-
}
|
|
252
|
-
|
|
253
|
-
// The top-level query interface.
|
|
254
|
-
export interface Query<TContext extends Context = Context>
|
|
255
|
-
extends BaseQuery<TContext> {
|
|
256
|
-
with?: Array<WithQuery<TContext>>
|
|
257
|
-
collections?: {
|
|
258
|
-
[K: string]: Collection<any>
|
|
259
|
-
}
|
|
260
|
-
}
|
|
261
|
-
|
|
262
|
-
// A WithQuery is a query that is used as a Common Table Expression (CTE)
|
|
263
|
-
// It cannot be keyed and must have an alias (as)
|
|
264
|
-
// There is no support for recursive CTEs
|
|
265
|
-
export interface WithQuery<TContext extends Context = Context>
|
|
266
|
-
extends BaseQuery<TContext> {
|
|
267
|
-
as: string
|
|
268
|
-
}
|
package/src/query/select.ts
DELETED
|
@@ -1,208 +0,0 @@
|
|
|
1
|
-
import { map } from "@electric-sql/d2mini"
|
|
2
|
-
import {
|
|
3
|
-
evaluateOperandOnNamespacedRow,
|
|
4
|
-
extractValueFromNamespacedRow,
|
|
5
|
-
} from "./extractors"
|
|
6
|
-
import type { ConditionOperand, Query, SelectCallback } from "./schema"
|
|
7
|
-
import type { KeyedStream, NamespacedAndKeyedStream } from "../types"
|
|
8
|
-
|
|
9
|
-
export function processSelect(
|
|
10
|
-
pipeline: NamespacedAndKeyedStream,
|
|
11
|
-
query: Query,
|
|
12
|
-
mainTableAlias: string,
|
|
13
|
-
inputs: Record<string, KeyedStream>
|
|
14
|
-
): KeyedStream {
|
|
15
|
-
return pipeline.pipe(
|
|
16
|
-
map(([key, namespacedRow]) => {
|
|
17
|
-
const result: Record<string, unknown> = {}
|
|
18
|
-
|
|
19
|
-
// Check if this is a grouped result (has no nested table structure)
|
|
20
|
-
// If it's a grouped result, we need to handle it differently
|
|
21
|
-
const isGroupedResult =
|
|
22
|
-
query.groupBy &&
|
|
23
|
-
Object.keys(namespacedRow).some(
|
|
24
|
-
(namespaceKey) =>
|
|
25
|
-
!Object.keys(inputs).includes(namespaceKey) &&
|
|
26
|
-
typeof namespacedRow[namespaceKey] !== `object`
|
|
27
|
-
)
|
|
28
|
-
|
|
29
|
-
if (!query.select) {
|
|
30
|
-
throw new Error(`Cannot process missing SELECT clause`)
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
for (const item of query.select) {
|
|
34
|
-
// Handle callback functions
|
|
35
|
-
if (typeof item === `function`) {
|
|
36
|
-
const callback = item as SelectCallback
|
|
37
|
-
const callbackResult = callback(namespacedRow)
|
|
38
|
-
|
|
39
|
-
// If the callback returns an object, merge its properties into the result
|
|
40
|
-
if (
|
|
41
|
-
callbackResult &&
|
|
42
|
-
typeof callbackResult === `object` &&
|
|
43
|
-
!Array.isArray(callbackResult)
|
|
44
|
-
) {
|
|
45
|
-
Object.assign(result, callbackResult)
|
|
46
|
-
} else {
|
|
47
|
-
// If the callback returns a primitive value, we can't merge it
|
|
48
|
-
// This would need a specific key, but since we don't have one, we'll skip it
|
|
49
|
-
// In practice, select callbacks should return objects with keys
|
|
50
|
-
console.warn(
|
|
51
|
-
`SelectCallback returned a non-object value. SelectCallbacks should return objects with key-value pairs.`
|
|
52
|
-
)
|
|
53
|
-
}
|
|
54
|
-
continue
|
|
55
|
-
}
|
|
56
|
-
|
|
57
|
-
if (typeof item === `string`) {
|
|
58
|
-
// Handle wildcard select - all columns from all tables
|
|
59
|
-
if ((item as string) === `@*`) {
|
|
60
|
-
// For grouped results, just return the row as is
|
|
61
|
-
if (isGroupedResult) {
|
|
62
|
-
Object.assign(result, namespacedRow)
|
|
63
|
-
} else {
|
|
64
|
-
// Extract all columns from all tables
|
|
65
|
-
Object.assign(
|
|
66
|
-
result,
|
|
67
|
-
extractAllColumnsFromAllTables(namespacedRow)
|
|
68
|
-
)
|
|
69
|
-
}
|
|
70
|
-
continue
|
|
71
|
-
}
|
|
72
|
-
|
|
73
|
-
// Handle @table.* syntax - all columns from a specific table
|
|
74
|
-
if (
|
|
75
|
-
(item as string).startsWith(`@`) &&
|
|
76
|
-
(item as string).endsWith(`.*`)
|
|
77
|
-
) {
|
|
78
|
-
const tableAlias = (item as string).slice(1, -2) // Remove the '@' and '.*' parts
|
|
79
|
-
|
|
80
|
-
// For grouped results, check if we have columns from this table
|
|
81
|
-
if (isGroupedResult) {
|
|
82
|
-
// In grouped results, we don't have the nested structure anymore
|
|
83
|
-
// So we can't extract by table. Just continue to the next item.
|
|
84
|
-
continue
|
|
85
|
-
} else {
|
|
86
|
-
// Extract all columns from the specified table
|
|
87
|
-
Object.assign(
|
|
88
|
-
result,
|
|
89
|
-
extractAllColumnsFromTable(namespacedRow, tableAlias)
|
|
90
|
-
)
|
|
91
|
-
}
|
|
92
|
-
continue
|
|
93
|
-
}
|
|
94
|
-
|
|
95
|
-
// Handle simple column references like "@table.column" or "@column"
|
|
96
|
-
if ((item as string).startsWith(`@`)) {
|
|
97
|
-
const columnRef = (item as string).substring(1)
|
|
98
|
-
const alias = columnRef
|
|
99
|
-
|
|
100
|
-
// For grouped results, check if the column is directly in the row first
|
|
101
|
-
if (isGroupedResult && columnRef in namespacedRow) {
|
|
102
|
-
result[alias] = namespacedRow[columnRef]
|
|
103
|
-
} else {
|
|
104
|
-
// Extract the value from the nested structure
|
|
105
|
-
result[alias] = extractValueFromNamespacedRow(
|
|
106
|
-
namespacedRow,
|
|
107
|
-
columnRef,
|
|
108
|
-
mainTableAlias,
|
|
109
|
-
undefined
|
|
110
|
-
)
|
|
111
|
-
}
|
|
112
|
-
|
|
113
|
-
// If the alias contains a dot (table.column),
|
|
114
|
-
// use just the column part as the field name
|
|
115
|
-
if (alias.includes(`.`)) {
|
|
116
|
-
const columnName = alias.split(`.`)[1]
|
|
117
|
-
result[columnName!] = result[alias]
|
|
118
|
-
delete result[alias]
|
|
119
|
-
}
|
|
120
|
-
}
|
|
121
|
-
} else {
|
|
122
|
-
// Handle aliased columns like { alias: "@column_name" }
|
|
123
|
-
for (const [alias, expr] of Object.entries(item)) {
|
|
124
|
-
if (typeof expr === `string` && (expr as string).startsWith(`@`)) {
|
|
125
|
-
const columnRef = (expr as string).substring(1)
|
|
126
|
-
|
|
127
|
-
// For grouped results, check if the column is directly in the row first
|
|
128
|
-
if (isGroupedResult && columnRef in namespacedRow) {
|
|
129
|
-
result[alias] = namespacedRow[columnRef]
|
|
130
|
-
} else {
|
|
131
|
-
// Extract the value from the nested structure
|
|
132
|
-
result[alias] = extractValueFromNamespacedRow(
|
|
133
|
-
namespacedRow,
|
|
134
|
-
columnRef,
|
|
135
|
-
mainTableAlias,
|
|
136
|
-
undefined
|
|
137
|
-
)
|
|
138
|
-
}
|
|
139
|
-
} else if (typeof expr === `object`) {
|
|
140
|
-
// For grouped results, the aggregate results are already in the row
|
|
141
|
-
if (isGroupedResult && alias in namespacedRow) {
|
|
142
|
-
result[alias] = namespacedRow[alias]
|
|
143
|
-
} else if ((expr as { ORDER_INDEX: unknown }).ORDER_INDEX) {
|
|
144
|
-
result[alias] = namespacedRow[mainTableAlias]![alias]
|
|
145
|
-
} else {
|
|
146
|
-
// This might be a function call
|
|
147
|
-
result[alias] = evaluateOperandOnNamespacedRow(
|
|
148
|
-
namespacedRow,
|
|
149
|
-
expr as ConditionOperand,
|
|
150
|
-
mainTableAlias,
|
|
151
|
-
undefined
|
|
152
|
-
)
|
|
153
|
-
}
|
|
154
|
-
}
|
|
155
|
-
}
|
|
156
|
-
}
|
|
157
|
-
}
|
|
158
|
-
|
|
159
|
-
return [key, result] as [string, typeof result]
|
|
160
|
-
})
|
|
161
|
-
)
|
|
162
|
-
}
|
|
163
|
-
|
|
164
|
-
// Helper function to extract all columns from all tables in a nested row
|
|
165
|
-
function extractAllColumnsFromAllTables(
|
|
166
|
-
namespacedRow: Record<string, unknown>
|
|
167
|
-
): Record<string, unknown> {
|
|
168
|
-
const result: Record<string, unknown> = {}
|
|
169
|
-
|
|
170
|
-
// Process each table in the nested row
|
|
171
|
-
for (const [tableAlias, tableData] of Object.entries(namespacedRow)) {
|
|
172
|
-
if (tableData && typeof tableData === `object`) {
|
|
173
|
-
// Add all columns from this table to the result
|
|
174
|
-
// If there are column name conflicts, the last table's columns will overwrite previous ones
|
|
175
|
-
Object.assign(
|
|
176
|
-
result,
|
|
177
|
-
extractAllColumnsFromTable(namespacedRow, tableAlias)
|
|
178
|
-
)
|
|
179
|
-
}
|
|
180
|
-
}
|
|
181
|
-
|
|
182
|
-
return result
|
|
183
|
-
}
|
|
184
|
-
|
|
185
|
-
// Helper function to extract all columns from a table in a nested row
|
|
186
|
-
function extractAllColumnsFromTable(
|
|
187
|
-
namespacedRow: Record<string, unknown>,
|
|
188
|
-
tableAlias: string
|
|
189
|
-
): Record<string, unknown> {
|
|
190
|
-
const result: Record<string, unknown> = {}
|
|
191
|
-
|
|
192
|
-
// Get the table data
|
|
193
|
-
const tableData = namespacedRow[tableAlias] as
|
|
194
|
-
| Record<string, unknown>
|
|
195
|
-
| null
|
|
196
|
-
| undefined
|
|
197
|
-
|
|
198
|
-
if (!tableData || typeof tableData !== `object`) {
|
|
199
|
-
return result
|
|
200
|
-
}
|
|
201
|
-
|
|
202
|
-
// Add all columns from the table to the result
|
|
203
|
-
for (const [columnName, value] of Object.entries(tableData)) {
|
|
204
|
-
result[columnName] = value
|
|
205
|
-
}
|
|
206
|
-
|
|
207
|
-
return result
|
|
208
|
-
}
|