UNPKG

offshore

Version:
148 lines (113 loc) 4.76 kB
/** * Dependencies */ var _ = require('lodash'); var schemaUtils = require('../utils/schema'); var COLLECTION_DEFAULTS = require('../collection/defaults'); var Model = require('../model'); var Cast = require('./typecast'); var Schema = require('./schema'); var Validator = require('./validations'); var Transformer = require('./transformations'); var hasOwnProperty = require('../utils/helpers').object.hasOwnProperty; /** * Core * * Setup the basic Core of a collection to extend. */ var Core = module.exports = function(options) { options = options || {}; // Set Defaults this.adapter = this.adapter || {}; this._attributes = this.attributes; this.connections = this.connections || {}; this.defaults = _.merge(COLLECTION_DEFAULTS, this.defaults); // Construct our internal objects this._cast = new Cast(); this._schema = new Schema(this); this._validator = new Validator(this); // Normalize attributes, extract instance methods, and callbacks // Note: this is ordered for a reason! this._callbacks = schemaUtils.normalizeCallbacks(this); this._instanceMethods = schemaUtils.instanceMethods(this.attributes); this._attributes = schemaUtils.normalizeAttributes(this._attributes); this.hasSchema = Core._normalizeSchemaFlag.call(this); this.migrate = Object.getPrototypeOf(this).hasOwnProperty('migrate') ? this.migrate : this.defaults.migrate; // Initalize the internal values from the Collection Core._initialize.call(this, options); return this; }; /** * Initialize * * Setups internal mappings from an extended collection. */ Core._initialize = function(options) { var self = this; options = options || {}; // Extend a base Model with instance methods this._model = new Model(this, this._instanceMethods); // Cache the attributes from the schema builder var schemaAttributes = this.offshore.schema[this.identity].attributes; // Remove auto attributes for validations var _validations = _.clone(this._attributes); if (this.autoPK) delete _validations.id; if (this.autoCreatedAt) delete _validations.createdAt; if (this.autoUpdatedAt) delete _validations.updatedAt; // If adapter exposes any reserved attributes, pass them to the schema var connIdx = Array.isArray(this.connection) ? this.connection[0] : this.connection; var adapterInfo = {}; if (this.connections[connIdx] && this.connections[connIdx]._adapter) { adapterInfo = this.connections[connIdx]._adapter; } var reservedAttributes = adapterInfo.reservedAttributes || {}; // Initialize internal objects from attributes this._schema.initialize(this._attributes, this.hasSchema, reservedAttributes); this._cast.initialize(this._schema.schema); this._validator.initialize(_validations, this.types, this.defaults.validations, this.offshore.schema[this.identity].criteria); // Set the collection's primaryKey attribute Object.keys(schemaAttributes).forEach(function(key) { if (hasOwnProperty(schemaAttributes[key], 'primaryKey') && schemaAttributes[key].primaryKey) { self.primaryKey = key; } }); // Build Data Transformer this._transformer = new Transformer(schemaAttributes, this.offshore.collections); // Transform Schema this._schema.schema = this._transformer.serialize(this._schema.schema, 'schema'); // Add this collection to the connection Object.keys(this.connections).forEach(function(conn) { self.connections[conn]._collections = self.connections[conn]._collections || []; self.connections[conn]._collections.push(self.identity); }); // Remove remnants of user defined attributes delete this.attributes; }; /** * Normalize Schema Flag * * Normalize schema setting by looking at the model first to see if it is defined, if not look at * the connection and see if it's defined and if not finally look into the adapter and check if * there is a default setting. If not found anywhere be safe and set to true. * * @api private * @return {Boolean} */ Core._normalizeSchemaFlag = function() { // If schema is defined on the collection, return the value if (hasOwnProperty(Object.getPrototypeOf(this), 'schema')) { return Object.getPrototypeOf(this).schema; } // Grab the first connection used if (!this.connection || !Array.isArray(this.connection)) return true; var connection = this.connections[this.connection[0]]; // Check the user defined config if (hasOwnProperty(connection, 'config') && hasOwnProperty(connection.config, 'schema')) { return connection.config.schema; } // Check the defaults defined in the adapter if (!hasOwnProperty(connection, '_adapter')) return true; if (!hasOwnProperty(connection._adapter, 'schema')) return true; return connection._adapter.schema; };