-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathApp.js
More file actions
142 lines (126 loc) · 3.94 KB
/
App.js
File metadata and controls
142 lines (126 loc) · 3.94 KB
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
import React, { useState, useEffect, useRef } from "react";
import "./styles.css";
import initSqlJs from "sql.js";
import Homepage from "./Homepage";
// Required to let webpack 4 know it needs to copy the wasm file to our assets
import sqlWasm from "!!file-loader?name=sql-wasm-[contenthash].wasm!sql.js/dist/sql-wasm.wasm";
export default function App() {
const [db, setDb] = useState(null);
const [error, setError] = useState(null);
const inputFile = useRef(null)
useEffect(async () => {
// sql.js needs to fetch its wasm file, so we cannot immediately instantiate the database
// without any configuration, initSqlJs will fetch the wasm files directly from the same path as the js
// see ../craco.config.js
if (inputFile) {
try {
const SQL = await initSqlJs({ locateFile: () => sqlWasm });
setDb(new SQL.Database());
} catch (err) {
setError(err);
}
}
}, []);
const handleFileUpload = (event) => {
console.log("handleFileUpload");
inputFile.current = event.target.files[0]; // update the inputFile ref object
const reader = new FileReader();
reader.onload = () => {
const f = event.target.files[0];
const r = new FileReader();
r.onload = function () {
const Uints = new Uint8Array(r.result);
const db = new SQL.Database(Uints);
}
r.readAsArrayBuffer(f);
}
}
// if (error) return <pre>{error.toString()}</pre>;
// else if (!db) return <pre>Loading...</pre>;
// else return <SQLRepl db={db} />;
// return <Homepage />;
// This should go in its own function
if (inputFile.current === useRef(null).current) return <ChooseScreen handleFileUpload={handleFileUpload} inputFile={inputFile} />
else return(
nice
);
}
function ChooseScreen({handleFileUpload, inputFile}) {
return (
<div className="App">
<header className="App-header">
<p>TextGeek</p>
<p>Choose your chat.db file.</p>
{/* Change this to react-native-fs instead of file upload */}
<input type="file" onChange={(event) => handleFileUpload(event)} />
</header>
</div>
);
}
/**
* A simple SQL read-eval-print-loop
* @param {{db: import("sql.js").Database}} props
*/
function SQLRepl({ db }) {
const [error, setError] = useState(null);
const [results, setResults] = useState([]);
function exec(sql) {
try {
// The sql is executed synchronously on the UI thread.
// You may want to use a web worker here instead
setResults(db.exec(sql)); // an array of objects is returned
setError(null);
} catch (err) {
// exec throws an error when the SQL statement is invalid
setError(err);
setResults([]);
}
}
return (
<div className="App">
<h1>React SQL interpreter</h1>
<textarea
onChange={(e) => exec(e.target.value)}
placeholder="Enter some SQL. No inspiration ? Try “select sqlite_version()”"
></textarea>
<pre className="error">{(error || "").toString()}</pre>
<pre>
{
// results contains one object per select statement in the query
results.map(({ columns, values }, i) => (
<ResultsTable key={i} columns={columns} values={values} />
))
}
</pre>
</div>
);
}
/**
* Renders a single value of the array returned by db.exec(...) as a table
* @param {import("sql.js").QueryExecResult} props
*/
function ResultsTable({ columns, values }) {
return (
<table>
<thead>
<tr>
{columns.map((columnName, i) => (
<td key={i}>{columnName}</td>
))}
</tr>
</thead>
<tbody>
{
// values is an array of arrays representing the results of the query
values.map((row, i) => (
<tr key={i}>
{row.map((value, i) => (
<td key={i}>{value}</td>
))}
</tr>
))
}
</tbody>
</table>
);
}