You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 

140 lines
4.7 KiB

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,
pressures 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) RETURNING id');
queries.insert_stroke = db.query('INSERT INTO strokes (width, color, points, pressures) VALUES ($width, $color, $points, $pressures) RETURNING id');
queries.insert_session = db.query('INSERT INTO sessions (id, desk_id, lsn) VALUES ($id, $desk_id, 0) RETURNING id');
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) RETURNING id');
// 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 desk of stored_desks) {
desks[desk.id] = desk;
desks[desk.id].events = [];
desks[desk.id].total_points = 0;
}
for (const stroke of stored_strokes) {
stroke.points = new Float32Array(stroke.points.buffer);
stroke_dict[stroke.id] = stroke;
}
for (const event of stored_events) {
if (event.type === EVENT.STROKE) {
const stroke = stroke_dict[event.stroke_id];
event.points = stroke.points;
event.pressures = stroke.pressures;
event.color = stroke.color;
event.width = stroke.width;
desks[event.desk_id].total_points += stroke.points.length / 2;
}
desks[event.desk_id].events.push(event);
}
for (const desk of stored_desks) {
desk.sn = desk.events.length;
}
for (const session of stored_sessions) {
session.state = SESSION.CLOSED;
session.ws = null;
session.sync_attempts = 0;
session.follow = null;
sessions[session.id] = session;
}
}