@javalabs/prisma-client 1.0.18 → 1.0.20
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/.github/CODEOWNERS +1 -0
- package/README.md +269 -269
- package/dist/index.d.ts +1 -1
- package/dist/prisma.service.d.ts +1 -1
- package/dist/scripts/add-uuid-to-table.js +32 -32
- package/dist/scripts/data-migration/batch-migrator.js +12 -12
- package/dist/scripts/data-migration/data-transformer.js +14 -14
- package/dist/scripts/data-migration/dependency-resolver.js +23 -23
- package/dist/scripts/data-migration/entity-discovery.js +68 -68
- package/dist/scripts/data-migration/foreign-key-manager.js +23 -23
- package/dist/scripts/data-migration/migration-tool.js +5 -5
- package/dist/scripts/data-migration/schema-utils.js +74 -74
- package/dist/scripts/data-migration/typecast-manager.js +4 -4
- package/dist/scripts/database-initializer.js +5 -5
- package/dist/scripts/drop-database.js +5 -5
- package/dist/scripts/fix-data-types.js +53 -53
- package/dist/scripts/fix-enum-values.js +34 -34
- package/dist/scripts/fix-schema-discrepancies.js +40 -40
- package/dist/scripts/fix-table-indexes.js +81 -81
- package/dist/scripts/migrate-schema-structure.js +4 -4
- package/dist/scripts/migrate-uuid.js +19 -19
- package/dist/scripts/post-migration-validator.js +49 -49
- package/dist/scripts/pre-migration-validator.js +107 -107
- package/dist/scripts/reset-database.js +21 -21
- package/dist/scripts/retry-failed-migrations.js +28 -28
- package/dist/scripts/run-migration.js +5 -5
- package/dist/scripts/schema-sync.js +18 -18
- package/dist/scripts/sequence-sync-cli.js +55 -55
- package/dist/scripts/sequence-synchronizer.js +20 -20
- package/dist/scripts/sync-enum-types.js +30 -30
- package/dist/scripts/sync-enum-values.js +52 -52
- package/dist/scripts/truncate-database.js +10 -10
- package/dist/scripts/verify-migration-setup.js +10 -10
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/migration-config.json +63 -63
- package/migration-config.json.bk +95 -95
- package/migrations/add_reserved_amount.sql +8 -0
- package/package.json +44 -44
- package/prisma/migrations/add_uuid_to_transactions.sql +13 -13
- package/prisma/schema.prisma +601 -554
- package/src/index.ts +23 -23
- package/src/prisma-factory.service.ts +40 -40
- package/src/prisma.module.ts +9 -9
- package/src/prisma.service.ts +16 -16
- package/src/scripts/add-uuid-to-table.ts +138 -138
- package/src/scripts/create-tenant-schemas.ts +145 -145
- package/src/scripts/data-migration/batch-migrator.ts +248 -248
- package/src/scripts/data-migration/data-transformer.ts +426 -426
- package/src/scripts/data-migration/db-connector.ts +120 -120
- package/src/scripts/data-migration/dependency-resolver.ts +174 -174
- package/src/scripts/data-migration/entity-discovery.ts +196 -196
- package/src/scripts/data-migration/foreign-key-manager.ts +277 -277
- package/src/scripts/data-migration/migration-config.json +63 -63
- package/src/scripts/data-migration/migration-tool.ts +509 -509
- package/src/scripts/data-migration/schema-utils.ts +248 -248
- package/src/scripts/data-migration/tenant-migrator.ts +201 -201
- package/src/scripts/data-migration/typecast-manager.ts +193 -193
- package/src/scripts/data-migration/types.ts +113 -113
- package/src/scripts/database-initializer.ts +49 -49
- package/src/scripts/drop-database.ts +104 -104
- package/src/scripts/dump-source-db.sh +61 -61
- package/src/scripts/encrypt-user-passwords.ts +36 -36
- package/src/scripts/error-handler.ts +117 -117
- package/src/scripts/fix-data-types.ts +241 -241
- package/src/scripts/fix-enum-values.ts +357 -357
- package/src/scripts/fix-schema-discrepancies.ts +317 -317
- package/src/scripts/fix-table-indexes.ts +601 -601
- package/src/scripts/migrate-schema-structure.ts +90 -90
- package/src/scripts/migrate-uuid.ts +76 -76
- package/src/scripts/post-migration-validator.ts +526 -526
- package/src/scripts/pre-migration-validator.ts +610 -610
- package/src/scripts/reset-database.ts +263 -263
- package/src/scripts/retry-failed-migrations.ts +416 -416
- package/src/scripts/run-migration.ts +707 -707
- package/src/scripts/schema-sync.ts +128 -128
- package/src/scripts/sequence-sync-cli.ts +416 -416
- package/src/scripts/sequence-synchronizer.ts +127 -127
- package/src/scripts/sync-enum-types.ts +170 -170
- package/src/scripts/sync-enum-values.ts +563 -563
- package/src/scripts/truncate-database.ts +123 -123
- package/src/scripts/verify-migration-setup.ts +135 -135
- package/tsconfig.json +17 -17
- package/dist/scripts/data-migration/dependency-manager.d.ts +0 -9
- package/dist/scripts/data-migration/dependency-manager.js +0 -86
- package/dist/scripts/data-migration/dependency-manager.js.map +0 -1
- package/dist/scripts/data-migration/migration-config.json +0 -63
- package/dist/scripts/data-migration/migration-phases.d.ts +0 -5
- package/dist/scripts/data-migration/migration-phases.js +0 -55
- package/dist/scripts/data-migration/migration-phases.js.map +0 -1
- package/dist/scripts/data-migration/multi-source-migrator.d.ts +0 -17
- package/dist/scripts/data-migration/multi-source-migrator.js +0 -130
- package/dist/scripts/data-migration/multi-source-migrator.js.map +0 -1
- package/dist/scripts/data-migration/phase-generator.d.ts +0 -15
- package/dist/scripts/data-migration/phase-generator.js +0 -187
- package/dist/scripts/data-migration/phase-generator.js.map +0 -1
- package/dist/scripts/data-migration.d.ts +0 -22
- package/dist/scripts/data-migration.js +0 -593
- package/dist/scripts/data-migration.js.map +0 -1
- package/dist/scripts/multi-db-migration.d.ts +0 -1
- package/dist/scripts/multi-db-migration.js +0 -55
- package/dist/scripts/multi-db-migration.js.map +0 -1
|
@@ -18,11 +18,11 @@ class DataTypeFixer {
|
|
|
18
18
|
async fixDataTypes() {
|
|
19
19
|
try {
|
|
20
20
|
this.logger.log("Starting data type fixing process");
|
|
21
|
-
const schemasQuery = `
|
|
22
|
-
SELECT schema_name
|
|
23
|
-
FROM information_schema.schemata
|
|
24
|
-
WHERE schema_name NOT IN ('public', 'information_schema', 'pg_catalog', 'pg_toast')
|
|
25
|
-
AND schema_name NOT LIKE 'pg_%';
|
|
21
|
+
const schemasQuery = `
|
|
22
|
+
SELECT schema_name
|
|
23
|
+
FROM information_schema.schemata
|
|
24
|
+
WHERE schema_name NOT IN ('public', 'information_schema', 'pg_catalog', 'pg_toast')
|
|
25
|
+
AND schema_name NOT LIKE 'pg_%';
|
|
26
26
|
`;
|
|
27
27
|
const schemasResult = await this.targetPool.query(schemasQuery);
|
|
28
28
|
const schemas = schemasResult.rows.map(row => row.schema_name);
|
|
@@ -43,31 +43,31 @@ class DataTypeFixer {
|
|
|
43
43
|
async fixNumericFieldsForSchema(schema) {
|
|
44
44
|
this.logger.log(`Processing numeric fields for schema: ${schema}`);
|
|
45
45
|
try {
|
|
46
|
-
const numericColumnsQuery = `
|
|
47
|
-
SELECT
|
|
48
|
-
table_name,
|
|
49
|
-
column_name
|
|
50
|
-
FROM
|
|
51
|
-
information_schema.columns
|
|
52
|
-
WHERE
|
|
53
|
-
table_schema = $1
|
|
54
|
-
AND data_type = 'numeric'
|
|
46
|
+
const numericColumnsQuery = `
|
|
47
|
+
SELECT
|
|
48
|
+
table_name,
|
|
49
|
+
column_name
|
|
50
|
+
FROM
|
|
51
|
+
information_schema.columns
|
|
52
|
+
WHERE
|
|
53
|
+
table_schema = $1
|
|
54
|
+
AND data_type = 'numeric'
|
|
55
55
|
`;
|
|
56
56
|
const numericColumnsResult = await this.targetPool.query(numericColumnsQuery, [schema]);
|
|
57
57
|
for (const row of numericColumnsResult.rows) {
|
|
58
58
|
const tableName = row.table_name;
|
|
59
59
|
const columnName = row.column_name;
|
|
60
60
|
this.logger.log(`Fixing numeric column ${columnName} in table ${schema}.${tableName}`);
|
|
61
|
-
const updateQuery = `
|
|
62
|
-
UPDATE "${schema}"."${tableName}"
|
|
63
|
-
SET "${columnName}" = CASE
|
|
64
|
-
WHEN "${columnName}" IS NULL THEN NULL
|
|
65
|
-
WHEN "${columnName}" = '' THEN NULL
|
|
66
|
-
ELSE CAST("${columnName}" AS NUMERIC)
|
|
67
|
-
END
|
|
68
|
-
WHERE "${columnName}" IS NOT NULL
|
|
69
|
-
AND "${columnName}" != ''
|
|
70
|
-
AND "${columnName}" ~ '^[0-9]+(\.[0-9]+)?$';
|
|
61
|
+
const updateQuery = `
|
|
62
|
+
UPDATE "${schema}"."${tableName}"
|
|
63
|
+
SET "${columnName}" = CASE
|
|
64
|
+
WHEN "${columnName}" IS NULL THEN NULL
|
|
65
|
+
WHEN "${columnName}" = '' THEN NULL
|
|
66
|
+
ELSE CAST("${columnName}" AS NUMERIC)
|
|
67
|
+
END
|
|
68
|
+
WHERE "${columnName}" IS NOT NULL
|
|
69
|
+
AND "${columnName}" != ''
|
|
70
|
+
AND "${columnName}" ~ '^[0-9]+(\.[0-9]+)?$';
|
|
71
71
|
`;
|
|
72
72
|
try {
|
|
73
73
|
await this.targetPool.query(updateQuery);
|
|
@@ -86,17 +86,17 @@ class DataTypeFixer {
|
|
|
86
86
|
async fixEnumFieldsForSchema(schema) {
|
|
87
87
|
this.logger.log(`Processing enum fields for schema: ${schema}`);
|
|
88
88
|
try {
|
|
89
|
-
const enumColumnsQuery = `
|
|
90
|
-
SELECT
|
|
91
|
-
c.table_name,
|
|
92
|
-
c.column_name,
|
|
93
|
-
c.udt_name
|
|
94
|
-
FROM
|
|
95
|
-
information_schema.columns c
|
|
96
|
-
WHERE
|
|
97
|
-
c.table_schema = $1
|
|
98
|
-
AND c.data_type = 'USER-DEFINED'
|
|
99
|
-
AND c.udt_name LIKE 'enum_%'
|
|
89
|
+
const enumColumnsQuery = `
|
|
90
|
+
SELECT
|
|
91
|
+
c.table_name,
|
|
92
|
+
c.column_name,
|
|
93
|
+
c.udt_name
|
|
94
|
+
FROM
|
|
95
|
+
information_schema.columns c
|
|
96
|
+
WHERE
|
|
97
|
+
c.table_schema = $1
|
|
98
|
+
AND c.data_type = 'USER-DEFINED'
|
|
99
|
+
AND c.udt_name LIKE 'enum_%'
|
|
100
100
|
`;
|
|
101
101
|
const enumColumnsResult = await this.targetPool.query(enumColumnsQuery, [schema]);
|
|
102
102
|
for (const row of enumColumnsResult.rows) {
|
|
@@ -104,12 +104,12 @@ class DataTypeFixer {
|
|
|
104
104
|
const columnName = row.column_name;
|
|
105
105
|
const enumTypeName = row.udt_name;
|
|
106
106
|
this.logger.log(`Fixing enum column ${columnName} (${enumTypeName}) in table ${schema}.${tableName}`);
|
|
107
|
-
const enumValuesQuery = `
|
|
108
|
-
SELECT e.enumlabel
|
|
109
|
-
FROM pg_enum e
|
|
110
|
-
JOIN pg_type t ON e.enumtypid = t.oid
|
|
111
|
-
WHERE t.typname = $1
|
|
112
|
-
ORDER BY e.enumsortorder
|
|
107
|
+
const enumValuesQuery = `
|
|
108
|
+
SELECT e.enumlabel
|
|
109
|
+
FROM pg_enum e
|
|
110
|
+
JOIN pg_type t ON e.enumtypid = t.oid
|
|
111
|
+
WHERE t.typname = $1
|
|
112
|
+
ORDER BY e.enumsortorder
|
|
113
113
|
`;
|
|
114
114
|
const enumValuesResult = await this.targetPool.query(enumValuesQuery, [enumTypeName]);
|
|
115
115
|
const validEnumValues = enumValuesResult.rows.map(r => r.enumlabel);
|
|
@@ -118,10 +118,10 @@ class DataTypeFixer {
|
|
|
118
118
|
continue;
|
|
119
119
|
}
|
|
120
120
|
this.logger.log(`Valid values for ${enumTypeName}: ${validEnumValues.join(', ')}`);
|
|
121
|
-
const currentValuesQuery = `
|
|
122
|
-
SELECT DISTINCT "${columnName}"
|
|
123
|
-
FROM "${schema}"."${tableName}"
|
|
124
|
-
WHERE "${columnName}" IS NOT NULL
|
|
121
|
+
const currentValuesQuery = `
|
|
122
|
+
SELECT DISTINCT "${columnName}"
|
|
123
|
+
FROM "${schema}"."${tableName}"
|
|
124
|
+
WHERE "${columnName}" IS NOT NULL
|
|
125
125
|
`;
|
|
126
126
|
const currentValuesResult = await this.targetPool.query(currentValuesQuery);
|
|
127
127
|
const currentValues = currentValuesResult.rows.map(r => r[columnName]);
|
|
@@ -132,19 +132,19 @@ class DataTypeFixer {
|
|
|
132
132
|
const matchingValidValue = validEnumValues.find(v => v.toLowerCase() === invalidValue.toLowerCase());
|
|
133
133
|
let updateQuery;
|
|
134
134
|
if (matchingValidValue) {
|
|
135
|
-
updateQuery = `
|
|
136
|
-
UPDATE "${schema}"."${tableName}"
|
|
137
|
-
SET "${columnName}" = $1
|
|
138
|
-
WHERE "${columnName}" = $2
|
|
135
|
+
updateQuery = `
|
|
136
|
+
UPDATE "${schema}"."${tableName}"
|
|
137
|
+
SET "${columnName}" = $1
|
|
138
|
+
WHERE "${columnName}" = $2
|
|
139
139
|
`;
|
|
140
140
|
await this.targetPool.query(updateQuery, [matchingValidValue, invalidValue]);
|
|
141
141
|
this.logger.log(`Updated invalid value "${invalidValue}" to "${matchingValidValue}"`);
|
|
142
142
|
}
|
|
143
143
|
else {
|
|
144
|
-
updateQuery = `
|
|
145
|
-
UPDATE "${schema}"."${tableName}"
|
|
146
|
-
SET "${columnName}" = NULL
|
|
147
|
-
WHERE "${columnName}" = $1
|
|
144
|
+
updateQuery = `
|
|
145
|
+
UPDATE "${schema}"."${tableName}"
|
|
146
|
+
SET "${columnName}" = NULL
|
|
147
|
+
WHERE "${columnName}" = $1
|
|
148
148
|
`;
|
|
149
149
|
await this.targetPool.query(updateQuery, [invalidValue]);
|
|
150
150
|
this.logger.log(`Set invalid value "${invalidValue}" to NULL`);
|
|
@@ -52,28 +52,28 @@ class EnumFixer {
|
|
|
52
52
|
}
|
|
53
53
|
}
|
|
54
54
|
async getSchemas() {
|
|
55
|
-
const result = await this.pool.query(`
|
|
56
|
-
SELECT schema_name
|
|
57
|
-
FROM information_schema.schemata
|
|
58
|
-
WHERE schema_name NOT IN ('information_schema', 'pg_catalog', 'pg_toast')
|
|
59
|
-
AND schema_name NOT LIKE 'pg_%'
|
|
55
|
+
const result = await this.pool.query(`
|
|
56
|
+
SELECT schema_name
|
|
57
|
+
FROM information_schema.schemata
|
|
58
|
+
WHERE schema_name NOT IN ('information_schema', 'pg_catalog', 'pg_toast')
|
|
59
|
+
AND schema_name NOT LIKE 'pg_%'
|
|
60
60
|
`);
|
|
61
61
|
return result.rows.map((row) => row.schema_name);
|
|
62
62
|
}
|
|
63
63
|
async fixEnumValuesForSchema(schema) {
|
|
64
64
|
this.logger.log(`Processing enum fields for schema: ${schema}`);
|
|
65
65
|
try {
|
|
66
|
-
const enumColumnsQuery = `
|
|
67
|
-
SELECT
|
|
68
|
-
c.table_name,
|
|
69
|
-
c.column_name,
|
|
70
|
-
c.udt_name
|
|
71
|
-
FROM
|
|
72
|
-
information_schema.columns c
|
|
73
|
-
WHERE
|
|
74
|
-
c.table_schema = $1
|
|
75
|
-
AND c.data_type = 'USER-DEFINED'
|
|
76
|
-
AND c.udt_name LIKE 'enum_%'
|
|
66
|
+
const enumColumnsQuery = `
|
|
67
|
+
SELECT
|
|
68
|
+
c.table_name,
|
|
69
|
+
c.column_name,
|
|
70
|
+
c.udt_name
|
|
71
|
+
FROM
|
|
72
|
+
information_schema.columns c
|
|
73
|
+
WHERE
|
|
74
|
+
c.table_schema = $1
|
|
75
|
+
AND c.data_type = 'USER-DEFINED'
|
|
76
|
+
AND c.udt_name LIKE 'enum_%'
|
|
77
77
|
`;
|
|
78
78
|
const enumColumnsResult = await this.pool.query(enumColumnsQuery, [
|
|
79
79
|
schema,
|
|
@@ -111,10 +111,10 @@ class EnumFixer {
|
|
|
111
111
|
return;
|
|
112
112
|
}
|
|
113
113
|
this.logger.log(`Valid values for ${enumTypeName}: ${validEnumValues.join(", ")}`);
|
|
114
|
-
const currentValuesQuery = `
|
|
115
|
-
SELECT DISTINCT "${columnName}"
|
|
116
|
-
FROM "${schema}"."${tableName}"
|
|
117
|
-
WHERE "${columnName}" IS NOT NULL
|
|
114
|
+
const currentValuesQuery = `
|
|
115
|
+
SELECT DISTINCT "${columnName}"
|
|
116
|
+
FROM "${schema}"."${tableName}"
|
|
117
|
+
WHERE "${columnName}" IS NOT NULL
|
|
118
118
|
`;
|
|
119
119
|
const currentValuesResult = await this.pool.query(currentValuesQuery);
|
|
120
120
|
const currentValues = currentValuesResult.rows.map((r) => r[columnName]);
|
|
@@ -162,15 +162,15 @@ class EnumFixer {
|
|
|
162
162
|
}
|
|
163
163
|
}
|
|
164
164
|
const updateQuery = mappedValue !== null
|
|
165
|
-
? `
|
|
166
|
-
UPDATE "${schema}"."${tableName}"
|
|
167
|
-
SET "${columnName}" = CAST($1 AS "${enumTypeName}")
|
|
168
|
-
WHERE "${columnName}" = $2
|
|
165
|
+
? `
|
|
166
|
+
UPDATE "${schema}"."${tableName}"
|
|
167
|
+
SET "${columnName}" = CAST($1 AS "${enumTypeName}")
|
|
168
|
+
WHERE "${columnName}" = $2
|
|
169
169
|
`
|
|
170
|
-
: `
|
|
171
|
-
UPDATE "${schema}"."${tableName}"
|
|
172
|
-
SET "${columnName}" = NULL
|
|
173
|
-
WHERE "${columnName}" = $1
|
|
170
|
+
: `
|
|
171
|
+
UPDATE "${schema}"."${tableName}"
|
|
172
|
+
SET "${columnName}" = NULL
|
|
173
|
+
WHERE "${columnName}" = $1
|
|
174
174
|
`;
|
|
175
175
|
const updateParams = mappedValue !== null ? [mappedValue, invalidValue] : [invalidValue];
|
|
176
176
|
const updateResult = await this.pool.query(updateQuery, updateParams);
|
|
@@ -183,12 +183,12 @@ class EnumFixer {
|
|
|
183
183
|
}
|
|
184
184
|
async getEnumValues(enumTypeName) {
|
|
185
185
|
try {
|
|
186
|
-
const enumQuery = `
|
|
187
|
-
SELECT e.enumlabel
|
|
188
|
-
FROM pg_enum e
|
|
189
|
-
JOIN pg_type t ON e.enumtypid = t.oid
|
|
190
|
-
WHERE t.typname = $1
|
|
191
|
-
ORDER BY e.enumsortorder
|
|
186
|
+
const enumQuery = `
|
|
187
|
+
SELECT e.enumlabel
|
|
188
|
+
FROM pg_enum e
|
|
189
|
+
JOIN pg_type t ON e.enumtypid = t.oid
|
|
190
|
+
WHERE t.typname = $1
|
|
191
|
+
ORDER BY e.enumsortorder
|
|
192
192
|
`;
|
|
193
193
|
const result = await this.pool.query(enumQuery, [enumTypeName]);
|
|
194
194
|
return result.rows.map((row) => row.enumlabel);
|
|
@@ -119,11 +119,11 @@ class SchemaDiscrepancyFixer {
|
|
|
119
119
|
}
|
|
120
120
|
}
|
|
121
121
|
async getTargetSchemas() {
|
|
122
|
-
const query = `
|
|
123
|
-
SELECT schema_name
|
|
124
|
-
FROM information_schema.schemata
|
|
125
|
-
WHERE schema_name NOT IN ('information_schema', 'pg_catalog', 'pg_toast')
|
|
126
|
-
AND schema_name NOT LIKE 'pg_%'
|
|
122
|
+
const query = `
|
|
123
|
+
SELECT schema_name
|
|
124
|
+
FROM information_schema.schemata
|
|
125
|
+
WHERE schema_name NOT IN ('information_schema', 'pg_catalog', 'pg_toast')
|
|
126
|
+
AND schema_name NOT LIKE 'pg_%'
|
|
127
127
|
`;
|
|
128
128
|
const result = await this.targetPool.query(query);
|
|
129
129
|
return result.rows.map(row => row.schema_name);
|
|
@@ -133,22 +133,22 @@ class SchemaDiscrepancyFixer {
|
|
|
133
133
|
this.columnTypeCache[table] = {};
|
|
134
134
|
}
|
|
135
135
|
const columnsStr = columns.map(c => `'${c}'`).join(',');
|
|
136
|
-
const query = `
|
|
137
|
-
SELECT column_name, data_type,
|
|
138
|
-
CASE
|
|
139
|
-
WHEN data_type = 'character varying' THEN data_type || '(' || character_maximum_length || ')'
|
|
140
|
-
WHEN data_type = 'numeric' THEN
|
|
141
|
-
CASE
|
|
142
|
-
WHEN numeric_precision IS NOT NULL AND numeric_scale IS NOT NULL
|
|
143
|
-
THEN data_type || '(' || numeric_precision || ',' || numeric_scale || ')'
|
|
144
|
-
ELSE data_type
|
|
145
|
-
END
|
|
146
|
-
ELSE data_type
|
|
147
|
-
END as full_data_type
|
|
148
|
-
FROM information_schema.columns
|
|
149
|
-
WHERE table_schema = 'public'
|
|
150
|
-
AND table_name = $1
|
|
151
|
-
AND column_name IN (${columnsStr})
|
|
136
|
+
const query = `
|
|
137
|
+
SELECT column_name, data_type,
|
|
138
|
+
CASE
|
|
139
|
+
WHEN data_type = 'character varying' THEN data_type || '(' || character_maximum_length || ')'
|
|
140
|
+
WHEN data_type = 'numeric' THEN
|
|
141
|
+
CASE
|
|
142
|
+
WHEN numeric_precision IS NOT NULL AND numeric_scale IS NOT NULL
|
|
143
|
+
THEN data_type || '(' || numeric_precision || ',' || numeric_scale || ')'
|
|
144
|
+
ELSE data_type
|
|
145
|
+
END
|
|
146
|
+
ELSE data_type
|
|
147
|
+
END as full_data_type
|
|
148
|
+
FROM information_schema.columns
|
|
149
|
+
WHERE table_schema = 'public'
|
|
150
|
+
AND table_name = $1
|
|
151
|
+
AND column_name IN (${columnsStr})
|
|
152
152
|
`;
|
|
153
153
|
const result = await this.sourcePool.query(query, [table]);
|
|
154
154
|
for (const row of result.rows) {
|
|
@@ -156,33 +156,33 @@ class SchemaDiscrepancyFixer {
|
|
|
156
156
|
}
|
|
157
157
|
}
|
|
158
158
|
async checkTableExists(schema, table) {
|
|
159
|
-
const query = `
|
|
160
|
-
SELECT EXISTS (
|
|
161
|
-
SELECT FROM information_schema.tables
|
|
162
|
-
WHERE table_schema = $1
|
|
163
|
-
AND table_name = $2
|
|
164
|
-
);
|
|
159
|
+
const query = `
|
|
160
|
+
SELECT EXISTS (
|
|
161
|
+
SELECT FROM information_schema.tables
|
|
162
|
+
WHERE table_schema = $1
|
|
163
|
+
AND table_name = $2
|
|
164
|
+
);
|
|
165
165
|
`;
|
|
166
166
|
const result = await this.targetPool.query(query, [schema, table]);
|
|
167
167
|
return result.rows[0].exists;
|
|
168
168
|
}
|
|
169
169
|
async checkColumnExists(schema, table, column) {
|
|
170
|
-
const query = `
|
|
171
|
-
SELECT EXISTS (
|
|
172
|
-
SELECT FROM information_schema.columns
|
|
173
|
-
WHERE table_schema = $1
|
|
174
|
-
AND table_name = $2
|
|
175
|
-
AND column_name = $3
|
|
176
|
-
);
|
|
170
|
+
const query = `
|
|
171
|
+
SELECT EXISTS (
|
|
172
|
+
SELECT FROM information_schema.columns
|
|
173
|
+
WHERE table_schema = $1
|
|
174
|
+
AND table_name = $2
|
|
175
|
+
AND column_name = $3
|
|
176
|
+
);
|
|
177
177
|
`;
|
|
178
178
|
const result = await this.targetPool.query(query, [schema, table, column]);
|
|
179
179
|
return result.rows[0].exists;
|
|
180
180
|
}
|
|
181
181
|
async addColumn(schema, table, column, type) {
|
|
182
182
|
try {
|
|
183
|
-
const query = `
|
|
184
|
-
ALTER TABLE "${schema}"."${table}"
|
|
185
|
-
ADD COLUMN IF NOT EXISTS "${column}" ${type};
|
|
183
|
+
const query = `
|
|
184
|
+
ALTER TABLE "${schema}"."${table}"
|
|
185
|
+
ADD COLUMN IF NOT EXISTS "${column}" ${type};
|
|
186
186
|
`;
|
|
187
187
|
await this.targetPool.query(query);
|
|
188
188
|
this.logger.log(`Added column "${column}" to "${schema}"."${table}" with type "${type}"`);
|
|
@@ -195,9 +195,9 @@ class SchemaDiscrepancyFixer {
|
|
|
195
195
|
async addUniqueConstraint(schema, table, column) {
|
|
196
196
|
try {
|
|
197
197
|
const constraintName = `${table}_${column}_unique`;
|
|
198
|
-
const query = `
|
|
199
|
-
ALTER TABLE "${schema}"."${table}"
|
|
200
|
-
ADD CONSTRAINT "${constraintName}" UNIQUE ("${column}");
|
|
198
|
+
const query = `
|
|
199
|
+
ALTER TABLE "${schema}"."${table}"
|
|
200
|
+
ADD CONSTRAINT "${constraintName}" UNIQUE ("${column}");
|
|
201
201
|
`;
|
|
202
202
|
await this.targetPool.query(query);
|
|
203
203
|
this.logger.log(`Added UNIQUE constraint on "${column}" to "${schema}"."${table}"`);
|
|
@@ -44,11 +44,11 @@ class TableIndexFixer {
|
|
|
44
44
|
}
|
|
45
45
|
}
|
|
46
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_%'
|
|
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
52
|
`);
|
|
53
53
|
return result.rows.map(row => row.schema_name);
|
|
54
54
|
}
|
|
@@ -66,11 +66,11 @@ class TableIndexFixer {
|
|
|
66
66
|
}
|
|
67
67
|
}
|
|
68
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'
|
|
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
74
|
`, [schema]);
|
|
75
75
|
return result.rows.map(row => row.table_name);
|
|
76
76
|
}
|
|
@@ -126,24 +126,24 @@ class TableIndexFixer {
|
|
|
126
126
|
async fixUserTableSequences(schema, table) {
|
|
127
127
|
var _a;
|
|
128
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%')
|
|
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
135
|
`;
|
|
136
136
|
const columnsResult = await this.targetPool.query(columnsQuery, [schema, table]);
|
|
137
137
|
const identityColumns = columnsResult.rows.map(row => row.column_name);
|
|
138
138
|
for (const column of identityColumns) {
|
|
139
|
-
const sequenceQuery = `
|
|
140
|
-
SELECT pg_get_serial_sequence($1, $2) AS sequence_name
|
|
139
|
+
const sequenceQuery = `
|
|
140
|
+
SELECT pg_get_serial_sequence($1, $2) AS sequence_name
|
|
141
141
|
`;
|
|
142
142
|
const sequenceResult = await this.targetPool.query(sequenceQuery, [`${schema}.${table}`, column]);
|
|
143
143
|
const sequenceName = (_a = sequenceResult.rows[0]) === null || _a === void 0 ? void 0 : _a.sequence_name;
|
|
144
144
|
if (sequenceName) {
|
|
145
|
-
const resetQuery = `
|
|
146
|
-
SELECT setval($1, COALESCE((SELECT MAX(${column}) FROM ${schema}.${table}), 0) + 1, true)
|
|
145
|
+
const resetQuery = `
|
|
146
|
+
SELECT setval($1, COALESCE((SELECT MAX(${column}) FROM ${schema}.${table}), 0) + 1, true)
|
|
147
147
|
`;
|
|
148
148
|
await this.targetPool.query(resetQuery, [sequenceName]);
|
|
149
149
|
this.logger.log(`Restablecida secuencia ${sequenceName} para la columna ${column} en ${schema}.${table} (tabla de usuarios)`);
|
|
@@ -210,24 +210,24 @@ class TableIndexFixer {
|
|
|
210
210
|
async fixSequences(schema, table) {
|
|
211
211
|
var _a;
|
|
212
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%')
|
|
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
219
|
`;
|
|
220
220
|
const columnsResult = await this.targetPool.query(columnsQuery, [schema, table]);
|
|
221
221
|
const identityColumns = columnsResult.rows.map(row => row.column_name);
|
|
222
222
|
for (const column of identityColumns) {
|
|
223
|
-
const sequenceQuery = `
|
|
224
|
-
SELECT pg_get_serial_sequence($1, $2) AS sequence_name
|
|
223
|
+
const sequenceQuery = `
|
|
224
|
+
SELECT pg_get_serial_sequence($1, $2) AS sequence_name
|
|
225
225
|
`;
|
|
226
226
|
const sequenceResult = await this.targetPool.query(sequenceQuery, [`${schema}.${table}`, column]);
|
|
227
227
|
const sequenceName = (_a = sequenceResult.rows[0]) === null || _a === void 0 ? void 0 : _a.sequence_name;
|
|
228
228
|
if (sequenceName) {
|
|
229
|
-
const resetQuery = `
|
|
230
|
-
SELECT setval($1, COALESCE((SELECT MAX(${column}) FROM ${schema}.${table}), 0) + 1, true)
|
|
229
|
+
const resetQuery = `
|
|
230
|
+
SELECT setval($1, COALESCE((SELECT MAX(${column}) FROM ${schema}.${table}), 0) + 1, true)
|
|
231
231
|
`;
|
|
232
232
|
await this.targetPool.query(resetQuery, [sequenceName]);
|
|
233
233
|
this.logger.log(`Restablecida secuencia ${sequenceName} para la columna ${column} en ${schema}.${table}`);
|
|
@@ -249,14 +249,14 @@ class TableIndexFixer {
|
|
|
249
249
|
async getTableInfo(schema, table) {
|
|
250
250
|
var _a;
|
|
251
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;
|
|
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
260
|
`;
|
|
261
261
|
const result = await this.targetPool.query(identityQuery, [schema, table]);
|
|
262
262
|
return {
|
|
@@ -269,26 +269,26 @@ class TableIndexFixer {
|
|
|
269
269
|
}
|
|
270
270
|
}
|
|
271
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;
|
|
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
292
|
`;
|
|
293
293
|
try {
|
|
294
294
|
const result = await pool.query(query, [schema, table]);
|
|
@@ -367,35 +367,35 @@ class TableIndexFixer {
|
|
|
367
367
|
}
|
|
368
368
|
}
|
|
369
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
|
|
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
375
|
`;
|
|
376
376
|
const result = await this.targetPool.query(query, [schema, table]);
|
|
377
377
|
return result.rows;
|
|
378
378
|
}
|
|
379
379
|
async fixForeignKeyIndexes(schema, table) {
|
|
380
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;
|
|
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
399
|
`;
|
|
400
400
|
const fkResult = await this.targetPool.query(fkQuery, [schema, table]);
|
|
401
401
|
const existingIndexes = await this.getTableIndexes(this.targetPool, schema, table);
|
|
@@ -57,10 +57,10 @@ async function migrateSchemaStructure() {
|
|
|
57
57
|
async function checkSchemaExists(schemaName) {
|
|
58
58
|
const prisma = new client_1.PrismaClient();
|
|
59
59
|
try {
|
|
60
|
-
const result = await prisma.$queryRaw `
|
|
61
|
-
SELECT schema_name
|
|
62
|
-
FROM information_schema.schemata
|
|
63
|
-
WHERE schema_name = ${schemaName}
|
|
60
|
+
const result = await prisma.$queryRaw `
|
|
61
|
+
SELECT schema_name
|
|
62
|
+
FROM information_schema.schemata
|
|
63
|
+
WHERE schema_name = ${schemaName}
|
|
64
64
|
`;
|
|
65
65
|
return Array.isArray(result) && result.length > 0;
|
|
66
66
|
}
|