Skip to content

Commit d3fb1f7

Browse files
committed
initial fillStorage
1 parent d93fd24 commit d3fb1f7

File tree

7 files changed

+140
-5
lines changed

7 files changed

+140
-5
lines changed

src/lib/server/db/index.ts

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,12 @@ type QueryWrapper = {
2222

2323
export type QueryResult<T> = { data: T } & QueryWrapper;
2424

25+
export function getCustomerCount(): number {
26+
const stmt = db.prepare(`SELECT COUNT(*) as "cnt" FROM customers`);
27+
const data = stmt.get() as { cnt: number };
28+
return data.cnt;
29+
}
30+
2531
export function getCustomers({ offset = 0, limit = 50 }): QueryResult<Customer[]> {
2632
const stmt = db.prepare(`
2733
SELECT CustomerID as "id"
@@ -40,6 +46,6 @@ export function getCustomers({ offset = 0, limit = 50 }): QueryResult<Customer[]
4046

4147
return {
4248
data,
43-
moreRows: data.length === limit
49+
moreRows: getCustomerCount() > offset + limit
4450
};
4551
}

src/lib/sqlite/initStorages.ts

Lines changed: 42 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,10 @@ import {
44
WorkerMessageTypes,
55
type WorkerMessage,
66
type TableExistsResponseData,
7-
type CreateTableRequestData
7+
type CreateTableRequestData,
8+
type DataRow,
9+
type FillStorageRequestData,
10+
type FillStorageResponseData
811
} from './types';
912

1013
const storages = ['customers_v1'];
@@ -15,6 +18,12 @@ async function getStructure(storage: string): Promise<TableStructure> {
1518
return data;
1619
}
1720

21+
async function getData(storage: string, offset: number, limit: number) {
22+
const res = await fetch(`/api/data/${storage}/data?offset=${offset}&limit=${limit}`);
23+
const data = (await res.json()) as { data: DataRow[]; moreRows: boolean };
24+
return data;
25+
}
26+
1827
async function createStorage(storage: string, structure: TableStructure) {
1928
const res = (await sendMsgToWorker({
2029
storageId: storage,
@@ -26,6 +35,32 @@ async function createStorage(storage: string, structure: TableStructure) {
2635
if (res.data.errorMsg) throw new Error(res.data.errorMsg);
2736
}
2837

38+
async function fillStorage(storage: string, structure: TableStructure) {
39+
const PAGE_SIZE = 100;
40+
let currOffset = 0;
41+
let fetchMore = false;
42+
43+
do {
44+
const { data, moreRows } = await getData(storage, currOffset, PAGE_SIZE);
45+
console.log(`Fetched ${data.length} rows from ${storage} at offset ${currOffset}`, data);
46+
47+
const res = (await sendMsgToWorker({
48+
storageId: storage,
49+
type: WorkerMessageTypes.FILL_STORAGE,
50+
expectedType: WorkerMessageTypes.FILL_STORAGE_RESPONSE,
51+
data: { rows: data, structure: structure } as FillStorageRequestData
52+
})) as WorkerMessage<FillStorageResponseData>;
53+
54+
if (res.data.errorMsg) {
55+
console.error(`Error filling storage ${storage} at offset ${currOffset}`, res.data.errorMsg);
56+
throw new Error(res.data.errorMsg);
57+
}
58+
59+
currOffset += PAGE_SIZE;
60+
fetchMore = moreRows;
61+
} while (fetchMore);
62+
}
63+
2964
export default async function initStorages() {
3065
for (const storageId of storages) {
3166
const res = (await sendMsgToWorker({
@@ -39,10 +74,16 @@ export default async function initStorages() {
3974

4075
if (res.data.tableExists) {
4176
console.log(`Table ${storageId} exists. Has data: ${res.data.hasData}`);
77+
78+
if (!res.data.hasData) {
79+
const structure = await getStructure(storageId);
80+
await fillStorage(storageId, structure);
81+
}
4282
} else {
4383
const structure = await getStructure(storageId);
4484
console.log(`Table ${storageId} does not exist. Creating...`, structure);
4585
await createStorage(storageId, structure);
86+
await fillStorage(storageId, structure);
4687
}
4788
}
4889
}

src/lib/sqlite/types.ts

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,9 +6,13 @@ export enum WorkerMessageTypes {
66
TABLE_EXISTS = 'TABLE_EXISTS',
77
TABLE_EXISTS_RESPONSE = 'TABLE_EXISTS_RESPONSE',
88
CREATE_TABLE = 'CREATE_TABLE',
9-
CREATE_TABLE_RESPONSE = 'CREATE_TABLE_RESPONSE'
9+
CREATE_TABLE_RESPONSE = 'CREATE_TABLE_RESPONSE',
10+
FILL_STORAGE = 'FILL_STORAGE',
11+
FILL_STORAGE_RESPONSE = 'FILL_STORAGE_RESPONSE'
1012
}
1113

14+
export type DataRow = { [key: string]: string | number | boolean | null };
15+
1216
export type WorkerMessageBase = {
1317
messageId: string;
1418
type: WorkerMessageTypes;
@@ -30,3 +34,12 @@ export type CreateTableRequestData = {
3034
export type CreateTableResponseData = {
3135
errorMsg?: string;
3236
};
37+
38+
export type FillStorageRequestData = {
39+
structure: TableStructure;
40+
rows: DataRow[];
41+
};
42+
43+
export type FillStorageResponseData = {
44+
errorMsg?: string;
45+
};

src/lib/sqlite/worker/storageHandlers.ts

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,15 @@
11
import type {
22
CreateTableRequestData,
33
CreateTableResponseData,
4+
FillStorageRequestData,
5+
FillStorageResponseData,
46
TableExistsResponseData,
57
WorkerMessage
68
} from '../types';
79
import { db } from './initDb';
10+
import genInsertSql from './util/genInsertSql';
811
import genTabSrc from './util/genTabSrc';
12+
import getBindObject from './util/getBindObject';
913
import { tableExists, tableHasData } from './util/tableInfo';
1014

1115
export function handleTableExists(data: WorkerMessage<unknown>): TableExistsResponseData {
@@ -53,3 +57,28 @@ export function handleCreateTable(
5357
};
5458
}
5559
}
60+
61+
export function handleFillStorage(
62+
msg: WorkerMessage<FillStorageRequestData>
63+
): FillStorageResponseData {
64+
try {
65+
const { storageId, data } = msg;
66+
const { rows, structure } = data;
67+
68+
const src = genInsertSql(storageId, structure);
69+
console.log('Insert sql:', src);
70+
71+
for (const row of rows) {
72+
db.exec({ sql: src, bind: getBindObject(row) });
73+
}
74+
75+
return {};
76+
} catch (err) {
77+
const msg = `Error filling storage: ${err}`;
78+
console.error(msg);
79+
80+
return {
81+
errorMsg: msg
82+
};
83+
}
84+
}
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
import type { TableStructure } from '../../../../routes/api/data/types';
2+
3+
export default function genInsertSql(storageId: string, structure: TableStructure) {
4+
let statement = `Insert Into ${storageId} (`;
5+
6+
const atomics: string[] = [];
7+
8+
for (const col of structure.columns) {
9+
atomics.push(col.name);
10+
}
11+
12+
statement += ` ${atomics.join(', ')} ) Values ( ${atomics
13+
.map((a) => `$${a}`)
14+
.join(', ')} );`;
15+
16+
return statement;
17+
}
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
import type { DataRow } from '$lib/sqlite/types';
2+
3+
export default function getBindObject(data: DataRow): DataRow {
4+
const bindObject: DataRow = {};
5+
6+
for (const key in data) {
7+
bindObject[`$${key}`] = data[key];
8+
}
9+
10+
return bindObject;
11+
}

src/lib/sqlite/worker/worker.ts

Lines changed: 20 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,10 +4,12 @@ import {
44
type WorkerMessage,
55
type TableExistsResponseData,
66
type CreateTableResponseData,
7-
type CreateTableRequestData
7+
type CreateTableRequestData,
8+
type FillStorageRequestData,
9+
type FillStorageResponseData
810
} from '../types';
911
import { initDb } from './initDb';
10-
import { handleCreateTable, handleTableExists } from './storageHandlers';
12+
import { handleCreateTable, handleFillStorage, handleTableExists } from './storageHandlers';
1113

1214
console.log('worker loaded');
1315

@@ -61,6 +63,22 @@ function sendMsgToMain(obj: WorkerMessage<unknown>) {
6163
};
6264
sendMsgToMain(createTableResult);
6365
break;
66+
67+
case WorkerMessageTypes.FILL_STORAGE:
68+
const fillStorageData = await handleFillStorage(
69+
data as WorkerMessage<FillStorageRequestData>
70+
);
71+
72+
const fillStorageResult: WorkerMessage<FillStorageResponseData> = {
73+
type: WorkerMessageTypes.FILL_STORAGE_RESPONSE,
74+
messageId: data.messageId,
75+
storageId: data.storageId,
76+
data: fillStorageData
77+
};
78+
79+
sendMsgToMain(fillStorageResult);
80+
break;
81+
6482
default:
6583
throw new Error(`Unknown message type: ${data.type}`);
6684
}

0 commit comments

Comments
 (0)