Skip to content

Commit 2d0bdca

Browse files
committed
feat(search): code cleanup
1 parent 6ab04db commit 2d0bdca

File tree

1 file changed

+94
-170
lines changed

1 file changed

+94
-170
lines changed

src/graphql/schemas/utils/filters-kysely.ts

Lines changed: 94 additions & 170 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ enum OperatorSymbols {
2727
contains = "@>",
2828
}
2929

30+
// TODO: remove when data client is updated
3031
export const generateFilterValues = (
3132
column: string,
3233
operator: OperatorType,
@@ -88,208 +89,132 @@ export const isFilterObject = (obj: never): boolean => {
8889
return Object.keys(obj).some((key) => filterKeys.includes(key));
8990
};
9091

91-
export const buildSearchCondition = (
92+
// Helper functions for building conditions
93+
const buildEqualityCondition = (
9294
column: string,
93-
value:
94-
| StringSearchOptions
95-
| NumberSearchOptions
96-
| StringArraySearchOptions
97-
| NumberArraySearchOptions,
95+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
96+
value: any,
97+
tableName: string,
98+
): SqlBool => sql`${sql.raw(`"${tableName}"."${column}"`)} =
99+
${value}`;
100+
101+
const buildComparisonCondition = (
102+
column: string,
103+
operator: string,
104+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
105+
value: any,
106+
tableName: string,
107+
): SqlBool =>
108+
sql`${sql.raw(`"${tableName}"."${column}"`)}
109+
${sql.raw(operator)}
110+
${value}`;
111+
112+
const buildLikeCondition = (
113+
column: string,
114+
pattern: string,
115+
tableName: string,
116+
): SqlBool => sql`${sql.raw(`"${tableName}"."${column}"`)} ILIKE
117+
${pattern}`;
118+
119+
const buildArrayCondition = (
120+
column: string,
121+
operator: string,
122+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
123+
values: any[],
124+
tableName: string,
125+
): SqlBool =>
126+
sql`${sql.raw(`"${tableName}"."${column}"`)}
127+
${sql.raw(operator)}
128+
${sql.raw(`ARRAY[${values.map((v) => `'${v}'`).join(", ")}]`)}`;
129+
130+
const conditionBuilders = {
131+
eq: buildEqualityCondition,
132+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
133+
gt: (column: string, value: any, tableName: string) =>
134+
buildComparisonCondition(column, ">", value, tableName),
135+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
136+
gte: (column: string, value: any, tableName: string) =>
137+
buildComparisonCondition(column, ">=", value, tableName),
138+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
139+
lt: (column: string, value: any, tableName: string) =>
140+
buildComparisonCondition(column, "<", value, tableName),
141+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
142+
lte: (column: string, value: any, tableName: string) =>
143+
buildComparisonCondition(column, "<=", value, tableName),
144+
contains: (column: string, value: string, tableName: string) =>
145+
buildLikeCondition(column, `%${value}%`, tableName),
146+
startsWith: (column: string, value: string, tableName: string) =>
147+
buildLikeCondition(column, `${value}%`, tableName),
148+
endsWith: (column: string, value: string, tableName: string) =>
149+
buildLikeCondition(column, `%${value}`, tableName),
150+
};
151+
152+
export const buildCondition = (
153+
column: string,
154+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
155+
value: any,
98156
tableName: string,
99157
): SqlBool => {
100158
const conditions: SqlBool[] = [];
101159

102-
if (value instanceof StringSearchOptions) {
103-
if (value.contains) {
104-
conditions.push(
105-
sql`${sql.raw(`"${tableName}"."${column}"`)} ILIKE
106-
${"%" + value.contains + "%"}`,
107-
);
108-
}
109-
if (value.startsWith) {
110-
conditions.push(
111-
sql`${sql.raw(`"${tableName}"."${column}"`)} ILIKE
112-
${value.startsWith + "%"}`,
113-
);
114-
}
115-
if (value.endsWith) {
116-
conditions.push(
117-
sql`${sql.raw(`"${tableName}"."${column}"`)} ILIKE
118-
${"%" + value.endsWith}`,
119-
);
120-
}
121-
if (value.eq) {
122-
conditions.push(
123-
sql`${sql.raw(`"${tableName}"."${column}"`)} =
124-
${value.eq}`,
125-
);
126-
}
127-
} else if (value instanceof NumberSearchOptions) {
128-
if (value.eq !== undefined) {
129-
conditions.push(
130-
sql`${sql.raw(`"${tableName}"."${column}"`)} =
131-
${value.eq}`,
132-
);
133-
}
134-
if (value.gt !== undefined) {
135-
conditions.push(
136-
sql`${sql.raw(`"${tableName}"."${column}"`)} >
137-
${value.gt}`,
138-
);
139-
}
140-
if (value.gte !== undefined) {
141-
conditions.push(
142-
sql`${sql.raw(`"${tableName}"."${column}"`)} >=
143-
${value.gte}`,
144-
);
145-
}
146-
if (value.lt !== undefined) {
147-
conditions.push(
148-
sql`${sql.raw(`"${tableName}"."${column}"`)} <
149-
${value.lt}`,
150-
);
151-
}
152-
if (value.lte !== undefined) {
153-
conditions.push(
154-
sql`${sql.raw(`"${tableName}"."${column}"`)} <=
155-
${value.lte}`,
156-
);
157-
}
158-
} else if (value instanceof StringArraySearchOptions) {
159-
if (value.contains && value.contains.length > 0) {
160-
conditions.push(
161-
sql`${sql.raw(`"${tableName}"."${column}"`)} @>
162-
${sql.raw(`ARRAY[${value.contains.map((v) => `'${v}'`).join(", ")}]`)}`,
163-
);
164-
}
165-
if (value.overlaps && value.overlaps.length > 0) {
166-
conditions.push(
167-
sql`${sql.raw(`"${tableName}"."${column}"`)} &&
168-
${sql.raw(`ARRAY[${value.overlaps.map((v) => `'${v}'`).join(", ")}]`)}`,
169-
);
170-
}
171-
} else if (value instanceof NumberArraySearchOptions) {
160+
if (
161+
value instanceof StringSearchOptions ||
162+
value instanceof NumberSearchOptions
163+
) {
164+
Object.entries(value).forEach(([key, val]) => {
165+
if (key in conditionBuilders && val !== undefined) {
166+
conditions.push(conditionBuilders[key](column, val, tableName));
167+
}
168+
});
169+
} else if (
170+
value instanceof StringArraySearchOptions ||
171+
value instanceof NumberArraySearchOptions
172+
) {
172173
if (value.contains && value.contains.length > 0) {
173174
conditions.push(
174-
sql`${sql.raw(`"${tableName}"."${column}"`)} @>
175-
${sql.raw(`ARRAY[${value.contains.join(", ")}]`)}`,
175+
buildArrayCondition(column, "@>", value.contains, tableName),
176176
);
177177
}
178178
if (value.overlaps && value.overlaps.length > 0) {
179179
conditions.push(
180-
sql`${sql.raw(`"${tableName}"."${column}"`)} &&
181-
${sql.raw(`ARRAY[${value.overlaps.join(", ")}]`)}`,
180+
buildArrayCondition(column, "&&", value.overlaps, tableName),
182181
);
183182
}
184-
}
185-
186-
return sql.join(conditions, sql` AND `);
187-
};
188-
export const buildFilterCondition = (
189-
column: string,
190-
filter: never,
191-
tableName: string,
192-
): SqlBool => {
193-
const conditions: SqlBool[] = [];
194-
195-
if ("eq" in filter) {
196-
conditions.push(
197-
sql`${sql.raw(`"${tableName}"."${column}"`)} =
198-
${filter.eq}`,
199-
);
200-
}
201-
if ("gt" in filter) {
202-
conditions.push(
203-
sql`${sql.raw(`"${tableName}"."${column}"`)} >
204-
${filter.gt}`,
205-
);
206-
}
207-
if ("gte" in filter) {
208-
conditions.push(
209-
sql`${sql.raw(`"${tableName}"."${column}"`)} >=
210-
${filter.gte}`,
211-
);
212-
}
213-
if ("lt" in filter) {
214-
conditions.push(
215-
sql`${sql.raw(`"${tableName}"."${column}"`)} <
216-
${filter.lt}`,
217-
);
218-
}
219-
if ("lte" in filter) {
220-
conditions.push(
221-
sql`${sql.raw(`"${tableName}"."${column}"`)} <=
222-
${filter.lte}`,
223-
);
224-
}
225-
if ("contains" in filter && typeof filter.contains === "string") {
226-
conditions.push(
227-
sql`${sql.raw(`"${tableName}"."${column}"`)} ILIKE
228-
${"%" + filter.contains + "%"}`,
229-
);
230-
}
231-
if ("startsWith" in filter) {
232-
conditions.push(
233-
sql`${sql.raw(`"${tableName}"."${column}"`)} ILIKE
234-
${filter.startsWith + "%"}`,
235-
);
236-
}
237-
if ("endsWith" in filter) {
238-
conditions.push(
239-
sql`${sql.raw(`"${tableName}"."${column}"`)} ILIKE
240-
${"%" + filter.endsWith}`,
241-
);
183+
} else if (typeof value === "object" && value !== null) {
184+
Object.entries(value).forEach(([key, val]) => {
185+
if (key in conditionBuilders && val !== undefined) {
186+
conditions.push(conditionBuilders[key](column, val, tableName));
187+
} else if (key === "contains" && Array.isArray(val)) {
188+
conditions.push(buildArrayCondition(column, "@>", val, tableName));
189+
} else if (key === "overlaps" && Array.isArray(val)) {
190+
conditions.push(buildArrayCondition(column, "&&", val, tableName));
191+
}
192+
});
242193
}
243194

244195
return sql.join(conditions, sql` AND `);
245196
};
246197

247198
export const buildWhereCondition = <T extends string>(
248199
column: string,
249-
value: never,
200+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
201+
value: any,
250202
tableName: T,
251-
eb: never,
203+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
204+
eb: any,
252205
): SqlBool | null => {
253206
if (!column || value === undefined) return null;
254-
console.log(
255-
"Building where condition for field",
256-
column,
257-
"in table",
258-
tableName,
259-
);
260-
261-
if (
262-
value instanceof StringSearchOptions ||
263-
value instanceof NumberSearchOptions ||
264-
value instanceof StringArraySearchOptions ||
265-
value instanceof NumberArraySearchOptions
266-
) {
267-
console.log("Found search condition for column: ", column);
268-
return buildSearchCondition(column, value, tableName);
269-
}
270207

271208
if (typeof value === "object" && value !== null) {
272209
if (isFilterObject(value)) {
273-
console.log("Found filter condition for column: ", column);
274-
if (
275-
("contains" in value && Array.isArray(value.contains)) ||
276-
"overlaps" in value
277-
) {
278-
// This is an array operation, use buildSearchCondition
279-
return buildSearchCondition(column, value, tableName);
280-
} else {
281-
// This is a non-array operation, use buildFilterCondition
282-
return buildFilterCondition(column, value, tableName);
283-
}
210+
return buildCondition(column, value, tableName);
284211
}
285212

286213
const relatedTable = getTablePrefix(column);
287214
const nestedConditions: SqlBool[] = [];
288215

289216
for (const [nestedColumn, nestedValue] of Object.entries(value)) {
290217
if (!nestedColumn || nestedValue === undefined) continue;
291-
console.log("Nested column", nestedColumn);
292-
console.log("Nested value", nestedValue);
293218
const nestedCondition = buildWhereCondition(
294219
nestedColumn,
295220
nestedValue,
@@ -306,7 +231,6 @@ export const buildWhereCondition = <T extends string>(
306231
: null;
307232
}
308233

309-
console.log("Simple equality condition for column: ", column);
310234
return sql`${sql.raw(`"${tableName}"."${column}"`)} =
311235
${value}`;
312236
};

0 commit comments

Comments
 (0)