parent
f45ee680d4
commit
955f22cd75
Binary file not shown.
@ -0,0 +1,2 @@
|
||||
export * from './mysql';
|
||||
export * from './redis';
|
||||
@ -0,0 +1,86 @@
|
||||
import mysql from 'mysql2/promise';
|
||||
import { config } from '../index';
|
||||
import { logger } from '../../utils/logger';
|
||||
|
||||
class MySQLConnection {
|
||||
private pool: mysql.Pool | null = null;
|
||||
|
||||
async connect() {
|
||||
try {
|
||||
this.pool = mysql.createPool({
|
||||
host: config.database.mysql.host,
|
||||
port: config.database.mysql.port,
|
||||
user: config.database.mysql.user,
|
||||
password: config.database.mysql.password,
|
||||
database: config.database.mysql.database,
|
||||
waitForConnections: true,
|
||||
connectionLimit: 10,
|
||||
queueLimit: 0
|
||||
});
|
||||
|
||||
// 测试连接
|
||||
const connection = await this.pool.getConnection();
|
||||
logger.log('MySQL连接成功');
|
||||
connection.release();
|
||||
|
||||
// 初始化表结构
|
||||
await this.initTables();
|
||||
} catch (error) {
|
||||
logger.error('MySQL连接失败:', error);
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
|
||||
async initTables() {
|
||||
if (!this.pool) {
|
||||
throw new Error('MySQL连接未初始化');
|
||||
}
|
||||
|
||||
try {
|
||||
// 创建市场数据表格
|
||||
await this.pool.execute(`
|
||||
CREATE TABLE IF NOT EXISTS market_data (
|
||||
id INT AUTO_INCREMENT PRIMARY KEY,
|
||||
symbol VARCHAR(20) NOT NULL,
|
||||
type VARCHAR(20) NOT NULL,
|
||||
data JSON NOT NULL,
|
||||
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
||||
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
|
||||
UNIQUE KEY unique_symbol_type (symbol, type)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
|
||||
`);
|
||||
|
||||
logger.log('MySQL表结构初始化完成');
|
||||
} catch (error) {
|
||||
logger.error('初始化MySQL表结构失败:', error);
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
|
||||
async getConnection() {
|
||||
if (!this.pool) {
|
||||
await this.connect();
|
||||
}
|
||||
return this.pool!.getConnection();
|
||||
}
|
||||
|
||||
async query(sql: string, values?: any[]) {
|
||||
if (!this.pool) {
|
||||
await this.connect();
|
||||
}
|
||||
if (values) {
|
||||
return this.pool!.execute(sql, values);
|
||||
} else {
|
||||
return this.pool!.execute(sql);
|
||||
}
|
||||
}
|
||||
|
||||
async close() {
|
||||
if (this.pool) {
|
||||
await this.pool.end();
|
||||
logger.log('MySQL连接已关闭');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export const mysqlConnection = new MySQLConnection();
|
||||
@ -0,0 +1,84 @@
|
||||
import { createClient } from 'redis';
|
||||
import { config } from '../index';
|
||||
import { logger } from '../../utils/logger';
|
||||
|
||||
class RedisConnection {
|
||||
private client: ReturnType<typeof createClient> | null = null;
|
||||
|
||||
async connect() {
|
||||
try {
|
||||
this.client = createClient({
|
||||
url: config.redis.url
|
||||
});
|
||||
|
||||
this.client.on('error', (error) => {
|
||||
logger.error('Redis连接错误:', error);
|
||||
});
|
||||
|
||||
this.client.on('connect', () => {
|
||||
logger.log('Redis连接成功');
|
||||
});
|
||||
|
||||
this.client.on('end', () => {
|
||||
logger.log('Redis连接已关闭');
|
||||
});
|
||||
|
||||
await this.client.connect();
|
||||
} catch (error) {
|
||||
logger.error('Redis连接失败:', error);
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
|
||||
async getClient() {
|
||||
if (!this.client || !this.client.isReady) {
|
||||
await this.connect();
|
||||
}
|
||||
return this.client!;
|
||||
}
|
||||
|
||||
async get(key: string) {
|
||||
const client = await this.getClient();
|
||||
return client.get(key);
|
||||
}
|
||||
|
||||
async set(key: string, value: string | number | Buffer, options?: {
|
||||
ex?: number;
|
||||
px?: number;
|
||||
nx?: boolean;
|
||||
xx?: boolean;
|
||||
}) {
|
||||
const client = await this.getClient();
|
||||
const stringValue = typeof value === 'object' ? JSON.stringify(value) : String(value);
|
||||
if (options) {
|
||||
// 使用Redis v4的正确set方法参数格式
|
||||
const setOptions: any = {};
|
||||
if (options.ex) setOptions.EX = options.ex;
|
||||
if (options.px) setOptions.PX = options.px;
|
||||
if (options.nx) setOptions.NX = options.nx;
|
||||
if (options.xx) setOptions.XX = options.xx;
|
||||
return client.set(key, stringValue, setOptions);
|
||||
} else {
|
||||
return client.set(key, stringValue);
|
||||
}
|
||||
}
|
||||
|
||||
async del(key: string) {
|
||||
const client = await this.getClient();
|
||||
return client.del(key);
|
||||
}
|
||||
|
||||
async exists(key: string) {
|
||||
const client = await this.getClient();
|
||||
return client.exists(key);
|
||||
}
|
||||
|
||||
async close() {
|
||||
if (this.client) {
|
||||
await this.client.quit();
|
||||
logger.log('Redis连接已关闭');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export const redisConnection = new RedisConnection();
|
||||
File diff suppressed because it is too large
Load Diff
Loading…
Reference in new issue