Skip to content

Commit 11da7f5

Browse files
committed
add handler to query storages
1 parent e65b751 commit 11da7f5

File tree

9 files changed

+446
-235
lines changed

9 files changed

+446
-235
lines changed

package.json

Lines changed: 13 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -13,26 +13,26 @@
1313
},
1414
"devDependencies": {
1515
"@rgossiaux/svelte-headlessui": "^1.0.2",
16-
"@sveltejs/adapter-auto": "^2.0.0",
17-
"@sveltejs/kit": "^1.15.0",
16+
"@sveltejs/adapter-auto": "^2.0.1",
17+
"@sveltejs/kit": "^1.16.2",
1818
"@types/better-sqlite3": "^7.6.4",
19-
"@typescript-eslint/eslint-plugin": "^5.57.0",
20-
"@typescript-eslint/parser": "^5.57.0",
19+
"@typescript-eslint/eslint-plugin": "^5.59.2",
20+
"@typescript-eslint/parser": "^5.59.2",
2121
"autoprefixer": "^10.4.14",
22-
"eslint": "^8.37.0",
22+
"eslint": "^8.40.0",
2323
"eslint-config-prettier": "^8.8.0",
2424
"eslint-plugin-svelte3": "^4.0.0",
25-
"postcss": "^8.4.21",
26-
"prettier": "^2.8.7",
25+
"postcss": "^8.4.23",
26+
"prettier": "^2.8.8",
2727
"prettier-plugin-svelte": "^2.10.0",
28-
"svelte": "^3.58.0",
29-
"svelte-check": "^3.1.4",
30-
"tailwindcss": "^3.3.1",
28+
"svelte": "^3.59.0",
29+
"svelte-check": "^3.3.1",
30+
"tailwindcss": "^3.3.2",
3131
"tslib": "^2.5.0",
32-
"typescript": "^5.0.3",
33-
"vite": "^4.2.1",
32+
"typescript": "^5.0.4",
33+
"vite": "^4.3.5",
3434
"vite-plugin-cross-origin-isolation": "^0.1.6",
35-
"vite-plugin-mkcert": "^1.14.0"
35+
"vite-plugin-mkcert": "^1.15.0"
3636
},
3737
"type": "module",
3838
"packageManager": "yarn@3.5.0",

src/lib/sqlite/dataApi.ts

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
import { sendMsgToWorker } from './messageBus';
2+
import {
3+
WorkerMessageTypes,
4+
type DataRow,
5+
type QueryRequestData,
6+
type QueryResponseData
7+
} from './types';
8+
9+
export async function runQuery(sql: string): Promise<DataRow[]> {
10+
const res = await sendMsgToWorker({
11+
storageId: 'generic',
12+
type: WorkerMessageTypes.QUERY,
13+
data: {
14+
sql: sql
15+
} as QueryRequestData,
16+
expectedType: WorkerMessageTypes.QUERY_RESPONSE
17+
});
18+
19+
const data = res.data as QueryResponseData;
20+
21+
if (data?.errorMsg) throw new Error(data.errorMsg);
22+
23+
return data.rows;
24+
}

src/lib/sqlite/initStorages.ts

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,33 @@ async function fillStorage(storage: string, structure: TableStructure) {
6565
console.timeEnd(`fillStorage-${storage}`);
6666
}
6767

68+
const readyStorages = new Set<string>();
69+
const storageCbs = new Map<string, (() => void)[]>();
70+
71+
function storageIsReady(storageId: string) {
72+
readyStorages.add(storageId);
73+
74+
if (storageCbs.has(storageId)) {
75+
const cbs = storageCbs.get(storageId);
76+
cbs?.forEach((cb) => cb());
77+
storageCbs.delete(storageId);
78+
}
79+
}
80+
81+
export function waitTillStroageReady(storageId: string) {
82+
return new Promise<void>((resolve) => {
83+
if (readyStorages.has(storageId)) {
84+
resolve();
85+
} else {
86+
if (!storageCbs.has(storageId)) {
87+
storageCbs.set(storageId, [resolve]);
88+
} else {
89+
storageCbs.get(storageId)?.push(resolve);
90+
}
91+
}
92+
});
93+
}
94+
6895
export default async function initStorages() {
6996
for (const storageId of storages) {
7097
const res = (await sendMsgToWorker({
@@ -89,5 +116,7 @@ export default async function initStorages() {
89116
await createStorage(storageId, structure);
90117
await fillStorage(storageId, structure);
91118
}
119+
120+
storageIsReady(storageId);
92121
}
93122
}

src/lib/sqlite/types.ts

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,9 @@ export enum WorkerMessageTypes {
88
CREATE_TABLE = 'CREATE_TABLE',
99
CREATE_TABLE_RESPONSE = 'CREATE_TABLE_RESPONSE',
1010
FILL_STORAGE = 'FILL_STORAGE',
11-
FILL_STORAGE_RESPONSE = 'FILL_STORAGE_RESPONSE'
11+
FILL_STORAGE_RESPONSE = 'FILL_STORAGE_RESPONSE',
12+
QUERY = 'QUERY',
13+
QUERY_RESPONSE = 'QUERY_RESPONSE'
1214
}
1315

1416
export type DataRow = { [key: string]: string | number | boolean | null };
@@ -43,3 +45,12 @@ export type FillStorageRequestData = {
4345
export type FillStorageResponseData = {
4446
errorMsg?: string;
4547
};
48+
49+
export type QueryRequestData = {
50+
sql: string;
51+
};
52+
53+
export type QueryResponseData = {
54+
rows: DataRow[];
55+
errorMsg?: string;
56+
};
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
import getErrorMessage from '$lib/util/getErrorMsg';
2+
import type { DataRow, QueryRequestData, QueryResponseData, WorkerMessage } from '../types';
3+
import { db } from './initDb';
4+
5+
export function handleQuery(msg: WorkerMessage<QueryRequestData>): QueryResponseData {
6+
try {
7+
console.log('sql', msg.data);
8+
9+
let data: DataRow[] = [];
10+
11+
try {
12+
db.transaction(() => {
13+
data = db.selectObjects(msg.data.sql);
14+
throw new Error('force rollback');
15+
});
16+
} catch (err) {
17+
if (getErrorMessage(err) !== 'force rollback') {
18+
throw err;
19+
}
20+
}
21+
22+
return {
23+
rows: data
24+
};
25+
} catch (err) {
26+
const msg = `Error running query: ${err}`;
27+
console.error(msg);
28+
29+
return {
30+
rows: [],
31+
errorMsg: msg
32+
};
33+
}
34+
}

src/lib/sqlite/worker/worker.ts

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,11 @@ import {
66
type CreateTableResponseData,
77
type CreateTableRequestData,
88
type FillStorageRequestData,
9-
type FillStorageResponseData
9+
type FillStorageResponseData,
10+
type QueryRequestData,
11+
type QueryResponseData
1012
} from '../types';
13+
import { handleQuery } from './handleQuery';
1114
import { initDb } from './initDb';
1215
import { handleCreateTable, handleFillStorage, handleTableExists } from './storageHandlers';
1316

@@ -23,7 +26,7 @@ function sendMsgToMain(obj: WorkerMessage<unknown>) {
2326

2427
switch (data.type) {
2528
case WorkerMessageTypes.INIT_DB:
26-
await import('../jswasm/sqlite3.mjs');
29+
await import('../jswasm/sqlite3-bundler-friendly.mjs');
2730

2831
const initRes = await initDb();
2932
console.log('worker initDb result:', initRes);
@@ -79,6 +82,18 @@ function sendMsgToMain(obj: WorkerMessage<unknown>) {
7982
sendMsgToMain(fillStorageResult);
8083
break;
8184

85+
case WorkerMessageTypes.QUERY:
86+
const queryData = await handleQuery(data as WorkerMessage<QueryRequestData>);
87+
const queryResult: WorkerMessage<QueryResponseData> = {
88+
type: WorkerMessageTypes.QUERY_RESPONSE,
89+
messageId: data.messageId,
90+
storageId: data.storageId,
91+
data: queryData
92+
};
93+
94+
sendMsgToMain(queryResult);
95+
break;
96+
8297
default:
8398
throw new Error(`Unknown message type: ${data.type}`);
8499
}

src/lib/util/getErrorMsg.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
export default function getErrorMessage(error: unknown) {
2+
if (error instanceof Error) return error.message;
3+
return String(error);
4+
}

src/routes/+page.svelte

Lines changed: 22 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,22 @@
1-
<h1 class="text-5xl text-teal-500">Welcome to SvelteKit</h1>
2-
<p>Visit <a href="https://kit.svelte.dev">kit.svelte.dev</a> to read the documentation</p>
1+
<script lang="ts">
2+
import { runQuery } from '$lib/sqlite/dataApi';
3+
import { waitTillStroageReady } from '$lib/sqlite/initStorages';
4+
import { onMount } from 'svelte';
5+
6+
let storageReady = false;
7+
8+
onMount(async () => {
9+
await waitTillStroageReady('customers_v1');
10+
storageReady = true;
11+
const data = await runQuery(`update customers_v1 set company = 'xyz' where 1 = 1`);
12+
console.log(data);
13+
const data2 = await runQuery('SELECT * FROM customers_v1 limit 10');
14+
console.log(data2);
15+
});
16+
</script>
17+
18+
<h1 class="text-5xl text-teal-500">SvelteKit Offline SQLite</h1>
19+
20+
<div>
21+
Storage Ready: {storageReady ? 'true' : 'false'}
22+
</div>

0 commit comments

Comments
 (0)