|
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