Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 7d74d94

Browse files
committed
Feat: Status and export
1 parent e42864e commit 7d74d94

File tree

1 file changed

+122
-37
lines changed

1 file changed

+122
-37
lines changed

src/App.svelte

Lines changed: 122 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,22 @@
11
<script>
2-
import { Button } from "flowbite-svelte";
2+
import { Button, ButtonGroup } from "flowbite-svelte";
33
import { Spinner, Alert } from "flowbite-svelte";
44
import { Heading, P, A } from "flowbite-svelte";
55
import { Select, Input, Label, Helper } from "flowbite-svelte";
6+
7+
import { createDbWorker } from "sql.js-httpvfs";
8+
import { PowerTable } from "@muonw/powertable";
9+
import { Sheet, FileJson2 } from "lucide-svelte";
10+
11+
import pTime from "p-time";
12+
import saveAs from "file-saver";
13+
// @ts-ignore
14+
import PapaParse from "papaparse";
15+
import prettyBytes from "pretty-bytes";
16+
import pluralize from "pluralize";
17+
18+
import { CodeJar } from "@novacbn/svelte-codejar";
19+
620
let pageSize = "1024";
721
let pageSizes = [
822
{ value: "512", name: "512" },
@@ -13,12 +27,6 @@
1327
{ value: "16384", name: "16384" },
1428
{ value: "32768", name: "32768" },
1529
];
16-
17-
import { createDbWorker } from "sql.js-httpvfs";
18-
import { PowerTable } from "@muonw/powertable";
19-
import pTime from "p-time";
20-
21-
import { CodeJar } from "@novacbn/svelte-codejar";
2230
let sqlQuery = `SELECT * from titles WHERE title_id LIKE "tt00000%";`;
2331
let dbUrl =
2432
"https://nishad.github.io/sql.js-httpvfs-playground/db/imdb-titles-100000_1024_indexed.db";
@@ -57,20 +65,51 @@
5765
wasmUrl.toString()
5866
);
5967
const result = await worker.db.query(sqlQuery);
60-
return result;
68+
const bytesRead = await worker.worker.bytesRead;
69+
const stats = await worker.worker.getStats();
70+
return { result, bytesRead, stats };
6171
}
6272
6373
let result;
6474
let timeTaken;
75+
let bytesRead;
76+
let querying = false;
77+
let error = false;
78+
let errorMessage = "";
79+
let jsonFile;
80+
let totalBytes;
81+
let totalRequests;
6582
6683
async function runQuery() {
67-
result = pTime(queryDb)();
68-
await result;
69-
timeTaken = result.time;
84+
result = null;
85+
querying = true;
86+
error = false;
87+
let queryData = pTime(queryDb)();
88+
await queryData
89+
.then((data) => {
90+
result = data.result;
91+
timeTaken = queryData.time;
92+
bytesRead = data.bytesRead;
93+
totalRequests = data.stats.totalRequests;
94+
totalBytes = data.stats.totalBytes;
95+
querying = false;
96+
error = false;
97+
jsonFile = new Blob([JSON.stringify(result, null, 2)], {
98+
type: "application/json",
99+
});
100+
})
101+
.catch((queryError) => {
102+
error = true;
103+
errorMessage = queryError.message;
104+
console.log("Query Error: ", queryError.message);
105+
console.log(queryError);
106+
querying = false;
107+
jsonFile = null;
108+
});
70109
}
71110
</script>
72111
73-
<main class="pt-8 pb-16 lg:pt-16 lg:pb-24 bg-white">
112+
<main class="pt-8 pb-12 lg:pt-12 lg:pb-12 bg-white">
74113
<div class=" px-4 mx-auto max-w-screen-xl">
75114
<div class="p-8">
76115
<Heading tag="h2" customeSize="text-4xl font-extrabold "
@@ -102,7 +141,7 @@
102141
</A>
103142
</div>
104143
105-
<div class="p-8">
144+
<div class="p-6">
106145
<Label class="space-y-2">
107146
<span>SQLite DB file URL</span>
108147
<Input type="url" placeholder="" size="md" bind:value={dbUrl} />
@@ -112,38 +151,84 @@
112151
<Select class="mt-2" items={pageSizes} bind:value={pageSize} />
113152
</Label>
114153
</div>
115-
<div class="p-8">
154+
<div class="p-6">
116155
<Label class="space-y-2">
117156
<span>Edit SQL Qery</span>
118157
<CodeJar bind:value={sqlQuery} syntax="sql" {highlight} />
119158
</Label>
120159
</div>
121-
<div class="p-8">
122-
<Button on:click={runQuery}>Query Database</Button>
123-
</div>
124-
{#await result}
125-
<div class="p-8">
126-
<Spinner />
127-
<p>Querying</p>
128-
</div>
129-
{:then data}
130-
{#if data}
131-
{#if timeTaken}
132-
<div class="p-8 mt-2">
133-
<Alert>
134-
Query took <span class="font-medium">{timeTaken}</span> ms
135-
</Alert>
136-
</div>
160+
<div class="p-6">
161+
<Button on:click={runQuery}>
162+
{#if querying}
163+
<Spinner class="mr-3" size="4" color="white" /> Querying ...
164+
{:else}
165+
Run Query
137166
{/if}
138-
<div class="p-8">
139-
<div class="MuonW PowerTable">
140-
<PowerTable ptData={data} {ptOptions} />
141-
</div>
167+
</Button>
168+
</div>
169+
170+
{#if result}
171+
{#if timeTaken}
172+
<div class="p-6 mt-2">
173+
<Alert>
174+
Query took <span class="font-medium">{timeTaken}</span> ms to read
175+
<span class="font-medium">{prettyBytes(bytesRead)}</span>
176+
with
177+
<span class="font-medium">{totalRequests}</span> requests from the
178+
database of
179+
<span class="font-medium">{prettyBytes(totalBytes)}</span>, and
180+
returned
181+
<span class="font-medium">
182+
{pluralize("row", result.length, true)}</span
183+
>
184+
equivalent to
185+
<span class="font-medium">{prettyBytes(jsonFile.size)}</span> of JSON.
186+
</Alert>
142187
</div>
143188
{/if}
144-
{:catch error}
145-
<p style="color: red">{error.message}</p>
146-
{/await}
189+
<div class="p-6">
190+
<div class="MuonW PowerTable">
191+
<PowerTable ptData={result} {ptOptions} />
192+
</div>
193+
</div>
194+
195+
<div class="p-4">
196+
<ButtonGroup>
197+
<Button
198+
color="light"
199+
size="xs"
200+
on:click={() => {
201+
const blob = jsonFile;
202+
saveAs(blob, "result.json");
203+
}}
204+
>
205+
<FileJson2 />
206+
Download as JSON
207+
</Button>
208+
<Button
209+
color="light"
210+
size="xs"
211+
on:click={() => {
212+
const blob = new Blob([PapaParse.unparse(result)], {
213+
type: "text/csv",
214+
});
215+
saveAs(blob, "result.csv");
216+
}}
217+
>
218+
<Sheet />
219+
Download as CSV
220+
</Button>
221+
</ButtonGroup>
222+
</div>
223+
{/if}
224+
{#if error}
225+
<div class="p-6 mt-2">
226+
<Alert color="red">
227+
<span class="font-medium">Error:</span>
228+
{errorMessage}
229+
</Alert>
230+
</div>
231+
{/if}
147232
</div>
148233
</main>
149234

0 commit comments

Comments
 (0)