PageRenderTime 61ms CodeModel.GetById 20ms RepoModel.GetById 14ms app.codeStats 0ms

/node_modules/bookshelf/lib/eager.js

https://gitlab.com/jonnyforney/beerbowerpainting
JavaScript | 175 lines | 106 code | 49 blank | 20 comment | 10 complexity | e3c75c27ee890fce12c48a5883efb966 MD5 | raw file
  1. 'use strict';
  2. Object.defineProperty(exports, "__esModule", {
  3. value: true
  4. });
  5. var _slicedToArray2 = require('babel-runtime/helpers/slicedToArray');
  6. var _slicedToArray3 = _interopRequireDefault(_slicedToArray2);
  7. var _extends2 = require('babel-runtime/helpers/extends');
  8. var _extends3 = _interopRequireDefault(_extends2);
  9. var _classCallCheck2 = require('babel-runtime/helpers/classCallCheck');
  10. var _classCallCheck3 = _interopRequireDefault(_classCallCheck2);
  11. var _createClass2 = require('babel-runtime/helpers/createClass');
  12. var _createClass3 = _interopRequireDefault(_createClass2);
  13. var _possibleConstructorReturn2 = require('babel-runtime/helpers/possibleConstructorReturn');
  14. var _possibleConstructorReturn3 = _interopRequireDefault(_possibleConstructorReturn2);
  15. var _inherits2 = require('babel-runtime/helpers/inherits');
  16. var _inherits3 = _interopRequireDefault(_inherits2);
  17. var _lodash = require('lodash');
  18. var _lodash2 = _interopRequireDefault(_lodash);
  19. var _helpers = require('./helpers');
  20. var _helpers2 = _interopRequireDefault(_helpers);
  21. var _promise = require('./base/promise');
  22. var _promise2 = _interopRequireDefault(_promise);
  23. var _eager = require('./base/eager');
  24. var _eager2 = _interopRequireDefault(_eager);
  25. function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
  26. // EagerRelation
  27. // ---------------
  28. var getAttributeUnique = function getAttributeUnique(models, attribute) {
  29. return (0, _lodash.uniq)((0, _lodash.map)(models, function (m) {
  30. return m.get(attribute);
  31. }));
  32. };
  33. // An `EagerRelation` object temporarily stores the models from an eager load,
  34. // and handles matching eager loaded objects with their parent(s). The
  35. // `tempModel` is only used to retrieve the value of the relation method, to
  36. // know the constraints for the eager query.
  37. var EagerRelation = (function (_EagerBase) {
  38. (0, _inherits3.default)(EagerRelation, _EagerBase);
  39. function EagerRelation() {
  40. (0, _classCallCheck3.default)(this, EagerRelation);
  41. return (0, _possibleConstructorReturn3.default)(this, Object.getPrototypeOf(EagerRelation).apply(this, arguments));
  42. }
  43. (0, _createClass3.default)(EagerRelation, [{
  44. key: 'eagerFetch',
  45. // Handles an eager loaded fetch, passing the name of the item we're fetching
  46. // for, and any options needed for the current fetch.
  47. value: function eagerFetch(relationName, handled, options) {
  48. var _this2 = this;
  49. var relatedData = handled.relatedData;
  50. // skip eager loading for rows where the foreign key isn't set
  51. if (relatedData.parentFk === null) return;
  52. if (relatedData.type === 'morphTo') {
  53. return this.morphToFetch(relationName, relatedData, options);
  54. }
  55. return handled.sync((0, _extends3.default)({}, options, { parentResponse: this.parentResponse })).select().tap(function (response) {
  56. return _this2._eagerLoadHelper(response, relationName, handled, _lodash2.default.omit(options, 'parentResponse'));
  57. });
  58. }
  59. // Special handler for the eager loaded morph-to relations, this handles the
  60. // fact that there are several potential models that we need to be fetching
  61. // against. pairing them up onto a single response for the eager loading.
  62. }, {
  63. key: 'morphToFetch',
  64. value: function morphToFetch(relationName, relatedData, options) {
  65. var _this3 = this;
  66. var columnNames = relatedData.columnNames || [];
  67. var morphName = relatedData.morphName;
  68. var _columnNames = (0, _slicedToArray3.default)(columnNames, 2);
  69. var _columnNames$ = _columnNames[0];
  70. var typeColumn = _columnNames$ === undefined ? morphName + '_type' : _columnNames$;
  71. var _columnNames$2 = _columnNames[1];
  72. var idColumn = _columnNames$2 === undefined ? morphName + '_id' : _columnNames$2;
  73. var parentsByType = (0, _lodash.groupBy)(this.parent, function (model) {
  74. return model.get(typeColumn);
  75. });
  76. var TargetByType = (0, _lodash.mapValues)(parentsByType, function (parents, type) {
  77. return _helpers2.default.morphCandidate(relatedData.candidates, type);
  78. });
  79. return _promise2.default.all((0, _lodash.map)(parentsByType, function (parents, type) {
  80. var Target = TargetByType[type];
  81. var idAttribute = _lodash2.default.result(Target.prototype, 'idAttribute');
  82. var ids = getAttributeUnique(parents, idColumn);
  83. return Target.query('whereIn', idAttribute, ids).sync(options).select().tap(function (response) {
  84. var clone = relatedData.instance('morphTo', Target, { morphName: morphName, columnNames: columnNames });
  85. return _this3._eagerLoadHelper(response, relationName, { relatedData: clone }, options);
  86. });
  87. })).then(_lodash.flatten);
  88. }
  89. // Handles the eager load for both the `morphTo` and regular cases.
  90. }, {
  91. key: '_eagerLoadHelper',
  92. value: function _eagerLoadHelper(response, relationName, handled, options) {
  93. var relatedModels = this.pushModels(relationName, handled, response);
  94. var relatedData = handled.relatedData;
  95. // If there is a response, fetch additional nested eager relations, if any.
  96. if (response.length > 0 && options.withRelated) {
  97. var relatedModel = relatedData.createModel();
  98. // If this is a `morphTo` relation, we need to do additional processing
  99. // to ensure we don't try to load any relations that don't look to exist.
  100. if (relatedData.type === 'morphTo') {
  101. var withRelated = this._filterRelated(relatedModel, options);
  102. if (withRelated.length === 0) return;
  103. options = _lodash2.default.extend({}, options, { withRelated: withRelated });
  104. }
  105. return new EagerRelation(relatedModels, response, relatedModel).fetch(options).return(response);
  106. }
  107. }
  108. // Filters the `withRelated` on a `morphTo` relation, to ensure that only valid
  109. // relations are attempted for loading.
  110. }, {
  111. key: '_filterRelated',
  112. value: function _filterRelated(relatedModel, options) {
  113. // By this point, all withRelated should be turned into a hash, so it should
  114. // be fairly simple to process by splitting on the dots.
  115. return _lodash2.default.reduce(options.withRelated, function (memo, val) {
  116. for (var key in val) {
  117. var seg = key.split('.')[0];
  118. if (_lodash2.default.isFunction(relatedModel[seg])) memo.push(val);
  119. }
  120. return memo;
  121. }, []);
  122. }
  123. }]);
  124. return EagerRelation;
  125. })(_eager2.default);
  126. exports.default = EagerRelation;