great-scott
Version:
A Marty-like data source for postgres.
189 lines (154 loc) • 5.26 kB
JavaScript
"use strict";
var _interopRequire = function (obj) { return obj && obj.__esModule ? obj["default"] : obj; };
var _prototypeProperties = function (child, staticProps, instanceProps) { if (staticProps) Object.defineProperties(child, staticProps); if (instanceProps) Object.defineProperties(child.prototype, instanceProps); };
var _classCallCheck = function (instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } };
var assert = _interopRequire(require("assert"));
var format = require("util").format;
var _ = _interopRequire(require("lodash"));
var Promise = _interopRequire(require("bluebird"));
var squel = _interopRequire(require("squel"));
var pools = _interopRequire(require("./pools"));
var _errors = require("./errors");
var PostgresError = _errors.PostgresError;
var NotFoundError = _errors.NotFoundError;
// Enable extra Postgres features (this is required!).
squel.useFlavour("postgres");
var DataSource = (function () {
function DataSource(options) {
_classCallCheck(this, DataSource);
assert(options.connectionString, "options.connectionString is required.");
this.connectionString = options.connectionString;
this.idAttribute = options.idAttribute || "id";
this.tableName = options.tableName || "";
this.builder = squel;
}
_prototypeProperties(DataSource, null, {
parse: {
value: function parse(row) {
return row;
},
writable: true,
configurable: true
},
format: {
value: function format(model) {
return model;
},
writable: true,
configurable: true
},
find: {
value: function find(idOrObj) {
var query = this.builder.select().from(this.tableName);
if (_.isObject(idOrObj)) {
_.each(idOrObj, function (value, attribute) {
query = query.where(format("%s = ?", attribute), value);
});
} else {
query = query.where(format("%s = ?", this.idAttribute), idOrObj);
}
return this.execute(query).then(function (result) {
if (!result.length) {
throw new NotFoundError();
}
return result[0];
});
},
writable: true,
configurable: true
},
findAll: {
value: function findAll() {
var where = arguments[0] === undefined ? {} : arguments[0];
var query = this.builder.select().from(this.tableName);
if (_.isObject(where)) {
_.each(where, function (value, attribute) {
query = query.where(format("%s = ?", attribute), value);
});
}
return this.execute(query);
},
writable: true,
configurable: true
},
insert: {
value: function insert(model) {
var fields = _.omit(this.format(model), _.isUndefined);
var query = this.builder.insert().into(this.tableName).setFields(fields).returning("*");
return this.execute(query).then(function (result) {
return result[0];
});
},
writable: true,
configurable: true
},
update: {
value: function update(model) {
var fields = _.omit(this.format(model), _.isUndefined);
_.each(fields, function (value, key) {
if (_.isUndefined(value)) {
delete fields[key];
}
});
var query = this.builder.update().table(this.tableName).setFields(fields).where(format("%s = ?", this.idAttribute), fields[this.idAttribute]).returning("*");
return this.execute(query).then(function (result) {
return result[0];
});
},
writable: true,
configurable: true
},
"delete": {
value: function _delete(idOrModel) {
var id = undefined;
if (_.isObject(idOrModel)) {
id = idOrModel.get(this.idAttribute);
} else {
id = idOrModel;
}
var query = this.builder["delete"]().from(this.tableName).where(format("%s = ?", this.idAttribute), id);
return this.execute(query).then(function () {
return true;
});
},
writable: true,
configurable: true
},
execute: {
value: function execute(query) {
var _this = this;
return this.execRaw(query).then(function (results) {
return results.rows.map(function (row) {
return _this.parse(row);
});
})["catch"](function (err) {
throw PostgresError.factory(err);
});
},
writable: true,
configurable: true
},
execRaw: {
value: function execRaw(query) {
return Promise.using(this._getClient(), function (client) {
query = query.toParam();
return client.queryAsync(query.text, query.values);
});
},
writable: true,
configurable: true
},
_getClient: {
value: function _getClient() {
var pool = pools.get(this.connectionString);
return pool.acquireAsync().disposer(function (client) {
pool.release(client);
});
},
writable: true,
configurable: true
}
});
return DataSource;
})();
module.exports = DataSource;