@javalabs/prisma-client 1.0.4 → 1.0.6
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/scripts/data-migration/batch-migrator.d.ts +14 -19
- package/dist/scripts/data-migration/batch-migrator.js +98 -297
- package/dist/scripts/data-migration/batch-migrator.js.map +1 -1
- package/dist/scripts/data-migration/data-transformer.d.ts +16 -7
- package/dist/scripts/data-migration/data-transformer.js +169 -133
- package/dist/scripts/data-migration/data-transformer.js.map +1 -1
- package/dist/scripts/data-migration/db-connector.d.ts +6 -1
- package/dist/scripts/data-migration/db-connector.js +44 -8
- package/dist/scripts/data-migration/db-connector.js.map +1 -1
- package/dist/scripts/data-migration/dependency-resolver.d.ts +10 -10
- package/dist/scripts/data-migration/dependency-resolver.js +92 -211
- package/dist/scripts/data-migration/dependency-resolver.js.map +1 -1
- package/dist/scripts/data-migration/foreign-key-manager.d.ts +6 -5
- package/dist/scripts/data-migration/foreign-key-manager.js +108 -18
- package/dist/scripts/data-migration/foreign-key-manager.js.map +1 -1
- package/dist/scripts/data-migration/migration-config.json +63 -0
- package/dist/scripts/data-migration/migration-tool.d.ts +25 -6
- package/dist/scripts/data-migration/migration-tool.js +78 -38
- package/dist/scripts/data-migration/migration-tool.js.map +1 -1
- package/dist/scripts/data-migration/multi-source-migrator.d.ts +17 -0
- package/dist/scripts/data-migration/multi-source-migrator.js +130 -0
- package/dist/scripts/data-migration/multi-source-migrator.js.map +1 -0
- package/dist/scripts/data-migration/schema-utils.d.ts +3 -3
- package/dist/scripts/data-migration/schema-utils.js +62 -19
- package/dist/scripts/data-migration/schema-utils.js.map +1 -1
- package/dist/scripts/data-migration/tenant-migrator.js +9 -2
- package/dist/scripts/data-migration/tenant-migrator.js.map +1 -1
- package/dist/scripts/data-migration/typecast-manager.d.ts +7 -3
- package/dist/scripts/data-migration/typecast-manager.js +169 -25
- package/dist/scripts/data-migration/typecast-manager.js.map +1 -1
- package/dist/scripts/data-migration/types.d.ts +68 -2
- package/dist/scripts/fix-table-indexes.d.ts +26 -0
- package/dist/scripts/fix-table-indexes.js +460 -0
- package/dist/scripts/fix-table-indexes.js.map +1 -0
- package/dist/scripts/multi-db-migration.d.ts +1 -0
- package/dist/scripts/multi-db-migration.js +55 -0
- package/dist/scripts/multi-db-migration.js.map +1 -0
- package/dist/scripts/run-migration.js +41 -75
- package/dist/scripts/run-migration.js.map +1 -1
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/migration-config.json +40 -72
- package/{migration-config-public.json → migration-config.json.bk} +14 -14
- package/package.json +6 -3
- package/src/scripts/data-migration/batch-migrator.ts +192 -513
- package/src/scripts/data-migration/data-transformer.ts +252 -203
- package/src/scripts/data-migration/db-connector.ts +66 -13
- package/src/scripts/data-migration/dependency-resolver.ts +121 -266
- package/src/scripts/data-migration/foreign-key-manager.ts +214 -32
- package/src/scripts/data-migration/migration-config.json +63 -0
- package/src/scripts/data-migration/migration-tool.ts +377 -225
- package/src/scripts/data-migration/schema-utils.ts +94 -32
- package/src/scripts/data-migration/tenant-migrator.ts +12 -5
- package/src/scripts/data-migration/typecast-manager.ts +186 -31
- package/src/scripts/data-migration/types.ts +78 -5
- package/src/scripts/dumps/source_dump_20250428_145606.sql +323 -0
- package/src/scripts/fix-table-indexes.ts +602 -0
- package/src/scripts/post-migration-validator.ts +206 -107
- package/src/scripts/run-migration.ts +87 -101
|
@@ -0,0 +1,460 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.TableIndexFixer = void 0;
|
|
4
|
+
const fs = require("fs");
|
|
5
|
+
const path = require("path");
|
|
6
|
+
const pg = require("pg");
|
|
7
|
+
const common_1 = require("@nestjs/common");
|
|
8
|
+
const dotenv = require("dotenv");
|
|
9
|
+
dotenv.config();
|
|
10
|
+
class TableIndexFixer {
|
|
11
|
+
constructor(targetUrl = process.env.DATABASE_URL) {
|
|
12
|
+
this.targetUrl = targetUrl;
|
|
13
|
+
this.logger = new common_1.Logger('TableIndexFixer');
|
|
14
|
+
this.fixedIndexes = [];
|
|
15
|
+
if (!this.targetUrl) {
|
|
16
|
+
throw new Error('DATABASE_URL environment variable is required');
|
|
17
|
+
}
|
|
18
|
+
this.targetPool = new pg.Pool({
|
|
19
|
+
connectionString: this.targetUrl,
|
|
20
|
+
});
|
|
21
|
+
this.logDir = path.join(process.cwd(), 'migration-logs');
|
|
22
|
+
if (!fs.existsSync(this.logDir)) {
|
|
23
|
+
fs.mkdirSync(this.logDir, { recursive: true });
|
|
24
|
+
}
|
|
25
|
+
const timestamp = new Date().toISOString().replace(/:/g, '-').replace(/\..+/, '');
|
|
26
|
+
this.logPath = path.join(this.logDir, `index-fixes-${timestamp}.json`);
|
|
27
|
+
}
|
|
28
|
+
async fixIndexes() {
|
|
29
|
+
try {
|
|
30
|
+
this.logger.log('Iniciando proceso de corrección de índices');
|
|
31
|
+
const schemas = await this.getSchemas();
|
|
32
|
+
this.logger.log(`Encontrados ${schemas.length} esquemas para procesar`);
|
|
33
|
+
for (const schema of schemas) {
|
|
34
|
+
await this.fixIndexesForSchema(schema);
|
|
35
|
+
}
|
|
36
|
+
this.saveFixLog();
|
|
37
|
+
this.logger.log(`Proceso de corrección de índices completado. Log guardado en: ${this.logPath}`);
|
|
38
|
+
}
|
|
39
|
+
catch (error) {
|
|
40
|
+
this.logger.error(`Error durante la corrección de índices: ${error.message}`, error.stack);
|
|
41
|
+
}
|
|
42
|
+
finally {
|
|
43
|
+
await this.cleanup();
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
async getSchemas() {
|
|
47
|
+
const result = await this.targetPool.query(`
|
|
48
|
+
SELECT schema_name
|
|
49
|
+
FROM information_schema.schemata
|
|
50
|
+
WHERE schema_name NOT IN ('information_schema', 'pg_catalog', 'pg_toast')
|
|
51
|
+
AND schema_name NOT LIKE 'pg_%'
|
|
52
|
+
`);
|
|
53
|
+
return result.rows.map(row => row.schema_name);
|
|
54
|
+
}
|
|
55
|
+
async fixIndexesForSchema(schema) {
|
|
56
|
+
this.logger.log(`Procesando índices para el esquema: ${schema}`);
|
|
57
|
+
try {
|
|
58
|
+
const tables = await this.getTablesForSchema(schema);
|
|
59
|
+
this.logger.log(`Encontradas ${tables.length} tablas en el esquema ${schema}`);
|
|
60
|
+
for (const table of tables) {
|
|
61
|
+
await this.fixIndexesForTable(schema, table);
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
catch (error) {
|
|
65
|
+
this.logger.error(`Error procesando índices para el esquema ${schema}: ${error.message}`);
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
async getTablesForSchema(schema) {
|
|
69
|
+
const result = await this.targetPool.query(`
|
|
70
|
+
SELECT table_name
|
|
71
|
+
FROM information_schema.tables
|
|
72
|
+
WHERE table_schema = $1
|
|
73
|
+
AND table_type = 'BASE TABLE'
|
|
74
|
+
`, [schema]);
|
|
75
|
+
return result.rows.map(row => row.table_name);
|
|
76
|
+
}
|
|
77
|
+
async fixIndexesForTable(schema, table) {
|
|
78
|
+
this.logger.log(`Procesando índices para la tabla ${schema}.${table}`);
|
|
79
|
+
try {
|
|
80
|
+
const tableInfo = await this.getTableInfo(schema, table);
|
|
81
|
+
const existingIndexes = await this.getTableIndexes(this.targetPool, schema, table);
|
|
82
|
+
this.logger.log(`Encontrados ${existingIndexes.length} índices en la tabla ${schema}.${table}`);
|
|
83
|
+
if (tableInfo.has_identity_column) {
|
|
84
|
+
await this.fixSequences(schema, table);
|
|
85
|
+
}
|
|
86
|
+
await this.fixCommonIndexIssues(schema, table);
|
|
87
|
+
await this.fixForeignKeyIndexes(schema, table);
|
|
88
|
+
await this.removeRedundantIndexes(schema, table, await this.getTableIndexes(this.targetPool, schema, table));
|
|
89
|
+
if (table === 'users' || table === 'user' || table.includes('user')) {
|
|
90
|
+
await this.ensureCriticalUserTableIndexes(schema, table);
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
catch (error) {
|
|
94
|
+
this.logger.error(`Error procesando índices para la tabla ${schema}.${table}: ${error.message}`);
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
async ensureCriticalUserTableIndexes(schema, table) {
|
|
98
|
+
try {
|
|
99
|
+
const columns = await this.getTableColumns(schema, table);
|
|
100
|
+
const existingIndexes = await this.getTableIndexes(this.targetPool, schema, table);
|
|
101
|
+
const indexedColumns = new Set(existingIndexes.flatMap(idx => idx.column_names));
|
|
102
|
+
const criticalColumns = ['email', 'username', 'phone', 'id', 'uuid'];
|
|
103
|
+
for (const criticalCol of criticalColumns) {
|
|
104
|
+
const column = columns.find(col => col.column_name === criticalCol);
|
|
105
|
+
if (column && !indexedColumns.has(column.column_name)) {
|
|
106
|
+
const shouldBeUnique = ['email', 'username', 'phone', 'uuid'].includes(column.column_name);
|
|
107
|
+
const indexInfo = {
|
|
108
|
+
schema,
|
|
109
|
+
table,
|
|
110
|
+
index_name: `idx_${table}_${column.column_name}`,
|
|
111
|
+
column_names: [column.column_name],
|
|
112
|
+
is_unique: shouldBeUnique,
|
|
113
|
+
is_primary: false,
|
|
114
|
+
definition: ''
|
|
115
|
+
};
|
|
116
|
+
this.logger.log(`Creando índice crítico para ${column.column_name} en tabla de usuarios ${schema}.${table}`);
|
|
117
|
+
await this.createIndex(schema, table, indexInfo);
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
await this.fixUserTableSequences(schema, table);
|
|
121
|
+
}
|
|
122
|
+
catch (error) {
|
|
123
|
+
this.logger.error(`Error asegurando índices críticos para tabla de usuarios ${schema}.${table}: ${error.message}`);
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
async fixUserTableSequences(schema, table) {
|
|
127
|
+
var _a;
|
|
128
|
+
try {
|
|
129
|
+
const columnsQuery = `
|
|
130
|
+
SELECT column_name
|
|
131
|
+
FROM information_schema.columns
|
|
132
|
+
WHERE table_schema = $1
|
|
133
|
+
AND table_name = $2
|
|
134
|
+
AND (is_identity = 'YES' OR column_default LIKE 'nextval%')
|
|
135
|
+
`;
|
|
136
|
+
const columnsResult = await this.targetPool.query(columnsQuery, [schema, table]);
|
|
137
|
+
const identityColumns = columnsResult.rows.map(row => row.column_name);
|
|
138
|
+
for (const column of identityColumns) {
|
|
139
|
+
const sequenceQuery = `
|
|
140
|
+
SELECT pg_get_serial_sequence($1, $2) AS sequence_name
|
|
141
|
+
`;
|
|
142
|
+
const sequenceResult = await this.targetPool.query(sequenceQuery, [`${schema}.${table}`, column]);
|
|
143
|
+
const sequenceName = (_a = sequenceResult.rows[0]) === null || _a === void 0 ? void 0 : _a.sequence_name;
|
|
144
|
+
if (sequenceName) {
|
|
145
|
+
const resetQuery = `
|
|
146
|
+
SELECT setval($1, COALESCE((SELECT MAX(${column}) FROM ${schema}.${table}), 0) + 1, true)
|
|
147
|
+
`;
|
|
148
|
+
await this.targetPool.query(resetQuery, [sequenceName]);
|
|
149
|
+
this.logger.log(`Restablecida secuencia ${sequenceName} para la columna ${column} en ${schema}.${table} (tabla de usuarios)`);
|
|
150
|
+
this.fixedIndexes.push({
|
|
151
|
+
schema,
|
|
152
|
+
table,
|
|
153
|
+
column,
|
|
154
|
+
sequence_name: sequenceName,
|
|
155
|
+
action: 'reset_sequence_user_table',
|
|
156
|
+
timestamp: new Date().toISOString()
|
|
157
|
+
});
|
|
158
|
+
}
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
catch (error) {
|
|
162
|
+
this.logger.error(`Error restableciendo secuencias para tabla de usuarios ${schema}.${table}: ${error.message}`);
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
async removeRedundantIndexes(schema, table, indexes) {
|
|
166
|
+
const redundantIndexes = [];
|
|
167
|
+
const criticalIndexPatterns = [
|
|
168
|
+
'email', 'username', 'phone', 'uuid', 'pkey', 'primary',
|
|
169
|
+
'unique', 'user_id', 'auth', 'session', 'token'
|
|
170
|
+
];
|
|
171
|
+
for (let i = 0; i < indexes.length; i++) {
|
|
172
|
+
for (let j = 0; j < indexes.length; j++) {
|
|
173
|
+
if (i !== j && !indexes[i].is_primary && !indexes[j].is_primary) {
|
|
174
|
+
const index1 = indexes[i];
|
|
175
|
+
const index2 = indexes[j];
|
|
176
|
+
if (!Array.isArray(index1.column_names) || !Array.isArray(index2.column_names)) {
|
|
177
|
+
this.logger.warn(`Índice con formato incorrecto en ${schema}.${table}: ${index1.index_name} o ${index2.index_name}`);
|
|
178
|
+
continue;
|
|
179
|
+
}
|
|
180
|
+
const isIndex1Critical = criticalIndexPatterns.some(pattern => index1.index_name.toLowerCase().includes(pattern));
|
|
181
|
+
if (isIndex1Critical) {
|
|
182
|
+
continue;
|
|
183
|
+
}
|
|
184
|
+
if (index1.column_names.every(col => index2.column_names.includes(col)) &&
|
|
185
|
+
index2.column_names.length > index1.column_names.length) {
|
|
186
|
+
redundantIndexes.push(index1);
|
|
187
|
+
break;
|
|
188
|
+
}
|
|
189
|
+
}
|
|
190
|
+
}
|
|
191
|
+
}
|
|
192
|
+
for (const index of redundantIndexes) {
|
|
193
|
+
try {
|
|
194
|
+
const query = `DROP INDEX IF EXISTS "${schema}"."${index.index_name}"`;
|
|
195
|
+
await this.targetPool.query(query);
|
|
196
|
+
this.logger.log(`Eliminado índice redundante ${index.index_name} en ${schema}.${table}`);
|
|
197
|
+
this.fixedIndexes.push({
|
|
198
|
+
schema,
|
|
199
|
+
table,
|
|
200
|
+
index_name: index.index_name,
|
|
201
|
+
action: 'removed_redundant',
|
|
202
|
+
timestamp: new Date().toISOString()
|
|
203
|
+
});
|
|
204
|
+
}
|
|
205
|
+
catch (error) {
|
|
206
|
+
this.logger.error(`Error eliminando índice redundante ${index.index_name} en ${schema}.${table}: ${error.message}`);
|
|
207
|
+
}
|
|
208
|
+
}
|
|
209
|
+
}
|
|
210
|
+
async fixSequences(schema, table) {
|
|
211
|
+
var _a;
|
|
212
|
+
try {
|
|
213
|
+
const columnsQuery = `
|
|
214
|
+
SELECT column_name
|
|
215
|
+
FROM information_schema.columns
|
|
216
|
+
WHERE table_schema = $1
|
|
217
|
+
AND table_name = $2
|
|
218
|
+
AND (is_identity = 'YES' OR column_default LIKE 'nextval%')
|
|
219
|
+
`;
|
|
220
|
+
const columnsResult = await this.targetPool.query(columnsQuery, [schema, table]);
|
|
221
|
+
const identityColumns = columnsResult.rows.map(row => row.column_name);
|
|
222
|
+
for (const column of identityColumns) {
|
|
223
|
+
const sequenceQuery = `
|
|
224
|
+
SELECT pg_get_serial_sequence($1, $2) AS sequence_name
|
|
225
|
+
`;
|
|
226
|
+
const sequenceResult = await this.targetPool.query(sequenceQuery, [`${schema}.${table}`, column]);
|
|
227
|
+
const sequenceName = (_a = sequenceResult.rows[0]) === null || _a === void 0 ? void 0 : _a.sequence_name;
|
|
228
|
+
if (sequenceName) {
|
|
229
|
+
const resetQuery = `
|
|
230
|
+
SELECT setval($1, COALESCE((SELECT MAX(${column}) FROM ${schema}.${table}), 0) + 1, true)
|
|
231
|
+
`;
|
|
232
|
+
await this.targetPool.query(resetQuery, [sequenceName]);
|
|
233
|
+
this.logger.log(`Restablecida secuencia ${sequenceName} para la columna ${column} en ${schema}.${table}`);
|
|
234
|
+
this.fixedIndexes.push({
|
|
235
|
+
schema,
|
|
236
|
+
table,
|
|
237
|
+
column,
|
|
238
|
+
sequence_name: sequenceName,
|
|
239
|
+
action: 'reset_sequence',
|
|
240
|
+
timestamp: new Date().toISOString()
|
|
241
|
+
});
|
|
242
|
+
}
|
|
243
|
+
}
|
|
244
|
+
}
|
|
245
|
+
catch (error) {
|
|
246
|
+
this.logger.error(`Error restableciendo secuencias para ${schema}.${table}: ${error.message}`);
|
|
247
|
+
}
|
|
248
|
+
}
|
|
249
|
+
async getTableInfo(schema, table) {
|
|
250
|
+
var _a;
|
|
251
|
+
try {
|
|
252
|
+
const identityQuery = `
|
|
253
|
+
SELECT EXISTS (
|
|
254
|
+
SELECT 1
|
|
255
|
+
FROM information_schema.columns
|
|
256
|
+
WHERE table_schema = $1
|
|
257
|
+
AND table_name = $2
|
|
258
|
+
AND is_identity = 'YES'
|
|
259
|
+
) AS has_identity_column;
|
|
260
|
+
`;
|
|
261
|
+
const result = await this.targetPool.query(identityQuery, [schema, table]);
|
|
262
|
+
return {
|
|
263
|
+
has_identity_column: ((_a = result.rows[0]) === null || _a === void 0 ? void 0 : _a.has_identity_column) || false
|
|
264
|
+
};
|
|
265
|
+
}
|
|
266
|
+
catch (error) {
|
|
267
|
+
this.logger.error(`Error obteniendo información de la tabla ${schema}.${table}: ${error.message}`);
|
|
268
|
+
return { has_identity_column: false };
|
|
269
|
+
}
|
|
270
|
+
}
|
|
271
|
+
async getTableIndexes(pool, schema, table) {
|
|
272
|
+
const query = `
|
|
273
|
+
SELECT
|
|
274
|
+
i.relname AS index_name,
|
|
275
|
+
array_agg(a.attname) AS column_names,
|
|
276
|
+
ix.indisunique AS is_unique,
|
|
277
|
+
ix.indisprimary AS is_primary,
|
|
278
|
+
pg_get_indexdef(ix.indexrelid) AS definition
|
|
279
|
+
FROM
|
|
280
|
+
pg_index ix
|
|
281
|
+
JOIN pg_class i ON i.oid = ix.indexrelid
|
|
282
|
+
JOIN pg_class t ON t.oid = ix.indrelid
|
|
283
|
+
JOIN pg_namespace n ON n.oid = t.relnamespace
|
|
284
|
+
JOIN pg_attribute a ON a.attrelid = t.oid AND a.attnum = ANY(ix.indkey)
|
|
285
|
+
WHERE
|
|
286
|
+
n.nspname = $1
|
|
287
|
+
AND t.relname = $2
|
|
288
|
+
GROUP BY
|
|
289
|
+
i.relname, ix.indisunique, ix.indisprimary, ix.indexrelid
|
|
290
|
+
ORDER BY
|
|
291
|
+
i.relname;
|
|
292
|
+
`;
|
|
293
|
+
try {
|
|
294
|
+
const result = await pool.query(query, [schema, table]);
|
|
295
|
+
return result.rows.map(row => ({
|
|
296
|
+
schema,
|
|
297
|
+
table,
|
|
298
|
+
index_name: row.index_name,
|
|
299
|
+
column_names: row.column_names,
|
|
300
|
+
is_unique: row.is_unique,
|
|
301
|
+
is_primary: row.is_primary,
|
|
302
|
+
definition: row.definition
|
|
303
|
+
}));
|
|
304
|
+
}
|
|
305
|
+
catch (error) {
|
|
306
|
+
this.logger.error(`Error obteniendo índices para ${schema}.${table}: ${error.message}`);
|
|
307
|
+
return [];
|
|
308
|
+
}
|
|
309
|
+
}
|
|
310
|
+
async createIndex(schema, table, indexInfo) {
|
|
311
|
+
try {
|
|
312
|
+
const columnList = indexInfo.column_names.join('_');
|
|
313
|
+
const indexName = `idx_${table}_${columnList}`.substring(0, 63);
|
|
314
|
+
let query = `CREATE`;
|
|
315
|
+
if (indexInfo.is_unique) {
|
|
316
|
+
query += ` UNIQUE`;
|
|
317
|
+
}
|
|
318
|
+
query += ` INDEX IF NOT EXISTS "${indexName}" ON "${schema}"."${table}" (${indexInfo.column_names.map(col => `"${col}"`).join(', ')})`;
|
|
319
|
+
await this.targetPool.query(query);
|
|
320
|
+
this.logger.log(`Creado índice ${indexName} en ${schema}.${table}`);
|
|
321
|
+
this.fixedIndexes.push({
|
|
322
|
+
schema,
|
|
323
|
+
table,
|
|
324
|
+
index_name: indexName,
|
|
325
|
+
columns: indexInfo.column_names,
|
|
326
|
+
is_unique: indexInfo.is_unique,
|
|
327
|
+
timestamp: new Date().toISOString()
|
|
328
|
+
});
|
|
329
|
+
}
|
|
330
|
+
catch (error) {
|
|
331
|
+
this.logger.error(`Error creando índice en ${schema}.${table}: ${error.message}`);
|
|
332
|
+
}
|
|
333
|
+
}
|
|
334
|
+
async fixCommonIndexIssues(schema, table) {
|
|
335
|
+
try {
|
|
336
|
+
const columns = await this.getTableColumns(schema, table);
|
|
337
|
+
const potentialIndexColumns = columns.filter(col => col.column_name.endsWith('_id') ||
|
|
338
|
+
col.column_name === 'id' ||
|
|
339
|
+
col.column_name === 'uuid' ||
|
|
340
|
+
col.column_name === 'slug' ||
|
|
341
|
+
col.column_name === 'email' ||
|
|
342
|
+
col.column_name === 'username' ||
|
|
343
|
+
col.column_name.includes('code') ||
|
|
344
|
+
col.column_name === 'user_id' ||
|
|
345
|
+
col.column_name === 'created_at' ||
|
|
346
|
+
col.column_name === 'updated_at');
|
|
347
|
+
const existingIndexes = await this.getTableIndexes(this.targetPool, schema, table);
|
|
348
|
+
const indexedColumns = new Set(existingIndexes.flatMap(idx => idx.column_names));
|
|
349
|
+
for (const column of potentialIndexColumns) {
|
|
350
|
+
if (!indexedColumns.has(column.column_name)) {
|
|
351
|
+
const shouldBeUnique = ['email', 'username', 'slug', 'uuid'].includes(column.column_name);
|
|
352
|
+
const indexInfo = {
|
|
353
|
+
schema,
|
|
354
|
+
table,
|
|
355
|
+
index_name: `idx_${table}_${column.column_name}`,
|
|
356
|
+
column_names: [column.column_name],
|
|
357
|
+
is_unique: shouldBeUnique,
|
|
358
|
+
is_primary: false,
|
|
359
|
+
definition: ''
|
|
360
|
+
};
|
|
361
|
+
await this.createIndex(schema, table, indexInfo);
|
|
362
|
+
}
|
|
363
|
+
}
|
|
364
|
+
}
|
|
365
|
+
catch (error) {
|
|
366
|
+
this.logger.error(`Error corrigiendo problemas comunes de índices en ${schema}.${table}: ${error.message}`);
|
|
367
|
+
}
|
|
368
|
+
}
|
|
369
|
+
async getTableColumns(schema, table) {
|
|
370
|
+
const query = `
|
|
371
|
+
SELECT column_name, data_type, is_nullable
|
|
372
|
+
FROM information_schema.columns
|
|
373
|
+
WHERE table_schema = $1
|
|
374
|
+
AND table_name = $2
|
|
375
|
+
`;
|
|
376
|
+
const result = await this.targetPool.query(query, [schema, table]);
|
|
377
|
+
return result.rows;
|
|
378
|
+
}
|
|
379
|
+
async fixForeignKeyIndexes(schema, table) {
|
|
380
|
+
try {
|
|
381
|
+
const fkQuery = `
|
|
382
|
+
SELECT
|
|
383
|
+
kcu.column_name,
|
|
384
|
+
ccu.table_schema AS foreign_table_schema,
|
|
385
|
+
ccu.table_name AS foreign_table_name,
|
|
386
|
+
ccu.column_name AS foreign_column_name
|
|
387
|
+
FROM
|
|
388
|
+
information_schema.table_constraints AS tc
|
|
389
|
+
JOIN information_schema.key_column_usage AS kcu
|
|
390
|
+
ON tc.constraint_name = kcu.constraint_name
|
|
391
|
+
AND tc.table_schema = kcu.table_schema
|
|
392
|
+
JOIN information_schema.constraint_column_usage AS ccu
|
|
393
|
+
ON ccu.constraint_name = tc.constraint_name
|
|
394
|
+
AND ccu.table_schema = tc.table_schema
|
|
395
|
+
WHERE
|
|
396
|
+
tc.constraint_type = 'FOREIGN KEY'
|
|
397
|
+
AND tc.table_schema = $1
|
|
398
|
+
AND tc.table_name = $2;
|
|
399
|
+
`;
|
|
400
|
+
const fkResult = await this.targetPool.query(fkQuery, [schema, table]);
|
|
401
|
+
const existingIndexes = await this.getTableIndexes(this.targetPool, schema, table);
|
|
402
|
+
const indexedColumns = new Set(existingIndexes.flatMap(idx => idx.column_names));
|
|
403
|
+
for (const fk of fkResult.rows) {
|
|
404
|
+
if (!indexedColumns.has(fk.column_name)) {
|
|
405
|
+
const indexInfo = {
|
|
406
|
+
schema,
|
|
407
|
+
table,
|
|
408
|
+
index_name: `idx_${table}_${fk.column_name}`,
|
|
409
|
+
column_names: [fk.column_name],
|
|
410
|
+
is_unique: false,
|
|
411
|
+
is_primary: false,
|
|
412
|
+
definition: ''
|
|
413
|
+
};
|
|
414
|
+
await this.createIndex(schema, table, indexInfo);
|
|
415
|
+
}
|
|
416
|
+
}
|
|
417
|
+
}
|
|
418
|
+
catch (error) {
|
|
419
|
+
this.logger.error(`Error creando índices para claves foráneas en ${schema}.${table}: ${error.message}`);
|
|
420
|
+
}
|
|
421
|
+
}
|
|
422
|
+
saveFixLog() {
|
|
423
|
+
try {
|
|
424
|
+
const logData = {
|
|
425
|
+
timestamp: new Date().toISOString(),
|
|
426
|
+
targetDatabase: this.targetUrl,
|
|
427
|
+
fixCount: this.fixedIndexes.length,
|
|
428
|
+
fixes: this.fixedIndexes
|
|
429
|
+
};
|
|
430
|
+
fs.writeFileSync(this.logPath, JSON.stringify(logData, null, 2), 'utf8');
|
|
431
|
+
}
|
|
432
|
+
catch (error) {
|
|
433
|
+
this.logger.error(`Error guardando log de correcciones: ${error.message}`);
|
|
434
|
+
}
|
|
435
|
+
}
|
|
436
|
+
async cleanup() {
|
|
437
|
+
try {
|
|
438
|
+
await this.targetPool.end();
|
|
439
|
+
}
|
|
440
|
+
catch (error) {
|
|
441
|
+
this.logger.error(`Error durante la limpieza: ${error.message}`);
|
|
442
|
+
}
|
|
443
|
+
}
|
|
444
|
+
}
|
|
445
|
+
exports.TableIndexFixer = TableIndexFixer;
|
|
446
|
+
if (require.main === module) {
|
|
447
|
+
const run = async () => {
|
|
448
|
+
try {
|
|
449
|
+
const indexFixer = new TableIndexFixer();
|
|
450
|
+
await indexFixer.fixIndexes();
|
|
451
|
+
process.exit(0);
|
|
452
|
+
}
|
|
453
|
+
catch (error) {
|
|
454
|
+
console.error("Error:", error.message);
|
|
455
|
+
process.exit(1);
|
|
456
|
+
}
|
|
457
|
+
};
|
|
458
|
+
run();
|
|
459
|
+
}
|
|
460
|
+
//# sourceMappingURL=fix-table-indexes.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"fix-table-indexes.js","sourceRoot":"","sources":["../../src/scripts/fix-table-indexes.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
const common_1 = require("@nestjs/common");
|
|
4
|
+
const dotenv = require("dotenv");
|
|
5
|
+
const path = require("path");
|
|
6
|
+
const db_connector_1 = require("./data-migration/db-connector");
|
|
7
|
+
const multi_source_migrator_1 = require("./data-migration/multi-source-migrator");
|
|
8
|
+
dotenv.config({
|
|
9
|
+
path: path.resolve(__dirname, '../../.env')
|
|
10
|
+
});
|
|
11
|
+
async function main() {
|
|
12
|
+
const logger = new common_1.Logger("MultiDBMigration");
|
|
13
|
+
logger.log("Iniciando migración desde múltiples bases de datos");
|
|
14
|
+
logger.log(`Variables de entorno cargadas: ${process.env.DATABASE_URL ? 'Sí' : 'No'}`);
|
|
15
|
+
const sourceDatabases = [
|
|
16
|
+
{
|
|
17
|
+
id: "colombia",
|
|
18
|
+
url: process.env.COLOMBIA_DATABASE_URL || "",
|
|
19
|
+
name: "Colombia"
|
|
20
|
+
},
|
|
21
|
+
{
|
|
22
|
+
id: "rd",
|
|
23
|
+
url: process.env.RD_DATABASE_URL || "",
|
|
24
|
+
name: "República Dominicana"
|
|
25
|
+
},
|
|
26
|
+
{
|
|
27
|
+
id: "guatemala",
|
|
28
|
+
url: process.env.GUATEMALA_DATABASE_URL || "",
|
|
29
|
+
name: "Guatemala"
|
|
30
|
+
}
|
|
31
|
+
];
|
|
32
|
+
const missingUrls = sourceDatabases.filter(db => !db.url);
|
|
33
|
+
if (missingUrls.length > 0) {
|
|
34
|
+
logger.error(`Faltan URLs de conexión para: ${missingUrls.map(db => db.name).join(", ")}`);
|
|
35
|
+
process.exit(1);
|
|
36
|
+
}
|
|
37
|
+
const connections = db_connector_1.DatabaseConnector.createConnections(sourceDatabases);
|
|
38
|
+
try {
|
|
39
|
+
const migrator = new multi_source_migrator_1.MultiSourceMigrator(connections);
|
|
40
|
+
await migrator.migrateAllSources({});
|
|
41
|
+
logger.log("Migración multi-origen completada con éxito");
|
|
42
|
+
}
|
|
43
|
+
catch (error) {
|
|
44
|
+
logger.error(`Error en la migración multi-origen: ${error.message}`);
|
|
45
|
+
process.exit(1);
|
|
46
|
+
}
|
|
47
|
+
finally {
|
|
48
|
+
await db_connector_1.DatabaseConnector.cleanup(connections);
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
main().catch(error => {
|
|
52
|
+
console.error("Error fatal:", error);
|
|
53
|
+
process.exit(1);
|
|
54
|
+
});
|
|
55
|
+
//# sourceMappingURL=multi-db-migration.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"multi-db-migration.js","sourceRoot":"","sources":["../../src/scripts/multi-db-migration.ts"],"names":[],"mappings":";;AAAA,2CAAwC;AACxC,iCAAiC;AACjC,6BAA6B;AAC7B,gEAAkF;AAClF,kFAA6E;AAG7E,MAAM,CAAC,MAAM,CAAC;IACZ,IAAI,EAAE,IAAI,CAAC,OAAO,CAAC,SAAS,EAAE,YAAY,CAAC;CAC5C,CAAC,CAAC;AAEH,KAAK,UAAU,IAAI;IACjB,MAAM,MAAM,GAAG,IAAI,eAAM,CAAC,kBAAkB,CAAC,CAAC;IAC9C,MAAM,CAAC,GAAG,CAAC,oDAAoD,CAAC,CAAC;IAGjE,MAAM,CAAC,GAAG,CAAC,kCAAkC,OAAO,CAAC,GAAG,CAAC,YAAY,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC;IAGvF,MAAM,eAAe,GAAqB;QACxC;YACE,EAAE,EAAE,UAAU;YACd,GAAG,EAAE,OAAO,CAAC,GAAG,CAAC,qBAAqB,IAAI,EAAE;YAC5C,IAAI,EAAE,UAAU;SACjB;QACD;YACE,EAAE,EAAE,IAAI;YACR,GAAG,EAAE,OAAO,CAAC,GAAG,CAAC,eAAe,IAAI,EAAE;YACtC,IAAI,EAAE,sBAAsB;SAC7B;QACD;YACE,EAAE,EAAE,WAAW;YACf,GAAG,EAAE,OAAO,CAAC,GAAG,CAAC,sBAAsB,IAAI,EAAE;YAC7C,IAAI,EAAE,WAAW;SAClB;KACF,CAAC;IAGF,MAAM,WAAW,GAAG,eAAe,CAAC,MAAM,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC;IAC1D,IAAI,WAAW,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QAC3B,MAAM,CAAC,KAAK,CAAC,iCAAiC,WAAW,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;QAC3F,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;IAGD,MAAM,WAAW,GAAG,gCAAiB,CAAC,iBAAiB,CAAC,eAAe,CAAC,CAAC;IAEzE,IAAI,CAAC;QAEH,MAAM,QAAQ,GAAG,IAAI,2CAAmB,CAAC,WAAW,CAAC,CAAC;QAGtD,MAAM,QAAQ,CAAC,iBAAiB,CAAC,EAIhC,CAAC,CAAC;QAEH,MAAM,CAAC,GAAG,CAAC,6CAA6C,CAAC,CAAC;IAC5D,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,MAAM,CAAC,KAAK,CAAC,uCAAuC,KAAK,CAAC,OAAO,EAAE,CAAC,CAAC;QACrE,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;YAAS,CAAC;QAET,MAAM,gCAAiB,CAAC,OAAO,CAAC,WAAW,CAAC,CAAC;IAC/C,CAAC;AACH,CAAC;AAGD,IAAI,EAAE,CAAC,KAAK,CAAC,KAAK,CAAC,EAAE;IACnB,OAAO,CAAC,KAAK,CAAC,cAAc,EAAE,KAAK,CAAC,CAAC;IACrC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AAClB,CAAC,CAAC,CAAC"}
|