|
|
|
import * as config from './config';
|
|
|
|
import * as sqlite from 'bun:sqlite';
|
|
|
|
|
|
|
|
import { EVENT, SESSION } from './enums';
|
|
|
|
|
|
|
|
// In-memory views
|
|
|
|
export const sessions = {};
|
|
|
|
export const desks = {};
|
|
|
|
|
|
|
|
export const queries = {};
|
|
|
|
export let db = null;
|
|
|
|
|
|
|
|
export function startup() {
|
|
|
|
const path = `${config.DATADIR}/db.sqlite`;
|
|
|
|
|
|
|
|
db = new sqlite.Database(path, { create: true });
|
|
|
|
|
|
|
|
db.query(`CREATE TABLE IF NOT EXISTS desks (
|
|
|
|
id INTEGER PRIMARY KEY,
|
|
|
|
sn INTEGER,
|
|
|
|
title TEXT
|
|
|
|
);`).run();
|
|
|
|
|
|
|
|
db.query(`CREATE TABLE IF NOT EXISTS sessions (
|
|
|
|
id INTEGER PRIMARY KEY,
|
|
|
|
desk_id INTEGER,
|
|
|
|
lsn INTEGER,
|
|
|
|
color INTEGER,
|
|
|
|
width INTEGER,
|
|
|
|
|
|
|
|
FOREIGN KEY (desk_id)
|
|
|
|
REFERENCES desks (id)
|
|
|
|
ON DELETE CASCADE
|
|
|
|
ON UPDATE NO ACTION
|
|
|
|
);`).run();
|
|
|
|
|
|
|
|
db.query(`CREATE TABLE IF NOT EXISTS strokes (
|
|
|
|
id INTEGER PRIMARY KEY,
|
|
|
|
width INTEGER,
|
|
|
|
color INTEGER,
|
|
|
|
points BLOB
|
|
|
|
);`).run();
|
|
|
|
|
|
|
|
db.query(`CREATE TABLE IF NOT EXISTS events (
|
|
|
|
id INTEGER PRIMARY KEY,
|
|
|
|
type INTEGER,
|
|
|
|
desk_id INTEGER,
|
|
|
|
session_id INTEGER,
|
|
|
|
stroke_id INTEGER,
|
|
|
|
image_id INTEGER,
|
|
|
|
x INTEGER,
|
|
|
|
y INTEGER,
|
|
|
|
|
|
|
|
FOREIGN KEY (desk_id)
|
|
|
|
REFERENCES desks (id)
|
|
|
|
ON DELETE CASCADE
|
|
|
|
ON UPDATE NO ACTION
|
|
|
|
|
|
|
|
FOREIGN KEY (session_id)
|
|
|
|
REFERENCES sessions (id)
|
|
|
|
ON DELETE NO ACTION
|
|
|
|
ON UPDATE NO ACTION
|
|
|
|
|
|
|
|
FOREIGN KEY (stroke_id)
|
|
|
|
REFERENCES strokes (id)
|
|
|
|
ON DELETE CASCADE
|
|
|
|
ON UPDATE NO ACTION
|
|
|
|
);`).run();
|
|
|
|
|
|
|
|
// INSERT
|
|
|
|
queries.insert_desk = db.query('INSERT INTO desks (id, title, sn) VALUES ($id, $title, 0)');
|
|
|
|
queries.insert_stroke = db.query('INSERT INTO strokes (id, width, color, points) VALUES ($id, $width, $color, $points) RETURNING id');
|
|
|
|
queries.insert_session = db.query('INSERT INTO sessions (id, desk_id, lsn) VALUES ($id, $desk_id, 0)');
|
|
|
|
queries.insert_event = db.query('INSERT INTO events (type, desk_id, session_id, stroke_id, image_id, x, y) VALUES ($type, $desk_id, $session_id, $stroke_id, $image_id, $x, $y)');
|
|
|
|
|
|
|
|
// UPDATE
|
|
|
|
queries.update_desk_sn = db.query('UPDATE desks SET sn = $sn WHERE id = $id');
|
|
|
|
queries.update_session_lsn = db.query('UPDATE sessions SET lsn = $lsn WHERE id = $id');
|
|
|
|
queries.update_session_color = db.query('UPDATE sessions SET color = $color WHERE id = $id');
|
|
|
|
queries.update_session_width = db.query('UPDATE sessions SET width = $width WHERE id = $id');
|
|
|
|
|
|
|
|
const res1 = db.query('SELECT COUNT(id) as count FROM desks').get();
|
|
|
|
const res2 = db.query('SELECT COUNT(id) as count FROM events').get();
|
|
|
|
const res3 = db.query('SELECT COUNT(id) as count FROM strokes').get();
|
|
|
|
const res4 = db.query('SELECT COUNT(id) as count FROM sessions').get();
|
|
|
|
|
|
|
|
console.log(`Storing data in ${path}`);
|
|
|
|
console.log(`Entity count at startup:
|
|
|
|
${res1.count} desks
|
|
|
|
${res2.count} events
|
|
|
|
${res3.count} strokes
|
|
|
|
${res4.count} sessions
|
|
|
|
`);
|
|
|
|
|
|
|
|
// Init in-memory view: merge strokes into events, set all sessions to closed
|
|
|
|
const stored_desks = db.query('SELECT * FROM desks').all();
|
|
|
|
const stored_events = db.query('SELECT * FROM events').all();
|
|
|
|
const stored_strokes = db.query('SELECT * FROM strokes').all();
|
|
|
|
const stored_sessions = db.query('SELECT * FROM sessions').all();
|
|
|
|
|
|
|
|
const stroke_dict = {};
|
|
|
|
|
|
|
|
for (const stroke of stored_strokes) {
|
|
|
|
stroke.points = new Float32Array(stroke.points.buffer);
|
|
|
|
stroke_dict[stroke.id] = stroke;
|
|
|
|
}
|
|
|
|
|
|
|
|
for (const desk of stored_desks) {
|
|
|
|
desks[desk.id] = desk;
|
|
|
|
desks[desk.id].events = [];
|
|
|
|
}
|
|
|
|
|
|
|
|
for (const event of stored_events) {
|
|
|
|
if (event.type === EVENT.STROKE) {
|
|
|
|
const stroke = stroke_dict[event.stroke_id];
|
|
|
|
event.points = stroke.points;
|
|
|
|
event.color = stroke.color;
|
|
|
|
event.width = stroke.width;
|
|
|
|
}
|
|
|
|
|
|
|
|
desks[event.desk_id].events.push(event);
|
|
|
|
}
|
|
|
|
|
|
|
|
for (const session of stored_sessions) {
|
|
|
|
session.state = SESSION.CLOSED;
|
|
|
|
session.ws = null;
|
|
|
|
sessions[session.id] = session;
|
|
|
|
}
|
|
|
|
}
|