diff --git a/backend/src/services/identity-project/identity-project-dal.ts b/backend/src/services/identity-project/identity-project-dal.ts index 63955fc73..3e7ca7946 100644 --- a/backend/src/services/identity-project/identity-project-dal.ts +++ b/backend/src/services/identity-project/identity-project-dal.ts @@ -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; @@ -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(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":