michaelp7725
michaelp7725
Explore posts from servers
DTDrizzle Team
Created by michaelp7725 on 11/19/2024 in #help
creating a generic selection function
Hey all, I'm trying to extract some shared logic into a function that will generate a query based off an input selectedFields. I can't for the life of me figure out how to get the generic right, and it seems like this should be a fairly common use case:
export function createBaseQuery<TSelection extends SelectedFields>(
selectedFields: TSelection,
filters: SQL[],
globalFilter: string,
) {
const baseQuery = db
.select(selectedFields)
.from(assetTable)
.innerJoin(locationTable, eq(assetTable.locationId, locationTable.id))
.innerJoin(assetStatusTable, eq(assetTable.statusId, assetStatusTable.id))
.innerJoin(modelTable, eq(assetTable.modelId, modelTable.id))
.innerJoin(clientTable, eq(assetTable.clientId, clientTable.id))
.innerJoin(
manufacturerTable,
eq(modelTable.manufacturerId, manufacturerTable.id),
)
.leftJoin(
modelImageTable,
eq(modelTable.defaultImageId, modelImageTable.id),
)
.where(
and(
...filters,
getGlobalFilters(globalFilter),
),
)
.$dynamic();

return baseQuery;
}
export function createBaseQuery<TSelection extends SelectedFields>(
selectedFields: TSelection,
filters: SQL[],
globalFilter: string,
) {
const baseQuery = db
.select(selectedFields)
.from(assetTable)
.innerJoin(locationTable, eq(assetTable.locationId, locationTable.id))
.innerJoin(assetStatusTable, eq(assetTable.statusId, assetStatusTable.id))
.innerJoin(modelTable, eq(assetTable.modelId, modelTable.id))
.innerJoin(clientTable, eq(assetTable.clientId, clientTable.id))
.innerJoin(
manufacturerTable,
eq(modelTable.manufacturerId, manufacturerTable.id),
)
.leftJoin(
modelImageTable,
eq(modelTable.defaultImageId, modelImageTable.id),
)
.where(
and(
...filters,
getGlobalFilters(globalFilter),
),
)
.$dynamic();

return baseQuery;
}
if i remove the generic, the return type is [x: string]: unknown regardless of what I use for selectedFields, if I use the provided type SelectedFields from :
import type { SelectedFields } from "drizzle-orm/pg-core";
import type { SelectedFields } from "drizzle-orm/pg-core";
the output is any. If i use the other SelectedFields type from:
import { type SelectedFields} from "drizzle-orm";
import { type SelectedFields} from "drizzle-orm";
It's a generic that requires two arguments, TColumn and TTable, however I don't see any helper for generating these two from a given table. Has anyone successfully been able to abstract a select query? Thanks for any help you can give, Michael.
2 replies
DTDrizzle Team
Created by michaelp7725 on 6/10/2024 in #help
Optionally chaining joins and typescript issues.
Hey everyone, I'm currently a bit stuck trying to brainstorm how to solve the following problem and I'm sure there's an easy way to do it that I'm completely overlooking. I'm implementing a backend route for a data table where certain columns can be shown or hidden. I want my database query to only include joins of tables when a relevant column is to be shown. I'm using Typescript, Drizzle, PostgreSQL, trpc, react, tanstack table and zod if any of that is relevant. my basic query is as follows: export function getAllAssets( { columns, globalFilter, pageIndex, pageSize, sorting }: GetAllAssetsInput, db: TRPCContext["db"] ) { const selectFields = getSelectFields(columns); let query = db.select(selectFields).from(assets).$dynamic(); if (columns.location_name) { query = withLocation(query); } if (columns.status_name) { query = withStatus(query); } if (columns.client_name) { query = withClient(query); } if (globalFilter !== "") { query = withGlobalFilter(query, globalFilter, columns); } else { query = query.where(isNull(assets.deletedAt)); } if (sorting.length !== 0) { query = withSorting(query, sorting); } else { query = query.orderBy(assets.id); } const finalQuery = withPagination(query, pageIndex, pageSize); return finalQuery; } where each corresponding join is done through a function like this: function withStatus<T extends PgSelectQueryBuilder>(query: T) { return query.leftJoin(assetStatuses, eq(assets.statusId, assetStatuses.id)); } The problem is that typescript is complaining that the type of query is changing between it's initialization and with each re-assignment. I've tried typecasting query but i'm unsure what type to use as drizzle doesn't have much documention on its types. If anyone could point me in the right direction, that would be great! Thanks, Michael
3 replies