@minnowdb/core 0.4.1 → 0.6.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 +5 -5
- package/dist/engine/cancellation.d.ts +2 -0
- package/dist/engine/cancellation.js +4 -0
- package/dist/engine/catalog.d.ts +5 -1
- package/dist/engine/catalog.js +5 -1
- package/dist/engine/client.d.ts +34 -6
- package/dist/engine/client.js +87 -19
- package/dist/engine/database.d.ts +43 -20
- package/dist/engine/database.js +823 -164
- package/dist/engine/defaults.js +11 -0
- package/dist/engine/errors.d.ts +19 -0
- package/dist/engine/errors.js +31 -0
- package/dist/engine/fts.d.ts +2 -15
- package/dist/engine/live.d.ts +1 -7
- package/dist/engine/live.js +12 -13
- package/dist/engine/optimizer.js +546 -39
- package/dist/engine/query-cache.js +1 -0
- package/dist/engine/query.d.ts +16 -278
- package/dist/engine/query.js +260 -74
- package/dist/engine/result-wire.d.ts +2 -0
- package/dist/engine/result-wire.js +21 -5
- package/dist/engine/schema-wire.d.ts +14 -1
- package/dist/engine/schema-wire.js +7 -1
- package/dist/engine/schema.d.ts +83 -32
- package/dist/engine/schema.js +180 -14
- package/dist/engine/sql-domains.d.ts +11 -0
- package/dist/engine/sql-domains.js +65 -1
- package/dist/engine/sql-json.js +22 -3
- package/dist/engine/sql-semantics.js +21 -3
- package/dist/engine/vector.d.ts +2 -2
- package/dist/engine/vector.js +328 -79
- package/dist/engine/worker-host.js +119 -44
- package/dist/plan/index.d.ts +5 -4
- package/dist/plan/index.js +3 -3
- package/dist/plan/model.d.ts +218 -0
- package/dist/plan/model.js +1 -0
- package/dist/storage/indexeddb.js +4 -12
- package/dist/storage/toolkit/record-core.js +7 -22
- package/dist/storage/types.d.ts +26 -8
- package/dist/storage/types.js +85 -0
- package/dist/transactions/index.d.ts +5 -3
- package/dist/transactions/index.js +58 -8
- package/dist/worker-protocol/index.d.ts +6 -1
- package/dist/worker-protocol/index.js +5 -2
- package/package.json +1 -1
- package/postgres-feature-profile.json +5 -0
- package/sql-feature-matrix.json +75 -19
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import type { SqlDomain } from "../storage/types.js";
|
|
1
2
|
import type { QueryResult, QueryRow, QueryValue } from "./query.js";
|
|
2
3
|
/**
|
|
3
4
|
* The shape a query result takes on the worker channel. A result is rows of objects at the
|
|
@@ -49,6 +50,7 @@ export type WireResultColumn = {
|
|
|
49
50
|
export interface WireQueryResult {
|
|
50
51
|
readonly kind: "columnar-result";
|
|
51
52
|
readonly columns: string[];
|
|
53
|
+
readonly columnDomains: Array<SqlDomain | null>;
|
|
52
54
|
readonly rowCount: number;
|
|
53
55
|
readonly values: WireResultColumn[];
|
|
54
56
|
}
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { dateMilliseconds } from "../date-value.js";
|
|
2
|
+
import { unknownColumnDomains } from "./query.js";
|
|
2
3
|
export function encodeQueryResult(result) {
|
|
3
|
-
return encodeRows(result.columns, result.rows);
|
|
4
|
+
return encodeRows(result.columns, result.rows, result.columnDomains);
|
|
4
5
|
}
|
|
5
6
|
/**
|
|
6
7
|
* Encodes a bare row array (`run()` returns rows without a column list). Every row of one result
|
|
@@ -8,13 +9,18 @@ export function encodeQueryResult(result) {
|
|
|
8
9
|
*/
|
|
9
10
|
export function encodeQueryRows(rows) {
|
|
10
11
|
const first = rows[0];
|
|
11
|
-
|
|
12
|
+
const columns = first === undefined ? [] : Object.keys(first);
|
|
13
|
+
return encodeRows(columns, rows, unknownColumnDomains(columns));
|
|
12
14
|
}
|
|
13
15
|
export function decodeQueryResult(payload) {
|
|
14
16
|
if (!isWireQueryResult(payload)) {
|
|
15
17
|
throw new TypeError("Expected a columnar query result frame");
|
|
16
18
|
}
|
|
17
19
|
const columns = [...payload.columns];
|
|
20
|
+
if (payload.values.length !== columns.length || payload.columnDomains.length !== columns.length) {
|
|
21
|
+
throw new TypeError("Columnar result frame metadata is not aligned");
|
|
22
|
+
}
|
|
23
|
+
const columnDomains = structuredClone(payload.columnDomains);
|
|
18
24
|
const rows = [];
|
|
19
25
|
for (let index = 0; index < payload.rowCount; index += 1)
|
|
20
26
|
rows.push({});
|
|
@@ -26,17 +32,21 @@ export function decodeQueryResult(payload) {
|
|
|
26
32
|
throw new TypeError("Columnar result frame is missing a column");
|
|
27
33
|
fillColumn(rows, name, column);
|
|
28
34
|
}
|
|
29
|
-
return { columns, rows };
|
|
35
|
+
return { columns, columnDomains, rows };
|
|
30
36
|
}
|
|
31
37
|
export function isWireQueryResult(value) {
|
|
32
38
|
return (typeof value === "object" &&
|
|
33
39
|
value !== null &&
|
|
34
40
|
value.kind === "columnar-result" &&
|
|
35
41
|
Array.isArray(value.columns) &&
|
|
42
|
+
Array.isArray(value.columnDomains) &&
|
|
36
43
|
Array.isArray(value.values) &&
|
|
37
44
|
typeof value.rowCount === "number");
|
|
38
45
|
}
|
|
39
|
-
function encodeRows(columns, rows) {
|
|
46
|
+
function encodeRows(columns, rows, columnDomains) {
|
|
47
|
+
if (columnDomains.length !== columns.length) {
|
|
48
|
+
throw new TypeError("Query result column domains must align with the result columns");
|
|
49
|
+
}
|
|
40
50
|
const transfer = [];
|
|
41
51
|
const values = columns.map((name) => {
|
|
42
52
|
const column = encodeColumn(name, rows);
|
|
@@ -53,7 +63,13 @@ function encodeRows(columns, rows) {
|
|
|
53
63
|
return column;
|
|
54
64
|
});
|
|
55
65
|
return {
|
|
56
|
-
payload: {
|
|
66
|
+
payload: {
|
|
67
|
+
kind: "columnar-result",
|
|
68
|
+
columns: [...columns],
|
|
69
|
+
columnDomains: structuredClone([...columnDomains]),
|
|
70
|
+
rowCount: rows.length,
|
|
71
|
+
values,
|
|
72
|
+
},
|
|
57
73
|
transfer,
|
|
58
74
|
};
|
|
59
75
|
}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { ColumnDefault, SqlDomain } from "../storage/types.js";
|
|
1
|
+
import type { ColumnDefault, ColumnGenerated, SqlDomain } from "../storage/types.js";
|
|
2
2
|
import { type AnyTable, type MigrationStep, type ReferentialAction, type SchemaColumnType, type SchemaDefinition, type TableCheck, type TableForeignKey } from "./schema.js";
|
|
3
3
|
/**
|
|
4
4
|
* Structured-clone-safe mirror of the schema DSL. Column builders and table validators carry
|
|
@@ -12,11 +12,13 @@ export interface WireColumn {
|
|
|
12
12
|
readonly integer?: true;
|
|
13
13
|
readonly sqlDomain?: SqlDomain;
|
|
14
14
|
readonly defaultSpec?: ColumnDefault;
|
|
15
|
+
readonly generatedSpec?: ColumnGenerated;
|
|
15
16
|
readonly renamedFromName?: string;
|
|
16
17
|
readonly reference?: {
|
|
17
18
|
table: string;
|
|
18
19
|
column: string;
|
|
19
20
|
onDelete: ReferentialAction;
|
|
21
|
+
enforced?: boolean;
|
|
20
22
|
};
|
|
21
23
|
readonly enumValues?: readonly string[];
|
|
22
24
|
/** Already frozen by planning, so the wire carries a value and never a generator. */
|
|
@@ -83,6 +85,17 @@ export type WireMigrationStep = {
|
|
|
83
85
|
tableName: string;
|
|
84
86
|
columnName: string;
|
|
85
87
|
defaultValue: ColumnDefault | null;
|
|
88
|
+
} | {
|
|
89
|
+
kind: "alter-generated";
|
|
90
|
+
tableName: string;
|
|
91
|
+
columnName: string;
|
|
92
|
+
generatedValue: ColumnGenerated | null;
|
|
93
|
+
} | {
|
|
94
|
+
kind: "alter-foreign-keys";
|
|
95
|
+
tableName: string;
|
|
96
|
+
foreignKeys: Extract<MigrationStep, {
|
|
97
|
+
kind: "alter-foreign-keys";
|
|
98
|
+
}>["foreignKeys"];
|
|
86
99
|
} | {
|
|
87
100
|
kind: "replace-view";
|
|
88
101
|
view: WireView;
|
|
@@ -14,6 +14,9 @@ function serializeColumn(definition, frozen) {
|
|
|
14
14
|
? {}
|
|
15
15
|
: { sqlDomain: structuredClone(definition.sqlDomain) }),
|
|
16
16
|
...(definition.defaultSpec === undefined ? {} : { defaultSpec: { ...definition.defaultSpec } }),
|
|
17
|
+
...(definition.generatedSpec === undefined
|
|
18
|
+
? {}
|
|
19
|
+
: { generatedSpec: { ...definition.generatedSpec } }),
|
|
17
20
|
...(definition.renamedFromName === undefined
|
|
18
21
|
? {}
|
|
19
22
|
: { renamedFromName: definition.renamedFromName }),
|
|
@@ -95,8 +98,11 @@ function deserializeColumn(wire) {
|
|
|
95
98
|
integer: wire.integer === true,
|
|
96
99
|
...(wire.sqlDomain === undefined ? {} : { sqlDomain: structuredClone(wire.sqlDomain) }),
|
|
97
100
|
...(wire.defaultSpec === undefined ? {} : { defaultSpec: wire.defaultSpec }),
|
|
101
|
+
...(wire.generatedSpec === undefined ? {} : { generatedSpec: wire.generatedSpec }),
|
|
98
102
|
...(wire.renamedFromName === undefined ? {} : { renamedFromName: wire.renamedFromName }),
|
|
99
|
-
...(wire.reference === undefined
|
|
103
|
+
...(wire.reference === undefined
|
|
104
|
+
? {}
|
|
105
|
+
: { reference: { ...wire.reference, enforced: wire.reference.enforced !== false } }),
|
|
100
106
|
...(wire.enumValues === undefined ? {} : { enumValues: wire.enumValues }),
|
|
101
107
|
...(wire.backfillValue === undefined ? {} : { backfillValue: wire.backfillValue }),
|
|
102
108
|
});
|
package/dist/engine/schema.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { type ColumnDefault, type SqlDomain, type TableColumnRecord, type TableRecord } from "../storage/types.js";
|
|
2
2
|
import { type Catalog, type CatalogColumn, type CatalogTable } from "./catalog.js";
|
|
3
|
-
import { type QueryValue } from "./query.js";
|
|
3
|
+
import { type Expression, type QueryValue } from "./query.js";
|
|
4
4
|
/**
|
|
5
5
|
* Typed schema DSL and catalog migration planning. Column builders carry compile-time value and
|
|
6
6
|
* nullability types; `planMigration` diffs a schema against the live catalog into metadata-only
|
|
@@ -9,6 +9,14 @@ import { type QueryValue } from "./query.js";
|
|
|
9
9
|
* catalog-only, and older segments read the new column as NULL.
|
|
10
10
|
*/
|
|
11
11
|
export type SchemaColumnType = "boolean" | "number" | "string" | "datetime";
|
|
12
|
+
/** Compiles and validates one immutable, row-local generated-column expression. */
|
|
13
|
+
export declare function compileGeneratedColumnExpression(tableName: string, columnName: string, sql: string, columns: ReadonlyArray<{
|
|
14
|
+
readonly name: string;
|
|
15
|
+
readonly generatedValue?: {
|
|
16
|
+
readonly kind: "stored";
|
|
17
|
+
readonly sql: string;
|
|
18
|
+
};
|
|
19
|
+
}>): Expression;
|
|
12
20
|
/** What a FOREIGN KEY does to child rows when the parent row is deleted (E141-04). */
|
|
13
21
|
export type ReferentialAction = "restrict" | "cascade" | "set null";
|
|
14
22
|
/** A declared relation. `onDelete` defaults to "restrict", matching SQL's own default. */
|
|
@@ -16,6 +24,7 @@ export interface ColumnReferenceSpec {
|
|
|
16
24
|
readonly table: string;
|
|
17
25
|
readonly column: string;
|
|
18
26
|
readonly onDelete: ReferentialAction;
|
|
27
|
+
readonly enforced: boolean;
|
|
19
28
|
}
|
|
20
29
|
/** A row condition every write must satisfy (E141-06); `sql` is a boolean expression. */
|
|
21
30
|
export interface TableCheck {
|
|
@@ -31,6 +40,8 @@ export interface TableForeignKey<TColumnName extends string = string> {
|
|
|
31
40
|
readonly columns: readonly string[];
|
|
32
41
|
};
|
|
33
42
|
readonly onDelete?: ReferentialAction;
|
|
43
|
+
/** False keeps the relationship in the catalog without validating or cascading rows. */
|
|
44
|
+
readonly enforced?: boolean;
|
|
34
45
|
}
|
|
35
46
|
/**
|
|
36
47
|
* The constraint name `migrate()` gives a declared relation. It matches the name the SQL parser
|
|
@@ -44,22 +55,29 @@ export declare function foreignKeyName(tableName: string, columnName: string): s
|
|
|
44
55
|
export type HasDefault<TValue> = TValue & {
|
|
45
56
|
readonly __minnowHasDefault?: true;
|
|
46
57
|
};
|
|
47
|
-
export interface ColumnBuilder<TValue extends SchemaValue, TNullable extends boolean, TUnique extends boolean = false, THasDefault extends boolean = false, TInput extends SchemaValue = TValue> {
|
|
58
|
+
export interface ColumnBuilder<TValue extends SchemaValue, TNullable extends boolean, TUnique extends boolean = false, THasDefault extends boolean = false, TInput extends SchemaValue = TValue, TDomain extends SqlDomain["kind"] | undefined = undefined, TGenerated extends boolean = false> {
|
|
48
59
|
readonly kind: "column";
|
|
49
60
|
readonly type: SchemaColumnType;
|
|
50
61
|
readonly isNullable: TNullable;
|
|
51
62
|
readonly isUnique: TUnique;
|
|
52
63
|
readonly hasDefault: THasDefault;
|
|
64
|
+
readonly isGenerated: TGenerated;
|
|
53
65
|
/** Type-only metadata consumed by adapters; optional so it emits no runtime payload. */
|
|
54
66
|
readonly "~types"?: {
|
|
55
67
|
readonly select: TValue;
|
|
56
68
|
readonly input: TInput;
|
|
69
|
+
readonly domain: TDomain;
|
|
70
|
+
readonly generated: TGenerated;
|
|
57
71
|
};
|
|
58
72
|
/** True for exact SQL integer columns; ordinary number columns use Float64 semantics. */
|
|
59
73
|
readonly integer: boolean;
|
|
60
74
|
/** Logical SQL semantics layered over the stable string storage encoding. */
|
|
61
75
|
readonly sqlDomain?: SqlDomain;
|
|
62
76
|
readonly defaultSpec?: ColumnDefault;
|
|
77
|
+
readonly generatedSpec?: {
|
|
78
|
+
readonly kind: "stored";
|
|
79
|
+
readonly sql: string;
|
|
80
|
+
};
|
|
63
81
|
/** Present on `column.enum()` builders: the closed set of values writes must draw from. */
|
|
64
82
|
readonly enumValues?: readonly string[];
|
|
65
83
|
/** What rows written before this column existed read as; see `.backfill()`. */
|
|
@@ -67,11 +85,11 @@ export interface ColumnBuilder<TValue extends SchemaValue, TNullable extends boo
|
|
|
67
85
|
readonly renamedFromName?: string;
|
|
68
86
|
readonly reference?: ColumnReferenceSpec;
|
|
69
87
|
/** Marks the column nullable; inserts may omit it and reads may return null. */
|
|
70
|
-
nullable(): ColumnBuilder<TValue, true, TUnique, THasDefault, TInput>;
|
|
88
|
+
nullable(): ColumnBuilder<TValue, true, TUnique, THasDefault, TInput, TDomain, TGenerated>;
|
|
71
89
|
/** Marks the table's unique key; exactly one non-nullable column may carry it. */
|
|
72
|
-
unique(this: ColumnBuilder<TValue, false, TUnique, THasDefault, TInput>): ColumnBuilder<TValue, TNullable, true, THasDefault, TInput>;
|
|
90
|
+
unique(this: ColumnBuilder<TValue, false, TUnique, THasDefault, TInput, TDomain, TGenerated>): ColumnBuilder<TValue, TNullable, true, THasDefault, TInput, TDomain, TGenerated>;
|
|
73
91
|
/** Declares this column as the rename target of an existing catalog column. */
|
|
74
|
-
renamedFrom(name: string): ColumnBuilder<TValue, TNullable, TUnique, THasDefault, TInput>;
|
|
92
|
+
renamedFrom(name: string): ColumnBuilder<TValue, TNullable, TUnique, THasDefault, TInput, TDomain, TGenerated>;
|
|
75
93
|
/**
|
|
76
94
|
* What rows written before this column existed read as, instead of NULL. Giving one is what
|
|
77
95
|
* makes adding a non-nullable column possible: no stored byte is rewritten, and reads
|
|
@@ -81,7 +99,7 @@ export interface ColumnBuilder<TValue extends SchemaValue, TNullable extends boo
|
|
|
81
99
|
* catalog — so it can derive a value (a timestamp, a version stamp) without readers ever
|
|
82
100
|
* disagreeing. It cannot derive from other columns; that would need a value per row.
|
|
83
101
|
*/
|
|
84
|
-
backfill(this: ColumnBuilder<TValue, false, TUnique, THasDefault, TInput>, value: TInput | (() => TInput)): ColumnBuilder<TValue, TNullable, TUnique, THasDefault, TInput>;
|
|
102
|
+
backfill(this: ColumnBuilder<TValue, false, TUnique, THasDefault, TInput, TDomain, TGenerated>, value: TInput | (() => TInput)): ColumnBuilder<TValue, TNullable, TUnique, THasDefault, TInput, TDomain, TGenerated>;
|
|
85
103
|
/**
|
|
86
104
|
* Declares a FOREIGN KEY onto another table's unique key. `migrate()` creates it as a real
|
|
87
105
|
* constraint, so a write naming a parent row that does not exist is rejected — the same
|
|
@@ -89,26 +107,33 @@ export interface ColumnBuilder<TValue extends SchemaValue, TNullable extends boo
|
|
|
89
107
|
*
|
|
90
108
|
* `onDelete` defaults to `"restrict"`. `"set null"` requires a nullable column.
|
|
91
109
|
*/
|
|
92
|
-
references(this: ColumnBuilder<TValue, TNullable, TUnique, THasDefault, TInput>, table: string, column: string, options?: {
|
|
110
|
+
references(this: ColumnBuilder<TValue, TNullable, TUnique, THasDefault, TInput, TDomain, TGenerated>, table: string, column: string, options?: {
|
|
93
111
|
onDelete?: Exclude<ReferentialAction, "set null">;
|
|
94
|
-
|
|
95
|
-
|
|
112
|
+
enforced?: true;
|
|
113
|
+
} | {
|
|
114
|
+
enforced: false;
|
|
115
|
+
onDelete?: never;
|
|
116
|
+
}): ColumnBuilder<TValue, TNullable, TUnique, THasDefault, TInput, TDomain, TGenerated>;
|
|
117
|
+
references(this: ColumnBuilder<TValue, true, TUnique, THasDefault, TInput, TDomain, TGenerated>, table: string, column: string, options: {
|
|
96
118
|
onDelete: "set null";
|
|
97
|
-
|
|
119
|
+
enforced?: true;
|
|
120
|
+
}): ColumnBuilder<TValue, TNullable, TUnique, THasDefault, TInput, TDomain, TGenerated>;
|
|
98
121
|
/** Declares a literal SQL default. Omission or SQL `DEFAULT` invokes it; NULL does not. */
|
|
99
|
-
default(value: TInput): ColumnBuilder<TValue, TNullable, TUnique, true, TInput>;
|
|
122
|
+
default(value: TInput): ColumnBuilder<TValue, TNullable, TUnique, true, TInput, TDomain, TGenerated>;
|
|
100
123
|
/**
|
|
101
124
|
* Declares a variable-free SQL default expression, such as `CURRENT_TIMESTAMP`,
|
|
102
125
|
* `gen_random_uuid()`, or `nextval('orders_id_seq')`. The engine parses and type-checks it
|
|
103
126
|
* before migration and evaluates it once per omitted row.
|
|
104
127
|
*/
|
|
105
|
-
defaultSql(sql: string): ColumnBuilder<TValue, TNullable, TUnique, true, TInput>;
|
|
128
|
+
defaultSql(sql: string): ColumnBuilder<TValue, TNullable, TUnique, true, TInput, TDomain, TGenerated>;
|
|
129
|
+
/** Declares a stored expression over sibling columns. Callers never insert or update it. */
|
|
130
|
+
generatedSql(sql: string): ColumnBuilder<TValue, TNullable, TUnique, false, TInput, TDomain, true>;
|
|
106
131
|
/**
|
|
107
132
|
* Generates monotonically increasing integers for omitted or SQL `DEFAULT` slots from a persistent
|
|
108
133
|
* per-table counter that is atomic across tabs. Explicit values are allowed and bump the
|
|
109
134
|
* counter past their maximum. Number unique-key columns only.
|
|
110
135
|
*/
|
|
111
|
-
autoIncrement: TValue extends number ? (this: ColumnBuilder<TValue, false, true, THasDefault, TInput>) => ColumnBuilder<TValue, TNullable, TUnique, true, TInput> : never;
|
|
136
|
+
autoIncrement: TValue extends number ? (this: ColumnBuilder<TValue, false, true, THasDefault, TInput, TDomain, TGenerated>) => ColumnBuilder<TValue, TNullable, TUnique, true, TInput, TDomain, TGenerated> : never;
|
|
112
137
|
}
|
|
113
138
|
type SchemaValue = boolean | number | string | Date;
|
|
114
139
|
/**
|
|
@@ -122,9 +147,14 @@ interface AnyColumn {
|
|
|
122
147
|
readonly isNullable: boolean;
|
|
123
148
|
readonly isUnique: boolean;
|
|
124
149
|
readonly hasDefault: boolean;
|
|
150
|
+
readonly isGenerated: boolean;
|
|
125
151
|
readonly integer: boolean;
|
|
126
152
|
readonly sqlDomain?: SqlDomain;
|
|
127
153
|
readonly defaultSpec?: ColumnDefault;
|
|
154
|
+
readonly generatedSpec?: {
|
|
155
|
+
readonly kind: "stored";
|
|
156
|
+
readonly sql: string;
|
|
157
|
+
};
|
|
128
158
|
readonly enumValues?: readonly string[];
|
|
129
159
|
readonly backfillValue?: SchemaValue | (() => SchemaValue);
|
|
130
160
|
readonly renamedFromName?: string;
|
|
@@ -136,28 +166,30 @@ interface AnyColumn {
|
|
|
136
166
|
*/
|
|
137
167
|
export declare function columnWithDefaultSpec(base: Pick<AnyColumn, "type" | "isNullable" | "isUnique" | "renamedFromName" | "reference" | "enumValues"> & Partial<Pick<AnyColumn, "integer" | "sqlDomain">>, spec: ColumnDefault): AnyColumn;
|
|
138
168
|
/** Rebuilds a fluent column from structured-clone-safe metadata. */
|
|
139
|
-
export declare function columnFromState(state: Pick<AnyColumn, "type" | "isNullable" | "isUnique"> & Partial<Pick<AnyColumn, "integer" | "sqlDomain" | "renamedFromName" | "reference" | "defaultSpec" | "enumValues" | "backfillValue">>): AnyColumn;
|
|
169
|
+
export declare function columnFromState(state: Pick<AnyColumn, "type" | "isNullable" | "isUnique"> & Partial<Pick<AnyColumn, "integer" | "sqlDomain" | "renamedFromName" | "reference" | "defaultSpec" | "generatedSpec" | "enumValues" | "backfillValue">>): AnyColumn;
|
|
140
170
|
export declare const column: {
|
|
141
|
-
boolean: () => ColumnBuilder<boolean, false, false, false, boolean>;
|
|
142
|
-
number: () => ColumnBuilder<number, false, false, false, number>;
|
|
171
|
+
boolean: () => ColumnBuilder<boolean, false, false, false, boolean, undefined, false>;
|
|
172
|
+
number: () => ColumnBuilder<number, false, false, false, number, undefined, false>;
|
|
143
173
|
/** Exact safe-integer semantics, matching SQL INTEGER/SMALLINT/BIGINT. */
|
|
144
|
-
integer: () => ColumnBuilder<number, false, false, false, number>;
|
|
145
|
-
string: () => ColumnBuilder<string, false, false, false, string>;
|
|
146
|
-
datetime: () => ColumnBuilder<Date, false, false, false, Date>;
|
|
174
|
+
integer: () => ColumnBuilder<number, false, false, false, number, undefined, false>;
|
|
175
|
+
string: () => ColumnBuilder<string, false, false, false, string, undefined, false>;
|
|
176
|
+
datetime: () => ColumnBuilder<Date, false, false, false, Date, undefined, false>;
|
|
147
177
|
/** Exact decimal SQL NUMERIC. Selects return strings; writes accept strings or numbers. */
|
|
148
178
|
numeric: (options?: {
|
|
149
179
|
precision?: number;
|
|
150
180
|
scale?: number;
|
|
151
|
-
}) => ColumnBuilder<string, false, false, false, string | number>;
|
|
152
|
-
json: () => ColumnBuilder<string, false, false, false, string>;
|
|
153
|
-
jsonb: () => ColumnBuilder<string, false, false, false, string>;
|
|
154
|
-
uuid: () => ColumnBuilder<string, false, false, false, string>;
|
|
155
|
-
|
|
156
|
-
|
|
181
|
+
}) => ColumnBuilder<string, false, false, false, string | number, "numeric", false>;
|
|
182
|
+
json: () => ColumnBuilder<string, false, false, false, string, "json", false>;
|
|
183
|
+
jsonb: () => ColumnBuilder<string, false, false, false, string, "jsonb", false>;
|
|
184
|
+
uuid: () => ColumnBuilder<string, false, false, false, string, "uuid", false>;
|
|
185
|
+
/** A zoneless calendar date, represented publicly as canonical `YYYY-MM-DD` text. */
|
|
186
|
+
date: () => ColumnBuilder<string, false, false, false, string, "date", false>;
|
|
187
|
+
time: () => ColumnBuilder<string, false, false, false, string, "time", false>;
|
|
188
|
+
interval: () => ColumnBuilder<string, false, false, false, string, "interval", false>;
|
|
157
189
|
/** JSON array text at the JavaScript boundary, with the SQL element type retained in metadata. */
|
|
158
|
-
array: (element: string) => ColumnBuilder<string, false, false, false, string>;
|
|
190
|
+
array: (element: string) => ColumnBuilder<string, false, false, false, string, "array", false>;
|
|
159
191
|
/** A named SQL enum domain, distinct from the lightweight `column.enum()` restriction. */
|
|
160
|
-
sqlEnum: <const TValues extends readonly [string, ...string[]]>(name: string, values: TValues) => ColumnBuilder<TValues[number], false>;
|
|
192
|
+
sqlEnum: <const TValues extends readonly [string, ...string[]]>(name: string, values: TValues) => ColumnBuilder<TValues[number], false, false, false, TValues[number], "enum">;
|
|
161
193
|
/**
|
|
162
194
|
* A string column restricted to a closed set of values, typed as their literal union:
|
|
163
195
|
*
|
|
@@ -234,6 +266,7 @@ export declare function declaredForeignKeys(definition: AnyTable): Array<{
|
|
|
234
266
|
parentTable: string;
|
|
235
267
|
parentColumns: string[];
|
|
236
268
|
onDelete: ReferentialAction;
|
|
269
|
+
enforced: boolean;
|
|
237
270
|
}>;
|
|
238
271
|
/**
|
|
239
272
|
* A view declared in the schema: the query it stands for, plus the column shape the author
|
|
@@ -299,11 +332,15 @@ type NullableKeys<TTable extends AnyTable> = {
|
|
|
299
332
|
type DefaultKeys<TTable extends AnyTable> = {
|
|
300
333
|
[K in keyof TTable["columns"]]: TTable["columns"][K]["hasDefault"] extends true ? K : never;
|
|
301
334
|
}[keyof TTable["columns"]];
|
|
302
|
-
type
|
|
335
|
+
type GeneratedKeys<TTable extends AnyTable> = {
|
|
336
|
+
[K in keyof TTable["columns"]]: TTable["columns"][K]["isGenerated"] extends true ? K : never;
|
|
337
|
+
}[keyof TTable["columns"]];
|
|
338
|
+
type OptionalInsertKeys<TTable extends AnyTable> = Exclude<NullableKeys<TTable> | DefaultKeys<TTable>, GeneratedKeys<TTable>>;
|
|
339
|
+
type RequiredInsertKeys<TTable extends AnyTable> = Exclude<keyof TTable["columns"], OptionalInsertKeys<TTable> | GeneratedKeys<TTable>>;
|
|
303
340
|
/** Insert rows require every non-nullable column and may omit nullable or default-bearing ones. */
|
|
304
|
-
export type InferInsertRow<TTable extends AnyTable> =
|
|
305
|
-
[K in
|
|
306
|
-
}
|
|
341
|
+
export type InferInsertRow<TTable extends AnyTable> = {
|
|
342
|
+
[K in RequiredInsertKeys<TTable>]: ColumnInputValue<TTable["columns"][K]>;
|
|
343
|
+
} & {
|
|
307
344
|
[K in OptionalInsertKeys<TTable>]?: ColumnInputValue<TTable["columns"][K]>;
|
|
308
345
|
};
|
|
309
346
|
/** Scalar `.unique()` keys plus columns named by a table-level primary key. */
|
|
@@ -316,7 +353,7 @@ export type PrimaryKeyKeys<TTable extends AnyTable> = {
|
|
|
316
353
|
* stays assignable under `exactOptionalPropertyTypes`.
|
|
317
354
|
*/
|
|
318
355
|
export type InferUpdateChanges<TTable extends AnyTable> = {
|
|
319
|
-
[K in keyof TTable["columns"] as K extends PrimaryKeyKeys<TTable> ? never : K]?: ColumnInputValue<TTable["columns"][K]> | undefined;
|
|
356
|
+
[K in keyof TTable["columns"] as K extends PrimaryKeyKeys<TTable> | GeneratedKeys<TTable> ? never : K]?: ColumnInputValue<TTable["columns"][K]> | undefined;
|
|
320
357
|
};
|
|
321
358
|
export type MigrationStep = {
|
|
322
359
|
kind: "create-table";
|
|
@@ -365,6 +402,20 @@ export type MigrationStep = {
|
|
|
365
402
|
tableName: string;
|
|
366
403
|
columnName: string;
|
|
367
404
|
defaultValue: ColumnDefault | null;
|
|
405
|
+
} | {
|
|
406
|
+
kind: "alter-generated";
|
|
407
|
+
tableName: string;
|
|
408
|
+
columnName: string;
|
|
409
|
+
generatedValue: {
|
|
410
|
+
readonly kind: "stored";
|
|
411
|
+
readonly sql: string;
|
|
412
|
+
} | null;
|
|
413
|
+
}
|
|
414
|
+
/** Informational relationships are catalog-only and may change without scanning stored rows. */
|
|
415
|
+
| {
|
|
416
|
+
kind: "alter-foreign-keys";
|
|
417
|
+
tableName: string;
|
|
418
|
+
foreignKeys: ReturnType<typeof declaredForeignKeys>;
|
|
368
419
|
}
|
|
369
420
|
/**
|
|
370
421
|
* A view is derived and disposable: nothing is stored under it, so replacing its body loses no
|