@things-factory/shell 7.0.33 → 7.0.43
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist-server/tsconfig.tsbuildinfo +1 -1
- package/dist-server/utils/get-query-builder-from-list-params.d.ts +9 -12
- package/dist-server/utils/get-query-builder-from-list-params.js +147 -125
- package/dist-server/utils/get-query-builder-from-list-params.js.map +1 -1
- package/package.json +2 -2
- package/server/utils/get-query-builder-from-list-params.ts +204 -150
@@ -1,23 +1,19 @@
|
|
1
1
|
import { Brackets, EntityMetadata, Repository, SelectQueryBuilder, WhereExpressionBuilder } from 'typeorm'
|
2
2
|
import { RelationMetadata } from 'typeorm/metadata/RelationMetadata'
|
3
|
-
|
4
|
-
import { Filter, ListParam, InheritedValueType } from '../service/common-types/list-param'
|
3
|
+
import { Filter, Sorting, Pagination, ListParam, InheritedValueType } from '../service/common-types/list-param'
|
5
4
|
import { Domain } from '../service/domain/domain'
|
6
5
|
|
7
6
|
/**
|
8
|
-
*
|
7
|
+
* Creates a TypeORM SelectQueryBuilder based on the provided parameters.
|
9
8
|
*
|
10
|
-
* @param options - An object containing
|
11
|
-
* @param options.repository - TypeORM repository
|
12
|
-
* @param options.params - ListParam object
|
13
|
-
* @param [options.domain] - Optional domain object for applying domain-
|
14
|
-
* @param [options.alias] -
|
15
|
-
* @param [options.searchables] - List of
|
16
|
-
* @param [options.filtersMap] - Mapping of filter names to their corresponding columns or relation columns
|
17
|
-
* @
|
18
|
-
* @param [options.filtersMap.columnName] - Name of the column where the filter is applied.
|
19
|
-
* @param [options.filtersMap.relationColumn] - If the filter is applied to a related column, the name of that relation column (optional).
|
20
|
-
* @returns {SelectQueryBuilder<Type>} - The generated SelectQueryBuilder object.
|
9
|
+
* @param options - An object containing the query building options.
|
10
|
+
* @param options.repository - The TypeORM repository for database operations.
|
11
|
+
* @param options.params - The ListParam object containing filters, sortings, and pagination.
|
12
|
+
* @param [options.domain] - Optional domain object for applying domain-specific filters.
|
13
|
+
* @param [options.alias] - The alias to be used in the SQL queries.
|
14
|
+
* @param [options.searchables] - List of columns that are searchable.
|
15
|
+
* @param [options.filtersMap] - Mapping of filter names to their corresponding columns or relation columns.
|
16
|
+
* @returns {SelectQueryBuilder<Type>} - The constructed SelectQueryBuilder instance.
|
21
17
|
*/
|
22
18
|
export function getQueryBuilderFromListParams<Type>(options: {
|
23
19
|
repository: Repository<Type>
|
@@ -27,23 +23,25 @@ export function getQueryBuilderFromListParams<Type>(options: {
|
|
27
23
|
searchables?: string[]
|
28
24
|
filtersMap?: { [name: string]: { columnName: string; relationColumn?: string } }
|
29
25
|
}): SelectQueryBuilder<Type> {
|
30
|
-
|
31
|
-
|
26
|
+
const { repository, params, domain, alias, searchables, filtersMap = {} } = options
|
27
|
+
const { inherited = InheritedValueType.None } = params || {}
|
32
28
|
|
33
29
|
const selectQueryBuilder = repository.createQueryBuilder(alias)
|
34
30
|
const entityAlias = selectQueryBuilder.alias
|
35
31
|
|
32
|
+
// Apply filters to the query
|
36
33
|
const columnFilters =
|
37
34
|
params.filters?.filter(filter => {
|
38
35
|
if (filter.operator === 'search') {
|
39
36
|
return false
|
40
37
|
}
|
41
38
|
if (filter.operator.toLowerCase().includes('like') && (!searchables || !searchables.includes(filter.name))) {
|
42
|
-
console.warn('"searchables" setting is required for
|
39
|
+
console.warn('"searchables" setting is required for LIKE searches to avoid heavy database load', filter.name)
|
43
40
|
return false
|
44
41
|
}
|
45
42
|
return true
|
46
43
|
}) || []
|
44
|
+
|
47
45
|
const searchFilters =
|
48
46
|
searchables instanceof Array
|
49
47
|
? params.filters?.filter(filter => {
|
@@ -51,23 +49,28 @@ export function getQueryBuilderFromListParams<Type>(options: {
|
|
51
49
|
return false
|
52
50
|
}
|
53
51
|
if (!searchables.includes(filter.name)) {
|
54
|
-
console.warn(
|
52
|
+
console.warn(
|
53
|
+
'"searchables" setting is required for LIKE searches to avoid heavy database load',
|
54
|
+
filter.name
|
55
|
+
)
|
55
56
|
return false
|
56
57
|
}
|
57
58
|
return true
|
58
59
|
}) || []
|
59
60
|
: []
|
61
|
+
|
60
62
|
const pagination = params.pagination
|
61
63
|
const sortings = params.sortings
|
62
|
-
|
63
64
|
const metadata = repository.metadata
|
64
65
|
|
65
|
-
|
66
|
+
// Apply column filters
|
67
|
+
if (columnFilters.length > 0) {
|
66
68
|
columnFilters.forEach(filter => {
|
67
69
|
addCondition(metadata, selectQueryBuilder, selectQueryBuilder, filter, filtersMap, true)
|
68
70
|
})
|
69
71
|
}
|
70
72
|
|
73
|
+
// Apply search filters
|
71
74
|
if (searchFilters.length > 0) {
|
72
75
|
selectQueryBuilder.andWhere(
|
73
76
|
new Brackets(qb => {
|
@@ -78,48 +81,58 @@ export function getQueryBuilderFromListParams<Type>(options: {
|
|
78
81
|
)
|
79
82
|
}
|
80
83
|
|
84
|
+
// Apply domain filters
|
81
85
|
if (domain) {
|
82
|
-
if (!inherited || inherited
|
86
|
+
if (!inherited || inherited === InheritedValueType.None) {
|
83
87
|
selectQueryBuilder.andWhere(`${entityAlias}.domain = :domain`, { domain: domain.id })
|
84
|
-
} else if (inherited
|
85
|
-
selectQueryBuilder.andWhere(`${entityAlias}.domain
|
88
|
+
} else if (inherited === InheritedValueType.Include) {
|
89
|
+
selectQueryBuilder.andWhere(`${entityAlias}.domain IN (:...domains)`, {
|
86
90
|
domains: [domain.id, domain.parentId].filter(Boolean)
|
87
91
|
})
|
88
|
-
} else if (inherited
|
92
|
+
} else if (inherited === InheritedValueType.Only) {
|
89
93
|
selectQueryBuilder.andWhere(`${entityAlias}.domain = :domain`, { domain: domain.parentId || 'Impossible' })
|
90
94
|
} else {
|
91
95
|
selectQueryBuilder.andWhere(`${entityAlias}.domain = :domain`, { domain: 'Impossible' })
|
92
96
|
}
|
93
97
|
}
|
94
98
|
|
95
|
-
|
96
|
-
|
97
|
-
selectQueryBuilder.take(pagination.limit)
|
98
|
-
}
|
99
|
+
// Apply pagination
|
100
|
+
addPagination(selectQueryBuilder, pagination)
|
99
101
|
|
102
|
+
// Apply sorting
|
100
103
|
if (sortings && sortings.length > 0) {
|
101
|
-
|
102
|
-
const sortField = sorting.name.split('.').length > 1 ? sorting.name : `${entityAlias}.${sorting.name}`
|
103
|
-
if (index === 0) {
|
104
|
-
selectQueryBuilder.orderBy(sortField, sorting.desc ? 'DESC' : 'ASC')
|
105
|
-
} else {
|
106
|
-
selectQueryBuilder.addOrderBy(sortField, sorting.desc ? 'DESC' : 'ASC')
|
107
|
-
}
|
108
|
-
})
|
104
|
+
addSorting(selectQueryBuilder, sortings, entityAlias, filtersMap, metadata)
|
109
105
|
}
|
110
106
|
|
111
107
|
return selectQueryBuilder
|
112
108
|
}
|
113
109
|
|
114
110
|
/**
|
115
|
-
*
|
111
|
+
* Adds pagination to the SelectQueryBuilder based on the provided Pagination object.
|
112
|
+
*
|
113
|
+
* @param selectQueryBuilder - The SelectQueryBuilder to which pagination should be applied.
|
114
|
+
* @param pagination - The Pagination object containing page and limit information.
|
115
|
+
*/
|
116
|
+
function addPagination<T>(selectQueryBuilder: SelectQueryBuilder<T>, pagination?: Pagination) {
|
117
|
+
if (pagination) {
|
118
|
+
const { page, limit } = pagination
|
119
|
+
if (page && limit && page > 0 && limit > 0) {
|
120
|
+
selectQueryBuilder.skip(limit * (page - 1)).take(limit)
|
121
|
+
} else if (limit && limit > 0) {
|
122
|
+
selectQueryBuilder.take(limit)
|
123
|
+
}
|
124
|
+
}
|
125
|
+
}
|
126
|
+
|
127
|
+
/**
|
128
|
+
* Adds a filtering condition to the SelectQueryBuilder based on the provided filter and mapping options.
|
116
129
|
*
|
117
|
-
* @param
|
118
|
-
* @param
|
119
|
-
* @param
|
120
|
-
* @param
|
121
|
-
* @param
|
122
|
-
* @param
|
130
|
+
* @param metadata - The EntityMetadata of the TypeORM entity.
|
131
|
+
* @param selectQueryBuilder - The SelectQueryBuilder to which the condition will be added.
|
132
|
+
* @param whereExpressionBuilder - The WhereExpressionBuilder to construct the where clause.
|
133
|
+
* @param filter - The Filter object containing the filter criteria.
|
134
|
+
* @param filtersMap - A mapping of filter names to column names and relation column names.
|
135
|
+
* @param andCondition - A flag indicating whether to use "AND" or "OR" for combining conditions.
|
123
136
|
*/
|
124
137
|
function addCondition<T>(
|
125
138
|
metadata: EntityMetadata,
|
@@ -130,210 +143,251 @@ function addCondition<T>(
|
|
130
143
|
andCondition: boolean
|
131
144
|
): void {
|
132
145
|
const { name, operator, value } = filter
|
133
|
-
|
134
|
-
|
135
|
-
|
136
|
-
|
137
|
-
/*
|
138
|
-
1. relationColumn과 columnName이 지정된 경우
|
139
|
-
- relation inverse 테이블에서, columnName을 찾는다.
|
140
|
-
2. relationColumn만 지정된 경우는 없어야 한다.
|
141
|
-
- 이 경우 columnName 은 'name' 이라고 판단한다.
|
142
|
-
3. columnName이 지정된 경우.
|
143
|
-
- 이 경우는 columnName 만 적용한다.
|
144
|
-
*/
|
146
|
+
let entityAlias = selectQueryBuilder.alias
|
147
|
+
|
148
|
+
const { relationColumn, columnName } = filtersMap[name] || {}
|
149
|
+
|
145
150
|
if (relationColumn) {
|
146
|
-
|
147
|
-
|
148
|
-
|
149
|
-
|
150
|
-
|
151
|
-
|
152
|
-
|
153
|
-
|
154
|
-
|
155
|
-
entityAlias = `${entityAlias}-${entityMetadata.tableName}-for-${columnName || 'name'}` as string
|
156
|
-
|
157
|
-
if (andCondition) {
|
158
|
-
selectQueryBuilder.innerJoin(property, entityAlias)
|
159
|
-
} else {
|
160
|
-
selectQueryBuilder.leftJoin(property, entityAlias)
|
161
|
-
}
|
162
|
-
} else {
|
163
|
-
entityMetadata = metadata
|
164
|
-
}
|
151
|
+
entityAlias = applyJoins(
|
152
|
+
selectQueryBuilder,
|
153
|
+
entityAlias,
|
154
|
+
relationColumn,
|
155
|
+
metadata,
|
156
|
+
andCondition ? 'innerJoin' : 'leftJoin',
|
157
|
+
columnName || name
|
158
|
+
)
|
159
|
+
}
|
165
160
|
|
166
|
-
|
167
|
-
|
168
|
-
console.warn(`relationColumn "${relationColumn}" in filtersMap for "${name}" is not a relation column`)
|
169
|
-
return
|
170
|
-
}
|
161
|
+
const field = `${entityAlias}.${columnName || name}`
|
162
|
+
const { clause, parameters } = getClauseAndParameters(field, name, operator, value)
|
171
163
|
|
172
|
-
|
173
|
-
|
174
|
-
|
164
|
+
if (andCondition) {
|
165
|
+
whereExpressionBuilder.andWhere(clause, parameters)
|
166
|
+
} else {
|
167
|
+
whereExpressionBuilder.orWhere(clause, parameters)
|
168
|
+
}
|
169
|
+
}
|
175
170
|
|
176
|
-
|
177
|
-
|
178
|
-
|
179
|
-
|
171
|
+
/**
|
172
|
+
* Adds sorting to the SelectQueryBuilder based on the provided Sorting objects.
|
173
|
+
*
|
174
|
+
* @param selectQueryBuilder - The SelectQueryBuilder to which sorting should be applied.
|
175
|
+
* @param sortings - An array of Sorting objects defining the sort order.
|
176
|
+
* @param entityAlias - The alias of the entity in the query.
|
177
|
+
* @param filtersMap - A mapping of filter names to column names and relation column names.
|
178
|
+
* @param metadata - The EntityMetadata of the TypeORM entity.
|
179
|
+
*/
|
180
|
+
function addSorting<T>(
|
181
|
+
selectQueryBuilder: SelectQueryBuilder<T>,
|
182
|
+
sortings: Sorting[],
|
183
|
+
entityAlias: string,
|
184
|
+
filtersMap: { [name: string]: { columnName: string; relationColumn?: string } },
|
185
|
+
metadata: EntityMetadata
|
186
|
+
) {
|
187
|
+
sortings.forEach((sorting, index) => {
|
188
|
+
const sortField = determineSortField(sorting.name, entityAlias, filtersMap, selectQueryBuilder, metadata)
|
189
|
+
if (index === 0) {
|
190
|
+
selectQueryBuilder.orderBy(sortField, sorting.desc ? 'DESC' : 'ASC')
|
191
|
+
} else {
|
192
|
+
selectQueryBuilder.addOrderBy(sortField, sorting.desc ? 'DESC' : 'ASC')
|
180
193
|
}
|
194
|
+
})
|
195
|
+
}
|
196
|
+
|
197
|
+
/**
|
198
|
+
* Determines the sorting field for a given sorting name, considering possible relation columns.
|
199
|
+
*
|
200
|
+
* @param sortingName - The name of the field to sort by.
|
201
|
+
* @param entityAlias - The alias of the entity in the query.
|
202
|
+
* @param filtersMap - A mapping of filter names to column names and relation column names.
|
203
|
+
* @param selectQueryBuilder - The SelectQueryBuilder instance to apply sorting to.
|
204
|
+
* @param metadata - The EntityMetadata of the TypeORM entity.
|
205
|
+
* @returns {string} - The fully qualified sorting field.
|
206
|
+
*/
|
207
|
+
function determineSortField<T>(
|
208
|
+
sortingName: string,
|
209
|
+
entityAlias: string,
|
210
|
+
filtersMap: { [name: string]: { columnName: string; relationColumn?: string } },
|
211
|
+
selectQueryBuilder: SelectQueryBuilder<T>,
|
212
|
+
metadata: EntityMetadata
|
213
|
+
): string {
|
214
|
+
const filter = filtersMap[sortingName]
|
215
|
+
|
216
|
+
if (!filter) {
|
217
|
+
return `${entityAlias}.${sortingName}`
|
218
|
+
}
|
219
|
+
|
220
|
+
const { columnName, relationColumn } = filter
|
221
|
+
|
222
|
+
if (relationColumn) {
|
223
|
+
const relationAlias = applyJoins(
|
224
|
+
selectQueryBuilder,
|
225
|
+
entityAlias,
|
226
|
+
relationColumn,
|
227
|
+
metadata,
|
228
|
+
'leftJoin',
|
229
|
+
columnName || sortingName,
|
230
|
+
true
|
231
|
+
)
|
232
|
+
return `${relationAlias}.${columnName}`
|
181
233
|
} else {
|
182
|
-
|
183
|
-
|
184
|
-
|
185
|
-
|
186
|
-
|
187
|
-
|
188
|
-
|
189
|
-
|
190
|
-
|
191
|
-
|
192
|
-
|
234
|
+
return `${entityAlias}.${columnName}`
|
235
|
+
}
|
236
|
+
}
|
237
|
+
|
238
|
+
/**
|
239
|
+
* Applies the necessary joins to the SelectQueryBuilder based on the relation column.
|
240
|
+
*
|
241
|
+
* @param selectQueryBuilder - The SelectQueryBuilder where the joins will be applied.
|
242
|
+
* @param entityAlias - The current alias of the entity in the query.
|
243
|
+
* @param relationColumn - The dot-notated string representing the relation chain (e.g., "user.profile.address").
|
244
|
+
* @param metadata - The EntityMetadata of the entity.
|
245
|
+
* @param joinType - The type of join to use ("innerJoin" or "leftJoin").
|
246
|
+
* @param columnName - The name of the column used for filtering or sorting, default to 'name'.
|
247
|
+
* @param selectField - Whether to include the field in the SELECT clause.
|
248
|
+
* @returns {string} - The alias to be used for the final field in the relation chain.
|
249
|
+
*/
|
250
|
+
function applyJoins<T>(
|
251
|
+
selectQueryBuilder: SelectQueryBuilder<T>,
|
252
|
+
entityAlias: string,
|
253
|
+
relationColumn: string,
|
254
|
+
metadata: EntityMetadata,
|
255
|
+
joinType: 'innerJoin' | 'leftJoin' = 'leftJoin',
|
256
|
+
columnName: string = 'name',
|
257
|
+
selectField: boolean = false
|
258
|
+
): string {
|
259
|
+
const columns = relationColumn.split('.')
|
260
|
+
let currentAlias = entityAlias
|
261
|
+
let currentMetadata = metadata
|
262
|
+
|
263
|
+
for (const column of columns) {
|
264
|
+
const relation = currentMetadata.relations.find(rel => rel.propertyName === column)
|
265
|
+
|
266
|
+
if (!relation) {
|
267
|
+
throw new Error(`Relation not found for column: ${column}`)
|
193
268
|
}
|
194
269
|
|
195
|
-
|
196
|
-
|
197
|
-
|
198
|
-
|
199
|
-
|
200
|
-
|
201
|
-
|
202
|
-
if (!columnMeta) {
|
203
|
-
console.warn(`relation column "${columnName || name}" does not have "name" column`)
|
204
|
-
return
|
205
|
-
}
|
270
|
+
const nextAlias = `${currentAlias}_${relation.inverseEntityMetadata.tableName}_for_${columnName}`
|
271
|
+
|
272
|
+
if (!selectQueryBuilder.expressionMap.aliases.some(alias => alias.name === nextAlias)) {
|
273
|
+
selectQueryBuilder[joinType](`${currentAlias}.${column}`, nextAlias)
|
274
|
+
}
|
275
|
+
if (selectField) {
|
276
|
+
selectQueryBuilder.addSelect(`${nextAlias}.${columnName}`, `${nextAlias}_${columnName}`)
|
206
277
|
}
|
207
|
-
}
|
208
278
|
|
209
|
-
|
210
|
-
|
279
|
+
currentAlias = nextAlias
|
280
|
+
currentMetadata = relation.inverseEntityMetadata
|
281
|
+
}
|
211
282
|
|
212
|
-
|
213
|
-
|
283
|
+
return currentAlias
|
284
|
+
}
|
214
285
|
|
215
|
-
|
216
|
-
|
286
|
+
/**
|
287
|
+
* Generates the SQL clause and parameters based on the provided filter.
|
288
|
+
*
|
289
|
+
* @param field - The database field to filter on.
|
290
|
+
* @param name - The name of the filter.
|
291
|
+
* @param operator - The operator to use in the filter.
|
292
|
+
* @param value - The value to filter with.
|
293
|
+
* @returns An object containing the SQL clause and the parameters.
|
294
|
+
*/
|
295
|
+
function getClauseAndParameters(
|
296
|
+
field: string,
|
297
|
+
name: string,
|
298
|
+
operator: string,
|
299
|
+
value: any
|
300
|
+
): { clause: string; parameters: { [key: string]: any } } {
|
301
|
+
const values = value instanceof Array ? value : [value]
|
302
|
+
let clause = ''
|
303
|
+
let parameters: { [key: string]: any } = {}
|
217
304
|
|
218
305
|
switch (operator) {
|
219
306
|
case 'eq':
|
220
307
|
clause = `${field} = :${name}`
|
221
308
|
parameters = { [name]: value }
|
222
309
|
break
|
223
|
-
|
224
310
|
case 'like':
|
225
311
|
clause = `${field} LIKE :${name}`
|
226
312
|
parameters = { [name]: `%${value}%` }
|
227
313
|
break
|
228
|
-
|
229
314
|
case 'search':
|
230
315
|
case 'i_like':
|
231
316
|
clause = `LOWER(${field}) LIKE :${name}`
|
232
317
|
parameters = { [name]: `%${String(value).toLowerCase()}%` }
|
233
318
|
break
|
234
|
-
|
235
319
|
case 'nlike':
|
236
320
|
clause = `${field} NOT LIKE :${name}`
|
237
321
|
parameters = { [name]: `%${value}%` }
|
238
322
|
break
|
239
|
-
|
240
323
|
case 'i_nlike':
|
241
324
|
clause = `LOWER(${field}) NOT LIKE :${name}`
|
242
325
|
parameters = { [name]: `%${String(value).toLowerCase()}%` }
|
243
326
|
break
|
244
|
-
|
245
327
|
case 'lt':
|
246
328
|
clause = `${field} < :${name}`
|
247
329
|
parameters = { [name]: value }
|
248
330
|
break
|
249
|
-
|
250
331
|
case 'gt':
|
251
332
|
clause = `${field} > :${name}`
|
252
333
|
parameters = { [name]: value }
|
253
334
|
break
|
254
|
-
|
255
335
|
case 'lte':
|
256
336
|
clause = `${field} <= :${name}`
|
257
337
|
parameters = { [name]: value }
|
258
338
|
break
|
259
|
-
|
260
339
|
case 'gte':
|
261
340
|
clause = `${field} >= :${name}`
|
262
341
|
parameters = { [name]: value }
|
263
342
|
break
|
264
|
-
|
265
343
|
case 'noteq':
|
266
344
|
clause = `${field} != :${name}`
|
267
345
|
parameters = { [name]: value }
|
268
346
|
break
|
269
|
-
|
270
347
|
case 'in':
|
271
348
|
clause = `${field} IN (:...${name})`
|
272
349
|
parameters = { [name]: values }
|
273
350
|
break
|
274
|
-
|
275
351
|
case 'notin':
|
276
352
|
clause = `${field} NOT IN (:...${name})`
|
277
353
|
parameters = { [name]: values }
|
278
354
|
break
|
279
|
-
|
280
355
|
case 'notin_with_null':
|
281
|
-
clause = `${field} IS NULL OR ${field} NOT IN (:...${name})
|
356
|
+
clause = `${field} IS NULL OR ${field} NOT IN (:...${name})`
|
282
357
|
parameters = { [name]: values }
|
283
358
|
break
|
284
|
-
|
285
359
|
case 'is_null':
|
286
360
|
clause = `${field} IS NULL`
|
287
361
|
break
|
288
|
-
|
289
362
|
case 'is_not_null':
|
290
363
|
clause = `${field} IS NOT NULL`
|
291
364
|
break
|
292
|
-
|
293
365
|
case 'is_false':
|
294
366
|
clause = `${field} IS FALSE`
|
295
367
|
break
|
296
|
-
|
297
368
|
case 'is_true':
|
298
369
|
clause = `${field} IS TRUE`
|
299
370
|
break
|
300
|
-
|
301
371
|
case 'is_not_false':
|
302
372
|
clause = `${field} IS NOT FALSE`
|
303
373
|
break
|
304
|
-
|
305
374
|
case 'is_not_true':
|
306
375
|
clause = `${field} IS NOT TRUE`
|
307
376
|
break
|
308
|
-
|
309
377
|
case 'is_present':
|
310
378
|
clause = `${field} IS PRESENT`
|
311
379
|
break
|
312
|
-
|
313
380
|
case 'is_blank':
|
314
381
|
clause = `${field} IS BLANK`
|
315
382
|
break
|
316
|
-
|
317
383
|
case 'is_empty_num_id':
|
318
384
|
clause = `${field} IS EMPTY NUMERIC ID`
|
319
385
|
break
|
320
|
-
|
321
386
|
case 'between':
|
322
387
|
clause = `${field} BETWEEN :${name}_1 AND :${name}_2`
|
323
388
|
parameters = { [`${name}_1`]: values[0], [`${name}_2`]: values[1] }
|
324
389
|
break
|
325
390
|
}
|
326
391
|
|
327
|
-
|
328
|
-
const { propertyName } = relationColumnMeta
|
329
|
-
const property = `${entityAlias}.${propertyName}`
|
330
|
-
if (andCondition) {
|
331
|
-
selectQueryBuilder.innerJoin(property, alias, clause, parameters)
|
332
|
-
} else {
|
333
|
-
selectQueryBuilder.leftJoin(property, alias)
|
334
|
-
whereExpressionBuilder.orWhere(clause, parameters)
|
335
|
-
}
|
336
|
-
} else {
|
337
|
-
andCondition ? whereExpressionBuilder.andWhere(clause, parameters) : whereExpressionBuilder.orWhere(clause, parameters)
|
338
|
-
}
|
392
|
+
return { clause, parameters }
|
339
393
|
}
|