useDbQuery.tsx93 lines · main
| 1 | import { type SafeSqlFragment } from '@supabase/pg-meta/src/pg-format' |
| 2 | import { useQuery } from '@tanstack/react-query' |
| 3 | |
| 4 | import { DEFAULT_QUERY_PARAMS } from '@/components/interfaces/Reports/Reports.constants' |
| 5 | import { |
| 6 | BaseReportParams, |
| 7 | MetaQueryResponse, |
| 8 | ReportQueryDb, |
| 9 | } from '@/components/interfaces/Reports/Reports.types' |
| 10 | import { useReadReplicasQuery } from '@/data/read-replicas/replicas-query' |
| 11 | import { executeSql } from '@/data/sql/execute-sql-query' |
| 12 | import { useSelectedProjectQuery } from '@/hooks/misc/useSelectedProject' |
| 13 | import { useDatabaseSelectorStateSnapshot } from '@/state/database-selector' |
| 14 | |
| 15 | export interface DbQueryHook<T = any> { |
| 16 | isLoading: boolean |
| 17 | isRefetching: boolean |
| 18 | error: string |
| 19 | data: T[] |
| 20 | params: BaseReportParams |
| 21 | logData?: never |
| 22 | runQuery: () => void |
| 23 | setParams?: never |
| 24 | changeQuery?: never |
| 25 | resolvedSql: string |
| 26 | } |
| 27 | |
| 28 | // [Joshen] Atm this is being used only in query performance |
| 29 | const useDbQuery = ({ |
| 30 | sql, |
| 31 | params = DEFAULT_QUERY_PARAMS, |
| 32 | where, |
| 33 | orderBy, |
| 34 | }: { |
| 35 | sql: ReportQueryDb['safeSql'] | SafeSqlFragment |
| 36 | params?: BaseReportParams |
| 37 | where?: string |
| 38 | orderBy?: string |
| 39 | }): DbQueryHook => { |
| 40 | const { data: project } = useSelectedProjectQuery() |
| 41 | const state = useDatabaseSelectorStateSnapshot() |
| 42 | |
| 43 | const { data: databases } = useReadReplicasQuery({ projectRef: project?.ref }) |
| 44 | const connectionString = (databases || []).find( |
| 45 | (db) => db.identifier === state.selectedDatabaseId |
| 46 | )?.connectionString |
| 47 | const identifier = state.selectedDatabaseId |
| 48 | |
| 49 | const resolvedSql = typeof sql === 'function' ? sql([]) : sql |
| 50 | |
| 51 | const { |
| 52 | data, |
| 53 | error: rqError, |
| 54 | isPending, |
| 55 | isRefetching, |
| 56 | refetch, |
| 57 | } = useQuery({ |
| 58 | queryKey: [ |
| 59 | 'projects', |
| 60 | project?.ref, |
| 61 | 'db', |
| 62 | { ...params, sql: resolvedSql, identifier }, |
| 63 | where, |
| 64 | orderBy, |
| 65 | ], |
| 66 | queryFn: ({ signal }) => { |
| 67 | return executeSql( |
| 68 | { |
| 69 | projectRef: project?.ref, |
| 70 | connectionString: connectionString || project?.connectionString, |
| 71 | sql: resolvedSql, |
| 72 | }, |
| 73 | signal |
| 74 | ).then((res) => res.result) as Promise<MetaQueryResponse> |
| 75 | }, |
| 76 | enabled: Boolean(resolvedSql), |
| 77 | refetchOnWindowFocus: false, |
| 78 | refetchOnReconnect: false, |
| 79 | }) |
| 80 | |
| 81 | const error = rqError || (typeof data === 'object' ? data?.error : '') |
| 82 | return { |
| 83 | error, |
| 84 | data, |
| 85 | isLoading: isPending, |
| 86 | isRefetching, |
| 87 | params, |
| 88 | runQuery: refetch, |
| 89 | resolvedSql, |
| 90 | } |
| 91 | } |
| 92 | |
| 93 | export default useDbQuery |