summaryrefslogtreecommitdiff
path: root/lib/filter-columns.ts
diff options
context:
space:
mode:
authordujinkim <dujin.kim@dtsolution.co.kr>2025-05-28 00:32:31 +0000
committerdujinkim <dujin.kim@dtsolution.co.kr>2025-05-28 00:32:31 +0000
commit20800b214145ee6056f94ca18fa1054f145eb977 (patch)
treeb5c8b27febe5b126e6d9ece115ea05eace33a020 /lib/filter-columns.ts
parente1344a5da1aeef8fbf0f33e1dfd553078c064ccc (diff)
(대표님) lib 파트 커밋
Diffstat (limited to 'lib/filter-columns.ts')
-rw-r--r--lib/filter-columns.ts139
1 files changed, 115 insertions, 24 deletions
diff --git a/lib/filter-columns.ts b/lib/filter-columns.ts
index 4b995925..4e561d05 100644
--- a/lib/filter-columns.ts
+++ b/lib/filter-columns.ts
@@ -22,39 +22,48 @@ import type { PgTable, PgView } from "drizzle-orm/pg-core"
type TableOrView = PgTable | PgView<any>
+// 조인된 테이블들의 타입 정의
+export interface JoinedTables {
+ [key: string]: TableOrView
+}
+
+// 커스텀 컬럼 매핑 타입 정의
+export interface CustomColumnMapping {
+ [filterId: string]: {
+ table: TableOrView
+ column: string
+ } | AnyColumn
+}
+
/**
- * Construct SQL conditions based on the provided filters for a specific table.
- *
- * This function takes a table and an array of filters, and returns a SQL
- * expression that represents the logical combination of these conditions. The conditions
- * are combined using the specified join operator (either 'AND' or 'OR'), which is determined
- * by the first filter's joinOperator property.
- *
- * Each filter can specify various operators (e.g., equality, inequality,
- * comparison for numbers and dates, etc.) and the function will generate the appropriate
- * SQL expressions based on the filter's type and value.
- *
- * @param table - The table to apply the filters on.
- * @param filters - An array of filters to be applied to the table.
- * @param joinOperator - The join operator to use for combining the filters.
- * @returns A SQL expression representing the combined filters, or undefined if no valid
- * filters are found.
+ * Enhanced filterColumns function that supports joined tables and custom column mapping.
+ *
+ * This function can handle filters that reference columns from different tables
+ * in a joined query, and allows for custom mapping of filter IDs to actual table columns.
*/
-
export function filterColumns<T extends TableOrView>({
table,
filters,
joinOperator,
+ joinedTables,
+ customColumnMapping,
}: {
table: T
filters: Filter<T>[]
joinOperator: JoinOperator
+ joinedTables?: JoinedTables
+ customColumnMapping?: CustomColumnMapping
}): SQL | undefined {
const joinFn = joinOperator === "and" ? and : or
const conditions = filters.map((filter) => {
- const column = getColumn(table, filter.id)
+ const column = getColumnWithMapping(table, filter.id, joinedTables, customColumnMapping)
+
+ if (!column) {
+ console.warn(`Column not found for filter ID: ${filter.id}`)
+ return undefined
+ }
switch (filter.operator) {
case "eq":
@@ -174,20 +183,102 @@ export function filterColumns<T extends TableOrView>({
(condition) => condition !== undefined
)
-
return validConditions.length > 0 ? joinFn(...validConditions) : undefined
}
/**
- * Get table column.
- * @param table The table to get the column from.
- * @param columnKey The key of the column to retrieve from the table.
- * @returns The column corresponding to the provided key.
+ * Enhanced column getter - 간단한 수정 버전
*/
+function getColumnWithMapping<T extends TableOrView>(
+ table: T,
+ columnKey: keyof T | string,
+ joinedTables?: JoinedTables,
+ customColumnMapping?: CustomColumnMapping
+): AnyColumn | undefined {
+
+ // 1. 커스텀 매핑이 있는 경우 우선 확인
+ if (customColumnMapping && columnKey in customColumnMapping) {
+ const mapping = customColumnMapping[columnKey as string]
+
+ if (typeof mapping === 'object' && 'dataType' in mapping) {
+ return mapping as AnyColumn
+ }
+
+ if (typeof mapping === 'object' && 'table' in mapping && 'column' in mapping) {
+ try {
+ if (mapping.table && typeof mapping.column === 'string') {
+ const column = (mapping.table as any)[mapping.column];
+ if (column !== undefined) {
+ return column as AnyColumn;
+ }
+ }
+ } catch (error) {
+ console.warn(`Failed to get column ${mapping.column} from table:`, error)
+ }
+ }
+ }
+
+ // 2. 메인 테이블에서 컬럼 찾기 - 수정된 부분
+ if (typeof columnKey === 'string') {
+ // ✅ in 연산자 대신 직접 접근해서 undefined 체크
+ try {
+ const column = (table as any)[columnKey];
+ if (column !== undefined && column !== null) {
+ return column as AnyColumn;
+ }
+ } catch (error) {
+ // 직접 접근 실패 시 조용히 넘어감
+ }
+ } else {
+ // keyof T 타입인 경우 기존 함수 사용
+ try {
+ return getColumn(table, columnKey);
+ } catch (error) {
+ // getColumn 실패 시 조용히 넘어감
+ }
+ }
+
+ // 3. 조인된 테이블들에서 컬럼 찾기
+ if (joinedTables && typeof columnKey === 'string') {
+ for (const [tableName, joinedTable] of Object.entries(joinedTables)) {
+ try {
+ const column = (joinedTable as any)[columnKey];
+ if (column !== undefined && column !== null) {
+ return column as AnyColumn;
+ }
+ } catch (error) {
+ // 조용히 넘어감
+ }
+ }
+ }
+
+ // 4. 컬럼을 찾지 못한 경우
+ return undefined;
+}
+/**
+ * Get table column (기존 함수 유지).
+ */
export function getColumn<T extends TableOrView>(
table: T,
columnKey: keyof T
): AnyColumn {
return table[columnKey] as AnyColumn
-} \ No newline at end of file
+}
+
+/**
+ * Safe helper to get column from any table with string key
+ */
+export function getColumnSafe(table: TableOrView, columnKey: string): AnyColumn | undefined {
+ try {
+ if (columnKey in table) {
+ return (table as any)[columnKey] as AnyColumn
+ }
+ } catch (error) {
+ console.warn(`Failed to get column ${columnKey} from table:`, error)
+ }
+ return undefined
+}
+
+// 사용 예시를 위한 타입 정의
+export type FilterColumnsParams<T extends TableOrView> = Parameters<typeof filterColumns<T>>[0] \ No newline at end of file