feat: optimize fetch database schema (#65)

This commit is contained in:
CorrectRoadH
2023-04-24 23:11:32 +08:00
committed by GitHub
parent 3264797661
commit 0471e40684
5 changed files with 19 additions and 17 deletions

View File

@ -8,7 +8,7 @@ export interface Connector {
execute: (databaseName: string, statement: string) => Promise<ExecutionResult>; execute: (databaseName: string, statement: string) => Promise<ExecutionResult>;
getDatabases: () => Promise<string[]>; getDatabases: () => Promise<string[]>;
getTables: (databaseName: string) => Promise<string[]>; getTables: (databaseName: string) => Promise<string[]>;
getTableStructure: (databaseName: string, tableName: string) => Promise<string>; getTableStructure: (databaseName: string, tableName: string, structureFetched: (tableName: string, structure: string) => void) => Promise<void>;
} }
export const newConnector = (connection: Connection): Connector => { export const newConnector = (connection: Connection): Connector => {

View File

@ -75,7 +75,7 @@ const getTables = async (connection: Connection, databaseName: string): Promise<
return tableList; return tableList;
}; };
const getTableStructure = async (connection: Connection, databaseName: string, tableName: string): Promise<string> => { const getTableStructure = async (connection: Connection, databaseName: string, tableName: string, structureFetched: (tableName: string,structure: string) => void): Promise<void> => {
const pool = await getMSSQLConnection(connection); const pool = await getMSSQLConnection(connection);
const request = pool.request(); const request = pool.request();
const { recordset } = await request.query( const { recordset } = await request.query(
@ -89,10 +89,9 @@ const getTableStructure = async (connection: Connection, databaseName: string, t
`${row["COLUMN_NAME"]} ${row["DATA_TYPE"].toUpperCase()} ${String(row["IS_NULLABLE"]).toUpperCase() === "NO" ? "NOT NULL" : ""}` `${row["COLUMN_NAME"]} ${row["DATA_TYPE"].toUpperCase()} ${String(row["IS_NULLABLE"]).toUpperCase() === "NO" ? "NOT NULL" : ""}`
); );
} }
structureFetched(tableName, `CREATE TABLE [${tableName}] (
return `CREATE TABLE [${tableName}] (
${columnList.join(",\n")} ${columnList.join(",\n")}
);`; );`);
}; };
const newConnector = (connection: Connection): Connector => { const newConnector = (connection: Connection): Connector => {
@ -101,7 +100,7 @@ const newConnector = (connection: Connection): Connector => {
execute: (databaseName: string, statement: string) => execute(connection, databaseName, statement), execute: (databaseName: string, statement: string) => execute(connection, databaseName, statement),
getDatabases: () => getDatabases(connection), getDatabases: () => getDatabases(connection),
getTables: (databaseName: string) => getTables(connection, databaseName), getTables: (databaseName: string) => getTables(connection, databaseName),
getTableStructure: (databaseName: string, tableName: string) => getTableStructure(connection, databaseName, tableName), getTableStructure: (databaseName: string, tableName: string, structureFetched: (tableName: string, structure: string) => void) => getTableStructure(connection, databaseName, tableName, structureFetched),
}; };
}; };

View File

@ -80,14 +80,14 @@ const getTables = async (connection: Connection, databaseName: string): Promise<
return tableList; return tableList;
}; };
const getTableStructure = async (connection: Connection, databaseName: string, tableName: string): Promise<string> => { const getTableStructure = async (connection: Connection, databaseName: string, tableName: string, structureFetched: (tableName: string,structure: string) => void): Promise<void> => {
const conn = await getMySQLConnection(connection); const conn = await getMySQLConnection(connection);
const [rows] = await conn.query<RowDataPacket[]>(`SHOW CREATE TABLE \`${databaseName}\`.\`${tableName}\`;`); const [rows] = await conn.query<RowDataPacket[]>(`SHOW CREATE TABLE \`${databaseName}\`.\`${tableName}\`;`);
conn.destroy(); conn.destroy();
if (rows.length !== 1) { if (rows.length !== 1) {
throw new Error("Unexpected number of rows."); throw new Error("Unexpected number of rows.");
} }
return rows[0]["Create Table"] || ""; structureFetched(tableName, rows[0]["Create Table"] || "");
}; };
const newConnector = (connection: Connection): Connector => { const newConnector = (connection: Connection): Connector => {
@ -96,7 +96,7 @@ const newConnector = (connection: Connection): Connector => {
execute: (databaseName: string, statement: string) => execute(connection, databaseName, statement), execute: (databaseName: string, statement: string) => execute(connection, databaseName, statement),
getDatabases: () => getDatabases(connection), getDatabases: () => getDatabases(connection),
getTables: (databaseName: string) => getTables(connection, databaseName), getTables: (databaseName: string) => getTables(connection, databaseName),
getTableStructure: (databaseName: string, tableName: string) => getTableStructure(connection, databaseName, tableName), getTableStructure: (databaseName: string, tableName: string, structureFetched: (tableName: string, structure: string) => void) => getTableStructure(connection, databaseName, tableName, structureFetched),
}; };
}; };

View File

@ -83,7 +83,7 @@ const getTables = async (connection: Connection, databaseName: string): Promise<
return tableList; return tableList;
}; };
const getTableStructure = async (connection: Connection, databaseName: string, tableName: string): Promise<string> => { const getTableStructure = async (connection: Connection, databaseName: string, tableName: string, structureFetched: (tableName: string,structure: string) => void): Promise<void> => {
connection.database = databaseName; connection.database = databaseName;
const client = newPostgresClient(connection); const client = newPostgresClient(connection);
await client.connect(); await client.connect();
@ -99,9 +99,9 @@ const getTableStructure = async (connection: Connection, databaseName: string, t
`${row["column_name"]} ${row["data_type"].toUpperCase()} ${String(row["is_nullable"]).toUpperCase() === "NO" ? "NOT NULL" : ""}` `${row["column_name"]} ${row["data_type"].toUpperCase()} ${String(row["is_nullable"]).toUpperCase() === "NO" ? "NOT NULL" : ""}`
); );
} }
return `CREATE TABLE \`${tableName}\` ( structureFetched(tableName, `CREATE TABLE \`${tableName}\` (
${columnList.join(",\n")} ${columnList.join(",\n")}
);`; );`);
}; };
const newConnector = (connection: Connection): Connector => { const newConnector = (connection: Connection): Connector => {
@ -110,7 +110,7 @@ const newConnector = (connection: Connection): Connector => {
execute: (databaseName: string, statement: string) => execute(connection, databaseName, statement), execute: (databaseName: string, statement: string) => execute(connection, databaseName, statement),
getDatabases: () => getDatabases(connection), getDatabases: () => getDatabases(connection),
getTables: (databaseName: string) => getTables(connection, databaseName), getTables: (databaseName: string) => getTables(connection, databaseName),
getTableStructure: (databaseName: string, tableName: string) => getTableStructure(connection, databaseName, tableName), getTableStructure: (databaseName: string, tableName: string, structureFetched: (tableName: string, structure: string) => void) => getTableStructure(connection, databaseName, tableName, structureFetched),
}; };
}; };

View File

@ -16,16 +16,19 @@ const handler = async (req: NextApiRequest, res: NextApiResponse) => {
const connector = newConnector(connection); const connector = newConnector(connection);
const tableStructures: Table[] = []; const tableStructures: Table[] = [];
const rawTableNameList = await connector.getTables(db); const rawTableNameList = await connector.getTables(db);
for (const tableName of rawTableNameList) { const structureFetched = (tableName:string, structure:string) => {
const structure = await connector.getTableStructure(db, tableName);
tableStructures.push({ tableStructures.push({
name: tableName, name: tableName,
structure, structure,
}); });
} }
Promise.all(rawTableNameList.map(async (tableName) =>
connector.getTableStructure(db, tableName, structureFetched)
)).then(() => {
res.status(200).json({ res.status(200).json({
data: tableStructures, data: tableStructures,
}); });
});
} catch (error: any) { } catch (error: any) {
res.status(400).json({ res.status(400).json({
message: error.message || "Failed to get database schema.", message: error.message || "Failed to get database schema.",