UNPKG

vitamin

Version:

Data Mapper library for Node.js applications

287 lines (228 loc) 6.91 kB
'use strict'; Object.defineProperty(exports, "__esModule", { value: true }); var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); var _bluebird = require('bluebird'); var _bluebird2 = _interopRequireDefault(_bluebird); var _query = require('./query'); var _query2 = _interopRequireDefault(_query); var _underscore = require('underscore'); var _underscore2 = _interopRequireDefault(_underscore); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } // exports var _class = function () { /** * BaseRelation constructor * * @param {Model} parent mapper instance * @param {Model} target mapper instance * @constructor */ function _class(parent) { var target = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : null; _classCallCheck(this, _class); this.name = null; this.parent = parent; this.localKey = null; // parent key this.otherKey = null; // target key if (target != null) this.setTarget(target); } /** * Set the target mapper instance * * @param {Mapper} target * @return this relation */ _createClass(_class, [{ key: 'setTarget', value: function setTarget(target) { this.query = new _query2.default(target.newQuery()).setRelation(this); this.target = target; return this; } /** * Set the name of the relationship * * @param {String} name * @return this relation */ }, { key: 'setName', value: function setName(name) { if (this.query) this.query.from(this.target.tableName, name); this.name = name; return this; } /** * Get the relation query * * @return query */ }, { key: 'getQuery', value: function getQuery() { return this.query; } /** * Create a new instance of the related model * * @param {Object} attrs * @param {Array} returning * @return promise */ }, { key: 'create', value: function create(attrs) { var returning = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : ['*']; return this.save(this.target.newInstance(attrs), returning); } /** * Create many instances of the related model * * @param {Array} records * @parma {Array} returning * @return promise */ }, { key: 'createMany', value: function createMany(records) { var _this = this; var returning = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : ['*']; return _bluebird2.default.map(records, function (attrs) { return _this.create(attrs, returning); }); } /** * Save the related model * * @param {Model} model * @param {Array} returning * @return promise */ }, { key: 'save', value: function save(model) { var _target; var returning = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : ['*']; return (_target = this.target).save.apply(_target, arguments); } /** * Save the related models * * @param {Array} models * @parma {Array} returning * @return promise */ }, { key: 'saveMany', value: function saveMany(models) { var _this2 = this; var returning = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : ['*']; return _bluebird2.default.map(models, function (model) { return _this2.save(model, returning); }); } /** * Modify the query of the relationship * * @param {Function} fn * @param {Array} args * @return this relation */ }, { key: 'modify', value: function modify(fn) { for (var _len = arguments.length, args = Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) { args[_key - 1] = arguments[_key]; } fn.apply(undefined, [this.query].concat(args)); return this; } /** * Load and populate the related models * * @param {Array} models * @return promise */ }, { key: 'eagerLoad', value: function eagerLoad(models) { var _this3 = this; this.addEagerLoadConstraints(models); return this.getQuery().fetch().then(function (res) { return _this3.populate(models, res); }); } /** * Add constraints on the relation query * * @param {Model} model * @return this relation */ }, { key: 'addConstraints', value: function addConstraints(model) { this.query.where(this.getCompareKey(), model.get(this.localKey)); this.model = model; return this; } /** * Add eager load constraints on the relation query * * @param {Array} models * @private */ }, { key: 'addEagerLoadConstraints', value: function addEagerLoadConstraints(models) { this.query.whereIn(this.getCompareKey(), this.getKeys(models, this.localKey)); } /** * Get the fully qualified compare key of the relation * * @return string * @private */ }, { key: 'getCompareKey', value: function getCompareKey() { return this.query.getQualifiedColumn(this.otherKey); } /** * Get the keys of the given models * * @param {Array} models * @param {String} key * @return array * @private */ }, { key: 'getKeys', value: function getKeys(models, key) { return _underscore2.default.chain(models).map(function (m) { return key ? m.get(key) : m.getId(); }).uniq().value(); } /** * Populate the parent models with the eagerly loaded results * * @param {Array} models * @param {Array} results * @private */ }, { key: 'populate', value: function populate(models, related) { var _this4 = this; var dict = this.buildDictionary(related, this.otherKey); models.forEach(function (parent) { var value = dict[parent.get(_this4.localKey)]; parent.setRelated(_this4.name, _this4.parseRelationValue(value)); }); } }]); return _class; }(); exports.default = _class;