Skip to content
This repository was archived by the owner on Jul 2, 2024. It is now read-only.

Commit 0dc1d34

Browse files
committed
Render performance for big sqlite files
1 parent 214b2f0 commit 0dc1d34

File tree

8 files changed

+139
-74
lines changed

8 files changed

+139
-74
lines changed

README.md

Lines changed: 7 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
1-
SQLite Viewer GUI Program written in Rust using Tauri + NextJS
1+
# SQLite Viewer V0.4
22

33
[ TODO LIST ]
44

55
- [ ] Make a web version ( if possible )
66
- [ ] Add Linux and MacOS Builds
77
- [ ] Handle Sqlite with password
8-
- [ ] Render performance for big sqlite files
8+
- [x] Render performance for big sqlite files
99
- [x] Execute SQL command tab
1010
- [x] Schema Generator
1111
- [ ] Sort by column
@@ -17,23 +17,19 @@ SQLite Viewer GUI Program written in Rust using Tauri + NextJS
1717

1818
**1- Browse All Your SQLite Tables.**
1919

20-
![photo](https://i.ibb.co/SBzVnFX/Browse.png)
20+
![photo](https://i.ibb.co/ZYJSDwx/brow.png)
2121

2222
**2- Database Structure View.**
2323

24-
![photo](https://i.ibb.co/8zGSBHN/Struct.png)
24+
![photo](https://i.ibb.co/fCGJVMk/stuct.png)
2525

2626
**3- Execute SQL Commands**
2727

28-
![photo](https://i.ibb.co/SnTXqwy/execute.png)
28+
![photo](https://i.ibb.co/JnMy5cH/execute.png)
2929

30-
**4- Errors are easy to recognize**
30+
**4- Light and Dark mode**
3131

32-
![photo](https://i.ibb.co/Xtb0pZT/error.png)
33-
34-
**5- Light and Dark mode**
35-
36-
![photo](https://i.ibb.co/XpC9Mwm/image.png)
32+
![photo](https://i.ibb.co/tP84yCS/light.png)
3733

3834
##
3935

src-tauri/tauri.conf.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -63,8 +63,8 @@
6363
"windows": [
6464
{
6565
"fullscreen": false,
66-
"height": 600,
67-
"minHeight": 600,
66+
"height": 630,
67+
"minHeight": 630,
6868
"resizable": true,
6969
"title": "SQLite Viewer",
7070
"width": 800,

src/app/browse.tsx

Lines changed: 92 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
"use client";
22

3+
import { useState } from "react";
34
import { Columns } from "@/types";
45
import { SetStateAction } from "react";
56
import {
@@ -27,8 +28,25 @@ interface BrowseProps {
2728
records: Columns;
2829
}
2930

31+
const ROWS_PER_PAGE = 100;
32+
3033
export default function Browse(props: BrowseProps) {
3134
const { setSelectedTable, tables, selectedTable, records } = props;
35+
const [currentPage, setCurrentPage] = useState(1);
36+
37+
const startIndex = (currentPage - 1) * ROWS_PER_PAGE;
38+
const endIndex = startIndex + ROWS_PER_PAGE;
39+
40+
const totalPages = Math.ceil(
41+
// @ts-ignore
42+
records[selectedTable]?.[Object.keys(records[selectedTable])[0]]?.length /
43+
ROWS_PER_PAGE
44+
);
45+
46+
const handleChangePage = (page: number) => {
47+
setCurrentPage(page);
48+
};
49+
3250
return (
3351
<div className="w-full">
3452
<div className="px-2 flex gap-2 items-center">
@@ -62,35 +80,83 @@ export default function Browse(props: BrowseProps) {
6280
</div>
6381
<div className="mt-2 h-[420px] overflow-auto">
6482
{selectedTable && records[selectedTable] && (
65-
<Table>
66-
<TableHeader>
67-
<TableRow>
68-
{Object.keys(records[selectedTable]).map((column, index) => (
69-
<TableHead key={index}>{column}</TableHead>
70-
))}
71-
</TableRow>
72-
</TableHeader>
73-
<TableBody>
74-
{records[selectedTable][
75-
Object.keys(records[selectedTable])[0]
76-
].map((_, rowIndex) => (
77-
<TableRow key={rowIndex}>
78-
{Object.keys(records[selectedTable]).map(
79-
(column, columnIndex) => (
80-
<TableCell
81-
key={columnIndex}
82-
className="max-w-[150px] truncate hover:max-w-full"
83-
>
84-
<span>{records[selectedTable][column][rowIndex]}</span>
85-
</TableCell>
86-
)
87-
)}
83+
<>
84+
<Table>
85+
<TableHeader>
86+
<TableRow>
87+
{Object.keys(records[selectedTable]).map((column, index) => (
88+
<TableHead key={index}>{column}</TableHead>
89+
))}
8890
</TableRow>
89-
))}
90-
</TableBody>
91-
</Table>
91+
</TableHeader>
92+
<TableBody>
93+
{records[selectedTable][Object.keys(records[selectedTable])[0]]
94+
.slice(startIndex, endIndex)
95+
.map((_, rowIndex) => (
96+
<TableRow key={rowIndex}>
97+
{Object.keys(records[selectedTable]).map(
98+
(column, columnIndex) => (
99+
<TableCell
100+
key={columnIndex}
101+
className="max-w-[150px] truncate"
102+
>
103+
<span>
104+
{
105+
records[selectedTable][column][
106+
rowIndex + startIndex
107+
]
108+
}
109+
</span>
110+
</TableCell>
111+
)
112+
)}
113+
</TableRow>
114+
))}
115+
</TableBody>
116+
</Table>
117+
</>
92118
)}
93119
</div>
120+
<Pagination
121+
currentPage={currentPage}
122+
totalPages={totalPages}
123+
onPageChange={handleChangePage}
124+
/>
94125
</div>
95126
);
96127
}
128+
129+
interface PaginationProps {
130+
currentPage: number;
131+
totalPages: number;
132+
onPageChange: (page: number) => void;
133+
}
134+
135+
const Pagination: React.FC<PaginationProps> = ({
136+
currentPage,
137+
totalPages,
138+
onPageChange,
139+
}) => {
140+
// @ts-ignore
141+
const pageNumbers = [...Array(totalPages).keys()].map((num) => num + 1);
142+
143+
return (
144+
<ul className="flex overflow-x-scroll">
145+
{pageNumbers.map((page) => (
146+
<li
147+
key={page}
148+
className={`grow ${
149+
currentPage === page ? "bg-primary text-background" : "bg-secondary"
150+
}`}
151+
>
152+
<button
153+
className={`page-link p-2 text-center w-full`}
154+
onClick={() => onPageChange(page)}
155+
>
156+
{page}
157+
</button>
158+
</li>
159+
))}
160+
</ul>
161+
);
162+
};

src/app/execute.tsx

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -68,10 +68,7 @@ export default function ExecuteSQL({ table }: { table: string }) {
6868
{result.map((row, index) => (
6969
<TableRow key={index}>
7070
{Object.values(row).map((value, index) => (
71-
<TableCell
72-
key={index}
73-
className="max-w-[150px] truncate hover:max-w-full"
74-
>
71+
<TableCell key={index} className="max-w-[150px] truncate">
7572
{value}
7673
</TableCell>
7774
))}

src/app/layout.tsx

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -26,10 +26,12 @@ export default function RootLayout({
2626
disableTransitionOnChange
2727
>
2828
{children}
29-
<footer className="p-4 fixed bottom-0 w-full bg-background">
29+
<footer className="p-4 fixed bottom-0 w-full bg-background border-t border-secondary">
3030
<div className="flex justify-between items-center">
3131
<Toggle />
32-
SQLite Viewer V0.3
32+
<span className="hover:animate-bounce animate-pulse">
33+
SQLite Viewer V0.4
34+
</span>
3335
</div>
3436
</footer>
3537
</ThemeProvider>

src/app/load.tsx

Lines changed: 31 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -59,33 +59,37 @@ export default function Load({ path }: { path: string }) {
5959

6060
return (
6161
<div className="w-full">
62-
<Tabs defaultValue="structure">
63-
<TabsList className="w-full flex gap-2">
64-
<TabsTrigger value="structure" className="grow">
65-
Structure
66-
</TabsTrigger>
67-
<TabsTrigger value="browse" className="grow">
68-
Browse Data
69-
</TabsTrigger>
70-
<TabsTrigger value="execute" className="grow">
71-
Execute SQL
72-
</TabsTrigger>
73-
</TabsList>
74-
<TabsContent value="structure">
75-
<Structure tablesInfo={tablesInfo} />
76-
</TabsContent>
77-
<TabsContent value="browse">
78-
<Browse
79-
tables={tables}
80-
selectedTable={selectedTable}
81-
records={records}
82-
setSelectedTable={setSelectedTable}
83-
/>
84-
</TabsContent>
85-
<TabsContent value="execute">
86-
<ExecuteSQL table={tables[0]} />
87-
</TabsContent>
88-
</Tabs>
62+
{selectedTable ? (
63+
<Tabs defaultValue="structure">
64+
<TabsList className="w-full flex gap-2">
65+
<TabsTrigger value="structure" className="grow">
66+
Structure
67+
</TabsTrigger>
68+
<TabsTrigger value="browse" className="grow">
69+
Browse Data
70+
</TabsTrigger>
71+
<TabsTrigger value="execute" className="grow">
72+
Execute SQL
73+
</TabsTrigger>
74+
</TabsList>
75+
<TabsContent value="structure">
76+
<Structure tablesInfo={tablesInfo} />
77+
</TabsContent>
78+
<TabsContent value="browse">
79+
<Browse
80+
tables={tables}
81+
selectedTable={selectedTable}
82+
records={records}
83+
setSelectedTable={setSelectedTable}
84+
/>
85+
</TabsContent>
86+
<TabsContent value="execute">
87+
<ExecuteSQL table={tables[0]} />
88+
</TabsContent>
89+
</Tabs>
90+
) : (
91+
<h1 className="text-2xl w-full mt-20 text-center">Loading Data..</h1>
92+
)}
8993
</div>
9094
);
9195
}

src/app/structure.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ import {
1919
export default function Structure({ tablesInfo }: { tablesInfo: TableInfos }) {
2020
return (
2121
<div className="w-full">
22-
<Accordion type="single" collapsible className="w-full">
22+
<Accordion type="multiple" className="w-full">
2323
{Object.keys(tablesInfo).map((table, index) => (
2424
<div key={index} className="flex flex-col">
2525
<AccordionItem value={table}>

src/components/theme/toggle.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ export default function Toggle() {
2222
<span className="sr-only">Toggle theme</span>
2323
</Button>
2424
</DropdownMenuTrigger>
25-
<DropdownMenuContent align="end">
25+
<DropdownMenuContent align="start">
2626
<DropdownMenuItem onClick={() => setTheme("light")}>
2727
Light
2828
</DropdownMenuItem>

0 commit comments

Comments
 (0)