<commit_before>var ChainFind       = require("./ChainFind");
var Instance        = require("./Instance").Instance;
var LazyLoad        = require("./LazyLoad");
var ManyAssociation = require("./Associations/Many");
var OneAssociation  = require("./Associations/One");
var Property        = require("./Property");
var Singleton       = require("./Singleton");
var Utilities       = require("./Utilities");
var Validators      = require("./Validators");

exports.Model = Model;

function Model(opts) {
	opts = opts || {};

	if (!Array.isArray(opts.keys) || opts.keys.length < 2) {
		opts.keys = [ opts.id ];
	} else {
		opts.id = null;
	}

	var one_associations = [];
	var many_associations = [];
	var association_properties = [];
	var model_fields = [];

	for (var i = 0; i < opts.keys.length; i++) {
		model_fields.push(opts.keys[i]);
	}

	var createInstance = function (data, inst_opts, cb) {
		if (!inst_opts) {
			inst_opts = {};
		}

		var found_assoc = false, i, k;

		for (k in data) {
			if (k == "extra_field") continue;
			if (opts.properties.hasOwnProperty(k)) continue;
			if (inst_opts.extra && inst_opts.extra.hasOwnProperty(k)) continue;
			if (opts.keys.indexOf(k) >= 0) continue;
			if (association_properties.indexOf(k) >= 0) continue;

			found_assoc = false;
			for (i = 0; i < one_associations.length; i++) {
				if (one_associations[i].name == k) {
					found_assoc = true;
					break;
				}
			}
			if (!found_assoc) {
				for (i = 0; i < many_associations.length; i++) {
					if (many_associations[i].name == k) {
						found_assoc = true;
						break;
					}
				}
			}
			if (!found_assoc) {
				delete data[k];
			}
		}

		var instance = new Instance({
			id                     : opts.id,
			keys                   : opts.keys,
			is_new                 : inst_opts.is_new || false,
			isShell                : inst_opts.isShell || false,
			data                   : data,
			autoSave               : inst_opts.autoSave || false,
			extra                  : inst_opts.extra,
			extra_info             : inst_opts.extra_info,
			model                  : model,
			driver                 : opts.driver,
			table                  : opts.table,
			properties             : opts.properties,
			hooks                  : opts.hooks,
			methods                : opts.methods,
			validations            : opts.validations,
			one_associations       : one_associations,
			many_associations      : many_associations,
			association_properties : association_properties
		});
		if (model_fields !== null) {
			LazyLoad.extend(instance, model, opts.properties);
		}
		OneAssociation.extend(model, instance, opts.driver, one_associations, {
			autoFetch      : inst_opts.autoFetch || false,
			autoFetchLimit : inst_opts.autoFetchLimit,
			cascadeRemove  : inst_opts.cascadeRemove
		}, function () {
			ManyAssociation.extend(model, instance, opts.driver, many_associations, {
				autoFetch      : inst_opts.autoFetch || false,
				autoFetchLimit : inst_opts.autoFetchLimit,
				cascadeRemove  : inst_opts.cascadeRemove
			}, function () {
				if (typeof cb == "function") {
					return cb(instance);
				}
			});
		});
		return instance;
	};

	var model = function (data) {
		var instance;
		if (typeof data == "number") {
			var data2 = {};
			data2[opts.id] = data;

			return createInstance(data2, { isShell: true });
		} else if (typeof data == "undefined") {
			data = {};
		}

		return createInstance(data, {
			is_new        : !data.hasOwnProperty(opts.id),
			autoSave      : opts.autoSave,
			cascadeRemove : opts.cascadeRemove
		});
	};

	// Standardize validations
	for (var k in opts.validations) {
		if (typeof opts.validations[k] == 'function') {
			opts.validations[k] = [opts.validations[k]]
		}
	}

	for (var k in opts.properties) {
		opts.properties[k] = Property.normalize(opts.properties[k], opts.settings);

		if (opts.properties[k].lazyload !== true) {
			model_fields.push(k);
		}
		if (opts.properties[k].required) {
			// Prepend `required` validation
			if(opts.validations.hasOwnProperty(k)) {
				opts.validations[k].splice(0, 0, Validators.required());
			} else {
				opts.validations[k] = [Validators.required()];
			}
		}
	}

	model.settings = opts.settings;

	model.drop = function (cb) {
		if (arguments.length === 0) {
			cb = function () {};
		}
		if (typeof opts.driver.drop == "function") {
			opts.driver.drop({
				table             : opts.table,
				properties        : opts.properties,
				one_associations  : one_associations,
				many_associations : many_associations
			}, cb);

			return this;
		}

		return cb(new Error("Driver does not support Model.drop()"));
	};

	model.sync = function (cb) {
		if (arguments.length === 0) {
			cb = function () {};
		}
		if (typeof opts.driver.sync == "function") {
			opts.driver.sync({
				keys              : opts.keys,
				table             : opts.table,
				properties        : opts.properties,
				indexes           : opts.indexes || [],
				one_associations  : one_associations,
				many_associations : many_associations
			}, cb);

			return this;
		}

		return cb(new Error("Driver does not support Model.sync()"));
	};

	model.get = function () {
		var conditions = {};
		var options    = {};
		var ids        = Array.prototype.slice.apply(arguments);
		var cb         = ids.pop();

		if (typeof cb != "function") {
			throw new Error("Missing Model.get() callback");
		}

		if (typeof ids[ids.length - 1] == "object") {
			options = ids.pop();
		}

		if (ids.length == 1 && Array.isArray(ids[0])) {
			ids = ids[0];
		}

		if (ids.length != opts.keys.length) {<commit_msg>Fixes bug when passing an array (object) of ids but no options object<commit_after>var ChainFind       = require("./ChainFind");
var Instance        = require("./Instance").Instance;
var LazyLoad        = require("./LazyLoad");
var ManyAssociation = require("./Associations/Many");
var OneAssociation  = require("./Associations/One");
var Property        = require("./Property");
var Singleton       = require("./Singleton");
var Utilities       = require("./Utilities");
var Validators      = require("./Validators");

exports.Model = Model;

function Model(opts) {
	opts = opts || {};

	if (!Array.isArray(opts.keys) || opts.keys.length < 2) {
		opts.keys = [ opts.id ];
	} else {
		opts.id = null;
	}

	var one_associations = [];
	var many_associations = [];
	var association_properties = [];
	var model_fields = [];

	for (var i = 0; i < opts.keys.length; i++) {
		model_fields.push(opts.keys[i]);
	}

	var createInstance = function (data, inst_opts, cb) {
		if (!inst_opts) {
			inst_opts = {};
		}

		var found_assoc = false, i, k;

		for (k in data) {
			if (k == "extra_field") continue;
			if (opts.properties.hasOwnProperty(k)) continue;
			if (inst_opts.extra && inst_opts.extra.hasOwnProperty(k)) continue;
			if (opts.keys.indexOf(k) >= 0) continue;
			if (association_properties.indexOf(k) >= 0) continue;

			found_assoc = false;
			for (i = 0; i < one_associations.length; i++) {
				if (one_associations[i].name == k) {
					found_assoc = true;
					break;
				}
			}
			if (!found_assoc) {
				for (i = 0; i < many_associations.length; i++) {
					if (many_associations[i].name == k) {
						found_assoc = true;
						break;
					}
				}
			}
			if (!found_assoc) {
				delete data[k];
			}
		}

		var instance = new Instance({
			id                     : opts.id,
			keys                   : opts.keys,
			is_new                 : inst_opts.is_new || false,
			isShell                : inst_opts.isShell || false,
			data                   : data,
			autoSave               : inst_opts.autoSave || false,
			extra                  : inst_opts.extra,
			extra_info             : inst_opts.extra_info,
			model                  : model,
			driver                 : opts.driver,
			table                  : opts.table,
			properties             : opts.properties,
			hooks                  : opts.hooks,
			methods                : opts.methods,
			validations            : opts.validations,
			one_associations       : one_associations,
			many_associations      : many_associations,
			association_properties : association_properties
		});
		if (model_fields !== null) {
			LazyLoad.extend(instance, model, opts.properties);
		}
		OneAssociation.extend(model, instance, opts.driver, one_associations, {
			autoFetch      : inst_opts.autoFetch || false,
			autoFetchLimit : inst_opts.autoFetchLimit,
			cascadeRemove  : inst_opts.cascadeRemove
		}, function () {
			ManyAssociation.extend(model, instance, opts.driver, many_associations, {
				autoFetch      : inst_opts.autoFetch || false,
				autoFetchLimit : inst_opts.autoFetchLimit,
				cascadeRemove  : inst_opts.cascadeRemove
			}, function () {
				if (typeof cb == "function") {
					return cb(instance);
				}
			});
		});
		return instance;
	};

	var model = function (data) {
		var instance;
		if (typeof data == "number") {
			var data2 = {};
			data2[opts.id] = data;

			return createInstance(data2, { isShell: true });
		} else if (typeof data == "undefined") {
			data = {};
		}

		return createInstance(data, {
			is_new        : !data.hasOwnProperty(opts.id),
			autoSave      : opts.autoSave,
			cascadeRemove : opts.cascadeRemove
		});
	};

	// Standardize validations
	for (var k in opts.validations) {
		if (typeof opts.validations[k] == 'function') {
			opts.validations[k] = [opts.validations[k]]
		}
	}

	for (var k in opts.properties) {
		opts.properties[k] = Property.normalize(opts.properties[k], opts.settings);

		if (opts.properties[k].lazyload !== true) {
			model_fields.push(k);
		}
		if (opts.properties[k].required) {
			// Prepend `required` validation
			if(opts.validations.hasOwnProperty(k)) {
				opts.validations[k].splice(0, 0, Validators.required());
			} else {
				opts.validations[k] = [Validators.required()];
			}
		}
	}

	model.settings = opts.settings;

	model.drop = function (cb) {
		if (arguments.length === 0) {
			cb = function () {};
		}
		if (typeof opts.driver.drop == "function") {
			opts.driver.drop({
				table             : opts.table,
				properties        : opts.properties,
				one_associations  : one_associations,
				many_associations : many_associations
			}, cb);

			return this;
		}

		return cb(new Error("Driver does not support Model.drop()"));
	};

	model.sync = function (cb) {
		if (arguments.length === 0) {
			cb = function () {};
		}
		if (typeof opts.driver.sync == "function") {
			opts.driver.sync({
				keys              : opts.keys,
				table             : opts.table,
				properties        : opts.properties,
				indexes           : opts.indexes || [],
				one_associations  : one_associations,
				many_associations : many_associations
			}, cb);

			return this;
		}

		return cb(new Error("Driver does not support Model.sync()"));
	};

	model.get = function () {
		var conditions = {};
		var options    = {};
		var ids        = Array.prototype.slice.apply(arguments);
		var cb         = ids.pop();

		if (typeof cb != "function") {
			throw new Error("Missing Model.get() callback");
		}

		if (typeof ids[ids.length - 1] == "object" && !Array.isArray(ids[ids.length - 1])) {
			options = ids.pop();
		}

		if (ids.length == 1 && Array.isArray(ids[0])) {
			ids = ids[0];
		}

		if (ids.length != opts.keys.length) {
{'fraction_non_alphanumeric': 0.14248911788220664, 'fraction_numerical': 0.003109176512392289, 'mean_word_length': 2.496273291925466, 'pattern_counts': {'":': 0, '<': 11, '<?xml version=': 0, '>': 7, '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': '5163168', 'n_tokens_mistral': 4199, 'n_tokens_neox': 3582, 'n_words': 778}