Paginator & SQL Querries where clauses & city search
This commit is contained in:
@@ -1,14 +1,15 @@
|
||||
import { Inject, Injectable } from '@nestjs/common';
|
||||
import { and, eq, ilike, or, sql } from 'drizzle-orm';
|
||||
import { and, count, eq, ilike, inArray, or, SQL, sql } from 'drizzle-orm';
|
||||
import { NodePgDatabase } from 'drizzle-orm/node-postgres/driver.js';
|
||||
import { WINSTON_MODULE_PROVIDER } from 'nest-winston';
|
||||
import { Logger } from 'winston';
|
||||
import * as schema from '../drizzle/schema.js';
|
||||
import { PG_CONNECTION } from '../drizzle/schema.js';
|
||||
import { customerSubTypeEnum, PG_CONNECTION } from '../drizzle/schema.js';
|
||||
import { FileService } from '../file/file.service.js';
|
||||
import { User } from '../models/db.model.js';
|
||||
import { JwtUser, UserListingCriteria, emailToDirName } from '../models/main.model.js';
|
||||
import { emailToDirName, JwtUser, UserListingCriteria } from '../models/main.model.js';
|
||||
|
||||
type CustomerSubType = (typeof customerSubTypeEnum.enumValues)[number];
|
||||
@Injectable()
|
||||
export class UserService {
|
||||
constructor(
|
||||
@@ -16,17 +17,85 @@ export class UserService {
|
||||
@Inject(PG_CONNECTION) private conn: NodePgDatabase<typeof schema>,
|
||||
private fileService: FileService,
|
||||
) {}
|
||||
private getConditions(criteria: UserListingCriteria): any[] {
|
||||
const conditions = [];
|
||||
if (criteria.states?.length > 0) {
|
||||
criteria.states.forEach(state => {
|
||||
conditions.push(sql`${schema.users.areasServed} @> ${JSON.stringify([{ state: state }])}`);
|
||||
});
|
||||
// private getConditions(criteria: UserListingCriteria): any[] {
|
||||
// const conditions = [];
|
||||
// if (criteria.states?.length > 0) {
|
||||
// criteria.states.forEach(state => {
|
||||
// conditions.push(sql`${schema.users.areasServed} @> ${JSON.stringify([{ state: state }])}`);
|
||||
// });
|
||||
// }
|
||||
// if (criteria.firstname || criteria.lastname) {
|
||||
// conditions.push(or(ilike(schema.users.firstname, `%${criteria.lastname}%`), ilike(schema.users.lastname, `%${criteria.lastname}%`)));
|
||||
// }
|
||||
// return conditions;
|
||||
// }
|
||||
private getWhereConditions(criteria: UserListingCriteria): SQL[] {
|
||||
const whereConditions: SQL[] = [];
|
||||
|
||||
if (criteria.city) {
|
||||
whereConditions.push(ilike(schema.users.companyLocation, `%${criteria.city}%`));
|
||||
}
|
||||
if (criteria.firstname || criteria.lastname) {
|
||||
conditions.push(or(ilike(schema.users.firstname, `%${criteria.lastname}%`), ilike(schema.users.lastname, `%${criteria.lastname}%`)));
|
||||
|
||||
if (criteria.types && criteria.types.length > 0) {
|
||||
// whereConditions.push(inArray(schema.users.customerSubType, criteria.types));
|
||||
whereConditions.push(inArray(schema.users.customerSubType, criteria.types as CustomerSubType[]));
|
||||
}
|
||||
return conditions;
|
||||
|
||||
if (criteria.firstname) {
|
||||
whereConditions.push(ilike(schema.users.firstname, `%${criteria.firstname}%`));
|
||||
}
|
||||
|
||||
if (criteria.lastname) {
|
||||
whereConditions.push(ilike(schema.users.lastname, `%${criteria.lastname}%`));
|
||||
}
|
||||
|
||||
if (criteria.companyName) {
|
||||
whereConditions.push(ilike(schema.users.companyName, `%${criteria.companyName}%`));
|
||||
}
|
||||
|
||||
if (criteria.counties && criteria.counties.length > 0) {
|
||||
whereConditions.push(or(...criteria.counties.map(county => sql`EXISTS (SELECT 1 FROM jsonb_array_elements(${schema.users.areasServed}) AS area WHERE area->>'county' ILIKE ${`%${county}%`})`)));
|
||||
}
|
||||
|
||||
if (criteria.states && criteria.states.length > 0) {
|
||||
whereConditions.push(or(...criteria.states.map(state => sql`EXISTS (SELECT 1 FROM jsonb_array_elements(${schema.users.areasServed}) AS area WHERE area->>'state' = ${state})`)));
|
||||
}
|
||||
|
||||
return whereConditions;
|
||||
}
|
||||
async searchUserListings(criteria: UserListingCriteria) {
|
||||
const start = criteria.start ? criteria.start : 0;
|
||||
const length = criteria.length ? criteria.length : 12;
|
||||
const query = this.conn.select().from(schema.users);
|
||||
const whereConditions = this.getWhereConditions(criteria);
|
||||
|
||||
if (whereConditions.length > 0) {
|
||||
const whereClause = and(...whereConditions);
|
||||
query.where(whereClause);
|
||||
}
|
||||
|
||||
// Paginierung
|
||||
query.limit(length).offset(start);
|
||||
|
||||
const results = await query;
|
||||
const totalCount = await this.getUserListingsCount(criteria);
|
||||
|
||||
return {
|
||||
results,
|
||||
totalCount,
|
||||
};
|
||||
}
|
||||
async getUserListingsCount(criteria: UserListingCriteria): Promise<number> {
|
||||
const countQuery = this.conn.select({ value: count() }).from(schema.users);
|
||||
const whereConditions = this.getWhereConditions(criteria);
|
||||
|
||||
if (whereConditions.length > 0) {
|
||||
const whereClause = and(...whereConditions);
|
||||
countQuery.where(whereClause);
|
||||
}
|
||||
|
||||
const [{ value: totalCount }] = await countQuery;
|
||||
return totalCount;
|
||||
}
|
||||
async getUserByMail(email: string, jwtuser?: JwtUser) {
|
||||
const users = (await this.conn
|
||||
@@ -68,25 +137,25 @@ export class UserService {
|
||||
return newUser as User;
|
||||
}
|
||||
}
|
||||
async findUser(criteria: UserListingCriteria) {
|
||||
const start = criteria.start ? criteria.start : 0;
|
||||
const length = criteria.length ? criteria.length : 12;
|
||||
const conditions = this.getConditions(criteria);
|
||||
const [data, total] = await Promise.all([
|
||||
this.conn
|
||||
.select()
|
||||
.from(schema.users)
|
||||
.where(and(...conditions))
|
||||
.offset(start)
|
||||
.limit(length),
|
||||
this.conn
|
||||
.select({ count: sql`count(*)` })
|
||||
.from(schema.users)
|
||||
.where(and(...conditions))
|
||||
.then(result => Number(result[0].count)),
|
||||
]);
|
||||
return { total, data };
|
||||
}
|
||||
// async findUser(criteria: UserListingCriteria) {
|
||||
// const start = criteria.start ? criteria.start : 0;
|
||||
// const length = criteria.length ? criteria.length : 12;
|
||||
// const conditions = this.getConditions(criteria);
|
||||
// const [data, total] = await Promise.all([
|
||||
// this.conn
|
||||
// .select()
|
||||
// .from(schema.users)
|
||||
// .where(and(...conditions))
|
||||
// .offset(start)
|
||||
// .limit(length),
|
||||
// this.conn
|
||||
// .select({ count: sql`count(*)` })
|
||||
// .from(schema.users)
|
||||
// .where(and(...conditions))
|
||||
// .then(result => Number(result[0].count)),
|
||||
// ]);
|
||||
// return { total, data };
|
||||
// }
|
||||
async getStates(): Promise<any[]> {
|
||||
const query = sql`SELECT jsonb_array_elements(${schema.users.areasServed}) ->> 'state' AS state, COUNT(DISTINCT ${schema.users.id}) AS count FROM ${schema.users} GROUP BY state ORDER BY count DESC`;
|
||||
const result = await this.conn.execute(query);
|
||||
|
||||
Reference in New Issue
Block a user