-
Notifications
You must be signed in to change notification settings - Fork 45
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
fix: database view performance (#1091)
* fix: simplification of user form access view (#1087) * fix: database view performance (#1090) * fix: simplification of user form access view * fix: remove the sorting in user_form_access_vw --------- Co-authored-by: Walter Moar <[email protected]>
- Loading branch information
1 parent
91943e1
commit a9e6b7f
Showing
1 changed file
with
176 additions
and
0 deletions.
There are no files selected for viewing
176 changes: 176 additions & 0 deletions
176
app/src/db/migrations/20231017192656_037-user-form-permissions.js
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,176 @@ | ||
// Having performance problems and these views seem to be a cause of it. | ||
// 1. Remove the join of "role" in user_form_permissions_vw. | ||
// 2. Remove the join of "role" in user_form_roles_vw. | ||
// 3. Simplify the EXISTS SELECT in user_form_permissions_vw. | ||
// 4. Simplify the EXISTS SELECT in user_form_roles_vw. | ||
// 5. Remove the sorting in the user_form_access_vw. | ||
|
||
/** | ||
* @param { import("knex").Knex } knex | ||
* @returns { Promise<void> } | ||
*/ | ||
exports.up = function (knex) { | ||
return Promise.resolve() | ||
.then(() => knex.schema.dropViewIfExists('user_form_access_vw')) | ||
.then(() => knex.schema.dropViewIfExists('user_form_permissions_vw')) | ||
.then(() => knex.schema.dropViewIfExists('user_form_roles_vw')) | ||
.then(() => | ||
knex.schema.raw(`CREATE OR REPLACE VIEW public.user_form_roles_vw | ||
AS SELECT fru."userId", | ||
fru."formId", | ||
array_agg(DISTINCT fru.role) AS roles | ||
FROM form_role_user fru | ||
GROUP BY fru."userId", fru."formId" | ||
UNION | ||
SELECT u2.id AS "userId", | ||
f2.id AS "formId", | ||
'{}'::character varying[] AS roles | ||
FROM form_vw f2, | ||
"user" u2 | ||
WHERE NOT EXISTS ( | ||
SELECT 1 FROM form_role_user fru2 | ||
WHERE fru2."formId" = f2.id AND fru2."userId" = u2.id);`) | ||
) | ||
.then(() => | ||
knex.schema.raw(`CREATE OR REPLACE VIEW public.user_form_permissions_vw | ||
AS SELECT fru."userId", | ||
fru."formId", | ||
array_agg(DISTINCT p.code) AS permissions | ||
FROM form_role_user fru | ||
JOIN role_permission rp ON fru.role::text = rp.role::text | ||
JOIN permission p ON rp.permission::text = p.code::text | ||
GROUP BY fru."userId", fru."formId" | ||
UNION | ||
SELECT u2.id AS "userId", | ||
f2.id AS "formId", | ||
'{submission_create,form_read}'::character varying[] AS permissions | ||
FROM form_vw f2, | ||
"user" u2 | ||
WHERE NOT EXISTS ( | ||
SELECT 1 FROM form_role_user fru2 | ||
WHERE fru2."formId" = f2.id AND fru2."userId" = u2.id);`) | ||
) | ||
.then(() => | ||
knex.schema.raw(`CREATE OR REPLACE VIEW public.user_form_access_vw | ||
AS SELECT r."userId", | ||
u."idpUserId", | ||
u.username, | ||
u."fullName", | ||
u."firstName", | ||
u."lastName", | ||
u.email, | ||
r."formId", | ||
f.name AS "formName", | ||
f.labels, | ||
u."idpCode" AS "user_idpCode", | ||
f."identityProviders", | ||
f."identityProviders" AS form_login_required, | ||
f.idps, | ||
f.active, | ||
f."formVersionId", | ||
f.version, | ||
r.roles, | ||
p.permissions, | ||
f.published, | ||
f."versionUpdatedAt", | ||
f.description AS "formDescription" | ||
FROM "user" u | ||
JOIN user_form_roles_vw r ON u.id = r."userId" | ||
JOIN user_form_permissions_vw p ON r."userId" = p."userId" AND r."formId" = p."formId" | ||
JOIN form_vw f ON f.id = p."formId";`) | ||
); | ||
}; | ||
|
||
/** | ||
* @param { import("knex").Knex } knex | ||
* @returns { Promise<void> } | ||
*/ | ||
exports.down = function (knex) { | ||
return Promise.resolve() | ||
.then(() => knex.schema.dropViewIfExists('user_form_access_vw')) | ||
.then(() => knex.schema.dropViewIfExists('user_form_permissions_vw')) | ||
.then(() => knex.schema.dropViewIfExists('user_form_roles_vw')) | ||
.then(() => | ||
knex.schema.raw(`CREATE OR REPLACE VIEW public.user_form_roles_vw | ||
AS SELECT fru."userId", | ||
fru."formId", | ||
array_agg(DISTINCT r.code) AS roles | ||
FROM form_role_user fru | ||
JOIN role r ON fru.role::text = r.code::text | ||
GROUP BY fru."userId", fru."formId" | ||
UNION | ||
SELECT u2.id AS "userId", | ||
f2.id AS "formId", | ||
'{}'::character varying[] AS roles | ||
FROM form_vw f2, | ||
"user" u2 | ||
WHERE NOT (EXISTS ( SELECT fru2.id, | ||
fru2.role, | ||
fru2."formId", | ||
fru2."userId", | ||
fru2."createdBy", | ||
fru2."createdAt", | ||
fru2."updatedBy", | ||
fru2."updatedAt" | ||
FROM form_role_user fru2 | ||
WHERE fru2."formId" = f2.id AND fru2."userId" = u2.id));`) | ||
) | ||
.then(() => | ||
knex.schema.raw(` | ||
CREATE OR REPLACE VIEW public.user_form_permissions_vw | ||
AS SELECT fru."userId", | ||
fru."formId", | ||
array_agg(DISTINCT p.code) AS permissions | ||
FROM form_role_user fru | ||
JOIN role r ON fru.role::text = r.code::text | ||
JOIN role_permission rp ON r.code::text = rp.role::text | ||
JOIN permission p ON rp.permission::text = p.code::text | ||
GROUP BY fru."userId", fru."formId" | ||
UNION | ||
SELECT u2.id AS "userId", | ||
f2.id AS "formId", | ||
'{submission_create,form_read}'::character varying[] AS permissions | ||
FROM form_vw f2, | ||
"user" u2 | ||
WHERE NOT (EXISTS ( SELECT fru2.id, | ||
fru2.role, | ||
fru2."formId", | ||
fru2."userId", | ||
fru2."createdBy", | ||
fru2."createdAt", | ||
fru2."updatedBy", | ||
fru2."updatedAt" | ||
FROM form_role_user fru2 | ||
WHERE fru2."formId" = f2.id AND fru2."userId" = u2.id));`) | ||
) | ||
.then(() => | ||
knex.schema.raw(`CREATE OR REPLACE VIEW public.user_form_access_vw | ||
AS SELECT r."userId", | ||
u."idpUserId", | ||
u.username, | ||
u."fullName", | ||
u."firstName", | ||
u."lastName", | ||
u.email, | ||
r."formId", | ||
f.name AS "formName", | ||
f.labels, | ||
u."idpCode" AS "user_idpCode", | ||
f."identityProviders", | ||
f."identityProviders" AS form_login_required, | ||
f.idps, | ||
f.active, | ||
f."formVersionId", | ||
f.version, | ||
r.roles, | ||
p.permissions, | ||
f.published, | ||
f."versionUpdatedAt", | ||
f.description AS "formDescription" | ||
FROM "user" u | ||
JOIN user_form_roles_vw r ON u.id = r."userId" | ||
JOIN user_form_permissions_vw p ON r."userId" = p."userId" AND r."formId" = p."formId" | ||
JOIN form_vw f ON f.id = p."formId" | ||
ORDER BY (lower(u."lastName"::text)), (lower(u."firstName"::text)), (lower(f.name::text));`) | ||
); | ||
}; |