-
Notifications
You must be signed in to change notification settings - Fork 0
/
application.repository.ts
118 lines (106 loc) · 5.08 KB
/
application.repository.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
import { HttpException, HttpStatus } from '@nestjs/common';
import { PaginatedDto } from 'src/paginated.dto';
import { createQueryBuilder, EntityRepository, Repository } from 'typeorm';
import { Application } from './application.entity';
import { ApplicationQuery } from './applicationquery.validator';
@EntityRepository(Application)
export class ApplicationRepository extends Repository<Application> {
constructor(
) {
super();
}
/**
* Performs a SQL query applying the filters according to the @param
* @param appSearchQuery
*/
async search(appSearchQuery: ApplicationQuery): Promise<PaginatedDto<ApplicationQuery,Application>> {
console.log('application.repository.search query=', appSearchQuery)
const escapeQuote = (str : string): string => {
if (typeof str === 'string')
return str.replace(/'/g, "''");
else
return str;
};
const transformValueToCommaList = (arr: string[] | string): string => {
arr = Array.isArray(arr) ? arr : [arr]
return arr.map(value => `'${escapeQuote(value)}'`).join(',');
}
const transformValueToLikeList = (fieldName: string, value: string[] | string): string => {
const values = Array.isArray(value) ? value : [value];
let str = '';
let sep = '';
values.forEach((value: string, index: number) => {
str += sep;
str += `${fieldName} ILIKE '%${escapeQuote(value)}%'`;
sep = ' OR ';
});
return "( "+str+" )";
}
/** NOTE: The name of "whereFunctions" need to be the same name of filter/properties of EventSearchQuery */
const whereFunctions = {
name(str: string[] | string): string {
return transformValueToLikeList('name', str);
},
email(str: string[] | string): string {
return transformValueToLikeList('email', str);
},
clinicalSiteId(str: string[] | string): string {
return `clinicalsite.id IN (${transformValueToCommaList(str)})`;
},
clinicalTrialId(str: string[] | string): string {
return `clinicaltrial.id IN (${transformValueToCommaList(str)})`;
},
sponsorId(str: string[] | string): string {
return `sponsor.id IN (${transformValueToCommaList(str)})`;
}
}
const sortProperties = {
// prop names must match ClinicalTrialQuerySortProperty
"NAME": "application.name",
"EMAIL": "application.email",
"SPONSOR": "sponsor.name",
"CLINICAL_SITE": "clinicalsite.name",
"CLINICAL_TRIAL": "clinicaltrial.name",
"CREATED_ON": "application.createdOn",
};
let queryBuilder = await createQueryBuilder(Application, 'application');
queryBuilder
.innerJoinAndSelect('application.matchRequest', 'matchrequest')
.innerJoinAndSelect('application.clinicalSite', 'clinicalsite')
.innerJoinAndSelect('application.clinicalTrial', 'clinicaltrial')
.innerJoinAndSelect('clinicaltrial.sponsor', 'sponsor')
;
for (let [filterName, filterValue] of Object.entries(appSearchQuery)) {
const whereFilter = whereFunctions[filterName]
if (!!whereFilter) {
const whereSql = whereFilter(filterValue);
queryBuilder.andWhere(whereSql);
}
}
const orderByProps = Array.isArray(appSearchQuery.sortProperty) ? appSearchQuery.sortProperty : [appSearchQuery.sortProperty];
const orderByDirs = Array.isArray(appSearchQuery.sortDirection) ? appSearchQuery.sortDirection : [appSearchQuery.sortDirection];
if (orderByProps.length != orderByDirs.length) {
throw new HttpException('sortProperty and sortDirection must have the sane number of values', HttpStatus.INTERNAL_SERVER_ERROR);
}
let i: number = 0;
for(i = 0; i<orderByProps.length; i++) {
const orderByProp = orderByProps[i];
const sortProp = sortProperties[orderByProp];
if (!sortProp) {
throw new HttpException('sortProperty value unsupported. See possible values.', HttpStatus.INTERNAL_SERVER_ERROR);
}
const orderByDir = orderByDirs[i];
queryBuilder.addOrderBy(sortProp, orderByDir);
}
queryBuilder.addOrderBy("application.id", "DESC"); // one last sort property to force deterministic output
console.log(queryBuilder.getSql());
const count = await queryBuilder.getCount()
queryBuilder.take(appSearchQuery.limit)
queryBuilder.skip(appSearchQuery.page * appSearchQuery.limit)
const rawAndEntities = await queryBuilder.getRawAndEntities();
console.log("Raw");
console.log(rawAndEntities);
const appCollection = rawAndEntities.entities;
return {count: count, query: appSearchQuery, results: appCollection };
}
}