effect-qb 0.19.0 → 0.21.0
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/README.md +7 -1
- package/dist/index.js +1990 -679
- package/dist/mysql.js +1490 -617
- package/dist/postgres/metadata.js +1334 -263
- package/dist/postgres.js +3376 -2307
- package/dist/sqlite.js +1573 -628
- package/dist/standard.js +1984 -673
- package/package.json +3 -6
- package/src/internal/coercion/rules.ts +13 -1
- package/src/internal/column-state.d.ts +3 -3
- package/src/internal/column-state.ts +13 -12
- package/src/internal/column.ts +8 -8
- package/src/internal/datatypes/define.ts +5 -0
- package/src/internal/datatypes/lookup.ts +67 -18
- package/src/internal/datatypes/matrix.ts +903 -0
- package/src/internal/datatypes/shape.ts +2 -0
- package/src/internal/dialect-renderers/mysql.ts +6 -4
- package/src/internal/dialect-renderers/postgres.ts +6 -4
- package/src/internal/dialect-renderers/sqlite.ts +6 -4
- package/src/internal/dialect.ts +1 -1
- package/src/internal/executor.ts +56 -43
- package/src/internal/json/path-access.ts +351 -0
- package/src/internal/query.d.ts +1 -1
- package/src/internal/query.ts +1 -1
- package/src/internal/runtime/driver-value-mapping.ts +3 -3
- package/src/internal/runtime/schema.ts +28 -38
- package/src/internal/runtime/value.ts +20 -23
- package/src/internal/scalar.d.ts +1 -1
- package/src/internal/scalar.ts +2 -1
- package/src/internal/schema-derivation.d.ts +7 -7
- package/src/internal/schema-derivation.ts +11 -11
- package/src/internal/standard-dsl.ts +121 -28
- package/src/internal/table.ts +451 -120
- package/src/mysql/column.ts +6 -6
- package/src/mysql/datatypes/index.ts +1 -0
- package/src/mysql/datatypes/spec.ts +6 -176
- package/src/mysql/errors/normalize.ts +0 -1
- package/src/mysql/executor.ts +4 -6
- package/src/mysql/function/temporal.ts +1 -1
- package/src/mysql/internal/dsl.ts +116 -16
- package/src/mysql/json.ts +1 -33
- package/src/mysql/renderer.ts +13 -6
- package/src/mysql/type.ts +60 -0
- package/src/mysql.ts +3 -1
- package/src/postgres/check.ts +1 -0
- package/src/postgres/column.ts +11 -11
- package/src/postgres/datatypes/index.ts +1 -0
- package/src/postgres/datatypes/spec.ts +6 -260
- package/src/postgres/errors/normalize.ts +0 -1
- package/src/postgres/executor.ts +4 -6
- package/src/postgres/foreign-key.ts +24 -0
- package/src/postgres/function/temporal.ts +1 -1
- package/src/postgres/index.ts +1 -0
- package/src/postgres/internal/dsl.ts +122 -21
- package/src/postgres/json-extension.ts +7 -0
- package/src/postgres/json.ts +726 -173
- package/src/postgres/jsonb.ts +0 -1
- package/src/postgres/primary-key.ts +24 -0
- package/src/postgres/renderer.ts +13 -6
- package/src/postgres/schema-management.ts +1 -6
- package/src/postgres/schema.ts +16 -8
- package/src/postgres/table.ts +111 -113
- package/src/postgres/type.ts +86 -4
- package/src/postgres/unique.ts +32 -0
- package/src/postgres.ts +12 -6
- package/src/sqlite/column.ts +6 -6
- package/src/sqlite/datatypes/index.ts +1 -0
- package/src/sqlite/datatypes/spec.ts +6 -94
- package/src/sqlite/errors/normalize.ts +0 -1
- package/src/sqlite/executor.ts +4 -6
- package/src/sqlite/function/temporal.ts +1 -1
- package/src/sqlite/internal/dsl.ts +100 -5
- package/src/sqlite/json.ts +1 -32
- package/src/sqlite/renderer.ts +13 -6
- package/src/sqlite/type.ts +40 -0
- package/src/sqlite.ts +3 -1
- package/src/standard/cast.ts +113 -0
- package/src/standard/check.ts +17 -0
- package/src/standard/column.ts +10 -10
- package/src/standard/datatypes/index.ts +2 -2
- package/src/standard/datatypes/spec.ts +10 -96
- package/src/standard/foreign-key.ts +37 -0
- package/src/standard/function/temporal.ts +1 -1
- package/src/standard/index.ts +17 -0
- package/src/standard/json.ts +883 -0
- package/src/standard/primary-key.ts +17 -0
- package/src/standard/renderer.ts +31 -3
- package/src/standard/table.ts +25 -21
- package/src/standard/unique.ts +17 -0
- package/src/standard.ts +14 -0
- package/src/internal/table.d.ts +0 -174
- package/src/postgres/cast.ts +0 -45
package/src/internal/table.ts
CHANGED
|
@@ -5,18 +5,15 @@ import * as Plan from "./row-set.js"
|
|
|
5
5
|
import type { Any as AnyExpression } from "./scalar.js"
|
|
6
6
|
import type { TrueFormula } from "./predicate/formula.js"
|
|
7
7
|
import type { BoundColumnFrom } from "./column-state.js"
|
|
8
|
-
import { bindColumn, type AnyColumnDefinition } from "./column-state.js"
|
|
8
|
+
import { bindColumn, BoundColumnTypeId, type AnyBoundColumn, type AnyColumnDefinition } from "./column-state.js"
|
|
9
9
|
import {
|
|
10
10
|
collectInlineOptions,
|
|
11
|
-
normalizeColumnList,
|
|
12
11
|
resolvePrimaryKeyColumns,
|
|
12
|
+
type ColumnList,
|
|
13
13
|
type DdlExpressionLike,
|
|
14
14
|
type IndexKeySpec,
|
|
15
15
|
type LiteralStringInput,
|
|
16
|
-
type MatchingColumnArityInput,
|
|
17
|
-
type NonEmptyColumnInput,
|
|
18
16
|
type NonEmptyStringInput,
|
|
19
|
-
type NormalizeColumns,
|
|
20
17
|
type ReferentialAction,
|
|
21
18
|
type TableOptionSpec,
|
|
22
19
|
type ValidateForeignKeyOptionColumns,
|
|
@@ -47,6 +44,7 @@ export const options: unique symbol = Symbol.for("effect-qb/Table/declaredOption
|
|
|
47
44
|
const CacheSymbol: unique symbol = Symbol.for("effect-qb/Table/cache")
|
|
48
45
|
const SchemaCacheSymbol: unique symbol = Symbol.for("effect-qb/Table/schemaCache")
|
|
49
46
|
const DeclaredOptionsSymbol: unique symbol = Symbol.for("effect-qb/Table/factoryDeclaredOptions")
|
|
47
|
+
const ResolveOptionSymbol: unique symbol = Symbol.for("effect-qb/Table/resolveOption")
|
|
50
48
|
|
|
51
49
|
type InlinePrimaryKeyKeys<Fields extends TableFieldMap> = Extract<{
|
|
52
50
|
[K in keyof Fields]: Fields[K]["metadata"]["primaryKey"] extends true ? K : never
|
|
@@ -63,6 +61,43 @@ type NonEmptyFieldMap<Fields extends TableFieldMap> =
|
|
|
63
61
|
string extends keyof Fields ? Fields : "" extends keyof Fields ? never : Fields
|
|
64
62
|
type FieldColumnName<Fields extends TableFieldMap> = Extract<keyof Fields, string>
|
|
65
63
|
type FieldColumnList<Fields extends TableFieldMap> = readonly [FieldColumnName<Fields>, ...FieldColumnName<Fields>[]]
|
|
64
|
+
export type SchemaTableDefinition = TableDefinition<any, any, any, "schema", any, any>
|
|
65
|
+
type LooseTableSelection = any
|
|
66
|
+
type ConcreteSelector<
|
|
67
|
+
Table extends SchemaTableDefinition,
|
|
68
|
+
Selection extends AnyColumnSelection
|
|
69
|
+
> = SchemaTableDefinition extends Table ? never : (table: Table) => Selection
|
|
70
|
+
type ColumnNameOfBound<Column> = Column extends {
|
|
71
|
+
readonly [BoundColumnTypeId]: {
|
|
72
|
+
readonly columnName: infer ColumnName extends string
|
|
73
|
+
}
|
|
74
|
+
} ? ColumnName : never
|
|
75
|
+
type BoundColumnTupleNames<Columns extends readonly AnyBoundColumn[]> =
|
|
76
|
+
Columns extends readonly [infer Head extends AnyBoundColumn, ...infer Tail extends AnyBoundColumn[]]
|
|
77
|
+
? readonly [ColumnNameOfBound<Head>, ...BoundColumnTupleNames<Tail>]
|
|
78
|
+
: readonly []
|
|
79
|
+
type ColumnSelectionNames<Selection> =
|
|
80
|
+
Selection extends AnyBoundColumn
|
|
81
|
+
? readonly [ColumnNameOfBound<Selection>]
|
|
82
|
+
: Selection extends readonly [infer Head extends AnyBoundColumn, ...infer Tail extends AnyBoundColumn[]]
|
|
83
|
+
? readonly [ColumnNameOfBound<Head>, ...BoundColumnTupleNames<Tail>]
|
|
84
|
+
: never
|
|
85
|
+
export type TableColumnSelection<Table extends SchemaTableDefinition> =
|
|
86
|
+
TableColumn<Table> | readonly [TableColumn<Table>, ...TableColumn<Table>[]]
|
|
87
|
+
export type TableColumn<Table extends SchemaTableDefinition> =
|
|
88
|
+
SchemaTableDefinition extends Table ? AnyBoundColumn : Table extends TableDefinition<infer Name, infer Fields, any, "schema", any>
|
|
89
|
+
? BoundColumns<Name, Fields>[Extract<keyof Fields, string>]
|
|
90
|
+
: never
|
|
91
|
+
export type AnyColumnSelection = AnyBoundColumn | readonly [AnyBoundColumn, ...AnyBoundColumn[]]
|
|
92
|
+
export type SelectedColumns<Selection extends AnyColumnSelection> = ColumnSelectionNames<Selection>
|
|
93
|
+
type MatchingSelectionArityInput<
|
|
94
|
+
Left extends AnyColumnSelection,
|
|
95
|
+
Right extends AnyColumnSelection
|
|
96
|
+
> = SelectedColumns<Left>["length"] extends SelectedColumns<Right>["length"]
|
|
97
|
+
? SelectedColumns<Right>["length"] extends SelectedColumns<Left>["length"]
|
|
98
|
+
? unknown
|
|
99
|
+
: never
|
|
100
|
+
: never
|
|
66
101
|
type FieldIndexKeySpec<Fields extends TableFieldMap> =
|
|
67
102
|
| (Extract<IndexKeySpec, { readonly kind: "column" }> & { readonly column: FieldColumnName<Fields> })
|
|
68
103
|
| Extract<IndexKeySpec, { readonly kind: "expression" }>
|
|
@@ -80,12 +115,16 @@ type ClassOptionSpec<Fields extends TableFieldMap = TableFieldMap> =
|
|
|
80
115
|
})
|
|
81
116
|
| Extract<TableOptionSpec, { readonly kind: "check" }>
|
|
82
117
|
interface TableOptionBuilderLike<
|
|
83
|
-
Spec extends TableOptionSpec = TableOptionSpec
|
|
118
|
+
Spec extends TableOptionSpec = TableOptionSpec,
|
|
119
|
+
TableContext extends SchemaTableDefinition = SchemaTableDefinition
|
|
84
120
|
> {
|
|
85
121
|
readonly option: Spec
|
|
86
122
|
}
|
|
87
123
|
|
|
88
|
-
type ClassTableOption<Fields extends TableFieldMap> =
|
|
124
|
+
type ClassTableOption<Fields extends TableFieldMap> = TableOption<
|
|
125
|
+
ClassOptionSpec<Fields>,
|
|
126
|
+
TableDefinition<string, Fields, keyof Fields & string, "schema", any>
|
|
127
|
+
>
|
|
89
128
|
type ClassDeclaredTableOptions<Fields extends TableFieldMap> = readonly ClassTableOption<Fields>[]
|
|
90
129
|
type TableNameOf<Table extends TableDefinition<any, any, any, "schema", any>> =
|
|
91
130
|
Table extends TableDefinition<infer Name, any, any, "schema", any> ? Name : never
|
|
@@ -95,39 +134,101 @@ type TablePrimaryKeyOf<Table extends TableDefinition<any, any, any, "schema", an
|
|
|
95
134
|
Table extends TableDefinition<any, any, infer PrimaryKeyColumns, "schema", any> ? PrimaryKeyColumns : never
|
|
96
135
|
type TableSchemaNameOf<Table extends TableDefinition<any, any, any, "schema", any>> =
|
|
97
136
|
Table extends TableDefinition<any, any, any, "schema", infer SchemaName> ? SchemaName : never
|
|
137
|
+
type HasBroadColumns<Columns extends readonly string[]> = string extends Columns[number] ? true : false
|
|
138
|
+
|
|
139
|
+
export type ConflictArbiterScope = "unconditional" | "partial"
|
|
140
|
+
export type ConflictArbiter<
|
|
141
|
+
Columns extends ColumnList = ColumnList,
|
|
142
|
+
Scope extends ConflictArbiterScope = ConflictArbiterScope,
|
|
143
|
+
Name extends string | undefined = string | undefined,
|
|
144
|
+
Constraint extends boolean = boolean
|
|
145
|
+
> = {
|
|
146
|
+
readonly columns: Columns
|
|
147
|
+
readonly scope: Scope
|
|
148
|
+
readonly name?: Name
|
|
149
|
+
readonly constraint: Constraint
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
type InlineConflictArbiters<Fields extends TableFieldMap> = Extract<{
|
|
153
|
+
[K in keyof Fields]: Fields[K] extends AnyColumnDefinition
|
|
154
|
+
? Fields[K]["metadata"]["primaryKey"] extends true
|
|
155
|
+
? ConflictArbiter<readonly [Extract<K, string>], "unconditional", undefined, true>
|
|
156
|
+
: Fields[K]["metadata"]["unique"] extends true
|
|
157
|
+
? ConflictArbiter<
|
|
158
|
+
readonly [Extract<K, string>],
|
|
159
|
+
"unconditional",
|
|
160
|
+
Fields[K]["metadata"]["uniqueConstraint"] extends { readonly name?: infer Name extends string } ? Name : undefined,
|
|
161
|
+
true
|
|
162
|
+
>
|
|
163
|
+
: never
|
|
164
|
+
: never
|
|
165
|
+
}[keyof Fields], ConflictArbiter>
|
|
166
|
+
|
|
167
|
+
type TableConflictArbitersOf<Table extends TableDefinition<any, any, any, any, any, any>> =
|
|
168
|
+
Table extends TableDefinition<any, any, any, any, any, infer ConflictArbiters> ? ConflictArbiters : never
|
|
169
|
+
|
|
170
|
+
type NormalizeArbiterColumns<Columns> =
|
|
171
|
+
Columns extends readonly [infer Head extends string, ...infer Tail extends string[]]
|
|
172
|
+
? readonly [Head, ...Tail]
|
|
173
|
+
: Columns extends string
|
|
174
|
+
? readonly [Columns]
|
|
175
|
+
: never
|
|
176
|
+
|
|
177
|
+
type OptionColumns<Spec extends TableOptionSpec> =
|
|
178
|
+
Spec extends { readonly columns?: infer Columns } ? NormalizeArbiterColumns<Columns> : never
|
|
179
|
+
|
|
180
|
+
type OptionName<Spec extends TableOptionSpec> =
|
|
181
|
+
Spec extends { readonly name: infer Name extends string } ? Name : undefined
|
|
182
|
+
|
|
183
|
+
type ConflictArbiterFromOption<Spec extends TableOptionSpec> =
|
|
184
|
+
OptionColumns<Spec> extends infer Columns extends ColumnList
|
|
185
|
+
? HasBroadColumns<Columns> extends true
|
|
186
|
+
? never
|
|
187
|
+
: Spec extends { readonly kind: "primaryKey" | "unique" }
|
|
188
|
+
? ConflictArbiter<Columns, "unconditional", OptionName<Spec>, true>
|
|
189
|
+
: Spec extends { readonly kind: "index"; readonly unique: true }
|
|
190
|
+
? ConflictArbiter<Columns, Spec extends { readonly predicate: DdlExpressionLike } ? "partial" : "unconditional", OptionName<Spec>, false>
|
|
191
|
+
: never
|
|
192
|
+
: never
|
|
98
193
|
|
|
99
194
|
type BuildPrimaryKey<
|
|
100
|
-
Table extends TableDefinition<any, any, any, "schema", any>,
|
|
195
|
+
Table extends TableDefinition<any, any, any, "schema", any, any>,
|
|
101
196
|
Spec extends TableOptionSpec
|
|
102
197
|
> = Spec extends { readonly kind: "primaryKey"; readonly columns: infer Columns extends readonly string[] }
|
|
103
|
-
? Columns
|
|
198
|
+
? HasBroadColumns<Columns> extends true
|
|
199
|
+
? TablePrimaryKeyOf<Table>
|
|
200
|
+
: Columns[number] & keyof TableFieldsOf<Table> & string
|
|
104
201
|
: TablePrimaryKeyOf<Table>
|
|
105
202
|
|
|
106
203
|
type OptionInputConstraint<
|
|
107
|
-
Table extends TableDefinition<any, any, any, "schema", any>,
|
|
204
|
+
Table extends TableDefinition<any, any, any, "schema", any, any>,
|
|
108
205
|
Spec extends TableOptionSpec
|
|
109
206
|
> = Spec extends { readonly kind: "primaryKey"; readonly columns: infer Columns extends readonly string[] }
|
|
110
|
-
? ValidatePrimaryKeyColumns<Table[typeof TypeId]["fields"], Columns> extends never ? never : unknown
|
|
207
|
+
? HasBroadColumns<Columns> extends true ? unknown : ValidatePrimaryKeyColumns<Table[typeof TypeId]["fields"], Columns> extends never ? never : unknown
|
|
111
208
|
: Spec extends { readonly kind: "index" }
|
|
112
|
-
?
|
|
209
|
+
? Spec extends { readonly columns: infer Columns extends readonly string[] }
|
|
210
|
+
? HasBroadColumns<Columns> extends true ? unknown : ValidateIndexOptionColumns<Table[typeof TypeId]["fields"], Spec> extends never ? never : unknown
|
|
211
|
+
: ValidateIndexOptionColumns<Table[typeof TypeId]["fields"], Spec> extends never ? never : unknown
|
|
113
212
|
: Spec extends { readonly kind: "foreignKey" }
|
|
114
|
-
?
|
|
213
|
+
? Spec extends { readonly columns: infer Columns extends readonly string[] }
|
|
214
|
+
? HasBroadColumns<Columns> extends true ? unknown : ValidateForeignKeyOptionColumns<Table[typeof TypeId]["fields"], Spec> extends never ? never : unknown
|
|
215
|
+
: ValidateForeignKeyOptionColumns<Table[typeof TypeId]["fields"], Spec> extends never ? never : unknown
|
|
115
216
|
: Spec extends { readonly columns: infer Columns extends readonly string[] }
|
|
116
|
-
? ValidateKnownColumns<Table[typeof TypeId]["fields"], Columns> extends never ? never : unknown
|
|
217
|
+
? HasBroadColumns<Columns> extends true ? unknown : ValidateKnownColumns<Table[typeof TypeId]["fields"], Columns> extends never ? never : unknown
|
|
117
218
|
: unknown
|
|
118
219
|
|
|
119
220
|
type OptionInputTable<
|
|
120
|
-
Table extends TableDefinition<any, any, any, "schema", any>,
|
|
221
|
+
Table extends TableDefinition<any, any, any, "schema", any, any>,
|
|
121
222
|
Spec extends TableOptionSpec
|
|
122
223
|
> = Table & OptionInputConstraint<Table, Spec>
|
|
123
224
|
|
|
124
225
|
type OptionValidationArgs<
|
|
125
|
-
Table extends TableDefinition<any, any, any, "schema", any>,
|
|
226
|
+
Table extends TableDefinition<any, any, any, "schema", any, any>,
|
|
126
227
|
Spec extends TableOptionSpec
|
|
127
228
|
> = OptionInputConstraint<Table, Spec> extends never ? [never] : []
|
|
128
229
|
|
|
129
230
|
type ApplyOption<
|
|
130
|
-
Table extends TableDefinition<any, any, any, "schema", any>,
|
|
231
|
+
Table extends TableDefinition<any, any, any, "schema", any, any>,
|
|
131
232
|
Spec extends TableOptionSpec
|
|
132
233
|
> = Spec extends { readonly kind: "primaryKey" }
|
|
133
234
|
? TableDefinition<
|
|
@@ -135,34 +236,41 @@ type ApplyOption<
|
|
|
135
236
|
TableFieldsOf<Table>,
|
|
136
237
|
BuildPrimaryKey<Table, Spec>,
|
|
137
238
|
"schema",
|
|
138
|
-
TableSchemaNameOf<Table
|
|
239
|
+
TableSchemaNameOf<Table>,
|
|
240
|
+
TableConflictArbitersOf<Table> | ConflictArbiterFromOption<Spec>
|
|
241
|
+
>
|
|
242
|
+
: TableDefinition<
|
|
243
|
+
TableNameOf<Table>,
|
|
244
|
+
TableFieldsOf<Table>,
|
|
245
|
+
TablePrimaryKeyOf<Table>,
|
|
246
|
+
"schema",
|
|
247
|
+
TableSchemaNameOf<Table>,
|
|
248
|
+
TableConflictArbitersOf<Table> | ConflictArbiterFromOption<Spec>
|
|
139
249
|
>
|
|
140
|
-
: Table
|
|
141
250
|
|
|
142
251
|
type ApplyTableOption<
|
|
143
|
-
Table extends TableDefinition<any, any, any, "schema", any>,
|
|
252
|
+
Table extends TableDefinition<any, any, any, "schema", any, any>,
|
|
144
253
|
Spec extends TableOptionSpec
|
|
145
|
-
> = Spec
|
|
146
|
-
? ApplyOption<Table, Spec>
|
|
147
|
-
: Table
|
|
254
|
+
> = ApplyOption<Table, Spec>
|
|
148
255
|
|
|
149
256
|
type TableOptionPipe<
|
|
150
257
|
Name extends string,
|
|
151
258
|
Fields extends TableFieldMap,
|
|
152
259
|
PrimaryKeyColumns extends keyof Fields & string,
|
|
153
260
|
Kind extends TableKind,
|
|
154
|
-
SchemaName extends string | undefined
|
|
261
|
+
SchemaName extends string | undefined,
|
|
262
|
+
ConflictArbiters extends ConflictArbiter
|
|
155
263
|
> = Kind extends "schema"
|
|
156
264
|
? {
|
|
157
265
|
pipe<Spec extends TableOptionSpec>(
|
|
158
|
-
option: TableOption<Spec
|
|
159
|
-
...validation: OptionValidationArgs<TableDefinition<Name, Fields, PrimaryKeyColumns, "schema", SchemaName>, Spec>
|
|
160
|
-
): ApplyTableOption<TableDefinition<Name, Fields, PrimaryKeyColumns, "schema", SchemaName>, Spec>
|
|
266
|
+
option: TableOption<Spec, TableDefinition<Name, Fields, PrimaryKeyColumns, "schema", SchemaName, ConflictArbiters>>,
|
|
267
|
+
...validation: OptionValidationArgs<TableDefinition<Name, Fields, PrimaryKeyColumns, "schema", SchemaName, ConflictArbiters>, Spec>
|
|
268
|
+
): ApplyTableOption<TableDefinition<Name, Fields, PrimaryKeyColumns, "schema", SchemaName, ConflictArbiters>, Spec>
|
|
161
269
|
}
|
|
162
270
|
: {}
|
|
163
271
|
|
|
164
272
|
export type ValidateDeclaredOptions<
|
|
165
|
-
Table extends TableDefinition<any, any, any, "schema", any>,
|
|
273
|
+
Table extends TableDefinition<any, any, any, "schema", any, any>,
|
|
166
274
|
Options extends DeclaredTableOptions
|
|
167
275
|
> = {
|
|
168
276
|
readonly [K in keyof Options]: Options[K] extends TableOptionBuilderLike<infer Spec>
|
|
@@ -171,7 +279,7 @@ export type ValidateDeclaredOptions<
|
|
|
171
279
|
}
|
|
172
280
|
|
|
173
281
|
export type ApplyDeclaredOptions<
|
|
174
|
-
Table extends TableDefinition<any, any, any, "schema", any>,
|
|
282
|
+
Table extends TableDefinition<any, any, any, "schema", any, any>,
|
|
175
283
|
Options extends DeclaredTableOptions
|
|
176
284
|
> = Options extends readonly [infer Head, ...infer Tail]
|
|
177
285
|
? Head extends TableOptionBuilderLike<infer Spec>
|
|
@@ -197,9 +305,9 @@ export interface TableSchemas<
|
|
|
197
305
|
Fields extends TableFieldMap,
|
|
198
306
|
PrimaryKeyColumns extends keyof Fields & string
|
|
199
307
|
> {
|
|
200
|
-
readonly select: Schema.
|
|
201
|
-
readonly insert: Schema.
|
|
202
|
-
readonly update: Schema.
|
|
308
|
+
readonly select: Schema.ConstraintDecoder<SelectRow<Name, Fields>, never>
|
|
309
|
+
readonly insert: Schema.ConstraintDecoder<InsertRow<Name, Fields>, never>
|
|
310
|
+
readonly update: Schema.ConstraintDecoder<UpdateRow<Name, Fields, PrimaryKeyColumns>, never>
|
|
203
311
|
}
|
|
204
312
|
|
|
205
313
|
type AnyTableSchemas = {
|
|
@@ -221,13 +329,15 @@ interface TableState<
|
|
|
221
329
|
Fields extends TableFieldMap,
|
|
222
330
|
PrimaryKeyColumns extends keyof Fields & string,
|
|
223
331
|
Kind extends TableKind = "schema",
|
|
224
|
-
SchemaName extends string | undefined = DefaultSchemaName
|
|
332
|
+
SchemaName extends string | undefined = DefaultSchemaName,
|
|
333
|
+
ConflictArbiters extends ConflictArbiter = InlineConflictArbiters<Fields>
|
|
225
334
|
> {
|
|
226
335
|
readonly name: Name
|
|
227
336
|
readonly baseName: string
|
|
228
337
|
readonly schemaName: SchemaName
|
|
229
338
|
readonly fields: Fields
|
|
230
339
|
readonly primaryKey: readonly PrimaryKeyColumns[]
|
|
340
|
+
readonly conflictArbiters: readonly ConflictArbiters[]
|
|
231
341
|
readonly kind: Kind
|
|
232
342
|
readonly casing?: Casing.Options
|
|
233
343
|
}
|
|
@@ -243,12 +353,13 @@ export type TableDefinition<
|
|
|
243
353
|
Fields extends TableFieldMap,
|
|
244
354
|
PrimaryKeyColumns extends keyof Fields & string = InlinePrimaryKeyKeys<Fields>,
|
|
245
355
|
Kind extends TableKind = "schema",
|
|
246
|
-
SchemaName extends string | undefined = DefaultSchemaName
|
|
247
|
-
|
|
356
|
+
SchemaName extends string | undefined = DefaultSchemaName,
|
|
357
|
+
ConflictArbiters extends ConflictArbiter = InlineConflictArbiters<Fields>
|
|
358
|
+
> = Pipeable & TableOptionPipe<Name, Fields, PrimaryKeyColumns, Kind, SchemaName, ConflictArbiters> & {
|
|
248
359
|
readonly name: Name
|
|
249
360
|
readonly columns: BoundColumns<Name, Fields>
|
|
250
361
|
readonly schemas: TableSchemas<Name, Fields, PrimaryKeyColumns> & AnyTableSchemas
|
|
251
|
-
readonly [TypeId]: TableState<Name, Fields, PrimaryKeyColumns, Kind, SchemaName>
|
|
362
|
+
readonly [TypeId]: TableState<Name, Fields, PrimaryKeyColumns, Kind, SchemaName, ConflictArbiters>
|
|
252
363
|
readonly [Plan.TypeId]: Plan.State<
|
|
253
364
|
BoundColumns<Name, Fields>,
|
|
254
365
|
never,
|
|
@@ -274,11 +385,12 @@ export type TableClassStatic<
|
|
|
274
385
|
Name extends string,
|
|
275
386
|
Fields extends TableFieldMap,
|
|
276
387
|
PrimaryKeyColumns extends keyof Fields & string = InlinePrimaryKeyKeys<Fields>,
|
|
277
|
-
SchemaName extends string | undefined = DefaultSchemaName
|
|
388
|
+
SchemaName extends string | undefined = DefaultSchemaName,
|
|
389
|
+
ConflictArbiters extends ConflictArbiter = InlineConflictArbiters<Fields>
|
|
278
390
|
> = (abstract new (...args: any[]) => any) & Pipeable & {
|
|
279
391
|
readonly columns: BoundColumns<Name, Fields>
|
|
280
392
|
readonly schemas: TableSchemas<Name, Fields, PrimaryKeyColumns>
|
|
281
|
-
readonly [TypeId]: TableState<Name, Fields, PrimaryKeyColumns, "schema", SchemaName>
|
|
393
|
+
readonly [TypeId]: TableState<Name, Fields, PrimaryKeyColumns, "schema", SchemaName, ConflictArbiters>
|
|
282
394
|
readonly [Plan.TypeId]: Plan.State<
|
|
283
395
|
BoundColumns<Name, Fields>,
|
|
284
396
|
never,
|
|
@@ -298,32 +410,33 @@ export type TableClassStatic<
|
|
|
298
410
|
|
|
299
411
|
/** Minimal structural table-like contract used across helper APIs. */
|
|
300
412
|
export type AnyTable<Dialect extends string = string> = {
|
|
301
|
-
readonly [TypeId]: TableState<string, TableFieldMap, string, TableKind, string | undefined>
|
|
413
|
+
readonly [TypeId]: TableState<string, TableFieldMap, string, TableKind, string | undefined, ConflictArbiter>
|
|
302
414
|
readonly [OptionsSymbol]: readonly TableOptionSpec[]
|
|
303
415
|
} & Plan.RowSet<any, any, Record<string, Plan.AnySource>, Dialect>
|
|
304
416
|
|
|
305
|
-
type
|
|
306
|
-
|
|
307
|
-
type ColumnNamesOfAnyTable<Table extends AnyTable> = Extract<keyof FieldsOfAnyTable<Table>, string>
|
|
417
|
+
type CheckPredicateTable = any
|
|
418
|
+
type CheckPredicate = (table: CheckPredicateTable) => DdlExpressionLike
|
|
308
419
|
|
|
309
420
|
/** Public table-option builder type used by `Table.index`, `Table.primaryKey`, and friends. */
|
|
310
421
|
export type TableOption<
|
|
311
|
-
Spec extends TableOptionSpec = TableOptionSpec
|
|
422
|
+
Spec extends TableOptionSpec = TableOptionSpec,
|
|
423
|
+
TableContext extends SchemaTableDefinition = SchemaTableDefinition
|
|
312
424
|
> = Pipeable & {
|
|
313
425
|
readonly pipe: Pipeable["pipe"]
|
|
314
426
|
readonly option: Spec
|
|
427
|
+
readonly [ResolveOptionSymbol]?: (table: TableDefinition<any, any, any, "schema", any>) => Spec
|
|
315
428
|
} & (Spec extends { readonly kind: "primaryKey" }
|
|
316
429
|
? {
|
|
317
|
-
<Table extends
|
|
430
|
+
<Table extends TableContext>(
|
|
318
431
|
table: Table,
|
|
319
432
|
...validation: OptionValidationArgs<Table, Spec>
|
|
320
433
|
): ApplyOption<Table, Spec>
|
|
321
434
|
}
|
|
322
435
|
: {
|
|
323
|
-
<Table extends
|
|
436
|
+
<Table extends TableContext>(
|
|
324
437
|
table: Table,
|
|
325
438
|
...validation: OptionValidationArgs<Table, Spec>
|
|
326
|
-
): Table
|
|
439
|
+
): ApplyOption<Table, Spec>
|
|
327
440
|
})
|
|
328
441
|
|
|
329
442
|
const TableProto = {
|
|
@@ -351,8 +464,42 @@ type BuildArtifacts<
|
|
|
351
464
|
readonly columns: BoundColumns<Name, Fields>
|
|
352
465
|
readonly normalizedOptions: readonly TableOptionSpec[]
|
|
353
466
|
readonly primaryKey: readonly PrimaryKeyColumns[]
|
|
467
|
+
readonly conflictArbiters: readonly ConflictArbiter[]
|
|
354
468
|
}
|
|
355
469
|
|
|
470
|
+
const conflictArbitersFromOptions = (
|
|
471
|
+
options: readonly TableOptionSpec[]
|
|
472
|
+
): readonly ConflictArbiter[] =>
|
|
473
|
+
options.flatMap((option): readonly ConflictArbiter[] => {
|
|
474
|
+
if (typeof option !== "object" || option === null) {
|
|
475
|
+
return []
|
|
476
|
+
}
|
|
477
|
+
if (!("columns" in option) || !Array.isArray(option.columns) || option.columns.length === 0) {
|
|
478
|
+
return []
|
|
479
|
+
}
|
|
480
|
+
switch (option.kind) {
|
|
481
|
+
case "primaryKey":
|
|
482
|
+
case "unique":
|
|
483
|
+
return [{
|
|
484
|
+
columns: option.columns as ColumnList,
|
|
485
|
+
scope: "unconditional",
|
|
486
|
+
name: option.name,
|
|
487
|
+
constraint: true
|
|
488
|
+
}]
|
|
489
|
+
case "index":
|
|
490
|
+
return option.unique === true
|
|
491
|
+
? [{
|
|
492
|
+
columns: option.columns as ColumnList,
|
|
493
|
+
scope: option.predicate === undefined ? "unconditional" : "partial",
|
|
494
|
+
name: option.name,
|
|
495
|
+
constraint: false
|
|
496
|
+
}]
|
|
497
|
+
: []
|
|
498
|
+
default:
|
|
499
|
+
return []
|
|
500
|
+
}
|
|
501
|
+
})
|
|
502
|
+
|
|
356
503
|
const buildArtifacts = <
|
|
357
504
|
Name extends string,
|
|
358
505
|
Fields extends TableFieldMap,
|
|
@@ -368,13 +515,15 @@ const buildArtifacts = <
|
|
|
368
515
|
validateFieldDialects(name, fields)
|
|
369
516
|
validateOptions(name, fields, declaredOptions)
|
|
370
517
|
const primaryKey = resolvePrimaryKeyColumns(fields, declaredOptions) as readonly (keyof Fields & string)[]
|
|
518
|
+
const conflictArbiters = conflictArbitersFromOptions(normalizedOptions)
|
|
371
519
|
const columns = Object.fromEntries(
|
|
372
520
|
Object.entries(fields).map(([key, column]) => [key, bindColumn(name, key, column, name, schemaName, casing)])
|
|
373
521
|
) as BoundColumns<Name, Fields>
|
|
374
522
|
return {
|
|
375
523
|
columns,
|
|
376
524
|
normalizedOptions,
|
|
377
|
-
primaryKey
|
|
525
|
+
primaryKey,
|
|
526
|
+
conflictArbiters
|
|
378
527
|
}
|
|
379
528
|
}
|
|
380
529
|
|
|
@@ -444,8 +593,8 @@ export function selectSchema<
|
|
|
444
593
|
PrimaryKeyColumns extends keyof Fields & string
|
|
445
594
|
>(
|
|
446
595
|
table: TableDefinition<Name, Fields, PrimaryKeyColumns, any, any> | TableClassStatic<Name, Fields, PrimaryKeyColumns, any>
|
|
447
|
-
): Schema.
|
|
448
|
-
return schemaFor(table, "select") as Schema.
|
|
596
|
+
): Schema.ConstraintDecoder<SelectRow<Name, Fields>, never> {
|
|
597
|
+
return schemaFor(table, "select") as Schema.ConstraintDecoder<SelectRow<Name, Fields>, never>
|
|
449
598
|
}
|
|
450
599
|
|
|
451
600
|
export function insertSchema<
|
|
@@ -454,8 +603,8 @@ export function insertSchema<
|
|
|
454
603
|
PrimaryKeyColumns extends keyof Fields & string
|
|
455
604
|
>(
|
|
456
605
|
table: TableDefinition<Name, Fields, PrimaryKeyColumns, any, any> | TableClassStatic<Name, Fields, PrimaryKeyColumns, any>
|
|
457
|
-
): Schema.
|
|
458
|
-
return schemaFor(table, "insert") as Schema.
|
|
606
|
+
): Schema.ConstraintDecoder<InsertRow<Name, Fields>, never> {
|
|
607
|
+
return schemaFor(table, "insert") as Schema.ConstraintDecoder<InsertRow<Name, Fields>, never>
|
|
459
608
|
}
|
|
460
609
|
|
|
461
610
|
export function updateSchema<
|
|
@@ -464,8 +613,8 @@ export function updateSchema<
|
|
|
464
613
|
PrimaryKeyColumns extends keyof Fields & string
|
|
465
614
|
>(
|
|
466
615
|
table: TableDefinition<Name, Fields, PrimaryKeyColumns, any, any> | TableClassStatic<Name, Fields, PrimaryKeyColumns, any>
|
|
467
|
-
): Schema.
|
|
468
|
-
return schemaFor(table, "update") as Schema.
|
|
616
|
+
): Schema.ConstraintDecoder<UpdateRow<Name, Fields, PrimaryKeyColumns>, never> {
|
|
617
|
+
return schemaFor(table, "update") as Schema.ConstraintDecoder<UpdateRow<Name, Fields, PrimaryKeyColumns>, never>
|
|
469
618
|
}
|
|
470
619
|
|
|
471
620
|
const schemasFor = <
|
|
@@ -519,7 +668,8 @@ const makeTable = <
|
|
|
519
668
|
Fields extends TableFieldMap,
|
|
520
669
|
PrimaryKeyColumns extends keyof Fields & string,
|
|
521
670
|
Kind extends TableKind = "schema",
|
|
522
|
-
SchemaName extends string | undefined = DefaultSchemaName
|
|
671
|
+
SchemaName extends string | undefined = DefaultSchemaName,
|
|
672
|
+
ConflictArbiters extends ConflictArbiter = InlineConflictArbiters<Fields>
|
|
523
673
|
>(
|
|
524
674
|
name: Name,
|
|
525
675
|
fields: Fields,
|
|
@@ -529,7 +679,7 @@ const makeTable = <
|
|
|
529
679
|
schemaName?: SchemaName,
|
|
530
680
|
schemaMode: "default" | "explicit" = "default",
|
|
531
681
|
casing?: Casing.Options
|
|
532
|
-
): TableDefinition<Name, Fields, PrimaryKeyColumns, Kind, SchemaName> => {
|
|
682
|
+
): TableDefinition<Name, Fields, PrimaryKeyColumns, Kind, SchemaName, ConflictArbiters> => {
|
|
533
683
|
const resolvedSchemaName = schemaMode === "explicit"
|
|
534
684
|
? schemaName
|
|
535
685
|
: ("public" as SchemaName)
|
|
@@ -545,6 +695,7 @@ const makeTable = <
|
|
|
545
695
|
schemaName: resolvedSchemaName,
|
|
546
696
|
fields,
|
|
547
697
|
primaryKey: artifacts.primaryKey,
|
|
698
|
+
conflictArbiters: artifacts.conflictArbiters as readonly ConflictArbiters[],
|
|
548
699
|
kind,
|
|
549
700
|
casing
|
|
550
701
|
}
|
|
@@ -645,7 +796,8 @@ const ensureClassArtifacts = <
|
|
|
645
796
|
const artifacts = {
|
|
646
797
|
columns: table.columns,
|
|
647
798
|
normalizedOptions: table[OptionsSymbol],
|
|
648
|
-
primaryKey: table[TypeId].primaryKey as readonly PrimaryKeyColumns[]
|
|
799
|
+
primaryKey: table[TypeId].primaryKey as readonly PrimaryKeyColumns[],
|
|
800
|
+
conflictArbiters: table[TypeId].conflictArbiters
|
|
649
801
|
} satisfies BuildArtifacts<Name, Fields, PrimaryKeyColumns>
|
|
650
802
|
Object.defineProperty(self, CacheSymbol, {
|
|
651
803
|
configurable: true,
|
|
@@ -674,7 +826,10 @@ const appendOption = <
|
|
|
674
826
|
) as unknown as ApplyOption<Table, Spec>
|
|
675
827
|
}
|
|
676
828
|
|
|
677
|
-
const makeOption = <
|
|
829
|
+
const makeOption = <
|
|
830
|
+
Spec extends TableOptionSpec,
|
|
831
|
+
TableContext extends SchemaTableDefinition = SchemaTableDefinition
|
|
832
|
+
>(option: Spec): TableOption<Spec, TableContext> => {
|
|
678
833
|
return attachPipe(Object.assign(
|
|
679
834
|
<Table extends TableDefinition<any, any, any, "schema", any>>(
|
|
680
835
|
table: Table,
|
|
@@ -682,13 +837,16 @@ const makeOption = <Spec extends TableOptionSpec>(option: Spec): TableOption<Spe
|
|
|
682
837
|
): ApplyTableOption<Table, Spec> =>
|
|
683
838
|
appendOption(table, option) as unknown as ApplyTableOption<Table, Spec>,
|
|
684
839
|
{ option }
|
|
685
|
-
)) as TableOption<Spec>
|
|
840
|
+
)) as unknown as TableOption<Spec, TableContext>
|
|
686
841
|
}
|
|
687
842
|
|
|
688
|
-
const makeResolvedOption = <
|
|
843
|
+
const makeResolvedOption = <
|
|
844
|
+
Spec extends TableOptionSpec,
|
|
845
|
+
TableContext extends SchemaTableDefinition = SchemaTableDefinition
|
|
846
|
+
>(
|
|
689
847
|
option: Spec,
|
|
690
848
|
resolve: (table: TableDefinition<any, any, any, "schema", any>) => Spec
|
|
691
|
-
): TableOption<Spec> => {
|
|
849
|
+
): TableOption<Spec, TableContext> => {
|
|
692
850
|
return attachPipe(Object.assign(
|
|
693
851
|
<Table extends TableDefinition<any, any, any, "schema", any>>(
|
|
694
852
|
table: Table,
|
|
@@ -698,19 +856,53 @@ const makeResolvedOption = <Spec extends TableOptionSpec>(
|
|
|
698
856
|
table,
|
|
699
857
|
resolve(table)
|
|
700
858
|
) as unknown as ApplyTableOption<Table, Spec>,
|
|
701
|
-
{
|
|
702
|
-
|
|
859
|
+
{
|
|
860
|
+
option,
|
|
861
|
+
[ResolveOptionSymbol]: resolve
|
|
862
|
+
}
|
|
863
|
+
)) as unknown as TableOption<Spec, TableContext>
|
|
703
864
|
}
|
|
704
865
|
|
|
705
866
|
export const option = <Spec extends TableOptionSpec>(spec: Spec): TableOption<Spec> =>
|
|
706
867
|
makeOption(spec)
|
|
707
868
|
|
|
708
|
-
export const optionFromTable = <
|
|
869
|
+
export const optionFromTable = <
|
|
870
|
+
Spec extends TableOptionSpec,
|
|
871
|
+
TableContext extends SchemaTableDefinition = SchemaTableDefinition
|
|
872
|
+
>(
|
|
709
873
|
spec: Spec,
|
|
710
874
|
resolve: (table: TableDefinition<any, any, any, "schema", any>) => Spec
|
|
711
|
-
): TableOption<Spec> =>
|
|
875
|
+
): TableOption<Spec, TableContext> =>
|
|
712
876
|
makeResolvedOption(spec, resolve)
|
|
713
877
|
|
|
878
|
+
export const resolveOption = <
|
|
879
|
+
Spec extends TableOptionSpec,
|
|
880
|
+
TableContext extends SchemaTableDefinition
|
|
881
|
+
>(
|
|
882
|
+
option: TableOption<Spec, TableContext>,
|
|
883
|
+
table: TableContext
|
|
884
|
+
): Spec => {
|
|
885
|
+
const resolve = option[ResolveOptionSymbol]
|
|
886
|
+
return resolve === undefined ? option.option : resolve(table)
|
|
887
|
+
}
|
|
888
|
+
|
|
889
|
+
export const mapOption = <
|
|
890
|
+
Spec extends TableOptionSpec,
|
|
891
|
+
Next extends TableOptionSpec,
|
|
892
|
+
TableContext extends SchemaTableDefinition
|
|
893
|
+
>(
|
|
894
|
+
option: TableOption<Spec, TableContext>,
|
|
895
|
+
map: (spec: Spec) => Next
|
|
896
|
+
): TableOption<Next, TableContext> => {
|
|
897
|
+
const resolve = option[ResolveOptionSymbol]
|
|
898
|
+
return resolve === undefined
|
|
899
|
+
? makeOption<Next, TableContext>(map(option.option))
|
|
900
|
+
: makeResolvedOption<Next, TableContext>(
|
|
901
|
+
map(option.option),
|
|
902
|
+
(table) => map(resolve(table))
|
|
903
|
+
)
|
|
904
|
+
}
|
|
905
|
+
|
|
714
906
|
/** Creates a table definition from a name and field map. */
|
|
715
907
|
export function make<
|
|
716
908
|
Name extends string,
|
|
@@ -732,7 +924,7 @@ export function make(
|
|
|
732
924
|
name: string,
|
|
733
925
|
fields: TableFieldMap,
|
|
734
926
|
schemaName?: string
|
|
735
|
-
):
|
|
927
|
+
): any {
|
|
736
928
|
const resolvedSchemaName = arguments.length >= 3
|
|
737
929
|
? schemaName
|
|
738
930
|
: "public"
|
|
@@ -778,7 +970,8 @@ export const withSchema = <
|
|
|
778
970
|
Table[typeof TypeId]["fields"],
|
|
779
971
|
Table[typeof TypeId]["primaryKey"][number],
|
|
780
972
|
Table[typeof TypeId]["kind"],
|
|
781
|
-
SchemaName
|
|
973
|
+
SchemaName,
|
|
974
|
+
Table[typeof TypeId]["conflictArbiters"][number]
|
|
782
975
|
> => {
|
|
783
976
|
const state = table[TypeId]
|
|
784
977
|
return makeTable(
|
|
@@ -795,7 +988,8 @@ export const withSchema = <
|
|
|
795
988
|
Table[typeof TypeId]["fields"],
|
|
796
989
|
Table[typeof TypeId]["primaryKey"][number],
|
|
797
990
|
Table[typeof TypeId]["kind"],
|
|
798
|
-
SchemaName
|
|
991
|
+
SchemaName,
|
|
992
|
+
Table[typeof TypeId]["conflictArbiters"][number]
|
|
799
993
|
>
|
|
800
994
|
}
|
|
801
995
|
|
|
@@ -811,16 +1005,18 @@ export const alias = <
|
|
|
811
1005
|
Fields extends TableFieldMap,
|
|
812
1006
|
PrimaryKeyColumns extends keyof Fields & string,
|
|
813
1007
|
SchemaName extends string,
|
|
1008
|
+
ConflictArbiters extends ConflictArbiter,
|
|
814
1009
|
AliasName extends string
|
|
815
1010
|
>(
|
|
816
|
-
table: TableDefinition<Name, Fields, PrimaryKeyColumns, any, SchemaName> | TableClassStatic<Name, Fields, PrimaryKeyColumns, SchemaName>,
|
|
1011
|
+
table: TableDefinition<Name, Fields, PrimaryKeyColumns, any, SchemaName, ConflictArbiters> | TableClassStatic<Name, Fields, PrimaryKeyColumns, SchemaName, ConflictArbiters>,
|
|
817
1012
|
aliasName: LiteralStringInput<AliasName>
|
|
818
1013
|
): TableDefinition<
|
|
819
1014
|
AliasName,
|
|
820
1015
|
Fields,
|
|
821
1016
|
PrimaryKeyColumns,
|
|
822
1017
|
"alias",
|
|
823
|
-
SchemaName
|
|
1018
|
+
SchemaName,
|
|
1019
|
+
ConflictArbiters
|
|
824
1020
|
> => {
|
|
825
1021
|
const state = table[TypeId]
|
|
826
1022
|
const columns = Object.fromEntries(
|
|
@@ -836,6 +1032,7 @@ export const alias = <
|
|
|
836
1032
|
schemaName: state.schemaName,
|
|
837
1033
|
fields: state.fields,
|
|
838
1034
|
primaryKey: state.primaryKey,
|
|
1035
|
+
conflictArbiters: state.conflictArbiters,
|
|
839
1036
|
kind: "alias",
|
|
840
1037
|
casing: state.casing
|
|
841
1038
|
}
|
|
@@ -913,12 +1110,14 @@ export function Class<
|
|
|
913
1110
|
|
|
914
1111
|
static get [TypeId]() {
|
|
915
1112
|
const declaredOptions = extractDeclaredOptions((this as unknown as TableClassStatic<Name, Fields>)[options])
|
|
1113
|
+
const normalizedOptions = [...collectInlineOptions(fields), ...declaredOptions]
|
|
916
1114
|
return {
|
|
917
1115
|
name,
|
|
918
1116
|
baseName: name,
|
|
919
1117
|
schemaName: resolvedSchemaName,
|
|
920
1118
|
fields,
|
|
921
1119
|
primaryKey: resolvePrimaryKeyColumns(fields, collectInlineOptions(fields)),
|
|
1120
|
+
conflictArbiters: conflictArbitersFromOptions(normalizedOptions),
|
|
922
1121
|
kind: "schema"
|
|
923
1122
|
}
|
|
924
1123
|
}
|
|
@@ -962,88 +1161,220 @@ export function Class<
|
|
|
962
1161
|
}
|
|
963
1162
|
}
|
|
964
1163
|
|
|
1164
|
+
const selectionArray = (selection: AnyColumnSelection): readonly AnyBoundColumn[] =>
|
|
1165
|
+
(Array.isArray(selection) ? selection : [selection]) as readonly AnyBoundColumn[]
|
|
1166
|
+
|
|
1167
|
+
export const selectedColumnList = <Selection extends AnyColumnSelection>(
|
|
1168
|
+
selection: Selection
|
|
1169
|
+
): SelectedColumns<Selection> =>
|
|
1170
|
+
selectionArray(selection).map((column) => column[BoundColumnTypeId].columnName) as unknown as SelectedColumns<Selection>
|
|
1171
|
+
|
|
1172
|
+
const referenceFromSelection = <Selection extends AnyColumnSelection>(selection: Selection) => {
|
|
1173
|
+
const columns = selectionArray(selection)
|
|
1174
|
+
const first = columns[0]!
|
|
1175
|
+
const bound = first[BoundColumnTypeId]
|
|
1176
|
+
return {
|
|
1177
|
+
tableName: bound.baseTableName,
|
|
1178
|
+
schemaName: bound.schemaName,
|
|
1179
|
+
casing: bound.casing,
|
|
1180
|
+
columns: columns.map((column) => column[BoundColumnTypeId].columnName) as unknown as SelectedColumns<Selection>
|
|
1181
|
+
}
|
|
1182
|
+
}
|
|
1183
|
+
|
|
965
1184
|
/** Declares a table-level primary key. */
|
|
966
|
-
export
|
|
967
|
-
|
|
1185
|
+
export function primaryKey<
|
|
1186
|
+
Table extends SchemaTableDefinition,
|
|
1187
|
+
Selection extends TableColumnSelection<Table> = TableColumnSelection<Table>
|
|
1188
|
+
>(
|
|
1189
|
+
columns: ConcreteSelector<Table, Selection>
|
|
1190
|
+
): TableOption<{
|
|
1191
|
+
readonly kind: "primaryKey"
|
|
1192
|
+
readonly columns: SelectedColumns<Selection>
|
|
1193
|
+
}, Table>
|
|
1194
|
+
export function primaryKey<
|
|
1195
|
+
Selection extends AnyColumnSelection
|
|
968
1196
|
>(
|
|
969
|
-
columns:
|
|
1197
|
+
columns: (table: LooseTableSelection) => Selection
|
|
1198
|
+
): TableOption<{
|
|
1199
|
+
readonly kind: "primaryKey"
|
|
1200
|
+
readonly columns: SelectedColumns<Selection>
|
|
1201
|
+
}>
|
|
1202
|
+
export function primaryKey(
|
|
1203
|
+
columns: (table: any) => AnyColumnSelection
|
|
970
1204
|
): TableOption<{
|
|
971
1205
|
readonly kind: "primaryKey"
|
|
972
|
-
readonly columns:
|
|
973
|
-
}>
|
|
974
|
-
|
|
975
|
-
|
|
976
|
-
|
|
1206
|
+
readonly columns: readonly [string, ...string[]]
|
|
1207
|
+
}> {
|
|
1208
|
+
return makeResolvedOption({
|
|
1209
|
+
kind: "primaryKey",
|
|
1210
|
+
columns: [] as unknown as readonly [string, ...string[]]
|
|
1211
|
+
}, (table) => ({
|
|
1212
|
+
kind: "primaryKey",
|
|
1213
|
+
columns: selectedColumnList(columns(table))
|
|
1214
|
+
}))
|
|
1215
|
+
}
|
|
977
1216
|
|
|
978
1217
|
/** Declares a table-level unique constraint. */
|
|
979
|
-
export
|
|
980
|
-
|
|
1218
|
+
export function unique<
|
|
1219
|
+
Table extends SchemaTableDefinition,
|
|
1220
|
+
Selection extends TableColumnSelection<Table> = TableColumnSelection<Table>
|
|
1221
|
+
>(
|
|
1222
|
+
columns: ConcreteSelector<Table, Selection>
|
|
1223
|
+
): TableOption<{
|
|
1224
|
+
readonly kind: "unique"
|
|
1225
|
+
readonly columns: SelectedColumns<Selection>
|
|
1226
|
+
}, Table>
|
|
1227
|
+
export function unique<
|
|
1228
|
+
Selection extends AnyColumnSelection
|
|
981
1229
|
>(
|
|
982
|
-
columns:
|
|
1230
|
+
columns: (table: LooseTableSelection) => Selection
|
|
1231
|
+
): TableOption<{
|
|
1232
|
+
readonly kind: "unique"
|
|
1233
|
+
readonly columns: SelectedColumns<Selection>
|
|
1234
|
+
}>
|
|
1235
|
+
export function unique(
|
|
1236
|
+
columns: (table: any) => AnyColumnSelection
|
|
983
1237
|
): TableOption<{
|
|
984
1238
|
readonly kind: "unique"
|
|
985
|
-
readonly columns:
|
|
986
|
-
}>
|
|
987
|
-
|
|
988
|
-
|
|
989
|
-
|
|
1239
|
+
readonly columns: readonly [string, ...string[]]
|
|
1240
|
+
}> {
|
|
1241
|
+
return makeResolvedOption({
|
|
1242
|
+
kind: "unique",
|
|
1243
|
+
columns: [] as unknown as readonly [string, ...string[]]
|
|
1244
|
+
}, (table) => ({
|
|
1245
|
+
kind: "unique",
|
|
1246
|
+
columns: selectedColumnList(columns(table))
|
|
1247
|
+
}))
|
|
1248
|
+
}
|
|
990
1249
|
|
|
991
1250
|
/** Declares a table-level index. */
|
|
992
|
-
export
|
|
993
|
-
|
|
1251
|
+
export function index<
|
|
1252
|
+
Table extends SchemaTableDefinition,
|
|
1253
|
+
Selection extends TableColumnSelection<Table> = TableColumnSelection<Table>
|
|
1254
|
+
>(
|
|
1255
|
+
columns: ConcreteSelector<Table, Selection>
|
|
1256
|
+
): TableOption<{
|
|
1257
|
+
readonly kind: "index"
|
|
1258
|
+
readonly columns: SelectedColumns<Selection>
|
|
1259
|
+
}, Table>
|
|
1260
|
+
export function index<
|
|
1261
|
+
Selection extends AnyColumnSelection
|
|
994
1262
|
>(
|
|
995
|
-
columns:
|
|
1263
|
+
columns: (table: LooseTableSelection) => Selection
|
|
1264
|
+
): TableOption<{
|
|
1265
|
+
readonly kind: "index"
|
|
1266
|
+
readonly columns: SelectedColumns<Selection>
|
|
1267
|
+
}>
|
|
1268
|
+
export function index(
|
|
1269
|
+
columns: (table: any) => AnyColumnSelection
|
|
996
1270
|
): TableOption<{
|
|
997
1271
|
readonly kind: "index"
|
|
998
|
-
readonly columns:
|
|
999
|
-
}>
|
|
1000
|
-
|
|
1001
|
-
|
|
1002
|
-
|
|
1272
|
+
readonly columns: readonly [string, ...string[]]
|
|
1273
|
+
}> {
|
|
1274
|
+
return makeResolvedOption({
|
|
1275
|
+
kind: "index",
|
|
1276
|
+
columns: [] as unknown as readonly [string, ...string[]]
|
|
1277
|
+
}, (table) => ({
|
|
1278
|
+
kind: "index",
|
|
1279
|
+
columns: selectedColumnList(columns(table))
|
|
1280
|
+
}))
|
|
1281
|
+
}
|
|
1003
1282
|
|
|
1004
1283
|
/** Declares a table-level foreign key. */
|
|
1005
|
-
export
|
|
1006
|
-
|
|
1007
|
-
|
|
1008
|
-
|
|
1284
|
+
export function foreignKey<
|
|
1285
|
+
Table extends SchemaTableDefinition,
|
|
1286
|
+
LocalSelection extends TableColumnSelection<Table> = TableColumnSelection<Table>,
|
|
1287
|
+
TargetSelection extends AnyColumnSelection = AnyColumnSelection
|
|
1009
1288
|
>(
|
|
1010
|
-
columns:
|
|
1011
|
-
target: () =>
|
|
1012
|
-
referencedColumns: TargetColumns & NonEmptyColumnInput<TargetColumns> & MatchingColumnArityInput<LocalColumns, TargetColumns>
|
|
1289
|
+
columns: ConcreteSelector<Table, LocalSelection>,
|
|
1290
|
+
target: () => TargetSelection & MatchingSelectionArityInput<LocalSelection, TargetSelection>
|
|
1013
1291
|
): TableOption<{
|
|
1014
1292
|
readonly kind: "foreignKey"
|
|
1015
|
-
readonly columns:
|
|
1293
|
+
readonly columns: SelectedColumns<LocalSelection>
|
|
1016
1294
|
readonly references: () => {
|
|
1017
1295
|
readonly tableName: string
|
|
1018
1296
|
readonly schemaName?: string
|
|
1019
|
-
readonly
|
|
1020
|
-
readonly
|
|
1297
|
+
readonly casing?: Casing.Options
|
|
1298
|
+
readonly columns: SelectedColumns<TargetSelection>
|
|
1021
1299
|
}
|
|
1022
|
-
}>
|
|
1023
|
-
|
|
1024
|
-
|
|
1025
|
-
|
|
1026
|
-
|
|
1027
|
-
|
|
1028
|
-
|
|
1029
|
-
|
|
1030
|
-
|
|
1031
|
-
|
|
1032
|
-
|
|
1300
|
+
}, Table>
|
|
1301
|
+
export function foreignKey<
|
|
1302
|
+
LocalSelection extends AnyColumnSelection,
|
|
1303
|
+
TargetSelection extends AnyColumnSelection
|
|
1304
|
+
>(
|
|
1305
|
+
columns: (table: LooseTableSelection) => LocalSelection,
|
|
1306
|
+
target: () => TargetSelection
|
|
1307
|
+
): TableOption<{
|
|
1308
|
+
readonly kind: "foreignKey"
|
|
1309
|
+
readonly columns: SelectedColumns<LocalSelection>
|
|
1310
|
+
readonly references: () => {
|
|
1311
|
+
readonly tableName: string
|
|
1312
|
+
readonly schemaName?: string
|
|
1313
|
+
readonly casing?: Casing.Options
|
|
1314
|
+
readonly columns: SelectedColumns<TargetSelection>
|
|
1315
|
+
}
|
|
1316
|
+
}>
|
|
1317
|
+
export function foreignKey(
|
|
1318
|
+
columns: (table: any) => AnyColumnSelection,
|
|
1319
|
+
target: () => AnyColumnSelection
|
|
1320
|
+
): TableOption<{
|
|
1321
|
+
readonly kind: "foreignKey"
|
|
1322
|
+
readonly columns: readonly [string, ...string[]]
|
|
1323
|
+
readonly references: () => {
|
|
1324
|
+
readonly tableName: string
|
|
1325
|
+
readonly schemaName?: string
|
|
1326
|
+
readonly casing?: Casing.Options
|
|
1327
|
+
readonly columns: readonly [string, ...string[]]
|
|
1328
|
+
}
|
|
1329
|
+
}> {
|
|
1330
|
+
return makeResolvedOption({
|
|
1331
|
+
kind: "foreignKey",
|
|
1332
|
+
columns: [] as unknown as readonly [string, ...string[]],
|
|
1333
|
+
references: () => referenceFromSelection(target())
|
|
1334
|
+
}, (table) => ({
|
|
1335
|
+
kind: "foreignKey",
|
|
1336
|
+
columns: selectedColumnList(columns(table)),
|
|
1337
|
+
references: () => referenceFromSelection(target())
|
|
1338
|
+
}))
|
|
1339
|
+
}
|
|
1033
1340
|
|
|
1034
1341
|
/** Declares a check constraint expression. */
|
|
1035
|
-
export
|
|
1342
|
+
export function check<const Name extends string>(
|
|
1036
1343
|
name: NonEmptyStringInput<Name>,
|
|
1037
1344
|
predicate: DdlExpressionLike
|
|
1038
1345
|
): TableOption<{
|
|
1039
1346
|
readonly kind: "check"
|
|
1040
1347
|
readonly name: Name
|
|
1041
1348
|
readonly predicate: DdlExpressionLike
|
|
1042
|
-
}>
|
|
1043
|
-
|
|
1044
|
-
name
|
|
1045
|
-
predicate
|
|
1046
|
-
|
|
1349
|
+
}>
|
|
1350
|
+
export function check<const Name extends string>(
|
|
1351
|
+
name: NonEmptyStringInput<Name>,
|
|
1352
|
+
predicate: CheckPredicate
|
|
1353
|
+
): TableOption<{
|
|
1354
|
+
readonly kind: "check"
|
|
1355
|
+
readonly name: Name
|
|
1356
|
+
readonly predicate: DdlExpressionLike
|
|
1357
|
+
}>
|
|
1358
|
+
export function check(
|
|
1359
|
+
name: string,
|
|
1360
|
+
predicate: DdlExpressionLike | CheckPredicate
|
|
1361
|
+
): TableOption<{
|
|
1362
|
+
readonly kind: "check"
|
|
1363
|
+
readonly name: string
|
|
1364
|
+
readonly predicate: DdlExpressionLike
|
|
1365
|
+
}> {
|
|
1366
|
+
const spec = {
|
|
1367
|
+
kind: "check",
|
|
1368
|
+
name,
|
|
1369
|
+
predicate: predicate as DdlExpressionLike
|
|
1370
|
+
} as const
|
|
1371
|
+
return typeof predicate === "function"
|
|
1372
|
+
? makeResolvedOption(spec, (table) => ({
|
|
1373
|
+
...spec,
|
|
1374
|
+
predicate: predicate(table as CheckPredicateTable)
|
|
1375
|
+
}))
|
|
1376
|
+
: makeOption(spec)
|
|
1377
|
+
}
|
|
1047
1378
|
|
|
1048
1379
|
/** Extracts the row type produced by `selectSchema(table)`. */
|
|
1049
1380
|
export type SelectOf<Table extends AnyTable> = Table[typeof TypeId] extends {
|