<commit_before>// --------------------
// Sequelize virtual fields
// beforeFind hook function
// --------------------

// modules
var _ = require('lodash');

// imports
var shared = require('./shared'),
	mergeClauses = shared.mergeClauses;

// exports
module.exports = function(options) {
	var model = this,
		sequelize = model.sequelize,
		Sequelize = sequelize.Sequelize;
	
	if (!sequelize.options.virtualFields.active) return;
	
	replaceVirtualFields(options, model);
	
	// ----------
	// functions
	
	function replaceVirtualFields(options, model) {
		if (options.attributes) {
			for (var i = 0; i < options.attributes.length; i++) { // not using _.forEach as array is altered during looping
				var fieldName = options.attributes[i],
					field = model.attributes[fieldName];
				
				if (field.type != Sequelize.VIRTUAL) continue;
				
				// field is virtual - add attributes & includes from virtualField
				addVirtualFieldOptions(options, field, fieldName);
			
				// delete virtual attribute
				options.attributes.splice(i, 1);
				i--;
			}
		} else {
			// no attributes specified - all attributes of model will load so check all virtualFields
			_.forIn(model.attributes, function(field, fieldName) {
				if (field.type != Sequelize.VIRTUAL) return;
				
				// add attributes & includes from virtual field
				addVirtualFieldOptions(options, field, fieldName);
			});
		}
		
		// repeat process for all includes recursively
		var includes = options.include;
		if (includes) {
			_.forEach(includes, function(include, index) {
				// if include given as model with no attributes/include, convert to {model: model} notation
				if (include instanceof Sequelize.Model) include = includes[index] = {model: include};
				
				// recurse through this include
				replaceVirtualFields(include, include.model);
			});
		}
	}
	
	function addVirtualFieldOptions(options, field, fieldName) {
		// record in options.virtuals
		options.virtuals = options.virtuals || [];
		options.virtuals.push(fieldName);
		
		// merge attributes + includes from virtual field
		mergeClauses(options, field);
	}
};<commit_msg>Replace virtual fields in order clause<commit_after>// --------------------
// Sequelize virtual fields
// beforeFind hook function
// --------------------

// modules
var _ = require('lodash');

// imports
var shared = require('./shared'),
	mergeClauses = shared.mergeClauses,
	mergeOrders = shared.mergeOrders;

// exports
module.exports = function(options) {
	var model = this,
		sequelize = model.sequelize,
		Sequelize = sequelize.Sequelize;
	
	if (!sequelize.options.virtualFields.active) return;
	
	replaceVirtualFields(options, model);
	replaceVirtualOrders(options, model);
	
	// ----------
	// functions
	
	function replaceVirtualFields(options, model) {
		if (options.attributes) {
			for (var i = 0; i < options.attributes.length; i++) { // not using _.forEach as array is altered during looping
				var fieldName = options.attributes[i],
					field = model.attributes[fieldName];
				
				if (field.type != Sequelize.VIRTUAL) continue;
				
				// field is virtual - add attributes & includes from virtualField
				addVirtualFieldOptions(options, field, fieldName);
			
				// delete virtual attribute
				options.attributes.splice(i, 1);
				i--;
			}
		} else {
			// no attributes specified - all attributes of model will load so check all virtualFields
			_.forIn(model.attributes, function(field, fieldName) {
				if (field.type != Sequelize.VIRTUAL) return;
				
				// add attributes & includes from virtual field
				addVirtualFieldOptions(options, field, fieldName);
			});
		}
		
		// repeat process for all includes recursively
		var includes = options.include;
		if (includes) {
			_.forEach(includes, function(include, index) {
				// if include given as model with no attributes/include, convert to {model: model} notation
				if (include instanceof Sequelize.Model) include = includes[index] = {model: include};
				
				// recurse through this include
				replaceVirtualFields(include, include.model);
			});
		}
	}
	
	function addVirtualFieldOptions(options, field, fieldName) {
		// record in options.virtuals
		options.virtuals = options.virtuals || [];
		options.virtuals.push(fieldName);
		
		// merge attributes + includes from virtual field
		mergeClauses(options, field);
	}
	
	function replaceVirtualOrders(options, model) {
		var orders = options.order;
		if (!options.order) return;
		if (!Array.isArray(orders)) orders = options.order = [orders];
		
		// parse order clauses, adding 'ASC' if none provided
		_.forEach(orders, function(order) {
			// if just a string, leave alone - is raw query
			if (_.isString(order)) return;
			
			// if an object (e.g. {raw: ...}), add 'ASC' sort order
			if (!Array.isArray(order)) {
				orders[index] = [order, 'ASC'];
				return;
			}
			
			// add 'ASC' sort order if no sort order defined
			if (order.length == 0) throw new Sequelize.SequelizeVirtualFieldsError('Invalid order clause');
			if (order.length == 1 || !_.isString(order[order.length - 2])) {
				order.push('ASC');
			} else {
				order[order.length - 1] = order[order.length - 1].toUpperCase();
			}
		});
		
		// replace virtual fields in orders by their referenced fields
		mergeOrders(orders, model);
	}
};
{'fraction_non_alphanumeric': 0.1342434584755404, 'fraction_numerical': 0.0017064846416382253, 'mean_word_length': 3.105058365758755, 'pattern_counts': {'":': 0, '<': 5, '<?xml version=': 0, '>': 3, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '314729', 'n_tokens_mistral': 1762, 'n_tokens_neox': 1472, 'n_words': 435}