fix: too many connect error (#71)

* add fetch all struct

* add other database implement

* rename method name

* adjust the order of functions

* eslint

* eslint

* eslint

* eslint

* eslint

* fix error end when fetch schema batch
This commit is contained in:
CorrectRoadH
2023-05-04 23:36:48 +08:00
committed by GitHub
parent 498bf156c0
commit 40e86fbdaf
5 changed files with 138 additions and 8 deletions

View File

@ -16,6 +16,11 @@ export interface Connector {
tableName: string, tableName: string,
structureFetched: (tableName: string, structure: string) => void structureFetched: (tableName: string, structure: string) => void
) => Promise<void>; ) => Promise<void>;
getTableStructureBatch: (
databaseName: string,
tableNameList: string[],
structureFetched: (tableName: string, structure: string) => void
) => Promise<void>;
} }
export const newConnector = (connection: Connection): Connector => { export const newConnector = (connection: Connection): Connector => {

View File

@ -117,6 +117,39 @@ const getTableStructure = async (
); );
}; };
const getTableStructureBatch = async (
connection: Connection,
databaseName: string,
tableNameList: string[],
structureFetched: (tableName: string, structure: string) => void
): Promise<void> => {
const pool = await getMSSQLConnection(connection);
const request = pool.request();
await Promise.all(
tableNameList.map(async (tableName) => {
const { recordset } = await request.query(
`SELECT COLUMN_NAME, DATA_TYPE, IS_NULLABLE FROM ${databaseName}.INFORMATION_SCHEMA.COLUMNS WHERE TABLE_SCHEMA='dbo' AND TABLE_NAME='${tableName}';`
);
const columnList = [];
// Transform to standard schema string.
for (const row of recordset) {
columnList.push(
`${row["COLUMN_NAME"]} ${row["DATA_TYPE"].toUpperCase()} ${
String(row["IS_NULLABLE"]).toUpperCase() === "NO" ? "NOT NULL" : ""
}`
);
}
structureFetched(
tableName,
`CREATE TABLE [${tableName}] (
${columnList.join(",\n")}
);`
);
})
);
};
const newConnector = (connection: Connection): Connector => { const newConnector = (connection: Connection): Connector => {
return { return {
testConnection: () => testConnection(connection), testConnection: () => testConnection(connection),
@ -130,6 +163,17 @@ const newConnector = (connection: Connection): Connector => {
structureFetched: (tableName: string, structure: string) => void structureFetched: (tableName: string, structure: string) => void
) => ) =>
getTableStructure(connection, databaseName, tableName, structureFetched), getTableStructure(connection, databaseName, tableName, structureFetched),
getTableStructureBatch: (
databaseName: string,
tableNameList: string[],
structureFetched: (tableName: string, structure: string) => void
) =>
getTableStructureBatch(
connection,
databaseName,
tableNameList,
structureFetched
),
}; };
}; };

View File

@ -111,6 +111,29 @@ const getTableStructure = async (
structureFetched(tableName, rows[0]["Create Table"] || ""); structureFetched(tableName, rows[0]["Create Table"] || "");
}; };
const getTableStructureBatch = async (
connection: Connection,
databaseName: string,
tableNameList: string[],
structureFetched: (tableName: string, structure: string) => void
): Promise<void> => {
const conn = await getMySQLConnection(connection);
await Promise.all(
tableNameList.map(async (tableName) => {
const [rows] = await conn.query<RowDataPacket[]>(
`SHOW CREATE TABLE \`${databaseName}\`.\`${tableName}\`;`
);
if (rows.length !== 1) {
throw new Error("Unexpected number of rows.");
}
structureFetched(tableName, rows[0]["Create Table"] || "");
})
).finally(() => {
conn.destroy();
});
};
const newConnector = (connection: Connection): Connector => { const newConnector = (connection: Connection): Connector => {
return { return {
testConnection: () => testConnection(connection), testConnection: () => testConnection(connection),
@ -124,6 +147,17 @@ const newConnector = (connection: Connection): Connector => {
structureFetched: (tableName: string, structure: string) => void structureFetched: (tableName: string, structure: string) => void
) => ) =>
getTableStructure(connection, databaseName, tableName, structureFetched), getTableStructure(connection, databaseName, tableName, structureFetched),
getTableStructureBatch: (
databaseName: string,
tableNameList: string[],
structureFetched: (tableName: string, structure: string) => void
) =>
getTableStructureBatch(
connection,
databaseName,
tableNameList,
structureFetched
),
}; };
}; };

View File

@ -121,6 +121,42 @@ const getTableStructure = async (
); );
}; };
const getTableStructureBatch = async (
connection: Connection,
databaseName: string,
tableNameList: string[],
structureFetched: (tableName: string, structure: string) => void
): Promise<void> => {
connection.database = databaseName;
const client = newPostgresClient(connection);
await client.connect();
await Promise.all(
tableNameList.map(async (tableName) => {
const { rows } = await client.query(
`SELECT column_name, data_type, is_nullable FROM information_schema.columns WHERE table_schema='public' AND table_name=$1;`,
[tableName]
);
const columnList = [];
// TODO(steven): transform it to standard schema string.
for (const row of rows) {
columnList.push(
`${row["column_name"]} ${row["data_type"].toUpperCase()} ${
String(row["is_nullable"]).toUpperCase() === "NO" ? "NOT NULL" : ""
}`
);
}
structureFetched(
tableName,
`CREATE TABLE \`${tableName}\` (
${columnList.join(",\n")}
);`
);
})
).finally(async () => {
await client.end();
});
};
const newConnector = (connection: Connection): Connector => { const newConnector = (connection: Connection): Connector => {
return { return {
testConnection: () => testConnection(connection), testConnection: () => testConnection(connection),
@ -134,6 +170,17 @@ const newConnector = (connection: Connection): Connector => {
structureFetched: (tableName: string, structure: string) => void structureFetched: (tableName: string, structure: string) => void
) => ) =>
getTableStructure(connection, databaseName, tableName, structureFetched), getTableStructure(connection, databaseName, tableName, structureFetched),
getTableStructureBatch: (
databaseName: string,
tableNameList: string[],
structureFetched: (tableName: string, structure: string) => void
) =>
getTableStructureBatch(
connection,
databaseName,
tableNameList,
structureFetched
),
}; };
}; };

View File

@ -22,14 +22,14 @@ const handler = async (req: NextApiRequest, res: NextApiResponse) => {
structure, structure,
}); });
}; };
Promise.all( await connector.getTableStructureBatch(
rawTableNameList.map(async (tableName) => db,
connector.getTableStructure(db, tableName, structureFetched) rawTableNameList,
) structureFetched
).then(() => { );
res.status(200).json({
data: tableStructures, res.status(200).json({
}); data: tableStructures,
}); });
} catch (error: any) { } catch (error: any) {
res.status(400).json({ res.status(400).json({