mirror of
https://github.com/chartdb/chartdb.git
synced 2025-10-24 16:43:59 +00:00
fix(performance): Import deps dynamically (#652)
This commit is contained in:
@@ -88,16 +88,16 @@ export const ImportDatabase: React.FC<ImportDatabaseProps> = ({
|
|||||||
|
|
||||||
if (!scriptResult.trim()) return;
|
if (!scriptResult.trim()) return;
|
||||||
|
|
||||||
const result = parseSQLError({
|
parseSQLError({
|
||||||
sqlContent: scriptResult,
|
sqlContent: scriptResult,
|
||||||
sourceDatabaseType: databaseType,
|
sourceDatabaseType: databaseType,
|
||||||
|
}).then((result) => {
|
||||||
|
if (result.success) {
|
||||||
|
setErrorMessage('');
|
||||||
|
} else if (!result.success && result.error) {
|
||||||
|
setErrorMessage(result.error);
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
if (result.success) {
|
|
||||||
setErrorMessage('');
|
|
||||||
} else if (!result.success && result.error) {
|
|
||||||
setErrorMessage(result.error);
|
|
||||||
}
|
|
||||||
}, [importMethod, scriptResult, databaseType]);
|
}, [importMethod, scriptResult, databaseType]);
|
||||||
|
|
||||||
// Check if the script result is a valid JSON
|
// Check if the script result is a valid JSON
|
||||||
|
|||||||
@@ -70,7 +70,7 @@ export const CreateDiagramDialog: React.FC<CreateDiagramDialogProps> = ({
|
|||||||
let diagram: Diagram | undefined;
|
let diagram: Diagram | undefined;
|
||||||
|
|
||||||
if (importMethod === 'ddl') {
|
if (importMethod === 'ddl') {
|
||||||
diagram = sqlImportToDiagram({
|
diagram = await sqlImportToDiagram({
|
||||||
sqlContent: scriptResult,
|
sqlContent: scriptResult,
|
||||||
sourceDatabaseType: databaseType,
|
sourceDatabaseType: databaseType,
|
||||||
targetDatabaseType: databaseType,
|
targetDatabaseType: databaseType,
|
||||||
|
|||||||
@@ -60,7 +60,7 @@ export const ImportDatabaseDialog: React.FC<ImportDatabaseDialogProps> = ({
|
|||||||
let diagram: Diagram | undefined;
|
let diagram: Diagram | undefined;
|
||||||
|
|
||||||
if (importMethod === 'ddl') {
|
if (importMethod === 'ddl') {
|
||||||
diagram = sqlImportToDiagram({
|
diagram = await sqlImportToDiagram({
|
||||||
sqlContent: scriptResult,
|
sqlContent: scriptResult,
|
||||||
sourceDatabaseType: databaseType,
|
sourceDatabaseType: databaseType,
|
||||||
targetDatabaseType: databaseType,
|
targetDatabaseType: databaseType,
|
||||||
|
|||||||
@@ -1,7 +1,3 @@
|
|||||||
import { Parser } from 'node-sql-parser';
|
|
||||||
|
|
||||||
// Common PostgreSQL parser instance
|
|
||||||
export const parser = new Parser();
|
|
||||||
export const parserOpts = {
|
export const parserOpts = {
|
||||||
database: 'MySQL', // Set dialect to MySQL
|
database: 'MySQL', // Set dialect to MySQL
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -13,12 +13,7 @@ import type {
|
|||||||
CreateTableStatement,
|
CreateTableStatement,
|
||||||
TableReference,
|
TableReference,
|
||||||
} from './mysql-common';
|
} from './mysql-common';
|
||||||
import {
|
import { parserOpts, extractColumnName, getTypeArgs } from './mysql-common';
|
||||||
parser,
|
|
||||||
parserOpts,
|
|
||||||
extractColumnName,
|
|
||||||
getTypeArgs,
|
|
||||||
} from './mysql-common';
|
|
||||||
|
|
||||||
// Interface for pending foreign keys that need to be processed later
|
// Interface for pending foreign keys that need to be processed later
|
||||||
interface PendingForeignKey {
|
interface PendingForeignKey {
|
||||||
@@ -213,7 +208,7 @@ function processCreateIndexStatement(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export function fromMySQL(sqlContent: string): SQLParserResult {
|
export async function fromMySQL(sqlContent: string): Promise<SQLParserResult> {
|
||||||
const tables: SQLTable[] = [];
|
const tables: SQLTable[] = [];
|
||||||
const relationships: SQLForeignKey[] = [];
|
const relationships: SQLForeignKey[] = [];
|
||||||
const tableMap: Record<string, string> = {}; // Maps table name to its ID
|
const tableMap: Record<string, string> = {}; // Maps table name to its ID
|
||||||
@@ -229,6 +224,8 @@ export function fromMySQL(sqlContent: string): SQLParserResult {
|
|||||||
// Process only CREATE TABLE statements
|
// Process only CREATE TABLE statements
|
||||||
if (trimmedStmt.toUpperCase().startsWith('CREATE TABLE')) {
|
if (trimmedStmt.toUpperCase().startsWith('CREATE TABLE')) {
|
||||||
try {
|
try {
|
||||||
|
const { Parser } = await import('node-sql-parser');
|
||||||
|
const parser = new Parser();
|
||||||
// Parse with SQL parser
|
// Parse with SQL parser
|
||||||
const ast = parser.astify(trimmedStmt, parserOpts);
|
const ast = parser.astify(trimmedStmt, parserOpts);
|
||||||
if (
|
if (
|
||||||
|
|||||||
@@ -1,7 +1,3 @@
|
|||||||
import { Parser } from 'node-sql-parser';
|
|
||||||
|
|
||||||
// Common PostgreSQL parser instance
|
|
||||||
export const parser = new Parser();
|
|
||||||
export const parserOpts = { database: 'postgresql' };
|
export const parserOpts = { database: 'postgresql' };
|
||||||
|
|
||||||
// Define interfaces for AST nodes - Fixed no-explicit-any issues
|
// Define interfaces for AST nodes - Fixed no-explicit-any issues
|
||||||
|
|||||||
@@ -14,7 +14,6 @@ import type {
|
|||||||
TableReference,
|
TableReference,
|
||||||
} from './postgresql-common';
|
} from './postgresql-common';
|
||||||
import {
|
import {
|
||||||
parser,
|
|
||||||
parserOpts,
|
parserOpts,
|
||||||
extractColumnName,
|
extractColumnName,
|
||||||
getTypeArgs,
|
getTypeArgs,
|
||||||
@@ -526,7 +525,9 @@ function processCreateIndexStatement(
|
|||||||
}
|
}
|
||||||
|
|
||||||
// PostgreSQL dump-specific parsing logic - optimized for pg_dump output format
|
// PostgreSQL dump-specific parsing logic - optimized for pg_dump output format
|
||||||
export function fromPostgresDump(sqlContent: string): SQLParserResult {
|
export async function fromPostgresDump(
|
||||||
|
sqlContent: string
|
||||||
|
): Promise<SQLParserResult> {
|
||||||
const tables: SQLTable[] = [];
|
const tables: SQLTable[] = [];
|
||||||
const relationships: SQLForeignKey[] = [];
|
const relationships: SQLForeignKey[] = [];
|
||||||
const tableMap: Record<string, string> = {}; // Maps table name to its ID
|
const tableMap: Record<string, string> = {}; // Maps table name to its ID
|
||||||
@@ -553,6 +554,8 @@ export function fromPostgresDump(sqlContent: string): SQLParserResult {
|
|||||||
// Phase 1: Process CREATE TABLE statements individually
|
// Phase 1: Process CREATE TABLE statements individually
|
||||||
for (const statement of createTableStatements) {
|
for (const statement of createTableStatements) {
|
||||||
try {
|
try {
|
||||||
|
const { Parser } = await import('node-sql-parser');
|
||||||
|
const parser = new Parser();
|
||||||
// Parse just this statement with the SQL parser
|
// Parse just this statement with the SQL parser
|
||||||
const ast = parser.astify(statement, parserOpts);
|
const ast = parser.astify(statement, parserOpts);
|
||||||
if (Array.isArray(ast) && ast.length > 0) {
|
if (Array.isArray(ast) && ast.length > 0) {
|
||||||
|
|||||||
@@ -19,7 +19,6 @@ import type {
|
|||||||
AlterTableStatement,
|
AlterTableStatement,
|
||||||
} from './postgresql-common';
|
} from './postgresql-common';
|
||||||
import {
|
import {
|
||||||
parser,
|
|
||||||
parserOpts,
|
parserOpts,
|
||||||
extractColumnName,
|
extractColumnName,
|
||||||
getTypeArgs,
|
getTypeArgs,
|
||||||
@@ -28,12 +27,16 @@ import {
|
|||||||
} from './postgresql-common';
|
} from './postgresql-common';
|
||||||
|
|
||||||
// PostgreSQL-specific parsing logic
|
// PostgreSQL-specific parsing logic
|
||||||
export function fromPostgres(sqlContent: string): SQLParserResult {
|
export async function fromPostgres(
|
||||||
|
sqlContent: string
|
||||||
|
): Promise<SQLParserResult> {
|
||||||
const tables: SQLTable[] = [];
|
const tables: SQLTable[] = [];
|
||||||
const relationships: SQLForeignKey[] = [];
|
const relationships: SQLForeignKey[] = [];
|
||||||
const tableMap: Record<string, string> = {}; // Maps table name to its ID
|
const tableMap: Record<string, string> = {}; // Maps table name to its ID
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
const { Parser } = await import('node-sql-parser');
|
||||||
|
const parser = new Parser();
|
||||||
// Parse the SQL DDL statements
|
// Parse the SQL DDL statements
|
||||||
const ast = parser.astify(sqlContent, parserOpts);
|
const ast = parser.astify(sqlContent, parserOpts);
|
||||||
|
|
||||||
|
|||||||
@@ -1,8 +1,6 @@
|
|||||||
import { Parser } from 'node-sql-parser';
|
|
||||||
import type { SQLASTNode } from '../../common';
|
import type { SQLASTNode } from '../../common';
|
||||||
|
|
||||||
// Set up the SQL parser with SQLite dialect
|
// Set up the SQL parser with SQLite dialect
|
||||||
export const parser = new Parser();
|
|
||||||
export const parserOpts = {
|
export const parserOpts = {
|
||||||
database: 'sqlite',
|
database: 'sqlite',
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -16,7 +16,6 @@ import type {
|
|||||||
AlterTableStatement,
|
AlterTableStatement,
|
||||||
} from './sqlite-common';
|
} from './sqlite-common';
|
||||||
import {
|
import {
|
||||||
parser as sqlParser,
|
|
||||||
parserOpts,
|
parserOpts,
|
||||||
extractColumnName,
|
extractColumnName,
|
||||||
getTypeArgs,
|
getTypeArgs,
|
||||||
@@ -27,15 +26,17 @@ import {
|
|||||||
/**
|
/**
|
||||||
* SQLite-specific parsing logic
|
* SQLite-specific parsing logic
|
||||||
*/
|
*/
|
||||||
export function fromSQLite(sqlContent: string): SQLParserResult {
|
export async function fromSQLite(sqlContent: string): Promise<SQLParserResult> {
|
||||||
const tables: SQLTable[] = [];
|
const tables: SQLTable[] = [];
|
||||||
const relationships: SQLForeignKey[] = [];
|
const relationships: SQLForeignKey[] = [];
|
||||||
const tableMap: Record<string, string> = {}; // Maps table name to its ID
|
const tableMap: Record<string, string> = {}; // Maps table name to its ID
|
||||||
|
|
||||||
try {
|
try {
|
||||||
// Parse the SQL DDL statements
|
// Parse the SQL DDL statements
|
||||||
|
const { Parser } = await import('node-sql-parser');
|
||||||
|
const parser = new Parser();
|
||||||
|
|
||||||
const ast = sqlParser.astify(
|
const ast = parser.astify(
|
||||||
sqlContent,
|
sqlContent,
|
||||||
parserOpts
|
parserOpts
|
||||||
) as unknown as SQLASTNode[];
|
) as unknown as SQLASTNode[];
|
||||||
|
|||||||
@@ -1,9 +1,7 @@
|
|||||||
import { Parser } from 'node-sql-parser';
|
|
||||||
import { generateId } from '@/lib/utils';
|
import { generateId } from '@/lib/utils';
|
||||||
import type { SQLASTNode } from '../../common';
|
import type { SQLASTNode } from '../../common';
|
||||||
|
|
||||||
// Set up the SQL parser with SQL Server dialect
|
// Set up the SQL parser with SQL Server dialect
|
||||||
export const parser = new Parser();
|
|
||||||
export const parserOpts = {
|
export const parserOpts = {
|
||||||
database: 'transactsql',
|
database: 'transactsql',
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -19,7 +19,6 @@ import type {
|
|||||||
AlterTableStatement,
|
AlterTableStatement,
|
||||||
} from './sqlserver-common';
|
} from './sqlserver-common';
|
||||||
import {
|
import {
|
||||||
parser,
|
|
||||||
parserOpts,
|
parserOpts,
|
||||||
extractColumnName,
|
extractColumnName,
|
||||||
getTypeArgs,
|
getTypeArgs,
|
||||||
@@ -273,7 +272,9 @@ function normalizeSQLServerDataType(dataType: string): string {
|
|||||||
* @param sqlContent SQL Server DDL content as string
|
* @param sqlContent SQL Server DDL content as string
|
||||||
* @returns Parsed structure including tables, columns, and relationships
|
* @returns Parsed structure including tables, columns, and relationships
|
||||||
*/
|
*/
|
||||||
export function fromSQLServer(sqlContent: string): SQLParserResult {
|
export async function fromSQLServer(
|
||||||
|
sqlContent: string
|
||||||
|
): Promise<SQLParserResult> {
|
||||||
const tables: SQLTable[] = [];
|
const tables: SQLTable[] = [];
|
||||||
const relationships: SQLForeignKey[] = [];
|
const relationships: SQLForeignKey[] = [];
|
||||||
const tableMap: Record<string, string> = {}; // Maps table name to its ID
|
const tableMap: Record<string, string> = {}; // Maps table name to its ID
|
||||||
@@ -302,6 +303,8 @@ export function fromSQLServer(sqlContent: string): SQLParserResult {
|
|||||||
relationships.push(...fkData);
|
relationships.push(...fkData);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const { Parser } = await import('node-sql-parser');
|
||||||
|
const parser = new Parser();
|
||||||
let ast;
|
let ast;
|
||||||
try {
|
try {
|
||||||
ast = parser.astify(preprocessedSQL, parserOpts);
|
ast = parser.astify(preprocessedSQL, parserOpts);
|
||||||
|
|||||||
@@ -166,7 +166,7 @@ export function detectDatabaseType(sqlContent: string): DatabaseType | null {
|
|||||||
* @param targetDatabaseType Target database type for the diagram
|
* @param targetDatabaseType Target database type for the diagram
|
||||||
* @returns Diagram object
|
* @returns Diagram object
|
||||||
*/
|
*/
|
||||||
export function sqlImportToDiagram({
|
export async function sqlImportToDiagram({
|
||||||
sqlContent,
|
sqlContent,
|
||||||
sourceDatabaseType,
|
sourceDatabaseType,
|
||||||
targetDatabaseType = DatabaseType.GENERIC,
|
targetDatabaseType = DatabaseType.GENERIC,
|
||||||
@@ -174,7 +174,7 @@ export function sqlImportToDiagram({
|
|||||||
sqlContent: string;
|
sqlContent: string;
|
||||||
sourceDatabaseType: DatabaseType;
|
sourceDatabaseType: DatabaseType;
|
||||||
targetDatabaseType: DatabaseType;
|
targetDatabaseType: DatabaseType;
|
||||||
}): Diagram {
|
}): Promise<Diagram> {
|
||||||
// If source database type is GENERIC, try to auto-detect the type
|
// If source database type is GENERIC, try to auto-detect the type
|
||||||
if (sourceDatabaseType === DatabaseType.GENERIC) {
|
if (sourceDatabaseType === DatabaseType.GENERIC) {
|
||||||
const detectedType = detectDatabaseType(sqlContent);
|
const detectedType = detectDatabaseType(sqlContent);
|
||||||
@@ -192,21 +192,21 @@ export function sqlImportToDiagram({
|
|||||||
case DatabaseType.POSTGRESQL:
|
case DatabaseType.POSTGRESQL:
|
||||||
// Check if the SQL is from pg_dump and use the appropriate parser
|
// Check if the SQL is from pg_dump and use the appropriate parser
|
||||||
if (isPgDumpFormat(sqlContent)) {
|
if (isPgDumpFormat(sqlContent)) {
|
||||||
parserResult = fromPostgresDump(sqlContent);
|
parserResult = await fromPostgresDump(sqlContent);
|
||||||
} else {
|
} else {
|
||||||
parserResult = fromPostgres(sqlContent);
|
parserResult = await fromPostgres(sqlContent);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case DatabaseType.MYSQL:
|
case DatabaseType.MYSQL:
|
||||||
// Check if the SQL is from MySQL dump and use the appropriate parser
|
// Check if the SQL is from MySQL dump and use the appropriate parser
|
||||||
parserResult = fromMySQL(sqlContent);
|
parserResult = await fromMySQL(sqlContent);
|
||||||
|
|
||||||
break;
|
break;
|
||||||
case DatabaseType.SQL_SERVER:
|
case DatabaseType.SQL_SERVER:
|
||||||
parserResult = fromSQLServer(sqlContent);
|
parserResult = await fromSQLServer(sqlContent);
|
||||||
break;
|
break;
|
||||||
case DatabaseType.SQLITE:
|
case DatabaseType.SQLITE:
|
||||||
parserResult = fromSQLite(sqlContent);
|
parserResult = await fromSQLite(sqlContent);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
throw new Error(`Unsupported database type: ${sourceDatabaseType}`);
|
throw new Error(`Unsupported database type: ${sourceDatabaseType}`);
|
||||||
@@ -246,35 +246,40 @@ export function sqlImportToDiagram({
|
|||||||
* @param sourceDatabaseType Source database type
|
* @param sourceDatabaseType Source database type
|
||||||
* @returns Object with success status and error information
|
* @returns Object with success status and error information
|
||||||
*/
|
*/
|
||||||
export function parseSQLError({
|
export async function parseSQLError({
|
||||||
sqlContent,
|
sqlContent,
|
||||||
sourceDatabaseType,
|
sourceDatabaseType,
|
||||||
}: {
|
}: {
|
||||||
sqlContent: string;
|
sqlContent: string;
|
||||||
sourceDatabaseType: DatabaseType;
|
sourceDatabaseType: DatabaseType;
|
||||||
}): { success: boolean; error?: string; line?: number; column?: number } {
|
}): Promise<{
|
||||||
|
success: boolean;
|
||||||
|
error?: string;
|
||||||
|
line?: number;
|
||||||
|
column?: number;
|
||||||
|
}> {
|
||||||
try {
|
try {
|
||||||
// Validate SQL based on the database type
|
// Validate SQL based on the database type
|
||||||
switch (sourceDatabaseType) {
|
switch (sourceDatabaseType) {
|
||||||
case DatabaseType.POSTGRESQL:
|
case DatabaseType.POSTGRESQL:
|
||||||
// PostgreSQL validation - check format and use appropriate parser
|
// PostgreSQL validation - check format and use appropriate parser
|
||||||
if (isPgDumpFormat(sqlContent)) {
|
if (isPgDumpFormat(sqlContent)) {
|
||||||
fromPostgresDump(sqlContent);
|
await fromPostgresDump(sqlContent);
|
||||||
} else {
|
} else {
|
||||||
fromPostgres(sqlContent);
|
await fromPostgres(sqlContent);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case DatabaseType.MYSQL:
|
case DatabaseType.MYSQL:
|
||||||
fromMySQL(sqlContent);
|
await fromMySQL(sqlContent);
|
||||||
|
|
||||||
break;
|
break;
|
||||||
case DatabaseType.SQL_SERVER:
|
case DatabaseType.SQL_SERVER:
|
||||||
// SQL Server validation
|
// SQL Server validation
|
||||||
fromSQLServer(sqlContent);
|
await fromSQLServer(sqlContent);
|
||||||
break;
|
break;
|
||||||
case DatabaseType.SQLITE:
|
case DatabaseType.SQLITE:
|
||||||
// SQLite validation
|
// SQLite validation
|
||||||
fromSQLite(sqlContent);
|
await fromSQLite(sqlContent);
|
||||||
break;
|
break;
|
||||||
// Add more database types here
|
// Add more database types here
|
||||||
default:
|
default:
|
||||||
|
|||||||
Reference in New Issue
Block a user