123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253 |
- const mysql = require('mysql');
- const sys = require('../config/sys_test');
- const pool = mysql.createPool({
- connectionLimit: 1,
- connectTimeout: 60 * 60 * 1000,
- host: sys.mysql.host,
- user: sys.mysql.user,
- password: sys.mysql.pwd,
- database: sys.mysql.db
- });
- class DBModule {
- constructor(args = {}) {
- Object.keys(args).forEach(key => {
- this[key] = args[key];
- })
- }
- /**
- * 使用连接池中已有的连接执行sql脚本
- * @param {string} sql sql脚本
- * @param {array} args sql中的参数
- * @return {promise}
- */
- _query(sql, args = []) {
- return new Promise((resolve, reject) => {
- pool.getConnection((err, connection) => {
- if (err) return reject(err);
- if (sys.debug) {
- console.log(`run ${sql} \narray ${args.map(item=> `${item} type: ${typeof item}\n`)}`)
- }
- connection.query(sql, args, (err, result) => {
- if (err) {
- reject(err);
- } else {
- resolve(result);
- }
-
- connection.release();
- });
- });
- });
- }
-
- /**
- * 执行对象插入数据库操作
- * @return {promise}
- */
- insert() {
- let sql, {attrs, vals, err} = DBModule.getDBModuleArgs(this);
- if (err) {
- throw `object ${this.constructor.toString()} lack necessary field (table, fields)`;
- }
- sql = `insert into \`${this.table}\`(${attrs.join(',')}) values(${vals.map(()=>'?')})`;
- return this._query(sql, vals);
- }
- /**
- * 执行对象更新映射到数据库操作,对象必须存在有效的主键
- * @return {promise}
- */
- update() {
- let sql, setFields, attrs, vals, err;
- if (this[this.primary] === undefined || this[this.primary] === null) {
- throw `object ${this.constructor.toString()} ${this.primary} is ${this[this.primary]}`;
- }
- ({attrs, vals, err} = DBModule.getDBModuleArgs(this));
- if (err) {
- throw `object ${this.constructor.toString()} lack necessary field (table, fields)`;
- }
- vals.push(this[this.primary]);
- setFields = attrs.map(attr=>`${attr}=?`);
- sql = `update \`${this.table}\` set ${setFields.join(',')} where ${this.primary}=?`;
- return this._query(sql, vals);
- }
- /**
- * 查看某条件的数据是否存在
- * @return {promise}
- */
- exists() {
- let fields, {attrs, vals, err} = DBModule.getDBModuleArgs(this);
-
- if (err) {
- throw `object ${this.constructor.toString()} lack necessary field (table, fields)`;
- }
- fields = attrs.map(attr=>` ${attr}=? `);
- fields.push(' 1=1 ');
- return this._query(`select count(*) as count from \`${this.table}\` where ${fields.join(' and ')}`, vals)
- .then(result => {
- return result[0].count !== 0
- });
- }
- /**
- * 删除数据库中单行操作,对象必须存在有效的主键
- * @return {promise}
- */
- delete() {
- let sql, vals;
- if (this[this.primary] === undefined || this[this.primary] === null) {
- throw `object ${this.constructor.toString()} ${this.primary} is ${this[this.primary]}`;
- } else if (DBModule.getDBModuleArgs(this).err) {
- throw `object ${this.constructor.toString()} lack necessary field (table, fields)`;
- }
- vals = [this[this.primary]]
- sql = `delete from \`${this.table}\` where ${this.primary}=?`;
- return this._query(sql, vals);
- }
- /**
- * 查询该对象表中的数据
- * @param connect 多字段要连接字符 如 and or
- * @param start 分页时开始位置
- * @param limit 分页时要获取的条数
- * @param afterAgs 要附加的参数
- * @return {promise}
- */
- query({connect = DBModule.AND, start = 0, limit, sql} = {}, beforeAgs) {
- let conneSql = '', fields, {attrs, vals, err} = DBModule.getDBModuleArgs(this);
- if (err) {
- throw `object ${this.constructor.toString()} lack necessary field (table, fields)`;
- } else if (connect !== DBModule.AND && connect !== DBModule.OR) {
- throw `query functiton connect args must be DBModule.AND or DBModule.OR`;
- }
- if (Number.isFinite(Number(this[this.primary]))) {
- attrs.push(this.primary);
- vals.push(this[this.primary]);
- }
- if (limit > 0) {
- conneSql = ` LIMIT ?,?`;
- vals.push(start);
- vals.push(limit);
- }
- fields = attrs.map(attr => ` \`${this.table}\`.${attr}=? `);
- fields.push(' 1=1 ');
- if (sql) {
- sql = `select * from (${sql}) as \`${this.table}\` `;
- } else {
- sql = `select * from \`${this.table}\` `;
- }
- sql = `${sql} where ${fields.join(connect)} ${conneSql}`
- if (beforeAgs && beforeAgs.length > 0) {
- vals = beforeAgs.concat(vals);
- }
- return this._query(sql, vals);
- }
- /**
- * 分页模式数据统一处理
- * @param {*} paging number 是否要开启分页模式
- * limit number 每页的条数
- * start number 从哪条开始读取
- * header string 获取表的表头
- * vals array sql的参数
- * sql string sql语句表头用{{header}}代替
- */
- paging({paging = 0, limit = 15, start = 0, sql, headers = 'header', vals = []} = {}) {
- let pData, pCount, conneSql = '';
- if (!sql) return Promise.resolve(1);
- if (limit > 0) {
- conneSql = ` LIMIT ?,?`;
- vals.push(start);
- vals.push(limit);
- }
- pData = this._query(sql.replace('{{header}}', headers) + conneSql, vals);
- if (paging) {
- pCount = this._query(sql.replace('{{header}}', 'count(*) as len'), vals);
- return Promise.all([pData, pCount])
- .then((arrs) => {
- return {
- total: arrs[1][0].len,
- data: arrs[0],
- average: limit
- }
- });
- } else {
- return pData;
- }
- }
- /**
- * 检测对象是否符合DBModule要求并获取对象能执行_query的参数
- * @param {object} dbModule要检测的对象
- * @return {object} fileds: err attrs vals
- * {boolean} err 是否符合DBModule的要求
- * {array} attrs 要进行数据库操作的字段
- * {array} vals 要进行数据库操作的字段对应的值
- */
- static getDBModuleArgs(dbModule) {
- if(!((dbModule.table && dbModule.table.length > 0) &&
- (dbModule.fields && dbModule.fields instanceof Array && dbModule.fields.length > 0)
- )) {
- return {err: true};
- }
- let attrs = [], vals = [];
- for (let field of dbModule.fields) {
- if (dbModule[field] !== undefined) {
- attrs.push('`'+field+'`');
- vals.push(dbModule[field]);
- }
- }
- return {attrs, vals, err: false};
- }
- static get AND() {
- return 'and';
- }
- static get OR() {
- return 'or';
- }
- static get HOT() {
- return 'hot';
- }
- static get SOAR() {
- return 'soar';
- }
- }
- module.exports = exports = DBModule;
|