@javalabs/prisma-client 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +220 -0
- package/dist/index.d.ts +7 -0
- package/dist/index.js +34 -0
- package/dist/index.js.map +1 -0
- package/dist/prisma-factory.service.d.ts +9 -0
- package/dist/prisma-factory.service.js +47 -0
- package/dist/prisma-factory.service.js.map +1 -0
- package/dist/prisma.module.d.ts +2 -0
- package/dist/prisma.module.js +23 -0
- package/dist/prisma.module.js.map +1 -0
- package/dist/prisma.service.d.ts +6 -0
- package/dist/prisma.service.js +27 -0
- package/dist/prisma.service.js.map +1 -0
- package/dist/scripts/create-tenant-schemas.d.ts +1 -0
- package/dist/scripts/create-tenant-schemas.js +117 -0
- package/dist/scripts/create-tenant-schemas.js.map +1 -0
- package/dist/scripts/data-migration/batch-migrator.d.ts +25 -0
- package/dist/scripts/data-migration/batch-migrator.js +333 -0
- package/dist/scripts/data-migration/batch-migrator.js.map +1 -0
- package/dist/scripts/data-migration/data-transformer.d.ts +17 -0
- package/dist/scripts/data-migration/data-transformer.js +242 -0
- package/dist/scripts/data-migration/data-transformer.js.map +1 -0
- package/dist/scripts/data-migration/db-connector.d.ts +7 -0
- package/dist/scripts/data-migration/db-connector.js +58 -0
- package/dist/scripts/data-migration/db-connector.js.map +1 -0
- package/dist/scripts/data-migration/dependency-manager.d.ts +9 -0
- package/dist/scripts/data-migration/dependency-manager.js +86 -0
- package/dist/scripts/data-migration/dependency-manager.js.map +1 -0
- package/dist/scripts/data-migration/dependency-resolver.d.ts +18 -0
- package/dist/scripts/data-migration/dependency-resolver.js +251 -0
- package/dist/scripts/data-migration/dependency-resolver.js.map +1 -0
- package/dist/scripts/data-migration/entity-discovery.d.ts +11 -0
- package/dist/scripts/data-migration/entity-discovery.js +152 -0
- package/dist/scripts/data-migration/entity-discovery.js.map +1 -0
- package/dist/scripts/data-migration/foreign-key-manager.d.ts +17 -0
- package/dist/scripts/data-migration/foreign-key-manager.js +70 -0
- package/dist/scripts/data-migration/foreign-key-manager.js.map +1 -0
- package/dist/scripts/data-migration/migration-phases.d.ts +5 -0
- package/dist/scripts/data-migration/migration-phases.js +55 -0
- package/dist/scripts/data-migration/migration-phases.js.map +1 -0
- package/dist/scripts/data-migration/migration-tool.d.ts +29 -0
- package/dist/scripts/data-migration/migration-tool.js +250 -0
- package/dist/scripts/data-migration/migration-tool.js.map +1 -0
- package/dist/scripts/data-migration/phase-generator.d.ts +15 -0
- package/dist/scripts/data-migration/phase-generator.js +187 -0
- package/dist/scripts/data-migration/phase-generator.js.map +1 -0
- package/dist/scripts/data-migration/schema-utils.d.ts +18 -0
- package/dist/scripts/data-migration/schema-utils.js +164 -0
- package/dist/scripts/data-migration/schema-utils.js.map +1 -0
- package/dist/scripts/data-migration/tenant-migrator.d.ts +15 -0
- package/dist/scripts/data-migration/tenant-migrator.js +110 -0
- package/dist/scripts/data-migration/tenant-migrator.js.map +1 -0
- package/dist/scripts/data-migration/typecast-manager.d.ts +5 -0
- package/dist/scripts/data-migration/typecast-manager.js +35 -0
- package/dist/scripts/data-migration/typecast-manager.js.map +1 -0
- package/dist/scripts/data-migration/types.d.ts +34 -0
- package/dist/scripts/data-migration/types.js +3 -0
- package/dist/scripts/data-migration/types.js.map +1 -0
- package/dist/scripts/data-migration.d.ts +22 -0
- package/dist/scripts/data-migration.js +593 -0
- package/dist/scripts/data-migration.js.map +1 -0
- package/dist/scripts/drop-database.d.ts +10 -0
- package/dist/scripts/drop-database.js +81 -0
- package/dist/scripts/drop-database.js.map +1 -0
- package/dist/scripts/error-handler.d.ts +12 -0
- package/dist/scripts/error-handler.js +82 -0
- package/dist/scripts/error-handler.js.map +1 -0
- package/dist/scripts/fix-data-types.d.ts +10 -0
- package/dist/scripts/fix-data-types.js +185 -0
- package/dist/scripts/fix-data-types.js.map +1 -0
- package/dist/scripts/fix-enum-values.d.ts +17 -0
- package/dist/scripts/fix-enum-values.js +234 -0
- package/dist/scripts/fix-enum-values.js.map +1 -0
- package/dist/scripts/fix-schema-discrepancies.d.ts +21 -0
- package/dist/scripts/fix-schema-discrepancies.js +240 -0
- package/dist/scripts/fix-schema-discrepancies.js.map +1 -0
- package/dist/scripts/migrate-schema-structure.d.ts +1 -0
- package/dist/scripts/migrate-schema-structure.js +76 -0
- package/dist/scripts/migrate-schema-structure.js.map +1 -0
- package/dist/scripts/post-migration-validator.d.ts +21 -0
- package/dist/scripts/post-migration-validator.js +341 -0
- package/dist/scripts/post-migration-validator.js.map +1 -0
- package/dist/scripts/pre-migration-validator.d.ts +25 -0
- package/dist/scripts/pre-migration-validator.js +491 -0
- package/dist/scripts/pre-migration-validator.js.map +1 -0
- package/dist/scripts/reset-database.d.ts +17 -0
- package/dist/scripts/reset-database.js +202 -0
- package/dist/scripts/reset-database.js.map +1 -0
- package/dist/scripts/retry-failed-migrations.d.ts +14 -0
- package/dist/scripts/retry-failed-migrations.js +301 -0
- package/dist/scripts/retry-failed-migrations.js.map +1 -0
- package/dist/scripts/run-migration.d.ts +1 -0
- package/dist/scripts/run-migration.js +525 -0
- package/dist/scripts/run-migration.js.map +1 -0
- package/dist/scripts/schema-sync.d.ts +1 -0
- package/dist/scripts/schema-sync.js +85 -0
- package/dist/scripts/schema-sync.js.map +1 -0
- package/dist/scripts/sync-enum-types.d.ts +13 -0
- package/dist/scripts/sync-enum-types.js +139 -0
- package/dist/scripts/sync-enum-types.js.map +1 -0
- package/dist/scripts/sync-enum-values.d.ts +20 -0
- package/dist/scripts/sync-enum-values.js +336 -0
- package/dist/scripts/sync-enum-values.js.map +1 -0
- package/dist/scripts/truncate-database.d.ts +10 -0
- package/dist/scripts/truncate-database.js +100 -0
- package/dist/scripts/truncate-database.js.map +1 -0
- package/dist/scripts/verify-migration-setup.d.ts +11 -0
- package/dist/scripts/verify-migration-setup.js +120 -0
- package/dist/scripts/verify-migration-setup.js.map +1 -0
- package/dist/tsconfig.tsbuildinfo +1 -0
- package/migration-config-public.json +95 -0
- package/migration-config.json +95 -0
- package/package.json +33 -0
- package/prisma/migrations/migration_lock.toml +3 -0
- package/prisma/schema.prisma +360 -0
- package/src/index.ts +23 -0
- package/src/prisma-factory.service.ts +41 -0
- package/src/prisma.module.ts +10 -0
- package/src/prisma.service.ts +17 -0
- package/src/scripts/create-tenant-schemas.ts +146 -0
- package/src/scripts/data-migration/batch-migrator.ts +569 -0
- package/src/scripts/data-migration/data-transformer.ts +377 -0
- package/src/scripts/data-migration/db-connector.ts +67 -0
- package/src/scripts/data-migration/dependency-resolver.ts +319 -0
- package/src/scripts/data-migration/entity-discovery.ts +197 -0
- package/src/scripts/data-migration/foreign-key-manager.ts +95 -0
- package/src/scripts/data-migration/migration-tool.ts +357 -0
- package/src/scripts/data-migration/schema-utils.ts +186 -0
- package/src/scripts/data-migration/tenant-migrator.ts +194 -0
- package/src/scripts/data-migration/typecast-manager.ts +38 -0
- package/src/scripts/data-migration/types.ts +40 -0
- package/src/scripts/drop-database.ts +105 -0
- package/src/scripts/dump-source-db.sh +62 -0
- package/src/scripts/dumps/source_dump_20250413_112626.sql +1527 -0
- package/src/scripts/error-handler.ts +118 -0
- package/src/scripts/fix-data-types.ts +242 -0
- package/src/scripts/fix-enum-values.ts +357 -0
- package/src/scripts/fix-schema-discrepancies.ts +318 -0
- package/src/scripts/migrate-schema-structure.ts +90 -0
- package/src/scripts/post-migration-validator.ts +427 -0
- package/src/scripts/pre-migration-validator.ts +611 -0
- package/src/scripts/reset-database.ts +264 -0
- package/src/scripts/retry-failed-migrations.ts +416 -0
- package/src/scripts/run-migration.ts +691 -0
- package/src/scripts/schema-sync.ts +129 -0
- package/src/scripts/sync-enum-types.ts +171 -0
- package/src/scripts/sync-enum-values.ts +563 -0
- package/src/scripts/truncate-database.ts +124 -0
- package/src/scripts/verify-migration-setup.ts +136 -0
- package/tsconfig.json +18 -0
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.DatabaseConnector = void 0;
|
|
4
|
+
const client_1 = require("@prisma/client");
|
|
5
|
+
const pg = require("pg");
|
|
6
|
+
const dotenv = require("dotenv");
|
|
7
|
+
dotenv.config();
|
|
8
|
+
class DatabaseConnector {
|
|
9
|
+
static createConnections() {
|
|
10
|
+
const sourcePool = new pg.Pool({
|
|
11
|
+
connectionString: process.env.SOURCE_DATABASE_URL,
|
|
12
|
+
});
|
|
13
|
+
const targetPool = new pg.Pool({
|
|
14
|
+
connectionString: process.env.DATABASE_URL,
|
|
15
|
+
});
|
|
16
|
+
const sourcePrisma = new client_1.PrismaClient({
|
|
17
|
+
datasources: {
|
|
18
|
+
db: {
|
|
19
|
+
url: process.env.SOURCE_DATABASE_URL,
|
|
20
|
+
},
|
|
21
|
+
},
|
|
22
|
+
});
|
|
23
|
+
const targetPrisma = new client_1.PrismaClient({
|
|
24
|
+
datasources: {
|
|
25
|
+
db: {
|
|
26
|
+
url: process.env.DATABASE_URL,
|
|
27
|
+
},
|
|
28
|
+
},
|
|
29
|
+
});
|
|
30
|
+
return {
|
|
31
|
+
sourcePrisma,
|
|
32
|
+
targetPrisma,
|
|
33
|
+
sourcePool,
|
|
34
|
+
targetPool,
|
|
35
|
+
};
|
|
36
|
+
}
|
|
37
|
+
static createTenantPrismaClient(tenantId) {
|
|
38
|
+
return new client_1.PrismaClient({
|
|
39
|
+
datasources: {
|
|
40
|
+
db: {
|
|
41
|
+
url: `${process.env.DATABASE_URL}?schema=${tenantId}`,
|
|
42
|
+
},
|
|
43
|
+
},
|
|
44
|
+
transactionOptions: {
|
|
45
|
+
maxWait: 120000,
|
|
46
|
+
timeout: 120000,
|
|
47
|
+
},
|
|
48
|
+
});
|
|
49
|
+
}
|
|
50
|
+
static async cleanup(connections) {
|
|
51
|
+
await connections.sourcePrisma.$disconnect();
|
|
52
|
+
await connections.targetPrisma.$disconnect();
|
|
53
|
+
await connections.sourcePool.end();
|
|
54
|
+
await connections.targetPool.end();
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
exports.DatabaseConnector = DatabaseConnector;
|
|
58
|
+
//# sourceMappingURL=db-connector.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"db-connector.js","sourceRoot":"","sources":["../../../src/scripts/data-migration/db-connector.ts"],"names":[],"mappings":";;;AAAA,2CAA8C;AAC9C,yBAAyB;AACzB,iCAAiC;AAGjC,MAAM,CAAC,MAAM,EAAE,CAAC;AAEhB,MAAa,iBAAiB;IAC5B,MAAM,CAAC,iBAAiB;QAEtB,MAAM,UAAU,GAAG,IAAI,EAAE,CAAC,IAAI,CAAC;YAC7B,gBAAgB,EAAE,OAAO,CAAC,GAAG,CAAC,mBAAmB;SAClD,CAAC,CAAC;QAGH,MAAM,UAAU,GAAG,IAAI,EAAE,CAAC,IAAI,CAAC;YAC7B,gBAAgB,EAAE,OAAO,CAAC,GAAG,CAAC,YAAY;SAC3C,CAAC,CAAC;QAGH,MAAM,YAAY,GAAG,IAAI,qBAAY,CAAC;YACpC,WAAW,EAAE;gBACX,EAAE,EAAE;oBACF,GAAG,EAAE,OAAO,CAAC,GAAG,CAAC,mBAAmB;iBACrC;aACF;SACF,CAAC,CAAC;QAGH,MAAM,YAAY,GAAG,IAAI,qBAAY,CAAC;YACpC,WAAW,EAAE;gBACX,EAAE,EAAE;oBACF,GAAG,EAAE,OAAO,CAAC,GAAG,CAAC,YAAY;iBAC9B;aACF;SACF,CAAC,CAAC;QAEH,OAAO;YACL,YAAY;YACZ,YAAY;YACZ,UAAU;YACV,UAAU;SACX,CAAC;IACJ,CAAC;IAED,MAAM,CAAC,wBAAwB,CAAC,QAAgB;QAC9C,OAAO,IAAI,qBAAY,CAAC;YACtB,WAAW,EAAE;gBACX,EAAE,EAAE;oBACF,GAAG,EAAE,GAAG,OAAO,CAAC,GAAG,CAAC,YAAY,WAAW,QAAQ,EAAE;iBACtD;aACF;YAED,kBAAkB,EAAE;gBAClB,OAAO,EAAE,MAAM;gBACf,OAAO,EAAE,MAAM;aAChB;SACF,CAAC,CAAC;IACL,CAAC;IAED,MAAM,CAAC,KAAK,CAAC,OAAO,CAAC,WAAgC;QACnD,MAAM,WAAW,CAAC,YAAY,CAAC,WAAW,EAAE,CAAC;QAC7C,MAAM,WAAW,CAAC,YAAY,CAAC,WAAW,EAAE,CAAC;QAC7C,MAAM,WAAW,CAAC,UAAU,CAAC,GAAG,EAAE,CAAC;QACnC,MAAM,WAAW,CAAC,UAAU,CAAC,GAAG,EAAE,CAAC;IACrC,CAAC;CACF;AA3DD,8CA2DC"}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { Pool } from "pg";
|
|
2
|
+
import { EntityType } from "./types";
|
|
3
|
+
export declare class DependencyManager {
|
|
4
|
+
private readonly targetPool;
|
|
5
|
+
private readonly logger;
|
|
6
|
+
constructor(targetPool: Pool);
|
|
7
|
+
orderEntitiesByDependency(entities: EntityType[], schemaName: string): Promise<EntityType[]>;
|
|
8
|
+
private buildDependencyMap;
|
|
9
|
+
}
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.DependencyManager = void 0;
|
|
4
|
+
const common_1 = require("@nestjs/common");
|
|
5
|
+
class DependencyManager {
|
|
6
|
+
constructor(targetPool) {
|
|
7
|
+
this.targetPool = targetPool;
|
|
8
|
+
this.logger = new common_1.Logger("DependencyManager");
|
|
9
|
+
}
|
|
10
|
+
async orderEntitiesByDependency(entities, schemaName) {
|
|
11
|
+
try {
|
|
12
|
+
const dependencyMap = await this.buildDependencyMap(schemaName);
|
|
13
|
+
const graph = {};
|
|
14
|
+
for (const entity of entities) {
|
|
15
|
+
graph[entity.name] = [];
|
|
16
|
+
}
|
|
17
|
+
for (const [table, dependencies] of Object.entries(dependencyMap)) {
|
|
18
|
+
if (graph[table]) {
|
|
19
|
+
graph[table] = dependencies.filter(dep => graph[dep] !== undefined);
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
const visited = new Set();
|
|
23
|
+
const temp = new Set();
|
|
24
|
+
const order = [];
|
|
25
|
+
const visit = (node) => {
|
|
26
|
+
if (temp.has(node)) {
|
|
27
|
+
return;
|
|
28
|
+
}
|
|
29
|
+
if (!visited.has(node)) {
|
|
30
|
+
temp.add(node);
|
|
31
|
+
for (const neighbor of graph[node]) {
|
|
32
|
+
visit(neighbor);
|
|
33
|
+
}
|
|
34
|
+
temp.delete(node);
|
|
35
|
+
visited.add(node);
|
|
36
|
+
order.push(node);
|
|
37
|
+
}
|
|
38
|
+
};
|
|
39
|
+
for (const node of Object.keys(graph)) {
|
|
40
|
+
if (!visited.has(node)) {
|
|
41
|
+
visit(node);
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
order.reverse();
|
|
45
|
+
const orderedEntities = order
|
|
46
|
+
.map(name => entities.find(e => e.name === name))
|
|
47
|
+
.filter((e) => e !== undefined);
|
|
48
|
+
return orderedEntities;
|
|
49
|
+
}
|
|
50
|
+
catch (error) {
|
|
51
|
+
this.logger.error(`Error ordering entities by dependency: ${error.message}`);
|
|
52
|
+
return entities;
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
async buildDependencyMap(schemaName) {
|
|
56
|
+
const query = `
|
|
57
|
+
SELECT
|
|
58
|
+
tc.table_name,
|
|
59
|
+
ccu.table_name AS referenced_table
|
|
60
|
+
FROM
|
|
61
|
+
information_schema.table_constraints tc
|
|
62
|
+
JOIN information_schema.constraint_column_usage ccu
|
|
63
|
+
ON ccu.constraint_name = tc.constraint_name
|
|
64
|
+
AND ccu.table_schema = tc.table_schema
|
|
65
|
+
WHERE
|
|
66
|
+
tc.constraint_type = 'FOREIGN KEY'
|
|
67
|
+
AND tc.table_schema = $1
|
|
68
|
+
GROUP BY tc.table_name, ccu.table_name;
|
|
69
|
+
`;
|
|
70
|
+
const { rows } = await this.targetPool.query(query, [schemaName]);
|
|
71
|
+
const dependencyMap = {};
|
|
72
|
+
for (const row of rows) {
|
|
73
|
+
const table = row.table_name;
|
|
74
|
+
const referencedTable = row.referenced_table;
|
|
75
|
+
if (!dependencyMap[table]) {
|
|
76
|
+
dependencyMap[table] = [];
|
|
77
|
+
}
|
|
78
|
+
if (table !== referencedTable) {
|
|
79
|
+
dependencyMap[table].push(referencedTable);
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
return dependencyMap;
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
exports.DependencyManager = DependencyManager;
|
|
86
|
+
//# sourceMappingURL=dependency-manager.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"dependency-manager.js","sourceRoot":"","sources":["../../../src/scripts/data-migration/dependency-manager.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { Pool } from "pg";
|
|
2
|
+
export declare class DependencyResolver {
|
|
3
|
+
private readonly sourcePool;
|
|
4
|
+
private readonly targetPool;
|
|
5
|
+
private readonly logger;
|
|
6
|
+
private dependencyGraph;
|
|
7
|
+
constructor(sourcePool: Pool, targetPool: Pool);
|
|
8
|
+
analyzeDependencies(): Promise<string[]>;
|
|
9
|
+
private getManualDependencies;
|
|
10
|
+
private getTables;
|
|
11
|
+
private getForeignKeys;
|
|
12
|
+
private inferTableFromEnum;
|
|
13
|
+
private inferTableFromArrayColumn;
|
|
14
|
+
private extractJsonReferences;
|
|
15
|
+
private inferTableNameFromColumn;
|
|
16
|
+
private parseTableComment;
|
|
17
|
+
private assignLevels;
|
|
18
|
+
}
|
|
@@ -0,0 +1,251 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.DependencyResolver = void 0;
|
|
4
|
+
const common_1 = require("@nestjs/common");
|
|
5
|
+
class DependencyResolver {
|
|
6
|
+
constructor(sourcePool, targetPool) {
|
|
7
|
+
this.sourcePool = sourcePool;
|
|
8
|
+
this.targetPool = targetPool;
|
|
9
|
+
this.logger = new common_1.Logger("DependencyResolver");
|
|
10
|
+
this.dependencyGraph = new Map();
|
|
11
|
+
}
|
|
12
|
+
async analyzeDependencies() {
|
|
13
|
+
try {
|
|
14
|
+
const tables = await this.getTables();
|
|
15
|
+
for (const table of tables) {
|
|
16
|
+
const foreignKeys = await this.getForeignKeys(table);
|
|
17
|
+
const manualDependencies = this.getManualDependencies(table);
|
|
18
|
+
const allDependencies = [
|
|
19
|
+
...new Set([...foreignKeys, ...manualDependencies]),
|
|
20
|
+
];
|
|
21
|
+
this.dependencyGraph.set(table, {
|
|
22
|
+
table,
|
|
23
|
+
dependencies: allDependencies,
|
|
24
|
+
});
|
|
25
|
+
}
|
|
26
|
+
this.assignLevels();
|
|
27
|
+
const sortedTables = Array.from(this.dependencyGraph.values())
|
|
28
|
+
.sort((a, b) => (a.level || 0) - (b.level || 0))
|
|
29
|
+
.map((dep) => dep.table);
|
|
30
|
+
this.logger.log(`Migration order: ${sortedTables.join(" -> ")}`);
|
|
31
|
+
return sortedTables;
|
|
32
|
+
}
|
|
33
|
+
catch (error) {
|
|
34
|
+
this.logger.error(`Error analyzing dependencies: ${error.message}`);
|
|
35
|
+
throw error;
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
getManualDependencies(tableName) {
|
|
39
|
+
const manualDependencyMap = {
|
|
40
|
+
api_keys: ["users", "providers"],
|
|
41
|
+
balances: ["users"],
|
|
42
|
+
customers: ["users"],
|
|
43
|
+
global_user_transactions: ["users", "providers", "transactions"],
|
|
44
|
+
invoices: ["transactions"],
|
|
45
|
+
credit_requests: ["users", "invoices"],
|
|
46
|
+
notifications: ["users", "transactions"],
|
|
47
|
+
pending_references: ["users", "providers"],
|
|
48
|
+
daily_logs: ["transactions"],
|
|
49
|
+
transaction_updates: ["transactions"],
|
|
50
|
+
toku: ["transactions"],
|
|
51
|
+
providers: ["countries"],
|
|
52
|
+
users: ["countries"],
|
|
53
|
+
};
|
|
54
|
+
return manualDependencyMap[tableName] || [];
|
|
55
|
+
}
|
|
56
|
+
async getTables() {
|
|
57
|
+
const query = `
|
|
58
|
+
SELECT table_name
|
|
59
|
+
FROM information_schema.tables
|
|
60
|
+
WHERE table_schema = 'public'
|
|
61
|
+
AND table_type = 'BASE TABLE'
|
|
62
|
+
AND table_name NOT IN ('_prisma_migrations', 'schema_migrations')
|
|
63
|
+
`;
|
|
64
|
+
const result = await this.sourcePool.query(query);
|
|
65
|
+
return result.rows.map((row) => row.table_name);
|
|
66
|
+
}
|
|
67
|
+
async getForeignKeys(tableName) {
|
|
68
|
+
try {
|
|
69
|
+
const foreignKeyQuery = `
|
|
70
|
+
SELECT DISTINCT
|
|
71
|
+
ccu.table_name AS foreign_table_name,
|
|
72
|
+
kcu.column_name AS column_name
|
|
73
|
+
FROM
|
|
74
|
+
information_schema.table_constraints AS tc
|
|
75
|
+
JOIN information_schema.constraint_column_usage AS ccu
|
|
76
|
+
ON ccu.constraint_name = tc.constraint_name
|
|
77
|
+
JOIN information_schema.key_column_usage AS kcu
|
|
78
|
+
ON kcu.constraint_name = tc.constraint_name
|
|
79
|
+
WHERE
|
|
80
|
+
tc.constraint_type = 'FOREIGN KEY'
|
|
81
|
+
AND tc.table_name = $1
|
|
82
|
+
AND tc.table_schema = 'public'
|
|
83
|
+
`;
|
|
84
|
+
const implicitDependencyQuery = `
|
|
85
|
+
SELECT DISTINCT
|
|
86
|
+
c.column_name,
|
|
87
|
+
c.udt_name,
|
|
88
|
+
c.column_default,
|
|
89
|
+
c.data_type
|
|
90
|
+
FROM
|
|
91
|
+
information_schema.columns c
|
|
92
|
+
WHERE
|
|
93
|
+
c.table_schema = 'public'
|
|
94
|
+
AND c.table_name = $1
|
|
95
|
+
AND (
|
|
96
|
+
-- Common ID patterns
|
|
97
|
+
c.column_name LIKE '%_id'
|
|
98
|
+
OR c.column_name LIKE '%_ids'
|
|
99
|
+
OR c.column_name LIKE 'id_%'
|
|
100
|
+
-- Reference patterns
|
|
101
|
+
OR c.column_name LIKE '%_ref%'
|
|
102
|
+
OR c.column_name LIKE '%_key'
|
|
103
|
+
OR c.column_name LIKE '%_code'
|
|
104
|
+
-- Relationship patterns
|
|
105
|
+
OR c.column_name LIKE '%_by'
|
|
106
|
+
OR c.column_name LIKE '%_to'
|
|
107
|
+
OR c.column_name LIKE '%_from'
|
|
108
|
+
OR c.column_name LIKE 'parent_%'
|
|
109
|
+
OR c.column_name LIKE 'child_%'
|
|
110
|
+
-- JSON/JSONB columns that might contain references
|
|
111
|
+
OR (c.data_type IN ('json', 'jsonb') AND c.column_name LIKE '%_data')
|
|
112
|
+
-- Array columns that might contain IDs
|
|
113
|
+
OR (c.data_type = 'ARRAY' AND c.column_name LIKE '%_ids')
|
|
114
|
+
-- Enum columns that might indicate relationships
|
|
115
|
+
OR (c.udt_name LIKE 'enum_%' AND c.column_name LIKE '%_type')
|
|
116
|
+
)
|
|
117
|
+
`;
|
|
118
|
+
const referencedTablesQuery = `
|
|
119
|
+
SELECT DISTINCT
|
|
120
|
+
obj_description(c.table_name::regclass, 'pg_class') as table_comment
|
|
121
|
+
FROM
|
|
122
|
+
information_schema.columns c
|
|
123
|
+
WHERE
|
|
124
|
+
c.table_schema = 'public'
|
|
125
|
+
AND c.table_name = $1
|
|
126
|
+
`;
|
|
127
|
+
const [fkResult, implicitResult, referencedResult] = await Promise.all([
|
|
128
|
+
this.sourcePool.query(foreignKeyQuery, [tableName]),
|
|
129
|
+
this.sourcePool.query(implicitDependencyQuery, [tableName]),
|
|
130
|
+
this.sourcePool.query(referencedTablesQuery, [tableName]),
|
|
131
|
+
]);
|
|
132
|
+
const allDependencies = new Set();
|
|
133
|
+
fkResult.rows.forEach((row) => allDependencies.add(row.foreign_table_name));
|
|
134
|
+
implicitResult.rows.forEach((row) => {
|
|
135
|
+
const columnName = row.column_name;
|
|
136
|
+
const potentialTable = this.inferTableNameFromColumn(columnName);
|
|
137
|
+
if (potentialTable) {
|
|
138
|
+
allDependencies.add(potentialTable);
|
|
139
|
+
}
|
|
140
|
+
});
|
|
141
|
+
referencedResult.rows.forEach((row) => {
|
|
142
|
+
if (row.table_comment) {
|
|
143
|
+
const referencedTables = this.parseTableComment(row.table_comment);
|
|
144
|
+
referencedTables.forEach((table) => allDependencies.add(table));
|
|
145
|
+
}
|
|
146
|
+
});
|
|
147
|
+
implicitResult.rows.forEach((row) => {
|
|
148
|
+
var _a;
|
|
149
|
+
if (row.data_type === "json" || row.data_type === "jsonb") {
|
|
150
|
+
const potentialRefs = this.extractJsonReferences(row.column_name);
|
|
151
|
+
potentialRefs.forEach((ref) => allDependencies.add(ref));
|
|
152
|
+
}
|
|
153
|
+
if ((_a = row.udt_name) === null || _a === void 0 ? void 0 : _a.startsWith("enum_")) {
|
|
154
|
+
const enumTable = this.inferTableFromEnum(row.udt_name);
|
|
155
|
+
if (enumTable)
|
|
156
|
+
allDependencies.add(enumTable);
|
|
157
|
+
}
|
|
158
|
+
if (row.data_type === "ARRAY") {
|
|
159
|
+
const arrayTable = this.inferTableFromArrayColumn(row.column_name);
|
|
160
|
+
if (arrayTable)
|
|
161
|
+
allDependencies.add(arrayTable);
|
|
162
|
+
}
|
|
163
|
+
});
|
|
164
|
+
return Array.from(allDependencies);
|
|
165
|
+
}
|
|
166
|
+
catch (error) {
|
|
167
|
+
this.logger.error(`Error getting dependencies for ${tableName}: ${error.message}`);
|
|
168
|
+
return [];
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
inferTableFromEnum(enumType) {
|
|
172
|
+
const parts = enumType.split("_");
|
|
173
|
+
if (parts.length > 1) {
|
|
174
|
+
return parts[1];
|
|
175
|
+
}
|
|
176
|
+
return null;
|
|
177
|
+
}
|
|
178
|
+
inferTableFromArrayColumn(columnName) {
|
|
179
|
+
if (columnName.endsWith("_ids")) {
|
|
180
|
+
return columnName.slice(0, -4) + "s";
|
|
181
|
+
}
|
|
182
|
+
return null;
|
|
183
|
+
}
|
|
184
|
+
extractJsonReferences(columnName) {
|
|
185
|
+
const refs = [];
|
|
186
|
+
const parts = columnName.split("_");
|
|
187
|
+
if (parts.length > 1) {
|
|
188
|
+
const potentialTable = parts[0] + "s";
|
|
189
|
+
refs.push(potentialTable);
|
|
190
|
+
}
|
|
191
|
+
return refs;
|
|
192
|
+
}
|
|
193
|
+
inferTableNameFromColumn(columnName) {
|
|
194
|
+
const suffixes = ["_id", "_by", "_ref", "_fk"];
|
|
195
|
+
let tableName = columnName;
|
|
196
|
+
for (const suffix of suffixes) {
|
|
197
|
+
if (tableName.endsWith(suffix)) {
|
|
198
|
+
tableName = tableName.slice(0, -suffix.length);
|
|
199
|
+
break;
|
|
200
|
+
}
|
|
201
|
+
}
|
|
202
|
+
if (!tableName.endsWith("s")) {
|
|
203
|
+
tableName += "s";
|
|
204
|
+
}
|
|
205
|
+
return tableName;
|
|
206
|
+
}
|
|
207
|
+
parseTableComment(comment) {
|
|
208
|
+
const referencesMatch = comment.match(/References:\s*([^;]+)/i);
|
|
209
|
+
if (referencesMatch) {
|
|
210
|
+
return referencesMatch[1]
|
|
211
|
+
.split(",")
|
|
212
|
+
.map((table) => table.trim())
|
|
213
|
+
.filter((table) => table.length > 0);
|
|
214
|
+
}
|
|
215
|
+
return [];
|
|
216
|
+
}
|
|
217
|
+
assignLevels() {
|
|
218
|
+
const visited = new Set();
|
|
219
|
+
const visiting = new Set();
|
|
220
|
+
const visit = (tableName, level = 0) => {
|
|
221
|
+
var _a;
|
|
222
|
+
if (visiting.has(tableName)) {
|
|
223
|
+
this.logger.warn(`Circular dependency detected involving table: ${tableName}`);
|
|
224
|
+
return level;
|
|
225
|
+
}
|
|
226
|
+
if (visited.has(tableName)) {
|
|
227
|
+
return ((_a = this.dependencyGraph.get(tableName)) === null || _a === void 0 ? void 0 : _a.level) || 0;
|
|
228
|
+
}
|
|
229
|
+
visiting.add(tableName);
|
|
230
|
+
const node = this.dependencyGraph.get(tableName);
|
|
231
|
+
if (!node)
|
|
232
|
+
return level;
|
|
233
|
+
let maxDepLevel = level;
|
|
234
|
+
for (const dep of node.dependencies) {
|
|
235
|
+
const depLevel = visit(dep, level + 1);
|
|
236
|
+
maxDepLevel = Math.max(maxDepLevel, depLevel + 1);
|
|
237
|
+
}
|
|
238
|
+
node.level = maxDepLevel;
|
|
239
|
+
visited.add(tableName);
|
|
240
|
+
visiting.delete(tableName);
|
|
241
|
+
return maxDepLevel;
|
|
242
|
+
};
|
|
243
|
+
for (const tableName of this.dependencyGraph.keys()) {
|
|
244
|
+
if (!visited.has(tableName)) {
|
|
245
|
+
visit(tableName);
|
|
246
|
+
}
|
|
247
|
+
}
|
|
248
|
+
}
|
|
249
|
+
}
|
|
250
|
+
exports.DependencyResolver = DependencyResolver;
|
|
251
|
+
//# sourceMappingURL=dependency-resolver.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"dependency-resolver.js","sourceRoot":"","sources":["../../../src/scripts/data-migration/dependency-resolver.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { Pool } from "pg";
|
|
2
|
+
import { EntityType } from "./types";
|
|
3
|
+
export declare class EntityDiscovery {
|
|
4
|
+
private readonly targetPool;
|
|
5
|
+
private readonly logger;
|
|
6
|
+
constructor(targetPool: Pool);
|
|
7
|
+
discoverEntityTypes(schemaName: string, tables: string[]): Promise<EntityType[]>;
|
|
8
|
+
private getPrimaryKey;
|
|
9
|
+
private getForeignKeys;
|
|
10
|
+
private findJoinTables;
|
|
11
|
+
}
|
|
@@ -0,0 +1,152 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.EntityDiscovery = void 0;
|
|
4
|
+
const common_1 = require("@nestjs/common");
|
|
5
|
+
class EntityDiscovery {
|
|
6
|
+
constructor(targetPool) {
|
|
7
|
+
this.targetPool = targetPool;
|
|
8
|
+
this.logger = new common_1.Logger("EntityDiscovery");
|
|
9
|
+
}
|
|
10
|
+
async discoverEntityTypes(schemaName, tables) {
|
|
11
|
+
try {
|
|
12
|
+
const entityTypes = [];
|
|
13
|
+
for (const tableName of tables) {
|
|
14
|
+
const primaryKey = await this.getPrimaryKey(schemaName, tableName);
|
|
15
|
+
if (!primaryKey) {
|
|
16
|
+
this.logger.warn(`No primary key found for table ${tableName}, skipping`);
|
|
17
|
+
continue;
|
|
18
|
+
}
|
|
19
|
+
const foreignKeys = await this.getForeignKeys(schemaName, tableName);
|
|
20
|
+
const providerForeignKey = foreignKeys.find(fk => fk.column_name.includes('provider_id') ||
|
|
21
|
+
fk.foreign_table_name === 'providers');
|
|
22
|
+
const entity = {
|
|
23
|
+
name: tableName,
|
|
24
|
+
idField: primaryKey,
|
|
25
|
+
foreignKey: providerForeignKey === null || providerForeignKey === void 0 ? void 0 : providerForeignKey.column_name,
|
|
26
|
+
};
|
|
27
|
+
if (!entity.foreignKey) {
|
|
28
|
+
const joinTables = await this.findJoinTables(schemaName, tableName, 'providers');
|
|
29
|
+
if (joinTables.length > 0) {
|
|
30
|
+
const joinTable = joinTables[0];
|
|
31
|
+
entity.joinTable = joinTable.join_table;
|
|
32
|
+
entity.joinField = joinTable.source_column;
|
|
33
|
+
entity.joinForeignKey = joinTable.target_column;
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
entityTypes.push(entity);
|
|
37
|
+
}
|
|
38
|
+
return entityTypes;
|
|
39
|
+
}
|
|
40
|
+
catch (error) {
|
|
41
|
+
this.logger.error(`Error discovering entity types: ${error.message}`);
|
|
42
|
+
return [];
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
async getPrimaryKey(schemaName, tableName) {
|
|
46
|
+
const query = `
|
|
47
|
+
SELECT a.attname
|
|
48
|
+
FROM pg_index i
|
|
49
|
+
JOIN pg_attribute a ON a.attrelid = i.indrelid
|
|
50
|
+
AND a.attnum = ANY(i.indkey)
|
|
51
|
+
WHERE i.indrelid = '"${schemaName}"."${tableName}"'::regclass
|
|
52
|
+
AND i.indisprimary;
|
|
53
|
+
`;
|
|
54
|
+
try {
|
|
55
|
+
const { rows } = await this.targetPool.query(query);
|
|
56
|
+
return rows.length > 0 ? rows[0].attname : null;
|
|
57
|
+
}
|
|
58
|
+
catch (error) {
|
|
59
|
+
this.logger.error(`Error getting primary key for ${tableName}: ${error.message}`);
|
|
60
|
+
return null;
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
async getForeignKeys(schemaName, tableName) {
|
|
64
|
+
const query = `
|
|
65
|
+
SELECT
|
|
66
|
+
kcu.column_name,
|
|
67
|
+
ccu.table_name AS foreign_table_name,
|
|
68
|
+
ccu.column_name AS foreign_column_name
|
|
69
|
+
FROM
|
|
70
|
+
information_schema.table_constraints tc
|
|
71
|
+
JOIN information_schema.key_column_usage kcu
|
|
72
|
+
ON tc.constraint_name = kcu.constraint_name
|
|
73
|
+
AND tc.table_schema = kcu.table_schema
|
|
74
|
+
JOIN information_schema.constraint_column_usage ccu
|
|
75
|
+
ON ccu.constraint_name = tc.constraint_name
|
|
76
|
+
AND ccu.table_schema = tc.table_schema
|
|
77
|
+
WHERE
|
|
78
|
+
tc.constraint_type = 'FOREIGN KEY'
|
|
79
|
+
AND tc.table_schema = $1
|
|
80
|
+
AND tc.table_name = $2;
|
|
81
|
+
`;
|
|
82
|
+
try {
|
|
83
|
+
const { rows } = await this.targetPool.query(query, [schemaName, tableName]);
|
|
84
|
+
return rows;
|
|
85
|
+
}
|
|
86
|
+
catch (error) {
|
|
87
|
+
this.logger.error(`Error getting foreign keys for ${tableName}: ${error.message}`);
|
|
88
|
+
return [];
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
async findJoinTables(schemaName, sourceTable, targetTable) {
|
|
92
|
+
const query = `
|
|
93
|
+
WITH source_fks AS (
|
|
94
|
+
SELECT
|
|
95
|
+
tc.table_name,
|
|
96
|
+
kcu.column_name,
|
|
97
|
+
ccu.table_name AS referenced_table
|
|
98
|
+
FROM
|
|
99
|
+
information_schema.table_constraints tc
|
|
100
|
+
JOIN information_schema.key_column_usage kcu
|
|
101
|
+
ON tc.constraint_name = kcu.constraint_name
|
|
102
|
+
AND tc.table_schema = kcu.table_schema
|
|
103
|
+
JOIN information_schema.constraint_column_usage ccu
|
|
104
|
+
ON ccu.constraint_name = tc.constraint_name
|
|
105
|
+
AND ccu.table_schema = tc.table_schema
|
|
106
|
+
WHERE
|
|
107
|
+
tc.constraint_type = 'FOREIGN KEY'
|
|
108
|
+
AND tc.table_schema = $1
|
|
109
|
+
AND ccu.table_name = $2
|
|
110
|
+
),
|
|
111
|
+
target_fks AS (
|
|
112
|
+
SELECT
|
|
113
|
+
tc.table_name,
|
|
114
|
+
kcu.column_name,
|
|
115
|
+
ccu.table_name AS referenced_table
|
|
116
|
+
FROM
|
|
117
|
+
information_schema.table_constraints tc
|
|
118
|
+
JOIN information_schema.key_column_usage kcu
|
|
119
|
+
ON tc.constraint_name = kcu.constraint_name
|
|
120
|
+
AND tc.table_schema = kcu.table_schema
|
|
121
|
+
JOIN information_schema.constraint_column_usage ccu
|
|
122
|
+
ON ccu.constraint_name = tc.constraint_name
|
|
123
|
+
AND ccu.table_schema = tc.table_schema
|
|
124
|
+
WHERE
|
|
125
|
+
tc.constraint_type = 'FOREIGN KEY'
|
|
126
|
+
AND tc.table_schema = $1
|
|
127
|
+
AND ccu.table_name = $3
|
|
128
|
+
)
|
|
129
|
+
SELECT
|
|
130
|
+
s.table_name AS join_table,
|
|
131
|
+
s.column_name AS source_column,
|
|
132
|
+
t.column_name AS target_column
|
|
133
|
+
FROM
|
|
134
|
+
source_fks s
|
|
135
|
+
JOIN target_fks t ON s.table_name = t.table_name
|
|
136
|
+
`;
|
|
137
|
+
try {
|
|
138
|
+
const { rows } = await this.targetPool.query(query, [
|
|
139
|
+
schemaName,
|
|
140
|
+
sourceTable,
|
|
141
|
+
targetTable,
|
|
142
|
+
]);
|
|
143
|
+
return rows;
|
|
144
|
+
}
|
|
145
|
+
catch (error) {
|
|
146
|
+
this.logger.error(`Error finding join tables between ${sourceTable} and ${targetTable}: ${error.message}`);
|
|
147
|
+
return [];
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
exports.EntityDiscovery = EntityDiscovery;
|
|
152
|
+
//# sourceMappingURL=entity-discovery.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"entity-discovery.js","sourceRoot":"","sources":["../../../src/scripts/data-migration/entity-discovery.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { PrismaClient } from "@prisma/client";
|
|
2
|
+
import { DatabaseConnections } from "./types";
|
|
3
|
+
export declare class ForeignKeyManager {
|
|
4
|
+
private readonly connections;
|
|
5
|
+
private readonly logger;
|
|
6
|
+
constructor(connections: DatabaseConnections);
|
|
7
|
+
getForeignKeyDependencies(schemaName: string, tableName: string): Promise<Array<{
|
|
8
|
+
column: string;
|
|
9
|
+
foreignTable: string;
|
|
10
|
+
foreignColumn: string;
|
|
11
|
+
}>>;
|
|
12
|
+
checkForeignKeyDependencies(prisma: PrismaClient, schemaName: string, row: any, dependencies: Array<{
|
|
13
|
+
column: string;
|
|
14
|
+
foreignTable: string;
|
|
15
|
+
foreignColumn: string;
|
|
16
|
+
}>): Promise<string[]>;
|
|
17
|
+
}
|