UNPKG

pg-sql-helpers

Version:

A set helpers for writing dynamic SQL queries with `pg-sql` in Javascript.

558 lines (460 loc) 16.1 kB
'use strict'; Object.defineProperty(exports, "__esModule", { value: true }); exports.WHERE = exports.where = exports.VALUES = exports.values = exports.UPSERT = exports.upsert = exports.UPDATE = exports.update = exports.SORT = exports.sort = exports.SELECT = exports.select = exports.ROW = exports.row = exports.ORDER_BY = exports.orderBy = exports.OR = exports.or = exports.OFFSET = exports.offset = exports.LIMIT = exports.limit = exports.INSERT = exports.insert = exports.COMPOSITES = exports.composites = exports.COMPOSITE = exports.composite = exports.COLUMNS = exports.columns = exports.COLUMN = exports.column = exports.AND = exports.and = undefined; 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 _templateObject = _taggedTemplateLiteral(['', ''], ['', '']), _templateObject2 = _taggedTemplateLiteral(['(', ')'], ['(', ')']), _templateObject3 = _taggedTemplateLiteral(['INSERT INTO ', ' (', ') ', ''], ['INSERT INTO ', ' (', ') ', '']), _templateObject4 = _taggedTemplateLiteral([''], ['']), _templateObject5 = _taggedTemplateLiteral(['LIMIT ALL'], ['LIMIT ALL']), _templateObject6 = _taggedTemplateLiteral(['LIMIT ', ''], ['LIMIT ', '']), _templateObject7 = _taggedTemplateLiteral(['OFFSET ', ''], ['OFFSET ', '']), _templateObject8 = _taggedTemplateLiteral(['ORDER BY ', ''], ['ORDER BY ', '']), _templateObject9 = _taggedTemplateLiteral(['ROW ', ''], ['ROW ', '']), _templateObject10 = _taggedTemplateLiteral(['SELECT ', ''], ['SELECT ', '']), _templateObject11 = _taggedTemplateLiteral(['', ' ', ' NULLS LAST'], ['', ' ', ' NULLS LAST']), _templateObject12 = _taggedTemplateLiteral(['UPDATE ', ' SET ', ' = ', ''], ['UPDATE ', ' SET ', ' = ', '']), _templateObject13 = _taggedTemplateLiteral(['UPDATE ', ' SET (', ') = ', ''], ['UPDATE ', ' SET (', ') = ', '']), _templateObject14 = _taggedTemplateLiteral(['ON CONFLICT (', ') DO'], ['ON CONFLICT (', ') DO']), _templateObject15 = _taggedTemplateLiteral(['UPDATE SET (', ') = (', ')'], ['UPDATE SET (', ') = (', ')']), _templateObject16 = _taggedTemplateLiteral(['NOTHING'], ['NOTHING']), _templateObject17 = _taggedTemplateLiteral(['WHERE (', ') IS DISTINCT FROM (', ')'], ['WHERE (', ') IS DISTINCT FROM (', ')']), _templateObject18 = _taggedTemplateLiteral(['', ' ', ' ', ' ', ''], ['', ' ', ' ', ' ', '']), _templateObject19 = _taggedTemplateLiteral(['VALUES ', ''], ['VALUES ', '']), _templateObject20 = _taggedTemplateLiteral(['', '.', ''], ['', '.', '']), _templateObject21 = _taggedTemplateLiteral(['', ' ', ' ', ''], ['', ' ', ' ', '']), _templateObject22 = _taggedTemplateLiteral(['', ' ', ''], ['', ' ', '']); var _is = require('is'); var _is2 = _interopRequireDefault(_is); var _isPlainObject = require('is-plain-object'); var _isPlainObject2 = _interopRequireDefault(_isPlainObject); var _pgSql = require('pg-sql'); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } function _toConsumableArray(arr) { if (Array.isArray(arr)) { for (var i = 0, arr2 = Array(arr.length); i < arr.length; i++) { arr2[i] = arr[i]; } return arr2; } else { return Array.from(arr); } } function _taggedTemplateLiteral(strings, raw) { return Object.freeze(Object.defineProperties(strings, { raw: { value: Object.freeze(raw) } })); } /** * A map of operators shorthands to PostgreSQL operators. * * @type {Object} */ var WHERE_OPERATORS = { eq: '=', gt: '>', gte: '>=', lt: '<', lte: '<=', ne: '!=', neq: '!=', like: 'LIKE', ilike: 'ILIKE' /** * Create a SQL "AND" clause, just like "WHERE". * * @param {String} ident * @param {Object} params * @param {Object} options * @return {sql} */ };function AND(ident, params) { var options = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {}; var query = WHERE(ident, params, _extends({}, options, { keyword: 'AND' })); return query; } /** * Create a SQL column expression, with optional table reference. * * @param {String} table (optional) * @param {String} column * @return {sql} */ function COLUMN(table, column) { if (column == null) { column = table; table = null; } var ref = table ? (0, _pgSql.sql)(_templateObject, _pgSql.sql.ident(table, column)) : (0, _pgSql.sql)(_templateObject, _pgSql.sql.ident(column)); return ref; } /** * Create a list of SQL identifiers from a `value`. * * @param {String} table (optional) * @param {Object|Array<Object>|Array<String>} value * @return {sql} */ function COLUMNS(table, value) { var options = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {}; if (table != null && !_is2.default.string(table)) { value = table; table = null; } var _options$delimiter = options.delimiter, delimiter = _options$delimiter === undefined ? ', ' : _options$delimiter; var keys = void 0; if (_is2.default.object(value)) { keys = getDefinedKeys(value); } else if (_is2.default.array(value) && _is2.default.object(value[0])) { keys = getDefinedKeys(value[0]); } else if (_is2.default.array(value) && _is2.default.string(value[0])) { keys = value; } else { throw new Error('The `COLUMNS` SQL helper must be passed an object, an array of objects or an array of strings, but you passed: ' + value); } var idents = keys.map(function (k) { return COLUMN(table, k); }); var query = (0, _pgSql.sql)(_templateObject, _pgSql.sql.join(idents, delimiter)); return query; } /** * Create a SQL composite value for the values of an `object`. * * @param {Object} object * @return {sql} */ function COMPOSITE(object) { if (!_is2.default.object(object)) { throw new Error('The `COMPOSITE` SQL helper must be passed an object, but you passed: ' + object); } var keys = getDefinedKeys(object); var vals = keys.map(function (k) { return (0, _pgSql.sql)(_templateObject, object[k]); }); var query = (0, _pgSql.sql)(_templateObject2, _pgSql.sql.join(vals, ', ')); return query; } /** * Create a list SQL composite values for the values of an `array` of objects. * * @param {Array} array * @return {sql} */ function COMPOSITES(array) { if (!Array.isArray(array)) { array = [array]; } var columns = void 0; var composites = array.map(function (object, i) { var composite = COMPOSITE(object); var keys = getDefinedKeys(object); var cols = keys.join(','); if (i === 0) { columns = cols; } else if (cols !== columns) { throw new Error('Every entry in a SQL composite expression must have the same columns, but you passed: ' + array); } return composite; }); var query = _pgSql.sql.join(composites, ', '); return query; } /** * Create a SQL "INSERT" statement from a dictionary or list of `values`. * * @param {String} table * @param {Object|Array<Object>} values * @return {sql} */ function INSERT(table, values) { var query = (0, _pgSql.sql)(_templateObject3, _pgSql.sql.ident(table), COLUMNS(values), VALUES(values)); return query; } /** * Create a literal SQL "LIMIT" string from `number`. * * @param {Number} number * @param {Object} options * @return {sql} */ function LIMIT(number) { var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; if (number == null) { return (0, _pgSql.sql)(_templateObject4); } if (options.max) { number = Math.min(number, options.max); } var query = number === Infinity ? (0, _pgSql.sql)(_templateObject5) : (0, _pgSql.sql)(_templateObject6, number); return query; } /** * Create a literal SQL "OFFSET" string from `number`. * * @param {Number} number * @param {Object} options * @return {sql} */ function OFFSET(number) { var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; if (number == null) { return (0, _pgSql.sql)(_templateObject4); } if (options.max) { number = Math.min(number, options.max); } var query = (0, _pgSql.sql)(_templateObject7, number); return query; } /** * Create a SQL "OR" clause, just like "WHERE". * * @param {String} ident * @param {Object} params * @param {Object} options * @return {sql} */ function OR(ident, params) { var options = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {}; var query = WHERE(ident, params, _extends({}, options, { keyword: 'OR' })); return query; } /** * Create a SQL "ORDER BY" string from `sorts`. * * @param {String} table (optional) * @param {Array} sorts * @return {sql} */ function ORDER_BY(table, sorts) { if (Array.isArray(table)) { sorts = table; table = null; } if (!Array.isArray(sorts)) { throw new Error('The `ORDER_BY` SQL helper must be passed an array of sorting parameters, but you passed: ' + sorts); } if (!sorts.length) { return (0, _pgSql.sql)(_templateObject4); } var values = sorts.map(function (sort) { return SORT(table, sort); }); var query = (0, _pgSql.sql)(_templateObject8, _pgSql.sql.join(values, ', ')); return query; } /** * Create a SQL `ROW` expression for the values of an `object`. * * @param {Object} object * @return {sql} */ function ROW(object) { var query = (0, _pgSql.sql)(_templateObject9, COMPOSITE(object)); return query; } /** * Create a SQL "SELECT" clause for `table` with `values`. * * @param {String} table * @param {Object|Array<String>|Array<Object>} values * @return {sql} */ function SELECT(table, values) { if (table != null && !_is2.default.string(table)) { values = table; table = null; } var query = (0, _pgSql.sql)(_templateObject10, COLUMNS(table, values)); return query; } /** * Create a SQL sort expression. * * @param {String} table (optional) * @param {String} column * @return {sql} */ function SORT(table, column) { if (arguments.length === 1) { column = table; table = null; } var order = 'ASC'; if (column.startsWith('-')) { order = 'DESC'; column = column.slice(1); } return (0, _pgSql.sql)(_templateObject11, COLUMN(table, column), _pgSql.sql.raw(order)); } /** * Create a SQL "UPDATE" clause for `table` with `values`. * * @param {String} table * @param {Object} values * @return {sql} */ function UPDATE(table, values) { if (typeof table != 'string') { values = table; table = null; } if (!_is2.default.object(values)) { throw new Error('The `UPDATE` SQL helper must be passed an object, but you passed: ' + values); } var keys = getDefinedKeys(values); var id = table ? (0, _pgSql.sql)(_templateObject, _pgSql.sql.ident(table)) : (0, _pgSql.sql)(_templateObject4); var query = keys.length == 1 ? (0, _pgSql.sql)(_templateObject12, id, COLUMN(keys[0]), values[keys[0]]) : (0, _pgSql.sql)(_templateObject13, id, COLUMNS(values), ROW(values)); return query; } /** * Create a SQL "INSERT ON CONFLICT UPDATE" statement from a dictionary or list of `values`. * * @param {String} table * @param {String|Array<String>} constraint * @param {Object|Array<Object>} values * @param {Object} options * @return {sql} */ function UPSERT(table, constraint, values) { var options = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : {}; if (typeof constraint === 'string') { constraint = [constraint]; } var keys = _is2.default.object(values) ? getDefinedKeys(values) : getDefinedKeys(values[0]); var others = keys.filter(function (k) { return !constraint.includes(k); }); var insert = INSERT(table, values); var conflict = (0, _pgSql.sql)(_templateObject14, COLUMNS(constraint)); var update = others.length > 0 ? (0, _pgSql.sql)(_templateObject15, COLUMNS(others), COLUMNS('excluded', others)) : (0, _pgSql.sql)(_templateObject16); var distinct = others.length > 0 && options.distinct !== false ? (0, _pgSql.sql)(_templateObject17, COLUMNS(table, others), COLUMNS('excluded', others)) : (0, _pgSql.sql)(_templateObject4); var query = (0, _pgSql.sql)(_templateObject18, insert, conflict, update, distinct); return query; } /** * Create a list of placeholders for the values of an `object`. * * @param {Object} object * @return {sql} */ function VALUES(object) { if (!Array.isArray(object)) { object = [object]; } var query = (0, _pgSql.sql)(_templateObject19, COMPOSITES(object)); return query; } /** * Create a SQL "where" clause with `params` and optional `ident`. * * @param {String} ident * @param {Object} params * @return {sql} */ function WHERE(ident, params) { var options = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {}; if (_is2.default.object(ident)) { params = ident; ident = ''; } if (params == null) { return (0, _pgSql.sql)(_templateObject4); } function handle(keys, obj) { var key = keys[keys.length - 1]; var value = obj[key]; var operator = WHERE_OPERATORS[key] || '='; if ((0, _isPlainObject2.default)(value)) { var ks = getDefinedKeys(value); if (ks.length === 0) return; ks.forEach(function (k) { return handle([].concat(_toConsumableArray(keys), [k]), value); }); return; } if (value === null) { value = _pgSql.sql.raw('NULL'); if (operator === '=') operator = 'IS'; if (operator === '!=') operator = 'IS NOT'; } var ref = key in WHERE_OPERATORS ? keys.slice(0, -1).join('->') : keys.join('->'); var id = ident ? (0, _pgSql.sql)(_templateObject20, _pgSql.sql.ident(ident), _pgSql.sql.ident(ref)) : (0, _pgSql.sql)(_templateObject, _pgSql.sql.ident(ref)); var clause = (0, _pgSql.sql)(_templateObject21, id, _pgSql.sql.raw(operator), value); clauses.push(clause); } var _options$keyword = options.keyword, keyword = _options$keyword === undefined ? 'WHERE' : _options$keyword, _options$delimiter2 = options.delimiter, delimiter = _options$delimiter2 === undefined ? 'AND' : _options$delimiter2; var clauses = []; getDefinedKeys(params).forEach(function (key) { handle([key], params); }); if (clauses.length === 0) { return (0, _pgSql.sql)(_templateObject4); } var query = (0, _pgSql.sql)(_templateObject22, _pgSql.sql.raw(keyword), _pgSql.sql.join(clauses, ' ' + delimiter + ' ')); return query; } /** * Get the keys for an `object` that don't have undefined values. * * @param {Object} object * @return {Array} */ function getDefinedKeys(object) { return Object.keys(object).filter(function (k) { return object[k] !== undefined; }).sort(); } /** * Add lowercase aliases for convenience. */ var and = AND; var column = COLUMN; var columns = COLUMNS; var composite = COMPOSITE; var composites = COMPOSITES; var insert = INSERT; var limit = LIMIT; var offset = OFFSET; var or = OR; var orderBy = ORDER_BY; var row = ROW; var select = SELECT; var sort = SORT; var update = UPDATE; var upsert = UPSERT; var values = VALUES; var where = WHERE; /** * Export. * * @type {Function} */ exports.and = and; exports.AND = AND; exports.column = column; exports.COLUMN = COLUMN; exports.columns = columns; exports.COLUMNS = COLUMNS; exports.composite = composite; exports.COMPOSITE = COMPOSITE; exports.composites = composites; exports.COMPOSITES = COMPOSITES; exports.insert = insert; exports.INSERT = INSERT; exports.limit = limit; exports.LIMIT = LIMIT; exports.offset = offset; exports.OFFSET = OFFSET; exports.or = or; exports.OR = OR; exports.orderBy = orderBy; exports.ORDER_BY = ORDER_BY; exports.row = row; exports.ROW = ROW; exports.select = select; exports.SELECT = SELECT; exports.sort = sort; exports.SORT = SORT; exports.update = update; exports.UPDATE = UPDATE; exports.upsert = upsert; exports.UPSERT = UPSERT; exports.values = values; exports.VALUES = VALUES; exports.where = where; exports.WHERE = WHERE;