Skip to content

Commit ced2f8e

Browse files
ytkimirtiCahidArda
andauthored
DX-1840: Add WITHTYPE support (#16)
* Revert "DX-1884:removed all types option (#15)" This reverts commit 38a3a39. * feat: add "WITHTYPE" support * fix: remove refetch from context * fix: remove obsolete exact match logic and fix bug with wrong MATCH arguemnt in scan * fix bug with handling redis response --------- Co-authored-by: CahidArda <cahidardaooz@hotmail.com>
1 parent 38a3a39 commit ced2f8e

File tree

10 files changed

+59
-207
lines changed

10 files changed

+59
-207
lines changed

src/components/databrowser/components/sidebar/index.tsx

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ import { Spinner } from "@/components/ui/spinner"
66

77
import { FETCH_LIST_ITEMS_QUERY_KEY, FETCH_SIMPLE_KEY_QUERY_KEY } from "../../hooks"
88
import { FETCH_KEY_TYPE_QUERY_KEY } from "../../hooks/use-fetch-key-type"
9-
import { useKeys } from "../../hooks/use-keys"
9+
import { FETCH_KEYS_QUERY_KEY, useKeys } from "../../hooks/use-keys"
1010
import { AddKeyModal } from "../add-key-modal"
1111
import { DisplayDbSize, FETCH_DB_SIZE_QUERY_KEY } from "./db-size"
1212
import { Empty } from "./empty"
@@ -17,7 +17,7 @@ import { LoadingSkeleton } from "./skeleton-buttons"
1717
import { DataTypeSelector } from "./type-selector"
1818

1919
export function Sidebar() {
20-
const { keys, query, refetch } = useKeys()
20+
const { keys, query } = useKeys()
2121

2222
return (
2323
<div className="flex h-full flex-col gap-2 rounded-xl border bg-white p-1">
@@ -29,7 +29,9 @@ export function Sidebar() {
2929
<Button
3030
className="h-7 w-7 px-0"
3131
onClick={() => {
32-
refetch()
32+
queryClient.invalidateQueries({
33+
queryKey: [FETCH_KEYS_QUERY_KEY],
34+
})
3335
queryClient.invalidateQueries({
3436
queryKey: [FETCH_LIST_ITEMS_QUERY_KEY],
3537
})

src/components/databrowser/components/sidebar/keys-list.tsx

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,9 @@
11
import { useDatabrowserStore } from "@/store"
2-
import type { DataType } from "@/types"
2+
import type { DataType, RedisKey } from "@/types"
33

44
import { cn } from "@/lib/utils"
55
import { Button } from "@/components/ui/button"
66
import { TypeTag } from "@/components/databrowser/components/type-tag"
7-
import type { RedisKey } from "@/components/databrowser/hooks"
87

98
import { useKeys } from "../../hooks/use-keys"
109
import { SidebarContextMenu } from "../sidebar-context-menu"

src/components/databrowser/components/sidebar/type-selector.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ export function DataTypeSelector() {
3232

3333
<SelectContent>
3434
<SelectGroup>
35-
{Object.entries(DATA_TYPE_NAMES).map(
35+
{[[ALL_TYPES_KEY, "All Types"], ...Object.entries(DATA_TYPE_NAMES)].map(
3636
([key, value]) => (
3737
<SelectItem value={key} key={key}>
3838
{value}

src/components/databrowser/hooks/index.ts

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@ export * from "./use-add-key"
22
export * from "./use-debounce"
33
export * from "./use-delete-key"
44
export * from "./use-edit-list-item"
5-
export * from "./use-fetch-keys"
65
export * from "./use-fetch-list-items"
76
export * from "./use-fetch-simple-key"
87
export * from "./use-fetch-ttl"

src/components/databrowser/hooks/use-add-key.ts

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,10 @@
11
import { useDatabrowser } from "@/store"
2-
import type { DataType } from "@/types"
2+
import type { DataType, RedisKey } from "@/types"
33
import { useMutation, type InfiniteData } from "@tanstack/react-query"
44

55
import { queryClient } from "@/lib/clients"
66

77
import { FETCH_DB_SIZE_QUERY_KEY } from "../components/sidebar/db-size"
8-
import { type RedisKey } from "./use-fetch-keys"
98
import { FETCH_KEYS_QUERY_KEY } from "./use-keys"
109

1110
export const useAddKey = () => {

src/components/databrowser/hooks/use-delete-key-cache.ts

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -6,11 +6,10 @@ import { queryClient } from "@/lib/clients"
66
import { FETCH_KEY_TYPE_QUERY_KEY } from "./use-fetch-key-type"
77
import { FETCH_LIST_ITEMS_QUERY_KEY } from "./use-fetch-list-items"
88
import { FETCH_SIMPLE_KEY_QUERY_KEY } from "./use-fetch-simple-key"
9-
import { FETCH_KEYS_QUERY_KEY, useKeys } from "./use-keys"
9+
import { FETCH_KEYS_QUERY_KEY } from "./use-keys"
1010

1111
export const useDeleteKeyCache = () => {
1212
const { setSelectedKey } = useDatabrowserStore()
13-
const { refetch } = useKeys()
1413

1514
const deleteKeyCache = useCallback(
1615
(key: string) => {
@@ -27,9 +26,8 @@ export const useDeleteKeyCache = () => {
2726
queryClient.invalidateQueries({
2827
queryKey: [FETCH_KEY_TYPE_QUERY_KEY, key],
2928
})
30-
refetch()
3129
},
32-
[setSelectedKey, refetch]
30+
[setSelectedKey]
3331
)
3432

3533
return { deleteKeyCache }

src/components/databrowser/hooks/use-fetch-keys.ts

Lines changed: 0 additions & 144 deletions
This file was deleted.

src/components/databrowser/hooks/use-keys.tsx

Lines changed: 46 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -1,73 +1,76 @@
1-
import {
2-
createContext,
3-
useCallback,
4-
useContext,
5-
useMemo,
6-
useRef,
7-
type PropsWithChildren,
8-
} from "react"
9-
import { useDatabrowserStore } from "@/store"
1+
import { createContext, useContext, useMemo, type PropsWithChildren } from "react"
2+
import { useDatabrowser, useDatabrowserStore } from "@/store"
3+
import type { DataType, RedisKey } from "@/types"
104
import { useInfiniteQuery, type UseInfiniteQueryResult } from "@tanstack/react-query"
115

12-
import { useFetchKeyType } from "./use-fetch-key-type"
13-
import { useFetchKeys, type RedisKey } from "./use-fetch-keys"
14-
156
const KeysContext = createContext<
167
| {
178
keys: RedisKey[]
189
query: UseInfiniteQueryResult
19-
refetch: () => void
2010
}
2111
| undefined
2212
>(undefined)
2313

2414
export const FETCH_KEYS_QUERY_KEY = "use-fetch-keys"
2515

16+
const SCAN_COUNT = 100
17+
2618
export const KeysProvider = ({ children }: PropsWithChildren) => {
2719
const { search } = useDatabrowserStore()
28-
const cleanSearchKey = search.key.replace("*", "")
2920

30-
const { data: exactMatchType, isFetching, isLoading } = useFetchKeyType(cleanSearchKey)
31-
32-
const { fetchKeys, resetCache } = useFetchKeys(search)
33-
const pageRef = useRef(0)
21+
const { redisNoPipeline: redis } = useDatabrowser()
3422

3523
const query = useInfiniteQuery({
3624
queryKey: [FETCH_KEYS_QUERY_KEY, search],
3725

38-
initialPageParam: 0,
39-
queryFn: async ({ pageParam: page }) => {
26+
initialPageParam: "0",
27+
queryFn: async ({ pageParam: lastCursor }) => {
4028
// We should reset the cache when the pagination is reset
41-
if (pageRef.current >= page) resetCache()
42-
pageRef.current = page
4329

44-
return await fetchKeys()
30+
const args = [lastCursor]
31+
32+
if (search.key) {
33+
args.push("MATCH", search.key)
34+
}
35+
36+
if (search.type) {
37+
args.push("TYPE", search.type)
38+
}
39+
40+
args.push("COUNT", SCAN_COUNT.toString())
41+
42+
if (!search.type) args.push("WITHTYPE")
43+
44+
const [cursor, values] = await redis.exec<[string, string[]]>(["SCAN", ...args])
45+
const keys: RedisKey[] = []
46+
47+
let index = 0
48+
while (true) {
49+
if (search.type) {
50+
if (index >= values.length) break
51+
keys.push([values[index], search.type as DataType])
52+
index += 1
53+
} else {
54+
if (index + 1 >= values.length) break
55+
keys.push([values[index], values[index + 1] as DataType])
56+
index += 2
57+
}
58+
}
59+
60+
return {
61+
cursor: cursor === "0" ? undefined : cursor,
62+
keys,
63+
hasNextPage: cursor !== "0",
64+
}
4565
},
4666
select: (data) => data,
47-
getNextPageParam: (lastPage, __, lastPageIndex) => {
48-
return lastPage.hasNextPage ? lastPageIndex + 1 : undefined
49-
},
50-
enabled: !isFetching,
67+
getNextPageParam: ({ cursor }) => cursor,
5168
refetchOnMount: false,
5269
})
5370

54-
const refetch = useCallback(() => {
55-
resetCache()
56-
query.refetch()
57-
}, [query, resetCache])
58-
5971
const keys = useMemo(() => {
6072
const keys = query.data?.pages.flatMap((page) => page.keys) ?? []
6173

62-
// Include the exact match if it exists before SCAN returns
63-
if (
64-
exactMatchType &&
65-
exactMatchType !== "none" &&
66-
(search.type === undefined || search.type === exactMatchType)
67-
) {
68-
keys.push([cleanSearchKey, exactMatchType])
69-
}
70-
7174
// deduplication
7275
const keysSet = new Set<string>()
7376
const dedupedKeys: RedisKey[] = []
@@ -79,19 +82,13 @@ export const KeysProvider = ({ children }: PropsWithChildren) => {
7982
dedupedKeys.push(key)
8083
}
8184
return dedupedKeys
82-
}, [query.data, cleanSearchKey, exactMatchType])
85+
}, [query.data])
8386

8487
return (
8588
<KeysContext.Provider
8689
value={{
8790
keys,
88-
// @ts-expect-error Ignore the error with spread syntax
89-
query: {
90-
...query,
91-
isLoading: isLoading || query.isLoading,
92-
isFetching: isFetching || query.isFetching,
93-
},
94-
refetch,
91+
query,
9592
}}
9693
>
9794
{children}

src/store.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -89,7 +89,7 @@ const createDatabrowserStore = () =>
8989
set((old) => ({ ...old, selectedListItem: item }))
9090
},
9191

92-
search: { key: "", type: "string" },
92+
search: { key: "", type: undefined },
9393
setSearch: (search) => set({ search }),
9494
setSearchKey: (key) => set((state) => ({ search: { ...state.search, key } })),
9595
setSearchType: (type) => set((state) => ({ search: { ...state.search, type } })),

src/types/index.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,8 @@ export const DATA_TYPE_NAMES = {
1111

1212
export type DataType = (typeof DATA_TYPES)[number]
1313

14+
export type RedisKey = [string, DataType]
15+
1416
export const LIST_DATA_TYPES = ["set", "zset", "list", "hash", "stream"] as const
1517
export const SIMPLE_DATA_TYPES = ["string", "json"] as const
1618

0 commit comments

Comments
 (0)