UNPKG

@actonate/mirkwood

Version:

GraphQL based Rapid Server-side Development framework

494 lines (422 loc) 13.5 kB
'use strict'; 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;