@actonate/mirkwood
Version:
GraphQL based Rapid Server-side Development framework
494 lines (422 loc) • 13.5 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", {
value: true
});
var _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; };
var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
var _flat = require('flat');
var _lodash = require('lodash');
var _knex = require('knex');
var _knex2 = _interopRequireDefault(_knex);
var _uuid = require('uuid');
var _uuid2 = _interopRequireDefault(_uuid);
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
var PostgresqlDatabaseAdapter = function () {
function PostgresqlDatabaseAdapter(connection) {
_classCallCheck(this, PostgresqlDatabaseAdapter);
this.client = (0, _knex2.default)({
client: 'pg',
connection: {
host: connection.host || 'localhost',
user: connection.user || 'root',
password: connection.password || '',
database: connection.database || 'pgsql',
port: connection.port || '5432'
},
debug: process.env['NODE_ENV'] === 'development' ? true : false
});
}
_createClass(PostgresqlDatabaseAdapter, [{
key: '_operatorMatch',
value: function _operatorMatch(operator) {
switch (operator) {
case '$eq':
return '=';
case '$ne':
return '!=';
case '$gt':
return '>';
case '$gte':
return '>=';
case '$lt':
return '<';
case '$lte':
return '<=';
case '$like':
return 'like';
case '$ilike':
return 'ilike';
case '$nin':
return 'not in';
case '$in':
return 'in';
}
}
}, {
key: '_resolveQuery',
value: function _resolveQuery(query, queryBuilder) {
var self = this;
if (query.and) {
var _loop = function _loop(qIdx) {
var subQuery = query.and[qIdx];
queryBuilder.where(function () {
self._resolveQuery(subQuery, this);
});
};
for (var qIdx = 0; qIdx < query.and.length; qIdx++) {
_loop(qIdx);
}
} else if (query.not) {
var _loop2 = function _loop2(qIdx) {
var subQuery = query.not[qIdx];
queryBuilder.whereNot(function () {
self._resolveQuery(subQuery, this);
});
};
for (var qIdx = 0; qIdx < query.not.length; qIdx++) {
_loop2(qIdx);
}
} else if (query.or) {
var _loop3 = function _loop3(qIdx) {
var subQuery = query.or[qIdx];
if (qIdx === 0) {
queryBuilder.where(function () {
self._resolveQuery(subQuery, this);
});
} else {
queryBuilder.orWhere(function () {
self._resolveQuery(subQuery, this);
});
}
};
for (var qIdx = 0; qIdx < query.or.length; qIdx++) {
_loop3(qIdx);
}
} else {
var keyCount = (0, _lodash.keys)(query.fields).length;
var resolvedSubQueries = [];
var _iteratorNormalCompletion = true;
var _didIteratorError = false;
var _iteratorError = undefined;
try {
for (var _iterator = Object.keys(query.fields)[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) {
var key = _step.value;
var _subQuery = query.fields[key];
var subQueryValue = _subQuery.value;
if ((_subQuery.operator === '$in' || _subQuery.operator === '$nin') && Array.isArray(_subQuery.values)) {
subQueryValue = _subQuery.values;
}
if (_subQuery.operator === '$regex') {
_subQuery.operator = '$like';
subQueryValue = '%' + subQueryValue + '%';
}
if (_subQuery.operator === '$iregex') {
_subQuery.operator = '$ilike';
subQueryValue = '%' + subQueryValue + '%';
}
if (_subQuery.operator === '$exists') {
queryBuilder.whereNotNull(key);
} else {
queryBuilder.where(key, this._operatorMatch(_subQuery.operator), subQueryValue);
}
}
} catch (err) {
_didIteratorError = true;
_iteratorError = err;
} finally {
try {
if (!_iteratorNormalCompletion && _iterator.return) {
_iterator.return();
}
} finally {
if (_didIteratorError) {
throw _iteratorError;
}
}
}
}
}
}, {
key: '_resolveFind',
value: function _resolveFind(find, queryBuilder) {
var _iteratorNormalCompletion2 = true;
var _didIteratorError2 = false;
var _iteratorError2 = undefined;
try {
for (var _iterator2 = Object.keys(find)[Symbol.iterator](), _step2; !(_iteratorNormalCompletion2 = (_step2 = _iterator2.next()).done); _iteratorNormalCompletion2 = true) {
var key = _step2.value;
if (Array.isArray(find[key])) {
queryBuilder.whereIn(key, find[key]);
} else {
queryBuilder.where(key, find[key]);
}
}
} catch (err) {
_didIteratorError2 = true;
_iteratorError2 = err;
} finally {
try {
if (!_iteratorNormalCompletion2 && _iterator2.return) {
_iterator2.return();
}
} finally {
if (_didIteratorError2) {
throw _iteratorError2;
}
}
}
}
}, {
key: '_resolveColumns',
value: function _resolveColumns(args, queryBuilder) {
if (!args) {
return;
}
var aggregate = args.aggregate,
groupBy = args.groupBy,
distinct = args.distinct;
// add group by columns
if (groupBy && Array.isArray(groupBy)) {
groupBy.map(function (groupBy) {
queryBuilder.column(groupBy.field);
});
}
// add distinct columns
if (distinct && Array.isArray(distinct)) {
distinct.map(function (distinct) {
queryBuilder.distinct(distinct);
});
}
// add aggregate fields
if (aggregate && (0, _lodash.keys)(aggregate).length > 0) {
var _iteratorNormalCompletion3 = true;
var _didIteratorError3 = false;
var _iteratorError3 = undefined;
try {
var _loop4 = function _loop4() {
var fn = _step3.value;
aggregate[fn].map(function (field) {
queryBuilder[fn]([field, 'as', ['aggr', fn, field].join('_')].join(' '));
});
};
for (var _iterator3 = Object.keys(aggregate)[Symbol.iterator](), _step3; !(_iteratorNormalCompletion3 = (_step3 = _iterator3.next()).done); _iteratorNormalCompletion3 = true) {
_loop4();
}
} catch (err) {
_didIteratorError3 = true;
_iteratorError3 = err;
} finally {
try {
if (!_iteratorNormalCompletion3 && _iterator3.return) {
_iterator3.return();
}
} finally {
if (_didIteratorError3) {
throw _iteratorError3;
}
}
}
}
}
}, {
key: '_transformRow',
value: function _transformRow(row) {
// identify all aggregate fields and unflatten them
var aggregateFields = (0, _lodash.pickBy)(row, function (value, key) {
return key.startsWith('aggr_');
});
// remove all aggr fields
row = (0, _lodash.pickBy)(row, function (value, key) {
return !key.startsWith('aggr_');
});
if (!aggregateFields || (0, _lodash.keys)(aggregateFields).length === 0) {
return row;
}
// to handle the fields starting with '_' (underscore), replace all underscore with .
aggregateFields = (0, _lodash.mapKeys)(aggregateFields, function (value, key) {
return key.replace(/aggr_(sum|min|max|count|avg)_/, 'aggr.$1.');
});
var aggregates = (0, _flat.unflatten)(aggregateFields, { delimiter: '.' });
return _extends({}, row, {
_aggregates: aggregates['aggr']
});
}
}, {
key: 'all',
value: function all(datasource, args) {
var _this = this;
var self = this;
var dbPromise = new Promise(function (resolve, reject) {
var tableName = datasource.table || datasource.collection;
_this.client.select().modify(function (queryBuilder) {
self._resolveColumns(args, queryBuilder);
}).table(tableName).modify(function (queryBuilder) {
if (args.find) {
self._resolveFind(args.find, queryBuilder);
}
if (args.query) {
self._resolveQuery(args.query, queryBuilder);
}
// handle soft deletion
if (datasource.skip_deleted) {
queryBuilder.whereNot('_deleted', true);
}
}).modify(function (queryBuilder) {
if (args.groupBy) {
args.groupBy.map(function (groupBy) {
queryBuilder.groupBy(groupBy.field);
});
}
}).modify(function (queryBuilder) {
if (args.sort) {
queryBuilder.orderBy(args.sort.field, args.sort.order);
}
if (args.orderBy && args.orderBy.length > 0) {
args.orderBy.map(function (orderBy) {
queryBuilder.orderBy(orderBy.field, orderBy.order);
});
}
}).limit(args.limit).offset(args.skip).then(function (res) {
var rows = res.map(_this._transformRow);
resolve(rows);
}).catch(function (err) {
reject(err);
});
});
return dbPromise;
}
}, {
key: 'count',
value: function count(datasource, args) {
var _this2 = this;
var self = this;
var dbPromise = new Promise(function (resolve, reject) {
var tableName = datasource.table || datasource.collection;
_this2.client.select().count().table(tableName).modify(function (queryBuilder) {
if (args.find) {
self._resolveFind(args.find, queryBuilder);
}
if (args.query) {
self._resolveQuery(args.query, queryBuilder);
}
// handle soft deletion
if (datasource.skip_deleted) {
queryBuilder.whereNot('_deleted', true);
}
}).then(function (res) {
resolve(res[0].count);
}).catch(function (err) {
reject(err);
});
});
return dbPromise;
}
}, {
key: 'one',
value: function one(datasource, args) {
var _this3 = this;
var self = this;
var dbPromise = new Promise(function (resolve, reject) {
var find = args.find,
query = args.query;
var tableName = datasource.table || datasource.collection;
_this3.client.select().modify(function (queryBuilder) {
self._resolveColumns(args, queryBuilder);
}).table(tableName).modify(function (queryBuilder) {
if (find) {
queryBuilder.where(find);
}
if (query) {
self._resolveQuery(query, queryBuilder);
}
// handle soft deletion
if (datasource.skip_deleted) {
queryBuilder.whereNot('_deleted', true);
}
})
// .where(find ? find : null)
.limit(1).then(function (res) {
if (!res[0]) {
resolve(null);
}
var row = _this3._transformRow(res[0]);
resolve(row);
}).catch(function (err) {
reject(err);
});
});
return dbPromise;
}
}, {
key: 'destroy',
value: function destroy(datasource, find, args) {
var _this4 = this;
var dbPromise = new Promise(function (resolve, reject) {
var tableName = datasource.table || datasource.collection;
_this4.client(tableName).where(find).del().then(function (res) {
resolve(true);
}).catch(reject);
});
return dbPromise;
}
}, {
key: 'delete',
value: function _delete(datasource, find, args) {
var _this5 = this;
var dbPromise = new Promise(function (resolve, reject) {
var tableName = datasource.table || datasource.collection;
_this5.client(tableName).where(find).update({ _deleted: true }).then(function (res) {
resolve(true);
}).catch(reject);
});
return dbPromise;
}
}, {
key: 'create',
value: function create(datasource, row, args) {
var _this6 = this;
var dbPromise = new Promise(function (resolve, reject) {
var tableName = datasource.table || datasource.collection;
row._id = _uuid2.default.v4();
_this6.client(tableName).insert(row).then(function (res) {
var find = {
_id: row._id
};
return _this6.one(datasource, { find: find });
}).then(resolve).catch(reject);
});
return dbPromise;
}
}, {
key: 'createMany',
value: function createMany(datasource, rows, args) {
var _this7 = this;
var dbPromise = new Promise(function (resolve, reject) {
var tableName = datasource.table || datasource.collection;
rows = rows.map(function (row) {
row._id = _uuid2.default.v4();
return row;
});
_this7.client(tableName).insert(rows).then(function (res) {
return resolve(res.rowCount);
}).catch(reject);
});
return dbPromise;
}
}, {
key: 'update',
value: function update(datasource, find, row, args) {
var _this8 = this;
var dbPromise = new Promise(function (resolve, reject) {
var tableName = datasource.table || datasource.collection;
_this8.client(tableName).where(find).update(row).then(function (res) {
resolve(true);
}).catch(reject);
});
return dbPromise;
}
}]);
return PostgresqlDatabaseAdapter;
}();
exports.default = PostgresqlDatabaseAdapter;