|
@@ -35,11 +35,24 @@ export default abstract class GetDataJob extends DataModuleJob {
|
|
.items(
|
|
.items(
|
|
Joi.object({
|
|
Joi.object({
|
|
filter: Joi.object({
|
|
filter: Joi.object({
|
|
- property: Joi.string().required()
|
|
|
|
|
|
+ name: Joi.string().optional(), // Remove eventually
|
|
|
|
+ displayName: Joi.string().optional(), // Remove eventually
|
|
|
|
+ property: Joi.string().required(),
|
|
|
|
+ filterTypes: Joi.array()
|
|
|
|
+ .items(
|
|
|
|
+ Joi.string()
|
|
|
|
+ .valid(...Object.values(FilterType))
|
|
|
|
+ .required()
|
|
|
|
+ )
|
|
|
|
+ .optional(), // Remove eventually
|
|
|
|
+ defaultFilterType: Joi.string()
|
|
|
|
+ .valid(...Object.values(FilterType))
|
|
|
|
+ .required() // Remove eventually
|
|
}).required(),
|
|
}).required(),
|
|
filterType: Joi.string()
|
|
filterType: Joi.string()
|
|
.valid(...Object.values(FilterType))
|
|
.valid(...Object.values(FilterType))
|
|
- .required()
|
|
|
|
|
|
+ .required(),
|
|
|
|
+ data: Joi.string().required()
|
|
})
|
|
})
|
|
)
|
|
)
|
|
.required(),
|
|
.required(),
|
|
@@ -60,7 +73,10 @@ export default abstract class GetDataJob extends DataModuleJob {
|
|
|
|
|
|
protected _specialQueries?: Record<
|
|
protected _specialQueries?: Record<
|
|
string,
|
|
string,
|
|
- (query: WhereOptions) => WhereOptions
|
|
|
|
|
|
+ (query: WhereOptions) => {
|
|
|
|
+ query: WhereOptions;
|
|
|
|
+ includeProperties: string[];
|
|
|
|
+ }
|
|
>;
|
|
>;
|
|
|
|
|
|
protected async _execute() {
|
|
protected async _execute() {
|
|
@@ -111,6 +127,9 @@ export default abstract class GetDataJob extends DataModuleJob {
|
|
}
|
|
}
|
|
);
|
|
);
|
|
|
|
|
|
|
|
+ // Properties that we need to include (join) with Sequelize, e.g. createdByModel
|
|
|
|
+ const includePropertiesSet = new Set();
|
|
|
|
+
|
|
// Adds where stage to query, which is responsible for filtering
|
|
// Adds where stage to query, which is responsible for filtering
|
|
const filterQueries = queries.flatMap(query => {
|
|
const filterQueries = queries.flatMap(query => {
|
|
const { data, filter, filterType } = query;
|
|
const { data, filter, filterType } = query;
|
|
@@ -174,7 +193,15 @@ export default abstract class GetDataJob extends DataModuleJob {
|
|
}
|
|
}
|
|
|
|
|
|
if (typeof this._specialQueries?.[filter.property] === "function") {
|
|
if (typeof this._specialQueries?.[filter.property] === "function") {
|
|
- return this._specialQueries[filter.property](newQuery);
|
|
|
|
|
|
+ const { query, includeProperties } =
|
|
|
|
+ this._specialQueries[filter.property](newQuery);
|
|
|
|
+
|
|
|
|
+ // Keep track of what property/properties Sequelize will have to include (join) for the special query to work
|
|
|
|
+ includeProperties.forEach(includeProperty => {
|
|
|
|
+ includePropertiesSet.add(includeProperty);
|
|
|
|
+ });
|
|
|
|
+
|
|
|
|
+ return query;
|
|
}
|
|
}
|
|
|
|
|
|
return newQuery;
|
|
return newQuery;
|
|
@@ -201,6 +228,19 @@ export default abstract class GetDataJob extends DataModuleJob {
|
|
findQuery.offset = pageSize * (page - 1);
|
|
findQuery.offset = pageSize * (page - 1);
|
|
findQuery.limit = pageSize;
|
|
findQuery.limit = pageSize;
|
|
|
|
|
|
|
|
+ // We need to tell Sequalize that some associated tables are used and must be included (joined)
|
|
|
|
+ const includeProperties = Array.from(includePropertiesSet);
|
|
|
|
+ findQuery.include = includeProperties.map(includeProperty => {
|
|
|
|
+ const association = this.getModel().associations[includeProperty];
|
|
|
|
+ const targetModel = association.target;
|
|
|
|
+
|
|
|
|
+ return {
|
|
|
|
+ model: targetModel, // E.g. User
|
|
|
|
+ as: includeProperty, // e.g. "createdByModel"
|
|
|
|
+ attributes: [] // We do not want to return any data from anything we include
|
|
|
|
+ };
|
|
|
|
+ });
|
|
|
|
+
|
|
// Executes the query
|
|
// Executes the query
|
|
const { rows, count } = await this.getModel().findAndCountAll(
|
|
const { rows, count } = await this.getModel().findAndCountAll(
|
|
findQuery
|
|
findQuery
|
|
@@ -208,6 +248,8 @@ export default abstract class GetDataJob extends DataModuleJob {
|
|
|
|
|
|
const data = rows.map(model => model.toJSON()); // TODO: Review generally
|
|
const data = rows.map(model => model.toJSON()); // TODO: Review generally
|
|
|
|
|
|
|
|
+ // TODO make absolutely sure createdByModel and similar here have been removed or aren't included, if they've been included at all
|
|
|
|
+
|
|
return { data, count };
|
|
return { data, count };
|
|
}
|
|
}
|
|
}
|
|
}
|