effect-qb 0.17.0 → 0.19.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 +4 -0
- package/dist/index.js +8065 -0
- package/dist/mysql.js +3053 -2505
- package/dist/postgres/metadata.js +1366 -1250
- package/dist/postgres.js +2020 -2719
- package/dist/sqlite.js +3226 -2732
- package/dist/standard.js +8019 -0
- package/package.json +10 -3
- package/src/casing.ts +71 -0
- package/src/index.ts +2 -0
- package/src/internal/casing.ts +89 -0
- package/src/internal/column-state.ts +11 -6
- package/src/internal/column.ts +44 -7
- package/src/internal/datatypes/define.ts +2 -1
- package/src/internal/datatypes/enrich.ts +23 -0
- package/src/internal/datatypes/lookup.ts +14 -7
- package/src/internal/derived-table.ts +4 -36
- package/src/{mysql/internal/sql-expression-renderer.ts → internal/dialect-renderers/mysql.ts} +548 -359
- package/src/{postgres/internal/sql-expression-renderer.ts → internal/dialect-renderers/postgres.ts} +654 -399
- package/src/{sqlite/internal/sql-expression-renderer.ts → internal/dialect-renderers/sqlite.ts} +501 -345
- package/src/internal/dialect.ts +35 -0
- package/src/internal/dsl-mutation-runtime.ts +12 -162
- package/src/internal/dsl-plan-runtime.ts +10 -138
- package/src/internal/dsl-query-runtime.ts +5 -79
- package/src/internal/dsl-transaction-ddl-runtime.ts +41 -65
- package/src/internal/executor.ts +10 -6
- package/src/internal/grouping-key.ts +87 -20
- package/src/internal/implication-runtime.ts +1 -1
- package/src/internal/predicate/runtime.ts +3 -0
- package/src/internal/query.d.ts +38 -11
- package/src/internal/query.ts +64 -25
- package/src/internal/renderer.ts +26 -14
- package/src/internal/runtime/normalize.ts +12 -5
- package/src/internal/scalar.ts +6 -1
- package/src/internal/schema-derivation.d.ts +12 -61
- package/src/internal/schema-derivation.ts +90 -38
- package/src/internal/schema-expression.ts +2 -2
- package/src/internal/sql-expression-renderer.ts +19 -0
- package/src/internal/standard-dsl.ts +6885 -0
- package/src/internal/table-options.ts +126 -66
- package/src/internal/table.d.ts +33 -32
- package/src/internal/table.ts +406 -155
- package/src/mysql/column-extension.ts +3 -0
- package/src/mysql/column.ts +10 -11
- package/src/mysql/datatypes/index.ts +3 -2
- package/src/mysql/executor.ts +7 -5
- package/src/mysql/internal/dialect.ts +9 -4
- package/src/mysql/internal/dsl.ts +219 -155
- package/src/mysql/internal/renderer.ts +6 -2
- package/src/mysql/json.ts +37 -0
- package/src/mysql/query-extension.ts +16 -0
- package/src/mysql/renderer.ts +31 -4
- package/src/mysql.ts +4 -12
- package/src/postgres/column-extension.ts +28 -0
- package/src/postgres/column.ts +5 -11
- package/src/postgres/datatypes/index.d.ts +2 -1
- package/src/postgres/datatypes/index.ts +3 -2
- package/src/postgres/executor.ts +7 -5
- package/src/postgres/function/core.ts +1 -3
- package/src/postgres/function/index.ts +1 -17
- package/src/postgres/internal/dialect.ts +9 -4
- package/src/postgres/internal/dsl.ts +208 -160
- package/src/postgres/internal/renderer.ts +6 -2
- package/src/postgres/internal/schema-ddl.ts +22 -10
- package/src/postgres/internal/schema-model.ts +238 -7
- package/src/postgres/json.ts +43 -7
- package/src/postgres/jsonb.ts +38 -0
- package/src/postgres/query-extension.ts +2 -0
- package/src/postgres/renderer.ts +31 -4
- package/src/postgres/schema-management.ts +17 -12
- package/src/postgres/schema.ts +98 -15
- package/src/postgres/table.ts +193 -524
- package/src/postgres/type.ts +8 -7
- package/src/postgres.ts +9 -11
- package/src/sqlite/column-extension.ts +3 -0
- package/src/sqlite/column.ts +10 -11
- package/src/sqlite/datatypes/index.ts +3 -2
- package/src/sqlite/executor.ts +7 -5
- package/src/sqlite/internal/dialect.ts +9 -4
- package/src/sqlite/internal/dsl.ts +208 -155
- package/src/sqlite/internal/renderer.ts +6 -2
- package/src/sqlite/json.ts +37 -0
- package/src/sqlite/query-extension.ts +2 -0
- package/src/sqlite/renderer.ts +31 -4
- package/src/sqlite.ts +4 -12
- package/src/standard/column.ts +163 -0
- package/src/standard/datatypes/index.ts +83 -0
- package/src/standard/datatypes/spec.ts +98 -0
- package/src/standard/dialect.ts +40 -0
- package/src/standard/function/aggregate.ts +2 -0
- package/src/standard/function/core.ts +2 -0
- package/src/standard/function/index.ts +18 -0
- package/src/standard/function/string.ts +2 -0
- package/src/standard/function/temporal.ts +78 -0
- package/src/standard/function/window.ts +2 -0
- package/src/standard/internal/renderer.ts +45 -0
- package/src/standard/query.ts +152 -0
- package/src/standard/renderer.ts +21 -0
- package/src/standard/table.ts +147 -0
- package/src/standard.ts +18 -0
- package/src/internal/aggregation-validation.ts +0 -57
- package/src/mysql/table.ts +0 -183
- package/src/sqlite/table.ts +0 -183
package/src/internal/table.ts
CHANGED
|
@@ -12,8 +12,10 @@ import {
|
|
|
12
12
|
resolvePrimaryKeyColumns,
|
|
13
13
|
type DdlExpressionLike,
|
|
14
14
|
type IndexKeySpec,
|
|
15
|
+
type LiteralStringInput,
|
|
15
16
|
type MatchingColumnArityInput,
|
|
16
17
|
type NonEmptyColumnInput,
|
|
18
|
+
type NonEmptyStringInput,
|
|
17
19
|
type NormalizeColumns,
|
|
18
20
|
type ReferentialAction,
|
|
19
21
|
type TableOptionSpec,
|
|
@@ -24,12 +26,16 @@ import {
|
|
|
24
26
|
validateOptions
|
|
25
27
|
} from "./table-options.js"
|
|
26
28
|
import {
|
|
27
|
-
|
|
29
|
+
deriveInsertSchema,
|
|
30
|
+
deriveSelectSchema,
|
|
31
|
+
deriveUpdateSchema,
|
|
28
32
|
type InsertRow,
|
|
29
33
|
type SelectRow,
|
|
30
34
|
type TableFieldMap,
|
|
35
|
+
type TableSchemaVariant,
|
|
31
36
|
type UpdateRow
|
|
32
37
|
} from "./schema-derivation.js"
|
|
38
|
+
import * as Casing from "./casing.js"
|
|
33
39
|
|
|
34
40
|
/** Symbol used to attach table-definition metadata. */
|
|
35
41
|
export const TypeId: unique symbol = Symbol.for("effect-qb/Table")
|
|
@@ -39,15 +45,22 @@ export const OptionsSymbol: unique symbol = Symbol.for("effect-qb/Table/normaliz
|
|
|
39
45
|
export const options: unique symbol = Symbol.for("effect-qb/Table/declaredOptions")
|
|
40
46
|
|
|
41
47
|
const CacheSymbol: unique symbol = Symbol.for("effect-qb/Table/cache")
|
|
48
|
+
const SchemaCacheSymbol: unique symbol = Symbol.for("effect-qb/Table/schemaCache")
|
|
42
49
|
const DeclaredOptionsSymbol: unique symbol = Symbol.for("effect-qb/Table/factoryDeclaredOptions")
|
|
43
50
|
|
|
44
51
|
type InlinePrimaryKeyKeys<Fields extends TableFieldMap> = Extract<{
|
|
45
52
|
[K in keyof Fields]: Fields[K]["metadata"]["primaryKey"] extends true ? K : never
|
|
46
53
|
}[keyof Fields], string>
|
|
47
54
|
|
|
48
|
-
type
|
|
55
|
+
type FieldDialects<Fields extends TableFieldMap> = Fields[keyof Fields][typeof import("./column-state.js").ColumnTypeId]["dbType"]["dialect"]
|
|
56
|
+
type ConcreteFieldDialects<Fields extends TableFieldMap> = Exclude<FieldDialects<Fields>, "standard">
|
|
57
|
+
type TableDialect<Fields extends TableFieldMap> = [ConcreteFieldDialects<Fields>] extends [never]
|
|
58
|
+
? "standard"
|
|
59
|
+
: ConcreteFieldDialects<Fields>
|
|
49
60
|
type TableKind = "schema" | "alias"
|
|
50
61
|
type DefaultSchemaName = "public"
|
|
62
|
+
type NonEmptyFieldMap<Fields extends TableFieldMap> =
|
|
63
|
+
string extends keyof Fields ? Fields : "" extends keyof Fields ? never : Fields
|
|
51
64
|
type FieldColumnName<Fields extends TableFieldMap> = Extract<keyof Fields, string>
|
|
52
65
|
type FieldColumnList<Fields extends TableFieldMap> = readonly [FieldColumnName<Fields>, ...FieldColumnName<Fields>[]]
|
|
53
66
|
type FieldIndexKeySpec<Fields extends TableFieldMap> =
|
|
@@ -74,43 +87,79 @@ interface TableOptionBuilderLike<
|
|
|
74
87
|
|
|
75
88
|
type ClassTableOption<Fields extends TableFieldMap> = TableOptionBuilderLike<ClassOptionSpec<Fields>>
|
|
76
89
|
type ClassDeclaredTableOptions<Fields extends TableFieldMap> = readonly ClassTableOption<Fields>[]
|
|
90
|
+
type TableNameOf<Table extends TableDefinition<any, any, any, "schema", any>> =
|
|
91
|
+
Table extends TableDefinition<infer Name, any, any, "schema", any> ? Name : never
|
|
92
|
+
type TableFieldsOf<Table extends TableDefinition<any, any, any, "schema", any>> =
|
|
93
|
+
Table extends TableDefinition<any, infer Fields, any, "schema", any> ? Fields : never
|
|
94
|
+
type TablePrimaryKeyOf<Table extends TableDefinition<any, any, any, "schema", any>> =
|
|
95
|
+
Table extends TableDefinition<any, any, infer PrimaryKeyColumns, "schema", any> ? PrimaryKeyColumns : never
|
|
96
|
+
type TableSchemaNameOf<Table extends TableDefinition<any, any, any, "schema", any>> =
|
|
97
|
+
Table extends TableDefinition<any, any, any, "schema", infer SchemaName> ? SchemaName : never
|
|
77
98
|
|
|
78
99
|
type BuildPrimaryKey<
|
|
79
100
|
Table extends TableDefinition<any, any, any, "schema", any>,
|
|
80
101
|
Spec extends TableOptionSpec
|
|
81
102
|
> = Spec extends { readonly kind: "primaryKey"; readonly columns: infer Columns extends readonly string[] }
|
|
82
|
-
? Columns[number] & keyof Table
|
|
83
|
-
: Table
|
|
103
|
+
? Columns[number] & keyof TableFieldsOf<Table> & string
|
|
104
|
+
: TablePrimaryKeyOf<Table>
|
|
84
105
|
|
|
85
|
-
type
|
|
106
|
+
type OptionInputConstraint<
|
|
86
107
|
Table extends TableDefinition<any, any, any, "schema", any>,
|
|
87
108
|
Spec extends TableOptionSpec
|
|
88
109
|
> = Spec extends { readonly kind: "primaryKey"; readonly columns: infer Columns extends readonly string[] }
|
|
89
|
-
? ValidatePrimaryKeyColumns<Table[typeof TypeId]["fields"], Columns> extends never ? never :
|
|
110
|
+
? ValidatePrimaryKeyColumns<Table[typeof TypeId]["fields"], Columns> extends never ? never : unknown
|
|
90
111
|
: Spec extends { readonly kind: "index" }
|
|
91
|
-
? ValidateIndexOptionColumns<Table[typeof TypeId]["fields"], Spec> extends never ? never :
|
|
112
|
+
? ValidateIndexOptionColumns<Table[typeof TypeId]["fields"], Spec> extends never ? never : unknown
|
|
92
113
|
: Spec extends { readonly kind: "foreignKey" }
|
|
93
|
-
? ValidateForeignKeyOptionColumns<Table[typeof TypeId]["fields"], Spec> extends never ? never :
|
|
114
|
+
? ValidateForeignKeyOptionColumns<Table[typeof TypeId]["fields"], Spec> extends never ? never : unknown
|
|
94
115
|
: Spec extends { readonly columns: infer Columns extends readonly string[] }
|
|
95
|
-
? ValidateKnownColumns<Table[typeof TypeId]["fields"], Columns> extends never ? never :
|
|
96
|
-
:
|
|
116
|
+
? ValidateKnownColumns<Table[typeof TypeId]["fields"], Columns> extends never ? never : unknown
|
|
117
|
+
: unknown
|
|
118
|
+
|
|
119
|
+
type OptionInputTable<
|
|
120
|
+
Table extends TableDefinition<any, any, any, "schema", any>,
|
|
121
|
+
Spec extends TableOptionSpec
|
|
122
|
+
> = Table & OptionInputConstraint<Table, Spec>
|
|
123
|
+
|
|
124
|
+
type OptionValidationArgs<
|
|
125
|
+
Table extends TableDefinition<any, any, any, "schema", any>,
|
|
126
|
+
Spec extends TableOptionSpec
|
|
127
|
+
> = OptionInputConstraint<Table, Spec> extends never ? [never] : []
|
|
97
128
|
|
|
98
129
|
type ApplyOption<
|
|
99
130
|
Table extends TableDefinition<any, any, any, "schema", any>,
|
|
100
131
|
Spec extends TableOptionSpec
|
|
101
132
|
> = Spec extends { readonly kind: "primaryKey" }
|
|
102
133
|
? TableDefinition<
|
|
103
|
-
Table
|
|
104
|
-
Table
|
|
134
|
+
TableNameOf<Table>,
|
|
135
|
+
TableFieldsOf<Table>,
|
|
105
136
|
BuildPrimaryKey<Table, Spec>,
|
|
106
|
-
"schema"
|
|
107
|
-
|
|
108
|
-
: TableDefinition<
|
|
109
|
-
Table[typeof TypeId]["name"],
|
|
110
|
-
Table[typeof TypeId]["fields"],
|
|
111
|
-
Table[typeof TypeId]["primaryKey"][number],
|
|
112
|
-
"schema"
|
|
137
|
+
"schema",
|
|
138
|
+
TableSchemaNameOf<Table>
|
|
113
139
|
>
|
|
140
|
+
: Table
|
|
141
|
+
|
|
142
|
+
type ApplyTableOption<
|
|
143
|
+
Table extends TableDefinition<any, any, any, "schema", any>,
|
|
144
|
+
Spec extends TableOptionSpec
|
|
145
|
+
> = Spec extends { readonly kind: "primaryKey" }
|
|
146
|
+
? ApplyOption<Table, Spec>
|
|
147
|
+
: Table
|
|
148
|
+
|
|
149
|
+
type TableOptionPipe<
|
|
150
|
+
Name extends string,
|
|
151
|
+
Fields extends TableFieldMap,
|
|
152
|
+
PrimaryKeyColumns extends keyof Fields & string,
|
|
153
|
+
Kind extends TableKind,
|
|
154
|
+
SchemaName extends string | undefined
|
|
155
|
+
> = Kind extends "schema"
|
|
156
|
+
? {
|
|
157
|
+
pipe<Spec extends TableOptionSpec>(
|
|
158
|
+
option: TableOption<Spec>,
|
|
159
|
+
...validation: OptionValidationArgs<TableDefinition<Name, Fields, PrimaryKeyColumns, "schema", SchemaName>, Spec>
|
|
160
|
+
): ApplyTableOption<TableDefinition<Name, Fields, PrimaryKeyColumns, "schema", SchemaName>, Spec>
|
|
161
|
+
}
|
|
162
|
+
: {}
|
|
114
163
|
|
|
115
164
|
export type ValidateDeclaredOptions<
|
|
116
165
|
Table extends TableDefinition<any, any, any, "schema", any>,
|
|
@@ -153,6 +202,20 @@ export interface TableSchemas<
|
|
|
153
202
|
readonly update: Schema.Schema<UpdateRow<Name, Fields, PrimaryKeyColumns>>
|
|
154
203
|
}
|
|
155
204
|
|
|
205
|
+
type AnyTableSchemas = {
|
|
206
|
+
readonly select: Schema.Schema<any>
|
|
207
|
+
readonly insert: Schema.Schema<any>
|
|
208
|
+
readonly update: Schema.Schema<any>
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
type TableSchemaCache<
|
|
212
|
+
Name extends string,
|
|
213
|
+
Fields extends TableFieldMap,
|
|
214
|
+
PrimaryKeyColumns extends keyof Fields & string
|
|
215
|
+
> = Partial<TableSchemas<Name, Fields, PrimaryKeyColumns>> & {
|
|
216
|
+
schemas?: TableSchemas<Name, Fields, PrimaryKeyColumns>
|
|
217
|
+
}
|
|
218
|
+
|
|
156
219
|
interface TableState<
|
|
157
220
|
Name extends string,
|
|
158
221
|
Fields extends TableFieldMap,
|
|
@@ -166,25 +229,14 @@ interface TableState<
|
|
|
166
229
|
readonly fields: Fields
|
|
167
230
|
readonly primaryKey: readonly PrimaryKeyColumns[]
|
|
168
231
|
readonly kind: Kind
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
/** Namespace-scoped table builder. */
|
|
172
|
-
export interface TableSchemaNamespace<SchemaName extends string> {
|
|
173
|
-
readonly schemaName: SchemaName
|
|
174
|
-
readonly table: <
|
|
175
|
-
Name extends string,
|
|
176
|
-
Fields extends TableFieldMap,
|
|
177
|
-
const Options extends DeclaredTableOptions,
|
|
178
|
-
PrimaryKeyColumns extends keyof Fields & string = InlinePrimaryKeyKeys<Fields>
|
|
179
|
-
>(
|
|
180
|
-
name: Name,
|
|
181
|
-
fields: Fields,
|
|
182
|
-
...options: Options & ValidateDeclaredOptions<TableDefinition<Name, Fields, PrimaryKeyColumns, "schema", SchemaName>, Options>
|
|
183
|
-
) => ApplyDeclaredOptions<TableDefinition<Name, Fields, PrimaryKeyColumns, "schema", SchemaName>, Options>
|
|
232
|
+
readonly casing?: Casing.Options
|
|
184
233
|
}
|
|
185
234
|
|
|
186
235
|
export type DeclaredTableOptions = readonly TableOptionBuilderLike[]
|
|
187
|
-
export type { DdlExpressionLike, IndexKeySpec, MatchingColumnArityInput, NonEmptyColumnInput, NormalizeColumns, ReferentialAction } from "./table-options.js"
|
|
236
|
+
export type { DdlExpressionLike, IndexKeySpec, LiteralStringInput, MatchingColumnArityInput, NonEmptyColumnInput, NonEmptyStringInput, NormalizeColumns, ReferentialAction } from "./table-options.js"
|
|
237
|
+
export type { NonEmptyFieldMap }
|
|
238
|
+
export type NonEmptySchemaNameInput<Value extends string | undefined> =
|
|
239
|
+
Value extends string ? NonEmptyStringInput<Value> : Value
|
|
188
240
|
|
|
189
241
|
export type TableDefinition<
|
|
190
242
|
Name extends string,
|
|
@@ -192,10 +244,10 @@ export type TableDefinition<
|
|
|
192
244
|
PrimaryKeyColumns extends keyof Fields & string = InlinePrimaryKeyKeys<Fields>,
|
|
193
245
|
Kind extends TableKind = "schema",
|
|
194
246
|
SchemaName extends string | undefined = DefaultSchemaName
|
|
195
|
-
> = Pipeable & {
|
|
247
|
+
> = TableOptionPipe<Name, Fields, PrimaryKeyColumns, Kind, SchemaName> & Pipeable & {
|
|
196
248
|
readonly name: Name
|
|
197
249
|
readonly columns: BoundColumns<Name, Fields>
|
|
198
|
-
readonly schemas: TableSchemas<Name, Fields, PrimaryKeyColumns>
|
|
250
|
+
readonly schemas: TableSchemas<Name, Fields, PrimaryKeyColumns> & AnyTableSchemas
|
|
199
251
|
readonly [TypeId]: TableState<Name, Fields, PrimaryKeyColumns, Kind, SchemaName>
|
|
200
252
|
readonly [Plan.TypeId]: Plan.State<
|
|
201
253
|
BoundColumns<Name, Fields>,
|
|
@@ -245,32 +297,37 @@ export type TableClassStatic<
|
|
|
245
297
|
>
|
|
246
298
|
|
|
247
299
|
/** Minimal structural table-like contract used across helper APIs. */
|
|
248
|
-
export type AnyTable
|
|
300
|
+
export type AnyTable<Dialect extends string = string> = {
|
|
301
|
+
readonly [TypeId]: TableState<string, TableFieldMap, string, TableKind, string | undefined>
|
|
302
|
+
readonly [OptionsSymbol]: readonly TableOptionSpec[]
|
|
303
|
+
} & Plan.RowSet<any, any, Record<string, Plan.AnySource>, Dialect>
|
|
249
304
|
|
|
250
|
-
type FieldsOfAnyTable<Table extends AnyTable> = Table
|
|
251
|
-
? Fields
|
|
252
|
-
: Table extends TableClassStatic<any, infer Fields extends TableFieldMap, any, any>
|
|
253
|
-
? Fields
|
|
254
|
-
: never
|
|
305
|
+
type FieldsOfAnyTable<Table extends AnyTable> = Table[typeof TypeId]["fields"]
|
|
255
306
|
|
|
256
307
|
type ColumnNamesOfAnyTable<Table extends AnyTable> = Extract<keyof FieldsOfAnyTable<Table>, string>
|
|
257
308
|
|
|
258
309
|
/** Public table-option builder type used by `Table.index`, `Table.primaryKey`, and friends. */
|
|
259
310
|
export type TableOption<
|
|
260
311
|
Spec extends TableOptionSpec = TableOptionSpec
|
|
261
|
-
> = {
|
|
262
|
-
|
|
263
|
-
Name extends string,
|
|
264
|
-
Fields extends TableFieldMap,
|
|
265
|
-
PrimaryKeyColumns extends keyof Fields & string
|
|
266
|
-
>(
|
|
267
|
-
table: OptionInputTable<TableDefinition<Name, Fields, PrimaryKeyColumns, "schema", any>, Spec>
|
|
268
|
-
): ApplyOption<TableDefinition<Name, Fields, PrimaryKeyColumns, "schema", any>, Spec>
|
|
312
|
+
> = Pipeable & {
|
|
313
|
+
readonly pipe: Pipeable["pipe"]
|
|
269
314
|
readonly option: Spec
|
|
270
|
-
}
|
|
315
|
+
} & (Spec extends { readonly kind: "primaryKey" }
|
|
316
|
+
? {
|
|
317
|
+
<Table extends TableDefinition<any, any, any, "schema", any>>(
|
|
318
|
+
table: Table,
|
|
319
|
+
...validation: OptionValidationArgs<Table, Spec>
|
|
320
|
+
): ApplyOption<Table, Spec>
|
|
321
|
+
}
|
|
322
|
+
: {
|
|
323
|
+
<Table extends TableDefinition<any, any, any, "schema", any>>(
|
|
324
|
+
table: Table,
|
|
325
|
+
...validation: OptionValidationArgs<Table, Spec>
|
|
326
|
+
): Table
|
|
327
|
+
})
|
|
271
328
|
|
|
272
329
|
const TableProto = {
|
|
273
|
-
pipe(this:
|
|
330
|
+
pipe(this: Pipeable) {
|
|
274
331
|
return pipeArguments(this, arguments)
|
|
275
332
|
}
|
|
276
333
|
}
|
|
@@ -279,7 +336,7 @@ const attachPipe = <Value extends object>(value: Value): Value => {
|
|
|
279
336
|
Object.defineProperty(value, "pipe", {
|
|
280
337
|
configurable: true,
|
|
281
338
|
writable: true,
|
|
282
|
-
value: function(this:
|
|
339
|
+
value: function(this: Value) {
|
|
283
340
|
return pipeArguments(value, arguments)
|
|
284
341
|
}
|
|
285
342
|
})
|
|
@@ -292,7 +349,6 @@ type BuildArtifacts<
|
|
|
292
349
|
PrimaryKeyColumns extends keyof Fields & string
|
|
293
350
|
> = {
|
|
294
351
|
readonly columns: BoundColumns<Name, Fields>
|
|
295
|
-
readonly schemas: TableSchemas<Name, Fields, PrimaryKeyColumns>
|
|
296
352
|
readonly normalizedOptions: readonly TableOptionSpec[]
|
|
297
353
|
readonly primaryKey: readonly PrimaryKeyColumns[]
|
|
298
354
|
}
|
|
@@ -305,24 +361,159 @@ const buildArtifacts = <
|
|
|
305
361
|
name: Name,
|
|
306
362
|
fields: Fields,
|
|
307
363
|
declaredOptions: readonly TableOptionSpec[],
|
|
308
|
-
schemaName: SchemaName
|
|
364
|
+
schemaName: SchemaName,
|
|
365
|
+
casing?: Casing.Options
|
|
309
366
|
): BuildArtifacts<Name, Fields, keyof Fields & string> => {
|
|
310
367
|
const normalizedOptions = [...collectInlineOptions(fields), ...declaredOptions]
|
|
311
368
|
validateFieldDialects(name, fields)
|
|
312
369
|
validateOptions(name, fields, declaredOptions)
|
|
313
370
|
const primaryKey = resolvePrimaryKeyColumns(fields, declaredOptions) as readonly (keyof Fields & string)[]
|
|
314
371
|
const columns = Object.fromEntries(
|
|
315
|
-
Object.entries(fields).map(([key, column]) => [key, bindColumn(name, key, column, name, schemaName)])
|
|
372
|
+
Object.entries(fields).map(([key, column]) => [key, bindColumn(name, key, column, name, schemaName, casing)])
|
|
316
373
|
) as BoundColumns<Name, Fields>
|
|
317
|
-
const schemas = deriveSchemas(name, fields, primaryKey)
|
|
318
374
|
return {
|
|
319
375
|
columns,
|
|
320
|
-
schemas,
|
|
321
376
|
normalizedOptions,
|
|
322
377
|
primaryKey
|
|
323
378
|
}
|
|
324
379
|
}
|
|
325
380
|
|
|
381
|
+
const getSchemaCache = <
|
|
382
|
+
Name extends string,
|
|
383
|
+
Fields extends TableFieldMap,
|
|
384
|
+
PrimaryKeyColumns extends keyof Fields & string
|
|
385
|
+
>(
|
|
386
|
+
table: TableDefinition<Name, Fields, PrimaryKeyColumns, any, any> | TableClassStatic<Name, Fields, PrimaryKeyColumns, any>
|
|
387
|
+
): TableSchemaCache<Name, Fields, PrimaryKeyColumns> => {
|
|
388
|
+
const target = table as {
|
|
389
|
+
[SchemaCacheSymbol]?: TableSchemaCache<Name, Fields, PrimaryKeyColumns>
|
|
390
|
+
}
|
|
391
|
+
if (target[SchemaCacheSymbol] !== undefined) {
|
|
392
|
+
return target[SchemaCacheSymbol]
|
|
393
|
+
}
|
|
394
|
+
const cache: TableSchemaCache<Name, Fields, PrimaryKeyColumns> = {}
|
|
395
|
+
Object.defineProperty(table, SchemaCacheSymbol, {
|
|
396
|
+
configurable: true,
|
|
397
|
+
value: cache
|
|
398
|
+
})
|
|
399
|
+
return cache
|
|
400
|
+
}
|
|
401
|
+
|
|
402
|
+
const deriveTableSchema = <
|
|
403
|
+
Variant extends TableSchemaVariant,
|
|
404
|
+
Name extends string,
|
|
405
|
+
Fields extends TableFieldMap,
|
|
406
|
+
PrimaryKeyColumns extends keyof Fields & string
|
|
407
|
+
>(
|
|
408
|
+
table: TableDefinition<Name, Fields, PrimaryKeyColumns, any, any> | TableClassStatic<Name, Fields, PrimaryKeyColumns, any>,
|
|
409
|
+
variant: Variant
|
|
410
|
+
): TableSchemas<Name, Fields, PrimaryKeyColumns>[Variant] => {
|
|
411
|
+
const state = table[TypeId]
|
|
412
|
+
switch (variant) {
|
|
413
|
+
case "select":
|
|
414
|
+
return deriveSelectSchema(state.name, state.fields, state.primaryKey) as TableSchemas<Name, Fields, PrimaryKeyColumns>[Variant]
|
|
415
|
+
case "insert":
|
|
416
|
+
return deriveInsertSchema(state.name, state.fields, state.primaryKey) as TableSchemas<Name, Fields, PrimaryKeyColumns>[Variant]
|
|
417
|
+
case "update":
|
|
418
|
+
return deriveUpdateSchema(state.name, state.fields, state.primaryKey) as TableSchemas<Name, Fields, PrimaryKeyColumns>[Variant]
|
|
419
|
+
}
|
|
420
|
+
}
|
|
421
|
+
|
|
422
|
+
const schemaFor = <
|
|
423
|
+
Variant extends TableSchemaVariant,
|
|
424
|
+
Name extends string,
|
|
425
|
+
Fields extends TableFieldMap,
|
|
426
|
+
PrimaryKeyColumns extends keyof Fields & string
|
|
427
|
+
>(
|
|
428
|
+
table: TableDefinition<Name, Fields, PrimaryKeyColumns, any, any> | TableClassStatic<Name, Fields, PrimaryKeyColumns, any>,
|
|
429
|
+
variant: Variant
|
|
430
|
+
): TableSchemas<Name, Fields, PrimaryKeyColumns>[Variant] => {
|
|
431
|
+
const cache = getSchemaCache(table)
|
|
432
|
+
const cached = cache[variant]
|
|
433
|
+
if (cached !== undefined) {
|
|
434
|
+
return cached as TableSchemas<Name, Fields, PrimaryKeyColumns>[Variant]
|
|
435
|
+
}
|
|
436
|
+
const schema = deriveTableSchema(table, variant)
|
|
437
|
+
cache[variant] = schema as any
|
|
438
|
+
return schema
|
|
439
|
+
}
|
|
440
|
+
|
|
441
|
+
export function selectSchema<
|
|
442
|
+
Name extends string,
|
|
443
|
+
Fields extends TableFieldMap,
|
|
444
|
+
PrimaryKeyColumns extends keyof Fields & string
|
|
445
|
+
>(
|
|
446
|
+
table: TableDefinition<Name, Fields, PrimaryKeyColumns, any, any> | TableClassStatic<Name, Fields, PrimaryKeyColumns, any>
|
|
447
|
+
): Schema.Schema<SelectRow<Name, Fields>> {
|
|
448
|
+
return schemaFor(table, "select") as Schema.Schema<SelectRow<Name, Fields>>
|
|
449
|
+
}
|
|
450
|
+
|
|
451
|
+
export function insertSchema<
|
|
452
|
+
Name extends string,
|
|
453
|
+
Fields extends TableFieldMap,
|
|
454
|
+
PrimaryKeyColumns extends keyof Fields & string
|
|
455
|
+
>(
|
|
456
|
+
table: TableDefinition<Name, Fields, PrimaryKeyColumns, any, any> | TableClassStatic<Name, Fields, PrimaryKeyColumns, any>
|
|
457
|
+
): Schema.Schema<InsertRow<Name, Fields>> {
|
|
458
|
+
return schemaFor(table, "insert") as Schema.Schema<InsertRow<Name, Fields>>
|
|
459
|
+
}
|
|
460
|
+
|
|
461
|
+
export function updateSchema<
|
|
462
|
+
Name extends string,
|
|
463
|
+
Fields extends TableFieldMap,
|
|
464
|
+
PrimaryKeyColumns extends keyof Fields & string
|
|
465
|
+
>(
|
|
466
|
+
table: TableDefinition<Name, Fields, PrimaryKeyColumns, any, any> | TableClassStatic<Name, Fields, PrimaryKeyColumns, any>
|
|
467
|
+
): Schema.Schema<UpdateRow<Name, Fields, PrimaryKeyColumns>> {
|
|
468
|
+
return schemaFor(table, "update") as Schema.Schema<UpdateRow<Name, Fields, PrimaryKeyColumns>>
|
|
469
|
+
}
|
|
470
|
+
|
|
471
|
+
const schemasFor = <
|
|
472
|
+
Name extends string,
|
|
473
|
+
Fields extends TableFieldMap,
|
|
474
|
+
PrimaryKeyColumns extends keyof Fields & string
|
|
475
|
+
>(
|
|
476
|
+
table: TableDefinition<Name, Fields, PrimaryKeyColumns, any, any> | TableClassStatic<Name, Fields, PrimaryKeyColumns, any>
|
|
477
|
+
): TableSchemas<Name, Fields, PrimaryKeyColumns> => {
|
|
478
|
+
const cache = getSchemaCache(table)
|
|
479
|
+
if (cache.schemas !== undefined) {
|
|
480
|
+
return cache.schemas
|
|
481
|
+
}
|
|
482
|
+
const schemas = {} as TableSchemas<Name, Fields, PrimaryKeyColumns>
|
|
483
|
+
Object.defineProperties(schemas, {
|
|
484
|
+
select: {
|
|
485
|
+
enumerable: true,
|
|
486
|
+
get: () => selectSchema(table)
|
|
487
|
+
},
|
|
488
|
+
insert: {
|
|
489
|
+
enumerable: true,
|
|
490
|
+
get: () => insertSchema(table)
|
|
491
|
+
},
|
|
492
|
+
update: {
|
|
493
|
+
enumerable: true,
|
|
494
|
+
get: () => updateSchema(table)
|
|
495
|
+
}
|
|
496
|
+
})
|
|
497
|
+
cache.schemas = schemas
|
|
498
|
+
return schemas
|
|
499
|
+
}
|
|
500
|
+
|
|
501
|
+
const defineSchemasGetter = <
|
|
502
|
+
Name extends string,
|
|
503
|
+
Fields extends TableFieldMap,
|
|
504
|
+
PrimaryKeyColumns extends keyof Fields & string
|
|
505
|
+
>(
|
|
506
|
+
table: TableDefinition<Name, Fields, PrimaryKeyColumns, any, any>
|
|
507
|
+
): void => {
|
|
508
|
+
Object.defineProperty(table, "schemas", {
|
|
509
|
+
configurable: true,
|
|
510
|
+
enumerable: true,
|
|
511
|
+
get() {
|
|
512
|
+
return schemasFor(table)
|
|
513
|
+
}
|
|
514
|
+
})
|
|
515
|
+
}
|
|
516
|
+
|
|
326
517
|
const makeTable = <
|
|
327
518
|
Name extends string,
|
|
328
519
|
Fields extends TableFieldMap,
|
|
@@ -336,24 +527,26 @@ const makeTable = <
|
|
|
336
527
|
baseName: string = name,
|
|
337
528
|
kind: Kind = "schema" as Kind,
|
|
338
529
|
schemaName?: SchemaName,
|
|
339
|
-
schemaMode: "default" | "explicit" = "default"
|
|
530
|
+
schemaMode: "default" | "explicit" = "default",
|
|
531
|
+
casing?: Casing.Options
|
|
340
532
|
): TableDefinition<Name, Fields, PrimaryKeyColumns, Kind, SchemaName> => {
|
|
341
533
|
const resolvedSchemaName = schemaMode === "explicit"
|
|
342
534
|
? schemaName
|
|
343
535
|
: ("public" as SchemaName)
|
|
344
|
-
const artifacts = buildArtifacts(name, fields, declaredOptions, resolvedSchemaName)
|
|
536
|
+
const artifacts = buildArtifacts(name, fields, declaredOptions, resolvedSchemaName, casing)
|
|
345
537
|
const dialect = resolveFieldDialect(fields)
|
|
346
538
|
const table = attachPipe(Object.create(TableProto))
|
|
347
539
|
table.name = name
|
|
348
540
|
table.columns = artifacts.columns
|
|
349
|
-
table
|
|
541
|
+
defineSchemasGetter(table)
|
|
350
542
|
table[TypeId] = {
|
|
351
543
|
name,
|
|
352
544
|
baseName,
|
|
353
545
|
schemaName: resolvedSchemaName,
|
|
354
546
|
fields,
|
|
355
547
|
primaryKey: artifacts.primaryKey,
|
|
356
|
-
kind
|
|
548
|
+
kind,
|
|
549
|
+
casing
|
|
357
550
|
}
|
|
358
551
|
table[Plan.TypeId] = {
|
|
359
552
|
selection: artifacts.columns,
|
|
@@ -400,23 +593,17 @@ const applyDeclaredOptions = <
|
|
|
400
593
|
) as unknown as Table
|
|
401
594
|
}
|
|
402
595
|
|
|
403
|
-
const validateClassOptions = (declaredOptions: readonly TableOptionSpec[]): void => {
|
|
404
|
-
for (const option of declaredOptions) {
|
|
405
|
-
if (option.kind === "primaryKey") {
|
|
406
|
-
throw new Error("Table.Class does not support table-level primary keys; declare primary keys inline on columns")
|
|
407
|
-
}
|
|
408
|
-
}
|
|
409
|
-
}
|
|
410
|
-
|
|
411
596
|
const resolveFieldDialect = (fields: TableFieldMap): string => {
|
|
412
597
|
const dialects = [...new Set(Object.values(fields).map((field) => field.metadata.dbType.dialect))]
|
|
413
598
|
if (dialects.length === 0) {
|
|
414
599
|
throw new Error("Cannot infer table dialect from an empty field set")
|
|
415
600
|
}
|
|
416
|
-
|
|
601
|
+
const concreteDialects = dialects.filter((dialect) => dialect !== "standard")
|
|
602
|
+
const uniqueConcreteDialects = [...new Set(concreteDialects)]
|
|
603
|
+
if (uniqueConcreteDialects.length > 1) {
|
|
417
604
|
throw new Error(`Mixed table dialects are not supported: ${dialects.join(", ")}`)
|
|
418
605
|
}
|
|
419
|
-
return
|
|
606
|
+
return uniqueConcreteDialects[0] ?? "standard"
|
|
420
607
|
}
|
|
421
608
|
|
|
422
609
|
const validateFieldDialects = (tableName: string, fields: TableFieldMap): void => {
|
|
@@ -442,7 +629,6 @@ const ensureClassArtifacts = <
|
|
|
442
629
|
}
|
|
443
630
|
const state = self[TypeId]
|
|
444
631
|
const classOptions = self[options]
|
|
445
|
-
validateClassOptions(extractDeclaredOptions(classOptions))
|
|
446
632
|
const table = applyDeclaredOptions(
|
|
447
633
|
makeTable(
|
|
448
634
|
state.name,
|
|
@@ -451,13 +637,13 @@ const ensureClassArtifacts = <
|
|
|
451
637
|
state.name,
|
|
452
638
|
"schema",
|
|
453
639
|
state.schemaName,
|
|
454
|
-
state.schemaName === undefined || state.schemaName === "public" ? "default" : "explicit"
|
|
640
|
+
state.schemaName === undefined || state.schemaName === "public" ? "default" : "explicit",
|
|
641
|
+
state.casing
|
|
455
642
|
) as TableDefinition<Name, Fields, PrimaryKeyColumns, "schema", typeof state.schemaName>,
|
|
456
643
|
classOptions
|
|
457
644
|
)
|
|
458
645
|
const artifacts = {
|
|
459
646
|
columns: table.columns,
|
|
460
|
-
schemas: table.schemas,
|
|
461
647
|
normalizedOptions: table[OptionsSymbol],
|
|
462
648
|
primaryKey: table[TypeId].primaryKey as readonly PrimaryKeyColumns[]
|
|
463
649
|
} satisfies BuildArtifacts<Name, Fields, PrimaryKeyColumns>
|
|
@@ -476,9 +662,6 @@ const appendOption = <
|
|
|
476
662
|
option: Spec
|
|
477
663
|
): ApplyOption<Table, Spec> => {
|
|
478
664
|
const state = table[TypeId]
|
|
479
|
-
if (state.kind !== "schema") {
|
|
480
|
-
throw new Error("Table options can only be applied to schema tables, not aliased query sources")
|
|
481
|
-
}
|
|
482
665
|
return makeTable(
|
|
483
666
|
state.name,
|
|
484
667
|
state.fields,
|
|
@@ -486,25 +669,37 @@ const appendOption = <
|
|
|
486
669
|
state.baseName,
|
|
487
670
|
state.kind,
|
|
488
671
|
state.schemaName,
|
|
489
|
-
"explicit"
|
|
672
|
+
"explicit",
|
|
673
|
+
state.casing
|
|
490
674
|
) as unknown as ApplyOption<Table, Spec>
|
|
491
675
|
}
|
|
492
676
|
|
|
493
677
|
const makeOption = <Spec extends TableOptionSpec>(option: Spec): TableOption<Spec> => {
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
|
|
678
|
+
return attachPipe(Object.assign(
|
|
679
|
+
<Table extends TableDefinition<any, any, any, "schema", any>>(
|
|
680
|
+
table: Table,
|
|
681
|
+
..._validation: OptionValidationArgs<Table, Spec>
|
|
682
|
+
): ApplyTableOption<Table, Spec> =>
|
|
683
|
+
appendOption(table, option) as unknown as ApplyTableOption<Table, Spec>,
|
|
684
|
+
{ option }
|
|
685
|
+
)) as TableOption<Spec>
|
|
498
686
|
}
|
|
499
687
|
|
|
500
688
|
const makeResolvedOption = <Spec extends TableOptionSpec>(
|
|
501
689
|
option: Spec,
|
|
502
690
|
resolve: (table: TableDefinition<any, any, any, "schema", any>) => Spec
|
|
503
691
|
): TableOption<Spec> => {
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
|
|
692
|
+
return attachPipe(Object.assign(
|
|
693
|
+
<Table extends TableDefinition<any, any, any, "schema", any>>(
|
|
694
|
+
table: Table,
|
|
695
|
+
..._validation: OptionValidationArgs<Table, Spec>
|
|
696
|
+
): ApplyTableOption<Table, Spec> =>
|
|
697
|
+
appendOption(
|
|
698
|
+
table,
|
|
699
|
+
resolve(table)
|
|
700
|
+
) as unknown as ApplyTableOption<Table, Spec>,
|
|
701
|
+
{ option }
|
|
702
|
+
)) as TableOption<Spec>
|
|
508
703
|
}
|
|
509
704
|
|
|
510
705
|
export const option = <Spec extends TableOptionSpec>(spec: Spec): TableOption<Spec> =>
|
|
@@ -517,18 +712,30 @@ export const optionFromTable = <Spec extends TableOptionSpec>(
|
|
|
517
712
|
makeResolvedOption(spec, resolve)
|
|
518
713
|
|
|
519
714
|
/** Creates a table definition from a name and field map. */
|
|
715
|
+
export function make<
|
|
716
|
+
Name extends string,
|
|
717
|
+
Fields extends TableFieldMap
|
|
718
|
+
>(
|
|
719
|
+
name: NonEmptyStringInput<Name>,
|
|
720
|
+
fields: Fields & NonEmptyFieldMap<Fields>
|
|
721
|
+
): TableDefinition<Name, Fields, InlinePrimaryKeyKeys<Fields>, "schema", DefaultSchemaName>
|
|
520
722
|
export function make<
|
|
521
723
|
Name extends string,
|
|
522
724
|
Fields extends TableFieldMap,
|
|
523
|
-
SchemaName extends string
|
|
725
|
+
const SchemaName extends string
|
|
524
726
|
>(
|
|
525
|
-
name: Name
|
|
526
|
-
fields: Fields
|
|
527
|
-
schemaName
|
|
528
|
-
): TableDefinition<Name, Fields, InlinePrimaryKeyKeys<Fields>, "schema", SchemaName>
|
|
727
|
+
name: NonEmptyStringInput<Name>,
|
|
728
|
+
fields: Fields & NonEmptyFieldMap<Fields>,
|
|
729
|
+
schemaName: NonEmptySchemaNameInput<SchemaName>
|
|
730
|
+
): TableDefinition<Name, Fields, InlinePrimaryKeyKeys<Fields>, "schema", SchemaName>
|
|
731
|
+
export function make(
|
|
732
|
+
name: string,
|
|
733
|
+
fields: TableFieldMap,
|
|
734
|
+
schemaName?: string
|
|
735
|
+
): TableDefinition<string, TableFieldMap, string, "schema", string | undefined> {
|
|
529
736
|
const resolvedSchemaName = arguments.length >= 3
|
|
530
737
|
? schemaName
|
|
531
|
-
:
|
|
738
|
+
: "public"
|
|
532
739
|
return makeTable(
|
|
533
740
|
name,
|
|
534
741
|
fields,
|
|
@@ -540,38 +747,56 @@ export function make<
|
|
|
540
747
|
)
|
|
541
748
|
}
|
|
542
749
|
|
|
543
|
-
|
|
544
|
-
|
|
545
|
-
|
|
546
|
-
|
|
547
|
-
|
|
548
|
-
):
|
|
549
|
-
const
|
|
550
|
-
|
|
551
|
-
|
|
552
|
-
|
|
553
|
-
|
|
554
|
-
|
|
555
|
-
|
|
556
|
-
|
|
557
|
-
|
|
558
|
-
|
|
559
|
-
|
|
560
|
-
|
|
561
|
-
|
|
562
|
-
|
|
563
|
-
|
|
564
|
-
|
|
565
|
-
|
|
566
|
-
|
|
567
|
-
|
|
568
|
-
|
|
569
|
-
|
|
570
|
-
|
|
571
|
-
|
|
750
|
+
export const withCasing = <
|
|
751
|
+
Table extends TableDefinition<any, any, any, any, any>
|
|
752
|
+
>(
|
|
753
|
+
table: Table,
|
|
754
|
+
casing: Casing.Options
|
|
755
|
+
): Table => {
|
|
756
|
+
const state = table[TypeId]
|
|
757
|
+
return makeTable(
|
|
758
|
+
state.name,
|
|
759
|
+
state.fields,
|
|
760
|
+
table[DeclaredOptionsSymbol],
|
|
761
|
+
state.baseName,
|
|
762
|
+
state.kind,
|
|
763
|
+
state.schemaName,
|
|
764
|
+
"explicit",
|
|
765
|
+
Casing.merge(state.casing, casing)
|
|
766
|
+
) as Table
|
|
767
|
+
}
|
|
768
|
+
|
|
769
|
+
export const withSchema = <
|
|
770
|
+
Table extends TableDefinition<any, any, any, any, any>,
|
|
771
|
+
SchemaName extends string
|
|
772
|
+
>(
|
|
773
|
+
table: Table,
|
|
774
|
+
schemaName: SchemaName,
|
|
775
|
+
schemaCasing?: Casing.Options
|
|
776
|
+
): TableDefinition<
|
|
777
|
+
Table[typeof TypeId]["name"],
|
|
778
|
+
Table[typeof TypeId]["fields"],
|
|
779
|
+
Table[typeof TypeId]["primaryKey"][number],
|
|
780
|
+
Table[typeof TypeId]["kind"],
|
|
781
|
+
SchemaName
|
|
782
|
+
> => {
|
|
783
|
+
const state = table[TypeId]
|
|
784
|
+
return makeTable(
|
|
785
|
+
state.name,
|
|
786
|
+
state.fields,
|
|
787
|
+
table[DeclaredOptionsSymbol],
|
|
788
|
+
state.baseName,
|
|
789
|
+
state.kind,
|
|
572
790
|
schemaName,
|
|
573
|
-
|
|
574
|
-
|
|
791
|
+
"explicit",
|
|
792
|
+
Casing.merge(schemaCasing, state.casing)
|
|
793
|
+
) as TableDefinition<
|
|
794
|
+
Table[typeof TypeId]["name"],
|
|
795
|
+
Table[typeof TypeId]["fields"],
|
|
796
|
+
Table[typeof TypeId]["primaryKey"][number],
|
|
797
|
+
Table[typeof TypeId]["kind"],
|
|
798
|
+
SchemaName
|
|
799
|
+
>
|
|
575
800
|
}
|
|
576
801
|
|
|
577
802
|
/**
|
|
@@ -589,7 +814,7 @@ export const alias = <
|
|
|
589
814
|
AliasName extends string
|
|
590
815
|
>(
|
|
591
816
|
table: TableDefinition<Name, Fields, PrimaryKeyColumns, any, SchemaName> | TableClassStatic<Name, Fields, PrimaryKeyColumns, SchemaName>,
|
|
592
|
-
aliasName: AliasName
|
|
817
|
+
aliasName: LiteralStringInput<AliasName>
|
|
593
818
|
): TableDefinition<
|
|
594
819
|
AliasName,
|
|
595
820
|
Fields,
|
|
@@ -599,26 +824,27 @@ export const alias = <
|
|
|
599
824
|
> => {
|
|
600
825
|
const state = table[TypeId]
|
|
601
826
|
const columns = Object.fromEntries(
|
|
602
|
-
Object.entries(state.fields).map(([key, column]) => [key, bindColumn(aliasName, key, column as AnyColumnDefinition, state.baseName, state.schemaName)])
|
|
827
|
+
Object.entries(state.fields).map(([key, column]) => [key, bindColumn(aliasName as AliasName, key, column as AnyColumnDefinition, state.baseName, state.schemaName, state.casing)])
|
|
603
828
|
) as BoundColumns<AliasName, Fields>
|
|
604
829
|
const aliased = attachPipe(Object.create(TableProto))
|
|
605
|
-
aliased.name = aliasName
|
|
830
|
+
aliased.name = aliasName as AliasName
|
|
606
831
|
aliased.columns = columns
|
|
607
|
-
aliased
|
|
832
|
+
defineSchemasGetter(aliased)
|
|
608
833
|
aliased[TypeId] = {
|
|
609
|
-
name: aliasName,
|
|
834
|
+
name: aliasName as AliasName,
|
|
610
835
|
baseName: state.baseName,
|
|
611
836
|
schemaName: state.schemaName,
|
|
612
837
|
fields: state.fields,
|
|
613
838
|
primaryKey: state.primaryKey,
|
|
614
|
-
kind: "alias"
|
|
839
|
+
kind: "alias",
|
|
840
|
+
casing: state.casing
|
|
615
841
|
}
|
|
616
842
|
aliased[Plan.TypeId] = {
|
|
617
843
|
selection: columns,
|
|
618
844
|
required: undefined as never,
|
|
619
845
|
available: {
|
|
620
846
|
[aliasName]: {
|
|
621
|
-
name: aliasName,
|
|
847
|
+
name: aliasName as AliasName,
|
|
622
848
|
mode: "required",
|
|
623
849
|
baseName: state.baseName
|
|
624
850
|
}
|
|
@@ -642,19 +868,38 @@ export const alias = <
|
|
|
642
868
|
* The returned base class can be extended and configured with
|
|
643
869
|
* `static readonly [Table.options]`.
|
|
644
870
|
*/
|
|
871
|
+
export function Class<Self = never>(
|
|
872
|
+
name: "",
|
|
873
|
+
schemaName?: string | undefined
|
|
874
|
+
): never
|
|
875
|
+
export function Class<Self = never>(
|
|
876
|
+
name: string,
|
|
877
|
+
schemaName: ""
|
|
878
|
+
): never
|
|
645
879
|
export function Class<
|
|
646
880
|
Self = never,
|
|
647
|
-
SchemaName extends string | undefined = DefaultSchemaName
|
|
881
|
+
const SchemaName extends string | undefined = DefaultSchemaName,
|
|
882
|
+
const Name extends string = string
|
|
883
|
+
>(
|
|
884
|
+
name: NonEmptyStringInput<Name>,
|
|
885
|
+
schemaName?: NonEmptySchemaNameInput<SchemaName>
|
|
886
|
+
): <Fields extends TableFieldMap>(fields: Fields & NonEmptyFieldMap<Fields>) => [Self] extends [never]
|
|
887
|
+
? MissingSelfGeneric
|
|
888
|
+
: TableClassStatic<Name, Fields, InlinePrimaryKeyKeys<Fields>, SchemaName>
|
|
889
|
+
export function Class<
|
|
890
|
+
Self = never,
|
|
891
|
+
SchemaName extends string | undefined = DefaultSchemaName,
|
|
892
|
+
Name extends string = string
|
|
648
893
|
>(
|
|
649
894
|
name: string,
|
|
650
895
|
schemaName?: SchemaName
|
|
651
|
-
) {
|
|
896
|
+
): any {
|
|
652
897
|
const resolvedSchemaName = arguments.length >= 2
|
|
653
898
|
? schemaName
|
|
654
899
|
: ("public" as SchemaName)
|
|
655
|
-
return <Fields extends TableFieldMap>(fields: Fields): [Self] extends [never]
|
|
900
|
+
return <Fields extends TableFieldMap>(fields: Fields & NonEmptyFieldMap<Fields>): [Self] extends [never]
|
|
656
901
|
? MissingSelfGeneric
|
|
657
|
-
: TableClassStatic<
|
|
902
|
+
: TableClassStatic<Name, Fields, InlinePrimaryKeyKeys<Fields>, SchemaName> => {
|
|
658
903
|
abstract class TableClassBase {
|
|
659
904
|
static readonly tableName = name
|
|
660
905
|
|
|
@@ -663,12 +908,11 @@ export function Class<
|
|
|
663
908
|
}
|
|
664
909
|
|
|
665
910
|
static get schemas() {
|
|
666
|
-
return
|
|
911
|
+
return schemasFor(this as any)
|
|
667
912
|
}
|
|
668
913
|
|
|
669
914
|
static get [TypeId]() {
|
|
670
|
-
const declaredOptions = extractDeclaredOptions((this as unknown as TableClassStatic<
|
|
671
|
-
validateClassOptions(declaredOptions)
|
|
915
|
+
const declaredOptions = extractDeclaredOptions((this as unknown as TableClassStatic<Name, Fields>)[options])
|
|
672
916
|
return {
|
|
673
917
|
name,
|
|
674
918
|
baseName: name,
|
|
@@ -699,7 +943,7 @@ export function Class<
|
|
|
699
943
|
return ensureClassArtifacts(this as any).normalizedOptions
|
|
700
944
|
}
|
|
701
945
|
|
|
702
|
-
static pipe(this:
|
|
946
|
+
static pipe(this: Pipeable) {
|
|
703
947
|
return pipeArguments(this, arguments)
|
|
704
948
|
}
|
|
705
949
|
}
|
|
@@ -781,14 +1025,15 @@ export const foreignKey = <
|
|
|
781
1025
|
references: () => ({
|
|
782
1026
|
tableName: target()[TypeId].baseName,
|
|
783
1027
|
schemaName: target()[TypeId].schemaName,
|
|
1028
|
+
casing: target()[TypeId].casing,
|
|
784
1029
|
columns: normalizeColumnList(referencedColumns) as NormalizeColumns<TargetColumns>,
|
|
785
|
-
knownColumns: Object.keys(target()[TypeId].fields)
|
|
1030
|
+
knownColumns: Object.keys(target()[TypeId].fields).map((key) => key as ColumnNamesOfAnyTable<TargetTable>)
|
|
786
1031
|
})
|
|
787
1032
|
})
|
|
788
1033
|
|
|
789
1034
|
/** Declares a check constraint expression. */
|
|
790
|
-
export const check = <Name extends string>(
|
|
791
|
-
name: Name
|
|
1035
|
+
export const check = <const Name extends string>(
|
|
1036
|
+
name: NonEmptyStringInput<Name>,
|
|
792
1037
|
predicate: DdlExpressionLike
|
|
793
1038
|
): TableOption<{
|
|
794
1039
|
readonly kind: "check"
|
|
@@ -800,15 +1045,21 @@ export const check = <Name extends string>(
|
|
|
800
1045
|
predicate
|
|
801
1046
|
})
|
|
802
1047
|
|
|
803
|
-
/** Extracts the row type
|
|
804
|
-
export type SelectOf<Table extends
|
|
805
|
-
|
|
806
|
-
|
|
807
|
-
|
|
808
|
-
|
|
809
|
-
|
|
810
|
-
>
|
|
811
|
-
|
|
812
|
-
|
|
813
|
-
|
|
814
|
-
|
|
1048
|
+
/** Extracts the row type produced by `selectSchema(table)`. */
|
|
1049
|
+
export type SelectOf<Table extends AnyTable> = Table[typeof TypeId] extends {
|
|
1050
|
+
readonly name: infer Name extends string
|
|
1051
|
+
readonly fields: infer Fields extends TableFieldMap
|
|
1052
|
+
} ? SelectRow<Name, Fields> : never
|
|
1053
|
+
|
|
1054
|
+
/** Extracts the payload type produced by `insertSchema(table)`. */
|
|
1055
|
+
export type InsertOf<Table extends AnyTable> = Table[typeof TypeId] extends {
|
|
1056
|
+
readonly name: infer Name extends string
|
|
1057
|
+
readonly fields: infer Fields extends TableFieldMap
|
|
1058
|
+
} ? InsertRow<Name, Fields> : never
|
|
1059
|
+
|
|
1060
|
+
/** Extracts the payload type produced by `updateSchema(table)`. */
|
|
1061
|
+
export type UpdateOf<Table extends AnyTable> = Table[typeof TypeId] extends {
|
|
1062
|
+
readonly name: infer Name extends string
|
|
1063
|
+
readonly fields: infer Fields extends TableFieldMap
|
|
1064
|
+
readonly primaryKey: readonly (infer PrimaryKeyColumns)[]
|
|
1065
|
+
} ? UpdateRow<Name, Fields, Extract<PrimaryKeyColumns, keyof Fields & string>> : never
|