effect-qb 0.15.0 → 0.17.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/dist/mysql.js +1957 -595
- package/dist/postgres/metadata.js +2507 -182
- package/dist/postgres.js +9587 -8201
- package/dist/sqlite.js +8360 -0
- package/package.json +7 -2
- package/src/internal/column-state.ts +7 -0
- package/src/internal/column.ts +22 -0
- package/src/internal/derived-table.ts +29 -3
- package/src/internal/dialect.ts +14 -1
- package/src/internal/dsl-mutation-runtime.ts +173 -4
- package/src/internal/dsl-plan-runtime.ts +165 -20
- package/src/internal/dsl-query-runtime.ts +60 -6
- package/src/internal/dsl-transaction-ddl-runtime.ts +72 -2
- package/src/internal/executor.ts +62 -13
- package/src/internal/expression-ast.ts +3 -2
- package/src/internal/grouping-key.ts +141 -1
- package/src/internal/implication-runtime.ts +2 -1
- package/src/internal/json/types.ts +155 -40
- package/src/internal/predicate/analysis.ts +103 -1
- package/src/internal/predicate/atom.ts +7 -0
- package/src/internal/predicate/context.ts +170 -17
- package/src/internal/predicate/key.ts +64 -2
- package/src/internal/predicate/normalize.ts +115 -34
- package/src/internal/predicate/runtime.ts +144 -13
- package/src/internal/query.ts +563 -103
- package/src/internal/renderer.ts +39 -2
- package/src/internal/runtime/driver-value-mapping.ts +244 -0
- package/src/internal/runtime/normalize.ts +62 -38
- package/src/internal/runtime/schema.ts +5 -3
- package/src/internal/runtime/value.ts +153 -30
- package/src/internal/scalar.ts +11 -0
- package/src/internal/table-options.ts +108 -1
- package/src/internal/table.ts +87 -29
- package/src/mysql/column.ts +19 -2
- package/src/mysql/datatypes/index.ts +21 -0
- package/src/mysql/errors/catalog.ts +5 -5
- package/src/mysql/errors/normalize.ts +2 -2
- package/src/mysql/executor.ts +20 -5
- package/src/mysql/internal/dialect.ts +12 -6
- package/src/mysql/internal/dsl.ts +995 -263
- package/src/mysql/internal/renderer.ts +13 -3
- package/src/mysql/internal/sql-expression-renderer.ts +530 -128
- package/src/mysql/query.ts +9 -2
- package/src/mysql/renderer.ts +7 -2
- package/src/mysql/table.ts +38 -12
- package/src/postgres/cast.ts +22 -7
- package/src/postgres/column.ts +5 -2
- package/src/postgres/errors/normalize.ts +2 -2
- package/src/postgres/executor.ts +68 -10
- package/src/postgres/function/core.ts +19 -1
- package/src/postgres/internal/dialect.ts +12 -6
- package/src/postgres/internal/dsl.ts +958 -288
- package/src/postgres/internal/renderer.ts +13 -3
- package/src/postgres/internal/schema-ddl.ts +2 -1
- package/src/postgres/internal/schema-model.ts +6 -3
- package/src/postgres/internal/sql-expression-renderer.ts +477 -96
- package/src/postgres/json.ts +57 -17
- package/src/postgres/query.ts +9 -2
- package/src/postgres/renderer.ts +7 -2
- package/src/postgres/schema-management.ts +91 -4
- package/src/postgres/schema.ts +1 -1
- package/src/postgres/table.ts +189 -53
- package/src/postgres/type.ts +4 -0
- package/src/sqlite/column.ts +128 -0
- package/src/sqlite/datatypes/index.ts +79 -0
- package/src/sqlite/datatypes/spec.ts +98 -0
- package/src/sqlite/errors/catalog.ts +103 -0
- package/src/sqlite/errors/fields.ts +19 -0
- package/src/sqlite/errors/index.ts +19 -0
- package/src/sqlite/errors/normalize.ts +229 -0
- package/src/sqlite/errors/requirements.ts +71 -0
- package/src/sqlite/errors/types.ts +29 -0
- package/src/sqlite/executor.ts +227 -0
- package/src/sqlite/function/aggregate.ts +2 -0
- package/src/sqlite/function/core.ts +2 -0
- package/src/sqlite/function/index.ts +19 -0
- package/src/sqlite/function/string.ts +2 -0
- package/src/sqlite/function/temporal.ts +100 -0
- package/src/sqlite/function/window.ts +2 -0
- package/src/sqlite/internal/dialect.ts +37 -0
- package/src/sqlite/internal/dsl.ts +6926 -0
- package/src/sqlite/internal/renderer.ts +47 -0
- package/src/sqlite/internal/sql-expression-renderer.ts +1821 -0
- package/src/sqlite/json.ts +2 -0
- package/src/sqlite/query.ts +196 -0
- package/src/sqlite/renderer.ts +24 -0
- package/src/sqlite/table.ts +183 -0
- package/src/sqlite.ts +22 -0
package/src/postgres/table.ts
CHANGED
|
@@ -3,6 +3,7 @@ import type * as Schema from "effect/Schema"
|
|
|
3
3
|
import type * as Expression from "../internal/scalar.js"
|
|
4
4
|
import { ColumnTypeId, type AnyColumnDefinition } from "../internal/column-state.js"
|
|
5
5
|
import * as BaseTable from "../internal/table.js"
|
|
6
|
+
import type { TableOptionSpec } from "../internal/table-options.js"
|
|
6
7
|
|
|
7
8
|
type Dialect = "postgres"
|
|
8
9
|
|
|
@@ -41,6 +42,8 @@ type FieldsOfTable<Table> = Table extends BaseTable.TableDefinition<any, infer F
|
|
|
41
42
|
? Fields
|
|
42
43
|
: never
|
|
43
44
|
|
|
45
|
+
type ColumnNamesOfTable<Table> = Extract<keyof FieldsOfTable<Table>, string>
|
|
46
|
+
|
|
44
47
|
type PrimaryKeyOfTable<Table> = Table extends BaseTable.TableDefinition<any, any, infer PrimaryKeyColumns extends string, any, any>
|
|
45
48
|
? PrimaryKeyColumns
|
|
46
49
|
: Table extends BaseTable.TableClassStatic<any, any, infer PrimaryKeyColumns extends string, any>
|
|
@@ -53,6 +56,33 @@ type SchemaNameOfTable<Table> = Table extends BaseTable.TableDefinition<any, any
|
|
|
53
56
|
? SchemaName
|
|
54
57
|
: never
|
|
55
58
|
|
|
59
|
+
type ApplySchemaTableOptions<
|
|
60
|
+
Name extends string,
|
|
61
|
+
Fields extends DialectFieldMap,
|
|
62
|
+
PrimaryKeyColumns extends keyof Fields & string,
|
|
63
|
+
SchemaName extends string,
|
|
64
|
+
Options extends BaseTable.DeclaredTableOptions
|
|
65
|
+
> = BaseTable.ApplyDeclaredOptions<
|
|
66
|
+
BaseTable.TableDefinition<Name, Fields, PrimaryKeyColumns, "schema", SchemaName>,
|
|
67
|
+
Options
|
|
68
|
+
> extends BaseTable.TableDefinition<any, any, infer AppliedPrimaryKeyColumns extends keyof Fields & string, "schema", any>
|
|
69
|
+
? TableDefinition<Name, Fields, AppliedPrimaryKeyColumns, "schema", SchemaName>
|
|
70
|
+
: TableDefinition<Name, Fields, PrimaryKeyColumns, "schema", SchemaName>
|
|
71
|
+
|
|
72
|
+
export type TableSchemaNamespace<SchemaName extends string> = {
|
|
73
|
+
readonly schemaName: SchemaName
|
|
74
|
+
readonly table: <
|
|
75
|
+
Name extends string,
|
|
76
|
+
Fields extends DialectFieldMap,
|
|
77
|
+
const Options extends BaseTable.DeclaredTableOptions,
|
|
78
|
+
PrimaryKeyColumns extends keyof Fields & string = InlinePrimaryKeyKeys<Fields>
|
|
79
|
+
>(
|
|
80
|
+
name: Name,
|
|
81
|
+
fields: Fields,
|
|
82
|
+
...options: Options & BaseTable.ValidateDeclaredOptions<BaseTable.TableDefinition<Name, Fields, PrimaryKeyColumns, "schema", SchemaName>, Options>
|
|
83
|
+
) => ApplySchemaTableOptions<Name, Fields, PrimaryKeyColumns, SchemaName, Options>
|
|
84
|
+
}
|
|
85
|
+
|
|
56
86
|
export type TableOption = BaseTable.TableOption
|
|
57
87
|
export type DdlExpressionLike = BaseTable.DdlExpressionLike
|
|
58
88
|
export type IndexKey = BaseTable.IndexKeySpec
|
|
@@ -89,6 +119,34 @@ export const make = <
|
|
|
89
119
|
): TableDefinition<Name, Fields> =>
|
|
90
120
|
BaseTable.make(name, fields, schemaName) as TableDefinition<Name, Fields>
|
|
91
121
|
|
|
122
|
+
export const schema = <SchemaName extends string>(
|
|
123
|
+
schemaName: SchemaName
|
|
124
|
+
): TableSchemaNamespace<SchemaName> => {
|
|
125
|
+
const table = <
|
|
126
|
+
Name extends string,
|
|
127
|
+
Fields extends DialectFieldMap,
|
|
128
|
+
const Options extends BaseTable.DeclaredTableOptions,
|
|
129
|
+
PrimaryKeyColumns extends keyof Fields & string = InlinePrimaryKeyKeys<Fields>
|
|
130
|
+
>(
|
|
131
|
+
name: Name,
|
|
132
|
+
fields: Fields,
|
|
133
|
+
...declaredOptions: Options & BaseTable.ValidateDeclaredOptions<BaseTable.TableDefinition<Name, Fields, PrimaryKeyColumns, "schema", SchemaName>, Options>
|
|
134
|
+
) =>
|
|
135
|
+
(BaseTable.schema(schemaName).table as (
|
|
136
|
+
name: Name,
|
|
137
|
+
fields: Fields,
|
|
138
|
+
...options: BaseTable.DeclaredTableOptions
|
|
139
|
+
) => BaseTable.TableDefinition<any, any, any, "schema", any>)(
|
|
140
|
+
name,
|
|
141
|
+
fields,
|
|
142
|
+
...declaredOptions
|
|
143
|
+
) as ApplySchemaTableOptions<Name, Fields, PrimaryKeyColumns, SchemaName, Options>
|
|
144
|
+
return {
|
|
145
|
+
schemaName,
|
|
146
|
+
table
|
|
147
|
+
} as unknown as TableSchemaNamespace<SchemaName>
|
|
148
|
+
}
|
|
149
|
+
|
|
92
150
|
export const alias = <
|
|
93
151
|
Table extends AnyTable,
|
|
94
152
|
AliasName extends string
|
|
@@ -125,14 +183,14 @@ export const Class = <Self = never, SchemaName extends string | undefined = "pub
|
|
|
125
183
|
export const option = BaseTable.option
|
|
126
184
|
|
|
127
185
|
type RichPrimaryKeyInput<Columns extends string | readonly string[]> = {
|
|
128
|
-
readonly columns: Columns
|
|
186
|
+
readonly columns: Columns & BaseTable.NonEmptyColumnInput<Columns>
|
|
129
187
|
readonly name?: string
|
|
130
188
|
readonly deferrable?: boolean
|
|
131
189
|
readonly initiallyDeferred?: boolean
|
|
132
190
|
}
|
|
133
191
|
|
|
134
192
|
type RichUniqueInput<Columns extends string | readonly string[]> = {
|
|
135
|
-
readonly columns: Columns
|
|
193
|
+
readonly columns: Columns & BaseTable.NonEmptyColumnInput<Columns>
|
|
136
194
|
readonly name?: string
|
|
137
195
|
readonly nullsNotDistinct?: boolean
|
|
138
196
|
readonly deferrable?: boolean
|
|
@@ -155,9 +213,7 @@ type RichIndexKeyInput =
|
|
|
155
213
|
readonly collation?: string
|
|
156
214
|
}
|
|
157
215
|
|
|
158
|
-
type
|
|
159
|
-
readonly columns?: Columns
|
|
160
|
-
readonly keys?: readonly [RichIndexKeyInput, ...RichIndexKeyInput[]]
|
|
216
|
+
type RichIndexDetails = {
|
|
161
217
|
readonly name?: string
|
|
162
218
|
readonly unique?: boolean
|
|
163
219
|
readonly method?: string
|
|
@@ -165,14 +221,98 @@ type RichIndexInput<Columns extends string | readonly string[] = string | readon
|
|
|
165
221
|
readonly predicate?: DdlExpressionLike
|
|
166
222
|
}
|
|
167
223
|
|
|
224
|
+
type RichIndexInput<Columns extends string | readonly string[] = string | readonly string[]> = RichIndexDetails & (
|
|
225
|
+
| {
|
|
226
|
+
readonly columns: Columns & BaseTable.NonEmptyColumnInput<Columns>
|
|
227
|
+
readonly keys?: readonly [RichIndexKeyInput, ...RichIndexKeyInput[]]
|
|
228
|
+
}
|
|
229
|
+
| {
|
|
230
|
+
readonly columns?: Columns & BaseTable.NonEmptyColumnInput<Columns>
|
|
231
|
+
readonly keys: readonly [RichIndexKeyInput, ...RichIndexKeyInput[]]
|
|
232
|
+
}
|
|
233
|
+
)
|
|
234
|
+
|
|
235
|
+
type PrimaryKeyOptionSpec = Extract<TableOptionSpec, { readonly kind: "primaryKey" }>
|
|
236
|
+
type UniqueOptionSpec = Extract<TableOptionSpec, { readonly kind: "unique" }>
|
|
237
|
+
type IndexOptionSpec = Extract<TableOptionSpec, { readonly kind: "index" }>
|
|
238
|
+
type ForeignKeyOptionSpec = Extract<TableOptionSpec, { readonly kind: "foreignKey" }>
|
|
239
|
+
|
|
240
|
+
type RichPrimaryKeyOptionSpec<Columns extends string | readonly string[]> = PrimaryKeyOptionSpec & {
|
|
241
|
+
readonly kind: "primaryKey"
|
|
242
|
+
readonly columns: BaseTable.NormalizeColumns<Columns>
|
|
243
|
+
}
|
|
244
|
+
|
|
245
|
+
type RichUniqueOptionSpec<Columns extends string | readonly string[]> = UniqueOptionSpec & {
|
|
246
|
+
readonly kind: "unique"
|
|
247
|
+
readonly columns: BaseTable.NormalizeColumns<Columns>
|
|
248
|
+
}
|
|
249
|
+
|
|
250
|
+
type KnownTargetColumnsInput<
|
|
251
|
+
TargetTable extends AnyTable,
|
|
252
|
+
Columns extends string | readonly string[]
|
|
253
|
+
> = BaseTable.NormalizeColumns<Columns> extends infer NormalizedColumns extends readonly string[]
|
|
254
|
+
? string extends NormalizedColumns[number]
|
|
255
|
+
? unknown
|
|
256
|
+
: Exclude<NormalizedColumns[number], ColumnNamesOfTable<TargetTable>> extends never
|
|
257
|
+
? unknown
|
|
258
|
+
: never
|
|
259
|
+
: never
|
|
260
|
+
|
|
261
|
+
type RichIndexColumnOption<Spec> = Spec extends { readonly columns: infer Columns extends string | readonly string[] }
|
|
262
|
+
? { readonly columns: BaseTable.NormalizeColumns<Columns> }
|
|
263
|
+
: {}
|
|
264
|
+
|
|
265
|
+
type RichIndexIncludeOption<Spec> = Spec extends { readonly include: infer Include extends readonly string[] }
|
|
266
|
+
? { readonly include: Include }
|
|
267
|
+
: {}
|
|
268
|
+
|
|
269
|
+
type RichIndexKeySpec<Key> = Key extends { readonly column: infer Column extends string }
|
|
270
|
+
? BaseTable.IndexKeySpec & { readonly kind: "column"; readonly column: Column }
|
|
271
|
+
: BaseTable.IndexKeySpec & { readonly kind: "expression" }
|
|
272
|
+
|
|
273
|
+
type RichIndexKeys<Keys extends readonly [RichIndexKeyInput, ...RichIndexKeyInput[]]> = {
|
|
274
|
+
readonly [K in keyof Keys]: Keys[K] extends RichIndexKeyInput ? RichIndexKeySpec<Keys[K]> : never
|
|
275
|
+
} & readonly [BaseTable.IndexKeySpec, ...BaseTable.IndexKeySpec[]]
|
|
276
|
+
|
|
277
|
+
type RichIndexKeysOption<Spec> = Spec extends { readonly keys: infer Keys extends readonly [RichIndexKeyInput, ...RichIndexKeyInput[]] }
|
|
278
|
+
? { readonly keys: RichIndexKeys<Keys> }
|
|
279
|
+
: {}
|
|
280
|
+
|
|
281
|
+
type RichIndexColumnsConstraint<Spec> = Spec extends { readonly columns: infer Columns extends string | readonly string[] }
|
|
282
|
+
? BaseTable.NonEmptyColumnInput<Columns> extends never ? never : unknown
|
|
283
|
+
: unknown
|
|
284
|
+
|
|
285
|
+
type RichIndexOptionSpec<Spec> = IndexOptionSpec & {
|
|
286
|
+
readonly kind: "index"
|
|
287
|
+
readonly name?: string
|
|
288
|
+
readonly unique?: boolean
|
|
289
|
+
readonly method?: string
|
|
290
|
+
readonly predicate?: DdlExpressionLike
|
|
291
|
+
} & RichIndexColumnOption<Spec> & RichIndexIncludeOption<Spec> & RichIndexKeysOption<Spec>
|
|
292
|
+
|
|
293
|
+
type RichForeignKeyOptionSpec<
|
|
294
|
+
LocalColumns extends string | readonly string[],
|
|
295
|
+
TargetTable extends AnyTable,
|
|
296
|
+
TargetColumns extends string | readonly string[]
|
|
297
|
+
> = ForeignKeyOptionSpec & {
|
|
298
|
+
readonly kind: "foreignKey"
|
|
299
|
+
readonly columns: BaseTable.NormalizeColumns<LocalColumns>
|
|
300
|
+
readonly references: () => {
|
|
301
|
+
readonly tableName: string
|
|
302
|
+
readonly schemaName?: string
|
|
303
|
+
readonly columns: BaseTable.NormalizeColumns<TargetColumns>
|
|
304
|
+
readonly knownColumns: readonly ColumnNamesOfTable<TargetTable>[]
|
|
305
|
+
}
|
|
306
|
+
}
|
|
307
|
+
|
|
168
308
|
type RichForeignKeyInput<
|
|
169
309
|
LocalColumns extends string | readonly string[],
|
|
170
310
|
TargetTable extends AnyTable,
|
|
171
311
|
TargetColumns extends string | readonly string[]
|
|
172
312
|
> = {
|
|
173
|
-
readonly columns: LocalColumns
|
|
313
|
+
readonly columns: LocalColumns & BaseTable.NonEmptyColumnInput<LocalColumns>
|
|
174
314
|
readonly target: () => TargetTable
|
|
175
|
-
readonly referencedColumns: TargetColumns
|
|
315
|
+
readonly referencedColumns: TargetColumns & BaseTable.NonEmptyColumnInput<TargetColumns> & BaseTable.MatchingColumnArityInput<LocalColumns, TargetColumns> & KnownTargetColumnsInput<NoInfer<TargetTable>, TargetColumns>
|
|
176
316
|
readonly name?: string
|
|
177
317
|
readonly onUpdate?: ReferentialAction
|
|
178
318
|
readonly onDelete?: ReferentialAction
|
|
@@ -205,8 +345,13 @@ const makeTableScopedOption = <
|
|
|
205
345
|
return builder
|
|
206
346
|
}
|
|
207
347
|
|
|
208
|
-
const normalizeColumns = (columns: string | readonly string[]): readonly [string, ...string[]] =>
|
|
209
|
-
|
|
348
|
+
const normalizeColumns = (columns: string | readonly string[]): readonly [string, ...string[]] => {
|
|
349
|
+
const normalized = Array.isArray(columns) ? [...columns] : [columns]
|
|
350
|
+
if (normalized.length === 0) {
|
|
351
|
+
throw new Error("Table options require at least one column")
|
|
352
|
+
}
|
|
353
|
+
return normalized as unknown as readonly [string, ...string[]]
|
|
354
|
+
}
|
|
210
355
|
|
|
211
356
|
const normalizeIndexKeys = (
|
|
212
357
|
keys: readonly [RichIndexKeyInput, ...RichIndexKeyInput[]]
|
|
@@ -231,14 +376,14 @@ const normalizeIndexKeys = (
|
|
|
231
376
|
|
|
232
377
|
export const primaryKey: {
|
|
233
378
|
<const Columns extends string | readonly string[]>(
|
|
234
|
-
columns: Columns
|
|
379
|
+
columns: Columns & BaseTable.NonEmptyColumnInput<Columns>
|
|
235
380
|
): BaseTable.TableOption<{
|
|
236
381
|
readonly kind: "primaryKey"
|
|
237
382
|
readonly columns: BaseTable.NormalizeColumns<Columns>
|
|
238
383
|
}>
|
|
239
384
|
<const Columns extends string | readonly string[]>(
|
|
240
385
|
spec: RichPrimaryKeyInput<Columns>
|
|
241
|
-
): BaseTable.TableOption
|
|
386
|
+
): BaseTable.TableOption<RichPrimaryKeyOptionSpec<Columns>>
|
|
242
387
|
} = ((input: unknown) =>
|
|
243
388
|
isObject(input) && "columns" in input
|
|
244
389
|
? BaseTable.option({
|
|
@@ -252,14 +397,14 @@ export const primaryKey: {
|
|
|
252
397
|
|
|
253
398
|
export const unique: {
|
|
254
399
|
<const Columns extends string | readonly string[]>(
|
|
255
|
-
columns: Columns
|
|
400
|
+
columns: Columns & BaseTable.NonEmptyColumnInput<Columns>
|
|
256
401
|
): BaseTable.TableOption<{
|
|
257
402
|
readonly kind: "unique"
|
|
258
403
|
readonly columns: BaseTable.NormalizeColumns<Columns>
|
|
259
404
|
}>
|
|
260
405
|
<const Columns extends string | readonly string[]>(
|
|
261
406
|
spec: RichUniqueInput<Columns>
|
|
262
|
-
): BaseTable.TableOption
|
|
407
|
+
): BaseTable.TableOption<RichUniqueOptionSpec<Columns>>
|
|
263
408
|
} = ((input: unknown) =>
|
|
264
409
|
isObject(input) && "columns" in input && ("name" in input || "nullsNotDistinct" in input || "deferrable" in input || "initiallyDeferred" in input)
|
|
265
410
|
? BaseTable.option({
|
|
@@ -274,30 +419,21 @@ export const unique: {
|
|
|
274
419
|
|
|
275
420
|
export const index: {
|
|
276
421
|
<const Columns extends string | readonly string[]>(
|
|
277
|
-
columns: Columns
|
|
422
|
+
columns: Columns & BaseTable.NonEmptyColumnInput<Columns>
|
|
278
423
|
): BaseTable.TableOption<{
|
|
279
424
|
readonly kind: "index"
|
|
280
425
|
readonly columns: BaseTable.NormalizeColumns<Columns>
|
|
281
426
|
}>
|
|
282
|
-
<Table extends SchemaTable, const Columns extends string | readonly string[]>
|
|
283
|
-
spec: Omit<RichIndexInput<Columns>, "predicate"> & {
|
|
427
|
+
<Table extends SchemaTable, const Columns extends string | readonly string[], const Spec extends Omit<RichIndexInput<Columns>, "predicate"> & {
|
|
284
428
|
readonly predicate: TableExpressionFactory<Table>
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
readonly unique?: boolean
|
|
292
|
-
readonly method?: string
|
|
293
|
-
readonly include?: readonly string[]
|
|
294
|
-
readonly predicate?: DdlExpressionLike
|
|
295
|
-
}>
|
|
296
|
-
<const Columns extends string | readonly string[]>(
|
|
297
|
-
spec: RichIndexInput<Columns>
|
|
298
|
-
): BaseTable.TableOption
|
|
429
|
+
}>(
|
|
430
|
+
spec: Spec & RichIndexColumnsConstraint<Spec>
|
|
431
|
+
): TableScopedOptionBuilder<Table, RichIndexOptionSpec<Spec>>
|
|
432
|
+
<const Columns extends string | readonly string[], const Spec extends RichIndexInput<Columns>>(
|
|
433
|
+
spec: Spec & RichIndexColumnsConstraint<Spec>
|
|
434
|
+
): BaseTable.TableOption<RichIndexOptionSpec<Spec>>
|
|
299
435
|
} = ((input: unknown) =>
|
|
300
|
-
isObject(input) && ("keys" in input || "name" in input || "unique" in input || "method" in input || "include" in input || "predicate" in input)
|
|
436
|
+
isObject(input) && ("columns" in input || "keys" in input || "name" in input || "unique" in input || "method" in input || "include" in input || "predicate" in input)
|
|
301
437
|
? (() => {
|
|
302
438
|
const spec = input as RichIndexInput<string | readonly string[]> & {
|
|
303
439
|
readonly predicate?: DdlExpressionLike | TableExpressionFactory<SchemaTable>
|
|
@@ -333,35 +469,35 @@ export const foreignKey = <
|
|
|
333
469
|
TargetTable extends AnyTable,
|
|
334
470
|
const TargetColumns extends string | readonly string[]
|
|
335
471
|
>(
|
|
336
|
-
columnsOrSpec: LocalColumns | RichForeignKeyInput<LocalColumns, TargetTable, TargetColumns>,
|
|
472
|
+
columnsOrSpec: (LocalColumns & BaseTable.NonEmptyColumnInput<LocalColumns>) | RichForeignKeyInput<LocalColumns, TargetTable, TargetColumns>,
|
|
337
473
|
target?: () => TargetTable,
|
|
338
|
-
referencedColumns?: TargetColumns
|
|
339
|
-
): BaseTable.TableOption =>
|
|
474
|
+
referencedColumns?: TargetColumns & BaseTable.NonEmptyColumnInput<TargetColumns> & BaseTable.MatchingColumnArityInput<LocalColumns, TargetColumns> & KnownTargetColumnsInput<NoInfer<TargetTable>, TargetColumns>
|
|
475
|
+
): BaseTable.TableOption<RichForeignKeyOptionSpec<LocalColumns, TargetTable, TargetColumns>> =>
|
|
340
476
|
isObject(columnsOrSpec) && "columns" in columnsOrSpec && "target" in columnsOrSpec
|
|
341
477
|
? (() => {
|
|
342
478
|
const spec = columnsOrSpec as RichForeignKeyInput<LocalColumns, TargetTable, TargetColumns>
|
|
343
|
-
const targetTable = spec.target()
|
|
479
|
+
const targetTable = spec.target()
|
|
344
480
|
const targetState = targetTable[BaseTable.TypeId]
|
|
345
481
|
return BaseTable.option({
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
482
|
+
kind: "foreignKey",
|
|
483
|
+
columns: normalizeColumns(spec.columns) as BaseTable.NormalizeColumns<LocalColumns>,
|
|
484
|
+
name: spec.name,
|
|
485
|
+
references: () => ({
|
|
486
|
+
tableName: targetState.baseName,
|
|
487
|
+
schemaName: targetState.schemaName,
|
|
488
|
+
columns: normalizeColumns(spec.referencedColumns) as BaseTable.NormalizeColumns<TargetColumns>,
|
|
489
|
+
knownColumns: Object.keys(targetState.fields) as unknown as readonly ColumnNamesOfTable<TargetTable>[]
|
|
490
|
+
}),
|
|
491
|
+
onUpdate: spec.onUpdate,
|
|
492
|
+
onDelete: spec.onDelete,
|
|
493
|
+
deferrable: spec.deferrable,
|
|
494
|
+
initiallyDeferred: spec.initiallyDeferred
|
|
495
|
+
} as RichForeignKeyOptionSpec<LocalColumns, TargetTable, TargetColumns>)
|
|
360
496
|
})()
|
|
361
|
-
: BaseTable.foreignKey(
|
|
362
|
-
columnsOrSpec as LocalColumns
|
|
363
|
-
target as () =>
|
|
364
|
-
referencedColumns as TargetColumns
|
|
497
|
+
: BaseTable.foreignKey<LocalColumns, TargetTable, TargetColumns>(
|
|
498
|
+
columnsOrSpec as LocalColumns & BaseTable.NonEmptyColumnInput<LocalColumns>,
|
|
499
|
+
target as () => TargetTable,
|
|
500
|
+
referencedColumns as TargetColumns & BaseTable.NonEmptyColumnInput<TargetColumns> & BaseTable.MatchingColumnArityInput<LocalColumns, TargetColumns> & KnownTargetColumnsInput<NoInfer<TargetTable>, TargetColumns>
|
|
365
501
|
)
|
|
366
502
|
|
|
367
503
|
export const check: {
|
package/src/postgres/type.ts
CHANGED
|
@@ -25,6 +25,10 @@ type PostgresTypeNamespace = typeof postgresDatatypes & {
|
|
|
25
25
|
readonly enum: <Kind extends string>(kind: Kind) => Expression.DbType.Enum<"postgres", Kind>
|
|
26
26
|
readonly set: <Kind extends string>(kind: Kind) => Expression.DbType.Set<"postgres", Kind>
|
|
27
27
|
readonly custom: <Kind extends string>(kind: Kind) => Expression.DbType.Base<"postgres", Kind>
|
|
28
|
+
readonly driverValueMapping: <Db extends Expression.DbType.Any>(
|
|
29
|
+
dbType: Db,
|
|
30
|
+
mapping: Expression.DriverValueMapping
|
|
31
|
+
) => Db
|
|
28
32
|
}
|
|
29
33
|
|
|
30
34
|
/** Postgres database-type constructors for casts and typed column references. */
|
|
@@ -0,0 +1,128 @@
|
|
|
1
|
+
import * as Schema from "effect/Schema"
|
|
2
|
+
|
|
3
|
+
import * as BaseColumn from "../internal/column.js"
|
|
4
|
+
import { makeColumnDefinition, type AnyColumnDefinition, type ColumnDefinition } from "../internal/column-state.js"
|
|
5
|
+
import type * as Expression from "../internal/scalar.js"
|
|
6
|
+
import {
|
|
7
|
+
DecimalStringSchema,
|
|
8
|
+
LocalDateStringSchema,
|
|
9
|
+
LocalDateTimeStringSchema,
|
|
10
|
+
LocalTimeStringSchema,
|
|
11
|
+
type DecimalString,
|
|
12
|
+
type LocalDateString,
|
|
13
|
+
type LocalDateTimeString,
|
|
14
|
+
type LocalTimeString
|
|
15
|
+
} from "../internal/runtime/value.js"
|
|
16
|
+
import { sqliteDatatypes } from "./datatypes/index.js"
|
|
17
|
+
|
|
18
|
+
const enrichDbType = <Db extends Expression.DbType.Any>(dbType: Db): Db => {
|
|
19
|
+
const candidate = (sqliteDatatypes as unknown as Record<string, (() => Expression.DbType.Any) | undefined>)[dbType.kind]
|
|
20
|
+
return typeof candidate === "function"
|
|
21
|
+
? { ...candidate(), ...dbType } as Db
|
|
22
|
+
: dbType
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
const primitive = <Type, Db extends Expression.DbType.Any>(
|
|
26
|
+
schema: Schema.Schema<Type, any, any>,
|
|
27
|
+
dbType: Db
|
|
28
|
+
): ColumnDefinition<Type, Type, Type, Db, false, false, false, false, false, undefined> =>
|
|
29
|
+
makeColumnDefinition(schema as Schema.Schema<NonNullable<Type>>, {
|
|
30
|
+
dbType,
|
|
31
|
+
nullable: false,
|
|
32
|
+
hasDefault: false,
|
|
33
|
+
generated: false,
|
|
34
|
+
primaryKey: false,
|
|
35
|
+
unique: false,
|
|
36
|
+
references: undefined
|
|
37
|
+
})
|
|
38
|
+
|
|
39
|
+
const renderNumericDdlType = (
|
|
40
|
+
kind: string,
|
|
41
|
+
options?: BaseColumn.NumericOptions
|
|
42
|
+
): string | undefined => {
|
|
43
|
+
if (options === undefined || options.precision === undefined) {
|
|
44
|
+
return undefined
|
|
45
|
+
}
|
|
46
|
+
return options.scale === undefined
|
|
47
|
+
? `${kind}(${options.precision})`
|
|
48
|
+
: `${kind}(${options.precision},${options.scale})`
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
export const custom = <SchemaType extends Schema.Schema.Any, Db extends Expression.DbType.Any>(
|
|
52
|
+
schema: SchemaType,
|
|
53
|
+
dbType: Db
|
|
54
|
+
) =>
|
|
55
|
+
makeColumnDefinition(schema as unknown as Schema.Schema<NonNullable<Schema.Schema.Type<SchemaType>>, any, any>, {
|
|
56
|
+
dbType: enrichDbType(dbType),
|
|
57
|
+
nullable: false,
|
|
58
|
+
hasDefault: false,
|
|
59
|
+
generated: false,
|
|
60
|
+
primaryKey: false,
|
|
61
|
+
unique: false,
|
|
62
|
+
references: undefined,
|
|
63
|
+
ddlType: undefined,
|
|
64
|
+
identity: undefined
|
|
65
|
+
})
|
|
66
|
+
|
|
67
|
+
export const uuid = () => primitive(Schema.UUID, sqliteDatatypes.uuid())
|
|
68
|
+
export const text = () => primitive(Schema.String, sqliteDatatypes.text())
|
|
69
|
+
export const int = () => primitive(Schema.Int, sqliteDatatypes.int())
|
|
70
|
+
export const number = (options?: BaseColumn.NumericOptions) =>
|
|
71
|
+
makeColumnDefinition(DecimalStringSchema, {
|
|
72
|
+
dbType: sqliteDatatypes.decimal(),
|
|
73
|
+
nullable: false,
|
|
74
|
+
hasDefault: false,
|
|
75
|
+
generated: false,
|
|
76
|
+
primaryKey: false,
|
|
77
|
+
unique: false,
|
|
78
|
+
references: undefined,
|
|
79
|
+
ddlType: renderNumericDdlType("decimal", options),
|
|
80
|
+
identity: undefined
|
|
81
|
+
})
|
|
82
|
+
export const boolean = () => primitive(Schema.Boolean, sqliteDatatypes.boolean())
|
|
83
|
+
export const date = () => primitive(LocalDateStringSchema, sqliteDatatypes.date())
|
|
84
|
+
export const time = () => primitive(LocalTimeStringSchema, sqliteDatatypes.time())
|
|
85
|
+
export const datetime = () => primitive(LocalDateTimeStringSchema, sqliteDatatypes.datetime())
|
|
86
|
+
export const timestamp = () => primitive(LocalDateTimeStringSchema, sqliteDatatypes.timestamp())
|
|
87
|
+
export const json = <SchemaType extends Schema.Schema.Any>(schema: SchemaType) =>
|
|
88
|
+
makeColumnDefinition(schema as unknown as Schema.Schema<NonNullable<Schema.Schema.Type<SchemaType>>, any, any>, {
|
|
89
|
+
dbType: { ...sqliteDatatypes.json(), variant: "json" } as Expression.DbType.Json<"sqlite", "json">,
|
|
90
|
+
nullable: false,
|
|
91
|
+
hasDefault: false,
|
|
92
|
+
generated: false,
|
|
93
|
+
primaryKey: false,
|
|
94
|
+
unique: false,
|
|
95
|
+
references: undefined,
|
|
96
|
+
ddlType: undefined,
|
|
97
|
+
identity: undefined
|
|
98
|
+
})
|
|
99
|
+
|
|
100
|
+
export const nullable = BaseColumn.nullable
|
|
101
|
+
export const brand = BaseColumn.brand
|
|
102
|
+
export const primaryKey = BaseColumn.primaryKey
|
|
103
|
+
type UniqueColumn<Column extends AnyColumnDefinition> = ReturnType<typeof BaseColumn.unique<Column>>
|
|
104
|
+
|
|
105
|
+
type SqliteUniqueOptions = {
|
|
106
|
+
readonly name?: string
|
|
107
|
+
readonly nullsNotDistinct?: never
|
|
108
|
+
readonly deferrable?: never
|
|
109
|
+
readonly initiallyDeferred?: never
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
type UniqueModifier = {
|
|
113
|
+
<Column extends AnyColumnDefinition>(column: Column): UniqueColumn<Column>
|
|
114
|
+
readonly options: <const Options extends SqliteUniqueOptions>(
|
|
115
|
+
options: Options
|
|
116
|
+
) => <Column extends AnyColumnDefinition>(column: Column) => UniqueColumn<Column>
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
export const unique = BaseColumn.unique as UniqueModifier
|
|
120
|
+
const default_ = BaseColumn.default_
|
|
121
|
+
export const generated = BaseColumn.generated
|
|
122
|
+
export const driverValueMapping = BaseColumn.driverValueMapping
|
|
123
|
+
export const references = BaseColumn.references
|
|
124
|
+
export const schema = BaseColumn.schema
|
|
125
|
+
export { default_ as default }
|
|
126
|
+
|
|
127
|
+
export type Any = BaseColumn.Any
|
|
128
|
+
export type AnyBound = BaseColumn.AnyBound
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
import type { DatatypeModule } from "../../internal/datatypes/define.js"
|
|
2
|
+
import type * as Expression from "../../internal/scalar.js"
|
|
3
|
+
import { sqliteDatatypeFamilies, sqliteDatatypeKinds } from "./spec.js"
|
|
4
|
+
|
|
5
|
+
const withMetadata = <Kind extends keyof typeof sqliteDatatypeKinds & string>(
|
|
6
|
+
kind: Kind
|
|
7
|
+
): Expression.DbType.Base<"sqlite", Kind> => {
|
|
8
|
+
const kindSpec = sqliteDatatypeKinds[kind]
|
|
9
|
+
const familySpec = sqliteDatatypeFamilies[kindSpec.family as keyof typeof sqliteDatatypeFamilies]
|
|
10
|
+
return {
|
|
11
|
+
dialect: "sqlite",
|
|
12
|
+
kind,
|
|
13
|
+
family: kindSpec.family,
|
|
14
|
+
runtime: kindSpec.runtime,
|
|
15
|
+
compareGroup: familySpec?.compareGroup,
|
|
16
|
+
castTargets: familySpec?.castTargets,
|
|
17
|
+
traits: familySpec?.traits
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
const sqliteDatatypeModule = {
|
|
22
|
+
custom: (kind: string) => ({
|
|
23
|
+
dialect: "sqlite",
|
|
24
|
+
kind
|
|
25
|
+
}),
|
|
26
|
+
uuid: () => ({
|
|
27
|
+
dialect: "sqlite",
|
|
28
|
+
kind: "uuid",
|
|
29
|
+
family: "uuid",
|
|
30
|
+
runtime: "string",
|
|
31
|
+
compareGroup: "uuid",
|
|
32
|
+
castTargets: ["uuid", "char", "varchar", "text"],
|
|
33
|
+
traits: {
|
|
34
|
+
textual: true
|
|
35
|
+
}
|
|
36
|
+
})
|
|
37
|
+
} as Record<string, (...args: readonly any[]) => Expression.DbType.Base<"sqlite", string>>
|
|
38
|
+
|
|
39
|
+
for (const kind of Object.keys(sqliteDatatypeKinds)) {
|
|
40
|
+
sqliteDatatypeModule[kind] = () => withMetadata(kind as keyof typeof sqliteDatatypeKinds & string)
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
type SqliteUuidWitness = Expression.DbType.Base<"sqlite", "uuid"> & {
|
|
44
|
+
readonly family: "uuid"
|
|
45
|
+
readonly runtime: "string"
|
|
46
|
+
readonly compareGroup: "uuid"
|
|
47
|
+
readonly castTargets: readonly ["uuid", "char", "varchar", "text"]
|
|
48
|
+
readonly traits: {
|
|
49
|
+
readonly textual: true
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
type SqliteJsonWitness = Expression.DbType.Base<"sqlite", "json"> & {
|
|
54
|
+
readonly family: "json"
|
|
55
|
+
readonly runtime: "json"
|
|
56
|
+
readonly compareGroup: "json"
|
|
57
|
+
readonly castTargets: readonly ["json", "text"]
|
|
58
|
+
readonly driverValueMapping: {
|
|
59
|
+
readonly toDriver: (value: unknown) => unknown
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
sqliteDatatypeModule.json = () => ({
|
|
64
|
+
...withMetadata("json"),
|
|
65
|
+
driverValueMapping: {
|
|
66
|
+
toDriver: (value: unknown) => JSON.stringify(value)
|
|
67
|
+
}
|
|
68
|
+
}) as SqliteJsonWitness
|
|
69
|
+
|
|
70
|
+
export const sqliteDatatypes = sqliteDatatypeModule as DatatypeModule<
|
|
71
|
+
"sqlite",
|
|
72
|
+
typeof sqliteDatatypeKinds,
|
|
73
|
+
typeof sqliteDatatypeFamilies
|
|
74
|
+
> & {
|
|
75
|
+
readonly uuid: () => SqliteUuidWitness
|
|
76
|
+
readonly json: () => SqliteJsonWitness
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
export type SqliteDatatypeModule = typeof sqliteDatatypes
|
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
import type { DatatypeFamilySpec, DatatypeKindSpec } from "../../internal/datatypes/shape.js"
|
|
2
|
+
|
|
3
|
+
export const sqliteDatatypeFamilies = {
|
|
4
|
+
text: {
|
|
5
|
+
compareGroup: "text",
|
|
6
|
+
castTargets: ["text", "numeric", "integer", "real", "boolean", "date", "time", "datetime", "json", "blob", "null"],
|
|
7
|
+
traits: {
|
|
8
|
+
textual: true,
|
|
9
|
+
ordered: true
|
|
10
|
+
}
|
|
11
|
+
},
|
|
12
|
+
numeric: {
|
|
13
|
+
compareGroup: "numeric",
|
|
14
|
+
castTargets: ["numeric", "integer", "real", "text", "boolean", "date", "time", "datetime"],
|
|
15
|
+
traits: {
|
|
16
|
+
ordered: true
|
|
17
|
+
}
|
|
18
|
+
},
|
|
19
|
+
integer: {
|
|
20
|
+
compareGroup: "numeric",
|
|
21
|
+
castTargets: ["integer", "numeric", "real", "text", "boolean", "date", "time", "datetime"],
|
|
22
|
+
traits: {
|
|
23
|
+
ordered: true
|
|
24
|
+
}
|
|
25
|
+
},
|
|
26
|
+
real: {
|
|
27
|
+
compareGroup: "numeric",
|
|
28
|
+
castTargets: ["real", "numeric", "integer", "text", "boolean"],
|
|
29
|
+
traits: {
|
|
30
|
+
ordered: true
|
|
31
|
+
}
|
|
32
|
+
},
|
|
33
|
+
boolean: {
|
|
34
|
+
compareGroup: "boolean",
|
|
35
|
+
castTargets: ["boolean", "integer", "numeric", "text"],
|
|
36
|
+
traits: {}
|
|
37
|
+
},
|
|
38
|
+
date: {
|
|
39
|
+
compareGroup: "date",
|
|
40
|
+
castTargets: ["date", "time", "datetime", "text", "numeric", "integer"],
|
|
41
|
+
traits: {
|
|
42
|
+
ordered: true
|
|
43
|
+
}
|
|
44
|
+
},
|
|
45
|
+
time: {
|
|
46
|
+
compareGroup: "time",
|
|
47
|
+
castTargets: ["time", "date", "datetime", "text", "numeric", "integer"],
|
|
48
|
+
traits: {
|
|
49
|
+
ordered: true
|
|
50
|
+
}
|
|
51
|
+
},
|
|
52
|
+
datetime: {
|
|
53
|
+
compareGroup: "datetime",
|
|
54
|
+
castTargets: ["datetime", "date", "time", "text", "numeric", "integer"],
|
|
55
|
+
traits: {
|
|
56
|
+
ordered: true
|
|
57
|
+
}
|
|
58
|
+
},
|
|
59
|
+
json: {
|
|
60
|
+
compareGroup: "json",
|
|
61
|
+
castTargets: ["json", "text"],
|
|
62
|
+
traits: {}
|
|
63
|
+
},
|
|
64
|
+
blob: {
|
|
65
|
+
compareGroup: "blob",
|
|
66
|
+
castTargets: ["blob", "text"],
|
|
67
|
+
traits: {}
|
|
68
|
+
},
|
|
69
|
+
null: {
|
|
70
|
+
compareGroup: "null",
|
|
71
|
+
castTargets: ["text", "numeric", "integer", "real", "boolean", "date", "time", "datetime", "json", "blob", "null"],
|
|
72
|
+
traits: {}
|
|
73
|
+
}
|
|
74
|
+
} as const satisfies Record<string, DatatypeFamilySpec>
|
|
75
|
+
|
|
76
|
+
export const sqliteDatatypeKinds = {
|
|
77
|
+
text: { family: "text", runtime: "string" },
|
|
78
|
+
varchar: { family: "text", runtime: "string" },
|
|
79
|
+
char: { family: "text", runtime: "string" },
|
|
80
|
+
clob: { family: "text", runtime: "string" },
|
|
81
|
+
int: { family: "integer", runtime: "number" },
|
|
82
|
+
integer: { family: "integer", runtime: "number" },
|
|
83
|
+
bigint: { family: "integer", runtime: "bigintString" },
|
|
84
|
+
numeric: { family: "numeric", runtime: "decimalString" },
|
|
85
|
+
decimal: { family: "numeric", runtime: "decimalString" },
|
|
86
|
+
real: { family: "real", runtime: "number" },
|
|
87
|
+
double: { family: "real", runtime: "number" },
|
|
88
|
+
boolean: { family: "boolean", runtime: "boolean" },
|
|
89
|
+
date: { family: "date", runtime: "localDate" },
|
|
90
|
+
time: { family: "time", runtime: "localTime" },
|
|
91
|
+
datetime: { family: "datetime", runtime: "localDateTime" },
|
|
92
|
+
timestamp: { family: "datetime", runtime: "localDateTime" },
|
|
93
|
+
json: { family: "json", runtime: "json" },
|
|
94
|
+
blob: { family: "blob", runtime: "bytes" }
|
|
95
|
+
} as const satisfies Record<string, DatatypeKindSpec>
|
|
96
|
+
|
|
97
|
+
export type SqliteDatatypeFamily = keyof typeof sqliteDatatypeFamilies
|
|
98
|
+
export type SqliteDatatypeKind = keyof typeof sqliteDatatypeKinds
|