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
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
import { type AnyColumnDefinition, type IsNullable } from "./column-state.js";
|
|
2
|
+
import type { Any as AnyExpression } from "./scalar.js";
|
|
3
|
+
import type { Any as AnySchemaExpression } from "./schema-expression.js";
|
|
4
|
+
import type { TableFieldMap } from "./schema-derivation.js";
|
|
5
|
+
/** Non-empty list of column names. */
|
|
6
|
+
export type ColumnList = readonly [string, ...string[]];
|
|
7
|
+
export type DdlExpressionLike = AnyExpression | AnySchemaExpression;
|
|
8
|
+
export type ReferentialAction = "noAction" | "restrict" | "cascade" | "setNull" | "setDefault";
|
|
9
|
+
export type IndexKeySpec = {
|
|
10
|
+
readonly kind: "column";
|
|
11
|
+
readonly column: string;
|
|
12
|
+
readonly order?: "asc" | "desc";
|
|
13
|
+
readonly nulls?: "first" | "last";
|
|
14
|
+
readonly operatorClass?: string;
|
|
15
|
+
readonly collation?: string;
|
|
16
|
+
} | {
|
|
17
|
+
readonly kind: "expression";
|
|
18
|
+
readonly expression: DdlExpressionLike;
|
|
19
|
+
readonly order?: "asc" | "desc";
|
|
20
|
+
readonly nulls?: "first" | "last";
|
|
21
|
+
readonly operatorClass?: string;
|
|
22
|
+
readonly collation?: string;
|
|
23
|
+
};
|
|
24
|
+
/** Normalized table-level option record. */
|
|
25
|
+
export type TableOptionSpec = {
|
|
26
|
+
readonly kind: "index";
|
|
27
|
+
readonly columns?: ColumnList;
|
|
28
|
+
readonly name?: string;
|
|
29
|
+
readonly unique?: boolean;
|
|
30
|
+
readonly method?: string;
|
|
31
|
+
readonly include?: readonly string[];
|
|
32
|
+
readonly predicate?: DdlExpressionLike;
|
|
33
|
+
readonly keys?: readonly [IndexKeySpec, ...IndexKeySpec[]];
|
|
34
|
+
} | {
|
|
35
|
+
readonly kind: "unique";
|
|
36
|
+
readonly columns: ColumnList;
|
|
37
|
+
readonly name?: string;
|
|
38
|
+
readonly nullsNotDistinct?: boolean;
|
|
39
|
+
readonly deferrable?: boolean;
|
|
40
|
+
readonly initiallyDeferred?: boolean;
|
|
41
|
+
} | {
|
|
42
|
+
readonly kind: "primaryKey";
|
|
43
|
+
readonly columns: ColumnList;
|
|
44
|
+
readonly name?: string;
|
|
45
|
+
readonly deferrable?: boolean;
|
|
46
|
+
readonly initiallyDeferred?: boolean;
|
|
47
|
+
} | {
|
|
48
|
+
readonly kind: "foreignKey";
|
|
49
|
+
readonly columns: ColumnList;
|
|
50
|
+
readonly name?: string;
|
|
51
|
+
readonly references: () => {
|
|
52
|
+
readonly tableName: string;
|
|
53
|
+
readonly schemaName?: string;
|
|
54
|
+
readonly columns: ColumnList;
|
|
55
|
+
readonly knownColumns?: readonly string[];
|
|
56
|
+
};
|
|
57
|
+
readonly onUpdate?: ReferentialAction;
|
|
58
|
+
readonly onDelete?: ReferentialAction;
|
|
59
|
+
readonly deferrable?: boolean;
|
|
60
|
+
readonly initiallyDeferred?: boolean;
|
|
61
|
+
} | {
|
|
62
|
+
readonly kind: "check";
|
|
63
|
+
readonly name: string;
|
|
64
|
+
readonly predicate: DdlExpressionLike;
|
|
65
|
+
readonly noInherit?: boolean;
|
|
66
|
+
};
|
|
67
|
+
/** Thin wrapper used by the public `Table.*` option builders. */
|
|
68
|
+
export interface TableOptionBuilder<Spec extends TableOptionSpec = TableOptionSpec> {
|
|
69
|
+
readonly option: Spec;
|
|
70
|
+
}
|
|
71
|
+
/** Collection of declared table options. */
|
|
72
|
+
export type DeclaredTableOptions = readonly TableOptionBuilder[];
|
|
73
|
+
type ColumnNameUnion<Fields extends TableFieldMap> = Extract<keyof Fields, string>;
|
|
74
|
+
type NullableColumnNames<Fields extends TableFieldMap> = {
|
|
75
|
+
[K in keyof Fields]: Fields[K] extends AnyColumnDefinition ? IsNullable<Fields[K]> extends true ? K : never : never;
|
|
76
|
+
}[keyof Fields];
|
|
77
|
+
type TupleFromColumns<Columns> = Columns extends readonly [infer Head extends string, ...infer Tail extends string[]] ? readonly [Head, ...Tail] : Columns extends readonly string[] ? Columns extends readonly [string, ...string[]] ? Columns : never : Columns extends string ? readonly [Columns] : never;
|
|
78
|
+
type AssertKnownColumns<Fields extends TableFieldMap, Columns extends readonly string[]> = Exclude<Columns[number], ColumnNameUnion<Fields>> extends never ? Columns : never;
|
|
79
|
+
type AssertPrimaryKeyColumns<Fields extends TableFieldMap, Columns extends readonly string[]> = Extract<Columns[number], NullableColumnNames<Fields>> extends never ? Columns : never;
|
|
80
|
+
/** Normalizes a string or tuple input into a non-empty column list. */
|
|
81
|
+
export declare const normalizeColumnList: (columns: string | readonly string[]) => ColumnList;
|
|
82
|
+
/** Converts inline column flags into normalized table option records. */
|
|
83
|
+
export declare const collectInlineOptions: <Fields extends TableFieldMap>(fields: Fields) => readonly TableOptionSpec[];
|
|
84
|
+
/** Resolves the effective primary-key columns for a table. */
|
|
85
|
+
export declare const resolvePrimaryKeyColumns: <Fields extends TableFieldMap>(fields: Fields, declaredOptions: readonly TableOptionSpec[]) => readonly (keyof Fields & string)[];
|
|
86
|
+
/** Validates that options reference known, legal columns for the table. */
|
|
87
|
+
export declare const validateOptions: <Fields extends TableFieldMap>(tableName: string, fields: Fields, options: readonly TableOptionSpec[]) => void;
|
|
88
|
+
/** Compile-time validation that option columns exist on the table. */
|
|
89
|
+
export type ValidateKnownColumns<Fields extends TableFieldMap, Columns extends readonly string[]> = AssertKnownColumns<Fields, Columns>;
|
|
90
|
+
/** Compile-time validation that primary-key columns are known and non-nullable. */
|
|
91
|
+
export type ValidatePrimaryKeyColumns<Fields extends TableFieldMap, Columns extends readonly string[]> = AssertPrimaryKeyColumns<Fields, AssertKnownColumns<Fields, Columns>>;
|
|
92
|
+
/** Normalizes a public column input into the internal tuple form. */
|
|
93
|
+
export type NormalizeColumns<Columns extends string | readonly string[]> = TupleFromColumns<Columns>;
|
|
94
|
+
export {};
|
|
@@ -4,40 +4,82 @@ import {
|
|
|
4
4
|
type AnyColumnDefinition,
|
|
5
5
|
type IsNullable
|
|
6
6
|
} from "./column-state.js"
|
|
7
|
-
import type { Any as AnyExpression } from "./
|
|
7
|
+
import type { Any as AnyExpression } from "./scalar.js"
|
|
8
|
+
import type { Any as AnySchemaExpression } from "./schema-expression.js"
|
|
8
9
|
import type { TableFieldMap } from "./schema-derivation.js"
|
|
9
10
|
|
|
10
11
|
/** Non-empty list of column names. */
|
|
11
12
|
export type ColumnList = readonly [string, ...string[]]
|
|
12
13
|
|
|
14
|
+
export type DdlExpressionLike = AnyExpression | AnySchemaExpression
|
|
15
|
+
|
|
16
|
+
export type ReferentialAction = "noAction" | "restrict" | "cascade" | "setNull" | "setDefault"
|
|
17
|
+
|
|
18
|
+
export type IndexKeySpec =
|
|
19
|
+
| {
|
|
20
|
+
readonly kind: "column"
|
|
21
|
+
readonly column: string
|
|
22
|
+
readonly order?: "asc" | "desc"
|
|
23
|
+
readonly nulls?: "first" | "last"
|
|
24
|
+
readonly operatorClass?: string
|
|
25
|
+
readonly collation?: string
|
|
26
|
+
}
|
|
27
|
+
| {
|
|
28
|
+
readonly kind: "expression"
|
|
29
|
+
readonly expression: DdlExpressionLike
|
|
30
|
+
readonly order?: "asc" | "desc"
|
|
31
|
+
readonly nulls?: "first" | "last"
|
|
32
|
+
readonly operatorClass?: string
|
|
33
|
+
readonly collation?: string
|
|
34
|
+
}
|
|
35
|
+
|
|
13
36
|
/** Normalized table-level option record. */
|
|
14
37
|
export type TableOptionSpec =
|
|
15
38
|
| {
|
|
16
39
|
readonly kind: "index"
|
|
17
|
-
readonly columns
|
|
40
|
+
readonly columns?: ColumnList
|
|
41
|
+
readonly name?: string
|
|
42
|
+
readonly unique?: boolean
|
|
43
|
+
readonly method?: string
|
|
44
|
+
readonly include?: readonly string[]
|
|
45
|
+
readonly predicate?: DdlExpressionLike
|
|
46
|
+
readonly keys?: readonly [IndexKeySpec, ...IndexKeySpec[]]
|
|
18
47
|
}
|
|
19
48
|
| {
|
|
20
49
|
readonly kind: "unique"
|
|
21
50
|
readonly columns: ColumnList
|
|
51
|
+
readonly name?: string
|
|
52
|
+
readonly nullsNotDistinct?: boolean
|
|
53
|
+
readonly deferrable?: boolean
|
|
54
|
+
readonly initiallyDeferred?: boolean
|
|
22
55
|
}
|
|
23
56
|
| {
|
|
24
57
|
readonly kind: "primaryKey"
|
|
25
58
|
readonly columns: ColumnList
|
|
59
|
+
readonly name?: string
|
|
60
|
+
readonly deferrable?: boolean
|
|
61
|
+
readonly initiallyDeferred?: boolean
|
|
26
62
|
}
|
|
27
63
|
| {
|
|
28
64
|
readonly kind: "foreignKey"
|
|
29
65
|
readonly columns: ColumnList
|
|
66
|
+
readonly name?: string
|
|
30
67
|
readonly references: () => {
|
|
31
68
|
readonly tableName: string
|
|
32
69
|
readonly schemaName?: string
|
|
33
70
|
readonly columns: ColumnList
|
|
34
71
|
readonly knownColumns?: readonly string[]
|
|
35
72
|
}
|
|
73
|
+
readonly onUpdate?: ReferentialAction
|
|
74
|
+
readonly onDelete?: ReferentialAction
|
|
75
|
+
readonly deferrable?: boolean
|
|
76
|
+
readonly initiallyDeferred?: boolean
|
|
36
77
|
}
|
|
37
78
|
| {
|
|
38
79
|
readonly kind: "check"
|
|
39
80
|
readonly name: string
|
|
40
|
-
readonly predicate:
|
|
81
|
+
readonly predicate: DdlExpressionLike
|
|
82
|
+
readonly noInherit?: boolean
|
|
41
83
|
}
|
|
42
84
|
|
|
43
85
|
/** Thin wrapper used by the public `Table.*` option builders. */
|
|
@@ -109,7 +151,11 @@ export const collectInlineOptions = <Fields extends TableFieldMap>(
|
|
|
109
151
|
if (column.metadata.unique && !column.metadata.primaryKey) {
|
|
110
152
|
options.push({
|
|
111
153
|
kind: "unique",
|
|
112
|
-
columns: [columnName]
|
|
154
|
+
columns: [columnName],
|
|
155
|
+
name: column.metadata.uniqueConstraint?.name,
|
|
156
|
+
nullsNotDistinct: column.metadata.uniqueConstraint?.nullsNotDistinct,
|
|
157
|
+
deferrable: column.metadata.uniqueConstraint?.deferrable,
|
|
158
|
+
initiallyDeferred: column.metadata.uniqueConstraint?.initiallyDeferred
|
|
113
159
|
})
|
|
114
160
|
}
|
|
115
161
|
if (column.metadata.references) {
|
|
@@ -125,7 +171,29 @@ export const collectInlineOptions = <Fields extends TableFieldMap>(
|
|
|
125
171
|
schemaName: bound.schemaName,
|
|
126
172
|
columns: [bound.columnName]
|
|
127
173
|
}
|
|
128
|
-
}
|
|
174
|
+
},
|
|
175
|
+
name: column.metadata.references.name,
|
|
176
|
+
onUpdate: column.metadata.references.onUpdate,
|
|
177
|
+
onDelete: column.metadata.references.onDelete,
|
|
178
|
+
deferrable: column.metadata.references.deferrable,
|
|
179
|
+
initiallyDeferred: column.metadata.references.initiallyDeferred
|
|
180
|
+
})
|
|
181
|
+
}
|
|
182
|
+
if (column.metadata.index) {
|
|
183
|
+
options.push({
|
|
184
|
+
kind: "index",
|
|
185
|
+
keys: [{
|
|
186
|
+
kind: "column",
|
|
187
|
+
column: columnName,
|
|
188
|
+
order: column.metadata.index.order,
|
|
189
|
+
nulls: column.metadata.index.nulls,
|
|
190
|
+
operatorClass: column.metadata.index.operatorClass,
|
|
191
|
+
collation: column.metadata.index.collation
|
|
192
|
+
}],
|
|
193
|
+
name: column.metadata.index.name,
|
|
194
|
+
method: column.metadata.index.method,
|
|
195
|
+
include: column.metadata.index.include,
|
|
196
|
+
predicate: column.metadata.index.predicate
|
|
129
197
|
})
|
|
130
198
|
}
|
|
131
199
|
}
|
|
@@ -174,17 +242,20 @@ export const validateOptions = <Fields extends TableFieldMap>(
|
|
|
174
242
|
case "primaryKey":
|
|
175
243
|
case "unique":
|
|
176
244
|
case "foreignKey": {
|
|
177
|
-
|
|
245
|
+
const columns = option.kind === "index"
|
|
246
|
+
? option.columns ?? []
|
|
247
|
+
: option.columns
|
|
248
|
+
if (columns.length === 0 && option.kind !== "index") {
|
|
178
249
|
throw new Error(`Option '${option.kind}' on table '${tableName}' requires at least one column`)
|
|
179
250
|
}
|
|
180
|
-
for (const column of
|
|
251
|
+
for (const column of columns) {
|
|
181
252
|
if (!knownColumns.has(column)) {
|
|
182
253
|
throw new Error(`Unknown column '${column}' on table '${tableName}'`)
|
|
183
254
|
}
|
|
184
255
|
}
|
|
185
256
|
if (option.kind === "foreignKey") {
|
|
186
257
|
const reference = option.references()
|
|
187
|
-
if (reference.columns.length !==
|
|
258
|
+
if (reference.columns.length !== columns.length) {
|
|
188
259
|
throw new Error(`Foreign key on table '${tableName}' must reference the same number of columns`)
|
|
189
260
|
}
|
|
190
261
|
if (reference.knownColumns) {
|
|
@@ -196,6 +267,21 @@ export const validateOptions = <Fields extends TableFieldMap>(
|
|
|
196
267
|
}
|
|
197
268
|
}
|
|
198
269
|
}
|
|
270
|
+
if (option.kind === "index") {
|
|
271
|
+
for (const column of option.include ?? []) {
|
|
272
|
+
if (!knownColumns.has(column)) {
|
|
273
|
+
throw new Error(`Unknown included column '${column}' on table '${tableName}'`)
|
|
274
|
+
}
|
|
275
|
+
}
|
|
276
|
+
for (const key of option.keys ?? []) {
|
|
277
|
+
if (key.kind === "column" && !knownColumns.has(key.column)) {
|
|
278
|
+
throw new Error(`Unknown index key column '${key.column}' on table '${tableName}'`)
|
|
279
|
+
}
|
|
280
|
+
}
|
|
281
|
+
if (option.columns === undefined && (option.keys === undefined || option.keys.length === 0)) {
|
|
282
|
+
throw new Error(`Index on table '${tableName}' requires at least one column or key`)
|
|
283
|
+
}
|
|
284
|
+
}
|
|
199
285
|
break
|
|
200
286
|
}
|
|
201
287
|
case "check": {
|
|
@@ -0,0 +1,173 @@
|
|
|
1
|
+
import { type Pipeable } from "effect/Pipeable";
|
|
2
|
+
import * as Schema from "effect/Schema";
|
|
3
|
+
import * as Plan from "./row-set.js";
|
|
4
|
+
import type { TrueFormula } from "./predicate/formula.js";
|
|
5
|
+
import type { BoundColumnFrom } from "./column-state.js";
|
|
6
|
+
import { type DdlExpressionLike, type NormalizeColumns, type TableOptionSpec, type ValidateKnownColumns, type ValidatePrimaryKeyColumns } from "./table-options.js";
|
|
7
|
+
import { type InsertRow, type SelectRow, type TableFieldMap, type UpdateRow } from "./schema-derivation.js";
|
|
8
|
+
/** Symbol used to attach table-definition metadata. */
|
|
9
|
+
export declare const TypeId: unique symbol;
|
|
10
|
+
/** Symbol for the normalized table option list. */
|
|
11
|
+
export declare const OptionsSymbol: unique symbol;
|
|
12
|
+
/** Symbol used by `Table.Class` to declare table-level options. */
|
|
13
|
+
export declare const options: unique symbol;
|
|
14
|
+
declare const DeclaredOptionsSymbol: unique symbol;
|
|
15
|
+
type InlinePrimaryKeyKeys<Fields extends TableFieldMap> = Extract<{
|
|
16
|
+
[K in keyof Fields]: Fields[K]["metadata"]["primaryKey"] extends true ? K : never;
|
|
17
|
+
}[keyof Fields], string>;
|
|
18
|
+
type TableDialect<Fields extends TableFieldMap> = Fields[keyof Fields][typeof import("./column-state.js").ColumnTypeId]["dbType"]["dialect"];
|
|
19
|
+
type TableKind = "schema" | "alias";
|
|
20
|
+
type DefaultSchemaName = "public";
|
|
21
|
+
type ClassOptionSpec = Exclude<TableOptionSpec, {
|
|
22
|
+
readonly kind: "primaryKey";
|
|
23
|
+
}>;
|
|
24
|
+
interface TableOptionBuilderLike<Spec extends TableOptionSpec = TableOptionSpec> {
|
|
25
|
+
(table: TableDefinition<any, any, any, "schema", any>): TableDefinition<any, any, any, "schema", any>;
|
|
26
|
+
readonly option: Spec;
|
|
27
|
+
}
|
|
28
|
+
type ClassTableOption = TableOptionBuilderLike<ClassOptionSpec>;
|
|
29
|
+
type ClassDeclaredTableOptions = readonly ClassTableOption[];
|
|
30
|
+
type BuildPrimaryKey<Table extends TableDefinition<any, any, any, "schema", any>, Spec extends TableOptionSpec> = Spec extends {
|
|
31
|
+
readonly kind: "primaryKey";
|
|
32
|
+
readonly columns: infer Columns extends readonly string[];
|
|
33
|
+
} ? Columns[number] & keyof Table[typeof TypeId]["fields"] & string : Table[typeof TypeId]["primaryKey"][number];
|
|
34
|
+
type OptionInputTable<Table extends TableDefinition<any, any, any, "schema", any>, Spec extends TableOptionSpec> = Spec extends {
|
|
35
|
+
readonly kind: "primaryKey";
|
|
36
|
+
readonly columns: infer Columns extends readonly string[];
|
|
37
|
+
} ? ValidatePrimaryKeyColumns<Table[typeof TypeId]["fields"], Columns> extends never ? never : Table : Spec extends {
|
|
38
|
+
readonly columns: infer Columns extends readonly string[];
|
|
39
|
+
} ? ValidateKnownColumns<Table[typeof TypeId]["fields"], Columns> extends never ? never : Table : Table;
|
|
40
|
+
type ApplyOption<Table extends TableDefinition<any, any, any, "schema", any>, Spec extends TableOptionSpec> = Spec extends {
|
|
41
|
+
readonly kind: "primaryKey";
|
|
42
|
+
} ? TableDefinition<Table[typeof TypeId]["name"], Table[typeof TypeId]["fields"], BuildPrimaryKey<Table, Spec>, "schema"> : TableDefinition<Table[typeof TypeId]["name"], Table[typeof TypeId]["fields"], Table[typeof TypeId]["primaryKey"][number], "schema">;
|
|
43
|
+
export type MissingSelfGeneric = "Missing `Self` generic - use `class Self extends Table.Class<Self>(...) {}`";
|
|
44
|
+
/** Bound columns keyed by field name for a particular table. */
|
|
45
|
+
export type BoundColumns<Name extends string, Fields extends TableFieldMap> = {
|
|
46
|
+
readonly [K in keyof Fields]: BoundColumnFrom<Fields[K], Name, Extract<K, string>>;
|
|
47
|
+
};
|
|
48
|
+
/** Derived runtime schemas exposed by a table definition. */
|
|
49
|
+
export interface TableSchemas<Name extends string, Fields extends TableFieldMap, PrimaryKeyColumns extends keyof Fields & string> {
|
|
50
|
+
readonly select: Schema.Schema<SelectRow<Name, Fields>>;
|
|
51
|
+
readonly insert: Schema.Schema<InsertRow<Name, Fields>>;
|
|
52
|
+
readonly update: Schema.Schema<UpdateRow<Name, Fields, PrimaryKeyColumns>>;
|
|
53
|
+
}
|
|
54
|
+
interface TableState<Name extends string, Fields extends TableFieldMap, PrimaryKeyColumns extends keyof Fields & string, Kind extends TableKind = "schema", SchemaName extends string | undefined = DefaultSchemaName> {
|
|
55
|
+
readonly name: Name;
|
|
56
|
+
readonly baseName: string;
|
|
57
|
+
readonly schemaName: SchemaName;
|
|
58
|
+
readonly fields: Fields;
|
|
59
|
+
readonly primaryKey: readonly PrimaryKeyColumns[];
|
|
60
|
+
readonly kind: Kind;
|
|
61
|
+
}
|
|
62
|
+
/** Namespace-scoped table builder. */
|
|
63
|
+
export interface TableSchemaNamespace<SchemaName extends string> {
|
|
64
|
+
readonly schemaName: SchemaName;
|
|
65
|
+
readonly table: <Name extends string, Fields extends TableFieldMap, PrimaryKeyColumns extends keyof Fields & string = InlinePrimaryKeyKeys<Fields>>(name: Name, fields: Fields, ...options: DeclaredTableOptions) => TableDefinition<Name, Fields, PrimaryKeyColumns, "schema", SchemaName>;
|
|
66
|
+
}
|
|
67
|
+
export type DeclaredTableOptions = readonly TableOptionBuilderLike[];
|
|
68
|
+
export type { DdlExpressionLike, IndexKeySpec, NormalizeColumns, ReferentialAction } from "./table-options.js";
|
|
69
|
+
export type TableDefinition<Name extends string, Fields extends TableFieldMap, PrimaryKeyColumns extends keyof Fields & string = InlinePrimaryKeyKeys<Fields>, Kind extends TableKind = "schema", SchemaName extends string | undefined = DefaultSchemaName> = Pipeable & {
|
|
70
|
+
readonly name: Name;
|
|
71
|
+
readonly columns: BoundColumns<Name, Fields>;
|
|
72
|
+
readonly schemas: TableSchemas<Name, Fields, PrimaryKeyColumns>;
|
|
73
|
+
readonly [TypeId]: TableState<Name, Fields, PrimaryKeyColumns, Kind, SchemaName>;
|
|
74
|
+
readonly [Plan.TypeId]: Plan.State<BoundColumns<Name, Fields>, never, Record<Name, Plan.Source<Name, "required", TrueFormula>>, TableDialect<Fields>>;
|
|
75
|
+
readonly [OptionsSymbol]: readonly TableOptionSpec[];
|
|
76
|
+
readonly [DeclaredOptionsSymbol]: readonly TableOptionSpec[];
|
|
77
|
+
} & BoundColumns<Name, Fields> & Plan.RowSet<BoundColumns<Name, Fields>, never, Record<Name, Plan.Source<Name, "required", TrueFormula>>, TableDialect<Fields>>;
|
|
78
|
+
/**
|
|
79
|
+
* Static class-based table definition.
|
|
80
|
+
*
|
|
81
|
+
* The class object itself acts as the table definition, exposing static bound
|
|
82
|
+
* columns, derived schemas, and plan metadata.
|
|
83
|
+
*/
|
|
84
|
+
export type TableClassStatic<Name extends string, Fields extends TableFieldMap, PrimaryKeyColumns extends keyof Fields & string = InlinePrimaryKeyKeys<Fields>, SchemaName extends string | undefined = DefaultSchemaName> = (abstract new (...args: any[]) => any) & Pipeable & {
|
|
85
|
+
readonly columns: BoundColumns<Name, Fields>;
|
|
86
|
+
readonly schemas: TableSchemas<Name, Fields, PrimaryKeyColumns>;
|
|
87
|
+
readonly [TypeId]: TableState<Name, Fields, PrimaryKeyColumns, "schema", SchemaName>;
|
|
88
|
+
readonly [Plan.TypeId]: Plan.State<BoundColumns<Name, Fields>, never, Record<Name, Plan.Source<Name, "required", TrueFormula>>, TableDialect<Fields>>;
|
|
89
|
+
readonly [OptionsSymbol]: readonly TableOptionSpec[];
|
|
90
|
+
readonly [DeclaredOptionsSymbol]?: readonly TableOptionSpec[];
|
|
91
|
+
readonly [options]?: ClassDeclaredTableOptions;
|
|
92
|
+
readonly tableName: Name;
|
|
93
|
+
} & BoundColumns<Name, Fields> & Plan.RowSet<BoundColumns<Name, Fields>, never, Record<Name, Plan.Source<Name, "required", TrueFormula>>, TableDialect<Fields>>;
|
|
94
|
+
/** Minimal structural table-like contract used across helper APIs. */
|
|
95
|
+
export type AnyTable = TableDefinition<any, any, any, any, any> | TableClassStatic<any, any, any, any>;
|
|
96
|
+
/** Public table-option builder type used by `Table.index`, `Table.primaryKey`, and friends. */
|
|
97
|
+
export type TableOption<Spec extends TableOptionSpec = TableOptionSpec> = {
|
|
98
|
+
<Name extends string, Fields extends TableFieldMap, PrimaryKeyColumns extends keyof Fields & string>(table: OptionInputTable<TableDefinition<Name, Fields, PrimaryKeyColumns, "schema", any>, Spec>): ApplyOption<TableDefinition<Name, Fields, PrimaryKeyColumns, "schema", any>, Spec>;
|
|
99
|
+
readonly option: Spec;
|
|
100
|
+
};
|
|
101
|
+
export declare const option: <Spec extends TableOptionSpec>(spec: Spec) => TableOption<Spec>;
|
|
102
|
+
export declare const optionFromTable: <Spec extends TableOptionSpec>(spec: Spec, resolve: (table: TableDefinition<any, any, any, "schema", any>) => Spec) => TableOption<Spec>;
|
|
103
|
+
/** Creates a table definition from a name and field map. */
|
|
104
|
+
export declare function make<Name extends string, Fields extends TableFieldMap, SchemaName extends string | undefined = DefaultSchemaName>(name: Name, fields: Fields, schemaName?: SchemaName): TableDefinition<Name, Fields, InlinePrimaryKeyKeys<Fields>, "schema", SchemaName>;
|
|
105
|
+
/**
|
|
106
|
+
* Creates a namespace-scoped builder for a concrete SQL schema/database.
|
|
107
|
+
*/
|
|
108
|
+
export declare const schema: <SchemaName extends string>(schemaName: SchemaName) => TableSchemaNamespace<SchemaName>;
|
|
109
|
+
/**
|
|
110
|
+
* Creates an aliased source from an existing table definition.
|
|
111
|
+
*
|
|
112
|
+
* The alias becomes the logical source identity used by the query layer while
|
|
113
|
+
* the original physical table name is retained in bound-column provenance for
|
|
114
|
+
* downstream SQL rendering work.
|
|
115
|
+
*/
|
|
116
|
+
export declare const alias: <Name extends string, Fields extends TableFieldMap, PrimaryKeyColumns extends keyof Fields & string, SchemaName extends string, AliasName extends string>(table: TableClassStatic<Name, Fields, PrimaryKeyColumns, SchemaName> | TableDefinition<Name, Fields, PrimaryKeyColumns, any, SchemaName>, aliasName: AliasName) => TableDefinition<AliasName, Fields, PrimaryKeyColumns, "alias", SchemaName>;
|
|
117
|
+
/**
|
|
118
|
+
* Class-based table constructor mirroring `Schema.Class`.
|
|
119
|
+
*
|
|
120
|
+
* The returned base class can be extended and configured with
|
|
121
|
+
* `static readonly [Table.options]`.
|
|
122
|
+
*/
|
|
123
|
+
export declare function Class<Self = never, SchemaName extends string | undefined = DefaultSchemaName>(name: string, schemaName?: SchemaName): <Fields extends TableFieldMap>(fields: Fields) => [Self] extends [never] ? "Missing `Self` generic - use `class Self extends Table.Class<Self>(...) {}`" : TableClassStatic<string, Fields, Extract<{ [K in keyof Fields]: Fields[K]["metadata"]["primaryKey"] extends true ? K : never; }[keyof Fields], string>, SchemaName>;
|
|
124
|
+
/** Declares a table-level primary key. */
|
|
125
|
+
export declare const primaryKey: <const Columns extends string | readonly string[]>(columns: Columns) => TableOption<{
|
|
126
|
+
readonly kind: "primaryKey";
|
|
127
|
+
readonly columns: NormalizeColumns<Columns>;
|
|
128
|
+
}>;
|
|
129
|
+
/** Declares a table-level unique constraint. */
|
|
130
|
+
export declare const unique: <const Columns extends string | readonly string[]>(columns: Columns) => TableOption<{
|
|
131
|
+
readonly kind: "unique";
|
|
132
|
+
readonly columns: NormalizeColumns<Columns>;
|
|
133
|
+
}>;
|
|
134
|
+
/** Declares a table-level index. */
|
|
135
|
+
export declare const index: <const Columns extends string | readonly string[]>(columns: Columns) => TableOption<{
|
|
136
|
+
readonly kind: "index";
|
|
137
|
+
readonly columns: NormalizeColumns<Columns>;
|
|
138
|
+
}>;
|
|
139
|
+
/** Declares a table-level foreign key. */
|
|
140
|
+
export declare const foreignKey: <const LocalColumns extends string | readonly string[], TargetTable extends AnyTable, const TargetColumns extends string | readonly string[]>(columns: LocalColumns, target: () => TargetTable, referencedColumns: TargetColumns) => TableOption<{
|
|
141
|
+
readonly kind: "foreignKey";
|
|
142
|
+
readonly columns: NormalizeColumns<LocalColumns>;
|
|
143
|
+
readonly references: () => {
|
|
144
|
+
readonly tableName: string;
|
|
145
|
+
readonly schemaName?: string | undefined;
|
|
146
|
+
readonly columns: NormalizeColumns<TargetColumns>;
|
|
147
|
+
readonly knownColumns: readonly string[];
|
|
148
|
+
};
|
|
149
|
+
}>;
|
|
150
|
+
/** Declares a check constraint expression. */
|
|
151
|
+
export declare const check: <Name extends string>(name: Name, predicate: DdlExpressionLike) => TableOption<{
|
|
152
|
+
readonly kind: "check";
|
|
153
|
+
readonly name: Name;
|
|
154
|
+
readonly predicate: DdlExpressionLike;
|
|
155
|
+
}>;
|
|
156
|
+
/** Extracts the row type of a table's select schema. */
|
|
157
|
+
export type SelectOf<Table extends {
|
|
158
|
+
readonly schemas: {
|
|
159
|
+
readonly select: Schema.Schema<any>;
|
|
160
|
+
};
|
|
161
|
+
}> = Schema.Schema.Type<Table["schemas"]["select"]>;
|
|
162
|
+
/** Extracts the payload type of a table's insert schema. */
|
|
163
|
+
export type InsertOf<Table extends {
|
|
164
|
+
readonly schemas: {
|
|
165
|
+
readonly insert: Schema.Schema<any>;
|
|
166
|
+
};
|
|
167
|
+
}> = Schema.Schema.Type<Table["schemas"]["insert"]>;
|
|
168
|
+
/** Extracts the payload type of a table's update schema. */
|
|
169
|
+
export type UpdateOf<Table extends {
|
|
170
|
+
readonly schemas: {
|
|
171
|
+
readonly update: Schema.Schema<any>;
|
|
172
|
+
};
|
|
173
|
+
}> = Schema.Schema.Type<Table["schemas"]["update"]>;
|