vitamin
Version:
Data Mapper library for Node.js applications
287 lines (228 loc) • 6.91 kB
JavaScript
'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;