sails-postgresql
Version:
a PostgreSQL adapter for Waterline and Sails.js
77 lines (64 loc) • 5.68 kB
JavaScript
// ██████╗ ██████╗ ███████╗ ██████╗ ██████╗ ██████╗ ██████╗███████╗███████╗███████╗
// ██╔══██╗██╔══██╗██╔════╝ ██╔══██╗██╔══██╗██╔═══██╗██╔════╝██╔════╝██╔════╝██╔════╝
// ██████╔╝██████╔╝█████╗ ██████╔╝██████╔╝██║ ██║██║ █████╗ ███████╗███████╗
// ██╔═══╝ ██╔══██╗██╔══╝ ██╔═══╝ ██╔══██╗██║ ██║██║ ██╔══╝ ╚════██║╚════██║
// ██║ ██║ ██║███████╗ ██║ ██║ ██║╚██████╔╝╚██████╗███████╗███████║███████║
// ╚═╝ ╚═╝ ╚═╝╚══════╝ ╚═╝ ╚═╝ ╚═╝ ╚═════╝ ╚═════╝╚══════╝╚══════╝╚══════╝
//
// ███████╗ █████╗ ██████╗██╗ ██╗ ██████╗ ███████╗ ██████╗ ██████╗ ██████╗ ██████╗
// ██╔════╝██╔══██╗██╔════╝██║ ██║ ██╔══██╗██╔════╝██╔════╝██╔═══██╗██╔══██╗██╔══██╗
// █████╗ ███████║██║ ███████║ ██████╔╝█████╗ ██║ ██║ ██║██████╔╝██║ ██║
// ██╔══╝ ██╔══██║██║ ██╔══██║ ██╔══██╗██╔══╝ ██║ ██║ ██║██╔══██╗██║ ██║
// ███████╗██║ ██║╚██████╗██║ ██║ ██║ ██║███████╗╚██████╗╚██████╔╝██║ ██║██████╔╝
// ╚══════╝╚═╝ ╚═╝ ╚═════╝╚═╝ ╚═╝ ╚═╝ ╚═╝╚══════╝ ╚═════╝ ╚═════╝ ╚═╝ ╚═╝╚═════╝
//
var _ = require('@sailshq/lodash');
var utils = require('waterline-utils');
var eachRecordDeep = utils.eachRecordDeep;
module.exports = function processEachRecord(options) {
// ╦ ╦╔═╗╦ ╦╔╦╗╔═╗╔╦╗╔═╗ ┌─┐┌─┐┌┬┐┬┌─┐┌┐┌┌─┐
// ╚╗╔╝╠═╣║ ║ ║║╠═╣ ║ ║╣ │ │├─┘ │ ││ ││││└─┐
// ╚╝ ╩ ╩╩═╝╩═╩╝╩ ╩ ╩ ╚═╝ └─┘┴ ┴ ┴└─┘┘└┘└─┘
if (_.isUndefined(options) || !_.isPlainObject(options)) {
throw new Error('Invalid options argument. Options must contain: records, identity, and orm.');
}
if (!_.has(options, 'records') || !_.isArray(options.records)) {
throw new Error('Invalid option used in options argument. Missing or invalid records.');
}
if (!_.has(options, 'identity') || !_.isString(options.identity)) {
throw new Error('Invalid option used in options argument. Missing or invalid identity.');
}
if (!_.has(options, 'orm') || !_.isPlainObject(options.orm)) {
throw new Error('Invalid option used in options argument. Missing or invalid orm.');
}
// Key the collections by identity instead of column name
var collections = _.reduce(options.orm.collections, function(memo, val) {
memo[val.identity] = val;
return memo;
}, {});
options.orm.collections = collections;
// Run all the records through the iterator so that they can be normalized.
// > (This should *never* go more than one level deep!)
eachRecordDeep(options.records, function iterator(record, WLModel, depth) {
if (depth !== 1) {
throw new Error('Consistency violation: Incoming new records in a s3q should never necessitate deep iteration! If you are seeing this error, it is probably because of a bug in this adapter, or in Waterline core.');
}
_.each(WLModel.definition, function checkAttributes(attrDef) {
var columnName = attrDef.columnName;
// JSON stringify any type of JSON attributes that have array values because
// the queries won't be generated correctly otherwise.
if (attrDef.type === 'json' && _.has(record, columnName)) {
if (_.isArray(record[columnName]) || _.isString(record[columnName])) {
record[columnName] = JSON.stringify(record[columnName]);
}
}
// For attributes using the `bigint` column type, coerce empty string to zero.
// This allows use of `type: 'string'` with bigint, which we want because the pg driver
// returns bigints as strings. And since the regular `int` field in postgres is too small
// to hold JS timestamps, users are forced to use `bigint` to hold them.
if (_.get(attrDef, 'autoMigrations.columnType') === 'bigint' && record[columnName] === '') {
record[columnName] = 0;
}
});
}, true, options.identity, options.orm);
};