Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Speed up /stock/lots/depot query #7273

Merged
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
54 changes: 35 additions & 19 deletions server/controllers/stock/core.js
Original file line number Diff line number Diff line change
Expand Up @@ -60,14 +60,13 @@ module.exports = {
};

/**
* @function getLotFilters
* getLotFilters
*
* @description
* Groups all filtering functionality used in the different getLots* functions into
* a single function. The filterparser is returned so that any additional modifications
* can be made in the function before execution.
*
* @param {Object} parameters - an object of filter params.
* @param {object} parameters - an object of filter params.
*/

function getLotFilters(parameters) {
Expand Down Expand Up @@ -137,22 +136,6 @@ function getLotFilters(parameters) {
)`,
);

// depot permission check
filters.custom(
'check_user_id',
`d.uuid IN (
SELECT DISTINCT d.depot_uuid
FROM (
SELECT dp.depot_uuid, dp.user_id
FROM depot_permission AS dp
UNION
SELECT ds.depot_uuid, ds.user_id
FROM depot_supervision AS ds
) AS d
WHERE d.user_id = ?
)`,
);

// lot tags
filters.custom('tags', 't.uuid IN (?)', [params.tags]);

Expand Down Expand Up @@ -196,6 +179,33 @@ function getLotFilters(parameters) {
return filters;
}

/**
* Use this additional filter to restrict the db lots queries to the depots
* that the user has permission to access
*
* @param {object} filters - the query filters object
* @param {object} params - the same parameters used to create the filters object
*/
async function addDepotPermissionsFilter(filters, params) {
if ('check_user_id' in params && params.check_user_id) {
const userId = params.check_user_id;
const psql = `
SELECT DISTINCT BUID(d.depot_uuid) AS uuid
FROM (
SELECT dp.depot_uuid, dp.user_id
FROM depot_permission AS dp
UNION
SELECT ds.depot_uuid, ds.user_id
FROM depot_supervision AS ds
) AS d
WHERE d.user_id = ?;
`;
const results = await db.exec(psql, [userId]);
const uuids = results.map(item => `'${item.uuid}'`);
filters.custom('check_user_id', `BUID(d.uuid) IN (${uuids})`);
}
}

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍🏽

async function lookupLotByUuid(uid) {
const [lot] = await getLots(null, { uuid : uid });
return lot;
Expand Down Expand Up @@ -233,6 +243,8 @@ function getLots(sqlQuery, parameters, finalClause = '', orderBy = '') {

const filters = getLotFilters(parameters);

addDepotPermissionsFilter(filters, parameters);

// if finalClause is an empty string, filterParser will not group, it will be an empty string
filters.setGroup(finalClause);

Expand Down Expand Up @@ -335,10 +347,13 @@ async function getAssets(params) {

const filters = getLotFilters(params);

addDepotPermissionsFilter(filters, params);

if (['scanned', 'unscanned'].includes(params.scan_status)) {
filters.custom('scan_status',
params.scan_status === 'scanned' ? 'last_scan.uuid IS NOT NULL' : 'last_scan.uuid IS NULL');
}

filters.setGroup(groupByClause);
filters.setHaving(havingClause);
filters.setOrder('ORDER BY i.code, l.label');
Expand Down Expand Up @@ -434,6 +449,7 @@ async function getLotsDepot(depotUuid, params, finalClause) {

const groupByClause = finalClause || ` GROUP BY l.uuid, m.depot_uuid ${emptyLotToken} ORDER BY i.code, l.label `;
const filters = getLotFilters(params);
addDepotPermissionsFilter(filters, params);
filters.setGroup(groupByClause);

let resultFromProcess;
Expand Down