UNPKG

libpiggy

Version:

Use a PostgreSQL database like a JSON document store.

273 lines (198 loc) 7.26 kB
'use strict'; Object.defineProperty(exports, "__esModule", { value: true }); var _extends2 = require('babel-runtime/helpers/extends'); var _extends3 = _interopRequireDefault(_extends2); var _asyncToGenerator2 = require('babel-runtime/helpers/asyncToGenerator'); var _asyncToGenerator3 = _interopRequireDefault(_asyncToGenerator2); var _stringify = require('babel-runtime/core-js/json/stringify'); var _stringify2 = _interopRequireDefault(_stringify); var _entries = require('babel-runtime/core-js/object/entries'); var _entries2 = _interopRequireDefault(_entries); var _isNumber = require('lodash/fp/isNumber'); var _isNumber2 = _interopRequireDefault(_isNumber); var _isString = require('lodash/fp/isString'); var _isString2 = _interopRequireDefault(_isString); var _isArray = require('lodash/fp/isArray'); var _isArray2 = _interopRequireDefault(_isArray); var _isObject = require('lodash/fp/isObject'); var _isObject2 = _interopRequireDefault(_isObject); var _isEmpty = require('lodash/fp/isEmpty'); var _isEmpty2 = _interopRequireDefault(_isEmpty); var _isUndefined = require('lodash/fp/isUndefined'); var _isUndefined2 = _interopRequireDefault(_isUndefined); var _defaultsDeep = require('lodash/fp/defaultsDeep'); var _defaultsDeep2 = _interopRequireDefault(_defaultsDeep); var _pickBy = require('lodash/fp/pickBy'); var _pickBy2 = _interopRequireDefault(_pickBy); var _map = require('lodash/fp/map'); var _map2 = _interopRequireDefault(_map); var _flow = require('lodash/fp/flow'); var _flow2 = _interopRequireDefault(_flow); var _createClient = require('./create-client'); var _createClient2 = _interopRequireDefault(_createClient); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } const defaults = { operators: 'jsonb', limit: 0, offset: 0, orderBy: 'updatedAt', direction: 'desc', caseInsensitive: false }; /* eslint complexity:0 */ const compact = (0, _pickBy2.default)(x => !(0, _isUndefined2.default)(x)); const isEmptyObject = (0, _flow2.default)(compact, _isEmpty2.default); const convertToJson = (column, options = {}) => search => { const [key, val] = search; if ((0, _isNumber2.default)(val)) { return `("${column}" ->> '${key}')::int = ${val}`; } if (options.caseInsensitive) { return `lower("${column}" ->> '${key}') = lower('${val}')`; } return `"${column}" ->> '${key}' = '${val}'`; }; const getQueryTextJson = ({ key, not, columnNames, caseInsensitive }) => { const toJson = convertToJson(columnNames.val, { caseInsensitive }); const search = key || not; if ((0, _isArray2.default)(search)) { const facets = (0, _map2.default)(obj => { const statements = (0, _map2.default)(toJson, (0, _entries2.default)(obj)); return `(${statements.join(' AND ')})`; }, search); return ` (${facets.join(' OR ')})`; } const statements = (0, _map2.default)(toJson, (0, _entries2.default)(search)); return ` (${statements.join(' AND ')})`; }; const convertToJsonb = (column, options = {}) => search => { if (options.caseInsensitive) { return ` (lower("${column}"::text)::jsonb) @> (lower('${(0, _stringify2.default)(search)}')::jsonb)`; } return ` "${column}" @> '${(0, _stringify2.default)(search)}'`; }; const getQueryTextJsonb = ({ key, not, columnNames, caseInsensitive }) => { const toJsonb = convertToJsonb(columnNames.val, { caseInsensitive }); const search = key || not; if ((0, _isArray2.default)(search)) { const facets = (0, _map2.default)(toJsonb, search); return ` (${facets.join(' OR ')})`; } return toJsonb(search); }; const getOrderByText = function ({ columnNames, field, direction }) { let text = ''; if (columnNames[field]) { text += `"${columnNames[field]}"`; } else { text += `"${columnNames.val}" ->> '${field}'`; } if (direction) { text += ` ${direction.toUpperCase()}`; } return text; }; const mget = (() => { var _ref = (0, _asyncToGenerator3.default)(function* (params, globals) { const { store, table, options } = params; let { key, not } = params; let { client } = params; let clientCreated = false; const settings = (0, _defaultsDeep2.default)(defaults, options); const { operators, limit, offset, orderBy, direction, caseInsensitive } = settings; const { columnNames } = store.settings; try { if (!client) { client = yield (0, _createClient2.default)(options, globals); clientCreated = true; } if ((0, _isObject2.default)(key) && isEmptyObject(key)) { key = undefined; } if ((0, _isObject2.default)(not) && isEmptyObject(not)) { not = undefined; } if ((0, _isUndefined2.default)(key) && (0, _isUndefined2.default)(not)) { throw new Error('incomplete query, key or not params are required'); } let text = `SELECT * FROM "${table}" WHERE`; if (!(0, _isUndefined2.default)(key)) { if ((0, _isString2.default)(key) || (0, _isNumber2.default)(key)) { text += ` "${columnNames.key}" LIKE '${key}'`; } else if (operators === 'json') { text += getQueryTextJson({ key, columnNames, caseInsensitive }); } else { text += getQueryTextJsonb({ key, columnNames, caseInsensitive }); } } if (!(0, _isUndefined2.default)(not)) { if (!(0, _isUndefined2.default)(key)) { text += ` AND`; } if ((0, _isString2.default)(not) || (0, _isNumber2.default)(not)) { text += ` "${columnNames.key}" NOT LIKE '${not}'`; } else if (operators === 'json') { text += ` NOT`; text += getQueryTextJson({ not, columnNames, caseInsensitive }); } else { text += ` NOT`; text += getQueryTextJsonb({ not, columnNames, caseInsensitive }); } } if (orderBy) { text += ` ORDER BY `; if ((0, _isString2.default)(orderBy)) { text += getOrderByText({ field: orderBy, direction, columnNames }); } else { text += orderBy.map(function (o) { if ((0, _isArray2.default)(o)) { return getOrderByText({ field: o[0], direction: o[1], columnNames }); } return getOrderByText((0, _extends3.default)({}, o, { columnNames })); }).join(', '); } } if (offset > 0) { text += ` OFFSET ${offset}`; } if (limit > 0) { text += ` LIMIT ${limit}`; } text += `;`; const results = yield client.query({ text }); const rows = results.rows.map(function (r) { return { table, key: r.key, val: r.val, createdAt: r[columnNames.createdAt], updatedAt: r[columnNames.updatedAt] }; }); return { client, results, rows }; } catch (error) { throw error; } finally { if (clientCreated) { client.close(); } } }); return function mget(_x, _x2) { return _ref.apply(this, arguments); }; })(); exports.default = mget;