ERP-node/backend-node/src/database/MariaDBConnector.ts

137 lines
4.2 KiB
TypeScript

import { DatabaseConnector, ConnectionConfig, QueryResult } from '../interfaces/DatabaseConnector';
import { ConnectionTestResult, TableInfo } from '../types/externalDbTypes';
// @ts-ignore
import * as mysql from 'mysql2/promise';
export class MariaDBConnector implements DatabaseConnector {
private connection: mysql.Connection | null = null;
private config: ConnectionConfig;
constructor(config: ConnectionConfig) {
this.config = config;
}
async connect(): Promise<void> {
if (!this.connection) {
this.connection = await mysql.createConnection({
host: this.config.host,
port: this.config.port,
user: this.config.user,
password: this.config.password,
database: this.config.database,
connectTimeout: this.config.connectionTimeoutMillis,
ssl: typeof this.config.ssl === 'boolean' ? undefined : this.config.ssl,
});
}
}
async disconnect(): Promise<void> {
if (this.connection) {
await this.connection.end();
this.connection = null;
}
}
async testConnection(): Promise<ConnectionTestResult> {
const startTime = Date.now();
try {
await this.connect();
const [rows] = await this.connection!.query("SELECT VERSION() as version");
const version = (rows as any[])[0]?.version || "Unknown";
const responseTime = Date.now() - startTime;
await this.disconnect();
return {
success: true,
message: "MariaDB/MySQL 연결이 성공했습니다.",
details: {
response_time: responseTime,
server_version: version,
},
};
} catch (error: any) {
await this.disconnect();
return {
success: false,
message: "MariaDB/MySQL 연결에 실패했습니다.",
error: {
code: "CONNECTION_FAILED",
details: error.message || "알 수 없는 오류",
},
};
}
}
async executeQuery(query: string): Promise<QueryResult> {
try {
await this.connect();
const [rows, fields] = await this.connection!.query(query);
await this.disconnect();
return {
rows: rows as any[],
fields: fields as any[],
};
} catch (error: any) {
await this.disconnect();
throw new Error(`쿼리 실행 실패: ${error.message}`);
}
}
async getTables(): Promise<TableInfo[]> {
try {
await this.connect();
const [rows] = await this.connection!.query(`
SELECT
TABLE_NAME as table_name,
TABLE_COMMENT as description
FROM information_schema.TABLES
WHERE TABLE_SCHEMA = DATABASE()
ORDER BY TABLE_NAME;
`);
const tables: TableInfo[] = [];
for (const row of rows as any[]) {
const columns = await this.getColumns(row.table_name);
tables.push({
table_name: row.table_name,
description: row.description || null,
columns: columns,
});
}
await this.disconnect();
return tables;
} catch (error: any) {
await this.disconnect();
throw new Error(`테이블 목록 조회 실패: ${error.message}`);
}
}
async getColumns(tableName: string): Promise<any[]> {
try {
console.log(`[MariaDBConnector] getColumns 호출: tableName=${tableName}`);
await this.connect();
console.log(`[MariaDBConnector] 연결 완료, 쿼리 실행 시작`);
const [rows] = await this.connection!.query(`
SELECT
COLUMN_NAME as column_name,
DATA_TYPE as data_type,
IS_NULLABLE as is_nullable,
COLUMN_DEFAULT as column_default
FROM information_schema.COLUMNS
WHERE TABLE_SCHEMA = DATABASE() AND TABLE_NAME = ?
ORDER BY ORDINAL_POSITION;
`, [tableName]);
console.log(`[MariaDBConnector] 쿼리 결과:`, rows);
console.log(`[MariaDBConnector] 결과 개수:`, Array.isArray(rows) ? rows.length : 'not array');
await this.disconnect();
return rows as any[];
} catch (error: any) {
console.error(`[MariaDBConnector] getColumns 오류:`, error);
await this.disconnect();
throw new Error(`컬럼 정보 조회 실패: ${error.message}`);
}
}
}