effect-qb 0.13.0 → 0.14.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 +6 -1431
- package/dist/mysql.js +1678 -355
- package/dist/postgres/metadata.js +2724 -0
- package/dist/postgres.js +7197 -5433
- package/package.json +8 -10
- package/src/internal/column-state.ts +84 -10
- package/src/internal/column.ts +556 -34
- package/src/internal/datatypes/define.ts +0 -30
- package/src/internal/executor.ts +45 -11
- package/src/internal/expression-ast.ts +4 -0
- package/src/internal/expression.ts +1 -1
- package/src/internal/implication-runtime.ts +171 -0
- package/src/internal/mysql-query.ts +7173 -0
- package/src/internal/mysql-renderer.ts +2 -2
- package/src/internal/plan.ts +14 -4
- package/src/internal/{query-factory.ts → postgres-query.ts} +619 -167
- package/src/internal/postgres-renderer.ts +2 -2
- package/src/internal/postgres-schema-model.ts +144 -0
- package/src/internal/predicate-analysis.ts +10 -0
- package/src/internal/predicate-context.ts +112 -36
- package/src/internal/predicate-formula.ts +31 -19
- package/src/internal/predicate-normalize.ts +177 -106
- package/src/internal/predicate-runtime.ts +676 -0
- package/src/internal/query.ts +455 -39
- package/src/internal/renderer.ts +2 -2
- package/src/internal/runtime-schema.ts +74 -20
- package/src/internal/schema-ddl.ts +55 -0
- package/src/internal/schema-derivation.ts +93 -21
- package/src/internal/schema-expression.ts +44 -0
- package/src/internal/sql-expression-renderer.ts +95 -31
- package/src/internal/table-options.ts +87 -7
- package/src/internal/table.ts +104 -41
- package/src/mysql/column.ts +1 -0
- package/src/mysql/datatypes/index.ts +17 -2
- package/src/mysql/function/core.ts +1 -0
- package/src/mysql/function/index.ts +1 -0
- package/src/mysql/private/query.ts +1 -13
- package/src/mysql/query.ts +5 -0
- package/src/postgres/cast.ts +31 -0
- package/src/postgres/column.ts +26 -0
- package/src/postgres/datatypes/index.ts +40 -5
- package/src/postgres/function/core.ts +12 -0
- package/src/postgres/function/index.ts +2 -1
- package/src/postgres/function/json.ts +499 -2
- package/src/postgres/metadata.ts +31 -0
- package/src/postgres/private/query.ts +1 -13
- package/src/postgres/query.ts +5 -2
- package/src/postgres/schema-expression.ts +16 -0
- package/src/postgres/schema-management.ts +204 -0
- package/src/postgres/schema.ts +35 -0
- package/src/postgres/table.ts +307 -41
- package/src/postgres/type.ts +4 -0
- package/src/postgres.ts +14 -0
- package/CHANGELOG.md +0 -134
package/src/internal/column.ts
CHANGED
|
@@ -1,22 +1,36 @@
|
|
|
1
|
+
import type * as Brand from "effect/Brand"
|
|
1
2
|
import * as Schema from "effect/Schema"
|
|
2
3
|
|
|
3
4
|
import * as Expression from "./expression.js"
|
|
5
|
+
import type { CanCastDbType } from "./datatypes/lookup.js"
|
|
4
6
|
import {
|
|
7
|
+
BigIntStringSchema,
|
|
8
|
+
InstantStringSchema,
|
|
5
9
|
LocalDateStringSchema,
|
|
6
10
|
DecimalStringSchema,
|
|
7
11
|
LocalDateTimeStringSchema,
|
|
12
|
+
LocalTimeStringSchema,
|
|
13
|
+
OffsetTimeStringSchema,
|
|
8
14
|
type LocalDateString,
|
|
15
|
+
type LocalTimeString,
|
|
16
|
+
type OffsetTimeString,
|
|
17
|
+
type InstantString,
|
|
9
18
|
type DecimalString,
|
|
10
|
-
type LocalDateTimeString
|
|
19
|
+
type LocalDateTimeString,
|
|
20
|
+
type BigIntString
|
|
11
21
|
} from "./runtime-value.js"
|
|
12
22
|
import {
|
|
13
23
|
type AnyBoundColumn,
|
|
14
24
|
type AnyColumnDefinition,
|
|
15
25
|
type BaseSelectType,
|
|
16
26
|
type BoundColumn,
|
|
27
|
+
BoundColumnTypeId,
|
|
17
28
|
ColumnTypeId,
|
|
29
|
+
type DdlExpression,
|
|
18
30
|
type ColumnDefinition,
|
|
31
|
+
type ColumnUniqueOptions,
|
|
19
32
|
type ColumnReference,
|
|
33
|
+
type ColumnIndexOptions,
|
|
20
34
|
type HasDefault,
|
|
21
35
|
type InsertType,
|
|
22
36
|
type IsGenerated,
|
|
@@ -29,6 +43,8 @@ import {
|
|
|
29
43
|
type UpdateType
|
|
30
44
|
} from "./column-state.js"
|
|
31
45
|
|
|
46
|
+
type ReferentialAction = "noAction" | "restrict" | "cascade" | "setNull" | "setDefault"
|
|
47
|
+
|
|
32
48
|
type CompatibleReference<
|
|
33
49
|
Self extends AnyColumnDefinition,
|
|
34
50
|
Target extends AnyBoundColumn
|
|
@@ -51,7 +67,7 @@ type NullableColumn<Column extends AnyColumnDefinition> = ColumnDefinition<
|
|
|
51
67
|
IsPrimaryKey<Column>,
|
|
52
68
|
Column[typeof ColumnTypeId]["unique"],
|
|
53
69
|
ReferencesOf<Column>
|
|
54
|
-
>
|
|
70
|
+
> & PreserveBrand<Column>
|
|
55
71
|
|
|
56
72
|
type PrimaryKeyColumn<Column extends AnyColumnDefinition> = ColumnDefinition<
|
|
57
73
|
SelectType<Column>,
|
|
@@ -64,7 +80,7 @@ type PrimaryKeyColumn<Column extends AnyColumnDefinition> = ColumnDefinition<
|
|
|
64
80
|
true,
|
|
65
81
|
true,
|
|
66
82
|
ReferencesOf<Column>
|
|
67
|
-
>
|
|
83
|
+
> & PreserveBrand<Column>
|
|
68
84
|
|
|
69
85
|
type UniqueColumn<Column extends AnyColumnDefinition> = ColumnDefinition<
|
|
70
86
|
SelectType<Column>,
|
|
@@ -77,7 +93,9 @@ type UniqueColumn<Column extends AnyColumnDefinition> = ColumnDefinition<
|
|
|
77
93
|
IsPrimaryKey<Column>,
|
|
78
94
|
true,
|
|
79
95
|
ReferencesOf<Column>
|
|
80
|
-
>
|
|
96
|
+
> & PreserveBrand<Column>
|
|
97
|
+
|
|
98
|
+
type IndexedColumn<Column extends AnyColumnDefinition> = Column
|
|
81
99
|
|
|
82
100
|
type HasDefaultColumn<Column extends AnyColumnDefinition> = ColumnDefinition<
|
|
83
101
|
SelectType<Column>,
|
|
@@ -90,7 +108,20 @@ type HasDefaultColumn<Column extends AnyColumnDefinition> = ColumnDefinition<
|
|
|
90
108
|
IsPrimaryKey<Column>,
|
|
91
109
|
Column[typeof ColumnTypeId]["unique"],
|
|
92
110
|
ReferencesOf<Column>
|
|
93
|
-
>
|
|
111
|
+
> & PreserveBrand<Column>
|
|
112
|
+
|
|
113
|
+
type DdlTypedColumn<Column extends AnyColumnDefinition> = ColumnDefinition<
|
|
114
|
+
SelectType<Column>,
|
|
115
|
+
InsertType<Column>,
|
|
116
|
+
UpdateType<Column>,
|
|
117
|
+
Column[typeof ColumnTypeId]["dbType"],
|
|
118
|
+
IsNullable<Column>,
|
|
119
|
+
HasDefault<Column>,
|
|
120
|
+
IsGenerated<Column>,
|
|
121
|
+
IsPrimaryKey<Column>,
|
|
122
|
+
Column[typeof ColumnTypeId]["unique"],
|
|
123
|
+
ReferencesOf<Column>
|
|
124
|
+
> & PreserveBrand<Column>
|
|
94
125
|
|
|
95
126
|
type GeneratedColumn<Column extends AnyColumnDefinition> = ColumnDefinition<
|
|
96
127
|
SelectType<Column>,
|
|
@@ -103,12 +134,55 @@ type GeneratedColumn<Column extends AnyColumnDefinition> = ColumnDefinition<
|
|
|
103
134
|
IsPrimaryKey<Column>,
|
|
104
135
|
Column[typeof ColumnTypeId]["unique"],
|
|
105
136
|
ReferencesOf<Column>
|
|
106
|
-
>
|
|
137
|
+
> & PreserveBrand<Column>
|
|
138
|
+
|
|
139
|
+
type ByDefaultIdentityColumn<Column extends AnyColumnDefinition> = ColumnDefinition<
|
|
140
|
+
SelectType<Column>,
|
|
141
|
+
InsertType<Column>,
|
|
142
|
+
UpdateType<Column>,
|
|
143
|
+
Column[typeof ColumnTypeId]["dbType"],
|
|
144
|
+
IsNullable<Column>,
|
|
145
|
+
true,
|
|
146
|
+
false,
|
|
147
|
+
IsPrimaryKey<Column>,
|
|
148
|
+
Column[typeof ColumnTypeId]["unique"],
|
|
149
|
+
ReferencesOf<Column>
|
|
150
|
+
> & PreserveBrand<Column>
|
|
151
|
+
|
|
152
|
+
type AlwaysIdentityColumn<Column extends AnyColumnDefinition> = ColumnDefinition<
|
|
153
|
+
SelectType<Column>,
|
|
154
|
+
InsertType<Column>,
|
|
155
|
+
UpdateType<Column>,
|
|
156
|
+
Column[typeof ColumnTypeId]["dbType"],
|
|
157
|
+
IsNullable<Column>,
|
|
158
|
+
false,
|
|
159
|
+
true,
|
|
160
|
+
IsPrimaryKey<Column>,
|
|
161
|
+
Column[typeof ColumnTypeId]["unique"],
|
|
162
|
+
ReferencesOf<Column>
|
|
163
|
+
> & PreserveBrand<Column>
|
|
107
164
|
|
|
108
165
|
type CompatibleColumnExpression<
|
|
109
166
|
Column extends AnyColumnDefinition,
|
|
110
167
|
Value extends Expression.Any
|
|
111
|
-
> = [Expression.RuntimeOf<Value>] extends [SelectType<Column>]
|
|
168
|
+
> = [Expression.RuntimeOf<Value>] extends [SelectType<Column>]
|
|
169
|
+
? Column
|
|
170
|
+
: CanCastDbType<
|
|
171
|
+
Expression.DbTypeOf<Value>,
|
|
172
|
+
Column[typeof ColumnTypeId]["dbType"],
|
|
173
|
+
Column[typeof ColumnTypeId]["dbType"]["dialect"]
|
|
174
|
+
> extends true
|
|
175
|
+
? Column
|
|
176
|
+
: never
|
|
177
|
+
|
|
178
|
+
type CompatibleDdlExpression<
|
|
179
|
+
Column extends AnyColumnDefinition,
|
|
180
|
+
Value extends DdlExpression
|
|
181
|
+
> = Value extends Expression.Any ? CompatibleColumnExpression<Column, Value> : Column
|
|
182
|
+
|
|
183
|
+
type BaseInsertType<Column extends AnyColumnDefinition> = NonNullable<InsertType<Column>>
|
|
184
|
+
|
|
185
|
+
type BaseUpdateType<Column extends AnyColumnDefinition> = NonNullable<UpdateType<Column>>
|
|
112
186
|
|
|
113
187
|
type ReferencingColumn<
|
|
114
188
|
Column extends AnyColumnDefinition,
|
|
@@ -124,7 +198,16 @@ type ReferencingColumn<
|
|
|
124
198
|
IsPrimaryKey<Column>,
|
|
125
199
|
Column[typeof ColumnTypeId]["unique"],
|
|
126
200
|
ColumnReference<Target>
|
|
127
|
-
>
|
|
201
|
+
> & PreserveBrand<Column>
|
|
202
|
+
|
|
203
|
+
type ForeignKeyOptions<Target extends AnyBoundColumn> = {
|
|
204
|
+
readonly target: () => Target
|
|
205
|
+
readonly name?: string
|
|
206
|
+
readonly onUpdate?: ReferentialAction
|
|
207
|
+
readonly onDelete?: ReferentialAction
|
|
208
|
+
readonly deferrable?: boolean
|
|
209
|
+
readonly initiallyDeferred?: boolean
|
|
210
|
+
}
|
|
128
211
|
|
|
129
212
|
type SchemaCompatibleColumn<
|
|
130
213
|
Column extends AnyColumnDefinition,
|
|
@@ -156,18 +239,130 @@ type ColumnWithSchema<
|
|
|
156
239
|
ReferencesOf<Column>,
|
|
157
240
|
Column[typeof ColumnTypeId]["source"],
|
|
158
241
|
Column[typeof ColumnTypeId]["dependencies"]
|
|
159
|
-
>
|
|
242
|
+
> & PreserveBrand<Column>
|
|
243
|
+
|
|
244
|
+
type BrandNameOf<Column extends AnyBoundColumn> =
|
|
245
|
+
`${Column[typeof BoundColumnTypeId]["tableName"]}.${Column[typeof BoundColumnTypeId]["columnName"]}`
|
|
246
|
+
|
|
247
|
+
type BrandedValue<
|
|
248
|
+
Value,
|
|
249
|
+
BrandName extends string
|
|
250
|
+
> = [Extract<Value, null | undefined>] extends [never]
|
|
251
|
+
? Value & Brand.Brand<BrandName>
|
|
252
|
+
: Exclude<Value, null | undefined> & Brand.Brand<BrandName> | Extract<Value, null | undefined>
|
|
253
|
+
|
|
254
|
+
type BrandMetadata<Column extends AnyColumnDefinition> = {
|
|
255
|
+
readonly metadata: Column["metadata"] & { readonly brand: true }
|
|
256
|
+
}
|
|
257
|
+
|
|
258
|
+
type PreserveBrand<Column extends AnyColumnDefinition> = Column["metadata"]["brand"] extends true
|
|
259
|
+
? BrandMetadata<Column>
|
|
260
|
+
: {}
|
|
261
|
+
|
|
262
|
+
type BrandedColumn<
|
|
263
|
+
Column extends AnyBoundColumn
|
|
264
|
+
> = ColumnDefinition<
|
|
265
|
+
BrandedValue<SelectType<Column>, BrandNameOf<Column>>,
|
|
266
|
+
BrandedValue<InsertType<Column>, BrandNameOf<Column>>,
|
|
267
|
+
BrandedValue<UpdateType<Column>, BrandNameOf<Column>>,
|
|
268
|
+
Column[typeof ColumnTypeId]["dbType"],
|
|
269
|
+
IsNullable<Column>,
|
|
270
|
+
HasDefault<Column>,
|
|
271
|
+
IsGenerated<Column>,
|
|
272
|
+
IsPrimaryKey<Column>,
|
|
273
|
+
Column[typeof ColumnTypeId]["unique"],
|
|
274
|
+
ReferencesOf<Column>,
|
|
275
|
+
Column[typeof ColumnTypeId]["source"],
|
|
276
|
+
Column[typeof ColumnTypeId]["dependencies"]
|
|
277
|
+
> & BrandMetadata<Column>
|
|
278
|
+
|
|
279
|
+
type BrandMarkedColumn<
|
|
280
|
+
Column extends AnyColumnDefinition
|
|
281
|
+
> = ColumnDefinition<
|
|
282
|
+
SelectType<Column>,
|
|
283
|
+
InsertType<Column>,
|
|
284
|
+
UpdateType<Column>,
|
|
285
|
+
Column[typeof ColumnTypeId]["dbType"],
|
|
286
|
+
IsNullable<Column>,
|
|
287
|
+
HasDefault<Column>,
|
|
288
|
+
IsGenerated<Column>,
|
|
289
|
+
IsPrimaryKey<Column>,
|
|
290
|
+
Column[typeof ColumnTypeId]["unique"],
|
|
291
|
+
ReferencesOf<Column>,
|
|
292
|
+
Column[typeof ColumnTypeId]["source"],
|
|
293
|
+
Column[typeof ColumnTypeId]["dependencies"]
|
|
294
|
+
> & BrandMetadata<Column>
|
|
295
|
+
|
|
296
|
+
export interface ArrayOptions {
|
|
297
|
+
readonly nullableElements?: boolean
|
|
298
|
+
}
|
|
299
|
+
|
|
300
|
+
export type NumericOptions =
|
|
301
|
+
| {
|
|
302
|
+
readonly precision?: undefined
|
|
303
|
+
readonly scale?: undefined
|
|
304
|
+
}
|
|
305
|
+
| {
|
|
306
|
+
readonly precision: number
|
|
307
|
+
readonly scale?: number
|
|
308
|
+
}
|
|
309
|
+
|
|
310
|
+
type ArrayElementSelect<
|
|
311
|
+
Column extends AnyColumnDefinition,
|
|
312
|
+
Options extends ArrayOptions | undefined
|
|
313
|
+
> = Options extends { readonly nullableElements: true }
|
|
314
|
+
? NullableSelect<BaseSelectType<Column>>
|
|
315
|
+
: BaseSelectType<Column>
|
|
316
|
+
|
|
317
|
+
type ArrayElementInsert<
|
|
318
|
+
Column extends AnyColumnDefinition,
|
|
319
|
+
Options extends ArrayOptions | undefined
|
|
320
|
+
> = Options extends { readonly nullableElements: true }
|
|
321
|
+
? NullableSelect<BaseInsertType<Column>>
|
|
322
|
+
: BaseInsertType<Column>
|
|
323
|
+
|
|
324
|
+
type ArrayElementUpdate<
|
|
325
|
+
Column extends AnyColumnDefinition,
|
|
326
|
+
Options extends ArrayOptions | undefined
|
|
327
|
+
> = Options extends { readonly nullableElements: true }
|
|
328
|
+
? NullableSelect<BaseUpdateType<Column>>
|
|
329
|
+
: BaseUpdateType<Column>
|
|
330
|
+
|
|
331
|
+
type ArrayColumn<
|
|
332
|
+
Column extends AnyColumnDefinition,
|
|
333
|
+
Options extends ArrayOptions | undefined = undefined
|
|
334
|
+
> = ColumnDefinition<
|
|
335
|
+
ReadonlyArray<ArrayElementSelect<Column, Options>>,
|
|
336
|
+
ReadonlyArray<ArrayElementInsert<Column, Options>>,
|
|
337
|
+
ReadonlyArray<ArrayElementUpdate<Column, Options>>,
|
|
338
|
+
Expression.DbType.Array<
|
|
339
|
+
Column[typeof ColumnTypeId]["dbType"]["dialect"],
|
|
340
|
+
Column[typeof ColumnTypeId]["dbType"],
|
|
341
|
+
`${Column[typeof ColumnTypeId]["dbType"]["kind"]}[]`
|
|
342
|
+
>,
|
|
343
|
+
IsNullable<Column>,
|
|
344
|
+
HasDefault<Column>,
|
|
345
|
+
IsGenerated<Column>,
|
|
346
|
+
IsPrimaryKey<Column>,
|
|
347
|
+
Column[typeof ColumnTypeId]["unique"],
|
|
348
|
+
ReferencesOf<Column>,
|
|
349
|
+
Column[typeof ColumnTypeId]["source"],
|
|
350
|
+
Column[typeof ColumnTypeId]["dependencies"]
|
|
351
|
+
> & PreserveBrand<Column>
|
|
160
352
|
|
|
161
353
|
const mapColumn = <
|
|
162
354
|
Column extends AnyColumnDefinition,
|
|
163
355
|
Next extends AnyColumnDefinition
|
|
164
356
|
>(
|
|
165
357
|
column: Column,
|
|
166
|
-
metadata:
|
|
358
|
+
metadata: AnyColumnDefinition["metadata"]
|
|
167
359
|
): Next => remapColumnDefinition(column as any, {
|
|
168
360
|
metadata
|
|
169
361
|
}) as Next
|
|
170
362
|
|
|
363
|
+
const isColumnDefinitionValue = (value: unknown): value is AnyColumnDefinition =>
|
|
364
|
+
typeof value === "object" && value !== null && ColumnTypeId in value
|
|
365
|
+
|
|
171
366
|
const primitive = <Type, Db extends Expression.DbType.Any>(
|
|
172
367
|
schema: Schema.Schema<Type, any, any>,
|
|
173
368
|
dbType: Db
|
|
@@ -214,7 +409,7 @@ type ColumnModule<
|
|
|
214
409
|
readonly uuid: () => ColumnDefinition<string, string, string, Expression.DbType.Base<Dialect, UuidKind>, false, false, false, false, false, undefined>
|
|
215
410
|
readonly text: () => ColumnDefinition<string, string, string, Expression.DbType.Base<Dialect, TextKind>, false, false, false, false, false, undefined>
|
|
216
411
|
readonly int: () => ColumnDefinition<number, number, number, Expression.DbType.Base<Dialect, IntKind>, false, false, false, false, false, undefined>
|
|
217
|
-
readonly number: () => ColumnDefinition<DecimalString, DecimalString, DecimalString, Expression.DbType.Base<Dialect, NumberKind>, false, false, false, false, false, undefined>
|
|
412
|
+
readonly number: (options?: NumericOptions) => ColumnDefinition<DecimalString, DecimalString, DecimalString, Expression.DbType.Base<Dialect, NumberKind>, false, false, false, false, false, undefined>
|
|
218
413
|
readonly boolean: () => ColumnDefinition<boolean, boolean, boolean, Expression.DbType.Base<Dialect, BooleanKind>, false, false, false, false, false, undefined>
|
|
219
414
|
readonly date: () => ColumnDefinition<LocalDateString, LocalDateString, LocalDateString, Expression.DbType.Base<Dialect, DateKind>, false, false, false, false, false, undefined>
|
|
220
415
|
readonly timestamp: () => ColumnDefinition<LocalDateTimeString, LocalDateTimeString, LocalDateTimeString, Expression.DbType.Base<Dialect, TimestampKind>, false, false, false, false, false, undefined>
|
|
@@ -234,12 +429,71 @@ type ColumnModule<
|
|
|
234
429
|
>
|
|
235
430
|
}
|
|
236
431
|
|
|
432
|
+
type PostgresColumnModule = ColumnModule<
|
|
433
|
+
"postgres",
|
|
434
|
+
"uuid",
|
|
435
|
+
"text",
|
|
436
|
+
"int4",
|
|
437
|
+
"numeric",
|
|
438
|
+
"bool",
|
|
439
|
+
"date",
|
|
440
|
+
"timestamp",
|
|
441
|
+
"json"
|
|
442
|
+
> & {
|
|
443
|
+
readonly int2: () => ColumnDefinition<number, number, number, Expression.DbType.Base<"postgres", "int2">, false, false, false, false, false, undefined>
|
|
444
|
+
readonly int8: () => ColumnDefinition<BigIntString, BigIntString, BigIntString, Expression.DbType.Base<"postgres", "int8">, false, false, false, false, false, undefined>
|
|
445
|
+
readonly float4: () => ColumnDefinition<number, number, number, Expression.DbType.Base<"postgres", "float4">, false, false, false, false, false, undefined>
|
|
446
|
+
readonly float8: () => ColumnDefinition<number, number, number, Expression.DbType.Base<"postgres", "float8">, false, false, false, false, false, undefined>
|
|
447
|
+
readonly char: (length?: number) => ColumnDefinition<string, string, string, Expression.DbType.Base<"postgres", "char">, false, false, false, false, false, undefined>
|
|
448
|
+
readonly varchar: (length?: number) => ColumnDefinition<string, string, string, Expression.DbType.Base<"postgres", "varchar">, false, false, false, false, false, undefined>
|
|
449
|
+
readonly time: () => ColumnDefinition<LocalTimeString, LocalTimeString, LocalTimeString, Expression.DbType.Base<"postgres", "time">, false, false, false, false, false, undefined>
|
|
450
|
+
readonly timetz: () => ColumnDefinition<OffsetTimeString, OffsetTimeString, OffsetTimeString, Expression.DbType.Base<"postgres", "timetz">, false, false, false, false, false, undefined>
|
|
451
|
+
readonly timestamptz: () => ColumnDefinition<InstantString, InstantString, InstantString, Expression.DbType.Base<"postgres", "timestamptz">, false, false, false, false, false, undefined>
|
|
452
|
+
readonly interval: () => ColumnDefinition<string, string, string, Expression.DbType.Base<"postgres", "interval">, false, false, false, false, false, undefined>
|
|
453
|
+
readonly bytea: () => ColumnDefinition<Uint8Array, Uint8Array, Uint8Array, Expression.DbType.Base<"postgres", "bytea">, false, false, false, false, false, undefined>
|
|
454
|
+
readonly name: () => ColumnDefinition<string, string, string, Expression.DbType.Base<"postgres", "name">, false, false, false, false, false, undefined>
|
|
455
|
+
readonly oid: () => ColumnDefinition<number, number, number, Expression.DbType.Base<"postgres", "oid">, false, false, false, false, false, undefined>
|
|
456
|
+
readonly regclass: () => ColumnDefinition<string, string, string, Expression.DbType.Base<"postgres", "regclass">, false, false, false, false, false, undefined>
|
|
457
|
+
readonly bit: () => ColumnDefinition<string, string, string, Expression.DbType.Base<"postgres", "bit">, false, false, false, false, false, undefined>
|
|
458
|
+
readonly varbit: () => ColumnDefinition<string, string, string, Expression.DbType.Base<"postgres", "varbit">, false, false, false, false, false, undefined>
|
|
459
|
+
readonly xml: () => ColumnDefinition<string, string, string, Expression.DbType.Base<"postgres", "xml">, false, false, false, false, false, undefined>
|
|
460
|
+
readonly pg_lsn: () => ColumnDefinition<string, string, string, Expression.DbType.Base<"postgres", "pg_lsn">, false, false, false, false, false, undefined>
|
|
461
|
+
readonly jsonb: <SchemaType extends Schema.Schema.Any>(
|
|
462
|
+
schema: SchemaType
|
|
463
|
+
) => ColumnDefinition<
|
|
464
|
+
Schema.Schema.Type<SchemaType>,
|
|
465
|
+
Schema.Schema.Type<SchemaType>,
|
|
466
|
+
Schema.Schema.Type<SchemaType>,
|
|
467
|
+
Expression.DbType.Json<"postgres", "jsonb">,
|
|
468
|
+
false,
|
|
469
|
+
false,
|
|
470
|
+
false,
|
|
471
|
+
false,
|
|
472
|
+
false,
|
|
473
|
+
undefined
|
|
474
|
+
>
|
|
475
|
+
}
|
|
476
|
+
|
|
237
477
|
const typeFactory = <Dialect extends string>(dialect: Dialect) =>
|
|
238
478
|
<Kind extends string>(kind: Kind): Expression.DbType.Base<Dialect, Kind> => ({
|
|
239
479
|
dialect,
|
|
240
480
|
kind
|
|
241
481
|
})
|
|
242
482
|
|
|
483
|
+
const postgresType = typeFactory("postgres")
|
|
484
|
+
|
|
485
|
+
const renderNumericDdlType = (
|
|
486
|
+
kind: string,
|
|
487
|
+
options?: NumericOptions
|
|
488
|
+
): string | undefined => {
|
|
489
|
+
if (options === undefined || options.precision === undefined) {
|
|
490
|
+
return undefined
|
|
491
|
+
}
|
|
492
|
+
return options.scale === undefined
|
|
493
|
+
? `${kind}(${options.precision})`
|
|
494
|
+
: `${kind}(${options.precision},${options.scale})`
|
|
495
|
+
}
|
|
496
|
+
|
|
243
497
|
const makeColumnModule = <
|
|
244
498
|
Dialect extends string,
|
|
245
499
|
UuidKind extends string,
|
|
@@ -276,12 +530,25 @@ const makeColumnModule = <
|
|
|
276
530
|
generated: false,
|
|
277
531
|
primaryKey: false,
|
|
278
532
|
unique: false,
|
|
279
|
-
references: undefined
|
|
533
|
+
references: undefined,
|
|
534
|
+
ddlType: undefined,
|
|
535
|
+
identity: undefined
|
|
280
536
|
}),
|
|
281
537
|
uuid: () => primitive(Schema.UUID, dialectType(kinds.uuid)),
|
|
282
538
|
text: () => primitive(Schema.String, dialectType(kinds.text)),
|
|
283
539
|
int: () => primitive(Schema.Int, dialectType(kinds.int)),
|
|
284
|
-
number: () =>
|
|
540
|
+
number: (options?: NumericOptions) =>
|
|
541
|
+
makeColumnDefinition(DecimalStringSchema, {
|
|
542
|
+
dbType: dialectType(kinds.number),
|
|
543
|
+
nullable: false,
|
|
544
|
+
hasDefault: false,
|
|
545
|
+
generated: false,
|
|
546
|
+
primaryKey: false,
|
|
547
|
+
unique: false,
|
|
548
|
+
references: undefined,
|
|
549
|
+
ddlType: renderNumericDdlType(kinds.number, options),
|
|
550
|
+
identity: undefined
|
|
551
|
+
}),
|
|
285
552
|
boolean: () => primitive(Schema.Boolean, dialectType(kinds.boolean)),
|
|
286
553
|
date: () => primitive(LocalDateStringSchema, dialectType(kinds.date)),
|
|
287
554
|
timestamp: () => primitive(LocalDateTimeStringSchema, dialectType(kinds.timestamp)),
|
|
@@ -296,13 +563,14 @@ const makeColumnModule = <
|
|
|
296
563
|
generated: false,
|
|
297
564
|
primaryKey: false,
|
|
298
565
|
unique: false,
|
|
299
|
-
references: undefined
|
|
566
|
+
references: undefined,
|
|
567
|
+
ddlType: undefined,
|
|
568
|
+
identity: undefined
|
|
300
569
|
})
|
|
301
570
|
}
|
|
302
571
|
}
|
|
303
572
|
|
|
304
|
-
|
|
305
|
-
export const postgres = makeColumnModule("postgres", {
|
|
573
|
+
const postgresBase = makeColumnModule("postgres", {
|
|
306
574
|
uuid: "uuid",
|
|
307
575
|
text: "text",
|
|
308
576
|
int: "int4",
|
|
@@ -313,6 +581,66 @@ export const postgres = makeColumnModule("postgres", {
|
|
|
313
581
|
json: "json"
|
|
314
582
|
})
|
|
315
583
|
|
|
584
|
+
/** Postgres-specialized column constructors. */
|
|
585
|
+
export const postgres: PostgresColumnModule = {
|
|
586
|
+
...postgresBase,
|
|
587
|
+
int2: () => primitive(Schema.Int, postgresType("int2")),
|
|
588
|
+
int8: () => primitive(BigIntStringSchema, postgresType("int8")),
|
|
589
|
+
float4: () => primitive(Schema.Number, postgresType("float4")),
|
|
590
|
+
float8: () => primitive(Schema.Number, postgresType("float8")),
|
|
591
|
+
char: (length = 1) =>
|
|
592
|
+
makeColumnDefinition(Schema.String, {
|
|
593
|
+
dbType: postgresType("char"),
|
|
594
|
+
nullable: false,
|
|
595
|
+
hasDefault: false,
|
|
596
|
+
generated: false,
|
|
597
|
+
primaryKey: false,
|
|
598
|
+
unique: false,
|
|
599
|
+
references: undefined,
|
|
600
|
+
ddlType: `char(${length})`,
|
|
601
|
+
identity: undefined
|
|
602
|
+
}),
|
|
603
|
+
varchar: (length?: number) =>
|
|
604
|
+
makeColumnDefinition(Schema.String, {
|
|
605
|
+
dbType: postgresType("varchar"),
|
|
606
|
+
nullable: false,
|
|
607
|
+
hasDefault: false,
|
|
608
|
+
generated: false,
|
|
609
|
+
primaryKey: false,
|
|
610
|
+
unique: false,
|
|
611
|
+
references: undefined,
|
|
612
|
+
ddlType: length === undefined ? "varchar" : `varchar(${length})`,
|
|
613
|
+
identity: undefined
|
|
614
|
+
}),
|
|
615
|
+
time: () => primitive(LocalTimeStringSchema, postgresType("time")),
|
|
616
|
+
timetz: () => primitive(OffsetTimeStringSchema, postgresType("timetz")),
|
|
617
|
+
timestamptz: () => primitive(InstantStringSchema, postgresType("timestamptz")),
|
|
618
|
+
interval: () => primitive(Schema.String, postgresType("interval")),
|
|
619
|
+
bytea: () => primitive(Schema.Uint8ArrayFromSelf, postgresType("bytea")),
|
|
620
|
+
name: () => primitive(Schema.String, postgresType("name")),
|
|
621
|
+
oid: () => primitive(Schema.Int, postgresType("oid")),
|
|
622
|
+
regclass: () => primitive(Schema.String, postgresType("regclass")),
|
|
623
|
+
bit: () => primitive(Schema.String, postgresType("bit")),
|
|
624
|
+
varbit: () => primitive(Schema.String, postgresType("varbit")),
|
|
625
|
+
xml: () => primitive(Schema.String, postgresType("xml")),
|
|
626
|
+
pg_lsn: () => primitive(Schema.String, postgresType("pg_lsn")),
|
|
627
|
+
jsonb: <SchemaType extends Schema.Schema.Any>(schema: SchemaType) =>
|
|
628
|
+
makeColumnDefinition(schema as unknown as Schema.Schema<NonNullable<Schema.Schema.Type<SchemaType>>, any, any>, {
|
|
629
|
+
dbType: {
|
|
630
|
+
...postgresType("jsonb"),
|
|
631
|
+
variant: "jsonb"
|
|
632
|
+
} as Expression.DbType.Json<"postgres", "jsonb">,
|
|
633
|
+
nullable: false,
|
|
634
|
+
hasDefault: false,
|
|
635
|
+
generated: false,
|
|
636
|
+
primaryKey: false,
|
|
637
|
+
unique: false,
|
|
638
|
+
references: undefined,
|
|
639
|
+
ddlType: undefined,
|
|
640
|
+
identity: undefined
|
|
641
|
+
})
|
|
642
|
+
}
|
|
643
|
+
|
|
316
644
|
/** MySQL-specialized column constructors. */
|
|
317
645
|
export const mysql = makeColumnModule("mysql", {
|
|
318
646
|
uuid: "uuid",
|
|
@@ -331,17 +659,55 @@ export const uuid = postgres.uuid
|
|
|
331
659
|
export const text = postgres.text
|
|
332
660
|
/** Creates a Postgres `int4` column. */
|
|
333
661
|
export const int = postgres.int
|
|
662
|
+
/** Creates a Postgres `int2` column. */
|
|
663
|
+
export const int2 = postgres.int2
|
|
664
|
+
/** Creates a Postgres `int8` column. */
|
|
665
|
+
export const int8 = postgres.int8
|
|
334
666
|
/** Creates a Postgres `numeric` column decoded as `DecimalString`. */
|
|
335
667
|
export const number = postgres.number
|
|
668
|
+
/** Creates a Postgres `float4` column. */
|
|
669
|
+
export const float4 = postgres.float4
|
|
670
|
+
/** Creates a Postgres `float8` column. */
|
|
671
|
+
export const float8 = postgres.float8
|
|
336
672
|
/** Creates a Postgres `bool` column. */
|
|
337
673
|
export const boolean = postgres.boolean
|
|
338
674
|
/** Creates a Postgres `date` column decoded as `LocalDateString`. */
|
|
339
675
|
export const date = postgres.date
|
|
340
676
|
/** Creates a Postgres `timestamp` column decoded as `LocalDateTimeString`. */
|
|
341
677
|
export const timestamp = postgres.timestamp
|
|
678
|
+
/** Creates a Postgres `time` column decoded as `LocalTimeString`. */
|
|
679
|
+
export const time = postgres.time
|
|
680
|
+
/** Creates a Postgres `timetz` column decoded as `OffsetTimeString`. */
|
|
681
|
+
export const timetz = postgres.timetz
|
|
682
|
+
/** Creates a Postgres `timestamptz` column decoded as `InstantString`. */
|
|
683
|
+
export const timestamptz = postgres.timestamptz
|
|
684
|
+
/** Creates a Postgres `char` column. */
|
|
685
|
+
export const char = postgres.char
|
|
686
|
+
/** Creates a Postgres `varchar` column. */
|
|
687
|
+
export const varchar = postgres.varchar
|
|
688
|
+
/** Creates a Postgres `interval` column. */
|
|
689
|
+
export const interval = postgres.interval
|
|
690
|
+
/** Creates a Postgres `bytea` column. */
|
|
691
|
+
export const bytea = postgres.bytea
|
|
692
|
+
/** Creates a Postgres `name` column. */
|
|
693
|
+
export const name = postgres.name
|
|
694
|
+
/** Creates a Postgres `oid` column. */
|
|
695
|
+
export const oid = postgres.oid
|
|
696
|
+
/** Creates a Postgres `regclass` column. */
|
|
697
|
+
export const regclass = postgres.regclass
|
|
698
|
+
/** Creates a Postgres `bit` column. */
|
|
699
|
+
export const bit = postgres.bit
|
|
700
|
+
/** Creates a Postgres `varbit` column. */
|
|
701
|
+
export const varbit = postgres.varbit
|
|
702
|
+
/** Creates a Postgres `xml` column. */
|
|
703
|
+
export const xml = postgres.xml
|
|
704
|
+
/** Creates a Postgres `pg_lsn` column. */
|
|
705
|
+
export const pg_lsn = postgres.pg_lsn
|
|
342
706
|
|
|
343
707
|
/** Creates a Postgres `json` column backed by an arbitrary Effect schema. */
|
|
344
708
|
export const json = postgres.json
|
|
709
|
+
/** Creates a Postgres `jsonb` column backed by an arbitrary Effect schema. */
|
|
710
|
+
export const jsonb = postgres.jsonb
|
|
345
711
|
/** Creates a Postgres column backed by an arbitrary SQL type and Effect schema. */
|
|
346
712
|
export const custom = postgres.custom
|
|
347
713
|
|
|
@@ -354,6 +720,33 @@ export const schema = <SchemaType extends Schema.Schema.Any>(nextSchema: SchemaT
|
|
|
354
720
|
schema: nextSchema
|
|
355
721
|
}) as ColumnWithSchema<Column, SchemaType>
|
|
356
722
|
|
|
723
|
+
type BrandResult<Column extends AnyColumnDefinition> = Column extends AnyBoundColumn
|
|
724
|
+
? BrandedColumn<Column>
|
|
725
|
+
: BrandMarkedColumn<Column>
|
|
726
|
+
|
|
727
|
+
/** Brands a column with its `table.column` provenance. */
|
|
728
|
+
export const brand = <Column extends AnyColumnDefinition>(
|
|
729
|
+
column: Column
|
|
730
|
+
): BrandResult<Column> => {
|
|
731
|
+
if (BoundColumnTypeId in column) {
|
|
732
|
+
const boundColumn = column as unknown as AnyBoundColumn
|
|
733
|
+
const brandName = `${boundColumn[BoundColumnTypeId].tableName}.${boundColumn[BoundColumnTypeId].columnName}`
|
|
734
|
+
return remapColumnDefinition(boundColumn, {
|
|
735
|
+
schema: Schema.brand(brandName)(boundColumn.schema),
|
|
736
|
+
metadata: {
|
|
737
|
+
...boundColumn.metadata,
|
|
738
|
+
brand: true
|
|
739
|
+
}
|
|
740
|
+
}) as BrandResult<Column>
|
|
741
|
+
}
|
|
742
|
+
return remapColumnDefinition(column, {
|
|
743
|
+
metadata: {
|
|
744
|
+
...column.metadata,
|
|
745
|
+
brand: true
|
|
746
|
+
}
|
|
747
|
+
}) as BrandResult<Column>
|
|
748
|
+
}
|
|
749
|
+
|
|
357
750
|
/** Marks a column as nullable. Nullable columns decode as `T | null`. */
|
|
358
751
|
export const nullable = <Column extends AnyColumnDefinition>(
|
|
359
752
|
column: Column[typeof ColumnTypeId]["primaryKey"] extends true ? never : Column
|
|
@@ -374,53 +767,182 @@ export const primaryKey = <Column extends AnyColumnDefinition>(
|
|
|
374
767
|
unique: true
|
|
375
768
|
})
|
|
376
769
|
|
|
770
|
+
type UniqueModifier = {
|
|
771
|
+
<Column extends AnyColumnDefinition>(column: Column): UniqueColumn<Column>
|
|
772
|
+
readonly options: <const Options extends ColumnUniqueOptions>(
|
|
773
|
+
options: Options
|
|
774
|
+
) => <Column extends AnyColumnDefinition>(column: Column) => UniqueColumn<Column>
|
|
775
|
+
}
|
|
776
|
+
|
|
377
777
|
/** Marks a column as unique. */
|
|
378
|
-
export const unique =
|
|
379
|
-
column: Column
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
778
|
+
export const unique: UniqueModifier = Object.assign(
|
|
779
|
+
<Column extends AnyColumnDefinition>(column: Column): UniqueColumn<Column> =>
|
|
780
|
+
mapColumn(column, {
|
|
781
|
+
...column.metadata,
|
|
782
|
+
unique: true
|
|
783
|
+
}),
|
|
784
|
+
{
|
|
785
|
+
options: <const Options extends ColumnUniqueOptions>(options: Options) =>
|
|
786
|
+
<Column extends AnyColumnDefinition>(column: Column): UniqueColumn<Column> =>
|
|
787
|
+
mapColumn(column, {
|
|
788
|
+
...column.metadata,
|
|
789
|
+
unique: true,
|
|
790
|
+
uniqueConstraint: options
|
|
791
|
+
})
|
|
792
|
+
}
|
|
793
|
+
)
|
|
385
794
|
|
|
386
795
|
/** Marks a column as having a database default expression and therefore optional on insert. */
|
|
387
|
-
export const default_ = <Value extends
|
|
796
|
+
export const default_ = <Value extends DdlExpression>(value: Value) =>
|
|
388
797
|
<Column extends AnyColumnDefinition>(
|
|
389
|
-
column: Column[typeof ColumnTypeId]["generated"] extends true ? never :
|
|
798
|
+
column: Column[typeof ColumnTypeId]["generated"] extends true ? never : CompatibleDdlExpression<Column, Value>
|
|
390
799
|
): HasDefaultColumn<Column> =>
|
|
391
800
|
mapColumn(column, {
|
|
392
801
|
...column.metadata,
|
|
393
802
|
hasDefault: true,
|
|
394
803
|
defaultValue: value,
|
|
395
|
-
generatedValue: undefined
|
|
804
|
+
generatedValue: undefined,
|
|
805
|
+
identity: undefined
|
|
396
806
|
})
|
|
397
807
|
|
|
398
808
|
/** Marks a column as generated by the database expression and omitted from insert/update. */
|
|
399
|
-
export const generated = <Value extends
|
|
809
|
+
export const generated = <Value extends DdlExpression>(value: Value) =>
|
|
400
810
|
<Column extends AnyColumnDefinition>(
|
|
401
|
-
column: Column[typeof ColumnTypeId]["hasDefault"] extends true ? never :
|
|
811
|
+
column: Column[typeof ColumnTypeId]["hasDefault"] extends true ? never : CompatibleDdlExpression<Column, Value>
|
|
402
812
|
): GeneratedColumn<Column> =>
|
|
403
813
|
mapColumn(column, {
|
|
404
814
|
...column.metadata,
|
|
405
815
|
generated: true,
|
|
406
816
|
hasDefault: false,
|
|
407
817
|
defaultValue: undefined,
|
|
408
|
-
generatedValue: value
|
|
818
|
+
generatedValue: value,
|
|
819
|
+
identity: undefined
|
|
820
|
+
})
|
|
821
|
+
|
|
822
|
+
/** Preserves the exact SQL type used for DDL rendering. */
|
|
823
|
+
export const ddlType = <SqlType extends string>(sqlType: SqlType) =>
|
|
824
|
+
<Column extends AnyColumnDefinition>(column: Column): DdlTypedColumn<Column> =>
|
|
825
|
+
mapColumn(column, {
|
|
826
|
+
...column.metadata,
|
|
827
|
+
ddlType: sqlType
|
|
828
|
+
})
|
|
829
|
+
|
|
830
|
+
/** Marks a column as a Postgres array type. */
|
|
831
|
+
export const array = <Options extends ArrayOptions | undefined = undefined>(
|
|
832
|
+
options?: Options
|
|
833
|
+
) =>
|
|
834
|
+
<Column extends AnyColumnDefinition>(
|
|
835
|
+
column: Column
|
|
836
|
+
): ArrayColumn<Column, Options> =>
|
|
837
|
+
remapColumnDefinition(column as AnyColumnDefinition, {
|
|
838
|
+
schema: Schema.Array(options?.nullableElements ? Schema.NullOr(column.schema) : column.schema),
|
|
839
|
+
metadata: {
|
|
840
|
+
...column.metadata,
|
|
841
|
+
dbType: {
|
|
842
|
+
dialect: column.metadata.dbType.dialect,
|
|
843
|
+
kind: `${column.metadata.dbType.kind}[]`,
|
|
844
|
+
element: column.metadata.dbType
|
|
845
|
+
} as Expression.DbType.Array<
|
|
846
|
+
Column[typeof ColumnTypeId]["dbType"]["dialect"],
|
|
847
|
+
Column[typeof ColumnTypeId]["dbType"],
|
|
848
|
+
`${Column[typeof ColumnTypeId]["dbType"]["kind"]}[]`
|
|
849
|
+
>,
|
|
850
|
+
ddlType: `${column.metadata.ddlType ?? column.metadata.dbType.kind}[]`
|
|
851
|
+
}
|
|
852
|
+
}) as ArrayColumn<Column, Options>
|
|
853
|
+
|
|
854
|
+
/** Marks a column as indexed. */
|
|
855
|
+
export function index<Column extends AnyColumnDefinition>(
|
|
856
|
+
column: Column
|
|
857
|
+
): IndexedColumn<Column>
|
|
858
|
+
export function index<const Options extends ColumnIndexOptions>(
|
|
859
|
+
options: Options
|
|
860
|
+
): <Column extends AnyColumnDefinition>(column: Column) => IndexedColumn<Column>
|
|
861
|
+
export function index(arg: unknown): unknown {
|
|
862
|
+
if (isColumnDefinitionValue(arg)) {
|
|
863
|
+
return mapColumn(arg, {
|
|
864
|
+
...arg.metadata,
|
|
865
|
+
index: arg.metadata.index ?? {}
|
|
409
866
|
})
|
|
867
|
+
}
|
|
868
|
+
const options = (arg ?? {}) as ColumnIndexOptions
|
|
869
|
+
return <Column extends AnyColumnDefinition>(
|
|
870
|
+
column: Column
|
|
871
|
+
): IndexedColumn<Column> =>
|
|
872
|
+
mapColumn(column, {
|
|
873
|
+
...column.metadata,
|
|
874
|
+
index: options
|
|
875
|
+
})
|
|
876
|
+
}
|
|
877
|
+
|
|
878
|
+
/** Marks a column as `generated by default as identity`. */
|
|
879
|
+
export const identityByDefault = <Column extends AnyColumnDefinition>(
|
|
880
|
+
column: Column[typeof ColumnTypeId]["generated"] extends true ? never : Column
|
|
881
|
+
): ByDefaultIdentityColumn<Column> =>
|
|
882
|
+
mapColumn(column, {
|
|
883
|
+
...column.metadata,
|
|
884
|
+
hasDefault: true,
|
|
885
|
+
generated: false,
|
|
886
|
+
defaultValue: undefined,
|
|
887
|
+
generatedValue: undefined,
|
|
888
|
+
identity: {
|
|
889
|
+
generation: "byDefault"
|
|
890
|
+
}
|
|
891
|
+
})
|
|
892
|
+
|
|
893
|
+
/** Marks a column as `generated always as identity`. */
|
|
894
|
+
export const identityAlways = <Column extends AnyColumnDefinition>(
|
|
895
|
+
column: Column[typeof ColumnTypeId]["hasDefault"] extends true ? never : Column
|
|
896
|
+
): AlwaysIdentityColumn<Column> =>
|
|
897
|
+
mapColumn(column, {
|
|
898
|
+
...column.metadata,
|
|
899
|
+
hasDefault: false,
|
|
900
|
+
generated: true,
|
|
901
|
+
defaultValue: undefined,
|
|
902
|
+
generatedValue: undefined,
|
|
903
|
+
identity: {
|
|
904
|
+
generation: "always"
|
|
905
|
+
}
|
|
906
|
+
})
|
|
410
907
|
|
|
411
908
|
/**
|
|
412
909
|
* Attaches a lazy foreign-key reference to another bound column.
|
|
413
910
|
*
|
|
414
911
|
* The base, non-null select types must match.
|
|
415
912
|
*/
|
|
416
|
-
export
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
913
|
+
export function foreignKey<Target extends AnyBoundColumn>(
|
|
914
|
+
target: () => Target
|
|
915
|
+
): <Column extends AnyColumnDefinition>(
|
|
916
|
+
column: CompatibleReference<Column, Target>
|
|
917
|
+
) => ReferencingColumn<Column, Target>
|
|
918
|
+
export function foreignKey<const Options extends ForeignKeyOptions<AnyBoundColumn>>(
|
|
919
|
+
options: Options
|
|
920
|
+
): <Column extends AnyColumnDefinition>(
|
|
921
|
+
column: CompatibleReference<Column, ReturnType<Options["target"]>>
|
|
922
|
+
) => ReferencingColumn<Column, ReturnType<Options["target"]>>
|
|
923
|
+
export function foreignKey(arg: unknown): unknown {
|
|
924
|
+
if (typeof arg === "function") {
|
|
925
|
+
const target = arg as () => AnyBoundColumn
|
|
926
|
+
return <Column extends AnyColumnDefinition>(
|
|
927
|
+
column: CompatibleReference<Column, AnyBoundColumn>
|
|
928
|
+
): ReferencingColumn<Column, AnyBoundColumn> =>
|
|
929
|
+
mapColumn(column, {
|
|
930
|
+
...column.metadata,
|
|
931
|
+
references: { target }
|
|
932
|
+
})
|
|
933
|
+
}
|
|
934
|
+
const options = arg as ForeignKeyOptions<AnyBoundColumn>
|
|
935
|
+
return <Column extends AnyColumnDefinition>(
|
|
936
|
+
column: CompatibleReference<Column, ReturnType<typeof options.target>>
|
|
937
|
+
): ReferencingColumn<Column, ReturnType<typeof options.target>> =>
|
|
420
938
|
mapColumn(column, {
|
|
421
939
|
...column.metadata,
|
|
422
|
-
references:
|
|
940
|
+
references: options
|
|
423
941
|
})
|
|
942
|
+
}
|
|
943
|
+
|
|
944
|
+
export const references = <Target extends AnyBoundColumn>(target: () => Target) =>
|
|
945
|
+
foreignKey(target)
|
|
424
946
|
|
|
425
947
|
/** Convenience alias for any column definition. */
|
|
426
948
|
export type Any = AnyColumnDefinition
|