Merge pull request #2420 from scott-ray-wilson/identity-pagination-fix

Fix: Apply Project Identity Pagination Prior to Left Join of Roles
This commit is contained in:
Maidul Islam
2024-09-12 20:23:03 -04:00
committed by GitHub

View File

@@ -1,10 +1,11 @@
import { Knex } from "knex";
import { TDbClient } from "@app/db";
import { TableName } from "@app/db/schemas";
import { TableName, TIdentities } from "@app/db/schemas";
import { DatabaseError } from "@app/lib/errors";
import { ormify, sqlNestRelationships } from "@app/lib/knex";
import { TListProjectIdentityDTO } from "@app/services/identity-project/identity-project-types";
import { ormify, selectAllTableCols, sqlNestRelationships } from "@app/lib/knex";
import { OrderByDirection } from "@app/lib/types";
import { ProjectIdentityOrderBy, TListProjectIdentityDTO } from "@app/services/identity-project/identity-project-types";
export type TIdentityProjectDALFactory = ReturnType<typeof identityProjectDALFactory>;
@@ -117,18 +118,40 @@ export const identityProjectDALFactory = (db: TDbClient) => {
tx?: Knex
) => {
try {
// TODO: scott - optimize, there's redundancy here with project membership and the below query
const fetchIdentitySubquery = (tx || db.replicaNode())(TableName.Identity)
.where((qb) => {
if (filter.search) {
void qb.whereILike(`${TableName.Identity}.name`, `%${filter.search}%`);
}
})
.join(
TableName.IdentityProjectMembership,
`${TableName.IdentityProjectMembership}.identityId`,
`${TableName.Identity}.id`
)
.where(`${TableName.IdentityProjectMembership}.projectId`, projectId)
.orderBy(
`${TableName.Identity}.${filter.orderBy ?? ProjectIdentityOrderBy.Name}`,
filter.orderDirection ?? OrderByDirection.ASC
)
.select(selectAllTableCols(TableName.Identity))
.as(TableName.Identity); // required for subqueries
if (filter.limit) {
void fetchIdentitySubquery.offset(filter.offset ?? 0).limit(filter.limit);
}
const query = (tx || db.replicaNode())(TableName.IdentityProjectMembership)
.where(`${TableName.IdentityProjectMembership}.projectId`, projectId)
.join(TableName.Project, `${TableName.IdentityProjectMembership}.projectId`, `${TableName.Project}.id`)
.join(TableName.Identity, `${TableName.IdentityProjectMembership}.identityId`, `${TableName.Identity}.id`)
.join<TIdentities, TIdentities>(fetchIdentitySubquery, (bd) => {
bd.on(`${TableName.IdentityProjectMembership}.identityId`, `${TableName.Identity}.id`);
})
.where((qb) => {
if (filter.identityId) {
void qb.where("identityId", filter.identityId);
}
if (filter.search) {
void qb.whereILike(`${TableName.Identity}.name`, `%${filter.search}%`);
}
})
.join(
TableName.IdentityProjectMembershipRole,
@@ -166,10 +189,7 @@ export const identityProjectDALFactory = (db: TDbClient) => {
db.ref("name").as("projectName").withSchema(TableName.Project)
);
if (filter.limit) {
void query.offset(filter.offset ?? 0).limit(filter.limit);
}
// TODO: scott - joins seem to reorder identities so need to order again, for the sake of urgency will optimize at a later point
if (filter.orderBy) {
switch (filter.orderBy) {
case "name":