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();
|
||||||
Loading…
Reference in new issue