@zintrust/d1-migrator 0.4.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 +871 -0
- package/dist/cli/DataMigrator.d.ts +104 -0
- package/dist/cli/DataMigrator.d.ts.map +1 -0
- package/dist/cli/DataMigrator.js +431 -0
- package/dist/cli/MigrateToD1Command.d.ts +52 -0
- package/dist/cli/MigrateToD1Command.d.ts.map +1 -0
- package/dist/cli/MigrateToD1Command.js +600 -0
- package/dist/cli/ProgressTracker.d.ts +32 -0
- package/dist/cli/ProgressTracker.d.ts.map +1 -0
- package/dist/cli/ProgressTracker.js +95 -0
- package/dist/cli/SchemaAnalyzer.d.ts +130 -0
- package/dist/cli/SchemaAnalyzer.d.ts.map +1 -0
- package/dist/cli/SchemaAnalyzer.js +660 -0
- package/dist/index.d.ts +46 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +32 -0
- package/dist/schema/SchemaBuilder.d.ts +51 -0
- package/dist/schema/SchemaBuilder.d.ts.map +1 -0
- package/dist/schema/SchemaBuilder.js +165 -0
- package/dist/schema/TypeConverter.d.ts +35 -0
- package/dist/schema/TypeConverter.d.ts.map +1 -0
- package/dist/schema/TypeConverter.js +187 -0
- package/dist/schema/Validator.d.ts +74 -0
- package/dist/schema/Validator.d.ts.map +1 -0
- package/dist/schema/Validator.js +225 -0
- package/dist/types.d.ts +145 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +5 -0
- package/dist/utils/CheckpointManager.d.ts +48 -0
- package/dist/utils/CheckpointManager.d.ts.map +1 -0
- package/dist/utils/CheckpointManager.js +191 -0
- package/dist/utils/DataValidator.d.ts +46 -0
- package/dist/utils/DataValidator.d.ts.map +1 -0
- package/dist/utils/DataValidator.js +139 -0
- package/package.json +37 -0
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Progress Tracker
|
|
3
|
+
* Tracks migration progress and provides status updates
|
|
4
|
+
*/
|
|
5
|
+
import { Logger } from '@zintrust/core';
|
|
6
|
+
/**
|
|
7
|
+
* ProgressTracker - Sealed namespace for progress tracking
|
|
8
|
+
* Provides migration progress monitoring and reporting
|
|
9
|
+
*/
|
|
10
|
+
export const ProgressTracker = Object.freeze({
|
|
11
|
+
/**
|
|
12
|
+
* Create new progress tracker
|
|
13
|
+
*/
|
|
14
|
+
create(migrationId) {
|
|
15
|
+
return {
|
|
16
|
+
migrationId,
|
|
17
|
+
startTime: new Date(),
|
|
18
|
+
currentTable: '',
|
|
19
|
+
table: '',
|
|
20
|
+
totalTables: 0,
|
|
21
|
+
totalRows: 0,
|
|
22
|
+
processedRows: 0,
|
|
23
|
+
percentage: 0,
|
|
24
|
+
errors: {},
|
|
25
|
+
status: 'pending',
|
|
26
|
+
};
|
|
27
|
+
},
|
|
28
|
+
/**
|
|
29
|
+
* Update progress
|
|
30
|
+
*/
|
|
31
|
+
update(progress, updates) {
|
|
32
|
+
const updated = { ...progress, ...updates };
|
|
33
|
+
// Log progress updates
|
|
34
|
+
if (updates.currentTable && updates.currentTable !== progress.currentTable) {
|
|
35
|
+
Logger.info(`Migrating table: ${updates.currentTable}`);
|
|
36
|
+
}
|
|
37
|
+
if (updates.processedRows !== undefined) {
|
|
38
|
+
const percentage = progress.totalRows > 0 ? Math.round((updates.processedRows / progress.totalRows) * 100) : 0;
|
|
39
|
+
Logger.info(`Progress: ${updates.processedRows}/${progress.totalRows} (${percentage}%)`);
|
|
40
|
+
}
|
|
41
|
+
return updated;
|
|
42
|
+
},
|
|
43
|
+
/**
|
|
44
|
+
* Add error to progress
|
|
45
|
+
*/
|
|
46
|
+
addError(progress, table, error) {
|
|
47
|
+
const updated = {
|
|
48
|
+
...progress,
|
|
49
|
+
errors: {
|
|
50
|
+
...progress.errors,
|
|
51
|
+
[table]: error,
|
|
52
|
+
},
|
|
53
|
+
status: 'failed',
|
|
54
|
+
};
|
|
55
|
+
Logger.error(`Migration error for table ${table}: ${error}`);
|
|
56
|
+
return updated;
|
|
57
|
+
},
|
|
58
|
+
/**
|
|
59
|
+
* Mark as completed
|
|
60
|
+
*/
|
|
61
|
+
complete(progress) {
|
|
62
|
+
const completed = {
|
|
63
|
+
...progress,
|
|
64
|
+
status: 'completed',
|
|
65
|
+
};
|
|
66
|
+
Logger.info(`Migration completed: ${progress.migrationId}`);
|
|
67
|
+
return completed;
|
|
68
|
+
},
|
|
69
|
+
/**
|
|
70
|
+
* Generate progress report
|
|
71
|
+
*/
|
|
72
|
+
generateReport(progress) {
|
|
73
|
+
const startTime = progress.startTime || new Date();
|
|
74
|
+
const duration = Date.now() - startTime.getTime();
|
|
75
|
+
const durationMinutes = Math.round(duration / 60000);
|
|
76
|
+
let report = '# Migration Progress Report\n\n';
|
|
77
|
+
report += `## Migration ID: ${progress.migrationId}\n`;
|
|
78
|
+
report += `## Status: ${progress.status}\n`;
|
|
79
|
+
report += `## Duration: ${durationMinutes} minutes\n\n`;
|
|
80
|
+
report += `## Tables\n`;
|
|
81
|
+
report += `- Completed: ${progress.processedRows}/${progress.totalRows}\n`;
|
|
82
|
+
report += `- Current: ${progress.currentTable || 'None'}\n\n`;
|
|
83
|
+
report += `## Rows\n`;
|
|
84
|
+
report += `- Migrated: ${progress.processedRows}/${progress.totalRows}\n`;
|
|
85
|
+
const percentage = progress.totalRows > 0 ? Math.round((progress.processedRows / progress.totalRows) * 100) : 0;
|
|
86
|
+
report += `- Progress: ${percentage}%\n\n`;
|
|
87
|
+
if (progress.errors && Object.keys(progress.errors).length > 0) {
|
|
88
|
+
report += `## Errors\n`;
|
|
89
|
+
Object.values(progress.errors).forEach((error, index) => {
|
|
90
|
+
report += `${index + 1}. ${error}\n`;
|
|
91
|
+
});
|
|
92
|
+
}
|
|
93
|
+
return report;
|
|
94
|
+
},
|
|
95
|
+
});
|
|
@@ -0,0 +1,130 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Schema Analyzer
|
|
3
|
+
* Analyzes database schemas for migration compatibility
|
|
4
|
+
*/
|
|
5
|
+
import type { ColumnSchema, DatabaseSchema, ForeignKeySchema, IndexSchema, TableConstraint, TableRelationship, TableSchema } from '../types';
|
|
6
|
+
export interface IDatabaseAdapter {
|
|
7
|
+
connect(): Promise<void>;
|
|
8
|
+
disconnect(): Promise<void>;
|
|
9
|
+
query(sql: string, parameters: unknown[]): Promise<{
|
|
10
|
+
rows: Record<string, unknown>[];
|
|
11
|
+
rowCount?: number;
|
|
12
|
+
}>;
|
|
13
|
+
queryOne(sql: string, parameters: unknown[]): Promise<Record<string, unknown> | null>;
|
|
14
|
+
ping(): Promise<void>;
|
|
15
|
+
transaction<T>(callback: (adapter: IDatabaseAdapter) => Promise<T>): Promise<T>;
|
|
16
|
+
rawQuery<T = unknown>(sql: string, parameters?: unknown[]): Promise<T[]>;
|
|
17
|
+
ensureMigrationsTable?(): Promise<void>;
|
|
18
|
+
getType(): string;
|
|
19
|
+
isConnected(): boolean;
|
|
20
|
+
getPlaceholder(index: number): string;
|
|
21
|
+
}
|
|
22
|
+
/**
|
|
23
|
+
* SchemaAnalyzer - Sealed namespace for schema analysis
|
|
24
|
+
* Provides database schema analysis and compatibility checking
|
|
25
|
+
*/
|
|
26
|
+
export declare const SchemaAnalyzer: Readonly<{
|
|
27
|
+
/**
|
|
28
|
+
* Analyze source database schema
|
|
29
|
+
*/
|
|
30
|
+
analyzeSchema(connection: {
|
|
31
|
+
driver: string;
|
|
32
|
+
connectionString: string;
|
|
33
|
+
}): Promise<DatabaseSchema>;
|
|
34
|
+
/**
|
|
35
|
+
* Extract tables from source database
|
|
36
|
+
*/
|
|
37
|
+
extractTables(connection: {
|
|
38
|
+
driver: string;
|
|
39
|
+
connectionString: string;
|
|
40
|
+
}): Promise<TableSchema[]>;
|
|
41
|
+
/**
|
|
42
|
+
* Extract relationships from source database
|
|
43
|
+
*/
|
|
44
|
+
extractRelationships(_connection: {
|
|
45
|
+
driver: string;
|
|
46
|
+
connectionString: string;
|
|
47
|
+
}, _tables: TableSchema[]): Promise<TableRelationship[]>;
|
|
48
|
+
/**
|
|
49
|
+
* Extract constraints from source database
|
|
50
|
+
*/
|
|
51
|
+
extractConstraints(_connection: {
|
|
52
|
+
driver: string;
|
|
53
|
+
connectionString: string;
|
|
54
|
+
}, _tables: TableSchema[]): Promise<TableConstraint[]>;
|
|
55
|
+
/**
|
|
56
|
+
* Check schema compatibility with D1
|
|
57
|
+
*/
|
|
58
|
+
checkD1Compatibility(schema: DatabaseSchema): {
|
|
59
|
+
compatible: boolean;
|
|
60
|
+
issues: string[];
|
|
61
|
+
warnings: string[];
|
|
62
|
+
};
|
|
63
|
+
/**
|
|
64
|
+
* Check if column type is supported by D1
|
|
65
|
+
*/
|
|
66
|
+
isSupportedType(type: string): boolean;
|
|
67
|
+
/**
|
|
68
|
+
* Check if table name is valid for D1
|
|
69
|
+
*/
|
|
70
|
+
isValidTableName(name: string): boolean;
|
|
71
|
+
/**
|
|
72
|
+
* Generate schema analysis report
|
|
73
|
+
*/
|
|
74
|
+
generateReport(schema: DatabaseSchema): string;
|
|
75
|
+
/**
|
|
76
|
+
* Get table list from database based on driver type
|
|
77
|
+
*/
|
|
78
|
+
getTableList(adapter: IDatabaseAdapter, driver: string): Promise<string[]>;
|
|
79
|
+
/**
|
|
80
|
+
* Get detailed schema for a specific table
|
|
81
|
+
*/
|
|
82
|
+
getTableSchema(adapter: IDatabaseAdapter, tableName: string, driver: string): Promise<TableSchema>;
|
|
83
|
+
/**
|
|
84
|
+
* Get column information for a table
|
|
85
|
+
*/
|
|
86
|
+
getTableColumns(adapter: IDatabaseAdapter, tableName: string, driver: string): Promise<ColumnSchema[]>;
|
|
87
|
+
/**
|
|
88
|
+
* Get primary key for a table
|
|
89
|
+
*/
|
|
90
|
+
getPrimaryKey(adapter: IDatabaseAdapter, tableName: string, driver: string): Promise<string | null>;
|
|
91
|
+
/**
|
|
92
|
+
* Normalize data type from different database systems to D1-compatible types
|
|
93
|
+
*/
|
|
94
|
+
normalizeDataType(dataType: string, _driver: string): string;
|
|
95
|
+
/**
|
|
96
|
+
* Get indexes for a table
|
|
97
|
+
*/
|
|
98
|
+
getTableIndexes(adapter: IDatabaseAdapter, tableName: string, driver: string): Promise<IndexSchema[]>;
|
|
99
|
+
/**
|
|
100
|
+
* Build index query for specific driver
|
|
101
|
+
*/
|
|
102
|
+
buildIndexQuery(tableName: string, driver: string): string | null;
|
|
103
|
+
/**
|
|
104
|
+
* Process index results into IndexSchema format
|
|
105
|
+
*/
|
|
106
|
+
processIndexResults(result: {
|
|
107
|
+
rows: Record<string, unknown>[];
|
|
108
|
+
}, driver: string): IndexSchema[];
|
|
109
|
+
/**
|
|
110
|
+
* Check if index is unique based on driver-specific data
|
|
111
|
+
*/
|
|
112
|
+
isIndexUnique(row: Record<string, unknown>, driver: string): boolean;
|
|
113
|
+
/**
|
|
114
|
+
* Get foreign keys for a table
|
|
115
|
+
*/
|
|
116
|
+
getForeignKeys(adapter: IDatabaseAdapter, tableName: string, driver: string): Promise<ForeignKeySchema[]>;
|
|
117
|
+
/**
|
|
118
|
+
* Build foreign key query for specific driver
|
|
119
|
+
*/
|
|
120
|
+
buildForeignKeyQuery(tableName: string, driver: string): string | null;
|
|
121
|
+
/**
|
|
122
|
+
* Process foreign key row into ForeignKeySchema format
|
|
123
|
+
*/
|
|
124
|
+
processForeignKeyRow(row: Record<string, unknown>, tableName: string): ForeignKeySchema;
|
|
125
|
+
/**
|
|
126
|
+
* Map referential action string to enum value
|
|
127
|
+
*/
|
|
128
|
+
mapReferentialAction(action: string): "CASCADE" | "SET NULL" | "RESTRICT";
|
|
129
|
+
}>;
|
|
130
|
+
//# sourceMappingURL=SchemaAnalyzer.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"SchemaAnalyzer.d.ts","sourceRoot":"","sources":["../../src/cli/SchemaAnalyzer.ts"],"names":[],"mappings":"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"}
|