mysqldb.ts 5.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164
  1. /**
  2. * @Author HonorLee (dev@honorlee.me)
  3. * @Version 1.0 (2018-05-04)
  4. * @License MIT
  5. */
  6. import Mysql = require('mysql');
  7. interface DBClient{
  8. getConnection:(callback:(err:Error,connection:any)=>void|null)=>void;
  9. }
  10. //数据对象
  11. export class MysqlDB{
  12. private _pool:DBClient;
  13. constructor(option:DBOption){
  14. this._pool = new MysqlPool().create(option);
  15. }
  16. public query(queryStr:string,callback:(err:Error,ret:any,fields:any)=>void){
  17. this._pool.getConnection((err,con)=>{
  18. if(err) return callback(err,null,null);
  19. con.query(queryStr,(err:Error, ret:any, fields:any)=>{
  20. if(err){
  21. LOGGER.error(`MysqlDB: "${queryStr}" error`);
  22. if(err.stack) LOGGER.error(err.stack);
  23. }
  24. con.release();
  25. if(callback) callback(err,ret,fields);
  26. });
  27. });
  28. }
  29. public querySync(queryStr:string){
  30. return new Promise((resolve)=>{
  31. this._pool.getConnection((err,con)=>{
  32. if(err){
  33. if(err.stack) LOGGER.error(err.stack);
  34. return resolve({err:err,data:[]});
  35. }
  36. con.query(queryStr,(err:Error, ret:any, fields:any)=>{
  37. con.release();
  38. if(err){
  39. LOGGER.error(`MysqlDB: "${queryStr}" error`);
  40. if(err.stack) LOGGER.error(err.stack);
  41. return resolve({err:err,data:[]});
  42. }
  43. resolve({err:null,data:ret});
  44. });
  45. });
  46. })
  47. }
  48. objToKVString(obj:any,joinStr?:string,keyPrefix?:string){
  49. const strArr:Array<string> = [];
  50. Object.keys(obj).forEach(key =>{
  51. let v = obj[key];
  52. if(key=='extraStr'){
  53. if(Array.isArray(v)){
  54. strArr.push(v.join(joinStr));
  55. }else{
  56. strArr.push(v);
  57. }
  58. }else{
  59. if(typeof(v)=='string'){
  60. if(v[0]=='='){
  61. v = v.substring(1,-1);
  62. }else{
  63. v = `"${v}"`;
  64. }
  65. }
  66. keyPrefix = keyPrefix?keyPrefix:'';
  67. const sqlkey = `${keyPrefix}\`${key}\``;
  68. strArr.push(`${sqlkey}=${v}`);
  69. }
  70. })
  71. if(joinStr) return strArr.join(joinStr);
  72. return strArr.join(",");
  73. }
  74. async update(tablename:string,updateObj:any,whereObj:any){
  75. if(!tablename || !updateObj) return;
  76. let whereRule="";
  77. const updateRule = this.objToKVString(updateObj);
  78. if(whereObj){
  79. whereRule = ` where ${this.objToKVString(whereObj,' and ')}`;
  80. }
  81. const sqlStr = `update ${tablename} set ${updateRule} ${whereRule}`;
  82. return await this.querySync(sqlStr);
  83. }
  84. async select(tablename:string,queryField?:Array<string>,whereObj?:any){
  85. if(!tablename){
  86. const err = new Error("Missing table name")
  87. if(err.stack) LOGGER.error(err.stack);
  88. return {err:err,data:null};
  89. }
  90. let queryStr = "*",whereStr = "";
  91. if(queryField) queryStr = queryField.join(",");
  92. if(whereObj) whereStr = ` where ${this.objToKVString(whereObj,' and ')}`;
  93. const sql = `select ${queryStr} from ${tablename} ${whereStr}`;
  94. return await this.querySync(sql);
  95. }
  96. async insert(tablename:string,insertData:any){
  97. if(!tablename){
  98. const err = new Error("Missing table name")
  99. if(err.stack) LOGGER.error(err.stack);
  100. return {err:err,data:null};
  101. }
  102. if(!insertData){
  103. const err = new Error("Missing insertData")
  104. if(err.stack) LOGGER.error(err.stack);
  105. return {err:err,data:null};
  106. }
  107. let sql = `insert into ${tablename} `;
  108. if(insertData.constructor == Object){
  109. sql += `set ${this.objToKVString(insertData)}`;
  110. }else if(insertData.constructor == Array && insertData.length>0 && insertData[0].constructor == Object){
  111. const fields = Object.keys(insertData[0]);
  112. const values = [];
  113. for(const data of insertData){
  114. const valueArr = [];
  115. for(const key of fields){
  116. if(data[key] != null || data[key] != undefined){
  117. if(data[key].constructor == String){
  118. data[key] = `"${data[key]}"`;
  119. }else if(data[key].constructor == Number){
  120. data[key] = Number(data[key]);
  121. }
  122. }
  123. valueArr.push(data[key]);
  124. }
  125. values.push(`(${valueArr.join(',')})`);
  126. }
  127. for(const i in fields){
  128. fields[i] = `\`${fields[i]}\``;
  129. }
  130. sql += `(${fields.join(',')}) values ${values.join(',')}`;
  131. }else{
  132. const err = new Error("InsertData type not support")
  133. if(err.stack) LOGGER.error(err.stack);
  134. return {err:err,data:null};
  135. }
  136. return await this.querySync(sql);
  137. }
  138. }
  139. //连接池
  140. class MysqlPool{
  141. private _option:DBOption|null = null;
  142. private _pool:any;
  143. public Client:DBClient|null = null;
  144. create(option:DBOption):DBClient{
  145. this._option = option;
  146. this._pool = Mysql.createPool(option);
  147. this.Client = {
  148. getConnection:(callback)=>{
  149. if(!this._pool) throw new Error("Mysql pool not created!");
  150. if(!callback || typeof(callback)!='function') throw new Error("Mysql pool get connection lost callback!");
  151. this._pool.getConnection((err:any,connection:any)=>{
  152. callback(err,connection);
  153. });
  154. }
  155. }
  156. return this.Client;
  157. }
  158. }