不要怂,就是干,撸起袖子干!

Commit b9bdc1d4 by Felix Becker Committed by Jan Aagaard Meier

ES6 refactor of utils.js (#6059)

- let, const, arrow functions, property shorthands, exports, classes
 - changes classes to be PascalCase
 - Removes inherit() function (not used anymore)
1 parent 49a7e543
......@@ -1098,9 +1098,9 @@ const QueryGenerator = {
if (Array.isArray(attr) && attr.length === 2) {
if (attr[0]._isSequelizeMethod) {
if (attr[0] instanceof Utils.literal ||
attr[0] instanceof Utils.cast ||
attr[0] instanceof Utils.fn
if (attr[0] instanceof Utils.Literal ||
attr[0] instanceof Utils.Cast ||
attr[0] instanceof Utils.Fn
) {
verbatim = true;
}
......@@ -1110,9 +1110,9 @@ const QueryGenerator = {
attrAs = attr[1];
attr = attr[0];
} else if (attr instanceof Utils.literal) {
} else if (attr instanceof Utils.Literal) {
return attr.val; // We trust the user to rename the field correctly
} else if (attr instanceof Utils.cast || attr instanceof Utils.fn) {
} else if (attr instanceof Utils.Cast || attr instanceof Utils.Fn) {
throw new Error(
'Tried to select attributes using Sequelize.cast or Sequelize.fn without specifying an alias for the result, during eager loading. ' +
'This means the attribute will not be added to the returned instance'
......@@ -1503,7 +1503,7 @@ const QueryGenerator = {
const subQueryOrder = [];
const validateOrder = order => {
if (order instanceof Utils.literal) return;
if (order instanceof Utils.Literal) return;
if (!_.includes([
'ASC',
......@@ -1538,7 +1538,7 @@ const QueryGenerator = {
mainQueryOrder.push(this.quote(t, model));
}
} else {
mainQueryOrder.push(this.quote(typeof options.order === 'string' ? new Utils.literal(options.order) : options.order, model));
mainQueryOrder.push(this.quote(typeof options.order === 'string' ? new Utils.Literal(options.order) : options.order, model));
}
return {mainQueryOrder, subQueryOrder};
......@@ -1757,7 +1757,7 @@ const QueryGenerator = {
handleSequelizeMethod(smth, tableName, factory, options, prepend) {
let result;
if (smth instanceof Utils.where) {
if (smth instanceof Utils.Where) {
let value = smth.logic;
let key;
......@@ -1784,9 +1784,9 @@ const QueryGenerator = {
result = (value === 'NULL') ? key + ' IS NULL' : [key, value].join(' ' + smth.comparator + ' ');
}
} else if (smth instanceof Utils.literal) {
} else if (smth instanceof Utils.Literal) {
result = smth.val;
} else if (smth instanceof Utils.cast) {
} else if (smth instanceof Utils.Cast) {
if (smth.val._isSequelizeMethod) {
result = this.handleSequelizeMethod(smth.val, tableName, factory, options, prepend);
} else {
......@@ -1794,7 +1794,7 @@ const QueryGenerator = {
}
result = 'CAST(' + result + ' AS ' + smth.type.toUpperCase() + ')';
} else if (smth instanceof Utils.fn) {
} else if (smth instanceof Utils.Fn) {
result = smth.fn + '(' + smth.args.map(arg => {
if (arg._isSequelizeMethod) {
return this.handleSequelizeMethod(arg, tableName, factory, options, prepend);
......@@ -1802,7 +1802,7 @@ const QueryGenerator = {
return this.escape(arg);
}
}).join(', ') + ')';
} else if (smth instanceof Utils.col) {
} else if (smth instanceof Utils.Col) {
if (Array.isArray(smth.col)) {
if (!factory) {
throw new Error('Cannot call Sequelize.col() with array outside of order / group clause');
......@@ -1949,7 +1949,7 @@ const QueryGenerator = {
}
}
if (value && value._isSequelizeMethod && !(key !== undefined && value instanceof Utils.fn)) {
if (value && value._isSequelizeMethod && !(key !== undefined && value instanceof Utils.Fn)) {
return this.handleSequelizeMethod(value);
}
......@@ -2025,7 +2025,7 @@ const QueryGenerator = {
let $baseKey = this.quoteIdentifier(key)+'#>>\'{'+path.join(', ')+'}\'';
if (options.prefix) {
if (options.prefix instanceof Utils.literal) {
if (options.prefix instanceof Utils.Literal) {
$baseKey = this.handleSequelizeMethod(options.prefix)+'.'+$baseKey;
} else {
$baseKey = this.quoteTable(options.prefix)+'.'+$baseKey;
......@@ -2060,7 +2060,7 @@ const QueryGenerator = {
$where[$prop] = $item;
const $key = castKey($item);
$items.push(this.whereItemQuery(new Utils.literal($key), $where/*, _.pick(options, 'prefix')*/));
$items.push(this.whereItemQuery(new Utils.Literal($key), $where/*, _.pick(options, 'prefix')*/));
} else {
traverse($prop, $item, path.concat([$prop]));
}
......@@ -2069,7 +2069,7 @@ const QueryGenerator = {
$where.$eq = item;
const $key = castKey(item);
$items.push(this.whereItemQuery(new Utils.literal($key), $where/*, _.pick(options, 'prefix')*/));
$items.push(this.whereItemQuery(new Utils.Literal($key), $where/*, _.pick(options, 'prefix')*/));
}
};
......@@ -2125,7 +2125,7 @@ const QueryGenerator = {
comparator = 'IN';
if (value.$notIn) comparator = 'NOT IN';
if ((value.$in || value.$notIn) instanceof Utils.literal) {
if ((value.$in || value.$notIn) instanceof Utils.Literal) {
value = (value.$in || value.$notIn).val;
} else if ((value.$in || value.$notIn).length) {
value = '('+(value.$in || value.$notIn).map(item => this.escape(item)).join(', ')+')';
......@@ -2226,7 +2226,7 @@ const QueryGenerator = {
}
if (options.prefix && prefix) {
if (options.prefix instanceof Utils.literal) {
if (options.prefix instanceof Utils.Literal) {
key = [this.handleSequelizeMethod(options.prefix), key].join('.');
} else {
key = [this.quoteTable(options.prefix), key].join('.');
......
......@@ -124,7 +124,7 @@ const QueryGenerator = {
},
handleSequelizeMethod(smth, tableName, factory, options, prepend) {
if (smth instanceof Utils.json) {
if (smth instanceof Utils.Json) {
// Parse nested object
if (smth.conditions) {
const conditions = _.map(this.parseConditionObject(smth.conditions), condition =>
......
......@@ -890,7 +890,7 @@ class Sequelize {
* @return {Sequelize.fn}
*/
static fn(fn) {
return new Utils.fn(fn, Utils.sliceArgs(arguments, 1));
return new Utils.Fn(fn, Utils.sliceArgs(arguments, 1));
}
/**
......@@ -903,7 +903,7 @@ class Sequelize {
* @return {Sequelize.col}
*/
static col(col) {
return new Utils.col(col);
return new Utils.Col(col);
}
/**
......@@ -916,7 +916,7 @@ class Sequelize {
* @return {Sequelize.cast}
*/
static cast(val, type) {
return new Utils.cast(val, type);
return new Utils.Cast(val, type);
}
/**
......@@ -929,7 +929,7 @@ class Sequelize {
* @return {Sequelize.literal}
*/
static literal(val) {
return new Utils.literal(val);
return new Utils.Literal(val);
}
/**
......@@ -968,7 +968,7 @@ class Sequelize {
* @return {Sequelize.json}
*/
static json(conditionsOrPath, value) {
return new Utils.json(conditionsOrPath, value);
return new Utils.Json(conditionsOrPath, value);
}
/**
......@@ -990,7 +990,7 @@ class Sequelize {
* @return {Sequelize.where}
*/
static where(attr, comparator, logic) {
return new Utils.where(attr, comparator, logic);
return new Utils.Where(attr, comparator, logic);
}
/**
......
'use strict';
var DataTypes = require('./data-types')
, SqlString = require('./sql-string')
, _ = require('lodash').runInContext() // Prevent anyone messing with template settings by creating a fresh copy
, parameterValidator = require('./utils/parameter-validator')
, inflection = require('inflection')
, uuid = require('node-uuid')
, primitives = ['string', 'number', 'boolean'];
var Utils = module.exports = {
inflection: inflection,
_: _,
camelizeIf: function(string, condition) {
var result = string;
if (condition) {
result = Utils.camelize(string);
const DataTypes = require('./data-types');
const SqlString = require('./sql-string');
const _ = require('lodash').runInContext(); // Prevent anyone messing with template settings by creating a fresh copy
const parameterValidator = require('./utils/parameter-validator');
const inflection = require('inflection');
const uuid = require('node-uuid');
const Promise = require('./promise');
const primitives = ['string', 'number', 'boolean'];
exports.Promise = Promise;
exports._ = _;
exports.inflection = inflection;
function camelizeIf(string, condition) {
let result = string;
if (condition) {
result = camelize(string);
}
return result;
}
exports.camelizeIf = camelizeIf;
function underscoredIf(string, condition) {
let result = string;
if (condition) {
result = inflection.underscore(string);
}
return result;
}
exports.underscoredIf = underscoredIf;
function isPrimitive(val) {
return primitives.indexOf(typeof val) !== -1;
}
exports.isPrimitive = isPrimitive;
// Same concept as _.merge, but don't overwrite properties that have already been assigned
function mergeDefaults(a, b) {
return _.mergeWith(a, b, (objectValue, sourceValue) => {
// If it's an object, let _ handle it this time, we will be called again for each property
if (!this._.isPlainObject(objectValue) && objectValue !== undefined) {
return objectValue;
}
return result;
},
underscoredIf: function(string, condition) {
var result = string;
if (condition) {
result = inflection.underscore(string);
}
return result;
},
isPrimitive: function (val) {
return primitives.indexOf(typeof val) !== -1;
},
// Same concept as _.merge, but don't overwrite properties that have already been assigned
mergeDefaults: function (a, b) {
return _.mergeWith(a, b, function (objectValue, sourceValue) {
// If it's an object, let _ handle it this time, we will be called again for each property
if (!this._.isPlainObject(objectValue) && objectValue !== undefined) {
return objectValue;
}
}.bind(this));
},
// An alternative to _.merge, which doesn't clone its arguments
// Cloning is a bad idea because options arguments may contain references to sequelize
// models - which again reference database libs which don't like to be cloned (in particular pg-native)
merge: function () {
var result = {};
Array.prototype.slice.apply(arguments).forEach(function (obj) {
_.forOwn(obj, function (value, key) {
if (typeof value !== 'undefined') {
if (!result[key]) {
result[key] = value;
} else if (_.isPlainObject(value) && _.isPlainObject(result[key])) {
result[key] = Utils.merge(result[key], value);
} else if (Array.isArray(value) && Array.isArray(result[key])) {
result[key] = value.concat(result[key]);
} else {
result[key] = value;
}
});
}
exports.mergeDefaults = mergeDefaults;
// An alternative to _.merge, which doesn't clone its arguments
// Cloning is a bad idea because options arguments may contain references to sequelize
// models - which again reference database libs which don't like to be cloned (in particular pg-native)
function merge() {
const result = {};
for (const obj of arguments) {
_.forOwn(obj, (value, key) => {
if (typeof value !== 'undefined') {
if (!result[key]) {
result[key] = value;
} else if (_.isPlainObject(value) && _.isPlainObject(result[key])) {
result[key] = merge(result[key], value);
} else if (Array.isArray(value) && Array.isArray(result[key])) {
result[key] = value.concat(result[key]);
} else {
result[key] = value;
}
});
});
return result;
},
lowercaseFirst: function (s) {
return s[0].toLowerCase() + s.slice(1);
},
uppercaseFirst: function (s) {
return s[0].toUpperCase() + s.slice(1);
},
spliceStr: function (str, index, count, add) {
return str.slice(0, index) + add + str.slice(index + count);
},
camelize: function(str){
return str.trim().replace(/[-_\s]+(.)?/g, function(match, c){ return c.toUpperCase(); });
},
format: function(arr, dialect) {
var timeZone = null;
// Make a clone of the array beacuse format modifies the passed args
return SqlString.format(arr[0], arr.slice(1), timeZone, dialect);
},
formatNamedParameters: function(sql, parameters, dialect) {
var timeZone = null;
return SqlString.formatNamedParameters(sql, parameters, timeZone, dialect);
},
cloneDeep: function(obj) {
obj = obj || {};
return _.cloneDeepWith(obj, function (elem) {
// Do not try to customize cloning of arrays or POJOs
if (Array.isArray(elem) || _.isPlainObject(elem)) {
return undefined;
}
// Don't clone stuff that's an object, but not a plain one - fx example sequelize models and instances
if (typeof elem === 'object') {
return elem;
}
// Preserve special data-types like `fn` across clones. _.get() is used for checking up the prototype chain
if (elem && typeof elem.clone === 'function') {
return elem.clone();
}
});
},
/* Expand and normalize finder options */
mapFinderOptions: function(options, Model) {
if (Model._hasVirtualAttributes && Array.isArray(options.attributes)) {
options.attributes.forEach(function (attribute) {
if (Model._isVirtualAttribute(attribute) && Model.rawAttributes[attribute].type.fields) {
options.attributes = options.attributes.concat(Model.rawAttributes[attribute].type.fields);
}
}.bind(Model));
options.attributes = _.without.apply(_, [options.attributes].concat(Model._virtualAttributes));
options.attributes = _.uniq(options.attributes);
}
return result;
}
exports.merge = merge;
function lowercaseFirst(s) {
return s[0].toLowerCase() + s.slice(1);
}
exports.lowercaseFirst = lowercaseFirst;
function uppercaseFirst(s) {
return s[0].toUpperCase() + s.slice(1);
}
exports.uppercaseFirst = uppercaseFirst;
function spliceStr(str, index, count, add) {
return str.slice(0, index) + add + str.slice(index + count);
}
exports.spliceStr = spliceStr;
function camelize(str) {
return str.trim().replace(/[-_\s]+(.)?/g, (match, c) => c.toUpperCase());
}
exports.camelize = camelize;
function format(arr, dialect) {
const timeZone = null;
// Make a clone of the array beacuse format modifies the passed args
return SqlString.format(arr[0], arr.slice(1), timeZone, dialect);
}
exports.format = format;
function formatNamedParameters(sql, parameters, dialect) {
const timeZone = null;
return SqlString.formatNamedParameters(sql, parameters, timeZone, dialect);
}
exports.formatNamedParameters = formatNamedParameters;
function cloneDeep(obj) {
obj = obj || {};
return _.cloneDeepWith(obj, elem => {
// Do not try to customize cloning of arrays or POJOs
if (Array.isArray(elem) || _.isPlainObject(elem)) {
return undefined;
}
Utils.mapOptionFieldNames(options, Model);
return options;
},
/* Used to map field names in attributes and where conditions */
mapOptionFieldNames: function(options, Model) {
if (Array.isArray(options.attributes)) {
options.attributes = options.attributes.map(function(attr) {
// Object lookups will force any variable to strings, we don't want that for special objects etc
if (typeof attr !== 'string') return attr;
// Map attributes to aliased syntax attributes
if (Model.rawAttributes[attr] && attr !== Model.rawAttributes[attr].field) {
return [Model.rawAttributes[attr].field, attr];
}
return attr;
});
// Don't clone stuff that's an object, but not a plain one - fx example sequelize models and instances
if (typeof elem === 'object') {
return elem;
}
if (options.where && _.isPlainObject(options.where)) {
options.where = Utils.mapWhereFieldNames(options.where, Model);
// Preserve special data-types like `fn` across clones. _.get() is used for checking up the prototype chain
if (elem && typeof elem.clone === 'function') {
return elem.clone();
}
if (Array.isArray(options.order)) {
options.order.forEach(function(oGroup) {
var OrderModel, attr, attrOffset;
if (Array.isArray(oGroup)) {
OrderModel = Model;
// Check if we have ['attr', 'DESC'] or [Model, 'attr', 'DESC']
if (typeof oGroup[oGroup.length - 2] === 'string') {
attrOffset = 2;
// Assume ['attr'], [Model, 'attr'] or [seq.fn('somefn', 1), 'DESC']
} else {
attrOffset = 1;
}
attr = oGroup[oGroup.length - attrOffset];
if (oGroup.length > attrOffset) {
OrderModel = oGroup[oGroup.length - (attrOffset + 1)];
if (OrderModel.model) {
OrderModel = OrderModel.model;
}
}
if (OrderModel.rawAttributes && OrderModel.rawAttributes[attr] && attr !== OrderModel.rawAttributes[attr].field) {
oGroup[oGroup.length - attrOffset] = OrderModel.rawAttributes[attr].field;
}
}
});
});
}
exports.cloneDeep = cloneDeep;
/* Expand and normalize finder options */
function mapFinderOptions(options, Model) {
if (Model._hasVirtualAttributes && Array.isArray(options.attributes)) {
for (const attribute of options.attributes) {
if (Model._isVirtualAttribute(attribute) && Model.rawAttributes[attribute].type.fields) {
options.attributes = options.attributes.concat(Model.rawAttributes[attribute].type.fields);
}
}
options.attributes = _.without.apply(_, [options.attributes].concat(Model._virtualAttributes));
options.attributes = _.uniq(options.attributes);
}
mapOptionFieldNames(options, Model);
return options;
}
exports.mapFinderOptions = mapFinderOptions;
/* Used to map field names in attributes and where conditions */
function mapOptionFieldNames(options, Model) {
if (Array.isArray(options.attributes)) {
options.attributes = options.attributes.map(attr => {
// Object lookups will force any variable to strings, we don't want that for special objects etc
if (typeof attr !== 'string') return attr;
// Map attributes to aliased syntax attributes
if (Model.rawAttributes[attr] && attr !== Model.rawAttributes[attr].field) {
return [Model.rawAttributes[attr].field, attr];
}
return attr;
});
}
return options;
},
if (options.where && _.isPlainObject(options.where)) {
options.where = mapWhereFieldNames(options.where, Model);
}
mapWhereFieldNames: function (attributes, Model) {
var attribute
, rawAttribute;
if (Array.isArray(options.order)) {
for (const oGroup of options.order) {
let OrderModel;
let attr;
let attrOffset;
if (attributes) {
for (attribute in attributes) {
rawAttribute = Model.rawAttributes[attribute];
if (Array.isArray(oGroup)) {
OrderModel = Model;
if (rawAttribute && rawAttribute.field !== rawAttribute.fieldName) {
attributes[rawAttribute.field] = attributes[attribute];
delete attributes[attribute];
}
// Check if we have ['attr', 'DESC'] or [Model, 'attr', 'DESC']
if (typeof oGroup[oGroup.length - 2] === 'string') {
attrOffset = 2;
if (_.isPlainObject(attributes[attribute])) {
attributes[attribute] = Utils.mapOptionFieldNames({
where: attributes[attribute]
}, Model).where;
// Assume ['attr'], [Model, 'attr'] or [seq.fn('somefn', 1), 'DESC']
} else {
attrOffset = 1;
}
if (Array.isArray(attributes[attribute])) {
attributes[attribute] = attributes[attribute].map(function (where) {
if (_.isPlainObject(where)) {
return Utils.mapWhereFieldNames(where, Model);
}
attr = oGroup[oGroup.length - attrOffset];
if (oGroup.length > attrOffset) {
OrderModel = oGroup[oGroup.length - (attrOffset + 1)];
if (OrderModel.model) {
OrderModel = OrderModel.model;
}
}
return where;
});
if (OrderModel.rawAttributes && OrderModel.rawAttributes[attr] && attr !== OrderModel.rawAttributes[attr].field) {
oGroup[oGroup.length - attrOffset] = OrderModel.rawAttributes[attr].field;
}
}
}
}
return attributes;
},
return options;
}
exports.mapOptionFieldNames = mapOptionFieldNames;
/* Used to map field names in values */
mapValueFieldNames: function (dataValues, fields, Model) {
var values = {};
function mapWhereFieldNames(attributes, Model) {
let attribute;
let rawAttribute;
fields.forEach(function(attr) {
if (dataValues[attr] !== undefined && !Model._isVirtualAttribute(attr)) {
// Field name mapping
if (Model.rawAttributes[attr] && Model.rawAttributes[attr].field && Model.rawAttributes[attr].field !== attr) {
values[Model.rawAttributes[attr].field] = dataValues[attr];
} else {
values[attr] = dataValues[attr];
}
}
});
if (attributes) {
for (attribute in attributes) {
rawAttribute = Model.rawAttributes[attribute];
return values;
},
isColString: function(value) {
return typeof value === 'string' && value.substr(0, 1) === '$' && value.substr(value.length - 1, 1) === '$';
},
argsArePrimaryKeys: function(args, primaryKeys) {
var result = (args.length === Object.keys(primaryKeys).length);
if (result) {
Utils._.each(args, function(arg) {
if (result) {
if (['number', 'string'].indexOf(typeof arg) !== -1) {
result = true;
} else {
result = (arg instanceof Date) || Buffer.isBuffer(arg);
}
}
});
}
return result;
},
canTreatArrayAsAnd: function(arr) {
return arr.reduce(function(treatAsAnd, arg) {
if (treatAsAnd) {
return treatAsAnd;
} else {
return Utils._.isPlainObject(arg);
if (rawAttribute && rawAttribute.field !== rawAttribute.fieldName) {
attributes[rawAttribute.field] = attributes[attribute];
delete attributes[attribute];
}
}, false);
},
combineTableNames: function(tableName1, tableName2) {
return (tableName1.toLowerCase() < tableName2.toLowerCase()) ? (tableName1 + tableName2) : (tableName2 + tableName1);
},
if (_.isPlainObject(attributes[attribute])) {
attributes[attribute] = mapOptionFieldNames({
where: attributes[attribute]
}, Model).where;
}
singularize: function(s) {
return inflection.singularize(s);
},
if (Array.isArray(attributes[attribute])) {
attributes[attribute] = attributes[attribute].map(where => {
if (_.isPlainObject(where)) {
return mapWhereFieldNames(where, Model);
}
pluralize: function(s) {
return inflection.pluralize(s);
},
return where;
});
}
}
}
removeCommentsFromFunctionString: function(s) {
s = s.replace(/\s*(\/\/.*)/g, '');
s = s.replace(/(\/\*[\n\r\s\S]*?\*\/)/mg, '');
return attributes;
}
exports.mapWhereFieldNames = mapWhereFieldNames;
return s;
},
/* Used to map field names in values */
function mapValueFieldNames(dataValues, fields, Model) {
const values = {};
toDefaultValue: function(value) {
if (typeof value === 'function') {
var tmp = value();
if (tmp instanceof DataTypes.ABSTRACT) {
return tmp.toSql();
for (const attr of fields) {
if (dataValues[attr] !== undefined && !Model._isVirtualAttribute(attr)) {
// Field name mapping
if (Model.rawAttributes[attr] && Model.rawAttributes[attr].field && Model.rawAttributes[attr].field !== attr) {
values[Model.rawAttributes[attr].field] = dataValues[attr];
} else {
return tmp;
values[attr] = dataValues[attr];
}
} else if (value instanceof DataTypes.UUIDV1) {
return uuid.v1();
} else if (value instanceof DataTypes.UUIDV4) {
return uuid.v4();
} else if (value instanceof DataTypes.NOW) {
return Utils.now();
} else if(_.isPlainObject(value) || _.isArray(value)) {
return _.clone(value);
} else {
return value;
}
},
/**
* Determine if the default value provided exists and can be described
* in a db schema using the DEFAULT directive.
*
* @param {*} value Any default value.
* @return {boolean} yes / no.
*/
defaultValueSchemable: function(value) {
if (typeof value === 'undefined') { return false; }
// TODO this will be schemable when all supported db
// have been normalized for this case
if (value instanceof DataTypes.NOW) { return false; }
if (value instanceof DataTypes.UUIDV1 || value instanceof DataTypes.UUIDV4) { return false; }
if (_.isFunction(value)) {
return false;
}
return true;
},
removeNullValuesFromHash: function(hash, omitNull, options) {
var result = hash;
options = options || {};
options.allowNull = options.allowNull || [];
if (omitNull) {
var _hash = {};
Utils._.forIn(hash, function(val, key) {
if (options.allowNull.indexOf(key) > -1 || key.match(/Id$/) || ((val !== null) && (val !== undefined))) {
_hash[key] = val;
}
return values;
}
exports.mapValueFieldNames = mapValueFieldNames;
function isColString(value) {
return typeof value === 'string' && value.substr(0, 1) === '$' && value.substr(value.length - 1, 1) === '$';
}
exports.isColString = isColString;
function argsArePrimaryKeys(args, primaryKeys) {
let result = (args.length === Object.keys(primaryKeys).length);
if (result) {
_.each(args, arg => {
if (result) {
if (['number', 'string'].indexOf(typeof arg) !== -1) {
result = true;
} else {
result = (arg instanceof Date) || Buffer.isBuffer(arg);
}
});
result = _hash;
}
return result;
},
inherit: function(SubClass, SuperClass) {
if (SuperClass.constructor === Function) {
// Normal Inheritance
SubClass.prototype = new SuperClass();
SubClass.prototype.constructor = SubClass;
SubClass.prototype.parent = SuperClass.prototype;
}
});
}
return result;
}
exports.argsArePrimaryKeys = argsArePrimaryKeys;
function canTreatArrayAsAnd(arr) {
return arr.reduce((treatAsAnd, arg) => {
if (treatAsAnd) {
return treatAsAnd;
} else {
// Pure Virtual Inheritance
SubClass.prototype = SuperClass;
SubClass.prototype.constructor = SubClass;
SubClass.prototype.parent = SuperClass;
return _.isPlainObject(arg);
}
return SubClass;
},
stack: function _stackGrabber() {
var orig = Error.prepareStackTrace;
Error.prepareStackTrace = function(_, stack) { return stack; };
var err = new Error();
Error.captureStackTrace(err, _stackGrabber);
var errStack = err.stack;
Error.prepareStackTrace = orig;
return errStack;
},
sliceArgs: function (args, begin) {
begin = begin || 0;
var tmp = new Array(args.length - begin);
for (var i = begin; i < args.length; ++i) {
tmp[i - begin] = args[i];
}, false);
}
exports.canTreatArrayAsAnd = canTreatArrayAsAnd;
function combineTableNames(tableName1, tableName2) {
return (tableName1.toLowerCase() < tableName2.toLowerCase()) ? (tableName1 + tableName2) : (tableName2 + tableName1);
}
exports.combineTableNames = combineTableNames;
function singularize(s) {
return inflection.singularize(s);
}
exports.singularize = singularize;
function pluralize(s) {
return inflection.pluralize(s);
}
exports.pluralize = pluralize;
function removeCommentsFromFunctionString(s) {
s = s.replace(/\s*(\/\/.*)/g, '');
s = s.replace(/(\/\*[\n\r\s\S]*?\*\/)/mg, '');
return s;
}
exports.removeCommentsFromFunctionString = removeCommentsFromFunctionString;
function toDefaultValue(value) {
if (typeof value === 'function') {
const tmp = value();
if (tmp instanceof DataTypes.ABSTRACT) {
return tmp.toSql();
} else {
return tmp;
}
return tmp;
},
} else if (value instanceof DataTypes.UUIDV1) {
return uuid.v1();
} else if (value instanceof DataTypes.UUIDV4) {
return uuid.v4();
} else if (value instanceof DataTypes.NOW) {
return now();
} else if(_.isPlainObject(value) || _.isArray(value)) {
return _.clone(value);
} else {
return value;
}
}
exports.toDefaultValue = toDefaultValue;
/**
* Determine if the default value provided exists and can be described
* in a db schema using the DEFAULT directive.
*
* @param {*} value Any default value.
* @return {boolean} yes / no.
*/
function defaultValueSchemable(value) {
if (typeof value === 'undefined') { return false; }
// TODO this will be schemable when all supported db
// have been normalized for this case
if (value instanceof DataTypes.NOW) { return false; }
if (value instanceof DataTypes.UUIDV1 || value instanceof DataTypes.UUIDV4) { return false; }
if (_.isFunction(value)) {
return false;
}
return true;
}
exports.defaultValueSchemable = defaultValueSchemable;
function removeNullValuesFromHash(hash, omitNull, options) {
let result = hash;
options = options || {};
options.allowNull = options.allowNull || [];
if (omitNull) {
const _hash = {};
_.forIn(hash, (val, key) => {
if (options.allowNull.indexOf(key) > -1 || key.match(/Id$/) || ((val !== null) && (val !== undefined))) {
_hash[key] = val;
}
});
now: function(dialect) {
var now = new Date();
if (['postgres', 'sqlite'].indexOf(dialect) === -1) {
now.setMilliseconds(0);
}
return now;
},
tick: function(func) {
var tick = (global.hasOwnProperty('setImmediate') ? global.setImmediate : process.nextTick);
tick(func);
},
// Note: Use the `quoteIdentifier()` and `escape()` methods on the
// `QueryInterface` instead for more portable code.
TICK_CHAR: '`',
addTicks: function(s, tickChar) {
tickChar = tickChar || Utils.TICK_CHAR;
return tickChar + Utils.removeTicks(s, tickChar) + tickChar;
},
removeTicks: function(s, tickChar) {
tickChar = tickChar || Utils.TICK_CHAR;
return s.replace(new RegExp(tickChar, 'g'), '');
},
/*
* Utility functions for representing SQL functions, and columns that should be escaped.
* Please do not use these functions directly, use Sequelize.fn and Sequelize.col instead.
*/
fn: function(fn, args) {
result = _hash;
}
return result;
}
exports.removeNullValuesFromHash = removeNullValuesFromHash;
function stack() {
const orig = Error.prepareStackTrace;
Error.prepareStackTrace = (_, stack) => stack;
const err = new Error();
Error.captureStackTrace(err, stack);
const errStack = err.stack;
Error.prepareStackTrace = orig;
return errStack;
}
exports.stack = stack;
function sliceArgs(args, begin) {
begin = begin || 0;
const tmp = new Array(args.length - begin);
for (let i = begin; i < args.length; ++i) {
tmp[i - begin] = args[i];
}
return tmp;
}
exports.sliceArgs = sliceArgs;
function now(dialect) {
const now = new Date();
if (['postgres', 'sqlite'].indexOf(dialect) === -1) {
now.setMilliseconds(0);
}
return now;
}
exports.now = now;
// Note: Use the `quoteIdentifier()` and `escape()` methods on the
// `QueryInterface` instead for more portable code.
const TICK_CHAR = '`';
exports.TICK_CHAR = TICK_CHAR;
function addTicks(s, tickChar) {
tickChar = tickChar || TICK_CHAR;
return tickChar + removeTicks(s, tickChar) + tickChar;
}
exports.addTicks = addTicks;
function removeTicks(s, tickChar) {
tickChar = tickChar || TICK_CHAR;
return s.replace(new RegExp(tickChar, 'g'), '');
}
exports.removeTicks = removeTicks;
/**
* Utility functions for representing SQL functions, and columns that should be escaped.
* Please do not use these functions directly, use Sequelize.fn and Sequelize.col instead.
*/
class Fn {
constructor(fn, args) {
this.fn = fn;
this.args = args;
},
col: function(col) {
}
clone() {
return new Fn(this.fn, this.args);
}
}
exports.Fn = Fn;
class Col {
constructor(col) {
if (arguments.length > 1) {
col = this.sliceArgs(arguments);
}
this.col = col;
},
}
}
exports.Col = Col;
cast: function(val, type) {
class Cast {
constructor(val, type) {
this.val = val;
this.type = (type || '').trim();
},
}
}
exports.Cast = Cast;
literal: function(val) {
class Literal {
constructor(val) {
this.val = val;
},
}
}
exports.Literal = Literal;
json: function(conditionsOrPath, value) {
if (Utils._.isObject(conditionsOrPath)) {
class Json {
constructor(conditionsOrPath, value) {
if (_.isObject(conditionsOrPath)) {
this.conditions = conditionsOrPath;
} else {
this.path = conditionsOrPath;
......@@ -436,9 +480,12 @@ var Utils = module.exports = {
this.value = value;
}
}
},
}
}
exports.Json = Json;
where: function(attribute, comparator, logic) {
class Where {
constructor(attribute, comparator, logic) {
if (logic === undefined) {
logic = comparator;
comparator = '=';
......@@ -447,20 +494,15 @@ var Utils = module.exports = {
this.attribute = attribute;
this.comparator = comparator;
this.logic = logic;
},
validateParameter: parameterValidator
};
Utils.where.prototype._isSequelizeMethod =
Utils.literal.prototype._isSequelizeMethod =
Utils.cast.prototype._isSequelizeMethod =
Utils.fn.prototype._isSequelizeMethod =
Utils.col.prototype._isSequelizeMethod =
Utils.json.prototype._isSequelizeMethod = true;
Utils.fn.prototype.clone = function() {
return new Utils.fn(this.fn, this.args);
};
Utils.Promise = require('./promise');
}
}
exports.Where = Where;
Where.prototype._isSequelizeMethod =
Literal.prototype._isSequelizeMethod =
Cast.prototype._isSequelizeMethod =
Fn.prototype._isSequelizeMethod =
Col.prototype._isSequelizeMethod =
Json.prototype._isSequelizeMethod = true;
exports.validateParameter = parameterValidator;
......@@ -130,8 +130,8 @@ describe(Support.getTestDialectTeaser('DAO'), function() {
b: self.sequelize.col('always_false')
});
expect(user.get('d')).to.be.instanceof(self.sequelize.Utils.fn);
expect(user.get('b')).to.be.instanceof(self.sequelize.Utils.col);
expect(user.get('d')).to.be.instanceof(self.sequelize.Utils.Fn);
expect(user.get('b')).to.be.instanceof(self.sequelize.Utils.Col);
return user.save().then(function() {
return user.reload().then(function() {
......
......@@ -195,23 +195,23 @@ describe(Support.getTestDialectTeaser('Utils'), function() {
another_json_field: { x: 1 }
};
var expected = "metadata#>>'{language}' = 'icelandic' and metadata#>>'{pg_rating,dk}' = 'G' and another_json_field#>>'{x}' = '1'";
expect(queryGenerator.handleSequelizeMethod(new Utils.json(conditions))).to.deep.equal(expected);
expect(queryGenerator.handleSequelizeMethod(new Utils.Json(conditions))).to.deep.equal(expected);
});
it('successfully parses a string using dot notation', function() {
var path = 'metadata.pg_rating.dk';
expect(queryGenerator.handleSequelizeMethod(new Utils.json(path))).to.equal("metadata#>>'{pg_rating,dk}'");
expect(queryGenerator.handleSequelizeMethod(new Utils.Json(path))).to.equal("metadata#>>'{pg_rating,dk}'");
});
it('allows postgres json syntax', function() {
var path = 'metadata->pg_rating->>dk';
expect(queryGenerator.handleSequelizeMethod(new Utils.json(path))).to.equal(path);
expect(queryGenerator.handleSequelizeMethod(new Utils.Json(path))).to.equal(path);
});
it('can take a value to compare against', function() {
var path = 'metadata.pg_rating.is';
var value = 'U';
expect(queryGenerator.handleSequelizeMethod(new Utils.json(path, value))).to.equal("metadata#>>'{pg_rating,is}' = 'U'");
expect(queryGenerator.handleSequelizeMethod(new Utils.Json(path, value))).to.equal("metadata#>>'{pg_rating,is}' = 'U'");
});
});
}
......
Markdown is supported
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!