@simplysm/orm-common 14.0.22 → 14.0.24

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.
@@ -1,150 +0,0 @@
1
- # Query Builder
2
-
3
- Transforms `QueryDef` AST into dialect-specific SQL strings.
4
-
5
- ## createQueryBuilder
6
-
7
- ```typescript
8
- function createQueryBuilder(dialect: Dialect): QueryBuilderBase
9
- ```
10
-
11
- Factory function that creates a dialect-specific QueryBuilder instance.
12
-
13
- | Parameter | Type | Description |
14
- |-----------|------|-------------|
15
- | `dialect` | `"mysql" \| "mssql" \| "postgresql"` | Target DBMS dialect |
16
-
17
- Returns `MysqlQueryBuilder`, `MssqlQueryBuilder`, or `PostgresqlQueryBuilder`.
18
-
19
- ## QueryBuilderBase
20
-
21
- ```typescript
22
- abstract class QueryBuilderBase {
23
- build(def: QueryDef): QueryBuildResult;
24
- }
25
- ```
26
-
27
- Abstract base class for rendering `QueryDef` AST to SQL. Implements common dispatch logic; dialect-specific differences are handled by abstract methods in subclasses.
28
-
29
- | Method | Signature | Description |
30
- |--------|-----------|-------------|
31
- | `build` | `(def: QueryDef) => QueryBuildResult` | Convert any QueryDef to SQL |
32
-
33
- `QueryBuildResult` contains:
34
-
35
- | Field | Type | Description |
36
- |-------|------|-------------|
37
- | `sql` | `string` | Generated SQL string |
38
- | `resultSetIndex` | `number?` | Result set index for multi-statement queries |
39
- | `resultSetStride` | `number?` | Stride for extracting results from multi-statement queries |
40
-
41
- ## Dialect-Specific Query Builders
42
-
43
- ### MysqlQueryBuilder
44
-
45
- ```typescript
46
- class MysqlQueryBuilder extends QueryBuilderBase
47
- ```
48
-
49
- MySQL 8.0.14+ query builder. Handles MySQL-specific syntax such as backtick quoting, `<=>` for NULL-safe equality, `LIMIT ... OFFSET`, `LOAD DATA LOCAL INFILE`, etc.
50
-
51
- ### MssqlQueryBuilder
52
-
53
- ```typescript
54
- class MssqlQueryBuilder extends QueryBuilderBase
55
- ```
56
-
57
- MSSQL 2012+ query builder. Handles bracket quoting, `TOP`, `OFFSET ... FETCH NEXT`, `MERGE` for upsert, `SET IDENTITY_INSERT`, etc.
58
-
59
- ### PostgresqlQueryBuilder
60
-
61
- ```typescript
62
- class PostgresqlQueryBuilder extends QueryBuilderBase
63
- ```
64
-
65
- PostgreSQL 9.0+ query builder. Handles double-quote quoting, `LIMIT ... OFFSET`, `ON CONFLICT` for upsert, `COPY FROM STDIN`, etc.
66
-
67
- ## ExprRendererBase
68
-
69
- ```typescript
70
- abstract class ExprRendererBase {
71
- renderExpr(expr: Expr): string;
72
- renderWhereExpr(expr: WhereExpr): string;
73
- }
74
- ```
75
-
76
- Abstract base class for rendering `Expr` and `WhereExpr` AST nodes to SQL fragments. Each QueryBuilder uses a corresponding ExprRenderer.
77
-
78
- | Method | Signature | Description |
79
- |--------|-----------|-------------|
80
- | `renderExpr` | `(expr: Expr) => string` | Render a value/function expression to SQL |
81
- | `renderWhereExpr` | `(expr: WhereExpr) => string` | Render a WHERE condition expression to SQL |
82
-
83
- ## Dialect-Specific Expression Renderers
84
-
85
- ### MysqlExprRenderer
86
-
87
- ```typescript
88
- class MysqlExprRenderer extends ExprRendererBase
89
- ```
90
-
91
- MySQL expression renderer. Uses `<=>` for NULL-safe equality, `IFNULL`, `LOCATE`, MySQL `DATE_FORMAT` patterns, etc.
92
-
93
- ### MssqlExprRenderer
94
-
95
- ```typescript
96
- class MssqlExprRenderer extends ExprRendererBase
97
- ```
98
-
99
- MSSQL expression renderer. Uses `IIF`, `CHARINDEX`, `FORMAT` for date formatting, `DATALENGTH` for byte length, etc.
100
-
101
- ### PostgresqlExprRenderer
102
-
103
- ```typescript
104
- class PostgresqlExprRenderer extends ExprRendererBase
105
- ```
106
-
107
- PostgreSQL expression renderer. Uses `IS NOT DISTINCT FROM` for NULL-safe equality, `POSITION`, `TO_CHAR` for date formatting, `OCTET_LENGTH`, etc.
108
-
109
- ## parseQueryResult
110
-
111
- ```typescript
112
- async function parseQueryResult<TRecord>(
113
- rawResults: Record<string, unknown>[],
114
- meta: ResultMeta,
115
- ): Promise<TRecord[] | undefined>
116
- ```
117
-
118
- Parses raw database query results into typed TypeScript objects. Handles:
119
-
120
- - **Type conversion**: Converts raw values (strings, numbers) to proper TypeScript types (`DateTime`, `DateOnly`, `Uuid`, etc.) based on `ResultMeta.columns`
121
- - **JOIN nesting**: Flattens `"posts.id"` keys into nested `{ posts: { id: ... } }` objects
122
- - **Grouping**: Groups rows by non-JOIN columns, collecting JOIN data into arrays (1:N) or single objects (1:1)
123
- - **Event loop yielding**: Yields to the event loop every 100 records for large result sets
124
-
125
- | Parameter | Type | Description |
126
- |-----------|------|-------------|
127
- | `rawResults` | `Record<string, unknown>[]` | Raw DB result rows |
128
- | `meta` | `ResultMeta` | Column types and JOIN structure info |
129
-
130
- Returns `undefined` if the input is empty or all records parse to empty objects.
131
-
132
- ```typescript
133
- // Simple type parsing
134
- const raw = [{ id: "1", createdAt: "2026-01-07T10:00:00.000Z" }];
135
- const meta = { columns: { id: "number", createdAt: "DateTime" }, joins: {} };
136
- const result = await parseQueryResult(raw, meta);
137
- // [{ id: 1, createdAt: DateTime(...) }]
138
-
139
- // JOIN nesting
140
- const raw = [
141
- { id: 1, name: "User1", "posts.id": 10, "posts.title": "Post1" },
142
- { id: 1, name: "User1", "posts.id": 11, "posts.title": "Post2" },
143
- ];
144
- const meta = {
145
- columns: { id: "number", name: "string", "posts.id": "number", "posts.title": "string" },
146
- joins: { posts: { isSingle: false } },
147
- };
148
- const result = await parseQueryResult(raw, meta);
149
- // [{ id: 1, name: "User1", posts: [{ id: 10, title: "Post1" }, { id: 11, title: "Post2" }] }]
150
- ```
package/docs/queryable.md DELETED
@@ -1,261 +0,0 @@
1
- # Queryable / Executable
2
-
3
- Type-safe query builder and stored procedure executor.
4
-
5
- ## Queryable
6
-
7
- ```typescript
8
- class Queryable<TData extends DataRecord, TFrom extends TableBuilder<any, any> | never> {
9
- constructor(readonly meta: QueryableMeta<TData>);
10
- }
11
- ```
12
-
13
- Fluent query builder for composing SELECT, INSERT, UPDATE, DELETE, and UPSERT queries. All methods return new Queryable instances (immutable chaining).
14
-
15
- - `TData` - Query result data type
16
- - `TFrom` - Source table (required for CUD operations, `never` for read-only)
17
-
18
- ### Option Methods (SELECT / DISTINCT / LOCK)
19
-
20
- | Method | Signature | Description |
21
- |--------|-----------|-------------|
22
- | `select` | `<R>(fn: (cols: QueryableRecord<TData>) => R) => Queryable<UnwrapQueryableRecord<R>, never>` | Specify columns to SELECT |
23
- | `distinct` | `() => Queryable<TData, never>` | Apply DISTINCT |
24
- | `lock` | `() => Queryable<TData, TFrom>` | Apply FOR UPDATE row lock |
25
-
26
- ### Restrict Methods (TOP / LIMIT)
27
-
28
- | Method | Signature | Description |
29
- |--------|-----------|-------------|
30
- | `top` | `(count: number) => Queryable<TData, TFrom>` | Select top N rows |
31
- | `limit` | `(skip: number, take: number) => Queryable<TData, TFrom>` | Pagination (requires orderBy) |
32
-
33
- ### Sorting (ORDER BY)
34
-
35
- | Method | Signature | Description |
36
- |--------|-----------|-------------|
37
- | `orderBy` | `(fn: (cols) => ExprUnit, orderBy?: "ASC" \| "DESC") => Queryable<TData, TFrom>` | Add sort condition (stackable) |
38
-
39
- ### Filtering (WHERE)
40
-
41
- | Method | Signature | Description |
42
- |--------|-----------|-------------|
43
- | `where` | `(predicate: (cols) => WhereExprUnit[]) => Queryable<TData, TFrom>` | Add WHERE conditions (stackable, AND) |
44
- | `search` | `(fn: (cols) => ExprUnit<string\|undefined>[], searchText: string) => Queryable<TData, TFrom>` | Full-text search across columns |
45
-
46
- ### Grouping (GROUP BY / HAVING)
47
-
48
- | Method | Signature | Description |
49
- |--------|-----------|-------------|
50
- | `groupBy` | `(fn: (cols) => ExprUnit[]) => Queryable<TData, never>` | Group by columns |
51
- | `having` | `(predicate: (cols) => WhereExprUnit[]) => Queryable<TData, never>` | Filter groups |
52
-
53
- ### JOIN
54
-
55
- | Method | Signature | Description |
56
- |--------|-----------|-------------|
57
- | `join` | `<A, R>(as: A, fn: (qr: JoinQueryable, cols) => Queryable<R, any>) => Queryable<TData & { [K in A]?: R[] }, TFrom>` | LEFT OUTER JOIN (1:N, result as array) |
58
- | `joinSingle` | `<A, R>(as: A, fn: (qr: JoinQueryable, cols) => Queryable<R, any>) => Queryable<TData & { [K in A]?: R }, TFrom>` | LEFT OUTER JOIN (N:1 or 1:1, result as single object) |
59
- | `include` | `(fn: (item: PathProxy<TData>) => PathProxy) => Queryable<TData, TFrom>` | Auto-JOIN based on TableBuilder FK/FKT relations |
60
-
61
- ### Subquery / Union
62
-
63
- | Method | Signature | Description |
64
- |--------|-----------|-------------|
65
- | `wrap` | `() => Queryable<TData, never>` | Wrap as subquery (needed for count after distinct/groupBy) |
66
- | `Queryable.union` (static) | `(...queries: Queryable<TData, any>[]) => Queryable<TData, never>` | Combine queries with UNION (min 2) |
67
-
68
- ### Recursive CTE
69
-
70
- | Method | Signature | Description |
71
- |--------|-----------|-------------|
72
- | `recursive` | `(fn: (cte: RecursiveQueryable<TData>) => Queryable<TData, any>) => Queryable<TData, never>` | Generate recursive CTE (WITH RECURSIVE) |
73
-
74
- ### Execution (SELECT)
75
-
76
- | Method | Signature | Description |
77
- |--------|-----------|-------------|
78
- | `execute` | `() => Promise<TData[]>` | Execute SELECT and return results |
79
- | `single` | `() => Promise<TData \| undefined>` | Return single result (throws if > 1) |
80
- | `first` | `() => Promise<TData \| undefined>` | Return first result |
81
- | `count` | `(fn?: (cols) => ExprUnit) => Promise<number>` | Count rows (throws after distinct/groupBy without wrap) |
82
- | `exists` | `() => Promise<boolean>` | Check if any matching data exists |
83
-
84
- ### QueryDef Getters (SELECT)
85
-
86
- | Method | Signature | Description |
87
- |--------|-----------|-------------|
88
- | `getSelectQueryDef` | `() => SelectQueryDef` | Get the SELECT QueryDef AST |
89
- | `getResultMeta` | `(outputColumns?: string[]) => ResultMeta` | Get result parsing metadata |
90
-
91
- ### INSERT
92
-
93
- | Method | Signature | Description |
94
- |--------|-----------|-------------|
95
- | `insert` | `(records: TFrom["$inferInsert"][]) => Promise<void>` | Insert records (auto-chunks per 1000) |
96
- | `insert` | `(records, outputColumns: K[]) => Promise<Pick<...>[]>` | Insert with output columns |
97
- | `insertIfNotExists` | `(record: TFrom["$inferInsert"]) => Promise<void>` | Insert if WHERE condition has no match |
98
- | `insertIfNotExists` | `(record, outputColumns: K[]) => Promise<Pick<...>>` | Insert if not exists with output |
99
- | `insertInto` | `(targetTable: TableBuilder) => Promise<void>` | INSERT INTO ... SELECT |
100
- | `insertInto` | `(targetTable, outputColumns: K[]) => Promise<Pick<...>[]>` | INSERT INTO ... SELECT with output |
101
-
102
- ### UPDATE / DELETE
103
-
104
- | Method | Signature | Description |
105
- |--------|-----------|-------------|
106
- | `update` | `(recordFwd: (cols) => QueryableWriteRecord) => Promise<void>` | Update matching rows |
107
- | `update` | `(recordFwd, outputColumns: K[]) => Promise<Pick<...>[]>` | Update with output |
108
- | `delete` | `() => Promise<void>` | Delete matching rows |
109
- | `delete` | `(outputColumns: K[]) => Promise<Pick<...>[]>` | Delete with output |
110
-
111
- ### UPSERT
112
-
113
- | Method | Signature | Description |
114
- |--------|-----------|-------------|
115
- | `upsert` | `(updateFn: (cols) => WriteRecord) => Promise<void>` | Update or insert (same data) |
116
- | `upsert` | `(updateFn, insertFn) => Promise<void>` | Update or insert (different data) |
117
- | `upsert` | `(updateFn, insertFn?, outputColumns?) => Promise<Pick<...>[] \| void>` | With output columns |
118
-
119
- ### DDL Helper
120
-
121
- | Method | Signature | Description |
122
- |--------|-----------|-------------|
123
- | `switchFk` | `(enabled: boolean) => Promise<void>` | Enable/disable FK constraints on this table |
124
-
125
- ## queryable (factory)
126
-
127
- ```typescript
128
- function queryable<TBuilder extends TableBuilder<any, any> | ViewBuilder<any, any, any>>(
129
- db: DbContextBase,
130
- tableOrView: TBuilder,
131
- as?: string,
132
- ): () => Queryable<TBuilder["$inferSelect"], TBuilder extends TableBuilder ? TBuilder : never>
133
- ```
134
-
135
- Creates a factory function that returns a new Queryable instance each time it is called. Each call allocates a fresh alias via `db.getNextAlias()`.
136
-
137
- ## Executable
138
-
139
- ```typescript
140
- class Executable<TParams extends ColumnBuilderRecord, TReturns extends ColumnBuilderRecord> {
141
- constructor(db: DbContextBase, builder: ProcedureBuilder<TParams, TReturns>);
142
- getExecProcQueryDef(params?: InferColumnExprs<TParams>): { type: "execProc"; ... };
143
- async execute(params: InferColumnExprs<TParams>): Promise<InferColumnExprs<TReturns>[][]>;
144
- }
145
- ```
146
-
147
- Stored procedure execution wrapper.
148
-
149
- | Method | Signature | Description |
150
- |--------|-----------|-------------|
151
- | `getExecProcQueryDef` | `(params?) => ExecProcQueryDef` | Build procedure execution QueryDef |
152
- | `execute` | `(params) => Promise<T[][]>` | Execute the procedure |
153
-
154
- ## executable (factory)
155
-
156
- ```typescript
157
- function executable<TParams, TReturns>(
158
- db: DbContextBase,
159
- builder: ProcedureBuilder<TParams, TReturns>,
160
- ): () => Executable<TParams, TReturns>
161
- ```
162
-
163
- Creates a factory function that returns a new Executable instance.
164
-
165
- ## parseSearchQuery
166
-
167
- ```typescript
168
- function parseSearchQuery(searchText: string): ParsedSearchQuery
169
- ```
170
-
171
- Parses a search query string into SQL LIKE patterns.
172
-
173
- | Syntax | Meaning | Example |
174
- |--------|---------|---------|
175
- | `term1 term2` | OR (match any) | `apple banana` |
176
- | `+term` | Required (AND) | `+apple +banana` |
177
- | `-term` | Exclude (NOT) | `apple -banana` |
178
- | `"exact phrase"` | Exact match (required) | `"delicious fruit"` |
179
- | `*` | Wildcard | `app*` becomes `app%` |
180
-
181
- Escape sequences: `\\` (literal `\`), `\*`, `\%`, `\"`, `\+`, `\-`.
182
-
183
- ## ParsedSearchQuery
184
-
185
- ```typescript
186
- interface ParsedSearchQuery {
187
- or: string[]; // OR conditions - LIKE patterns
188
- must: string[]; // AND conditions (+ prefix or quotes) - LIKE patterns
189
- not: string[]; // NOT conditions (- prefix) - LIKE patterns
190
- }
191
- ```
192
-
193
- ## getMatchedPrimaryKeys
194
-
195
- ```typescript
196
- function getMatchedPrimaryKeys(
197
- fkCols: string[],
198
- targetTable: TableBuilder<any, any>,
199
- ): string[]
200
- ```
201
-
202
- Match FK column array with the target table's PK. Returns PK column name array. Throws if column counts do not match.
203
-
204
- ## QueryableRecord
205
-
206
- ```typescript
207
- type QueryableRecord<TData extends DataRecord> = {
208
- [K in keyof TData]: TData[K] extends ColumnPrimitive
209
- ? ExprUnit<TData[K]>
210
- : TData[K] extends (infer U)[]
211
- ? U extends DataRecord ? QueryableRecord<U>[] : never
212
- : TData[K] extends DataRecord ? QueryableRecord<TData[K]> : ...
213
- }
214
- ```
215
-
216
- Maps each field of a DataRecord to its corresponding ExprUnit proxy. Used as the column accessor type in Queryable callbacks.
217
-
218
- ## QueryableWriteRecord
219
-
220
- ```typescript
221
- type QueryableWriteRecord<TData> = {
222
- [K in keyof TData]: TData[K] extends ColumnPrimitive ? ExprInput<TData[K]> : never;
223
- }
224
- ```
225
-
226
- Maps each field to ExprInput for write operations (UPDATE, UPSERT).
227
-
228
- ## NullableQueryableRecord
229
-
230
- ```typescript
231
- type NullableQueryableRecord<TData extends DataRecord> = { ... }
232
- ```
233
-
234
- Like QueryableRecord but all primitive fields become `ExprUnit<T | undefined>`. Used for LEFT JOIN results where all columns may be NULL.
235
-
236
- ## UnwrapQueryableRecord
237
-
238
- ```typescript
239
- type UnwrapQueryableRecord<R> = {
240
- [K in keyof R]: R[K] extends ExprUnit<infer T> ? T : ...
241
- }
242
- ```
243
-
244
- Reverse-maps QueryableRecord back to a plain DataRecord. Used internally by `select()` to infer the resulting data type.
245
-
246
- ## PathProxy
247
-
248
- ```typescript
249
- type PathProxy<TObject> = {
250
- [K in keyof TObject as TObject[K] extends ColumnPrimitive ? never : K]-?: PathProxy<UnwrapArray<TObject[K]>>;
251
- } & { readonly [PATH_SYMBOL]: string[] }
252
- ```
253
-
254
- Type-safe proxy for `include()` that only exposes non-primitive (relation) fields. Property access builds a path array internally.
255
-
256
- ```typescript
257
- // Only relation fields are accessible:
258
- db.post().include((p) => p.author) // OK - author is a relation
259
- db.post().include((p) => p.author.company) // OK - nested relation
260
- // db.post().include((p) => p.title) // Compile error - title is string
261
- ```
@@ -1,288 +0,0 @@
1
- # Schema Builders
2
-
3
- Fluent API builders for defining tables, views, procedures, columns, indexes, and relations.
4
-
5
- ## Table (function)
6
-
7
- ```typescript
8
- function Table(name: string): TableBuilder<{}, {}>
9
- ```
10
-
11
- Creates a new TableBuilder with the given table name.
12
-
13
- ## TableBuilder
14
-
15
- ```typescript
16
- class TableBuilder<TColumns extends ColumnBuilderRecord, TRelations extends RelationBuilderRecord>
17
- ```
18
-
19
- Fluent API for defining database table schema including columns, primary key, indexes, and relations.
20
-
21
- ### Phantom Type Fields
22
-
23
- | Field | Type | Description |
24
- |-------|------|-------------|
25
- | `$columns` | `TColumns` | Column definitions (type inference) |
26
- | `$relations` | `TRelations` | Relation definitions (type inference) |
27
- | `$inferSelect` | `InferColumns<TColumns> & InferDeepRelations<TRelations>` | Full SELECT type |
28
- | `$inferColumns` | `InferColumns<TColumns>` | Column-only type |
29
- | `$inferInsert` | `InferInsertColumns<TColumns>` | INSERT type (AI/nullable/default optional) |
30
- | `$inferUpdate` | `InferUpdateColumns<TColumns>` | UPDATE type (all optional) |
31
-
32
- ### Constructor
33
-
34
- ```typescript
35
- constructor(readonly meta: {
36
- name: string;
37
- description?: string;
38
- database?: string;
39
- schema?: string;
40
- columns?: TColumns;
41
- primaryKey?: (keyof TColumns & string)[];
42
- relations?: TRelations;
43
- indexes?: IndexBuilder<(keyof TColumns & string)[]>[];
44
- })
45
- ```
46
-
47
- ### Methods
48
-
49
- | Method | Signature | Description |
50
- |--------|-----------|-------------|
51
- | `description` | `(desc: string) => TableBuilder` | Set table description (DDL comment) |
52
- | `database` | `(db: string) => TableBuilder` | Set database name |
53
- | `schema` | `(schema: string) => TableBuilder` | Set schema name (MSSQL/PostgreSQL) |
54
- | `columns` | `<T>(fn: (c: ColumnFactory) => T) => TableBuilder<T, TRelations>` | Define columns via column factory |
55
- | `primaryKey` | `(...columns: (keyof TColumns & string)[]) => TableBuilder` | Set primary key (single or composite) |
56
- | `indexes` | `(fn: (i: IndexFactory) => IndexBuilder[]) => TableBuilder` | Define indexes |
57
- | `relations` | `<T>(fn: (r: RelationFactory) => T) => TableBuilder<TColumns, T>` | Define FK and relation mappings |
58
-
59
- ## View (function)
60
-
61
- ```typescript
62
- function View(name: string): ViewBuilder<any, any, {}>
63
- ```
64
-
65
- Creates a new ViewBuilder with the given view name.
66
-
67
- ## ViewBuilder
68
-
69
- ```typescript
70
- class ViewBuilder<TDbContext extends DbContextBase, TData extends DataRecord, TRelations extends RelationBuilderRecord>
71
- ```
72
-
73
- Fluent API for defining database view schema.
74
-
75
- ### Phantom Type Fields
76
-
77
- | Field | Type | Description |
78
- |-------|------|-------------|
79
- | `$relations` | `TRelations` | Relation definitions |
80
- | `$inferSelect` | `TData` | Full SELECT type |
81
-
82
- ### Methods
83
-
84
- | Method | Signature | Description |
85
- |--------|-----------|-------------|
86
- | `description` | `(desc: string) => ViewBuilder` | Set view description |
87
- | `database` | `(db: string) => ViewBuilder` | Set database name |
88
- | `schema` | `(schema: string) => ViewBuilder` | Set schema name |
89
- | `query` | `<TViewData, TDb>(viewFn: (db: TDb) => Queryable<TViewData, any>) => ViewBuilder<TDb, TViewData, TRelations>` | Define the view's SELECT query |
90
- | `relations` | `<T>(fn: (r: RelationFactory) => T) => ViewBuilder` | Define relations (RelationKey only, no FK) |
91
-
92
- ## Procedure (function)
93
-
94
- ```typescript
95
- function Procedure(name: string): ProcedureBuilder<never, never>
96
- ```
97
-
98
- Creates a new ProcedureBuilder with the given procedure name.
99
-
100
- ## ProcedureBuilder
101
-
102
- ```typescript
103
- class ProcedureBuilder<TParams extends ColumnBuilderRecord, TReturns extends ColumnBuilderRecord>
104
- ```
105
-
106
- Fluent API for defining stored procedure schema.
107
-
108
- ### Phantom Type Fields
109
-
110
- | Field | Type | Description |
111
- |-------|------|-------------|
112
- | `$params` | `TParams` | Parameter definitions |
113
- | `$returns` | `TReturns` | Return type definitions |
114
-
115
- ### Methods
116
-
117
- | Method | Signature | Description |
118
- |--------|-----------|-------------|
119
- | `description` | `(desc: string) => ProcedureBuilder` | Set procedure description |
120
- | `database` | `(db: string) => ProcedureBuilder` | Set database name |
121
- | `schema` | `(schema: string) => ProcedureBuilder` | Set schema name |
122
- | `params` | `<T>(fn: (c: ColumnFactory) => T) => ProcedureBuilder<T, TReturns>` | Define input parameters |
123
- | `returns` | `<T>(fn: (c: ColumnFactory) => T) => ProcedureBuilder<TParams, T>` | Define return columns |
124
- | `body` | `(sql: string) => ProcedureBuilder` | Set procedure body SQL |
125
-
126
- ## ColumnBuilder
127
-
128
- ```typescript
129
- class ColumnBuilder<TValue extends ColumnPrimitive, TMeta extends ColumnMeta> {
130
- constructor(readonly meta: TMeta);
131
- }
132
- ```
133
-
134
- Column definition builder with fluent API for type modifiers.
135
-
136
- ### Methods
137
-
138
- | Method | Signature | Description |
139
- |--------|-----------|-------------|
140
- | `autoIncrement` | `() => ColumnBuilder<TValue, TMeta & { autoIncrement: true }>` | Set auto-increment (INSERT optional) |
141
- | `nullable` | `() => ColumnBuilder<TValue \| undefined, TMeta & { nullable: true }>` | Allow NULL values |
142
- | `default` | `(value: TValue) => ColumnBuilder<TValue, TMeta & { default: TValue }>` | Set default value (INSERT optional) |
143
- | `description` | `(desc: string) => ColumnBuilder<TValue, TMeta & { description: string }>` | Set column description (DDL comment) |
144
-
145
- ## createColumnFactory
146
-
147
- ```typescript
148
- function createColumnFactory(): ColumnFactory
149
- ```
150
-
151
- Returns a column type factory object. Used inside `TableBuilder.columns()` and `ProcedureBuilder.params()/returns()`.
152
-
153
- ### Factory Methods
154
-
155
- | Method | Signature | SQL Type | TypeScript Type |
156
- |--------|-----------|----------|-----------------|
157
- | `int` | `() => ColumnBuilder<number, ...>` | `INT` | `number` |
158
- | `bigint` | `() => ColumnBuilder<number, ...>` | `BIGINT` | `number` |
159
- | `float` | `() => ColumnBuilder<number, ...>` | `FLOAT` | `number` |
160
- | `double` | `() => ColumnBuilder<number, ...>` | `DOUBLE` | `number` |
161
- | `decimal` | `(precision, scale?) => ColumnBuilder<number, ...>` | `DECIMAL(p,s)` | `number` |
162
- | `varchar` | `(length) => ColumnBuilder<string, ...>` | `VARCHAR(n)` | `string` |
163
- | `char` | `(length) => ColumnBuilder<string, ...>` | `CHAR(n)` | `string` |
164
- | `text` | `() => ColumnBuilder<string, ...>` | `TEXT` | `string` |
165
- | `binary` | `() => ColumnBuilder<Bytes, ...>` | `LONGBLOB`/`BYTEA` | `Bytes` |
166
- | `boolean` | `() => ColumnBuilder<boolean, ...>` | `TINYINT(1)`/`BIT`/`BOOLEAN` | `boolean` |
167
- | `datetime` | `() => ColumnBuilder<DateTime, ...>` | `DATETIME` | `DateTime` |
168
- | `date` | `() => ColumnBuilder<DateOnly, ...>` | `DATE` | `DateOnly` |
169
- | `time` | `() => ColumnBuilder<Time, ...>` | `TIME` | `Time` |
170
- | `uuid` | `() => ColumnBuilder<Uuid, ...>` | `BINARY(16)`/`UNIQUEIDENTIFIER`/`UUID` | `Uuid` |
171
-
172
- ## IndexBuilder
173
-
174
- ```typescript
175
- class IndexBuilder<TKeys extends string[]> {
176
- constructor(readonly meta: {
177
- columns: TKeys;
178
- name?: string;
179
- unique?: boolean;
180
- orderBy?: { [K in keyof TKeys]: "ASC" | "DESC" };
181
- description?: string;
182
- });
183
- }
184
- ```
185
-
186
- ### Methods
187
-
188
- | Method | Signature | Description |
189
- |--------|-----------|-------------|
190
- | `name` | `(name: string) => IndexBuilder<TKeys>` | Set custom index name |
191
- | `unique` | `() => IndexBuilder<TKeys>` | Mark as unique index |
192
- | `orderBy` | `(...orderBy: ("ASC" \| "DESC")[]) => IndexBuilder<TKeys>` | Set sort order per column |
193
- | `description` | `(desc: string) => IndexBuilder<TKeys>` | Set index description |
194
-
195
- ## createIndexFactory
196
-
197
- ```typescript
198
- function createIndexFactory<TColumnKey extends string>(): { index: (...columns: TColumnKey[]) => IndexBuilder }
199
- ```
200
-
201
- Returns an index factory. Used inside `TableBuilder.indexes()`.
202
-
203
- ## ForeignKeyBuilder
204
-
205
- ```typescript
206
- class ForeignKeyBuilder<TOwner extends TableBuilder<any, any>, TTargetFn extends () => TableBuilder<any, any>> {
207
- constructor(readonly meta: {
208
- ownerFn: () => TOwner;
209
- columns: string[];
210
- targetFn: TTargetFn;
211
- description?: string;
212
- });
213
- }
214
- ```
215
-
216
- N:1 FK relation builder. Creates an actual DB foreign key constraint.
217
-
218
- `description` is configured via the factory function's `opts` parameter (3rd argument to `foreignKey()`), not via method chaining. This class has no methods — it is a data holder for relation metadata.
219
-
220
- ## ForeignKeyTargetBuilder
221
-
222
- ```typescript
223
- class ForeignKeyTargetBuilder<TTargetTableFn extends () => TableBuilder<any, any>, TIsSingle extends boolean> {
224
- constructor(readonly meta: {
225
- targetTableFn: TTargetTableFn;
226
- relationName: string;
227
- description?: string;
228
- isSingle?: TIsSingle;
229
- });
230
- }
231
- ```
232
-
233
- 1:N FK reverse-reference builder. Loaded as array by default, single object with `{ single: true }` opts.
234
-
235
- `description` and `single` are configured via the factory function's `opts` parameter (3rd argument to `foreignKeyTarget()`), not via method chaining. Method chaining was removed to prevent TS7022 in complex circular references.
236
-
237
- This class has no methods — it is a data holder for relation metadata.
238
-
239
- ## RelationKeyBuilder
240
-
241
- ```typescript
242
- class RelationKeyBuilder<
243
- TOwner extends TableBuilder<any, any> | ViewBuilder<any, any, any>,
244
- TTargetFn extends () => TableBuilder<any, any> | ViewBuilder<any, any, any>,
245
- >
246
- ```
247
-
248
- Logical N:1 relation builder (no DB FK constraint). Works with both Tables and Views.
249
-
250
- `description` is configured via the factory function's `opts` parameter (3rd argument to `relationKey()`), not via method chaining. This class has no methods — it is a data holder for relation metadata.
251
-
252
- ## RelationKeyTargetBuilder
253
-
254
- ```typescript
255
- class RelationKeyTargetBuilder<
256
- TTargetTableFn extends () => TableBuilder<any, any> | ViewBuilder<any, any, any>,
257
- TIsSingle extends boolean,
258
- >
259
- ```
260
-
261
- Logical 1:N reverse-reference builder (no DB FK constraint). Works with both Tables and Views.
262
-
263
- `description` and `single` are configured via the factory function's `opts` parameter (3rd argument to `relationKeyTarget()`), not via method chaining.
264
-
265
- This class has no methods — it is a data holder for relation metadata.
266
-
267
- ## createRelationFactory
268
-
269
- ```typescript
270
- function createRelationFactory<TOwner, TColumnKey extends string>(
271
- ownerFn: () => TOwner,
272
- ): RelationFactory
273
- ```
274
-
275
- Creates a relation factory. For `TableBuilder`: provides `foreignKey`, `foreignKeyTarget`, `relationKey`, `relationKeyTarget`. For `ViewBuilder`: provides only `relationKey`, `relationKeyTarget`.
276
-
277
- ### Factory Methods (Table)
278
-
279
- | Method | Signature | Description |
280
- |--------|-----------|-------------|
281
- | `foreignKey` | `(columns, targetFn, opts?: { description?: string })` | N:1 FK (creates DB constraint) |
282
- | `foreignKeyTarget` | `(targetTableFn, relationName, opts?: { single?: boolean; description?: string })` | 1:N FK reverse-reference. `{ single: true }` → 1:1 |
283
- | `relationKey` | `(columns, targetFn, opts?: { description?: string })` | N:1 logical relation (no DB FK) |
284
- | `relationKeyTarget` | `(targetTableFn, relationName, opts?: { single?: boolean; description?: string })` | 1:N logical reverse-reference. `{ single: true }` → 1:1 |
285
-
286
- ### Factory Methods (View)
287
-
288
- Only `relationKey` and `relationKeyTarget` are available for ViewBuilder.