diff --git a/src/screens/database/views/explorer/ExplorerPane/hooks.tsx b/src/screens/database/views/explorer/ExplorerPane/hooks.tsx index b5c111d2..3b875c7d 100644 --- a/src/screens/database/views/explorer/ExplorerPane/hooks.tsx +++ b/src/screens/database/views/explorer/ExplorerPane/hooks.tsx @@ -1,9 +1,7 @@ import { keepPreviousData, useQuery } from "@tanstack/react-query"; import { useDatabaseSchema } from "~/hooks/schema"; -import { - executeQueryFirst, - executeQuerySingle, -} from "~/screens/database/connection/connection"; +import { executeQueryFirst, executeQuerySingle } from "~/screens/database/connection/connection"; +import { escapeIdent } from "~/util/surrealql"; export type SortMode = [string, "asc" | "desc"] | null; @@ -23,14 +21,7 @@ export function useRecordQuery(input: RecordQueryInput) { queryKey: ["explorer", "records", input], placeholderData: keepPreviousData, queryFn: async () => { - const { - activeTable, - currentPage, - pageSize, - sortMode, - isFilterValid, - filter, - } = input; + const { activeTable, currentPage, pageSize, sortMode, isFilterValid, filter } = input; try { if (!activeTable || !isFilterValid) { @@ -40,7 +31,7 @@ export function useRecordQuery(input: RecordQueryInput) { const limitBy = pageSize; const startAt = (currentPage - 1) * pageSize; - let fetchQuery = `SELECT * FROM ${activeTable}`; + let fetchQuery = `SELECT * FROM ${escapeIdent(activeTable)}`; if (filter) { fetchQuery += ` WHERE ${filter}`; @@ -61,11 +52,7 @@ export function useRecordQuery(input: RecordQueryInput) { const headers = schema?.tables ?.find((t) => t.schema.name === activeTable) - ?.fields?.filter( - (f) => - !f.name.includes("[*]") && - !f.name.includes("."), - ) + ?.fields?.filter((f) => !f.name.includes("[*]") && !f.name.includes(".")) ?.map((f) => f.name) || []; return { @@ -96,7 +83,7 @@ export function usePaginationQuery(input: PaginationQueryInput) { } try { - let countQuery = `SELECT count() AS count FROM ${activeTable}`; + let countQuery = `SELECT count() AS count FROM ${escapeIdent(activeTable)}`; if (filter) { countQuery += ` WHERE ${filter}`; diff --git a/src/screens/database/views/explorer/ExplorerView/index.tsx b/src/screens/database/views/explorer/ExplorerView/index.tsx index 1f066386..e9dc2c1e 100644 --- a/src/screens/database/views/explorer/ExplorerView/index.tsx +++ b/src/screens/database/views/explorer/ExplorerView/index.tsx @@ -1,3 +1,14 @@ +import { + iconChevronRight, + iconDesigner, + iconDownload, + iconExplorer, + iconOpen, + iconPlus, + iconTable, + iconUpload, +} from "~/util/icons"; + import { Box, Button, Group, Text } from "@mantine/core"; import { useDisclosure } from "@mantine/hooks"; import { memo, useState } from "react"; @@ -11,23 +22,12 @@ import { useConnection, useIsConnected } from "~/hooks/connection"; import { useEventSubscription } from "~/hooks/event"; import { usePanelMinSize } from "~/hooks/panels"; import { useStable } from "~/hooks/stable"; -import { useIsLight } from "~/hooks/theme"; import { dispatchIntent, useIntent } from "~/hooks/url"; import { useViewEffect } from "~/hooks/view"; import { useDesigner } from "~/providers/Designer"; import { TablesPane } from "~/screens/database/components/TablesPane"; import { useInterfaceStore } from "~/stores/interface"; import { DisconnectedEvent } from "~/util/global-events"; -import { - iconChevronRight, - iconDesigner, - iconDownload, - iconExplorer, - iconOpen, - iconPlus, - iconTable, - iconUpload, -} from "~/util/icons"; import { syncConnectionSchema } from "~/util/schema"; import { CreatorDrawer } from "../CreatorDrawer"; import { ExplorerPane } from "../ExplorerPane"; @@ -93,12 +93,19 @@ export function ExplorerView() { return ( <> - + - + - The explorer view provides an easy way to - browse your tables and records without - writing any queries. + The explorer view provides an easy way to browse your tables and + records without writing any queries.