-
Notifications
You must be signed in to change notification settings - Fork 0
/
main.js
156 lines (150 loc) · 4.3 KB
/
main.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
const w = new Worker("sqlite3-worker1.js");
window.sqlite3Worker = w;
/**
*
* @param {MessageEvent<any>} event
*/
w.onmessage = function (event) {
event = event.data;
switch (event.type) {
case "sqlite3-api":
if ("worker1-ready" === event.result) {
// The worker is now ready to accept messages
generateNotification("DB is ready.");
break;
}
default: {
// console.log({ event });
}
}
};
const form = /** @type {HTMLFormElement} */ (
document.getElementById("query-form")
);
/**
* @param {SubmitEvent} e
*/
form.onsubmit = async (e) => {
e.preventDefault();
};
const runQueryButton = /** @type {HTMLButtonElement} */ (
document.getElementById("run-query")
);
runQueryButton.onclick = async (e) => {
const query = /** @type {HTMLTextAreaElement} */ (
document.getElementById("query")
);
if (query?.value) {
console.time("userQuery");
await handleSqlInput(query.value);
sendFragmentedMessageToPeers(query.value);
console.timeEnd("userQuery");
return;
}
};
const importFileButton = /** @type {HTMLButtonElement} */ (
document.getElementById("import")
);
importFileButton.onclick = async (e) => {
/**
* @type {HTMLInputElement}
*/
const fileInput = /** @type {HTMLInputElement} */ (
document.getElementById("file_input")
);
/**
* @type {File}
*/
const file = fileInput.files[0];
console.log({ fileType: file.type });
const SUPPORTED_FILE_TYPES = {
CSV: "text/csv",
SQLITE: "application/vnd.sqlite3",
};
if (Object.values(SUPPORTED_FILE_TYPES).includes(file.type) == false) {
alert(`Unsupported file type: ${file.type}`);
return;
}
const reader = new FileReader();
switch (file.type) {
case SUPPORTED_FILE_TYPES.CSV: {
reader.readAsText(file);
reader.onload = async (e) => {
const content = e.target.result; // Get file content
console.time("importCsv");
const { tableName, createTable, insert } = createTableFromCSV(
content,
file.name
);
await handleSqlInput(createTable);
sendFragmentedMessageToPeers(createTable);
await handleSqlInput(insert);
console.timeEnd("importCsv");
generateNotification("Import finished successfully.");
sendFragmentedMessageToPeers(insert);
};
break;
}
case SUPPORTED_FILE_TYPES.SQLITE: {
reader.readAsArrayBuffer(file);
reader.onload = async (e) => {
const root = await navigator.storage.getDirectory();
const fileHandle = await root.removeEntry("db.sqlite3");
const newFile = await root.getFileHandle("db.sqlite3", {
create: true,
});
const writableStream = await newFile.createWritable();
const data = await file.arrayBuffer();
await writableStream.write(data);
await writableStream.close();
generateNotification("Import finished successfully.");
sendFragmentedMessageToPeers(data);
};
break;
}
default: {
console.error(`Unsupported file type: ${file.type}`);
alert(`Unsupported file type: ${file.type}`);
}
}
fileInput.value = "";
};
const exportDBButton = /** @type {HTMLButtonElement} */ (
document.getElementById("export")
);
exportDBButton.onclick = async (e) => {
const root = await navigator.storage.getDirectory();
const fileHandle = await root.getFileHandle("db.sqlite3");
const file = await fileHandle.getFile();
downloadFile(file);
};
/**
* @param {File} file
*/
function downloadFile(file) {
// Create a Blob if you only have a File object
const blob = new Blob([file], { type: file.type });
// Create a link element
const link = document.createElement("a");
// Create a URL for the Blob and set it as the href
const url = URL.createObjectURL(blob);
link.href = url;
// Set the download attribute with a filename
link.download = file.name || "download";
// Append the link to the body (required for Firefox)
document.body.appendChild(link);
// Programmatically click the link to trigger the download
link.click();
// Clean up: remove the link and revoke the object URL
document.body.removeChild(link);
URL.revokeObjectURL(url);
}
/**
* @param {string} query
*/
async function handleSqlInput(query) {
const res = await sql(query);
if (res.resultRows) {
grid(res);
}
}