47 lines
1.7 KiB
TypeScript
47 lines
1.7 KiB
TypeScript
|
|
/**
|
||
|
|
* @module useQueryManager
|
||
|
|
* @description 리포트에 연결된 SQL 쿼리 목록과 실행 결과 캐시를 관리한다.
|
||
|
|
* - queries: 저장/편집 대상 쿼리 정의 목록
|
||
|
|
* - queryResults: 각 쿼리의 마지막 실행 결과 (캐시)
|
||
|
|
*/
|
||
|
|
|
||
|
|
import { useState, useCallback } from "react";
|
||
|
|
import type { ReportQuery, QueryResult } from "./types";
|
||
|
|
|
||
|
|
export interface QueryManagerState {
|
||
|
|
queries: ReportQuery[];
|
||
|
|
setQueries: (queries: ReportQuery[]) => void;
|
||
|
|
queryResults: QueryResult[];
|
||
|
|
setQueryResult: (queryId: string, fields: string[], rows: Record<string, unknown>[]) => void;
|
||
|
|
getQueryResult: (queryId: string) => QueryResult | null;
|
||
|
|
}
|
||
|
|
|
||
|
|
export function useQueryManager(): QueryManagerState {
|
||
|
|
const [queries, setQueries] = useState<ReportQuery[]>([]);
|
||
|
|
const [queryResults, setQueryResults] = useState<QueryResult[]>([]);
|
||
|
|
|
||
|
|
/**
|
||
|
|
* 특정 쿼리의 실행 결과를 캐시에 저장/갱신한다.
|
||
|
|
* 동일 queryId가 이미 있으면 덮어쓰고, 없으면 추가한다.
|
||
|
|
*/
|
||
|
|
const setQueryResult = useCallback((queryId: string, fields: string[], rows: Record<string, unknown>[]) => {
|
||
|
|
setQueryResults((prev) => {
|
||
|
|
const exists = prev.some((r) => r.queryId === queryId);
|
||
|
|
if (exists) {
|
||
|
|
return prev.map((r) => (r.queryId === queryId ? { queryId, fields, rows } : r));
|
||
|
|
}
|
||
|
|
return [...prev, { queryId, fields, rows }];
|
||
|
|
});
|
||
|
|
}, []);
|
||
|
|
|
||
|
|
/** 쿼리 ID로 캐시된 실행 결과를 조회한다. 없으면 null 반환. */
|
||
|
|
const getQueryResult = useCallback(
|
||
|
|
(queryId: string): QueryResult | null => {
|
||
|
|
return queryResults.find((r) => r.queryId === queryId) ?? null;
|
||
|
|
},
|
||
|
|
[queryResults],
|
||
|
|
);
|
||
|
|
|
||
|
|
return { queries, setQueries, queryResults, setQueryResult, getQueryResult };
|
||
|
|
}
|