@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
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* D1 Migrator Package
|
|
3
|
+
* Migrate any database to Cloudflare D1 with resumable operations
|
|
4
|
+
*/
|
|
5
|
+
import type { CommandOptions } from '@zintrust/core/cli';
|
|
6
|
+
import type { Command } from 'commander';
|
|
7
|
+
import { CheckpointManager } from './utils/CheckpointManager';
|
|
8
|
+
import { DataValidator } from './utils/DataValidator';
|
|
9
|
+
import { DataMigrator } from './cli/DataMigrator';
|
|
10
|
+
import { ProgressTracker } from './cli/ProgressTracker';
|
|
11
|
+
import { SchemaAnalyzer } from './cli/SchemaAnalyzer';
|
|
12
|
+
import { SchemaBuilder } from './schema/SchemaBuilder';
|
|
13
|
+
import { TypeConverter } from './schema/TypeConverter';
|
|
14
|
+
import { SchemaValidator } from './schema/Validator';
|
|
15
|
+
type D1MigratorCommand = {
|
|
16
|
+
[x: string]: unknown;
|
|
17
|
+
name: string;
|
|
18
|
+
description: string;
|
|
19
|
+
verbose?: boolean;
|
|
20
|
+
getCommand(): Command;
|
|
21
|
+
addOptions?: (command: Command) => void;
|
|
22
|
+
execute(options: CommandOptions): void | Promise<void>;
|
|
23
|
+
info(message: string): void;
|
|
24
|
+
success(message: string): void;
|
|
25
|
+
warn(message: string): void;
|
|
26
|
+
debug(message: unknown): void;
|
|
27
|
+
};
|
|
28
|
+
/**
|
|
29
|
+
* D1 Migrator - Sealed namespace for database migration operations
|
|
30
|
+
* Provides comprehensive migration from MySQL, PostgreSQL, SQLite, SQL Server to D1/D1Remote
|
|
31
|
+
*/
|
|
32
|
+
type D1MigratorNamespace = Readonly<{
|
|
33
|
+
MigrateToD1Command: D1MigratorCommand;
|
|
34
|
+
CheckpointManager: typeof CheckpointManager;
|
|
35
|
+
DataValidator: typeof DataValidator;
|
|
36
|
+
SchemaAnalyzer: typeof SchemaAnalyzer;
|
|
37
|
+
DataMigrator: typeof DataMigrator;
|
|
38
|
+
ProgressTracker: typeof ProgressTracker;
|
|
39
|
+
TypeConverter: typeof TypeConverter;
|
|
40
|
+
SchemaBuilder: typeof SchemaBuilder;
|
|
41
|
+
SchemaValidator: typeof SchemaValidator;
|
|
42
|
+
}>;
|
|
43
|
+
export declare const D1Migrator: D1MigratorNamespace;
|
|
44
|
+
export type { CheckpointData, ColumnSchema, DataValidationResult, IndexSchema, MigrationConfig, MigrationProgress, MigrationState, TableSchema, } from './types';
|
|
45
|
+
export default D1Migrator;
|
|
46
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,oBAAoB,CAAC;AACzD,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAMzC,OAAO,EAAE,iBAAiB,EAAE,MAAM,2BAA2B,CAAC;AAC9D,OAAO,EAAE,aAAa,EAAE,MAAM,uBAAuB,CAAC;AAGtD,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAClD,OAAO,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAC;AACxD,OAAO,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AAGtD,OAAO,EAAE,aAAa,EAAE,MAAM,wBAAwB,CAAC;AACvD,OAAO,EAAE,aAAa,EAAE,MAAM,wBAAwB,CAAC;AACvD,OAAO,EAAE,eAAe,EAAE,MAAM,oBAAoB,CAAC;AAErD,KAAK,iBAAiB,GAAG;IACvB,CAAC,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC;IACrB,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,MAAM,CAAC;IACpB,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,UAAU,IAAI,OAAO,CAAC;IACtB,UAAU,CAAC,EAAE,CAAC,OAAO,EAAE,OAAO,KAAK,IAAI,CAAC;IACxC,OAAO,CAAC,OAAO,EAAE,cAAc,GAAG,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IACvD,IAAI,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;IAC5B,OAAO,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;IAC/B,IAAI,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;IAC5B,KAAK,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI,CAAC;CAC/B,CAAC;AAEF;;;GAGG;AACH,KAAK,mBAAmB,GAAG,QAAQ,CAAC;IAClC,kBAAkB,EAAE,iBAAiB,CAAC;IACtC,iBAAiB,EAAE,OAAO,iBAAiB,CAAC;IAC5C,aAAa,EAAE,OAAO,aAAa,CAAC;IACpC,cAAc,EAAE,OAAO,cAAc,CAAC;IACtC,YAAY,EAAE,OAAO,YAAY,CAAC;IAClC,eAAe,EAAE,OAAO,eAAe,CAAC;IACxC,aAAa,EAAE,OAAO,aAAa,CAAC;IACpC,aAAa,EAAE,OAAO,aAAa,CAAC;IACpC,eAAe,EAAE,OAAO,eAAe,CAAC;CACzC,CAAC,CAAC;AAEH,eAAO,MAAM,UAAU,EAAE,mBAevB,CAAC;AAGH,YAAY,EACV,cAAc,EACd,YAAY,EACZ,oBAAoB,EACpB,WAAW,EACX,eAAe,EACf,iBAAiB,EACjB,cAAc,EACd,WAAW,GACZ,MAAM,SAAS,CAAC;AAEjB,eAAe,UAAU,CAAC"}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* D1 Migrator Package
|
|
3
|
+
* Migrate any database to Cloudflare D1 with resumable operations
|
|
4
|
+
*/
|
|
5
|
+
// CLI Commands
|
|
6
|
+
import { MigrateToD1Command } from './cli/MigrateToD1Command';
|
|
7
|
+
// Utilities
|
|
8
|
+
import { CheckpointManager } from './utils/CheckpointManager';
|
|
9
|
+
import { DataValidator } from './utils/DataValidator';
|
|
10
|
+
// CLI Components
|
|
11
|
+
import { DataMigrator } from './cli/DataMigrator';
|
|
12
|
+
import { ProgressTracker } from './cli/ProgressTracker';
|
|
13
|
+
import { SchemaAnalyzer } from './cli/SchemaAnalyzer';
|
|
14
|
+
// Schema Components
|
|
15
|
+
import { SchemaBuilder } from './schema/SchemaBuilder';
|
|
16
|
+
import { TypeConverter } from './schema/TypeConverter';
|
|
17
|
+
import { SchemaValidator } from './schema/Validator';
|
|
18
|
+
export const D1Migrator = Object.freeze({
|
|
19
|
+
// CLI Commands
|
|
20
|
+
MigrateToD1Command,
|
|
21
|
+
// Core Components
|
|
22
|
+
CheckpointManager,
|
|
23
|
+
DataValidator,
|
|
24
|
+
SchemaAnalyzer,
|
|
25
|
+
DataMigrator,
|
|
26
|
+
ProgressTracker,
|
|
27
|
+
// Schema Components
|
|
28
|
+
TypeConverter,
|
|
29
|
+
SchemaBuilder,
|
|
30
|
+
SchemaValidator,
|
|
31
|
+
});
|
|
32
|
+
export default D1Migrator;
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Schema Builder
|
|
3
|
+
* Builds D1/SQLite compatible schemas from source schemas
|
|
4
|
+
*/
|
|
5
|
+
import type { ColumnSchema, TableSchema } from '../types';
|
|
6
|
+
/**
|
|
7
|
+
* SchemaBuilder - Sealed namespace for schema building
|
|
8
|
+
* Provides D1 schema generation from source schemas
|
|
9
|
+
*/
|
|
10
|
+
export declare const SchemaBuilder: Readonly<{
|
|
11
|
+
/**
|
|
12
|
+
* Build D1 schema from source schema
|
|
13
|
+
*/
|
|
14
|
+
buildD1Schema(sourceSchema: TableSchema[], sourceDriver: string): TableSchema[];
|
|
15
|
+
/**
|
|
16
|
+
* Build D1 table from source table
|
|
17
|
+
*/
|
|
18
|
+
buildD1Table(sourceTable: TableSchema, sourceDriver: string): TableSchema;
|
|
19
|
+
/**
|
|
20
|
+
* Build D1 column from source column
|
|
21
|
+
*/
|
|
22
|
+
buildD1Column(sourceColumn: ColumnSchema, sourceDriver: string): ColumnSchema;
|
|
23
|
+
/**
|
|
24
|
+
* Generate CREATE TABLE SQL
|
|
25
|
+
*/
|
|
26
|
+
generateCreateTableSQL(table: TableSchema): string;
|
|
27
|
+
/**
|
|
28
|
+
* Generate column definition
|
|
29
|
+
*/
|
|
30
|
+
generateColumnDefinition(column: ColumnSchema): string;
|
|
31
|
+
/**
|
|
32
|
+
* Format default value for SQL
|
|
33
|
+
*/
|
|
34
|
+
formatDefaultValue(value: unknown): string;
|
|
35
|
+
/**
|
|
36
|
+
* Generate index statements
|
|
37
|
+
*/
|
|
38
|
+
generateIndexSQL(table: TableSchema): string[];
|
|
39
|
+
/**
|
|
40
|
+
* Generate complete schema SQL
|
|
41
|
+
*/
|
|
42
|
+
generateSchemaSQL(tables: TableSchema[]): string;
|
|
43
|
+
/**
|
|
44
|
+
* Validate built schema
|
|
45
|
+
*/
|
|
46
|
+
validateSchema(tables: TableSchema[]): {
|
|
47
|
+
valid: boolean;
|
|
48
|
+
errors: string[];
|
|
49
|
+
};
|
|
50
|
+
}>;
|
|
51
|
+
//# sourceMappingURL=SchemaBuilder.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"SchemaBuilder.d.ts","sourceRoot":"","sources":["../../src/schema/SchemaBuilder.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAGH,OAAO,KAAK,EAAE,YAAY,EAAE,WAAW,EAAE,MAAM,UAAU,CAAC;AAI1D;;;GAGG;AACH,eAAO,MAAM,aAAa;IACxB;;OAEG;gCACyB,WAAW,EAAE,gBAAgB,MAAM,GAAG,WAAW,EAAE;IAM/E;;OAEG;8BACuB,WAAW,gBAAgB,MAAM,GAAG,WAAW;IAkBzE;;OAEG;gCACyB,YAAY,gBAAgB,MAAM,GAAG,YAAY;IAmB7E;;OAEG;kCAC2B,WAAW,GAAG,MAAM;IAmBlD;;OAEG;qCAC8B,YAAY,GAAG,MAAM;IActD;;OAEG;8BACuB,OAAO,GAAG,MAAM;IAgB1C;;OAEG;4BACqB,WAAW,GAAG,MAAM,EAAE;IAqB9C;;OAEG;8BACuB,WAAW,EAAE,GAAG,MAAM;IAqBhD;;OAEG;2BACoB,WAAW,EAAE,GAAG;QACrC,KAAK,EAAE,OAAO,CAAC;QACf,MAAM,EAAE,MAAM,EAAE,CAAC;KAClB;EAmCD,CAAC"}
|
|
@@ -0,0 +1,165 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Schema Builder
|
|
3
|
+
* Builds D1/SQLite compatible schemas from source schemas
|
|
4
|
+
*/
|
|
5
|
+
import { Logger } from '@zintrust/core';
|
|
6
|
+
import { DataValidator } from '../utils/DataValidator';
|
|
7
|
+
import { TypeConverter } from './TypeConverter';
|
|
8
|
+
/**
|
|
9
|
+
* SchemaBuilder - Sealed namespace for schema building
|
|
10
|
+
* Provides D1 schema generation from source schemas
|
|
11
|
+
*/
|
|
12
|
+
export const SchemaBuilder = Object.freeze({
|
|
13
|
+
/**
|
|
14
|
+
* Build D1 schema from source schema
|
|
15
|
+
*/
|
|
16
|
+
buildD1Schema(sourceSchema, sourceDriver) {
|
|
17
|
+
Logger.info('Building D1 schema...');
|
|
18
|
+
return sourceSchema.map((table) => SchemaBuilder.buildD1Table(table, sourceDriver));
|
|
19
|
+
},
|
|
20
|
+
/**
|
|
21
|
+
* Build D1 table from source table
|
|
22
|
+
*/
|
|
23
|
+
buildD1Table(sourceTable, sourceDriver) {
|
|
24
|
+
const sanitizedTableName = DataValidator.sanitizeTableName(sourceTable.name);
|
|
25
|
+
const d1Table = {
|
|
26
|
+
name: sanitizedTableName,
|
|
27
|
+
columns: sourceTable.columns.map((column) => SchemaBuilder.buildD1Column(column, sourceDriver)),
|
|
28
|
+
primaryKey: sourceTable.primaryKeys?.[0] || '',
|
|
29
|
+
indexes: sourceTable.indexes || [],
|
|
30
|
+
primaryKeys: sourceTable.primaryKeys || [],
|
|
31
|
+
foreignKeys: sourceTable.foreignKeys || [],
|
|
32
|
+
};
|
|
33
|
+
Logger.info(`Converted table: ${sourceTable.name} -> ${sanitizedTableName}`);
|
|
34
|
+
return d1Table;
|
|
35
|
+
},
|
|
36
|
+
/**
|
|
37
|
+
* Build D1 column from source column
|
|
38
|
+
*/
|
|
39
|
+
buildD1Column(sourceColumn, sourceDriver) {
|
|
40
|
+
const d1Type = TypeConverter.convertToD1Type(sourceColumn.type, sourceDriver);
|
|
41
|
+
const warnings = TypeConverter.getConversionWarnings(sourceColumn.type, d1Type);
|
|
42
|
+
// Log conversion warnings
|
|
43
|
+
warnings.forEach((warning) => {
|
|
44
|
+
Logger.warn(`Column conversion warning: ${sourceColumn.name} - ${warning}`);
|
|
45
|
+
});
|
|
46
|
+
const d1Column = {
|
|
47
|
+
name: sourceColumn.name,
|
|
48
|
+
type: d1Type,
|
|
49
|
+
nullable: sourceColumn.nullable,
|
|
50
|
+
defaultValue: sourceColumn.defaultValue,
|
|
51
|
+
};
|
|
52
|
+
return d1Column;
|
|
53
|
+
},
|
|
54
|
+
/**
|
|
55
|
+
* Generate CREATE TABLE SQL
|
|
56
|
+
*/
|
|
57
|
+
generateCreateTableSQL(table) {
|
|
58
|
+
let sql = `CREATE TABLE \`${table.name}\` (\n`;
|
|
59
|
+
const columnDefinitions = table.columns.map((column) => SchemaBuilder.generateColumnDefinition(column));
|
|
60
|
+
sql += columnDefinitions.join(',\n');
|
|
61
|
+
if (table.primaryKey) {
|
|
62
|
+
const keyList = table.primaryKey;
|
|
63
|
+
sql += `,\n PRIMARY KEY (${keyList})`;
|
|
64
|
+
}
|
|
65
|
+
sql += '\n);';
|
|
66
|
+
return sql;
|
|
67
|
+
},
|
|
68
|
+
/**
|
|
69
|
+
* Generate column definition
|
|
70
|
+
*/
|
|
71
|
+
generateColumnDefinition(column) {
|
|
72
|
+
let definition = ` \`${column.name}\` ${column.type}`;
|
|
73
|
+
if (!column.nullable) {
|
|
74
|
+
definition += ' NOT NULL';
|
|
75
|
+
}
|
|
76
|
+
if (column.defaultValue !== undefined) {
|
|
77
|
+
definition += ` DEFAULT ${SchemaBuilder.formatDefaultValue(column.defaultValue)}`;
|
|
78
|
+
}
|
|
79
|
+
return definition;
|
|
80
|
+
},
|
|
81
|
+
/**
|
|
82
|
+
* Format default value for SQL
|
|
83
|
+
*/
|
|
84
|
+
formatDefaultValue(value) {
|
|
85
|
+
if (value === null) {
|
|
86
|
+
return 'NULL';
|
|
87
|
+
}
|
|
88
|
+
if (typeof value === 'string') {
|
|
89
|
+
return `'${value.replaceAll("'", "''")}'`;
|
|
90
|
+
}
|
|
91
|
+
if (typeof value === 'boolean') {
|
|
92
|
+
return value ? '1' : '0';
|
|
93
|
+
}
|
|
94
|
+
return String(value);
|
|
95
|
+
},
|
|
96
|
+
/**
|
|
97
|
+
* Generate index statements
|
|
98
|
+
*/
|
|
99
|
+
generateIndexSQL(table) {
|
|
100
|
+
const indexes = [];
|
|
101
|
+
if (table.indexes) {
|
|
102
|
+
table.indexes.forEach((index) => {
|
|
103
|
+
const indexName = `idx_${table.name}_${index.columns.join('_')}`;
|
|
104
|
+
const columns = index.columns.map((col) => `\`${col}\``).join(', ');
|
|
105
|
+
let sql = `CREATE`;
|
|
106
|
+
if (index.unique) {
|
|
107
|
+
sql += ' UNIQUE';
|
|
108
|
+
}
|
|
109
|
+
sql += ` INDEX \`${indexName}\` ON \`${table.name}\` (${columns});`;
|
|
110
|
+
indexes.push(sql);
|
|
111
|
+
});
|
|
112
|
+
}
|
|
113
|
+
return indexes;
|
|
114
|
+
},
|
|
115
|
+
/**
|
|
116
|
+
* Generate complete schema SQL
|
|
117
|
+
*/
|
|
118
|
+
generateSchemaSQL(tables) {
|
|
119
|
+
let sql = '-- D1 Schema Migration\n';
|
|
120
|
+
sql += '-- Generated by ZinTrust D1 Migrator\n\n';
|
|
121
|
+
tables.forEach((table) => {
|
|
122
|
+
sql += SchemaBuilder.generateCreateTableSQL(table);
|
|
123
|
+
sql += '\n\n';
|
|
124
|
+
const indexes = SchemaBuilder.generateIndexSQL(table);
|
|
125
|
+
indexes.forEach((indexSql) => {
|
|
126
|
+
sql += indexSql + '\n';
|
|
127
|
+
});
|
|
128
|
+
if (indexes.length > 0) {
|
|
129
|
+
sql += '\n';
|
|
130
|
+
}
|
|
131
|
+
});
|
|
132
|
+
return sql;
|
|
133
|
+
},
|
|
134
|
+
/**
|
|
135
|
+
* Validate built schema
|
|
136
|
+
*/
|
|
137
|
+
validateSchema(tables) {
|
|
138
|
+
const errors = [];
|
|
139
|
+
tables.forEach((table) => {
|
|
140
|
+
// Check table name
|
|
141
|
+
if (!DataValidator.sanitizeTableName(table.name)) {
|
|
142
|
+
errors.push(`Invalid table name: ${table.name}`);
|
|
143
|
+
}
|
|
144
|
+
// Check columns
|
|
145
|
+
table.columns.forEach((column) => {
|
|
146
|
+
if (!column.name || column.name.trim() === '') {
|
|
147
|
+
errors.push(`Empty column name in table: ${table.name}`);
|
|
148
|
+
}
|
|
149
|
+
if (!column.type || column.type.trim() === '') {
|
|
150
|
+
errors.push(`Empty column type: ${table.name}.${column.name}`);
|
|
151
|
+
}
|
|
152
|
+
});
|
|
153
|
+
if (table.primaryKey) {
|
|
154
|
+
const hasPrimaryKeyColumn = table.columns.some((column) => column.name === table.primaryKey);
|
|
155
|
+
if (!hasPrimaryKeyColumn) {
|
|
156
|
+
errors.push(`Primary key column '${table.primaryKey}' not found in table: ${table.name}`);
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
});
|
|
160
|
+
return {
|
|
161
|
+
valid: errors.length === 0,
|
|
162
|
+
errors,
|
|
163
|
+
};
|
|
164
|
+
},
|
|
165
|
+
});
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Type Converter
|
|
3
|
+
* Converts database types between different database systems
|
|
4
|
+
*/
|
|
5
|
+
/**
|
|
6
|
+
* TypeConverter - Sealed namespace for type conversion
|
|
7
|
+
* Provides database type conversion utilities
|
|
8
|
+
*/
|
|
9
|
+
export declare const TypeConverter: Readonly<{
|
|
10
|
+
/**
|
|
11
|
+
* Convert column type to D1/SQLite compatible type
|
|
12
|
+
*/
|
|
13
|
+
convertToD1Type(sourceType: string, sourceDriver: string): string;
|
|
14
|
+
/**
|
|
15
|
+
* Convert MySQL types to D1
|
|
16
|
+
*/
|
|
17
|
+
convertMySQLType(type: string): string;
|
|
18
|
+
/**
|
|
19
|
+
* Convert PostgreSQL types to D1
|
|
20
|
+
*/
|
|
21
|
+
convertPostgreSQLType(type: string): string;
|
|
22
|
+
/**
|
|
23
|
+
* Convert SQL Server types to D1
|
|
24
|
+
*/
|
|
25
|
+
convertSQLServerType(type: string): string;
|
|
26
|
+
/**
|
|
27
|
+
* Convert data value for D1 compatibility
|
|
28
|
+
*/
|
|
29
|
+
convertValue(value: unknown, targetType: string): unknown;
|
|
30
|
+
/**
|
|
31
|
+
* Get type conversion warnings
|
|
32
|
+
*/
|
|
33
|
+
getConversionWarnings(sourceType: string, targetType: string): string[];
|
|
34
|
+
}>;
|
|
35
|
+
//# sourceMappingURL=TypeConverter.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"TypeConverter.d.ts","sourceRoot":"","sources":["../../src/schema/TypeConverter.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAIH;;;GAGG;AACH,eAAO,MAAM,aAAa;IACxB;;OAEG;gCACyB,MAAM,gBAAgB,MAAM,GAAG,MAAM;IA4BjE;;OAEG;2BACoB,MAAM,GAAG,MAAM;IAmCtC;;OAEG;gCACyB,MAAM,GAAG,MAAM;IAoC3C;;OAEG;+BACwB,MAAM,GAAG,MAAM;IAgC1C;;OAEG;wBACiB,OAAO,cAAc,MAAM,GAAG,OAAO;IAuBzD;;OAEG;sCAC+B,MAAM,cAAc,MAAM,GAAG,MAAM,EAAE;EA2BvE,CAAC"}
|
|
@@ -0,0 +1,187 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Type Converter
|
|
3
|
+
* Converts database types between different database systems
|
|
4
|
+
*/
|
|
5
|
+
import { Logger } from '@zintrust/core';
|
|
6
|
+
/**
|
|
7
|
+
* TypeConverter - Sealed namespace for type conversion
|
|
8
|
+
* Provides database type conversion utilities
|
|
9
|
+
*/
|
|
10
|
+
export const TypeConverter = Object.freeze({
|
|
11
|
+
/**
|
|
12
|
+
* Convert column type to D1/SQLite compatible type
|
|
13
|
+
*/
|
|
14
|
+
convertToD1Type(sourceType, sourceDriver) {
|
|
15
|
+
const normalizedType = sourceType.toLowerCase().trim();
|
|
16
|
+
// MySQL conversions
|
|
17
|
+
if (sourceDriver === 'mysql') {
|
|
18
|
+
return TypeConverter.convertMySQLType(normalizedType);
|
|
19
|
+
}
|
|
20
|
+
// PostgreSQL conversions
|
|
21
|
+
if (sourceDriver === 'postgresql') {
|
|
22
|
+
return TypeConverter.convertPostgreSQLType(normalizedType);
|
|
23
|
+
}
|
|
24
|
+
// SQL Server conversions
|
|
25
|
+
if (sourceDriver === 'sqlserver') {
|
|
26
|
+
return TypeConverter.convertSQLServerType(normalizedType);
|
|
27
|
+
}
|
|
28
|
+
// SQLite is already compatible
|
|
29
|
+
if (sourceDriver === 'sqlite') {
|
|
30
|
+
return normalizedType;
|
|
31
|
+
}
|
|
32
|
+
// Default fallback
|
|
33
|
+
Logger.warn(`Unknown source type: ${normalizedType}, defaulting to TEXT`);
|
|
34
|
+
return 'TEXT';
|
|
35
|
+
},
|
|
36
|
+
/**
|
|
37
|
+
* Convert MySQL types to D1
|
|
38
|
+
*/
|
|
39
|
+
convertMySQLType(type) {
|
|
40
|
+
const conversions = {
|
|
41
|
+
varchar: 'TEXT',
|
|
42
|
+
char: 'TEXT',
|
|
43
|
+
text: 'TEXT',
|
|
44
|
+
longtext: 'TEXT',
|
|
45
|
+
mediumtext: 'TEXT',
|
|
46
|
+
tinytext: 'TEXT',
|
|
47
|
+
int: 'INTEGER',
|
|
48
|
+
integer: 'INTEGER',
|
|
49
|
+
bigint: 'INTEGER',
|
|
50
|
+
smallint: 'INTEGER',
|
|
51
|
+
tinyint: 'INTEGER',
|
|
52
|
+
decimal: 'REAL',
|
|
53
|
+
numeric: 'REAL',
|
|
54
|
+
float: 'REAL',
|
|
55
|
+
double: 'REAL',
|
|
56
|
+
datetime: 'TEXT',
|
|
57
|
+
timestamp: 'TEXT',
|
|
58
|
+
date: 'TEXT',
|
|
59
|
+
time: 'TEXT',
|
|
60
|
+
boolean: 'INTEGER',
|
|
61
|
+
'tinyint(1)': 'INTEGER',
|
|
62
|
+
json: 'TEXT',
|
|
63
|
+
enum: 'TEXT',
|
|
64
|
+
set: 'TEXT',
|
|
65
|
+
blob: 'BLOB',
|
|
66
|
+
longblob: 'BLOB',
|
|
67
|
+
mediumblob: 'BLOB',
|
|
68
|
+
tinyblob: 'BLOB',
|
|
69
|
+
};
|
|
70
|
+
return conversions[type] || 'TEXT';
|
|
71
|
+
},
|
|
72
|
+
/**
|
|
73
|
+
* Convert PostgreSQL types to D1
|
|
74
|
+
*/
|
|
75
|
+
convertPostgreSQLType(type) {
|
|
76
|
+
const conversions = {
|
|
77
|
+
varchar: 'TEXT',
|
|
78
|
+
'character varying': 'TEXT',
|
|
79
|
+
char: 'TEXT',
|
|
80
|
+
character: 'TEXT',
|
|
81
|
+
text: 'TEXT',
|
|
82
|
+
integer: 'INTEGER',
|
|
83
|
+
int: 'INTEGER',
|
|
84
|
+
int4: 'INTEGER',
|
|
85
|
+
bigint: 'INTEGER',
|
|
86
|
+
int8: 'INTEGER',
|
|
87
|
+
smallint: 'INTEGER',
|
|
88
|
+
int2: 'INTEGER',
|
|
89
|
+
decimal: 'REAL',
|
|
90
|
+
numeric: 'REAL',
|
|
91
|
+
real: 'REAL',
|
|
92
|
+
float4: 'REAL',
|
|
93
|
+
'double precision': 'REAL',
|
|
94
|
+
float8: 'REAL',
|
|
95
|
+
timestamp: 'TEXT',
|
|
96
|
+
timestamptz: 'TEXT',
|
|
97
|
+
date: 'TEXT',
|
|
98
|
+
time: 'TEXT',
|
|
99
|
+
timetz: 'TEXT',
|
|
100
|
+
boolean: 'INTEGER',
|
|
101
|
+
bool: 'INTEGER',
|
|
102
|
+
json: 'TEXT',
|
|
103
|
+
jsonb: 'TEXT',
|
|
104
|
+
uuid: 'TEXT',
|
|
105
|
+
bytea: 'BLOB',
|
|
106
|
+
};
|
|
107
|
+
return conversions[type] || 'TEXT';
|
|
108
|
+
},
|
|
109
|
+
/**
|
|
110
|
+
* Convert SQL Server types to D1
|
|
111
|
+
*/
|
|
112
|
+
convertSQLServerType(type) {
|
|
113
|
+
const conversions = {
|
|
114
|
+
varchar: 'TEXT',
|
|
115
|
+
char: 'TEXT',
|
|
116
|
+
nvarchar: 'TEXT',
|
|
117
|
+
nchar: 'TEXT',
|
|
118
|
+
text: 'TEXT',
|
|
119
|
+
ntext: 'TEXT',
|
|
120
|
+
int: 'INTEGER',
|
|
121
|
+
integer: 'INTEGER',
|
|
122
|
+
bigint: 'INTEGER',
|
|
123
|
+
smallint: 'INTEGER',
|
|
124
|
+
tinyint: 'INTEGER',
|
|
125
|
+
decimal: 'REAL',
|
|
126
|
+
numeric: 'REAL',
|
|
127
|
+
float: 'REAL',
|
|
128
|
+
real: 'REAL',
|
|
129
|
+
datetime: 'TEXT',
|
|
130
|
+
datetime2: 'TEXT',
|
|
131
|
+
smalldatetime: 'TEXT',
|
|
132
|
+
date: 'TEXT',
|
|
133
|
+
time: 'TEXT',
|
|
134
|
+
bit: 'INTEGER',
|
|
135
|
+
uniqueidentifier: 'TEXT',
|
|
136
|
+
varbinary: 'BLOB',
|
|
137
|
+
binary: 'BLOB',
|
|
138
|
+
image: 'BLOB',
|
|
139
|
+
};
|
|
140
|
+
return conversions[type] || 'TEXT';
|
|
141
|
+
},
|
|
142
|
+
/**
|
|
143
|
+
* Convert data value for D1 compatibility
|
|
144
|
+
*/
|
|
145
|
+
convertValue(value, targetType) {
|
|
146
|
+
if (value === null || value === undefined) {
|
|
147
|
+
return null;
|
|
148
|
+
}
|
|
149
|
+
// Handle boolean conversion
|
|
150
|
+
if (targetType === 'INTEGER' && typeof value === 'boolean') {
|
|
151
|
+
return value ? 1 : 0;
|
|
152
|
+
}
|
|
153
|
+
// Handle date/time conversion
|
|
154
|
+
if (targetType === 'TEXT' && value instanceof Date) {
|
|
155
|
+
return value.toISOString();
|
|
156
|
+
}
|
|
157
|
+
// Handle JSON conversion
|
|
158
|
+
if (targetType === 'TEXT' && typeof value === 'object') {
|
|
159
|
+
return JSON.stringify(value);
|
|
160
|
+
}
|
|
161
|
+
return value;
|
|
162
|
+
},
|
|
163
|
+
/**
|
|
164
|
+
* Get type conversion warnings
|
|
165
|
+
*/
|
|
166
|
+
getConversionWarnings(sourceType, targetType) {
|
|
167
|
+
const warnings = [];
|
|
168
|
+
const normalizedSourceType = sourceType.toLowerCase();
|
|
169
|
+
// Precision loss warnings
|
|
170
|
+
if (normalizedSourceType.includes('decimal') && targetType === 'REAL') {
|
|
171
|
+
warnings.push('Decimal to REAL conversion may cause precision loss');
|
|
172
|
+
}
|
|
173
|
+
// Size limitations
|
|
174
|
+
if (normalizedSourceType.includes('longtext') && targetType === 'TEXT') {
|
|
175
|
+
warnings.push('Large text fields may have size limitations in SQLite');
|
|
176
|
+
}
|
|
177
|
+
// Boolean conversion
|
|
178
|
+
if (normalizedSourceType.includes('boolean') && targetType === 'INTEGER') {
|
|
179
|
+
warnings.push('Boolean values will be converted to 0/1 integers');
|
|
180
|
+
}
|
|
181
|
+
// JSON conversion
|
|
182
|
+
if (normalizedSourceType.includes('json') && targetType === 'TEXT') {
|
|
183
|
+
warnings.push('JSON fields will be stored as text strings');
|
|
184
|
+
}
|
|
185
|
+
return warnings;
|
|
186
|
+
},
|
|
187
|
+
});
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Schema Validator
|
|
3
|
+
* Validates schemas and provides detailed error reporting
|
|
4
|
+
*/
|
|
5
|
+
import type { ColumnSchema, TableSchema } from '../types';
|
|
6
|
+
/**
|
|
7
|
+
* SchemaValidator - Sealed namespace for schema validation
|
|
8
|
+
* Provides comprehensive schema validation utilities
|
|
9
|
+
*/
|
|
10
|
+
export declare const SchemaValidator: Readonly<{
|
|
11
|
+
/**
|
|
12
|
+
* Validate complete schema
|
|
13
|
+
*/
|
|
14
|
+
validateSchema(tables: TableSchema[]): {
|
|
15
|
+
valid: boolean;
|
|
16
|
+
errors: string[];
|
|
17
|
+
warnings: string[];
|
|
18
|
+
};
|
|
19
|
+
/**
|
|
20
|
+
* Validate single table
|
|
21
|
+
*/
|
|
22
|
+
validateTable(table: TableSchema): {
|
|
23
|
+
valid: boolean;
|
|
24
|
+
errors: string[];
|
|
25
|
+
warnings: string[];
|
|
26
|
+
};
|
|
27
|
+
/**
|
|
28
|
+
* Validate single column
|
|
29
|
+
*/
|
|
30
|
+
validateColumn(column: ColumnSchema): {
|
|
31
|
+
valid: boolean;
|
|
32
|
+
errors: string[];
|
|
33
|
+
warnings: string[];
|
|
34
|
+
};
|
|
35
|
+
/**
|
|
36
|
+
* Check for schema compatibility issues
|
|
37
|
+
*/
|
|
38
|
+
checkCompatibility(issues: {
|
|
39
|
+
sourceDriver: string;
|
|
40
|
+
tables: TableSchema[];
|
|
41
|
+
}): {
|
|
42
|
+
blocking: string[];
|
|
43
|
+
warnings: string[];
|
|
44
|
+
};
|
|
45
|
+
/**
|
|
46
|
+
* Check column type compatibility for specific driver
|
|
47
|
+
*/
|
|
48
|
+
checkColumnTypeCompatibility(type: string, sourceDriver: string, tableName: string, columnName: string): string | null;
|
|
49
|
+
/**
|
|
50
|
+
* Check MySQL-specific compatibility
|
|
51
|
+
*/
|
|
52
|
+
checkMySQLCompatibility(type: string, tableName: string, columnName: string): string | null;
|
|
53
|
+
/**
|
|
54
|
+
* Check PostgreSQL-specific compatibility
|
|
55
|
+
*/
|
|
56
|
+
checkPostgreSQLCompatibility(type: string, tableName: string, columnName: string): string | null;
|
|
57
|
+
/**
|
|
58
|
+
* Check SQL Server-specific compatibility
|
|
59
|
+
*/
|
|
60
|
+
checkSQLServerCompatibility(type: string, tableName: string, columnName: string): string | null;
|
|
61
|
+
/**
|
|
62
|
+
* Check general compatibility issues
|
|
63
|
+
*/
|
|
64
|
+
checkGeneralCompatibility(type: string, tableName: string, columnName: string): string | null;
|
|
65
|
+
/**
|
|
66
|
+
* Generate validation report
|
|
67
|
+
*/
|
|
68
|
+
generateReport(validation: {
|
|
69
|
+
valid: boolean;
|
|
70
|
+
errors: string[];
|
|
71
|
+
warnings: string[];
|
|
72
|
+
}): string;
|
|
73
|
+
}>;
|
|
74
|
+
//# sourceMappingURL=Validator.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Validator.d.ts","sourceRoot":"","sources":["../../src/schema/Validator.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAAK,EAAE,YAAY,EAAE,WAAW,EAAE,MAAM,UAAU,CAAC;AAE1D;;;GAGG;AACH,eAAO,MAAM,eAAe;IAC1B;;OAEG;2BACoB,WAAW,EAAE,GAAG;QACrC,KAAK,EAAE,OAAO,CAAC;QACf,MAAM,EAAE,MAAM,EAAE,CAAC;QACjB,QAAQ,EAAE,MAAM,EAAE,CAAC;KACpB;IA8BD;;OAEG;yBACkB,WAAW,GAAG;QACjC,KAAK,EAAE,OAAO,CAAC;QACf,MAAM,EAAE,MAAM,EAAE,CAAC;QACjB,QAAQ,EAAE,MAAM,EAAE,CAAC;KACpB;IAyDD;;OAEG;2BACoB,YAAY,GAAG;QACpC,KAAK,EAAE,OAAO,CAAC;QACf,MAAM,EAAE,MAAM,EAAE,CAAC;QACjB,QAAQ,EAAE,MAAM,EAAE,CAAC;KACpB;IAoDD;;OAEG;+BACwB;QAAE,YAAY,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,WAAW,EAAE,CAAA;KAAE,GAAG;QAC3E,QAAQ,EAAE,MAAM,EAAE,CAAC;QACnB,QAAQ,EAAE,MAAM,EAAE,CAAC;KACpB;IAyBD;;OAEG;uCAEK,MAAM,gBACE,MAAM,aACT,MAAM,cACL,MAAM,GACjB,MAAM,GAAG,IAAI;IAahB;;OAEG;kCAC2B,MAAM,aAAa,MAAM,cAAc,MAAM,GAAG,MAAM,GAAG,IAAI;IAU3F;;OAEG;uCACgC,MAAM,aAAa,MAAM,cAAc,MAAM,GAAG,MAAM,GAAG,IAAI;IAUhG;;OAEG;sCAC+B,MAAM,aAAa,MAAM,cAAc,MAAM,GAAG,MAAM,GAAG,IAAI;IAU/F;;OAEG;oCAC6B,MAAM,aAAa,MAAM,cAAc,MAAM,GAAG,MAAM,GAAG,IAAI;IAO7F;;OAEG;+BACwB;QAAE,KAAK,EAAE,OAAO,CAAC;QAAC,MAAM,EAAE,MAAM,EAAE,CAAC;QAAC,QAAQ,EAAE,MAAM,EAAE,CAAA;KAAE,GAAG,MAAM;EAqB5F,CAAC"}
|