|
1 | 1 | const _ = require('lodash');
|
2 |
| -const P = require('bluebird'); |
3 | 2 | const Interface = require('forest-express');
|
4 | 3 | const SearchBuilder = require('./search-builder');
|
5 | 4 | const utils = require('../utils/schema');
|
6 | 5 | const FiltersParser = require('./filters-parser');
|
7 | 6 |
|
8 |
| -function HasManyGetter(model, association, opts, params) { |
| 7 | +function HasManyGetter(parentModel, childModel, opts, params) { |
9 | 8 | const OBJECTID_REGEXP = /^[0-9a-fA-F]{24}$/;
|
10 |
| - const schema = Interface.Schemas.schemas[utils.getModelName(association)]; |
11 |
| - const searchBuilder = new SearchBuilder(association, opts, params); |
12 |
| - const filtersParser = new FiltersParser(association, params.timezone, opts); |
| 9 | + const schema = Interface.Schemas.schemas[utils.getModelName(childModel)]; |
| 10 | + const searchBuilder = new SearchBuilder(childModel, opts, params); |
| 11 | + const filtersParser = new FiltersParser(childModel, params.timezone, opts); |
13 | 12 |
|
14 | 13 | function hasPagination() {
|
15 | 14 | return params.page && params.page.number;
|
@@ -66,71 +65,65 @@ function HasManyGetter(model, association, opts, params) {
|
66 | 65 | return conditions;
|
67 | 66 | }
|
68 | 67 |
|
69 |
| - function getRecordsAndRecordIds() { |
70 |
| - return new P((resolve, reject) => { |
71 |
| - let id = params.recordId; |
72 |
| - if (OBJECTID_REGEXP.test(params.recordId)) { |
73 |
| - id = opts.Mongoose.Types.ObjectId(id); |
74 |
| - } |
| 68 | + async function getRecordsAndRecordIds() { |
| 69 | + let id = params.recordId; |
| 70 | + if (OBJECTID_REGEXP.test(params.recordId)) { |
| 71 | + id = opts.Mongoose.Types.ObjectId(id); |
| 72 | + } |
75 | 73 |
|
76 |
| - return model |
77 |
| - .aggregate() |
78 |
| - .match({ _id: id }) |
79 |
| - .unwind(params.associationName) |
80 |
| - .project(getProjection()) |
81 |
| - .exec((error, records) => { |
82 |
| - if (error) { return reject(error); } |
83 |
| - return resolve(_.map(records, (record) => record[params.associationName])); |
84 |
| - }); |
85 |
| - }) |
86 |
| - .then(async (recordIds) => { |
87 |
| - const conditions = await buildConditions(recordIds); |
88 |
| - const query = association.find(conditions); |
89 |
| - handlePopulate(query); |
90 |
| - |
91 |
| - return query.then((records) => [records, recordIds]); |
92 |
| - }); |
| 74 | + const parentRecords = await parentModel |
| 75 | + .aggregate() |
| 76 | + .match({ _id: id }) |
| 77 | + .unwind(params.associationName) |
| 78 | + .project(getProjection()) |
| 79 | + .exec(); |
| 80 | + |
| 81 | + const childRecordIds = _.map(parentRecords, (record) => record[params.associationName]); |
| 82 | + const conditions = await buildConditions(childRecordIds); |
| 83 | + const query = childModel.find(conditions); |
| 84 | + handlePopulate(query); |
| 85 | + |
| 86 | + const childRecords = await query; |
| 87 | + return [childRecords, childRecordIds]; |
93 | 88 | }
|
94 | 89 |
|
95 |
| - this.perform = () => |
96 |
| - getRecordsAndRecordIds() |
97 |
| - .then((recordsAndRecordIds) => { |
98 |
| - const records = recordsAndRecordIds[0]; |
99 |
| - let fieldSort = params.sort; |
100 |
| - let descending = false; |
101 |
| - |
102 |
| - if (params.sort && (params.sort[0] === '-')) { |
103 |
| - fieldSort = params.sort.substring(1); |
104 |
| - descending = true; |
105 |
| - } |
106 |
| - |
107 |
| - let recordsSorted; |
108 |
| - if (fieldSort) { |
109 |
| - recordsSorted = _.sortBy(records, (record) => record[fieldSort]); |
110 |
| - } else { |
111 |
| - const recordIds = recordsAndRecordIds[1]; |
112 |
| - // NOTICE: Convert values to strings, so ObjectIds could be easily searched and compared. |
113 |
| - const recordIdStrings = recordIds.map((recordId) => String(recordId)); |
114 |
| - // NOTICE: indexOf could be improved by making a Map from record-ids to their index. |
115 |
| - recordsSorted = _.sortBy(records, record => recordIdStrings.indexOf(String(record._id))); // eslint-disable-line |
116 |
| - } |
117 |
| - return descending ? recordsSorted.reverse() : recordsSorted; |
118 |
| - }) |
119 |
| - .then((records) => { |
120 |
| - let fieldsSearched = null; |
121 |
| - |
122 |
| - if (params.search) { |
123 |
| - fieldsSearched = searchBuilder.getFieldsSearched(); |
124 |
| - } |
125 |
| - |
126 |
| - records = _.slice(records, getSkip(), getSkip() + getLimit()); |
127 |
| - |
128 |
| - return [records, fieldsSearched]; |
129 |
| - }); |
130 |
| - |
131 |
| - this.count = () => |
132 |
| - getRecordsAndRecordIds() |
133 |
| - .then((recordsAndRecordIds) => recordsAndRecordIds[0].length); |
| 90 | + this.perform = async () => { |
| 91 | + const [childRecords, childRecordIds] = await getRecordsAndRecordIds(); |
| 92 | + |
| 93 | + let fieldSort = params.sort; |
| 94 | + let descending = false; |
| 95 | + |
| 96 | + if (params.sort && (params.sort[0] === '-')) { |
| 97 | + fieldSort = params.sort.substring(1); |
| 98 | + descending = true; |
| 99 | + } |
| 100 | + |
| 101 | + let recordsSorted; |
| 102 | + if (fieldSort) { |
| 103 | + recordsSorted = _.sortBy(childRecords, (record) => record[fieldSort]); |
| 104 | + } else { |
| 105 | + // NOTICE: Convert values to strings, so ObjectIds could be easily searched and compared. |
| 106 | + const recordIdStrings = childRecordIds.map((recordId) => String(recordId)); |
| 107 | + // NOTICE: indexOf could be improved by making a Map from record-ids to their index. |
| 108 | + recordsSorted = _.sortBy(childRecords, record => recordIdStrings.indexOf(String(record._id))); // eslint-disable-line |
| 109 | + } |
| 110 | + |
| 111 | + let sortedChildRecords = descending ? recordsSorted.reverse() : recordsSorted; |
| 112 | + let fieldsSearched = null; |
| 113 | + |
| 114 | + if (params.search) { |
| 115 | + fieldsSearched = searchBuilder.getFieldsSearched(); |
| 116 | + } |
| 117 | + |
| 118 | + sortedChildRecords = _.slice(sortedChildRecords, getSkip(), getSkip() + getLimit()); |
| 119 | + |
| 120 | + return [sortedChildRecords, fieldsSearched]; |
| 121 | + }; |
| 122 | + |
| 123 | + this.count = async () => { |
| 124 | + const recordsAndRecordIds = await getRecordsAndRecordIds(); |
| 125 | + return recordsAndRecordIds[0].length; |
| 126 | + }; |
134 | 127 | }
|
135 | 128 |
|
136 | 129 | module.exports = HasManyGetter;
|
0 commit comments