import {MysqlDB} from '../extra/mysqldb'; // const RedisBridge = require(Core.Path.ExtraLib + '/redisdb.js'); import MongoDB from 'mongodb'; import MemcacheDB from 'memcached'; import * as RedisDB from 'redis'; //默认配置 const DatabaseOption:any = { mysql : '{"host":"localhost","port":3306,"user":"root","password":"","database":"","prefix":"","connectionLimit":10}', mongodb : '{"host":"localhost","port":27017,"user":null,"password":"","database":"","prefix":""}', memcache : '{"host":"localhost","port":11211}', redis : '{"host":"localhost","port":6379,"prefix":null}' } class Database { /** * @param {String} DatabaseType 数据库类型 * @param {Object} option 数据库配置 * @param {String} GlobalName 自动全局命名 * @param {Function} callback 回调函数 */ public static create(DatabaseType:string,option:DBOption,GlobalName?:string,callback?:(err:Error|null,conn?:any)=>void){ DatabaseType = DatabaseType.toLowerCase(); switch(DatabaseType){ case 'mysql': Creater._createMysqlConnection(option,GlobalName,callback); break; case 'mongodb': Creater._createMongoConnection(option,GlobalName,callback); break; case 'memcache': Creater._createMemcacheConnection(option,GlobalName,callback); break; case 'redis': Creater._createRedisConnection(option,GlobalName,callback); break; default: if(callback) callback(new Error('Wrong database type!')); } } //生成默认配置 public static getOption(type:string){ type = type.toLowerCase(); if(DatabaseOption[type]!=undefined){ return JSON.parse(DatabaseOption[type]); }else{ return null; } } } //连接控制器 class Creater{ static _createMysqlConnection (option:DBOption,GlobalName?:string,callback?:(err:Error|null,conn?:any)=>void){ const _MysqlDB = new MysqlDB(option); // if(!callback || typeof(callback)!='function') callback = ()=>{return} //连接测试 _MysqlDB.query('SELECT VERSION() as version',(err,result,fields?:any)=>{ if(err){ LOGGER.error('Mysql Connect error,please recheck your config'); if(err.stack) LOGGER.error(err.stack); if(callback) callback(err,null); return; }else{ LOGGER.info('Mysql Connect success'); LOGGER.info(`Mysql Version: ${result[0]['version']} | User: ${option.username} | Database: ${option.database} | GlobalName: ${GlobalName}`); if(GlobalName){ if((global as any)[GlobalName]){ LOGGER.error(`Create global name fail with "${GlobalName}"`); if(callback) callback(new Error('Duplicate global name'),null); return; }else{ (global as any)[GlobalName] = _MysqlDB; } } if(callback) callback(null,_MysqlDB); } }); } static _createMongoConnection(option:DBOption,GlobalName?:string,callback?:(err:Error|null,conn?:any)=>void){ const verify = option.username?option.username+':'+option.password+'@':''; const mongoConnect = 'mongodb://' + verify + option.host+':'+option.port+'/'+option.database; // if(!callback) callback = ()=>{return} MongoDB.MongoClient.connect(mongoConnect,(err?:Error,db?:any)=>{ if(err) { LOGGER.error('MongoDB connect error!'); if(err.stack) LOGGER.error(err.stack); if(callback) callback(err,null); return; }else{ LOGGER.info(`Mongodb Connect success | GlobalName: ${GlobalName}`); const _mongoClient = { db:db, c:(collection:any)=>{ return db.collection(option.prefix+collection); } }; if(GlobalName){ if((global as any)[GlobalName]){ LOGGER.error(`Create global name fail with "${GlobalName}"`); if(callback) callback(new Error('Duplicate global name'),null); return; } (global as any)[GlobalName] = _mongoClient; } if(callback) callback(null,_mongoClient); } }); } static _createMemcacheConnection(option:DBOption,GlobalName?:string,callback?:(err:Error|null,conn?:any)=>void){ const _Memcache = new MemcacheDB(option.host+':'+option.port); _Memcache.version(function(err,data){ if(err){ LOGGER.error('Memcache Connect error,please recheck your config'); LOGGER.error(err); if(callback) callback(err,null); return; }else{ LOGGER.info('Memcache Connect success'); LOGGER.info(`Memcache Version: ${data[0]['version']} | GlobalName: ${GlobalName}`); if(GlobalName){ if((global as any)[GlobalName]){ LOGGER.error(`Create global name fail with "${GlobalName}"`); if(callback) callback(new Error('Duplicate global name'),null); return; }else{ (global as any)[GlobalName] = _Memcache; } } if(callback) callback(null,_Memcache); } }); } static async _createRedisConnection(option:DBOption,GlobalName?:string,callback?:(err:Error|null,conn?:any)=>void){ let _redisConnStr = `${option.host}:${option.port}`; if(option.username){ if(option.password){ _redisConnStr = `${option.username}:${option.password}@${_redisConnStr}`; }else{ _redisConnStr = `${option.username}@${_redisConnStr}`; } } _redisConnStr = `redis://${_redisConnStr}`; const _redisClient = RedisDB.createClient({url:_redisConnStr,socket:{keepAlive:30000}}); _redisClient.on('error',(err:Error)=>{ if(err instanceof RedisDB.SocketClosedUnexpectedlyError){ LOGGER.error(`Redis [${option.host}:${option.port}] connect has been refused,please recheck your config,and make sure redis server is running!`); } }) _redisClient.on('ready',async ()=>{ LOGGER.info('Redis Connect success'); const infoStr = await _redisClient.info(); const infoLine = infoStr.split('\n'); const info:any = {}; for(const line of infoLine){ const lineArr = line.split(':'); if(lineArr.length>1) info[lineArr[0]] = lineArr[1]; } if(info.redis_version) LOGGER.info(`GlobalName: ${GlobalName} | Redis Version: ${info.redis_version}`); // _redisClient.stream.setKeepAlive(true,30 * 1000); if(GlobalName){ if((global as any)[GlobalName]){ LOGGER.error(`Create global name fail with "${GlobalName}"`); if(callback) callback(new Error('Duplicate global name'),null); return; }else{ (global as any)[GlobalName] = _redisClient; } } if(callback) callback(null,_redisClient); }); _redisClient.on('reconnecting',function(e:any){ LOGGER.warn('Redis lost connect,reconnecting!'); }); await _redisClient.connect(); // {port:option.port,host:option.host,socket_keepalive:true,socket_initialdelay:30000,retry_strategy: function (retryData) { // if (retryData.error && retryData.error.code === 'ECONNREFUSED') { // } // if (retryData.total_retry_time > 1000 * 10) { // LOGGER.error('Redis retry connect time exhausted'); // } // if (retryData.attempt > 10) { // LOGGER.error('Redis unknow error'); // } // // reconnect after // return Math.min(retryData.attempt * 100, 3000); // },prefix:option.prefix}); // if(!callback || typeof(callback)!='function') callback = ()=>{} } } // (global as any).DBManager = Database; module.exports = Database;