metal-orm 1.0.11 → 1.0.12
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 -3
- package/dist/decorators/index.cjs +15 -2
- package/dist/decorators/index.cjs.map +1 -1
- package/dist/decorators/index.d.cts +1 -1
- package/dist/decorators/index.d.ts +1 -1
- package/dist/decorators/index.js +15 -2
- package/dist/decorators/index.js.map +1 -1
- package/dist/index.cjs +1394 -149
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +257 -23
- package/dist/index.d.ts +257 -23
- package/dist/index.js +1376 -149
- package/dist/index.js.map +1 -1
- package/dist/{select-654m4qy8.d.cts → select-BKlr2ivY.d.cts} +141 -4
- package/dist/{select-654m4qy8.d.ts → select-BKlr2ivY.d.ts} +141 -4
- package/package.json +1 -1
- package/src/core/ddl/dialects/base-schema-dialect.ts +48 -0
- package/src/core/ddl/dialects/index.ts +5 -0
- package/src/core/ddl/dialects/mssql-schema-dialect.ts +97 -0
- package/src/core/ddl/dialects/mysql-schema-dialect.ts +109 -0
- package/src/core/ddl/dialects/postgres-schema-dialect.ts +99 -0
- package/src/core/ddl/dialects/sqlite-schema-dialect.ts +103 -0
- package/src/core/ddl/introspect/mssql.ts +149 -0
- package/src/core/ddl/introspect/mysql.ts +99 -0
- package/src/core/ddl/introspect/postgres.ts +154 -0
- package/src/core/ddl/introspect/sqlite.ts +66 -0
- package/src/core/ddl/introspect/types.ts +19 -0
- package/src/core/ddl/introspect/utils.ts +27 -0
- package/src/core/ddl/schema-diff.ts +179 -0
- package/src/core/ddl/schema-generator.ts +229 -0
- package/src/core/ddl/schema-introspect.ts +32 -0
- package/src/core/ddl/schema-types.ts +39 -0
- package/src/core/dialect/base/sql-dialect.ts +161 -0
- package/src/core/dialect/mysql/index.ts +18 -112
- package/src/core/dialect/postgres/index.ts +30 -126
- package/src/core/dialect/sqlite/index.ts +29 -129
- package/src/index.ts +4 -0
- package/src/schema/column.ts +206 -27
- package/src/schema/table.ts +89 -32
- package/src/schema/types.ts +8 -5
package/dist/index.cjs
CHANGED
|
@@ -20,15 +20,21 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
|
|
|
20
20
|
var index_exports = {};
|
|
21
21
|
__export(index_exports, {
|
|
22
22
|
AsyncLocalStorage: () => AsyncLocalStorage,
|
|
23
|
+
BaseSchemaDialect: () => BaseSchemaDialect,
|
|
23
24
|
DefaultBelongsToReference: () => DefaultBelongsToReference,
|
|
24
25
|
DefaultHasManyCollection: () => DefaultHasManyCollection,
|
|
25
26
|
DefaultManyToManyCollection: () => DefaultManyToManyCollection,
|
|
26
27
|
DeleteQueryBuilder: () => DeleteQueryBuilder,
|
|
27
28
|
EntityStatus: () => EntityStatus,
|
|
28
29
|
InsertQueryBuilder: () => InsertQueryBuilder,
|
|
30
|
+
MSSqlSchemaDialect: () => MSSqlSchemaDialect,
|
|
29
31
|
MySqlDialect: () => MySqlDialect,
|
|
32
|
+
MySqlSchemaDialect: () => MySqlSchemaDialect,
|
|
30
33
|
OrmContext: () => OrmContext,
|
|
34
|
+
PostgresDialect: () => PostgresDialect,
|
|
35
|
+
PostgresSchemaDialect: () => PostgresSchemaDialect,
|
|
31
36
|
RelationKinds: () => RelationKinds,
|
|
37
|
+
SQLiteSchemaDialect: () => SQLiteSchemaDialect,
|
|
32
38
|
SelectQueryBuilder: () => SelectQueryBuilder,
|
|
33
39
|
SqlServerDialect: () => SqlServerDialect,
|
|
34
40
|
SqliteDialect: () => SqliteDialect,
|
|
@@ -50,15 +56,22 @@ __export(index_exports, {
|
|
|
50
56
|
createLiteral: () => createLiteral,
|
|
51
57
|
defineTable: () => defineTable,
|
|
52
58
|
denseRank: () => denseRank,
|
|
59
|
+
deriveIndexName: () => deriveIndexName,
|
|
60
|
+
diffSchema: () => diffSchema,
|
|
53
61
|
eq: () => eq,
|
|
62
|
+
escapeLiteral: () => escapeLiteral,
|
|
54
63
|
executeHydrated: () => executeHydrated,
|
|
55
64
|
exists: () => exists,
|
|
56
65
|
firstValue: () => firstValue,
|
|
66
|
+
formatLiteral: () => formatLiteral,
|
|
67
|
+
generateCreateTableSql: () => generateCreateTableSql,
|
|
68
|
+
generateSchemaSql: () => generateSchemaSql,
|
|
57
69
|
gt: () => gt,
|
|
58
70
|
gte: () => gte,
|
|
59
71
|
hasMany: () => hasMany,
|
|
60
72
|
hydrateRows: () => hydrateRows,
|
|
61
73
|
inList: () => inList,
|
|
74
|
+
introspectSchema: () => introspectSchema,
|
|
62
75
|
isCaseExpressionNode: () => isCaseExpressionNode,
|
|
63
76
|
isExpressionSelectionNode: () => isExpressionSelectionNode,
|
|
64
77
|
isFunctionNode: () => isFunctionNode,
|
|
@@ -83,9 +96,14 @@ __export(index_exports, {
|
|
|
83
96
|
notLike: () => notLike,
|
|
84
97
|
ntile: () => ntile,
|
|
85
98
|
or: () => or,
|
|
99
|
+
quoteQualified: () => quoteQualified,
|
|
86
100
|
rank: () => rank,
|
|
101
|
+
renderColumnDefinition: () => renderColumnDefinition,
|
|
102
|
+
renderIndexColumns: () => renderIndexColumns,
|
|
103
|
+
resolvePrimaryKey: () => resolvePrimaryKey,
|
|
87
104
|
rowNumber: () => rowNumber,
|
|
88
105
|
sum: () => sum,
|
|
106
|
+
synchronizeSchema: () => synchronizeSchema,
|
|
89
107
|
valueToOperand: () => valueToOperand,
|
|
90
108
|
visitExpression: () => visitExpression,
|
|
91
109
|
visitOperand: () => visitOperand,
|
|
@@ -94,12 +112,25 @@ __export(index_exports, {
|
|
|
94
112
|
module.exports = __toCommonJS(index_exports);
|
|
95
113
|
|
|
96
114
|
// src/schema/table.ts
|
|
97
|
-
var defineTable = (name, columns, relations = {}, hooks) => {
|
|
115
|
+
var defineTable = (name, columns, relations = {}, hooks, options = {}) => {
|
|
98
116
|
const colsWithNames = Object.entries(columns).reduce((acc, [key, def]) => {
|
|
99
117
|
acc[key] = { ...def, name: key, table: name };
|
|
100
118
|
return acc;
|
|
101
119
|
}, {});
|
|
102
|
-
return {
|
|
120
|
+
return {
|
|
121
|
+
name,
|
|
122
|
+
schema: options.schema,
|
|
123
|
+
columns: colsWithNames,
|
|
124
|
+
relations,
|
|
125
|
+
hooks,
|
|
126
|
+
primaryKey: options.primaryKey,
|
|
127
|
+
indexes: options.indexes,
|
|
128
|
+
checks: options.checks,
|
|
129
|
+
comment: options.comment,
|
|
130
|
+
engine: options.engine,
|
|
131
|
+
charset: options.charset,
|
|
132
|
+
collation: options.collation
|
|
133
|
+
};
|
|
103
134
|
};
|
|
104
135
|
|
|
105
136
|
// src/schema/column.ts
|
|
@@ -109,12 +140,52 @@ var col = {
|
|
|
109
140
|
* @returns ColumnDef with INT type
|
|
110
141
|
*/
|
|
111
142
|
int: () => ({ name: "", type: "INT" }),
|
|
143
|
+
/**
|
|
144
|
+
* Creates a big integer column definition
|
|
145
|
+
*/
|
|
146
|
+
bigint: () => ({ name: "", type: "BIGINT" }),
|
|
112
147
|
/**
|
|
113
148
|
* Creates a variable character column definition
|
|
114
149
|
* @param length - Maximum length of the string
|
|
115
150
|
* @returns ColumnDef with VARCHAR type
|
|
116
151
|
*/
|
|
117
152
|
varchar: (length) => ({ name: "", type: "VARCHAR", args: [length] }),
|
|
153
|
+
/**
|
|
154
|
+
* Creates a fixed precision decimal column definition
|
|
155
|
+
*/
|
|
156
|
+
decimal: (precision, scale = 0) => ({
|
|
157
|
+
name: "",
|
|
158
|
+
type: "DECIMAL",
|
|
159
|
+
args: [precision, scale]
|
|
160
|
+
}),
|
|
161
|
+
/**
|
|
162
|
+
* Creates a floating point column definition
|
|
163
|
+
*/
|
|
164
|
+
float: (precision) => ({
|
|
165
|
+
name: "",
|
|
166
|
+
type: "FLOAT",
|
|
167
|
+
args: precision !== void 0 ? [precision] : void 0
|
|
168
|
+
}),
|
|
169
|
+
/**
|
|
170
|
+
* Creates a UUID column definition
|
|
171
|
+
*/
|
|
172
|
+
uuid: () => ({ name: "", type: "UUID" }),
|
|
173
|
+
/**
|
|
174
|
+
* Creates a timestamp column definition
|
|
175
|
+
*/
|
|
176
|
+
timestamp: () => ({ name: "", type: "TIMESTAMP" }),
|
|
177
|
+
/**
|
|
178
|
+
* Creates a timestamptz column definition
|
|
179
|
+
*/
|
|
180
|
+
timestamptz: () => ({ name: "", type: "TIMESTAMPTZ" }),
|
|
181
|
+
/**
|
|
182
|
+
* Creates a date column definition
|
|
183
|
+
*/
|
|
184
|
+
date: () => ({ name: "", type: "DATE" }),
|
|
185
|
+
/**
|
|
186
|
+
* Creates a datetime column definition
|
|
187
|
+
*/
|
|
188
|
+
datetime: () => ({ name: "", type: "DATETIME" }),
|
|
118
189
|
/**
|
|
119
190
|
* Creates a JSON column definition
|
|
120
191
|
* @returns ColumnDef with JSON type
|
|
@@ -125,12 +196,64 @@ var col = {
|
|
|
125
196
|
* @returns ColumnDef with BOOLEAN type
|
|
126
197
|
*/
|
|
127
198
|
boolean: () => ({ name: "", type: "BOOLEAN" }),
|
|
199
|
+
/**
|
|
200
|
+
* Creates an enum column definition
|
|
201
|
+
* @param values - Enum values
|
|
202
|
+
*/
|
|
203
|
+
enum: (values) => ({ name: "", type: "ENUM", args: values }),
|
|
128
204
|
/**
|
|
129
205
|
* Marks a column definition as a primary key
|
|
130
206
|
* @param def - Column definition to modify
|
|
131
207
|
* @returns Modified ColumnDef with primary: true
|
|
132
208
|
*/
|
|
133
|
-
primaryKey: (def) => ({ ...def, primary: true })
|
|
209
|
+
primaryKey: (def) => ({ ...def, primary: true }),
|
|
210
|
+
/**
|
|
211
|
+
* Marks a column as NOT NULL
|
|
212
|
+
*/
|
|
213
|
+
notNull: (def) => ({ ...def, notNull: true }),
|
|
214
|
+
/**
|
|
215
|
+
* Marks a column as UNIQUE
|
|
216
|
+
*/
|
|
217
|
+
unique: (def, name) => ({
|
|
218
|
+
...def,
|
|
219
|
+
unique: name ?? true
|
|
220
|
+
}),
|
|
221
|
+
/**
|
|
222
|
+
* Sets a default value for the column
|
|
223
|
+
*/
|
|
224
|
+
default: (def, value) => ({
|
|
225
|
+
...def,
|
|
226
|
+
default: value
|
|
227
|
+
}),
|
|
228
|
+
/**
|
|
229
|
+
* Sets a raw SQL default value for the column
|
|
230
|
+
*/
|
|
231
|
+
defaultRaw: (def, expression) => ({
|
|
232
|
+
...def,
|
|
233
|
+
default: { raw: expression }
|
|
234
|
+
}),
|
|
235
|
+
/**
|
|
236
|
+
* Marks a column as auto-increment / identity
|
|
237
|
+
*/
|
|
238
|
+
autoIncrement: (def, strategy = "byDefault") => ({
|
|
239
|
+
...def,
|
|
240
|
+
autoIncrement: true,
|
|
241
|
+
generated: strategy
|
|
242
|
+
}),
|
|
243
|
+
/**
|
|
244
|
+
* Adds a foreign key reference
|
|
245
|
+
*/
|
|
246
|
+
references: (def, ref) => ({
|
|
247
|
+
...def,
|
|
248
|
+
references: ref
|
|
249
|
+
}),
|
|
250
|
+
/**
|
|
251
|
+
* Adds a check constraint to the column
|
|
252
|
+
*/
|
|
253
|
+
check: (def, expression) => ({
|
|
254
|
+
...def,
|
|
255
|
+
check: expression
|
|
256
|
+
})
|
|
134
257
|
};
|
|
135
258
|
|
|
136
259
|
// src/schema/relation.ts
|
|
@@ -2994,8 +3117,132 @@ var Dialect = class {
|
|
|
2994
3117
|
}
|
|
2995
3118
|
};
|
|
2996
3119
|
|
|
3120
|
+
// src/core/dialect/base/sql-dialect.ts
|
|
3121
|
+
var SqlDialectBase = class extends Dialect {
|
|
3122
|
+
/**
|
|
3123
|
+
* Compiles SELECT query AST to SQL using common rules.
|
|
3124
|
+
*/
|
|
3125
|
+
compileSelectAst(ast, ctx) {
|
|
3126
|
+
const ctes = this.compileCtes(ast, ctx);
|
|
3127
|
+
const columns = this.compileSelectColumns(ast, ctx);
|
|
3128
|
+
const from = this.compileFrom(ast.from);
|
|
3129
|
+
const joins = this.compileJoins(ast, ctx);
|
|
3130
|
+
const whereClause = this.compileWhere(ast.where, ctx);
|
|
3131
|
+
const groupBy = this.compileGroupBy(ast);
|
|
3132
|
+
const having = this.compileHaving(ast, ctx);
|
|
3133
|
+
const orderBy = this.compileOrderBy(ast);
|
|
3134
|
+
const pagination = this.compilePagination(ast, orderBy);
|
|
3135
|
+
return `${ctes}SELECT ${this.compileDistinct(ast)}${columns} FROM ${from}${joins}${whereClause}${groupBy}${having}${orderBy}${pagination}`;
|
|
3136
|
+
}
|
|
3137
|
+
compileInsertAst(ast, ctx) {
|
|
3138
|
+
const table = this.compileTableName(ast.into);
|
|
3139
|
+
const columnList = ast.columns.map((column) => `${this.quoteIdentifier(column.table)}.${this.quoteIdentifier(column.name)}`).join(", ");
|
|
3140
|
+
const values = ast.values.map((row) => `(${row.map((value) => this.compileOperand(value, ctx)).join(", ")})`).join(", ");
|
|
3141
|
+
const returning = this.compileReturning(ast.returning, ctx);
|
|
3142
|
+
return `INSERT INTO ${table} (${columnList}) VALUES ${values}${returning}`;
|
|
3143
|
+
}
|
|
3144
|
+
compileUpdateAst(ast, ctx) {
|
|
3145
|
+
const table = this.compileTableName(ast.table);
|
|
3146
|
+
const assignments = ast.set.map((assignment) => {
|
|
3147
|
+
const col2 = assignment.column;
|
|
3148
|
+
const target = `${this.quoteIdentifier(col2.table)}.${this.quoteIdentifier(col2.name)}`;
|
|
3149
|
+
const value = this.compileOperand(assignment.value, ctx);
|
|
3150
|
+
return `${target} = ${value}`;
|
|
3151
|
+
}).join(", ");
|
|
3152
|
+
const whereClause = this.compileWhere(ast.where, ctx);
|
|
3153
|
+
const returning = this.compileReturning(ast.returning, ctx);
|
|
3154
|
+
return `UPDATE ${table} SET ${assignments}${whereClause}${returning}`;
|
|
3155
|
+
}
|
|
3156
|
+
compileDeleteAst(ast, ctx) {
|
|
3157
|
+
const table = this.compileTableName(ast.from);
|
|
3158
|
+
const whereClause = this.compileWhere(ast.where, ctx);
|
|
3159
|
+
const returning = this.compileReturning(ast.returning, ctx);
|
|
3160
|
+
return `DELETE FROM ${table}${whereClause}${returning}`;
|
|
3161
|
+
}
|
|
3162
|
+
/**
|
|
3163
|
+
* Default RETURNING compilation: no support.
|
|
3164
|
+
*/
|
|
3165
|
+
compileReturning(returning, _ctx) {
|
|
3166
|
+
if (!returning || returning.length === 0) return "";
|
|
3167
|
+
throw new Error("RETURNING is not supported by this dialect.");
|
|
3168
|
+
}
|
|
3169
|
+
/**
|
|
3170
|
+
* DISTINCT clause. Override for DISTINCT ON support.
|
|
3171
|
+
*/
|
|
3172
|
+
compileDistinct(ast) {
|
|
3173
|
+
return ast.distinct ? "DISTINCT " : "";
|
|
3174
|
+
}
|
|
3175
|
+
compileSelectColumns(ast, ctx) {
|
|
3176
|
+
return ast.columns.map((c) => {
|
|
3177
|
+
const expr = this.compileOperand(c, ctx);
|
|
3178
|
+
if (c.alias) {
|
|
3179
|
+
if (c.alias.includes("(")) return c.alias;
|
|
3180
|
+
return `${expr} AS ${this.quoteIdentifier(c.alias)}`;
|
|
3181
|
+
}
|
|
3182
|
+
return expr;
|
|
3183
|
+
}).join(", ");
|
|
3184
|
+
}
|
|
3185
|
+
compileFrom(ast) {
|
|
3186
|
+
const base = this.compileTableName(ast);
|
|
3187
|
+
return ast.alias ? `${base} AS ${this.quoteIdentifier(ast.alias)}` : base;
|
|
3188
|
+
}
|
|
3189
|
+
compileTableName(table) {
|
|
3190
|
+
if (table.schema) {
|
|
3191
|
+
return `${this.quoteIdentifier(table.schema)}.${this.quoteIdentifier(table.name)}`;
|
|
3192
|
+
}
|
|
3193
|
+
return this.quoteIdentifier(table.name);
|
|
3194
|
+
}
|
|
3195
|
+
compileJoins(ast, ctx) {
|
|
3196
|
+
if (!ast.joins || ast.joins.length === 0) return "";
|
|
3197
|
+
const parts = ast.joins.map((j) => {
|
|
3198
|
+
const table = this.compileFrom(j.table);
|
|
3199
|
+
const cond = this.compileExpression(j.condition, ctx);
|
|
3200
|
+
return `${j.kind} JOIN ${table} ON ${cond}`;
|
|
3201
|
+
});
|
|
3202
|
+
return ` ${parts.join(" ")}`;
|
|
3203
|
+
}
|
|
3204
|
+
compileGroupBy(ast) {
|
|
3205
|
+
if (!ast.groupBy || ast.groupBy.length === 0) return "";
|
|
3206
|
+
const cols = ast.groupBy.map((c) => `${this.quoteIdentifier(c.table)}.${this.quoteIdentifier(c.name)}`).join(", ");
|
|
3207
|
+
return ` GROUP BY ${cols}`;
|
|
3208
|
+
}
|
|
3209
|
+
compileHaving(ast, ctx) {
|
|
3210
|
+
if (!ast.having) return "";
|
|
3211
|
+
return ` HAVING ${this.compileExpression(ast.having, ctx)}`;
|
|
3212
|
+
}
|
|
3213
|
+
compileOrderBy(ast) {
|
|
3214
|
+
if (!ast.orderBy || ast.orderBy.length === 0) return "";
|
|
3215
|
+
const parts = ast.orderBy.map((o) => `${this.quoteIdentifier(o.column.table)}.${this.quoteIdentifier(o.column.name)} ${o.direction}`).join(", ");
|
|
3216
|
+
return ` ORDER BY ${parts}`;
|
|
3217
|
+
}
|
|
3218
|
+
/**
|
|
3219
|
+
* Default LIMIT/OFFSET pagination clause.
|
|
3220
|
+
*/
|
|
3221
|
+
compilePagination(ast, _orderByClause) {
|
|
3222
|
+
const parts = [];
|
|
3223
|
+
if (ast.limit !== void 0) parts.push(`LIMIT ${ast.limit}`);
|
|
3224
|
+
if (ast.offset !== void 0) parts.push(`OFFSET ${ast.offset}`);
|
|
3225
|
+
return parts.length ? ` ${parts.join(" ")}` : "";
|
|
3226
|
+
}
|
|
3227
|
+
compileCtes(ast, ctx) {
|
|
3228
|
+
if (!ast.ctes || ast.ctes.length === 0) return "";
|
|
3229
|
+
const hasRecursive = ast.ctes.some((cte) => cte.recursive);
|
|
3230
|
+
const prefix = hasRecursive ? "WITH RECURSIVE " : "WITH ";
|
|
3231
|
+
const cteDefs = ast.ctes.map((cte) => {
|
|
3232
|
+
const name = this.quoteIdentifier(cte.name);
|
|
3233
|
+
const cols = cte.columns && cte.columns.length ? `(${cte.columns.map((c) => this.quoteIdentifier(c)).join(", ")})` : "";
|
|
3234
|
+
const query = this.stripTrailingSemicolon(this.compileSelectAst(cte.query, ctx));
|
|
3235
|
+
return `${name}${cols} AS (${query})`;
|
|
3236
|
+
}).join(", ");
|
|
3237
|
+
return `${prefix}${cteDefs} `;
|
|
3238
|
+
}
|
|
3239
|
+
stripTrailingSemicolon(sql) {
|
|
3240
|
+
return sql.trim().replace(/;$/, "");
|
|
3241
|
+
}
|
|
3242
|
+
};
|
|
3243
|
+
|
|
2997
3244
|
// src/core/dialect/mysql/index.ts
|
|
2998
|
-
var MySqlDialect = class extends
|
|
3245
|
+
var MySqlDialect = class extends SqlDialectBase {
|
|
2999
3246
|
/**
|
|
3000
3247
|
* Creates a new MySqlDialect instance
|
|
3001
3248
|
*/
|
|
@@ -3019,78 +3266,6 @@ var MySqlDialect = class extends Dialect {
|
|
|
3019
3266
|
const col2 = `${this.quoteIdentifier(node.column.table)}.${this.quoteIdentifier(node.column.name)}`;
|
|
3020
3267
|
return `${col2}->'${node.path}'`;
|
|
3021
3268
|
}
|
|
3022
|
-
/**
|
|
3023
|
-
* Compiles SELECT query AST to MySQL SQL
|
|
3024
|
-
* @param ast - Query AST
|
|
3025
|
-
* @param ctx - Compiler context
|
|
3026
|
-
* @returns MySQL SQL string
|
|
3027
|
-
*/
|
|
3028
|
-
compileSelectAst(ast, ctx) {
|
|
3029
|
-
const columns = ast.columns.map((c) => {
|
|
3030
|
-
let expr = "";
|
|
3031
|
-
if (c.type === "Function") {
|
|
3032
|
-
expr = this.compileOperand(c, ctx);
|
|
3033
|
-
} else if (c.type === "Column") {
|
|
3034
|
-
expr = `${this.quoteIdentifier(c.table)}.${this.quoteIdentifier(c.name)}`;
|
|
3035
|
-
} else if (c.type === "ScalarSubquery") {
|
|
3036
|
-
expr = this.compileOperand(c, ctx);
|
|
3037
|
-
} else if (c.type === "WindowFunction") {
|
|
3038
|
-
expr = this.compileOperand(c, ctx);
|
|
3039
|
-
}
|
|
3040
|
-
if (c.alias) {
|
|
3041
|
-
if (c.alias.includes("(")) return c.alias;
|
|
3042
|
-
return `${expr} AS ${this.quoteIdentifier(c.alias)}`;
|
|
3043
|
-
}
|
|
3044
|
-
return expr;
|
|
3045
|
-
}).join(", ");
|
|
3046
|
-
const distinct = ast.distinct ? "DISTINCT " : "";
|
|
3047
|
-
const from = `${this.quoteIdentifier(ast.from.name)}`;
|
|
3048
|
-
const joins = ast.joins.map((j) => {
|
|
3049
|
-
const table = this.quoteIdentifier(j.table.name);
|
|
3050
|
-
const cond = this.compileExpression(j.condition, ctx);
|
|
3051
|
-
return `${j.kind} JOIN ${table} ON ${cond}`;
|
|
3052
|
-
}).join(" ");
|
|
3053
|
-
const whereClause = this.compileWhere(ast.where, ctx);
|
|
3054
|
-
const groupBy = ast.groupBy && ast.groupBy.length > 0 ? " GROUP BY " + ast.groupBy.map((c) => `${this.quoteIdentifier(c.table)}.${this.quoteIdentifier(c.name)}`).join(", ") : "";
|
|
3055
|
-
const having = ast.having ? ` HAVING ${this.compileExpression(ast.having, ctx)}` : "";
|
|
3056
|
-
const orderBy = ast.orderBy && ast.orderBy.length > 0 ? " ORDER BY " + ast.orderBy.map((o) => `${this.quoteIdentifier(o.column.table)}.${this.quoteIdentifier(o.column.name)} ${o.direction}`).join(", ") : "";
|
|
3057
|
-
const limit = ast.limit ? ` LIMIT ${ast.limit}` : "";
|
|
3058
|
-
const offset = ast.offset ? ` OFFSET ${ast.offset}` : "";
|
|
3059
|
-
const ctes = ast.ctes && ast.ctes.length > 0 ? (() => {
|
|
3060
|
-
const hasRecursive = ast.ctes.some((cte) => cte.recursive);
|
|
3061
|
-
const prefix = hasRecursive ? "WITH RECURSIVE " : "WITH ";
|
|
3062
|
-
const cteDefs = ast.ctes.map((cte) => {
|
|
3063
|
-
const name = this.quoteIdentifier(cte.name);
|
|
3064
|
-
const cols = cte.columns ? `(${cte.columns.map((c) => this.quoteIdentifier(c)).join(", ")})` : "";
|
|
3065
|
-
const query = this.compileSelectAst(cte.query, ctx).trim().replace(/;$/, "");
|
|
3066
|
-
return `${name}${cols} AS (${query})`;
|
|
3067
|
-
}).join(", ");
|
|
3068
|
-
return prefix + cteDefs + " ";
|
|
3069
|
-
})() : "";
|
|
3070
|
-
return `${ctes}SELECT ${distinct}${columns} FROM ${from}${joins ? " " + joins : ""}${whereClause}${groupBy}${having}${orderBy}${limit}${offset};`;
|
|
3071
|
-
}
|
|
3072
|
-
compileInsertAst(ast, ctx) {
|
|
3073
|
-
const table = this.quoteIdentifier(ast.into.name);
|
|
3074
|
-
const columnList = ast.columns.map((column) => `${this.quoteIdentifier(column.table)}.${this.quoteIdentifier(column.name)}`).join(", ");
|
|
3075
|
-
const values = ast.values.map((row) => `(${row.map((value) => this.compileOperand(value, ctx)).join(", ")})`).join(", ");
|
|
3076
|
-
return `INSERT INTO ${table} (${columnList}) VALUES ${values};`;
|
|
3077
|
-
}
|
|
3078
|
-
compileUpdateAst(ast, ctx) {
|
|
3079
|
-
const table = this.quoteIdentifier(ast.table.name);
|
|
3080
|
-
const assignments = ast.set.map((assignment) => {
|
|
3081
|
-
const col2 = assignment.column;
|
|
3082
|
-
const target = `${this.quoteIdentifier(col2.table)}.${this.quoteIdentifier(col2.name)}`;
|
|
3083
|
-
const value = this.compileOperand(assignment.value, ctx);
|
|
3084
|
-
return `${target} = ${value}`;
|
|
3085
|
-
}).join(", ");
|
|
3086
|
-
const whereClause = this.compileWhere(ast.where, ctx);
|
|
3087
|
-
return `UPDATE ${table} SET ${assignments}${whereClause};`;
|
|
3088
|
-
}
|
|
3089
|
-
compileDeleteAst(ast, ctx) {
|
|
3090
|
-
const table = this.quoteIdentifier(ast.from.name);
|
|
3091
|
-
const whereClause = this.compileWhere(ast.where, ctx);
|
|
3092
|
-
return `DELETE FROM ${table}${whereClause};`;
|
|
3093
|
-
}
|
|
3094
3269
|
};
|
|
3095
3270
|
|
|
3096
3271
|
// src/core/dialect/mssql/index.ts
|
|
@@ -3204,7 +3379,7 @@ var SqlServerDialect = class extends Dialect {
|
|
|
3204
3379
|
};
|
|
3205
3380
|
|
|
3206
3381
|
// src/core/dialect/sqlite/index.ts
|
|
3207
|
-
var SqliteDialect = class extends
|
|
3382
|
+
var SqliteDialect = class extends SqlDialectBase {
|
|
3208
3383
|
/**
|
|
3209
3384
|
* Creates a new SqliteDialect instance
|
|
3210
3385
|
*/
|
|
@@ -3228,82 +3403,40 @@ var SqliteDialect = class extends Dialect {
|
|
|
3228
3403
|
const col2 = `${this.quoteIdentifier(node.column.table)}.${this.quoteIdentifier(node.column.name)}`;
|
|
3229
3404
|
return `json_extract(${col2}, '${node.path}')`;
|
|
3230
3405
|
}
|
|
3231
|
-
|
|
3232
|
-
|
|
3233
|
-
|
|
3234
|
-
|
|
3235
|
-
|
|
3236
|
-
*/
|
|
3237
|
-
compileSelectAst(ast, ctx) {
|
|
3238
|
-
const columns = ast.columns.map((c) => {
|
|
3239
|
-
let expr = "";
|
|
3240
|
-
if (c.type === "Function") {
|
|
3241
|
-
expr = this.compileOperand(c, ctx);
|
|
3242
|
-
} else if (c.type === "Column") {
|
|
3243
|
-
expr = `${this.quoteIdentifier(c.table)}.${this.quoteIdentifier(c.name)}`;
|
|
3244
|
-
} else if (c.type === "ScalarSubquery") {
|
|
3245
|
-
expr = this.compileOperand(c, ctx);
|
|
3246
|
-
} else if (c.type === "CaseExpression") {
|
|
3247
|
-
expr = this.compileOperand(c, ctx);
|
|
3248
|
-
} else if (c.type === "WindowFunction") {
|
|
3249
|
-
expr = this.compileOperand(c, ctx);
|
|
3250
|
-
}
|
|
3251
|
-
if (c.alias) {
|
|
3252
|
-
if (c.alias.includes("(")) return c.alias;
|
|
3253
|
-
return `${expr} AS ${this.quoteIdentifier(c.alias)}`;
|
|
3254
|
-
}
|
|
3255
|
-
return expr;
|
|
3406
|
+
compileReturning(returning, ctx) {
|
|
3407
|
+
if (!returning || returning.length === 0) return "";
|
|
3408
|
+
const columns = returning.map((column) => {
|
|
3409
|
+
const tablePart = column.table ? `${this.quoteIdentifier(column.table)}.` : "";
|
|
3410
|
+
return `${tablePart}${this.quoteIdentifier(column.name)}`;
|
|
3256
3411
|
}).join(", ");
|
|
3257
|
-
|
|
3258
|
-
const from = `${this.quoteIdentifier(ast.from.name)}`;
|
|
3259
|
-
const joins = ast.joins.map((j) => {
|
|
3260
|
-
const table = this.quoteIdentifier(j.table.name);
|
|
3261
|
-
const cond = this.compileExpression(j.condition, ctx);
|
|
3262
|
-
return `${j.kind} JOIN ${table} ON ${cond}`;
|
|
3263
|
-
}).join(" ");
|
|
3264
|
-
const whereClause = this.compileWhere(ast.where, ctx);
|
|
3265
|
-
const groupBy = ast.groupBy && ast.groupBy.length > 0 ? " GROUP BY " + ast.groupBy.map((c) => `${this.quoteIdentifier(c.table)}.${this.quoteIdentifier(c.name)}`).join(", ") : "";
|
|
3266
|
-
const having = ast.having ? ` HAVING ${this.compileExpression(ast.having, ctx)}` : "";
|
|
3267
|
-
const orderBy = ast.orderBy && ast.orderBy.length > 0 ? " ORDER BY " + ast.orderBy.map((o) => `${this.quoteIdentifier(o.column.table)}.${this.quoteIdentifier(o.column.name)} ${o.direction}`).join(", ") : "";
|
|
3268
|
-
const limit = ast.limit ? ` LIMIT ${ast.limit}` : "";
|
|
3269
|
-
const offset = ast.offset ? ` OFFSET ${ast.offset}` : "";
|
|
3270
|
-
const ctes = ast.ctes && ast.ctes.length > 0 ? (() => {
|
|
3271
|
-
const hasRecursive = ast.ctes.some((cte) => cte.recursive);
|
|
3272
|
-
const prefix = hasRecursive ? "WITH RECURSIVE " : "WITH ";
|
|
3273
|
-
const cteDefs = ast.ctes.map((cte) => {
|
|
3274
|
-
const name = this.quoteIdentifier(cte.name);
|
|
3275
|
-
const cols = cte.columns ? `(${cte.columns.map((c) => this.quoteIdentifier(c)).join(", ")})` : "";
|
|
3276
|
-
const query = this.compileSelectAst(cte.query, ctx).trim().replace(/;$/, "");
|
|
3277
|
-
return `${name}${cols} AS (${query})`;
|
|
3278
|
-
}).join(", ");
|
|
3279
|
-
return prefix + cteDefs + " ";
|
|
3280
|
-
})() : "";
|
|
3281
|
-
return `${ctes}SELECT ${distinct}${columns} FROM ${from}${joins ? " " + joins : ""}${whereClause}${groupBy}${having}${orderBy}${limit}${offset};`;
|
|
3412
|
+
return ` RETURNING ${columns}`;
|
|
3282
3413
|
}
|
|
3283
|
-
|
|
3284
|
-
|
|
3285
|
-
|
|
3286
|
-
|
|
3287
|
-
|
|
3288
|
-
|
|
3414
|
+
};
|
|
3415
|
+
|
|
3416
|
+
// src/core/dialect/postgres/index.ts
|
|
3417
|
+
var PostgresDialect = class extends SqlDialectBase {
|
|
3418
|
+
/**
|
|
3419
|
+
* Creates a new PostgresDialect instance
|
|
3420
|
+
*/
|
|
3421
|
+
constructor() {
|
|
3422
|
+
super();
|
|
3289
3423
|
}
|
|
3290
|
-
|
|
3291
|
-
|
|
3292
|
-
|
|
3293
|
-
|
|
3294
|
-
|
|
3295
|
-
|
|
3296
|
-
|
|
3297
|
-
}).join(", ");
|
|
3298
|
-
const whereClause = this.compileWhere(ast.where, ctx);
|
|
3299
|
-
const returning = this.compileReturning(ast.returning, ctx);
|
|
3300
|
-
return `UPDATE ${table} SET ${assignments}${whereClause}${returning};`;
|
|
3424
|
+
/**
|
|
3425
|
+
* Quotes an identifier using PostgreSQL double-quote syntax
|
|
3426
|
+
* @param id - Identifier to quote
|
|
3427
|
+
* @returns Quoted identifier
|
|
3428
|
+
*/
|
|
3429
|
+
quoteIdentifier(id) {
|
|
3430
|
+
return `"${id}"`;
|
|
3301
3431
|
}
|
|
3302
|
-
|
|
3303
|
-
|
|
3304
|
-
|
|
3305
|
-
|
|
3306
|
-
|
|
3432
|
+
/**
|
|
3433
|
+
* Compiles JSON path expression using PostgreSQL syntax
|
|
3434
|
+
* @param node - JSON path node
|
|
3435
|
+
* @returns PostgreSQL JSON path expression
|
|
3436
|
+
*/
|
|
3437
|
+
compileJsonPath(node) {
|
|
3438
|
+
const col2 = `${this.quoteIdentifier(node.column.table)}.${this.quoteIdentifier(node.column.name)}`;
|
|
3439
|
+
return `${col2}->>'${node.path}'`;
|
|
3307
3440
|
}
|
|
3308
3441
|
compileReturning(returning, ctx) {
|
|
3309
3442
|
if (!returning || returning.length === 0) return "";
|
|
@@ -3315,6 +3448,1100 @@ var SqliteDialect = class extends Dialect {
|
|
|
3315
3448
|
}
|
|
3316
3449
|
};
|
|
3317
3450
|
|
|
3451
|
+
// src/core/ddl/dialects/base-schema-dialect.ts
|
|
3452
|
+
var BaseSchemaDialect = class {
|
|
3453
|
+
supportsPartialIndexes() {
|
|
3454
|
+
return false;
|
|
3455
|
+
}
|
|
3456
|
+
formatTableName(table) {
|
|
3457
|
+
if (table.schema) {
|
|
3458
|
+
return `${this.quoteIdentifier(table.schema)}.${this.quoteIdentifier(table.name)}`;
|
|
3459
|
+
}
|
|
3460
|
+
return this.quoteIdentifier(table.name);
|
|
3461
|
+
}
|
|
3462
|
+
renderDefault(value, _column) {
|
|
3463
|
+
return formatLiteral(value, this.name);
|
|
3464
|
+
}
|
|
3465
|
+
renderReference(ref, _table) {
|
|
3466
|
+
const parts = ["REFERENCES", quoteQualified(this, ref.table), `(${this.quoteIdentifier(ref.column)})`];
|
|
3467
|
+
if (ref.onDelete) parts.push("ON DELETE", ref.onDelete);
|
|
3468
|
+
if (ref.onUpdate) parts.push("ON UPDATE", ref.onUpdate);
|
|
3469
|
+
if (ref.deferrable && this.name === "postgres") parts.push("DEFERRABLE INITIALLY DEFERRED");
|
|
3470
|
+
return parts.join(" ");
|
|
3471
|
+
}
|
|
3472
|
+
renderTableOptions(_table) {
|
|
3473
|
+
return void 0;
|
|
3474
|
+
}
|
|
3475
|
+
dropTableSql(table) {
|
|
3476
|
+
return [`DROP TABLE IF EXISTS ${this.formatTableName(table)};`];
|
|
3477
|
+
}
|
|
3478
|
+
warnDropColumn(_table, _column) {
|
|
3479
|
+
return void 0;
|
|
3480
|
+
}
|
|
3481
|
+
};
|
|
3482
|
+
|
|
3483
|
+
// src/core/ddl/dialects/postgres-schema-dialect.ts
|
|
3484
|
+
var PostgresSchemaDialect = class extends BaseSchemaDialect {
|
|
3485
|
+
constructor() {
|
|
3486
|
+
super(...arguments);
|
|
3487
|
+
this.name = "postgres";
|
|
3488
|
+
}
|
|
3489
|
+
quoteIdentifier(id) {
|
|
3490
|
+
return `"${id}"`;
|
|
3491
|
+
}
|
|
3492
|
+
renderColumnType(column) {
|
|
3493
|
+
switch (column.type) {
|
|
3494
|
+
case "INT":
|
|
3495
|
+
case "INTEGER":
|
|
3496
|
+
case "int":
|
|
3497
|
+
case "integer":
|
|
3498
|
+
return "integer";
|
|
3499
|
+
case "BIGINT":
|
|
3500
|
+
case "bigint":
|
|
3501
|
+
return "bigint";
|
|
3502
|
+
case "UUID":
|
|
3503
|
+
case "uuid":
|
|
3504
|
+
return "uuid";
|
|
3505
|
+
case "BOOLEAN":
|
|
3506
|
+
case "boolean":
|
|
3507
|
+
return "boolean";
|
|
3508
|
+
case "JSON":
|
|
3509
|
+
case "json":
|
|
3510
|
+
return "jsonb";
|
|
3511
|
+
case "DECIMAL":
|
|
3512
|
+
case "decimal":
|
|
3513
|
+
return column.args?.length ? `numeric(${column.args[0]}, ${column.args[1] ?? 0})` : "numeric";
|
|
3514
|
+
case "FLOAT":
|
|
3515
|
+
case "float":
|
|
3516
|
+
case "DOUBLE":
|
|
3517
|
+
case "double":
|
|
3518
|
+
return "double precision";
|
|
3519
|
+
case "TIMESTAMPTZ":
|
|
3520
|
+
case "timestamptz":
|
|
3521
|
+
return "timestamptz";
|
|
3522
|
+
case "TIMESTAMP":
|
|
3523
|
+
case "timestamp":
|
|
3524
|
+
return "timestamp";
|
|
3525
|
+
case "DATE":
|
|
3526
|
+
case "date":
|
|
3527
|
+
return "date";
|
|
3528
|
+
case "DATETIME":
|
|
3529
|
+
case "datetime":
|
|
3530
|
+
return "timestamp";
|
|
3531
|
+
case "VARCHAR":
|
|
3532
|
+
case "varchar":
|
|
3533
|
+
return column.args?.length ? `varchar(${column.args[0]})` : "varchar";
|
|
3534
|
+
case "TEXT":
|
|
3535
|
+
case "text":
|
|
3536
|
+
return "text";
|
|
3537
|
+
case "ENUM":
|
|
3538
|
+
case "enum":
|
|
3539
|
+
return "text";
|
|
3540
|
+
default:
|
|
3541
|
+
return String(column.type).toLowerCase();
|
|
3542
|
+
}
|
|
3543
|
+
}
|
|
3544
|
+
renderAutoIncrement(column) {
|
|
3545
|
+
if (!column.autoIncrement) return void 0;
|
|
3546
|
+
const strategy = column.generated === "always" ? "GENERATED ALWAYS" : "GENERATED BY DEFAULT";
|
|
3547
|
+
return `${strategy} AS IDENTITY`;
|
|
3548
|
+
}
|
|
3549
|
+
renderIndex(table, index) {
|
|
3550
|
+
const name = index.name || deriveIndexName(table, index);
|
|
3551
|
+
const cols = renderIndexColumns(this, index.columns);
|
|
3552
|
+
const unique = index.unique ? "UNIQUE " : "";
|
|
3553
|
+
const where = index.where ? ` WHERE ${index.where}` : "";
|
|
3554
|
+
return `CREATE ${unique}INDEX IF NOT EXISTS ${this.quoteIdentifier(name)} ON ${this.formatTableName(table)} (${cols})${where};`;
|
|
3555
|
+
}
|
|
3556
|
+
supportsPartialIndexes() {
|
|
3557
|
+
return true;
|
|
3558
|
+
}
|
|
3559
|
+
dropColumnSql(table, column) {
|
|
3560
|
+
return [`ALTER TABLE ${this.formatTableName(table)} DROP COLUMN ${this.quoteIdentifier(column)};`];
|
|
3561
|
+
}
|
|
3562
|
+
dropIndexSql(table, index) {
|
|
3563
|
+
const qualified = table.schema ? `${this.quoteIdentifier(table.schema)}.${this.quoteIdentifier(index)}` : this.quoteIdentifier(index);
|
|
3564
|
+
return [`DROP INDEX IF EXISTS ${qualified};`];
|
|
3565
|
+
}
|
|
3566
|
+
};
|
|
3567
|
+
|
|
3568
|
+
// src/core/ddl/dialects/mysql-schema-dialect.ts
|
|
3569
|
+
var MySqlSchemaDialect = class extends BaseSchemaDialect {
|
|
3570
|
+
constructor() {
|
|
3571
|
+
super(...arguments);
|
|
3572
|
+
this.name = "mysql";
|
|
3573
|
+
}
|
|
3574
|
+
quoteIdentifier(id) {
|
|
3575
|
+
return `\`${id}\``;
|
|
3576
|
+
}
|
|
3577
|
+
renderColumnType(column) {
|
|
3578
|
+
switch (column.type) {
|
|
3579
|
+
case "INT":
|
|
3580
|
+
case "INTEGER":
|
|
3581
|
+
case "int":
|
|
3582
|
+
case "integer":
|
|
3583
|
+
return "INT";
|
|
3584
|
+
case "BIGINT":
|
|
3585
|
+
case "bigint":
|
|
3586
|
+
return "BIGINT";
|
|
3587
|
+
case "UUID":
|
|
3588
|
+
case "uuid":
|
|
3589
|
+
return "CHAR(36)";
|
|
3590
|
+
case "BOOLEAN":
|
|
3591
|
+
case "boolean":
|
|
3592
|
+
return "TINYINT(1)";
|
|
3593
|
+
case "JSON":
|
|
3594
|
+
case "json":
|
|
3595
|
+
return "JSON";
|
|
3596
|
+
case "DECIMAL":
|
|
3597
|
+
case "decimal":
|
|
3598
|
+
return column.args?.length ? `DECIMAL(${column.args[0]},${column.args[1] ?? 0})` : "DECIMAL";
|
|
3599
|
+
case "FLOAT":
|
|
3600
|
+
case "float":
|
|
3601
|
+
return column.args?.length ? `FLOAT(${column.args[0]})` : "FLOAT";
|
|
3602
|
+
case "DOUBLE":
|
|
3603
|
+
case "double":
|
|
3604
|
+
return "DOUBLE";
|
|
3605
|
+
case "TIMESTAMPTZ":
|
|
3606
|
+
case "timestamptz":
|
|
3607
|
+
return "TIMESTAMP";
|
|
3608
|
+
case "TIMESTAMP":
|
|
3609
|
+
case "timestamp":
|
|
3610
|
+
return "TIMESTAMP";
|
|
3611
|
+
case "DATETIME":
|
|
3612
|
+
case "datetime":
|
|
3613
|
+
return "DATETIME";
|
|
3614
|
+
case "DATE":
|
|
3615
|
+
case "date":
|
|
3616
|
+
return "DATE";
|
|
3617
|
+
case "VARCHAR":
|
|
3618
|
+
case "varchar":
|
|
3619
|
+
return column.args?.length ? `VARCHAR(${column.args[0]})` : "VARCHAR(255)";
|
|
3620
|
+
case "TEXT":
|
|
3621
|
+
case "text":
|
|
3622
|
+
return "TEXT";
|
|
3623
|
+
case "ENUM":
|
|
3624
|
+
case "enum":
|
|
3625
|
+
return column.args && Array.isArray(column.args) && column.args.length ? `ENUM(${column.args.map((v) => `'${escapeLiteral(v)}'`).join(",")})` : "ENUM";
|
|
3626
|
+
default:
|
|
3627
|
+
return String(column.type).toUpperCase();
|
|
3628
|
+
}
|
|
3629
|
+
}
|
|
3630
|
+
renderDefault(value) {
|
|
3631
|
+
return formatLiteral(value, this.name);
|
|
3632
|
+
}
|
|
3633
|
+
renderAutoIncrement(column) {
|
|
3634
|
+
return column.autoIncrement ? "AUTO_INCREMENT" : void 0;
|
|
3635
|
+
}
|
|
3636
|
+
renderIndex(table, index) {
|
|
3637
|
+
if (index.where) {
|
|
3638
|
+
throw new Error("MySQL does not support partial/filtered indexes");
|
|
3639
|
+
}
|
|
3640
|
+
const name = index.name || deriveIndexName(table, index);
|
|
3641
|
+
const cols = renderIndexColumns(this, index.columns);
|
|
3642
|
+
const unique = index.unique ? "UNIQUE " : "";
|
|
3643
|
+
return `CREATE ${unique}INDEX ${this.quoteIdentifier(name)} ON ${this.formatTableName(table)} (${cols});`;
|
|
3644
|
+
}
|
|
3645
|
+
renderTableOptions(table) {
|
|
3646
|
+
const parts = [];
|
|
3647
|
+
if (table.engine) parts.push(`ENGINE=${table.engine}`);
|
|
3648
|
+
if (table.charset) parts.push(`DEFAULT CHARSET=${table.charset}`);
|
|
3649
|
+
if (table.collation) parts.push(`COLLATE=${table.collation}`);
|
|
3650
|
+
return parts.length ? parts.join(" ") : void 0;
|
|
3651
|
+
}
|
|
3652
|
+
dropColumnSql(table, column) {
|
|
3653
|
+
return [`ALTER TABLE ${this.formatTableName(table)} DROP COLUMN ${this.quoteIdentifier(column)};`];
|
|
3654
|
+
}
|
|
3655
|
+
dropIndexSql(table, index) {
|
|
3656
|
+
return [`DROP INDEX ${this.quoteIdentifier(index)} ON ${this.formatTableName(table)};`];
|
|
3657
|
+
}
|
|
3658
|
+
};
|
|
3659
|
+
|
|
3660
|
+
// src/core/ddl/dialects/sqlite-schema-dialect.ts
|
|
3661
|
+
var SQLiteSchemaDialect = class extends BaseSchemaDialect {
|
|
3662
|
+
constructor() {
|
|
3663
|
+
super(...arguments);
|
|
3664
|
+
this.name = "sqlite";
|
|
3665
|
+
}
|
|
3666
|
+
quoteIdentifier(id) {
|
|
3667
|
+
return `"${id}"`;
|
|
3668
|
+
}
|
|
3669
|
+
renderColumnType(column) {
|
|
3670
|
+
switch (column.type) {
|
|
3671
|
+
case "INT":
|
|
3672
|
+
case "INTEGER":
|
|
3673
|
+
case "int":
|
|
3674
|
+
case "integer":
|
|
3675
|
+
case "BIGINT":
|
|
3676
|
+
case "bigint":
|
|
3677
|
+
return "INTEGER";
|
|
3678
|
+
case "BOOLEAN":
|
|
3679
|
+
case "boolean":
|
|
3680
|
+
return "INTEGER";
|
|
3681
|
+
case "DECIMAL":
|
|
3682
|
+
case "decimal":
|
|
3683
|
+
case "FLOAT":
|
|
3684
|
+
case "float":
|
|
3685
|
+
case "DOUBLE":
|
|
3686
|
+
case "double":
|
|
3687
|
+
return "REAL";
|
|
3688
|
+
case "DATE":
|
|
3689
|
+
case "date":
|
|
3690
|
+
case "DATETIME":
|
|
3691
|
+
case "datetime":
|
|
3692
|
+
case "TIMESTAMP":
|
|
3693
|
+
case "timestamp":
|
|
3694
|
+
case "TIMESTAMPTZ":
|
|
3695
|
+
case "timestamptz":
|
|
3696
|
+
return "TEXT";
|
|
3697
|
+
case "VARCHAR":
|
|
3698
|
+
case "varchar":
|
|
3699
|
+
case "TEXT":
|
|
3700
|
+
case "text":
|
|
3701
|
+
case "JSON":
|
|
3702
|
+
case "json":
|
|
3703
|
+
case "UUID":
|
|
3704
|
+
case "uuid":
|
|
3705
|
+
return "TEXT";
|
|
3706
|
+
case "ENUM":
|
|
3707
|
+
case "enum":
|
|
3708
|
+
return "TEXT";
|
|
3709
|
+
default:
|
|
3710
|
+
return "TEXT";
|
|
3711
|
+
}
|
|
3712
|
+
}
|
|
3713
|
+
renderAutoIncrement(column, table) {
|
|
3714
|
+
const pk = resolvePrimaryKey(table);
|
|
3715
|
+
if (column.autoIncrement && pk.length === 1 && pk[0] === column.name) {
|
|
3716
|
+
return "PRIMARY KEY AUTOINCREMENT";
|
|
3717
|
+
}
|
|
3718
|
+
return void 0;
|
|
3719
|
+
}
|
|
3720
|
+
preferInlinePkAutoincrement(column, table, pk) {
|
|
3721
|
+
return !!(column.autoIncrement && pk.length === 1 && pk[0] === column.name);
|
|
3722
|
+
}
|
|
3723
|
+
renderDefault(value) {
|
|
3724
|
+
return formatLiteral(value, this.name);
|
|
3725
|
+
}
|
|
3726
|
+
renderIndex(table, index) {
|
|
3727
|
+
if (index.where) {
|
|
3728
|
+
throw new Error("SQLite does not support partial/filtered indexes");
|
|
3729
|
+
}
|
|
3730
|
+
const name = index.name || deriveIndexName(table, index);
|
|
3731
|
+
const cols = renderIndexColumns(this, index.columns);
|
|
3732
|
+
const unique = index.unique ? "UNIQUE " : "";
|
|
3733
|
+
return `CREATE ${unique}INDEX IF NOT EXISTS ${this.quoteIdentifier(name)} ON ${this.formatTableName(table)} (${cols});`;
|
|
3734
|
+
}
|
|
3735
|
+
dropColumnSql(_table, _column) {
|
|
3736
|
+
return [];
|
|
3737
|
+
}
|
|
3738
|
+
dropIndexSql(_table, index) {
|
|
3739
|
+
return [`DROP INDEX IF EXISTS ${this.quoteIdentifier(index)};`];
|
|
3740
|
+
}
|
|
3741
|
+
warnDropColumn(table, column) {
|
|
3742
|
+
const key = table.schema ? `${table.schema}.${table.name}` : table.name;
|
|
3743
|
+
return `Dropping columns on SQLite requires table rebuild (column ${column} on ${key}).`;
|
|
3744
|
+
}
|
|
3745
|
+
};
|
|
3746
|
+
|
|
3747
|
+
// src/core/ddl/dialects/mssql-schema-dialect.ts
|
|
3748
|
+
var MSSqlSchemaDialect = class extends BaseSchemaDialect {
|
|
3749
|
+
constructor() {
|
|
3750
|
+
super(...arguments);
|
|
3751
|
+
this.name = "mssql";
|
|
3752
|
+
}
|
|
3753
|
+
quoteIdentifier(id) {
|
|
3754
|
+
return `[${id.replace(/]/g, "]]")}]`;
|
|
3755
|
+
}
|
|
3756
|
+
renderColumnType(column) {
|
|
3757
|
+
switch (column.type) {
|
|
3758
|
+
case "INT":
|
|
3759
|
+
case "INTEGER":
|
|
3760
|
+
case "int":
|
|
3761
|
+
case "integer":
|
|
3762
|
+
return "INT";
|
|
3763
|
+
case "BIGINT":
|
|
3764
|
+
case "bigint":
|
|
3765
|
+
return "BIGINT";
|
|
3766
|
+
case "UUID":
|
|
3767
|
+
case "uuid":
|
|
3768
|
+
return "UNIQUEIDENTIFIER";
|
|
3769
|
+
case "BOOLEAN":
|
|
3770
|
+
case "boolean":
|
|
3771
|
+
return "BIT";
|
|
3772
|
+
case "JSON":
|
|
3773
|
+
case "json":
|
|
3774
|
+
return "NVARCHAR(MAX)";
|
|
3775
|
+
case "DECIMAL":
|
|
3776
|
+
case "decimal":
|
|
3777
|
+
return column.args?.length ? `DECIMAL(${column.args[0]},${column.args[1] ?? 0})` : "DECIMAL(18,0)";
|
|
3778
|
+
case "FLOAT":
|
|
3779
|
+
case "float":
|
|
3780
|
+
case "DOUBLE":
|
|
3781
|
+
case "double":
|
|
3782
|
+
return "FLOAT";
|
|
3783
|
+
case "TIMESTAMPTZ":
|
|
3784
|
+
case "timestamptz":
|
|
3785
|
+
case "TIMESTAMP":
|
|
3786
|
+
case "timestamp":
|
|
3787
|
+
case "DATETIME":
|
|
3788
|
+
case "datetime":
|
|
3789
|
+
return "DATETIME2";
|
|
3790
|
+
case "DATE":
|
|
3791
|
+
case "date":
|
|
3792
|
+
return "DATE";
|
|
3793
|
+
case "VARCHAR":
|
|
3794
|
+
case "varchar":
|
|
3795
|
+
return column.args?.length ? `NVARCHAR(${column.args[0]})` : "NVARCHAR(255)";
|
|
3796
|
+
case "TEXT":
|
|
3797
|
+
case "text":
|
|
3798
|
+
return "NVARCHAR(MAX)";
|
|
3799
|
+
case "ENUM":
|
|
3800
|
+
case "enum":
|
|
3801
|
+
return "NVARCHAR(255)";
|
|
3802
|
+
default:
|
|
3803
|
+
return String(column.type).toUpperCase();
|
|
3804
|
+
}
|
|
3805
|
+
}
|
|
3806
|
+
renderDefault(value) {
|
|
3807
|
+
return formatLiteral(value, this.name);
|
|
3808
|
+
}
|
|
3809
|
+
renderAutoIncrement(column) {
|
|
3810
|
+
return column.autoIncrement ? "IDENTITY(1,1)" : void 0;
|
|
3811
|
+
}
|
|
3812
|
+
renderIndex(table, index) {
|
|
3813
|
+
const name = index.name || deriveIndexName(table, index);
|
|
3814
|
+
const cols = renderIndexColumns(this, index.columns);
|
|
3815
|
+
const unique = index.unique ? "UNIQUE " : "";
|
|
3816
|
+
const where = index.where ? ` WHERE ${index.where}` : "";
|
|
3817
|
+
return `CREATE ${unique}INDEX ${this.quoteIdentifier(name)} ON ${this.formatTableName(table)} (${cols})${where};`;
|
|
3818
|
+
}
|
|
3819
|
+
supportsPartialIndexes() {
|
|
3820
|
+
return true;
|
|
3821
|
+
}
|
|
3822
|
+
dropColumnSql(table, column) {
|
|
3823
|
+
return [`ALTER TABLE ${this.formatTableName(table)} DROP COLUMN ${this.quoteIdentifier(column)};`];
|
|
3824
|
+
}
|
|
3825
|
+
dropIndexSql(table, index) {
|
|
3826
|
+
return [`DROP INDEX ${this.quoteIdentifier(index)} ON ${this.formatTableName(table)};`];
|
|
3827
|
+
}
|
|
3828
|
+
};
|
|
3829
|
+
|
|
3830
|
+
// src/core/ddl/schema-generator.ts
|
|
3831
|
+
var escapeLiteral = (value) => value.replace(/'/g, "''");
|
|
3832
|
+
var isRawDefault = (value) => {
|
|
3833
|
+
return !!value && typeof value === "object" && "raw" in value && typeof value.raw === "string";
|
|
3834
|
+
};
|
|
3835
|
+
var formatLiteral = (value, dialect) => {
|
|
3836
|
+
if (isRawDefault(value)) return value.raw;
|
|
3837
|
+
if (value === null) return "NULL";
|
|
3838
|
+
if (typeof value === "number") return Number.isFinite(value) ? String(value) : "NULL";
|
|
3839
|
+
if (typeof value === "boolean") {
|
|
3840
|
+
if (dialect === "mysql" || dialect === "sqlite" || dialect === "mssql") {
|
|
3841
|
+
return value ? "1" : "0";
|
|
3842
|
+
}
|
|
3843
|
+
return value ? "TRUE" : "FALSE";
|
|
3844
|
+
}
|
|
3845
|
+
if (value instanceof Date) return `'${escapeLiteral(value.toISOString())}'`;
|
|
3846
|
+
if (typeof value === "string") return `'${escapeLiteral(value)}'`;
|
|
3847
|
+
return `'${escapeLiteral(JSON.stringify(value))}'`;
|
|
3848
|
+
};
|
|
3849
|
+
var resolvePrimaryKey = (table) => {
|
|
3850
|
+
if (table.primaryKey && table.primaryKey.length > 0) {
|
|
3851
|
+
return table.primaryKey;
|
|
3852
|
+
}
|
|
3853
|
+
const cols = Object.values(table.columns);
|
|
3854
|
+
return cols.filter((c) => c.primary).map((c) => c.name);
|
|
3855
|
+
};
|
|
3856
|
+
var quoteQualified = (dialect, identifier) => {
|
|
3857
|
+
if (identifier.includes(".")) {
|
|
3858
|
+
return identifier.split(".").map((part) => dialect.quoteIdentifier(part)).join(".");
|
|
3859
|
+
}
|
|
3860
|
+
return dialect.quoteIdentifier(identifier);
|
|
3861
|
+
};
|
|
3862
|
+
var renderIndexColumns = (dialect, columns) => {
|
|
3863
|
+
return columns.map((col2) => {
|
|
3864
|
+
if (typeof col2 === "string") return dialect.quoteIdentifier(col2);
|
|
3865
|
+
const parts = [dialect.quoteIdentifier(col2.column)];
|
|
3866
|
+
if (col2.order) parts.push(col2.order);
|
|
3867
|
+
if (col2.nulls) parts.push(`NULLS ${col2.nulls}`);
|
|
3868
|
+
return parts.join(" ");
|
|
3869
|
+
}).join(", ");
|
|
3870
|
+
};
|
|
3871
|
+
var deriveIndexName = (table, index) => {
|
|
3872
|
+
const base = (index.columns || []).map((col2) => typeof col2 === "string" ? col2 : col2.column).join("_");
|
|
3873
|
+
const suffix = index.unique ? "uniq" : "idx";
|
|
3874
|
+
return `${table.name}_${base}_${suffix}`;
|
|
3875
|
+
};
|
|
3876
|
+
var renderColumnDefinition = (table, col2, dialect, options = {}) => {
|
|
3877
|
+
const parts = [];
|
|
3878
|
+
parts.push(dialect.quoteIdentifier(col2.name));
|
|
3879
|
+
parts.push(dialect.renderColumnType(col2));
|
|
3880
|
+
const autoInc = dialect.renderAutoIncrement(col2, table);
|
|
3881
|
+
if (autoInc) parts.push(autoInc);
|
|
3882
|
+
if (col2.notNull) parts.push("NOT NULL");
|
|
3883
|
+
if (col2.unique) parts.push("UNIQUE");
|
|
3884
|
+
if (col2.default !== void 0) {
|
|
3885
|
+
parts.push(`DEFAULT ${dialect.renderDefault(col2.default, col2)}`);
|
|
3886
|
+
}
|
|
3887
|
+
if (options.includePrimary && col2.primary) {
|
|
3888
|
+
parts.push("PRIMARY KEY");
|
|
3889
|
+
}
|
|
3890
|
+
if (col2.check) {
|
|
3891
|
+
parts.push(`CHECK (${col2.check})`);
|
|
3892
|
+
}
|
|
3893
|
+
if (col2.references) {
|
|
3894
|
+
parts.push(dialect.renderReference(col2.references, table));
|
|
3895
|
+
}
|
|
3896
|
+
return { sql: parts.join(" "), inlinePrimary: !!(options.includePrimary && col2.primary) };
|
|
3897
|
+
};
|
|
3898
|
+
var generateCreateTableSql = (table, dialect) => {
|
|
3899
|
+
const pk = resolvePrimaryKey(table);
|
|
3900
|
+
const inlinePkColumns = /* @__PURE__ */ new Set();
|
|
3901
|
+
const columnLines = Object.values(table.columns).map((col2) => {
|
|
3902
|
+
const includePk = dialect.preferInlinePkAutoincrement?.(col2, table, pk) && pk.includes(col2.name);
|
|
3903
|
+
if (includePk) {
|
|
3904
|
+
inlinePkColumns.add(col2.name);
|
|
3905
|
+
}
|
|
3906
|
+
return renderColumnDefinition(table, col2, dialect, { includePrimary: includePk }).sql;
|
|
3907
|
+
});
|
|
3908
|
+
const constraintLines = [];
|
|
3909
|
+
if (pk.length > 0 && !(pk.length === 1 && inlinePkColumns.has(pk[0]))) {
|
|
3910
|
+
const cols = pk.map((c) => dialect.quoteIdentifier(c)).join(", ");
|
|
3911
|
+
constraintLines.push(`PRIMARY KEY (${cols})`);
|
|
3912
|
+
}
|
|
3913
|
+
if (table.checks) {
|
|
3914
|
+
table.checks.forEach((check) => {
|
|
3915
|
+
const name = check.name ? `${dialect.quoteIdentifier(check.name)} ` : "";
|
|
3916
|
+
constraintLines.push(`CONSTRAINT ${name}CHECK (${check.expression})`);
|
|
3917
|
+
});
|
|
3918
|
+
}
|
|
3919
|
+
const allLines = [...columnLines, ...constraintLines];
|
|
3920
|
+
const body = allLines.map((line) => ` ${line}`).join(",\n");
|
|
3921
|
+
const tableOptions = dialect.renderTableOptions(table);
|
|
3922
|
+
const tableSql = `CREATE TABLE ${dialect.formatTableName(table)} (
|
|
3923
|
+
${body}
|
|
3924
|
+
)${tableOptions ? " " + tableOptions : ""};`;
|
|
3925
|
+
const indexSql = [];
|
|
3926
|
+
if (table.indexes && table.indexes.length > 0) {
|
|
3927
|
+
for (const idx of table.indexes) {
|
|
3928
|
+
if (idx.where && !dialect.supportsPartialIndexes()) {
|
|
3929
|
+
throw new Error(`Dialect ${dialect.name} does not support partial/filtered indexes (${idx.name || idx.columns.join("_")}).`);
|
|
3930
|
+
}
|
|
3931
|
+
indexSql.push(dialect.renderIndex(table, idx));
|
|
3932
|
+
}
|
|
3933
|
+
}
|
|
3934
|
+
return { tableSql, indexSql };
|
|
3935
|
+
};
|
|
3936
|
+
var generateSchemaSql = (tables, dialect) => {
|
|
3937
|
+
const ordered = orderTablesByDependencies(tables);
|
|
3938
|
+
const statements = [];
|
|
3939
|
+
ordered.forEach((table) => {
|
|
3940
|
+
const { tableSql, indexSql } = generateCreateTableSql(table, dialect);
|
|
3941
|
+
statements.push(tableSql, ...indexSql);
|
|
3942
|
+
});
|
|
3943
|
+
return statements;
|
|
3944
|
+
};
|
|
3945
|
+
var orderTablesByDependencies = (tables) => {
|
|
3946
|
+
const map = /* @__PURE__ */ new Map();
|
|
3947
|
+
tables.forEach((t) => map.set(t.name, t));
|
|
3948
|
+
const deps = /* @__PURE__ */ new Map();
|
|
3949
|
+
for (const table of tables) {
|
|
3950
|
+
const refTables = /* @__PURE__ */ new Set();
|
|
3951
|
+
Object.values(table.columns).forEach((col2) => {
|
|
3952
|
+
if (col2.references?.table) {
|
|
3953
|
+
refTables.add(col2.references.table);
|
|
3954
|
+
}
|
|
3955
|
+
});
|
|
3956
|
+
deps.set(table.name, refTables);
|
|
3957
|
+
}
|
|
3958
|
+
const visited = /* @__PURE__ */ new Set();
|
|
3959
|
+
const ordered = [];
|
|
3960
|
+
const visit = (name, stack) => {
|
|
3961
|
+
if (visited.has(name)) return;
|
|
3962
|
+
const table = map.get(name);
|
|
3963
|
+
if (!table) return;
|
|
3964
|
+
if (stack.has(name)) {
|
|
3965
|
+
ordered.push(table);
|
|
3966
|
+
visited.add(name);
|
|
3967
|
+
return;
|
|
3968
|
+
}
|
|
3969
|
+
stack.add(name);
|
|
3970
|
+
for (const dep of deps.get(name) || []) {
|
|
3971
|
+
visit(dep, stack);
|
|
3972
|
+
}
|
|
3973
|
+
stack.delete(name);
|
|
3974
|
+
visited.add(name);
|
|
3975
|
+
ordered.push(table);
|
|
3976
|
+
};
|
|
3977
|
+
tables.forEach((t) => visit(t.name, /* @__PURE__ */ new Set()));
|
|
3978
|
+
return ordered;
|
|
3979
|
+
};
|
|
3980
|
+
|
|
3981
|
+
// src/core/ddl/schema-diff.ts
|
|
3982
|
+
var tableKey = (name, schema) => schema ? `${schema}.${name}` : name;
|
|
3983
|
+
var mapTables = (schema) => {
|
|
3984
|
+
const map = /* @__PURE__ */ new Map();
|
|
3985
|
+
for (const table of schema.tables) {
|
|
3986
|
+
map.set(tableKey(table.name, table.schema), table);
|
|
3987
|
+
}
|
|
3988
|
+
return map;
|
|
3989
|
+
};
|
|
3990
|
+
var buildAddColumnSql = (table, colName, dialect) => {
|
|
3991
|
+
const column = table.columns[colName];
|
|
3992
|
+
const rendered = renderColumnDefinition(table, column, dialect);
|
|
3993
|
+
return `ALTER TABLE ${dialect.formatTableName(table)} ADD ${rendered.sql};`;
|
|
3994
|
+
};
|
|
3995
|
+
var diffSchema = (expectedTables, actualSchema, dialect, options = {}) => {
|
|
3996
|
+
const allowDestructive = options.allowDestructive ?? false;
|
|
3997
|
+
const plan = { changes: [], warnings: [] };
|
|
3998
|
+
const actualMap = mapTables(actualSchema);
|
|
3999
|
+
for (const table of expectedTables) {
|
|
4000
|
+
const key = tableKey(table.name, table.schema);
|
|
4001
|
+
const actual = actualMap.get(key);
|
|
4002
|
+
if (!actual) {
|
|
4003
|
+
const { tableSql, indexSql } = generateCreateTableSql(table, dialect);
|
|
4004
|
+
plan.changes.push({
|
|
4005
|
+
kind: "createTable",
|
|
4006
|
+
table: key,
|
|
4007
|
+
description: `Create table ${key}`,
|
|
4008
|
+
statements: [tableSql, ...indexSql],
|
|
4009
|
+
safe: true
|
|
4010
|
+
});
|
|
4011
|
+
continue;
|
|
4012
|
+
}
|
|
4013
|
+
const actualCols = new Map(actual.columns.map((c) => [c.name, c]));
|
|
4014
|
+
for (const colName of Object.keys(table.columns)) {
|
|
4015
|
+
if (!actualCols.has(colName)) {
|
|
4016
|
+
plan.changes.push({
|
|
4017
|
+
kind: "addColumn",
|
|
4018
|
+
table: key,
|
|
4019
|
+
description: `Add column ${colName} to ${key}`,
|
|
4020
|
+
statements: [buildAddColumnSql(table, colName, dialect)],
|
|
4021
|
+
safe: true
|
|
4022
|
+
});
|
|
4023
|
+
}
|
|
4024
|
+
}
|
|
4025
|
+
for (const colName of actualCols.keys()) {
|
|
4026
|
+
if (!table.columns[colName]) {
|
|
4027
|
+
plan.changes.push({
|
|
4028
|
+
kind: "dropColumn",
|
|
4029
|
+
table: key,
|
|
4030
|
+
description: `Drop column ${colName} from ${key}`,
|
|
4031
|
+
statements: allowDestructive ? dialect.dropColumnSql(actual, colName) : [],
|
|
4032
|
+
safe: false
|
|
4033
|
+
});
|
|
4034
|
+
const warning = dialect.warnDropColumn?.(actual, colName);
|
|
4035
|
+
if (warning) plan.warnings.push(warning);
|
|
4036
|
+
}
|
|
4037
|
+
}
|
|
4038
|
+
const expectedIndexes = table.indexes ?? [];
|
|
4039
|
+
const actualIndexes = actual.indexes ?? [];
|
|
4040
|
+
const actualIndexMap = new Map(actualIndexes.map((idx) => [idx.name, idx]));
|
|
4041
|
+
for (const idx of expectedIndexes) {
|
|
4042
|
+
const name = idx.name || deriveIndexName(table, idx);
|
|
4043
|
+
if (!actualIndexMap.has(name)) {
|
|
4044
|
+
plan.changes.push({
|
|
4045
|
+
kind: "addIndex",
|
|
4046
|
+
table: key,
|
|
4047
|
+
description: `Create index ${name} on ${key}`,
|
|
4048
|
+
statements: [dialect.renderIndex(table, { ...idx, name })],
|
|
4049
|
+
safe: true
|
|
4050
|
+
});
|
|
4051
|
+
}
|
|
4052
|
+
}
|
|
4053
|
+
for (const idx of actualIndexes) {
|
|
4054
|
+
if (idx.name && !expectedIndexes.find((expected) => (expected.name || deriveIndexName(table, expected)) === idx.name)) {
|
|
4055
|
+
plan.changes.push({
|
|
4056
|
+
kind: "dropIndex",
|
|
4057
|
+
table: key,
|
|
4058
|
+
description: `Drop index ${idx.name} on ${key}`,
|
|
4059
|
+
statements: allowDestructive ? dialect.dropIndexSql(actual, idx.name) : [],
|
|
4060
|
+
safe: false
|
|
4061
|
+
});
|
|
4062
|
+
}
|
|
4063
|
+
}
|
|
4064
|
+
}
|
|
4065
|
+
for (const actual of actualSchema.tables) {
|
|
4066
|
+
const key = tableKey(actual.name, actual.schema);
|
|
4067
|
+
if (!expectedTables.find((t) => tableKey(t.name, t.schema) === key)) {
|
|
4068
|
+
plan.changes.push({
|
|
4069
|
+
kind: "dropTable",
|
|
4070
|
+
table: key,
|
|
4071
|
+
description: `Drop table ${key}`,
|
|
4072
|
+
statements: allowDestructive ? dialect.dropTableSql(actual) : [],
|
|
4073
|
+
safe: false
|
|
4074
|
+
});
|
|
4075
|
+
}
|
|
4076
|
+
}
|
|
4077
|
+
return plan;
|
|
4078
|
+
};
|
|
4079
|
+
var synchronizeSchema = async (expectedTables, actualSchema, dialect, executor, options = {}) => {
|
|
4080
|
+
const plan = diffSchema(expectedTables, actualSchema, dialect, options);
|
|
4081
|
+
if (options.dryRun) return plan;
|
|
4082
|
+
for (const change of plan.changes) {
|
|
4083
|
+
if (!change.statements.length) continue;
|
|
4084
|
+
if (!change.safe && !options.allowDestructive) continue;
|
|
4085
|
+
for (const stmt of change.statements) {
|
|
4086
|
+
if (!stmt.trim()) continue;
|
|
4087
|
+
await executor.executeSql(stmt);
|
|
4088
|
+
}
|
|
4089
|
+
}
|
|
4090
|
+
return plan;
|
|
4091
|
+
};
|
|
4092
|
+
|
|
4093
|
+
// src/core/ddl/introspect/utils.ts
|
|
4094
|
+
var toRows = (result) => {
|
|
4095
|
+
if (!result) return [];
|
|
4096
|
+
return result.values.map(
|
|
4097
|
+
(row) => result.columns.reduce((acc, col2, idx) => {
|
|
4098
|
+
acc[col2] = row[idx];
|
|
4099
|
+
return acc;
|
|
4100
|
+
}, {})
|
|
4101
|
+
);
|
|
4102
|
+
};
|
|
4103
|
+
var queryRows = async (executor, sql, params = []) => {
|
|
4104
|
+
const [first] = await executor.executeSql(sql, params);
|
|
4105
|
+
return toRows(first);
|
|
4106
|
+
};
|
|
4107
|
+
var shouldIncludeTable = (name, options) => {
|
|
4108
|
+
if (options.includeTables && !options.includeTables.includes(name)) return false;
|
|
4109
|
+
if (options.excludeTables && options.excludeTables.includes(name)) return false;
|
|
4110
|
+
return true;
|
|
4111
|
+
};
|
|
4112
|
+
|
|
4113
|
+
// src/core/ddl/introspect/postgres.ts
|
|
4114
|
+
var postgresIntrospector = {
|
|
4115
|
+
async introspect(executor, options) {
|
|
4116
|
+
const schema = options.schema || "public";
|
|
4117
|
+
const tables = [];
|
|
4118
|
+
const columnRows = await queryRows(
|
|
4119
|
+
executor,
|
|
4120
|
+
`
|
|
4121
|
+
SELECT table_schema, table_name, column_name, data_type, is_nullable, column_default
|
|
4122
|
+
FROM information_schema.columns
|
|
4123
|
+
WHERE table_schema = $1
|
|
4124
|
+
ORDER BY table_name, ordinal_position
|
|
4125
|
+
`,
|
|
4126
|
+
[schema]
|
|
4127
|
+
);
|
|
4128
|
+
const pkRows = await queryRows(
|
|
4129
|
+
executor,
|
|
4130
|
+
`
|
|
4131
|
+
SELECT
|
|
4132
|
+
ns.nspname AS table_schema,
|
|
4133
|
+
tbl.relname AS table_name,
|
|
4134
|
+
array_agg(att.attname ORDER BY arr.idx) AS pk_columns
|
|
4135
|
+
FROM pg_index i
|
|
4136
|
+
JOIN pg_class tbl ON tbl.oid = i.indrelid
|
|
4137
|
+
JOIN pg_namespace ns ON ns.oid = tbl.relnamespace
|
|
4138
|
+
JOIN LATERAL unnest(i.indkey) WITH ORDINALITY AS arr(attnum, idx) ON TRUE
|
|
4139
|
+
LEFT JOIN pg_attribute att ON att.attrelid = tbl.oid AND att.attnum = arr.attnum
|
|
4140
|
+
WHERE i.indisprimary AND ns.nspname = $1
|
|
4141
|
+
GROUP BY ns.nspname, tbl.relname
|
|
4142
|
+
`,
|
|
4143
|
+
[schema]
|
|
4144
|
+
);
|
|
4145
|
+
const pkMap = /* @__PURE__ */ new Map();
|
|
4146
|
+
pkRows.forEach((r) => {
|
|
4147
|
+
pkMap.set(`${r.table_schema}.${r.table_name}`, r.pk_columns || []);
|
|
4148
|
+
});
|
|
4149
|
+
const fkRows = await queryRows(
|
|
4150
|
+
executor,
|
|
4151
|
+
`
|
|
4152
|
+
SELECT
|
|
4153
|
+
tc.table_schema,
|
|
4154
|
+
tc.table_name,
|
|
4155
|
+
kcu.column_name,
|
|
4156
|
+
ccu.table_schema AS foreign_table_schema,
|
|
4157
|
+
ccu.table_name AS foreign_table_name,
|
|
4158
|
+
ccu.column_name AS foreign_column_name,
|
|
4159
|
+
rc.update_rule AS on_update,
|
|
4160
|
+
rc.delete_rule AS on_delete
|
|
4161
|
+
FROM information_schema.table_constraints AS tc
|
|
4162
|
+
JOIN information_schema.key_column_usage AS kcu
|
|
4163
|
+
ON tc.constraint_name = kcu.constraint_name AND tc.table_schema = kcu.table_schema
|
|
4164
|
+
JOIN information_schema.constraint_column_usage AS ccu
|
|
4165
|
+
ON ccu.constraint_name = tc.constraint_name AND ccu.table_schema = tc.table_schema
|
|
4166
|
+
JOIN information_schema.referential_constraints rc
|
|
4167
|
+
ON rc.constraint_name = tc.constraint_name AND rc.constraint_schema = tc.table_schema
|
|
4168
|
+
WHERE tc.constraint_type = 'FOREIGN KEY' AND tc.table_schema = $1
|
|
4169
|
+
`,
|
|
4170
|
+
[schema]
|
|
4171
|
+
);
|
|
4172
|
+
const fkMap = /* @__PURE__ */ new Map();
|
|
4173
|
+
fkRows.forEach((r) => {
|
|
4174
|
+
const key = `${r.table_schema}.${r.table_name}.${r.column_name}`;
|
|
4175
|
+
fkMap.set(key, [{
|
|
4176
|
+
table: `${r.foreign_table_schema}.${r.foreign_table_name}`,
|
|
4177
|
+
column: r.foreign_column_name,
|
|
4178
|
+
onDelete: r.on_delete?.toUpperCase(),
|
|
4179
|
+
onUpdate: r.on_update?.toUpperCase()
|
|
4180
|
+
}]);
|
|
4181
|
+
});
|
|
4182
|
+
const indexRows = await queryRows(
|
|
4183
|
+
executor,
|
|
4184
|
+
`
|
|
4185
|
+
SELECT
|
|
4186
|
+
ns.nspname AS table_schema,
|
|
4187
|
+
tbl.relname AS table_name,
|
|
4188
|
+
idx.relname AS index_name,
|
|
4189
|
+
i.indisunique AS is_unique,
|
|
4190
|
+
pg_get_expr(i.indpred, i.indrelid) AS predicate,
|
|
4191
|
+
array_agg(att.attname ORDER BY arr.idx) AS column_names
|
|
4192
|
+
FROM pg_index i
|
|
4193
|
+
JOIN pg_class tbl ON tbl.oid = i.indrelid
|
|
4194
|
+
JOIN pg_namespace ns ON ns.oid = tbl.relnamespace
|
|
4195
|
+
JOIN pg_class idx ON idx.oid = i.indexrelid
|
|
4196
|
+
JOIN LATERAL unnest(i.indkey) WITH ORDINALITY AS arr(attnum, idx) ON TRUE
|
|
4197
|
+
LEFT JOIN pg_attribute att ON att.attrelid = tbl.oid AND att.attnum = arr.attnum
|
|
4198
|
+
WHERE ns.nspname = $1 AND NOT i.indisprimary
|
|
4199
|
+
GROUP BY ns.nspname, tbl.relname, idx.relname, i.indisunique, i.indpred
|
|
4200
|
+
`,
|
|
4201
|
+
[schema]
|
|
4202
|
+
);
|
|
4203
|
+
const tablesByKey = /* @__PURE__ */ new Map();
|
|
4204
|
+
columnRows.forEach((r) => {
|
|
4205
|
+
const key = `${r.table_schema}.${r.table_name}`;
|
|
4206
|
+
if (!shouldIncludeTable(r.table_name, options)) {
|
|
4207
|
+
return;
|
|
4208
|
+
}
|
|
4209
|
+
if (!tablesByKey.has(key)) {
|
|
4210
|
+
tablesByKey.set(key, {
|
|
4211
|
+
name: r.table_name,
|
|
4212
|
+
schema: r.table_schema,
|
|
4213
|
+
columns: [],
|
|
4214
|
+
primaryKey: pkMap.get(key) || [],
|
|
4215
|
+
indexes: []
|
|
4216
|
+
});
|
|
4217
|
+
}
|
|
4218
|
+
const cols = tablesByKey.get(key);
|
|
4219
|
+
const fk = fkMap.get(`${r.table_schema}.${r.table_name}.${r.column_name}`)?.[0];
|
|
4220
|
+
const column = {
|
|
4221
|
+
name: r.column_name,
|
|
4222
|
+
type: r.data_type,
|
|
4223
|
+
notNull: r.is_nullable === "NO",
|
|
4224
|
+
default: r.column_default ?? void 0,
|
|
4225
|
+
references: fk ? {
|
|
4226
|
+
table: fk.table,
|
|
4227
|
+
column: fk.column,
|
|
4228
|
+
onDelete: fk.onDelete,
|
|
4229
|
+
onUpdate: fk.onUpdate
|
|
4230
|
+
} : void 0
|
|
4231
|
+
};
|
|
4232
|
+
cols.columns.push(column);
|
|
4233
|
+
});
|
|
4234
|
+
indexRows.forEach((r) => {
|
|
4235
|
+
const key = `${r.table_schema}.${r.table_name}`;
|
|
4236
|
+
const table = tablesByKey.get(key);
|
|
4237
|
+
if (!table) return;
|
|
4238
|
+
const idx = {
|
|
4239
|
+
name: r.index_name,
|
|
4240
|
+
columns: (r.column_names || []).map((c) => ({ column: c })),
|
|
4241
|
+
unique: !!r.is_unique,
|
|
4242
|
+
where: r.predicate || void 0
|
|
4243
|
+
};
|
|
4244
|
+
table.indexes = table.indexes || [];
|
|
4245
|
+
table.indexes.push(idx);
|
|
4246
|
+
});
|
|
4247
|
+
tables.push(...tablesByKey.values());
|
|
4248
|
+
return { tables };
|
|
4249
|
+
}
|
|
4250
|
+
};
|
|
4251
|
+
|
|
4252
|
+
// src/core/ddl/introspect/mysql.ts
|
|
4253
|
+
var mysqlIntrospector = {
|
|
4254
|
+
async introspect(executor, options) {
|
|
4255
|
+
const schema = options.schema;
|
|
4256
|
+
const filterClause = schema ? "table_schema = ?" : "table_schema = database()";
|
|
4257
|
+
const params = schema ? [schema] : [];
|
|
4258
|
+
const columnRows = await queryRows(
|
|
4259
|
+
executor,
|
|
4260
|
+
`
|
|
4261
|
+
SELECT table_schema, table_name, column_name, data_type, is_nullable, column_default, extra
|
|
4262
|
+
FROM information_schema.columns
|
|
4263
|
+
WHERE ${filterClause}
|
|
4264
|
+
ORDER BY table_name, ordinal_position
|
|
4265
|
+
`,
|
|
4266
|
+
params
|
|
4267
|
+
);
|
|
4268
|
+
const pkRows = await queryRows(
|
|
4269
|
+
executor,
|
|
4270
|
+
`
|
|
4271
|
+
SELECT table_schema, table_name, column_name
|
|
4272
|
+
FROM information_schema.key_column_usage
|
|
4273
|
+
WHERE constraint_name = 'PRIMARY' AND ${filterClause}
|
|
4274
|
+
ORDER BY ordinal_position
|
|
4275
|
+
`,
|
|
4276
|
+
params
|
|
4277
|
+
);
|
|
4278
|
+
const pkMap = /* @__PURE__ */ new Map();
|
|
4279
|
+
pkRows.forEach((r) => {
|
|
4280
|
+
const key = `${r.table_schema}.${r.table_name}`;
|
|
4281
|
+
const list = pkMap.get(key) || [];
|
|
4282
|
+
list.push(r.column_name);
|
|
4283
|
+
pkMap.set(key, list);
|
|
4284
|
+
});
|
|
4285
|
+
const indexRows = await queryRows(
|
|
4286
|
+
executor,
|
|
4287
|
+
`
|
|
4288
|
+
SELECT
|
|
4289
|
+
table_schema,
|
|
4290
|
+
table_name,
|
|
4291
|
+
index_name,
|
|
4292
|
+
non_unique,
|
|
4293
|
+
GROUP_CONCAT(column_name ORDER BY seq_in_index) AS cols
|
|
4294
|
+
FROM information_schema.statistics
|
|
4295
|
+
WHERE ${filterClause} AND index_name <> 'PRIMARY'
|
|
4296
|
+
GROUP BY table_schema, table_name, index_name, non_unique
|
|
4297
|
+
`,
|
|
4298
|
+
params
|
|
4299
|
+
);
|
|
4300
|
+
const tablesByKey = /* @__PURE__ */ new Map();
|
|
4301
|
+
columnRows.forEach((r) => {
|
|
4302
|
+
const key = `${r.table_schema}.${r.table_name}`;
|
|
4303
|
+
if (!shouldIncludeTable(r.table_name, options)) return;
|
|
4304
|
+
if (!tablesByKey.has(key)) {
|
|
4305
|
+
tablesByKey.set(key, {
|
|
4306
|
+
name: r.table_name,
|
|
4307
|
+
schema: r.table_schema,
|
|
4308
|
+
columns: [],
|
|
4309
|
+
primaryKey: pkMap.get(key) || [],
|
|
4310
|
+
indexes: []
|
|
4311
|
+
});
|
|
4312
|
+
}
|
|
4313
|
+
const cols = tablesByKey.get(key);
|
|
4314
|
+
const column = {
|
|
4315
|
+
name: r.column_name,
|
|
4316
|
+
type: r.data_type,
|
|
4317
|
+
notNull: r.is_nullable === "NO",
|
|
4318
|
+
default: r.column_default ?? void 0,
|
|
4319
|
+
autoIncrement: typeof r.extra === "string" && r.extra.includes("auto_increment")
|
|
4320
|
+
};
|
|
4321
|
+
cols.columns.push(column);
|
|
4322
|
+
});
|
|
4323
|
+
indexRows.forEach((r) => {
|
|
4324
|
+
const key = `${r.table_schema}.${r.table_name}`;
|
|
4325
|
+
const table = tablesByKey.get(key);
|
|
4326
|
+
if (!table) return;
|
|
4327
|
+
const cols = (typeof r.cols === "string" ? r.cols.split(",") : []).map((c) => ({ column: c.trim() }));
|
|
4328
|
+
const idx = {
|
|
4329
|
+
name: r.index_name,
|
|
4330
|
+
columns: cols,
|
|
4331
|
+
unique: r.non_unique === 0
|
|
4332
|
+
};
|
|
4333
|
+
table.indexes = table.indexes || [];
|
|
4334
|
+
table.indexes.push(idx);
|
|
4335
|
+
});
|
|
4336
|
+
return { tables: Array.from(tablesByKey.values()) };
|
|
4337
|
+
}
|
|
4338
|
+
};
|
|
4339
|
+
|
|
4340
|
+
// src/core/ddl/introspect/sqlite.ts
|
|
4341
|
+
var escapeSingleQuotes = (name) => name.replace(/'/g, "''");
|
|
4342
|
+
var sqliteIntrospector = {
|
|
4343
|
+
async introspect(executor, options) {
|
|
4344
|
+
const tables = [];
|
|
4345
|
+
const tableRows = await queryRows(
|
|
4346
|
+
executor,
|
|
4347
|
+
`SELECT name FROM sqlite_master WHERE type = 'table' AND name NOT LIKE 'sqlite_%';`
|
|
4348
|
+
);
|
|
4349
|
+
for (const row of tableRows) {
|
|
4350
|
+
const name = row.name;
|
|
4351
|
+
if (!shouldIncludeTable(name, options)) continue;
|
|
4352
|
+
const table = { name, columns: [], primaryKey: [], indexes: [] };
|
|
4353
|
+
const cols = await queryRows(executor, `PRAGMA table_info('${escapeSingleQuotes(name)}');`);
|
|
4354
|
+
cols.forEach((c) => {
|
|
4355
|
+
table.columns.push({
|
|
4356
|
+
name: c.name,
|
|
4357
|
+
type: c.type,
|
|
4358
|
+
notNull: c.notnull === 1,
|
|
4359
|
+
default: c.dflt_value ?? void 0,
|
|
4360
|
+
autoIncrement: false
|
|
4361
|
+
});
|
|
4362
|
+
if (c.pk && c.pk > 0) {
|
|
4363
|
+
table.primaryKey = table.primaryKey || [];
|
|
4364
|
+
table.primaryKey.push(c.name);
|
|
4365
|
+
}
|
|
4366
|
+
});
|
|
4367
|
+
const fkRows = await queryRows(executor, `PRAGMA foreign_key_list('${escapeSingleQuotes(name)}');`);
|
|
4368
|
+
fkRows.forEach((fk) => {
|
|
4369
|
+
const col2 = table.columns.find((c) => c.name === fk.from);
|
|
4370
|
+
if (col2) {
|
|
4371
|
+
col2.references = {
|
|
4372
|
+
table: fk.table,
|
|
4373
|
+
column: fk.to,
|
|
4374
|
+
onDelete: fk.on_delete?.toUpperCase(),
|
|
4375
|
+
onUpdate: fk.on_update?.toUpperCase()
|
|
4376
|
+
};
|
|
4377
|
+
}
|
|
4378
|
+
});
|
|
4379
|
+
const idxList = await queryRows(executor, `PRAGMA index_list('${escapeSingleQuotes(name)}');`);
|
|
4380
|
+
for (const idx of idxList) {
|
|
4381
|
+
const idxName = idx.name;
|
|
4382
|
+
const columnsInfo = await queryRows(executor, `PRAGMA index_info('${escapeSingleQuotes(idxName)}');`);
|
|
4383
|
+
const idxEntry = {
|
|
4384
|
+
name: idxName,
|
|
4385
|
+
columns: columnsInfo.map((ci) => ({ column: ci.name })),
|
|
4386
|
+
unique: idx.unique === 1
|
|
4387
|
+
};
|
|
4388
|
+
table.indexes.push(idxEntry);
|
|
4389
|
+
}
|
|
4390
|
+
tables.push(table);
|
|
4391
|
+
}
|
|
4392
|
+
return { tables };
|
|
4393
|
+
}
|
|
4394
|
+
};
|
|
4395
|
+
|
|
4396
|
+
// src/core/ddl/introspect/mssql.ts
|
|
4397
|
+
var mssqlIntrospector = {
|
|
4398
|
+
async introspect(executor, options) {
|
|
4399
|
+
const schema = options.schema;
|
|
4400
|
+
const filterSchema = schema ? "sch.name = @p1" : "1=1";
|
|
4401
|
+
const params = schema ? [schema] : [];
|
|
4402
|
+
const columnRows = await queryRows(
|
|
4403
|
+
executor,
|
|
4404
|
+
`
|
|
4405
|
+
SELECT
|
|
4406
|
+
sch.name AS table_schema,
|
|
4407
|
+
t.name AS table_name,
|
|
4408
|
+
c.name AS column_name,
|
|
4409
|
+
ty.name AS data_type,
|
|
4410
|
+
c.is_nullable,
|
|
4411
|
+
c.is_identity,
|
|
4412
|
+
object_definition(c.default_object_id) AS column_default
|
|
4413
|
+
FROM sys.columns c
|
|
4414
|
+
JOIN sys.tables t ON t.object_id = c.object_id
|
|
4415
|
+
JOIN sys.schemas sch ON sch.schema_id = t.schema_id
|
|
4416
|
+
JOIN sys.types ty ON ty.user_type_id = c.user_type_id
|
|
4417
|
+
WHERE t.is_ms_shipped = 0 AND ${filterSchema}
|
|
4418
|
+
`,
|
|
4419
|
+
params
|
|
4420
|
+
);
|
|
4421
|
+
const pkRows = await queryRows(
|
|
4422
|
+
executor,
|
|
4423
|
+
`
|
|
4424
|
+
SELECT
|
|
4425
|
+
sch.name AS table_schema,
|
|
4426
|
+
t.name AS table_name,
|
|
4427
|
+
c.name AS column_name,
|
|
4428
|
+
ic.key_ordinal
|
|
4429
|
+
FROM sys.indexes i
|
|
4430
|
+
JOIN sys.index_columns ic ON ic.object_id = i.object_id AND ic.index_id = i.index_id
|
|
4431
|
+
JOIN sys.columns c ON c.object_id = ic.object_id AND c.column_id = ic.column_id
|
|
4432
|
+
JOIN sys.tables t ON t.object_id = i.object_id
|
|
4433
|
+
JOIN sys.schemas sch ON sch.schema_id = t.schema_id
|
|
4434
|
+
WHERE i.is_primary_key = 1 AND ${filterSchema}
|
|
4435
|
+
ORDER BY ic.key_ordinal
|
|
4436
|
+
`,
|
|
4437
|
+
params
|
|
4438
|
+
);
|
|
4439
|
+
const pkMap = /* @__PURE__ */ new Map();
|
|
4440
|
+
pkRows.forEach((r) => {
|
|
4441
|
+
const key = `${r.table_schema}.${r.table_name}`;
|
|
4442
|
+
const list = pkMap.get(key) || [];
|
|
4443
|
+
list.push(r.column_name);
|
|
4444
|
+
pkMap.set(key, list);
|
|
4445
|
+
});
|
|
4446
|
+
const indexRows = await queryRows(
|
|
4447
|
+
executor,
|
|
4448
|
+
`
|
|
4449
|
+
SELECT
|
|
4450
|
+
sch.name AS table_schema,
|
|
4451
|
+
t.name AS table_name,
|
|
4452
|
+
i.name AS index_name,
|
|
4453
|
+
i.is_unique,
|
|
4454
|
+
i.has_filter,
|
|
4455
|
+
i.filter_definition
|
|
4456
|
+
FROM sys.indexes i
|
|
4457
|
+
JOIN sys.tables t ON t.object_id = i.object_id
|
|
4458
|
+
JOIN sys.schemas sch ON sch.schema_id = t.schema_id
|
|
4459
|
+
WHERE i.is_primary_key = 0 AND i.is_hypothetical = 0 AND ${filterSchema}
|
|
4460
|
+
`,
|
|
4461
|
+
params
|
|
4462
|
+
);
|
|
4463
|
+
const indexColsRows = await queryRows(
|
|
4464
|
+
executor,
|
|
4465
|
+
`
|
|
4466
|
+
SELECT
|
|
4467
|
+
sch.name AS table_schema,
|
|
4468
|
+
t.name AS table_name,
|
|
4469
|
+
i.name AS index_name,
|
|
4470
|
+
c.name AS column_name,
|
|
4471
|
+
ic.key_ordinal
|
|
4472
|
+
FROM sys.index_columns ic
|
|
4473
|
+
JOIN sys.indexes i ON i.object_id = ic.object_id AND i.index_id = ic.index_id
|
|
4474
|
+
JOIN sys.columns c ON c.object_id = ic.object_id AND c.column_id = ic.column_id
|
|
4475
|
+
JOIN sys.tables t ON t.object_id = i.object_id
|
|
4476
|
+
JOIN sys.schemas sch ON sch.schema_id = t.schema_id
|
|
4477
|
+
WHERE i.is_primary_key = 0 AND ${filterSchema}
|
|
4478
|
+
ORDER BY ic.key_ordinal
|
|
4479
|
+
`,
|
|
4480
|
+
params
|
|
4481
|
+
);
|
|
4482
|
+
const indexColumnsMap = /* @__PURE__ */ new Map();
|
|
4483
|
+
indexColsRows.forEach((r) => {
|
|
4484
|
+
const key = `${r.table_schema}.${r.table_name}.${r.index_name}`;
|
|
4485
|
+
const list = indexColumnsMap.get(key) || [];
|
|
4486
|
+
list.push({ column: r.column_name, order: r.key_ordinal });
|
|
4487
|
+
indexColumnsMap.set(key, list);
|
|
4488
|
+
});
|
|
4489
|
+
const tablesByKey = /* @__PURE__ */ new Map();
|
|
4490
|
+
columnRows.forEach((r) => {
|
|
4491
|
+
if (!shouldIncludeTable(r.table_name, options)) return;
|
|
4492
|
+
const key = `${r.table_schema}.${r.table_name}`;
|
|
4493
|
+
if (!tablesByKey.has(key)) {
|
|
4494
|
+
tablesByKey.set(key, {
|
|
4495
|
+
name: r.table_name,
|
|
4496
|
+
schema: r.table_schema,
|
|
4497
|
+
columns: [],
|
|
4498
|
+
primaryKey: pkMap.get(key) || [],
|
|
4499
|
+
indexes: []
|
|
4500
|
+
});
|
|
4501
|
+
}
|
|
4502
|
+
const t = tablesByKey.get(key);
|
|
4503
|
+
const column = {
|
|
4504
|
+
name: r.column_name,
|
|
4505
|
+
type: r.data_type,
|
|
4506
|
+
notNull: r.is_nullable === false || r.is_nullable === 0,
|
|
4507
|
+
default: r.column_default ?? void 0,
|
|
4508
|
+
autoIncrement: !!r.is_identity
|
|
4509
|
+
};
|
|
4510
|
+
t.columns.push(column);
|
|
4511
|
+
});
|
|
4512
|
+
indexRows.forEach((r) => {
|
|
4513
|
+
const key = `${r.table_schema}.${r.table_name}`;
|
|
4514
|
+
const table = tablesByKey.get(key);
|
|
4515
|
+
if (!table) return;
|
|
4516
|
+
const cols = (indexColumnsMap.get(`${r.table_schema}.${r.table_name}.${r.index_name}`) || []).sort((a, b) => a.order - b.order).map((c) => ({ column: c.column }));
|
|
4517
|
+
const idx = {
|
|
4518
|
+
name: r.index_name,
|
|
4519
|
+
columns: cols,
|
|
4520
|
+
unique: !!r.is_unique,
|
|
4521
|
+
where: r.has_filter ? r.filter_definition : void 0
|
|
4522
|
+
};
|
|
4523
|
+
table.indexes = table.indexes || [];
|
|
4524
|
+
table.indexes.push(idx);
|
|
4525
|
+
});
|
|
4526
|
+
return { tables: Array.from(tablesByKey.values()) };
|
|
4527
|
+
}
|
|
4528
|
+
};
|
|
4529
|
+
|
|
4530
|
+
// src/core/ddl/schema-introspect.ts
|
|
4531
|
+
var INTROSPECTORS = {
|
|
4532
|
+
postgres: postgresIntrospector,
|
|
4533
|
+
mysql: mysqlIntrospector,
|
|
4534
|
+
sqlite: sqliteIntrospector,
|
|
4535
|
+
mssql: mssqlIntrospector
|
|
4536
|
+
};
|
|
4537
|
+
var introspectSchema = async (executor, dialect, options = {}) => {
|
|
4538
|
+
const handler = INTROSPECTORS[dialect];
|
|
4539
|
+
if (!handler) {
|
|
4540
|
+
throw new Error(`Unsupported dialect for introspection: ${dialect}`);
|
|
4541
|
+
}
|
|
4542
|
+
return handler.introspect(executor, options);
|
|
4543
|
+
};
|
|
4544
|
+
|
|
3318
4545
|
// src/orm/als.ts
|
|
3319
4546
|
var AsyncLocalStorage = class {
|
|
3320
4547
|
/**
|
|
@@ -4153,15 +5380,21 @@ var OrmContext = class {
|
|
|
4153
5380
|
// Annotate the CommonJS export names for ESM import in node:
|
|
4154
5381
|
0 && (module.exports = {
|
|
4155
5382
|
AsyncLocalStorage,
|
|
5383
|
+
BaseSchemaDialect,
|
|
4156
5384
|
DefaultBelongsToReference,
|
|
4157
5385
|
DefaultHasManyCollection,
|
|
4158
5386
|
DefaultManyToManyCollection,
|
|
4159
5387
|
DeleteQueryBuilder,
|
|
4160
5388
|
EntityStatus,
|
|
4161
5389
|
InsertQueryBuilder,
|
|
5390
|
+
MSSqlSchemaDialect,
|
|
4162
5391
|
MySqlDialect,
|
|
5392
|
+
MySqlSchemaDialect,
|
|
4163
5393
|
OrmContext,
|
|
5394
|
+
PostgresDialect,
|
|
5395
|
+
PostgresSchemaDialect,
|
|
4164
5396
|
RelationKinds,
|
|
5397
|
+
SQLiteSchemaDialect,
|
|
4165
5398
|
SelectQueryBuilder,
|
|
4166
5399
|
SqlServerDialect,
|
|
4167
5400
|
SqliteDialect,
|
|
@@ -4183,15 +5416,22 @@ var OrmContext = class {
|
|
|
4183
5416
|
createLiteral,
|
|
4184
5417
|
defineTable,
|
|
4185
5418
|
denseRank,
|
|
5419
|
+
deriveIndexName,
|
|
5420
|
+
diffSchema,
|
|
4186
5421
|
eq,
|
|
5422
|
+
escapeLiteral,
|
|
4187
5423
|
executeHydrated,
|
|
4188
5424
|
exists,
|
|
4189
5425
|
firstValue,
|
|
5426
|
+
formatLiteral,
|
|
5427
|
+
generateCreateTableSql,
|
|
5428
|
+
generateSchemaSql,
|
|
4190
5429
|
gt,
|
|
4191
5430
|
gte,
|
|
4192
5431
|
hasMany,
|
|
4193
5432
|
hydrateRows,
|
|
4194
5433
|
inList,
|
|
5434
|
+
introspectSchema,
|
|
4195
5435
|
isCaseExpressionNode,
|
|
4196
5436
|
isExpressionSelectionNode,
|
|
4197
5437
|
isFunctionNode,
|
|
@@ -4216,9 +5456,14 @@ var OrmContext = class {
|
|
|
4216
5456
|
notLike,
|
|
4217
5457
|
ntile,
|
|
4218
5458
|
or,
|
|
5459
|
+
quoteQualified,
|
|
4219
5460
|
rank,
|
|
5461
|
+
renderColumnDefinition,
|
|
5462
|
+
renderIndexColumns,
|
|
5463
|
+
resolvePrimaryKey,
|
|
4220
5464
|
rowNumber,
|
|
4221
5465
|
sum,
|
|
5466
|
+
synchronizeSchema,
|
|
4222
5467
|
valueToOperand,
|
|
4223
5468
|
visitExpression,
|
|
4224
5469
|
visitOperand,
|