mysqli/lib/method.js

256 lines
5.4 KiB
JavaScript

/**
*
* @authors yutent (yutent@doui.cc)
* @date 2017-12-14 14:01:03
* @version $Id$
*/
const { escape } = require('mysql')
const parser = require('./parser')
class SqlErr extends Error {
constructor(msg, sql) {
super(msg)
this.sql = sql || ''
}
}
class Method {
constructor(pool, slave, db) {
this.pool = pool
this.slave = slave
this.db = db
}
connect() {
const defer = Promise.defer()
this.pool.getConnection(this.slave, (err, conn) => {
if (err) {
return defer.reject(new SqlErr(`MySQL connect ${err}`))
}
if (this.db) {
conn.query('USE ' + this.db, err => {
if (err) {
return defer.reject(new SqlErr('Select DB ' + err))
}
defer.resolve(conn)
})
} else {
defer.resolve(conn)
}
})
return defer.promise
}
listDb() {
return this.connect().then(conn => {
const defer = Promise.defer()
conn.query('SHOW DATABASES', (err, row) => {
conn.release()
if (err) {
return defer.reject(new SqlErr('SHOW DATABASES ' + err))
}
defer.resolve(row.map(it => it.Database))
})
return defer.promise
})
}
//返回数据表
listTable() {
return this.connect().then(conn => {
const defer = Promise.defer()
conn.query('SHOW TABLES', (err, row) => {
conn.release()
if (err) {
return defer.reject(new SqlErr('SHOW TABLES ' + err))
}
defer.resolve(row.map(it => Object.values(it)[0]))
})
return defer.promise
})
}
/**
* [query sql语句执行]
* @param {[type]} sql [sql语句]
*/
query(sql) {
if (typeof sql !== 'string') {
return Promise.reject(
new SqlErr(
`Query error, argument sql must be string. ${typeof sql} given`,
sql
)
)
}
return this.connect().then(conn => {
const defer = Promise.defer()
conn.query(sql, (err, result) => {
conn.release()
if (err) {
return defer.reject(new SqlErr(`Query ${err}`, sql))
}
defer.resolve(result)
})
return defer.promise
})
}
find(condition, select) {
const { table, leftJoin, rightJoin, join, where, sort, limit } = condition
if (!table) {
return Promise.reject(new SqlErr('Find Error: empty table'))
}
let sql = parser.select(select)
sql += `FROM ${table} `
if (leftJoin) {
sql += parser.leftJoin(leftJoin)
}
if (rightJoin) {
sql += parser.rightJoin(rightJoin)
}
if (join) {
sql += parser.join(join)
}
if (where) {
sql += parser.where(where)
}
if (sort) {
sql += parser.sort(sort)
}
if (limit) {
sql += parser.limit(limit)
}
return this.connect().then(conn => {
const defer = Promise.defer()
conn.query(sql, (err, result) => {
conn.release()
if (err) {
return defer.reject(new SqlErr(`Find ${err}`, sql))
}
defer.resolve(result)
})
return defer.promise
})
}
findOne(condition, select) {
condition.limit = [1]
return this.find(condition, select).then(row => {
return row[0] || null
})
}
count(condition) {
delete condition.limit
return this.find(condition, ['count(*) AS total']).then(row => {
return (row[0] && row[0].total) || 0
})
}
insert({ table }, doc) {
if (!table) {
return Promise.reject(new SqlErr('Insert Error: empty table'))
}
let sql = `INSERT INTO ${table} `
let keys = []
let vals = []
for (let i in doc) {
keys.push(i)
vals.push(escape(doc[i]))
}
sql += `(${keys.join(',')}) VALUES (${vals.join(',')})`
return this.connect().then(conn => {
const defer = Promise.defer()
conn.query(sql, (err, result) => {
conn.release()
if (err) {
return defer.reject(new SqlErr(`Insert ${err}`, sql))
}
defer.resolve(result.insertId)
})
return defer.promise
})
}
update({ table, where }, doc) {
if (!table) {
return Promise.reject(new SqlErr('Update Error: empty table'))
}
let sql = `UPDATE ${table} SET `
let fields = [] //要更新的字段
for (let i in doc) {
let val = doc[i]
if (typeof val === 'object' && val.$sql) {
val = `(${val.$sql})`
} else {
val = escape(val)
}
fields.push(i + ' = ' + val)
}
sql += fields.join(',')
sql += parser.where(where)
return this.connect().then(conn => {
const defer = Promise.defer()
conn.query(sql, (err, res) => {
conn.release()
if (err) {
return defer.reject(new SqlErr(`Update ${err}`, sql))
}
defer.resolve(res.affectedRows)
})
return defer.promise
})
}
remove({ table, where }) {
if (!table) {
return Promise.reject(new SqlErr('Remove Error: empty table'))
}
let sql = `DELETE FROM \`${table}\` `
if (where) {
sql += parser.where(where)
}
return this.connect().then(conn => {
const defer = Promise.defer()
conn.query(sql, (err, res) => {
conn.release()
if (err) {
return defer.reject(new SqlErr(`Remove ${err}`, sql))
}
defer.resolve(res.affectedRows)
})
return defer.promise
})
}
}
module.exports = Method
MySQL tool
JavaScript 100%