forge-sql-orm-cli 2.1.16 → 2.1.18
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/dist-cli/actions/migrations-create.d.ts +5 -6
- package/dist-cli/cli.js +59 -32
- package/dist-cli/cli.js.map +1 -1
- package/dist-cli/cli.mjs +59 -32
- package/dist-cli/cli.mjs.map +1 -1
- package/package.json +11 -11
- package/src/actions/migrations-create.ts +120 -62
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import "reflect-metadata";
|
|
2
2
|
import fs from "fs";
|
|
3
3
|
import path from "path";
|
|
4
|
-
|
|
5
|
-
import {
|
|
4
|
+
import mysql from "mysql2/promise";
|
|
5
|
+
import { RowDataPacket } from "mysql2";
|
|
6
6
|
|
|
7
7
|
/**
|
|
8
8
|
* Options for migration creation
|
|
@@ -11,6 +11,16 @@ export interface CreateMigrationOptions {
|
|
|
11
11
|
output: string;
|
|
12
12
|
entitiesPath: string;
|
|
13
13
|
force?: boolean;
|
|
14
|
+
host?: string;
|
|
15
|
+
port?: number;
|
|
16
|
+
user?: string;
|
|
17
|
+
password?: string;
|
|
18
|
+
dbName?: string;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
interface CreateTableRow extends RowDataPacket {
|
|
22
|
+
Table: string;
|
|
23
|
+
"Create Table": string;
|
|
14
24
|
}
|
|
15
25
|
|
|
16
26
|
/**
|
|
@@ -35,29 +45,37 @@ export const loadMigrationVersion = async (migrationPath: string): Promise<numbe
|
|
|
35
45
|
}
|
|
36
46
|
};
|
|
37
47
|
|
|
48
|
+
/**
|
|
49
|
+
* Regular expressions for adding IF NOT EXISTS to SQL statements
|
|
50
|
+
* Note: MySQL/TiDB does not support IF NOT EXISTS for ALTER TABLE ADD CONSTRAINT
|
|
51
|
+
*/
|
|
52
|
+
const SQL_KIND_REGEX = /CREATE (?!.*IF NOT EXISTS)(UNIQUE INDEX|INDEX|TABLE) /gim;
|
|
53
|
+
|
|
54
|
+
/**
|
|
55
|
+
* Inserts IF NOT EXISTS into CREATE statements.
|
|
56
|
+
* Only adds IF NOT EXISTS to CREATE TABLE, CREATE INDEX, and CREATE UNIQUE INDEX.
|
|
57
|
+
* Does not add IF NOT EXISTS to ALTER TABLE statements as MySQL/TiDB doesn't support it.
|
|
58
|
+
* @param content - The SQL content.
|
|
59
|
+
* @returns The SQL content with IF NOT EXISTS added.
|
|
60
|
+
*/
|
|
61
|
+
function insertNotExists(content: string): string {
|
|
62
|
+
SQL_KIND_REGEX.lastIndex = 0;
|
|
63
|
+
|
|
64
|
+
// Add IF NOT EXISTS to CREATE TABLE, CREATE INDEX, CREATE UNIQUE INDEX
|
|
65
|
+
// Note: ALTER TABLE ADD CONSTRAINT and ALTER TABLE ADD INDEX don't support IF NOT EXISTS in MySQL/TiDB
|
|
66
|
+
content = content.replace(SQL_KIND_REGEX, "CREATE $1 IF NOT EXISTS ");
|
|
67
|
+
|
|
68
|
+
return content;
|
|
69
|
+
}
|
|
70
|
+
|
|
38
71
|
/**
|
|
39
72
|
* Cleans SQL statements by removing unnecessary database options.
|
|
40
73
|
* @param sql - The raw SQL statement.
|
|
41
74
|
* @returns The cleaned SQL statement.
|
|
42
75
|
*/
|
|
43
76
|
export function cleanSQLStatement(sql: string): string {
|
|
44
|
-
// Add IF NOT EXISTS to
|
|
45
|
-
sql = sql
|
|
46
|
-
|
|
47
|
-
// Add IF NOT EXISTS to CREATE INDEX statements
|
|
48
|
-
sql = sql.replace(/create\s+index\s+(\w+)/gi, "create index if not exists $1");
|
|
49
|
-
|
|
50
|
-
// Add IF NOT EXISTS to ADD INDEX statements
|
|
51
|
-
sql = sql.replace(
|
|
52
|
-
/alter\s+table\s+(\w+)\s+add\s+index\s+(\w+)/gi,
|
|
53
|
-
"alter table $1 add index if not exists $2",
|
|
54
|
-
);
|
|
55
|
-
|
|
56
|
-
// Add IF NOT EXISTS to ADD CONSTRAINT statements
|
|
57
|
-
sql = sql.replace(
|
|
58
|
-
/alter\s+table\s+(\w+)\s+add\s+constraint\s+(\w+)/gi,
|
|
59
|
-
"alter table $1 add constraint if not exists $2",
|
|
60
|
-
);
|
|
77
|
+
// Add IF NOT EXISTS to relevant statements
|
|
78
|
+
sql = insertNotExists(sql);
|
|
61
79
|
|
|
62
80
|
// Remove unnecessary database options
|
|
63
81
|
return sql.replace(/\s+default\s+character\s+set\s+utf8mb4\s+engine\s*=\s*InnoDB;?/gi, "").trim();
|
|
@@ -143,27 +161,51 @@ ${callLines.join("\n")}
|
|
|
143
161
|
}
|
|
144
162
|
|
|
145
163
|
/**
|
|
146
|
-
*
|
|
147
|
-
* @param
|
|
148
|
-
* @returns
|
|
164
|
+
* Gets list of tables from the database
|
|
165
|
+
* @param connection - MySQL connection
|
|
166
|
+
* @returns Array of table names
|
|
149
167
|
*/
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
);
|
|
166
|
-
|
|
168
|
+
async function getTables(connection: mysql.Connection): Promise<string[]> {
|
|
169
|
+
const [rows] = await connection.execute<any[]>("SHOW TABLES");
|
|
170
|
+
return rows.map((row) => Object.values(row)[0] as string);
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
/**
|
|
174
|
+
* Gets CREATE TABLE statement for a specific table
|
|
175
|
+
* @param connection - MySQL connection
|
|
176
|
+
* @param tableName - Name of the table
|
|
177
|
+
* @returns CREATE TABLE statement
|
|
178
|
+
*/
|
|
179
|
+
async function getCreateTableStatement(
|
|
180
|
+
connection: mysql.Connection,
|
|
181
|
+
tableName: string,
|
|
182
|
+
): Promise<string | null> {
|
|
183
|
+
const [rows] = await connection.execute<CreateTableRow[]>(`SHOW CREATE TABLE \`${tableName}\``);
|
|
184
|
+
const result = rows as CreateTableRow[];
|
|
185
|
+
if (result.length > 0 && result[0]["Create Table"]) {
|
|
186
|
+
return result[0]["Create Table"];
|
|
187
|
+
}
|
|
188
|
+
return null;
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
/**
|
|
192
|
+
* Gets all CREATE TABLE statements from the database
|
|
193
|
+
* @param connection - MySQL connection
|
|
194
|
+
* @returns Array of CREATE TABLE statements
|
|
195
|
+
*/
|
|
196
|
+
async function getAllCreateTableStatements(connection: mysql.Connection): Promise<string[]> {
|
|
197
|
+
const tables = await getTables(connection);
|
|
198
|
+
const statements: string[] = [];
|
|
199
|
+
|
|
200
|
+
for (const table of tables) {
|
|
201
|
+
const createTable = await getCreateTableStatement(connection, table);
|
|
202
|
+
if (createTable) {
|
|
203
|
+
statements.push(createTable);
|
|
204
|
+
}
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
return statements;
|
|
208
|
+
}
|
|
167
209
|
|
|
168
210
|
/**
|
|
169
211
|
* Creates a full database migration.
|
|
@@ -186,29 +228,45 @@ export const createMigration = async (options: CreateMigrationOptions) => {
|
|
|
186
228
|
}
|
|
187
229
|
}
|
|
188
230
|
|
|
189
|
-
//
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
//
|
|
198
|
-
const
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
231
|
+
// Validate database connection parameters
|
|
232
|
+
if (!options.host || !options.port || !options.user || !options.password || !options.dbName) {
|
|
233
|
+
console.error(
|
|
234
|
+
`❌ Error: Database connection parameters are required (host, port, user, password, dbName)`,
|
|
235
|
+
);
|
|
236
|
+
process.exit(1);
|
|
237
|
+
}
|
|
238
|
+
|
|
239
|
+
// Create database connection
|
|
240
|
+
const connection = await mysql.createConnection({
|
|
241
|
+
host: options.host,
|
|
242
|
+
port: options.port,
|
|
243
|
+
user: options.user,
|
|
244
|
+
password: options.password,
|
|
245
|
+
database: options.dbName,
|
|
246
|
+
});
|
|
247
|
+
|
|
248
|
+
try {
|
|
249
|
+
console.log(`✅ Connected to database: ${options.dbName}`);
|
|
250
|
+
|
|
251
|
+
// Get all CREATE TABLE statements from the database
|
|
252
|
+
console.log(`📋 Fetching CREATE TABLE statements from database...`);
|
|
253
|
+
const createStatements = await getAllCreateTableStatements(connection);
|
|
254
|
+
|
|
255
|
+
if (createStatements.length === 0) {
|
|
256
|
+
console.warn(`⚠️ Warning: No tables found in the database.`);
|
|
257
|
+
} else {
|
|
258
|
+
console.log(`✅ Found ${createStatements.length} table(s)`);
|
|
259
|
+
}
|
|
260
|
+
|
|
261
|
+
// Generate and save migration files
|
|
262
|
+
const migrationFile = generateMigrationFile(createStatements, 1);
|
|
263
|
+
saveMigrationFiles(migrationFile, 1, options.output);
|
|
264
|
+
|
|
265
|
+
console.log(`✅ Migration successfully created!`);
|
|
266
|
+
process.exit(0);
|
|
267
|
+
} finally {
|
|
268
|
+
await connection.end();
|
|
269
|
+
}
|
|
212
270
|
} catch (error) {
|
|
213
271
|
console.error(`❌ Error during migration creation:`, error);
|
|
214
272
|
process.exit(1);
|