Skip to content

Commit

Permalink
feat: add get(), list(), insert(), update()
Browse files Browse the repository at this point in the history
  • Loading branch information
fengmk2 committed Jun 2, 2015
1 parent fc4b1ce commit 9cae1cb
Show file tree
Hide file tree
Showing 6 changed files with 362 additions and 9 deletions.
23 changes: 19 additions & 4 deletions lib/client.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,10 @@
* Module dependencies.
*/

var debug = require('debug')('ali-sdk:ali-rds:client');
var mysql = require('mysql');
var util = require('util');
var Operator = require('./operator');
var RDSConnection = require('./connection');

module.exports = RDSClient;
Expand All @@ -23,17 +26,22 @@ function RDSClient(options) {
if (!(this instanceof RDSClient)) {
return new RDSClient(options);
}
Operator.call(this);

this.pool = mysql.createPool(options);
// if needFields = false, return rows result instead of {rows, fields} object result.
this._needFields = options.needFields === false ? false : true;
}

util.inherits(RDSClient, Operator);

var proto = RDSClient.prototype;

proto.query = function (sql, values) {
var pool = this.pool;
var needFields = this._needFields;
return function (callback) {
debug('query %j, needFields: %s', sql, needFields);
pool.query(sql, values, function (err, rows, fields) {
if (needFields) {
callback(err, { rows: rows, fields: fields });
Expand All @@ -44,10 +52,6 @@ proto.query = function (sql, values) {
};
};

proto.escape = function (val) {
return this.pool.escape(val);
};

proto.getConnection = function () {
var pool = this.pool;
var needFields = this._needFields;
Expand All @@ -64,3 +68,14 @@ proto.getConnection = function () {
});
};
};

proto.beginTransaction = function* () {
var conn = yield this.getConnection();
try {
yield conn.beginTransaction();
} catch (err) {
conn.release();
throw err;
}
return conn;
};
11 changes: 7 additions & 4 deletions lib/connection.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,12 +14,18 @@
* Module dependencies.
*/

var debug = require('debug')('ali-sdk:ali-rds:connection');
var util = require('util');
var Operator = require('./operator');

module.exports = RDSConnection;

function RDSConnection(conn, needFields) {
Operator.call(this);
this.conn = conn;
this._needFields = needFields;
}
util.inherits(RDSConnection, Operator);

var proto = RDSConnection.prototype;

Expand All @@ -31,6 +37,7 @@ proto.query = function (sql, values) {
var conn = this.conn;
var needFields = this._needFields;
return function (callback) {
debug('query %j, needFields: %s', sql, needFields);
conn.query(sql, values, function (err, rows, fields) {
if (needFields) {
callback(err, { rows: rows, fields: fields });
Expand All @@ -41,10 +48,6 @@ proto.query = function (sql, values) {
};
};

proto.escape = function (val) {
return this.conn.escape(val);
};

proto.beginTransaction = function () {
var conn = this.conn;
return function (callback) {
Expand Down
159 changes: 159 additions & 0 deletions lib/operator.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,159 @@
/**!
* ali-rds - lib/operator.js
*
* Copyright(c) fengmk2 and other contributors.
* MIT Licensed
*
* Authors:
* fengmk2 <m@fengmk2.com> (http://fengmk2.com)
*/

'use strict';

/**
* Module dependencies.
*/

var mysql = require('mysql');

module.exports = Operator;

function Operator() {

}

var proto = Operator.prototype;

proto.escape = function (value, stringifyObjects, timeZone) {
return mysql.escape(value, stringifyObjects, timeZone);
};

proto.escapeId = function (value, forbidQualified) {
return mysql.escapeId(value, forbidQualified);
};

proto.format = function (sql, values, stringifyObjects, timeZone) {
return mysql.format(sql, values, stringifyObjects, timeZone);
};

proto.query = function () {
throw new Error('Not Impl');
};

proto.list = function* (table, obj, keys, columns, orders, limit, offset) {
var sql = this._selectColumns(table, columns) + this._where(obj, keys) + this._orders(orders)
+ this._limit(limit, offset) + ';';
return yield this.query(sql);
};

proto.get = function* (table, obj, keys, columns, orders) {
var rows = yield this.list(table, obj, keys, columns, orders, 1);
if (!Array.isArray(rows)) {
rows = rows.rows;
}
return rows && rows[0] || null;
};

proto.insert = function* (table, obj, columns) {
if (!columns) {
columns = Object.keys(obj);
}
var values = [];
for (var i = 0; i < columns.length; i++) {
values.push(obj[columns[i]]);
}
var sql = this.format('INSERT INTO ??(??) VALUES(?);', [table, columns, values]);
return yield this.query(sql);
};

proto.update = function* (table, obj, keys, columns) {
if (!columns) {
columns = Object.keys(obj);
}
var sets = [];
var values = [];
for (var i = 0; i < columns.length; i++) {
var column = columns[i];
if (keys.indexOf(column) >= 0) {
continue;
}
sets.push('?? = ?');
values.push(column);
values.push(obj[column]);
}
var sql = this.format('UPDATE ?? SET ', [table]) + this.format(sets.join(', '), values) + this._where(obj, keys);
return yield this.query(sql);
};

proto._where = function (obj, keys) {
if (!keys) {
keys = [ 'id' ];
} else if (typeof keys === 'string') {
keys = [ keys ];
}
var wheres = [];
var values = [];
for (var i = 0; i < keys.length; i++) {
var key = keys[i];
var value = obj[key];
if (Array.isArray(value)) {
wheres.push('?? IN (?)');
} else {
wheres.push('?? = ?');
}
values.push(key);
values.push(value);
}
return this.format(' WHERE ' + wheres.join(' AND '), values);
};

proto._selectColumns = function (table, columns) {
if (!columns) {
columns = '*';
}
var sql;
if (columns === '*') {
sql = this.format('SELECT * FROM ??', [table]);
} else {
sql = this.format('SELECT ?? FROM ??', [columns, table]);
}
return sql;
};

proto._orders = function (orders) {
if (!orders) {
return '';
}
if (typeof orders === 'string') {
orders = [ orders ];
}
var values = [];
for (var i = 0; i < orders.length; i++) {
var value = orders[i];
if (typeof value === 'string') {
values.push(this.escapeId(value));
} else if (Array.isArray(value)) {
// value format: ['name', 'desc'], ['name'], ['name', 'asc']
var sort = String(value[1]).toUpperCase();
if (sort !== 'ASC' && sort !== 'DESC') {
sort = null;
}
if (sort) {
values.push(this.escapeId(value[0]) + ' ' + sort);
} else {
values.push(this.escapeId(value[0]));
}
}
}
return ' ORDER BY ' + values.join(', ');
};

proto._limit = function (limit, offset) {
if (!limit || typeof limit !== 'number') {
return '';
}
if (typeof offset !== 'number') {
offset = 0;
}
return ' LIMIT ' + offset + ', ' + limit;
};
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
"cnpm": "npm install --registry=https://registry.npm.taobao.org"
},
"dependencies": {
"debug": "~2.2.0",
"mysql": "~2.7.0"
},
"devDependencies": {
Expand Down
Loading

0 comments on commit 9cae1cb

Please sign in to comment.