This repository was archived by the owner on Nov 1, 2023. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathsqlite.js
More file actions
124 lines (105 loc) · 2.97 KB
/
sqlite.js
File metadata and controls
124 lines (105 loc) · 2.97 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
import fs from "fs/promises";
import sqlite from "sqlite3";
import url from "url";
const fields = JSON.parse(
await fs.readFile("./fields.json", { encoding: "utf-8" })
)
.filter(({ active }) => active)
.flatMap(({ fields }) => fields)
.map(({ id, names: { sql: name }, tracked }) => ({ id, name, tracked }));
const dir = "output";
const path = `${dir}/mo-vid.sqlite`;
const all = async (db, query, params) =>
new Promise((resolve, reject) => {
db.all(query, params, (err, out) => {
if (err) {
return reject(err);
}
return resolve(out);
});
});
const run = async (db, query, params) =>
new Promise((resolve, reject) => {
db.run(query, params, (err) => {
if (err) {
return reject(err);
}
return resolve();
});
});
const get = async (db, query, params) =>
new Promise((resolve, reject) => {
db.get(query, params, (err, row) => {
if (err) {
return reject(err);
}
return resolve(row);
});
});
const addData = async (dates, data) => {
await fs.mkdir(dir, { recursive: true });
const [updated, start, end] = dates.split(",");
const db = new sqlite.Database(path);
await run(
db,
`CREATE TABLE IF NOT EXISTS mo_vid (updated TEXT, start TEXT, end TEXT, ${fields
.map(({ name }) => name)
.join(" REAL, ")} REAL)`
);
const pragma = await all(db, "PRAGMA table_info(mo_vid)");
const columns = new Set(pragma.map(({ name }) => name));
await Promise.all(
fields.map((field) => {
if (!columns.has(field.name)) {
return run(db, `ALTER TABLE mo_vid ADD COLUMN ${field.name} REAL`);
}
return Promise.resolve();
})
);
const { count } = await get(
db,
"SELECT COUNT(*) as count FROM mo_vid WHERE updated=$updated",
{
$updated: updated,
}
);
const tracked = fields.filter(({ tracked }) => tracked);
if (count === 0) {
const columns = [
"updated",
"start",
"end",
...tracked.map(({ name }) => name),
];
const values = [updated, start, end, ...tracked.map(({ id }) => data[id])];
const query = `INSERT INTO mo_vid (${columns.join(",")}) VALUES (${values
.map(() => "?")
.join(",")})`;
await run(db, query, values);
}
};
export default addData;
const rebuild = async () => {
await fs.unlink(path);
const js = JSON.parse(
await fs.readFile(`${dir}/mo-vid.json`, { encoding: "utf-8" })
).map((data) => ({
dates: [data.updated, data.start, data.end].join(","),
data: Object.keys(data)
.slice(3)
.reduce((o, key, i) => ({ ...o, [fields[i].id]: data[key] }), {}),
}));
for await (const { dates, data } of js) {
await addData(dates, data);
}
};
if (import.meta.url === url.pathToFileURL(process.argv[1]).href) {
rebuild();
}
const db = new sqlite.Database(path);
await run(
db,
`CREATE TABLE IF NOT EXISTS mo_vid (updated TEXT, start TEXT, end TEXT, ${fields
.map(({ name }) => name)
.join(" REAL, ")} REAL)`
);