import { Knex } from "knex"; import { db } from "@db/db"; export interface RequestQuery { length: string; start: string; order: { column: string; dir: string }[]; columns: { [key: string]: { data: string; searchable: string } }; search: { value: string }; filters: { [key: string]: any }; } export interface ResponseQuery { query: Knex.QueryBuilder; recordsTotal: number | string; recordsFiltered: number | string; } type FilterConfig = { [key: string]: (value: any) => Knex.QueryBuilder; }; export const buildDatatableQuery = async (request: { query: RequestQuery }, query: Knex.QueryBuilder, tableName: string): Promise => { const size: number = parseInt(request.query.length) || 10; const start: number = parseInt(request.query.start); const order: string = ( request.query.order && request.query.columns [request.query.order[0].column].data ) || 'id' const direction: string = (request.query.order && request.query.order[0].dir) || "asc"; const search: string = request.query.search.value; const recordsTotalResult = await query.clone().count("* as count").first(); const recordsTotal = recordsTotalResult ? recordsTotalResult.count : 0; const filterConfig: FilterConfig = { active: (value: string) => query.where('active', '=', value), }; if (request.query.filters) { Object.keys(request.query.filters).forEach((filterName: any) => { const filterValue = request.query.filters[filterName]; if (filterConfig[filterName] && filterValue) { query = filterConfig[filterName](filterValue); } }); } if (search) { console.log("applying search: " + search) console.log("columns: " + JSON.stringify(request.query.columns, null, 4)); query = query.where(builder => { Object.values(request.query.columns) .filter(column => column.searchable === "true") .forEach((col, index) => index === 0 ? builder.where(`${tableName}.${col.data}`, "like", `%${search}%`) : builder.orWhere(`${tableName}.${col.data}`, "like", `%${search}%`) ); }); } const recordsFilteredResult = await query.clone().count("* as count").first(); const recordsFiltered = recordsFilteredResult ? recordsFilteredResult.count : 0; query = query.orderBy(`${tableName}.${order}`, direction).limit(size).offset(start); return { query, recordsTotal, recordsFiltered }; }