libpiggy
Version:
Use a PostgreSQL database like a JSON document store.
273 lines (198 loc) • 7.26 kB
JavaScript
;
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;