effect-qb 0.13.0 → 0.15.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 +61945 -3611
- package/dist/postgres/metadata.js +2818 -0
- package/dist/postgres.js +9942 -5591
- package/package.json +21 -10
- package/src/internal/aggregation-validation.ts +3 -3
- package/src/internal/case-analysis.d.ts +18 -0
- package/src/internal/case-analysis.ts +4 -4
- package/src/internal/coercion/analysis.d.ts +7 -0
- package/src/internal/{coercion-analysis.ts → coercion/analysis.ts} +3 -3
- package/src/internal/coercion/errors.d.ts +17 -0
- package/src/internal/{coercion-errors.ts → coercion/errors.ts} +1 -1
- package/src/internal/coercion/kind.d.ts +4 -0
- package/src/internal/{coercion-kind.ts → coercion/kind.ts} +2 -2
- package/src/internal/{coercion-normalize.ts → coercion/normalize.ts} +1 -1
- package/src/internal/coercion/rules.d.ts +6 -0
- package/src/internal/{coercion-rules.ts → coercion/rules.ts} +2 -2
- package/src/internal/column-state.d.ts +190 -0
- package/src/internal/column-state.ts +119 -56
- package/src/internal/column.ts +387 -149
- package/src/internal/datatypes/define.d.ts +17 -0
- package/src/internal/datatypes/define.ts +18 -34
- package/src/internal/datatypes/lookup.d.ts +44 -0
- package/src/internal/datatypes/lookup.ts +61 -152
- package/src/internal/datatypes/shape.d.ts +16 -0
- package/src/internal/datatypes/shape.ts +1 -1
- package/src/internal/derived-table.d.ts +4 -0
- package/src/internal/derived-table.ts +21 -16
- package/src/internal/dsl-mutation-runtime.ts +378 -0
- package/src/internal/dsl-plan-runtime.ts +387 -0
- package/src/internal/dsl-query-runtime.ts +160 -0
- package/src/internal/dsl-transaction-ddl-runtime.ts +263 -0
- package/src/internal/executor.ts +173 -38
- package/src/internal/expression-ast.ts +19 -5
- package/src/internal/grouping-key.d.ts +3 -0
- package/src/internal/grouping-key.ts +1 -1
- package/src/internal/implication-runtime.d.ts +15 -0
- package/src/internal/implication-runtime.ts +171 -0
- package/src/internal/json/ast.d.ts +30 -0
- package/src/internal/json/ast.ts +1 -1
- package/src/internal/json/errors.d.ts +8 -0
- package/src/internal/json/path.d.ts +75 -0
- package/src/internal/json/path.ts +1 -1
- package/src/internal/json/types.d.ts +62 -0
- package/src/internal/predicate/analysis.d.ts +20 -0
- package/src/internal/{predicate-analysis.ts → predicate/analysis.ts} +13 -3
- package/src/internal/predicate/atom.d.ts +28 -0
- package/src/internal/{predicate-branches.ts → predicate/branches.ts} +2 -2
- package/src/internal/predicate/context.d.ts +67 -0
- package/src/internal/{predicate-context.ts → predicate/context.ts} +111 -32
- package/src/internal/predicate/formula.d.ts +35 -0
- package/src/internal/{predicate-formula.ts → predicate/formula.ts} +32 -20
- package/src/internal/predicate/key.d.ts +11 -0
- package/src/internal/{predicate-key.ts → predicate/key.ts} +2 -2
- package/src/internal/{predicate-nnf.ts → predicate/nnf.ts} +2 -2
- package/src/internal/predicate/normalize.d.ts +53 -0
- package/src/internal/predicate/normalize.ts +273 -0
- package/src/internal/predicate/runtime.d.ts +31 -0
- package/src/internal/predicate/runtime.ts +679 -0
- package/src/internal/projection-alias.d.ts +13 -0
- package/src/internal/projections.d.ts +31 -0
- package/src/internal/projections.ts +1 -1
- package/src/internal/query-ast.d.ts +217 -0
- package/src/internal/query-ast.ts +1 -1
- package/src/internal/query-requirements.d.ts +20 -0
- package/src/internal/query.d.ts +775 -0
- package/src/internal/query.ts +767 -275
- package/src/internal/renderer.ts +7 -21
- package/src/internal/row-set.d.ts +53 -0
- package/src/internal/{plan.ts → row-set.ts} +23 -11
- package/src/internal/{runtime-normalize.ts → runtime/normalize.ts} +9 -31
- package/src/internal/{runtime-schema.ts → runtime/schema.ts} +84 -55
- package/src/internal/runtime/value.d.ts +22 -0
- package/src/internal/{runtime-value.ts → runtime/value.ts} +2 -2
- package/src/internal/scalar.d.ts +107 -0
- package/src/internal/scalar.ts +191 -0
- package/src/internal/schema-derivation.d.ts +105 -0
- package/src/internal/schema-derivation.ts +93 -21
- package/src/internal/schema-expression.d.ts +18 -0
- package/src/internal/schema-expression.ts +75 -0
- package/src/internal/table-options.d.ts +94 -0
- package/src/internal/table-options.ts +94 -8
- package/src/internal/table.d.ts +173 -0
- package/src/internal/table.ts +135 -54
- package/src/mysql/column.ts +95 -18
- package/src/mysql/datatypes/index.ts +58 -3
- package/src/mysql/errors/generated.ts +57336 -0
- package/src/mysql/errors/index.ts +1 -0
- package/src/mysql/errors/normalize.ts +55 -53
- package/src/mysql/errors/types.ts +74 -0
- package/src/mysql/executor.ts +69 -7
- package/src/mysql/function/aggregate.ts +1 -5
- package/src/mysql/function/core.ts +1 -3
- package/src/mysql/function/index.ts +1 -1
- package/src/mysql/function/string.ts +1 -5
- package/src/mysql/function/temporal.ts +12 -15
- package/src/mysql/function/window.ts +1 -6
- package/src/{internal/mysql-dialect.ts → mysql/internal/dialect.ts} +1 -1
- package/src/mysql/internal/dsl.ts +6115 -0
- package/src/{internal/mysql-renderer.ts → mysql/internal/renderer.ts} +6 -6
- package/src/mysql/internal/sql-expression-renderer.ts +1455 -0
- package/src/mysql/json.ts +2 -0
- package/src/mysql/query.ts +111 -86
- package/src/mysql/renderer.ts +1 -1
- package/src/mysql/table.ts +1 -1
- package/src/mysql.ts +6 -4
- package/src/postgres/cast.ts +30 -0
- package/src/postgres/column.ts +178 -20
- package/src/postgres/datatypes/index.d.ts +515 -0
- package/src/postgres/datatypes/index.ts +49 -5
- package/src/postgres/datatypes/spec.d.ts +412 -0
- package/src/postgres/errors/generated.ts +2636 -0
- package/src/postgres/errors/index.ts +1 -0
- package/src/postgres/errors/normalize.ts +47 -62
- package/src/postgres/errors/types.ts +92 -34
- package/src/postgres/executor.ts +37 -5
- package/src/postgres/function/aggregate.ts +1 -5
- package/src/postgres/function/core.ts +20 -2
- package/src/postgres/function/index.ts +1 -1
- package/src/postgres/function/string.ts +1 -5
- package/src/postgres/function/temporal.ts +12 -15
- package/src/postgres/function/window.ts +1 -6
- package/src/{internal/postgres-dialect.ts → postgres/internal/dialect.ts} +1 -1
- package/src/{internal/query-factory.ts → postgres/internal/dsl.ts} +1568 -2120
- package/src/{internal/postgres-renderer.ts → postgres/internal/renderer.ts} +6 -6
- package/src/postgres/internal/schema-ddl.ts +108 -0
- package/src/postgres/internal/schema-model.ts +150 -0
- package/src/{internal → postgres/internal}/sql-expression-renderer.ts +112 -46
- package/src/postgres/json.ts +493 -0
- package/src/postgres/metadata.ts +31 -0
- package/src/postgres/query.ts +113 -86
- package/src/postgres/renderer.ts +3 -13
- package/src/postgres/schema-expression.ts +17 -0
- package/src/postgres/schema-management.ts +204 -0
- package/src/postgres/schema.ts +35 -0
- package/src/postgres/table.ts +316 -42
- package/src/postgres/type.ts +31 -0
- package/src/postgres.ts +20 -4
- package/CHANGELOG.md +0 -134
- package/src/internal/expression.ts +0 -327
- package/src/internal/predicate-normalize.ts +0 -202
- package/src/mysql/function/json.ts +0 -4
- package/src/mysql/private/query.ts +0 -13
- package/src/postgres/function/json.ts +0 -4
- package/src/postgres/private/query.ts +0 -13
- /package/src/internal/{predicate-atom.ts → predicate/atom.ts} +0 -0
package/src/internal/table.ts
CHANGED
|
@@ -1,16 +1,19 @@
|
|
|
1
1
|
import { pipeArguments, type Pipeable } from "effect/Pipeable"
|
|
2
2
|
import * as Schema from "effect/Schema"
|
|
3
3
|
|
|
4
|
-
import * as Plan from "./
|
|
5
|
-
import type { Any as AnyExpression } from "./
|
|
4
|
+
import * as Plan from "./row-set.js"
|
|
5
|
+
import type { Any as AnyExpression } from "./scalar.js"
|
|
6
|
+
import type { TrueFormula } from "./predicate/formula.js"
|
|
6
7
|
import type { BoundColumnFrom } from "./column-state.js"
|
|
7
8
|
import { bindColumn, type AnyColumnDefinition } from "./column-state.js"
|
|
8
9
|
import {
|
|
9
10
|
collectInlineOptions,
|
|
10
11
|
normalizeColumnList,
|
|
11
12
|
resolvePrimaryKeyColumns,
|
|
12
|
-
type
|
|
13
|
+
type DdlExpressionLike,
|
|
14
|
+
type IndexKeySpec,
|
|
13
15
|
type NormalizeColumns,
|
|
16
|
+
type ReferentialAction,
|
|
14
17
|
type TableOptionSpec,
|
|
15
18
|
type ValidateKnownColumns,
|
|
16
19
|
type ValidatePrimaryKeyColumns,
|
|
@@ -42,7 +45,16 @@ type TableDialect<Fields extends TableFieldMap> = Fields[keyof Fields][typeof im
|
|
|
42
45
|
type TableKind = "schema" | "alias"
|
|
43
46
|
type DefaultSchemaName = "public"
|
|
44
47
|
type ClassOptionSpec = Exclude<TableOptionSpec, { readonly kind: "primaryKey" }>
|
|
45
|
-
|
|
48
|
+
interface TableOptionBuilderLike<
|
|
49
|
+
Spec extends TableOptionSpec = TableOptionSpec
|
|
50
|
+
> {
|
|
51
|
+
(
|
|
52
|
+
table: TableDefinition<any, any, any, "schema", any>
|
|
53
|
+
): TableDefinition<any, any, any, "schema", any>
|
|
54
|
+
readonly option: Spec
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
type ClassTableOption = TableOptionBuilderLike<ClassOptionSpec>
|
|
46
58
|
type ClassDeclaredTableOptions = readonly ClassTableOption[]
|
|
47
59
|
|
|
48
60
|
type BuildPrimaryKey<
|
|
@@ -64,12 +76,19 @@ type OptionInputTable<
|
|
|
64
76
|
type ApplyOption<
|
|
65
77
|
Table extends TableDefinition<any, any, any, "schema", any>,
|
|
66
78
|
Spec extends TableOptionSpec
|
|
67
|
-
> =
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
79
|
+
> = Spec extends { readonly kind: "primaryKey" }
|
|
80
|
+
? TableDefinition<
|
|
81
|
+
Table[typeof TypeId]["name"],
|
|
82
|
+
Table[typeof TypeId]["fields"],
|
|
83
|
+
BuildPrimaryKey<Table, Spec>,
|
|
84
|
+
"schema"
|
|
85
|
+
>
|
|
86
|
+
: TableDefinition<
|
|
87
|
+
Table[typeof TypeId]["name"],
|
|
88
|
+
Table[typeof TypeId]["fields"],
|
|
89
|
+
Table[typeof TypeId]["primaryKey"][number],
|
|
90
|
+
"schema"
|
|
91
|
+
>
|
|
73
92
|
|
|
74
93
|
export type MissingSelfGeneric = "Missing `Self` generic - use `class Self extends Table.Class<Self>(...) {}`"
|
|
75
94
|
|
|
@@ -83,12 +102,13 @@ export type BoundColumns<
|
|
|
83
102
|
|
|
84
103
|
/** Derived runtime schemas exposed by a table definition. */
|
|
85
104
|
export interface TableSchemas<
|
|
105
|
+
Name extends string,
|
|
86
106
|
Fields extends TableFieldMap,
|
|
87
107
|
PrimaryKeyColumns extends keyof Fields & string
|
|
88
108
|
> {
|
|
89
|
-
readonly select: Schema.Schema<SelectRow<Fields>>
|
|
90
|
-
readonly insert: Schema.Schema<InsertRow<Fields>>
|
|
91
|
-
readonly update: Schema.Schema<UpdateRow<Fields, PrimaryKeyColumns>>
|
|
109
|
+
readonly select: Schema.Schema<SelectRow<Name, Fields>>
|
|
110
|
+
readonly insert: Schema.Schema<InsertRow<Name, Fields>>
|
|
111
|
+
readonly update: Schema.Schema<UpdateRow<Name, Fields, PrimaryKeyColumns>>
|
|
92
112
|
}
|
|
93
113
|
|
|
94
114
|
interface TableState<
|
|
@@ -116,11 +136,12 @@ export interface TableSchemaNamespace<SchemaName extends string> {
|
|
|
116
136
|
>(
|
|
117
137
|
name: Name,
|
|
118
138
|
fields: Fields,
|
|
119
|
-
...options:
|
|
139
|
+
...options: DeclaredTableOptions
|
|
120
140
|
) => TableDefinition<Name, Fields, PrimaryKeyColumns, "schema", SchemaName>
|
|
121
141
|
}
|
|
122
142
|
|
|
123
|
-
export type DeclaredTableOptions =
|
|
143
|
+
export type DeclaredTableOptions = readonly TableOptionBuilderLike[]
|
|
144
|
+
export type { DdlExpressionLike, IndexKeySpec, NormalizeColumns, ReferentialAction } from "./table-options.js"
|
|
124
145
|
|
|
125
146
|
export type TableDefinition<
|
|
126
147
|
Name extends string,
|
|
@@ -131,20 +152,20 @@ export type TableDefinition<
|
|
|
131
152
|
> = Pipeable & {
|
|
132
153
|
readonly name: Name
|
|
133
154
|
readonly columns: BoundColumns<Name, Fields>
|
|
134
|
-
readonly schemas: TableSchemas<Fields, PrimaryKeyColumns>
|
|
155
|
+
readonly schemas: TableSchemas<Name, Fields, PrimaryKeyColumns>
|
|
135
156
|
readonly [TypeId]: TableState<Name, Fields, PrimaryKeyColumns, Kind, SchemaName>
|
|
136
157
|
readonly [Plan.TypeId]: Plan.State<
|
|
137
158
|
BoundColumns<Name, Fields>,
|
|
138
159
|
never,
|
|
139
|
-
Record<Name, Plan.Source<Name>>,
|
|
160
|
+
Record<Name, Plan.Source<Name, "required", TrueFormula>>,
|
|
140
161
|
TableDialect<Fields>
|
|
141
162
|
>
|
|
142
163
|
readonly [OptionsSymbol]: readonly TableOptionSpec[]
|
|
143
164
|
readonly [DeclaredOptionsSymbol]: readonly TableOptionSpec[]
|
|
144
|
-
} & BoundColumns<Name, Fields> & Plan.
|
|
165
|
+
} & BoundColumns<Name, Fields> & Plan.RowSet<
|
|
145
166
|
BoundColumns<Name, Fields>,
|
|
146
167
|
never,
|
|
147
|
-
Record<Name, Plan.Source<Name>>,
|
|
168
|
+
Record<Name, Plan.Source<Name, "required", TrueFormula>>,
|
|
148
169
|
TableDialect<Fields>
|
|
149
170
|
>
|
|
150
171
|
|
|
@@ -161,22 +182,22 @@ export type TableClassStatic<
|
|
|
161
182
|
SchemaName extends string | undefined = DefaultSchemaName
|
|
162
183
|
> = (abstract new (...args: any[]) => any) & Pipeable & {
|
|
163
184
|
readonly columns: BoundColumns<Name, Fields>
|
|
164
|
-
readonly schemas: TableSchemas<Fields, PrimaryKeyColumns>
|
|
185
|
+
readonly schemas: TableSchemas<Name, Fields, PrimaryKeyColumns>
|
|
165
186
|
readonly [TypeId]: TableState<Name, Fields, PrimaryKeyColumns, "schema", SchemaName>
|
|
166
187
|
readonly [Plan.TypeId]: Plan.State<
|
|
167
188
|
BoundColumns<Name, Fields>,
|
|
168
189
|
never,
|
|
169
|
-
Record<Name, Plan.Source<Name>>,
|
|
190
|
+
Record<Name, Plan.Source<Name, "required", TrueFormula>>,
|
|
170
191
|
TableDialect<Fields>
|
|
171
192
|
>
|
|
172
193
|
readonly [OptionsSymbol]: readonly TableOptionSpec[]
|
|
173
194
|
readonly [DeclaredOptionsSymbol]?: readonly TableOptionSpec[]
|
|
174
195
|
readonly [options]?: ClassDeclaredTableOptions
|
|
175
196
|
readonly tableName: Name
|
|
176
|
-
} & BoundColumns<Name, Fields> & Plan.
|
|
197
|
+
} & BoundColumns<Name, Fields> & Plan.RowSet<
|
|
177
198
|
BoundColumns<Name, Fields>,
|
|
178
199
|
never,
|
|
179
|
-
Record<Name, Plan.Source<Name>>,
|
|
200
|
+
Record<Name, Plan.Source<Name, "required", TrueFormula>>,
|
|
180
201
|
TableDialect<Fields>
|
|
181
202
|
>
|
|
182
203
|
|
|
@@ -203,13 +224,24 @@ const TableProto = {
|
|
|
203
224
|
}
|
|
204
225
|
}
|
|
205
226
|
|
|
227
|
+
const attachPipe = <Value extends object>(value: Value): Value => {
|
|
228
|
+
Object.defineProperty(value, "pipe", {
|
|
229
|
+
configurable: true,
|
|
230
|
+
writable: true,
|
|
231
|
+
value: function(this: unknown) {
|
|
232
|
+
return pipeArguments(value, arguments)
|
|
233
|
+
}
|
|
234
|
+
})
|
|
235
|
+
return value
|
|
236
|
+
}
|
|
237
|
+
|
|
206
238
|
type BuildArtifacts<
|
|
207
239
|
Name extends string,
|
|
208
240
|
Fields extends TableFieldMap,
|
|
209
241
|
PrimaryKeyColumns extends keyof Fields & string
|
|
210
242
|
> = {
|
|
211
243
|
readonly columns: BoundColumns<Name, Fields>
|
|
212
|
-
readonly schemas: TableSchemas<Fields, PrimaryKeyColumns>
|
|
244
|
+
readonly schemas: TableSchemas<Name, Fields, PrimaryKeyColumns>
|
|
213
245
|
readonly normalizedOptions: readonly TableOptionSpec[]
|
|
214
246
|
readonly primaryKey: readonly PrimaryKeyColumns[]
|
|
215
247
|
}
|
|
@@ -231,7 +263,7 @@ const buildArtifacts = <
|
|
|
231
263
|
const columns = Object.fromEntries(
|
|
232
264
|
Object.entries(fields).map(([key, column]) => [key, bindColumn(name, key, column, name, schemaName)])
|
|
233
265
|
) as BoundColumns<Name, Fields>
|
|
234
|
-
const schemas = deriveSchemas(fields, primaryKey)
|
|
266
|
+
const schemas = deriveSchemas(name, fields, primaryKey)
|
|
235
267
|
return {
|
|
236
268
|
columns,
|
|
237
269
|
schemas,
|
|
@@ -260,7 +292,7 @@ const makeTable = <
|
|
|
260
292
|
: ("public" as SchemaName)
|
|
261
293
|
const artifacts = buildArtifacts(name, fields, declaredOptions, resolvedSchemaName)
|
|
262
294
|
const dialect = resolveFieldDialect(fields)
|
|
263
|
-
const table = Object.create(TableProto)
|
|
295
|
+
const table = attachPipe(Object.create(TableProto))
|
|
264
296
|
table.name = name
|
|
265
297
|
table.columns = artifacts.columns
|
|
266
298
|
table.schemas = artifacts.schemas
|
|
@@ -299,6 +331,21 @@ const extractDeclaredOptions = (
|
|
|
299
331
|
declaredOptions: DeclaredTableOptions | undefined
|
|
300
332
|
): readonly TableOptionSpec[] => declaredOptions?.map((option) => option.option) ?? []
|
|
301
333
|
|
|
334
|
+
const applyDeclaredOptions = <
|
|
335
|
+
Table extends TableDefinition<any, any, any, "schema", any>
|
|
336
|
+
>(
|
|
337
|
+
table: Table,
|
|
338
|
+
declaredOptions: DeclaredTableOptions | undefined
|
|
339
|
+
): Table => {
|
|
340
|
+
if (declaredOptions === undefined || declaredOptions.length === 0) {
|
|
341
|
+
return table
|
|
342
|
+
}
|
|
343
|
+
return declaredOptions.reduce<TableDefinition<any, any, any, "schema", any>>(
|
|
344
|
+
(current, option) => option(current),
|
|
345
|
+
table
|
|
346
|
+
) as unknown as Table
|
|
347
|
+
}
|
|
348
|
+
|
|
302
349
|
const validateClassOptions = (declaredOptions: readonly TableOptionSpec[]): void => {
|
|
303
350
|
for (const option of declaredOptions) {
|
|
304
351
|
if (option.kind === "primaryKey") {
|
|
@@ -310,7 +357,7 @@ const validateClassOptions = (declaredOptions: readonly TableOptionSpec[]): void
|
|
|
310
357
|
const resolveFieldDialect = (fields: TableFieldMap): string => {
|
|
311
358
|
const dialects = [...new Set(Object.values(fields).map((field) => field.metadata.dbType.dialect))]
|
|
312
359
|
if (dialects.length === 0) {
|
|
313
|
-
|
|
360
|
+
throw new Error("Cannot infer table dialect from an empty field set")
|
|
314
361
|
}
|
|
315
362
|
if (dialects.length > 1) {
|
|
316
363
|
throw new Error(`Mixed table dialects are not supported: ${dialects.join(", ")}`)
|
|
@@ -340,14 +387,26 @@ const ensureClassArtifacts = <
|
|
|
340
387
|
return cached
|
|
341
388
|
}
|
|
342
389
|
const state = self[TypeId]
|
|
343
|
-
const
|
|
344
|
-
validateClassOptions(
|
|
345
|
-
const
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
390
|
+
const classOptions = self[options]
|
|
391
|
+
validateClassOptions(extractDeclaredOptions(classOptions))
|
|
392
|
+
const table = applyDeclaredOptions(
|
|
393
|
+
makeTable(
|
|
394
|
+
state.name,
|
|
395
|
+
state.fields,
|
|
396
|
+
[],
|
|
397
|
+
state.name,
|
|
398
|
+
"schema",
|
|
399
|
+
state.schemaName,
|
|
400
|
+
state.schemaName === undefined || state.schemaName === "public" ? "default" : "explicit"
|
|
401
|
+
) as TableDefinition<Name, Fields, PrimaryKeyColumns, "schema", typeof state.schemaName>,
|
|
402
|
+
classOptions
|
|
403
|
+
)
|
|
404
|
+
const artifacts = {
|
|
405
|
+
columns: table.columns,
|
|
406
|
+
schemas: table.schemas,
|
|
407
|
+
normalizedOptions: table[OptionsSymbol],
|
|
408
|
+
primaryKey: table[TypeId].primaryKey as readonly PrimaryKeyColumns[]
|
|
409
|
+
} satisfies BuildArtifacts<Name, Fields, PrimaryKeyColumns>
|
|
351
410
|
Object.defineProperty(self, CacheSymbol, {
|
|
352
411
|
configurable: true,
|
|
353
412
|
value: artifacts
|
|
@@ -384,6 +443,25 @@ const makeOption = <Spec extends TableOptionSpec>(option: Spec): TableOption<Spe
|
|
|
384
443
|
return builder
|
|
385
444
|
}
|
|
386
445
|
|
|
446
|
+
const makeResolvedOption = <Spec extends TableOptionSpec>(
|
|
447
|
+
option: Spec,
|
|
448
|
+
resolve: (table: TableDefinition<any, any, any, "schema", any>) => Spec
|
|
449
|
+
): TableOption<Spec> => {
|
|
450
|
+
const builder = ((table: TableDefinition<any, any, any, "schema", any>) =>
|
|
451
|
+
appendOption(table, resolve(table))) as unknown as TableOption<Spec>
|
|
452
|
+
;(builder as { option: Spec }).option = option
|
|
453
|
+
return builder
|
|
454
|
+
}
|
|
455
|
+
|
|
456
|
+
export const option = <Spec extends TableOptionSpec>(spec: Spec): TableOption<Spec> =>
|
|
457
|
+
makeOption(spec)
|
|
458
|
+
|
|
459
|
+
export const optionFromTable = <Spec extends TableOptionSpec>(
|
|
460
|
+
spec: Spec,
|
|
461
|
+
resolve: (table: TableDefinition<any, any, any, "schema", any>) => Spec
|
|
462
|
+
): TableOption<Spec> =>
|
|
463
|
+
makeResolvedOption(spec, resolve)
|
|
464
|
+
|
|
387
465
|
/** Creates a table definition from a name and field map. */
|
|
388
466
|
export function make<
|
|
389
467
|
Name extends string,
|
|
@@ -422,17 +500,20 @@ export const schema = <SchemaName extends string>(
|
|
|
422
500
|
>(
|
|
423
501
|
name: Name,
|
|
424
502
|
fields: Fields,
|
|
425
|
-
...options:
|
|
503
|
+
...options: DeclaredTableOptions
|
|
426
504
|
): TableDefinition<Name, Fields, PrimaryKeyColumns, "schema", SchemaName> =>
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
505
|
+
applyDeclaredOptions(
|
|
506
|
+
makeTable(
|
|
507
|
+
name,
|
|
508
|
+
fields,
|
|
509
|
+
[],
|
|
510
|
+
name,
|
|
511
|
+
"schema",
|
|
512
|
+
schemaName,
|
|
513
|
+
"explicit"
|
|
514
|
+
) as TableDefinition<Name, Fields, PrimaryKeyColumns, "schema", SchemaName>,
|
|
515
|
+
options
|
|
516
|
+
)
|
|
436
517
|
})
|
|
437
518
|
|
|
438
519
|
/**
|
|
@@ -462,10 +543,10 @@ export const alias = <
|
|
|
462
543
|
const columns = Object.fromEntries(
|
|
463
544
|
Object.entries(state.fields).map(([key, column]) => [key, bindColumn(aliasName, key, column as AnyColumnDefinition, state.baseName, state.schemaName)])
|
|
464
545
|
) as BoundColumns<AliasName, Fields>
|
|
465
|
-
const aliased = Object.create(TableProto)
|
|
546
|
+
const aliased = attachPipe(Object.create(TableProto))
|
|
466
547
|
aliased.name = aliasName
|
|
467
548
|
aliased.columns = columns
|
|
468
|
-
aliased.schemas =
|
|
549
|
+
aliased.schemas = deriveSchemas(aliasName, state.fields, state.primaryKey)
|
|
469
550
|
aliased[TypeId] = {
|
|
470
551
|
name: aliasName,
|
|
471
552
|
baseName: state.baseName,
|
|
@@ -581,7 +662,7 @@ export function Class<
|
|
|
581
662
|
|
|
582
663
|
/** Declares a table-level primary key. */
|
|
583
664
|
export const primaryKey = <
|
|
584
|
-
Columns extends string | readonly string[]
|
|
665
|
+
const Columns extends string | readonly string[]
|
|
585
666
|
>(
|
|
586
667
|
columns: Columns
|
|
587
668
|
): TableOption<{
|
|
@@ -594,7 +675,7 @@ export const primaryKey = <
|
|
|
594
675
|
|
|
595
676
|
/** Declares a table-level unique constraint. */
|
|
596
677
|
export const unique = <
|
|
597
|
-
Columns extends string | readonly string[]
|
|
678
|
+
const Columns extends string | readonly string[]
|
|
598
679
|
>(
|
|
599
680
|
columns: Columns
|
|
600
681
|
): TableOption<{
|
|
@@ -607,7 +688,7 @@ export const unique = <
|
|
|
607
688
|
|
|
608
689
|
/** Declares a table-level index. */
|
|
609
690
|
export const index = <
|
|
610
|
-
Columns extends string | readonly string[]
|
|
691
|
+
const Columns extends string | readonly string[]
|
|
611
692
|
>(
|
|
612
693
|
columns: Columns
|
|
613
694
|
): TableOption<{
|
|
@@ -620,9 +701,9 @@ export const index = <
|
|
|
620
701
|
|
|
621
702
|
/** Declares a table-level foreign key. */
|
|
622
703
|
export const foreignKey = <
|
|
623
|
-
LocalColumns extends string | readonly string[],
|
|
704
|
+
const LocalColumns extends string | readonly string[],
|
|
624
705
|
TargetTable extends AnyTable,
|
|
625
|
-
TargetColumns extends string | readonly string[]
|
|
706
|
+
const TargetColumns extends string | readonly string[]
|
|
626
707
|
>(
|
|
627
708
|
columns: LocalColumns,
|
|
628
709
|
target: () => TargetTable,
|
|
@@ -650,11 +731,11 @@ export const foreignKey = <
|
|
|
650
731
|
/** Declares a check constraint expression. */
|
|
651
732
|
export const check = <Name extends string>(
|
|
652
733
|
name: Name,
|
|
653
|
-
predicate:
|
|
734
|
+
predicate: DdlExpressionLike
|
|
654
735
|
): TableOption<{
|
|
655
736
|
readonly kind: "check"
|
|
656
737
|
readonly name: Name
|
|
657
|
-
readonly predicate:
|
|
738
|
+
readonly predicate: DdlExpressionLike
|
|
658
739
|
}> => makeOption({
|
|
659
740
|
kind: "check",
|
|
660
741
|
name,
|
package/src/mysql/column.ts
CHANGED
|
@@ -1,24 +1,101 @@
|
|
|
1
|
+
import * as Schema from "effect/Schema"
|
|
2
|
+
|
|
1
3
|
import * as BaseColumn from "../internal/column.js"
|
|
2
|
-
import
|
|
3
|
-
import
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
4
|
+
import { makeColumnDefinition, 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
|
+
type DecimalString,
|
|
11
|
+
type LocalDateString,
|
|
12
|
+
type LocalDateTimeString
|
|
13
|
+
} from "../internal/runtime/value.js"
|
|
14
|
+
import { mysqlDatatypes } from "./datatypes/index.js"
|
|
15
|
+
|
|
16
|
+
const enrichDbType = <Db extends Expression.DbType.Any>(dbType: Db): Db => {
|
|
17
|
+
const candidate = (mysqlDatatypes as unknown as Record<string, (() => Expression.DbType.Any) | undefined>)[dbType.kind]
|
|
18
|
+
return typeof candidate === "function"
|
|
19
|
+
? { ...candidate(), ...dbType } as Db
|
|
20
|
+
: dbType
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
const primitive = <Type, Db extends Expression.DbType.Any>(
|
|
24
|
+
schema: Schema.Schema<Type, any, any>,
|
|
25
|
+
dbType: Db
|
|
26
|
+
): ColumnDefinition<Type, Type, Type, Db, false, false, false, false, false, undefined> =>
|
|
27
|
+
makeColumnDefinition(schema as Schema.Schema<NonNullable<Type>>, {
|
|
28
|
+
dbType,
|
|
29
|
+
nullable: false,
|
|
30
|
+
hasDefault: false,
|
|
31
|
+
generated: false,
|
|
32
|
+
primaryKey: false,
|
|
33
|
+
unique: false,
|
|
34
|
+
references: undefined
|
|
35
|
+
})
|
|
36
|
+
|
|
37
|
+
const renderNumericDdlType = (
|
|
38
|
+
kind: string,
|
|
39
|
+
options?: BaseColumn.NumericOptions
|
|
40
|
+
): string | undefined => {
|
|
41
|
+
if (options === undefined || options.precision === undefined) {
|
|
42
|
+
return undefined
|
|
43
|
+
}
|
|
44
|
+
return options.scale === undefined
|
|
45
|
+
? `${kind}(${options.precision})`
|
|
46
|
+
: `${kind}(${options.precision},${options.scale})`
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
export const custom = <SchemaType extends Schema.Schema.Any, Db extends Expression.DbType.Any>(
|
|
50
|
+
schema: SchemaType,
|
|
51
|
+
dbType: Db
|
|
52
|
+
) =>
|
|
53
|
+
makeColumnDefinition(schema as unknown as Schema.Schema<NonNullable<Schema.Schema.Type<SchemaType>>, any, any>, {
|
|
54
|
+
dbType: enrichDbType(dbType),
|
|
55
|
+
nullable: false,
|
|
56
|
+
hasDefault: false,
|
|
57
|
+
generated: false,
|
|
58
|
+
primaryKey: false,
|
|
59
|
+
unique: false,
|
|
60
|
+
references: undefined,
|
|
61
|
+
ddlType: undefined,
|
|
62
|
+
identity: undefined
|
|
63
|
+
})
|
|
64
|
+
|
|
65
|
+
export const uuid = () => primitive(Schema.UUID, mysqlDatatypes.uuid())
|
|
66
|
+
export const text = () => primitive(Schema.String, mysqlDatatypes.text())
|
|
67
|
+
export const int = () => primitive(Schema.Int, mysqlDatatypes.int())
|
|
68
|
+
export const number = (options?: BaseColumn.NumericOptions) =>
|
|
69
|
+
makeColumnDefinition(DecimalStringSchema, {
|
|
70
|
+
dbType: mysqlDatatypes.decimal(),
|
|
71
|
+
nullable: false,
|
|
72
|
+
hasDefault: false,
|
|
73
|
+
generated: false,
|
|
74
|
+
primaryKey: false,
|
|
75
|
+
unique: false,
|
|
76
|
+
references: undefined,
|
|
77
|
+
ddlType: renderNumericDdlType("decimal", options),
|
|
78
|
+
identity: undefined
|
|
79
|
+
})
|
|
80
|
+
export const boolean = () => primitive(Schema.Boolean, mysqlDatatypes.boolean())
|
|
81
|
+
export const date = () => primitive(LocalDateStringSchema, mysqlDatatypes.date())
|
|
82
|
+
export const datetime = () => primitive(LocalDateTimeStringSchema, mysqlDatatypes.datetime())
|
|
83
|
+
export const timestamp = () => primitive(LocalDateTimeStringSchema, mysqlDatatypes.timestamp())
|
|
84
|
+
export const json = <SchemaType extends Schema.Schema.Any>(schema: SchemaType) =>
|
|
85
|
+
makeColumnDefinition(schema as unknown as Schema.Schema<NonNullable<Schema.Schema.Type<SchemaType>>, any, any>, {
|
|
86
|
+
dbType: { ...mysqlDatatypes.json(), variant: "json" } as Expression.DbType.Json<"mysql", "json">,
|
|
87
|
+
nullable: false,
|
|
88
|
+
hasDefault: false,
|
|
89
|
+
generated: false,
|
|
90
|
+
primaryKey: false,
|
|
91
|
+
unique: false,
|
|
92
|
+
references: undefined,
|
|
93
|
+
ddlType: undefined,
|
|
94
|
+
identity: undefined
|
|
95
|
+
})
|
|
20
96
|
|
|
21
97
|
export const nullable = BaseColumn.nullable
|
|
98
|
+
export const brand = BaseColumn.brand
|
|
22
99
|
export const primaryKey = BaseColumn.primaryKey
|
|
23
100
|
export const unique = BaseColumn.unique
|
|
24
101
|
const default_ = BaseColumn.default_
|
|
@@ -1,6 +1,61 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import
|
|
1
|
+
import type { DatatypeModule } from "../../internal/datatypes/define.js"
|
|
2
|
+
import type * as Expression from "../../internal/scalar.js"
|
|
3
|
+
import { mysqlDatatypeFamilies, mysqlDatatypeKinds } from "./spec.js"
|
|
3
4
|
|
|
4
|
-
|
|
5
|
+
const withMetadata = <Kind extends keyof typeof mysqlDatatypeKinds & string>(
|
|
6
|
+
kind: Kind
|
|
7
|
+
): Expression.DbType.Base<"mysql", Kind> => {
|
|
8
|
+
const kindSpec = mysqlDatatypeKinds[kind]
|
|
9
|
+
const familySpec = mysqlDatatypeFamilies[kindSpec.family as keyof typeof mysqlDatatypeFamilies]
|
|
10
|
+
return {
|
|
11
|
+
dialect: "mysql",
|
|
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 mysqlDatatypeModule = {
|
|
22
|
+
custom: (kind: string) => ({
|
|
23
|
+
dialect: "mysql",
|
|
24
|
+
kind
|
|
25
|
+
}),
|
|
26
|
+
uuid: () => ({
|
|
27
|
+
dialect: "mysql",
|
|
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<"mysql", string>>
|
|
38
|
+
|
|
39
|
+
for (const kind of Object.keys(mysqlDatatypeKinds)) {
|
|
40
|
+
mysqlDatatypeModule[kind] = () => withMetadata(kind as keyof typeof mysqlDatatypeKinds & string)
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
type MysqlUuidWitness = Expression.DbType.Base<"mysql", "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
|
+
export const mysqlDatatypes = mysqlDatatypeModule as DatatypeModule<
|
|
54
|
+
"mysql",
|
|
55
|
+
typeof mysqlDatatypeKinds,
|
|
56
|
+
typeof mysqlDatatypeFamilies
|
|
57
|
+
> & {
|
|
58
|
+
readonly uuid: () => MysqlUuidWitness
|
|
59
|
+
}
|
|
5
60
|
|
|
6
61
|
export type MysqlDatatypeModule = typeof mysqlDatatypes
|