|
|
|
import * as config from './config';
|
|
|
|
import * as sqlite from 'bun:sqlite';
|
|
|
|
|
|
|
|
import { EVENT, SESSION } from './enums';
|
|
|
|
|
|
|
|
export const sessions = {};
|
|
|
|
export const desks = {};
|
|
|
|
|
|
|
|
let db = null;
|
|
|
|
const queries = {};
|
|
|
|
|
|
|
|
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 users (
|
|
|
|
id INTEGER PRIMARY KEY,
|
|
|
|
login TEXT
|
|
|
|
);`).run();
|
|
|
|
|
|
|
|
db.query(`CREATE TABLE IF NOT EXISTS sessions (
|
|
|
|
id INTEGER PRIMARY KEY,
|
|
|
|
user_id INTEGER,
|
|
|
|
desk_id INTEGER,
|
|
|
|
lsn INTEGER,
|
|
|
|
|
|
|
|
FOREIGN KEY (user_id)
|
|
|
|
REFERENCES users (id)
|
|
|
|
ON DELETE CASCADE
|
|
|
|
ON UPDATE NO ACTION,
|
|
|
|
|
|
|
|
FOREIGN KEY (desk_id)
|
|
|
|
REFERENCES desks (id)
|
|
|
|
ON DELETE CASCADE
|
|
|
|
ON UPDATE NO ACTION
|
|
|
|
);`).run();
|
|
|
|
|
|
|
|
db.query(`CREATE TABLE IF NOT EXISTS images (
|
|
|
|
id INTEGER PRIMARY KEY,
|
|
|
|
desk_id 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,
|
|
|
|
desk_id INTEGER,
|
|
|
|
points BLOB,
|
|
|
|
width INTEGER,
|
|
|
|
color INTEGER,
|
|
|
|
|
|
|
|
FOREIGN KEY (desk_id)
|
|
|
|
REFERENCES desks (id)
|
|
|
|
ON DELETE CASCADE
|
|
|
|
ON UPDATE NO ACTION
|
|
|
|
);`).run();
|
|
|
|
|
|
|
|
db.query(`CREATE TABLE IF NOT EXISTS events (
|
|
|
|
id INTEGER PRIMARY KEY,
|
|
|
|
type INTEGER,
|
|
|
|
desk_id INTEGER,
|
|
|
|
user_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 (user_id)
|
|
|
|
REFERENCES users (id)
|
|
|
|
ON DELETE CASCADE
|
|
|
|
ON UPDATE NO ACTION
|
|
|
|
|
|
|
|
FOREIGN KEY (stroke_id)
|
|
|
|
REFERENCES strokes (id)
|
|
|
|
ON DELETE CASCADE
|
|
|
|
ON UPDATE NO ACTION
|
|
|
|
|
|
|
|
FOREIGN KEY (image_id)
|
|
|
|
REFERENCES images (id)
|
|
|
|
ON DELETE CASCADE
|
|
|
|
ON UPDATE NO ACTION
|
|
|
|
);`).run();
|
|
|
|
|
|
|
|
db.query(`CREATE INDEX IF NOT EXISTS idx_events_desk_id
|
|
|
|
ON events (desk_id);
|
|
|
|
`).run();
|
|
|
|
|
|
|
|
db.query(`CREATE INDEX IF NOT EXISTS idx_strokes_desk_id
|
|
|
|
ON strokes (desk_id);
|
|
|
|
`).run();
|
|
|
|
|
|
|
|
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 users').get();
|
|
|
|
const res5 = db.query('SELECT COUNT(id) as count FROM sessions').get();
|
|
|
|
const res6 = db.query('SELECT COUNT(id) as count FROM images').get();
|
|
|
|
|
|
|
|
queries.desks = db.query('SELECT id, sn FROM desks');
|
|
|
|
queries.events = db.query('SELECT * FROM events');
|
|
|
|
queries.sessions = db.query('SELECT id, lsn, user_id, desk_id FROM sessions');
|
|
|
|
queries.strokes = db.query('SELECT * FROM strokes');
|
|
|
|
queries.empty_desk = db.query('INSERT INTO desks (id, title, sn) VALUES (?1, ?2, 0)');
|
|
|
|
queries.desk_strokes = db.query('SELECT id, points FROM strokes WHERE desk_id = ?1');
|
|
|
|
queries.put_desk_stroke = db.query('INSERT INTO strokes (id, desk_id, points, width, color) VALUES (?1, ?2, ?3, ?4, ?5)');
|
|
|
|
queries.clear_desk_events = db.query('DELETE FROM events WHERE desk_id = ?1');
|
|
|
|
queries.set_desk_sn = db.query('UPDATE desks SET sn = ?1 WHERE id = ?2');
|
|
|
|
queries.save_session_lsn = db.query('UPDATE sessions SET lsn = ?1 WHERE id = ?2');
|
|
|
|
queries.create_session = db.query('INSERT INTO sessions (id, lsn, user_id, desk_id) VALUES (?1, 0, ?2, ?3)');
|
|
|
|
queries.create_user = db.query('INSERT INTO users (id, login) VALUES (?1, ?2)');
|
|
|
|
queries.put_event = db.query('INSERT INTO events (type, desk_id, user_id, stroke_id, image_id, x, y) VALUES (?1, ?2, ?3, ?4, ?5, ?6, ?7)');
|
|
|
|
queries.put_image = db.query('INSERT INTO images (id, desk_id) VALUES (?1, ?2)');
|
|
|
|
|
|
|
|
console.log(`Storing data in ${path}`);
|
|
|
|
console.log(`Entity count at startup:
|
|
|
|
${res1.count} desks
|
|
|
|
${res2.count} events
|
|
|
|
${res3.count} strokes
|
|
|
|
${res4.count} users
|
|
|
|
${res5.count} sessions
|
|
|
|
${res6.count} images`
|
|
|
|
);
|
|
|
|
|
|
|
|
const stored_desks = get_desks();
|
|
|
|
const stored_events = get_events();
|
|
|
|
const stored_strokes = get_strokes();
|
|
|
|
const stored_sessions = get_sessions();
|
|
|
|
|
|
|
|
const stroke_dict = {};
|
|
|
|
|
|
|
|
for (const stroke of stored_strokes) {
|
|
|
|
stroke.points = new Uint16Array(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;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
export function get_strokes() {
|
|
|
|
return queries.strokes.all();
|
|
|
|
}
|
|
|
|
|
|
|
|
export function get_sessions() {
|
|
|
|
return queries.sessions.all();
|
|
|
|
}
|
|
|
|
|
|
|
|
export function get_desks() {
|
|
|
|
return queries.desks.all();
|
|
|
|
}
|
|
|
|
|
|
|
|
export function get_events() {
|
|
|
|
return queries.events.all();
|
|
|
|
}
|
|
|
|
|
|
|
|
export function get_desk_strokes(desk_id) {
|
|
|
|
return queries.desk_strokes.all(desk_id);
|
|
|
|
}
|
|
|
|
|
|
|
|
export function put_event(event) {
|
|
|
|
return queries.put_event.get(event.type, event.desk_id || 0, event.user_id || 0, event.stroke_id || 0, event.image_id || 0, event.x || 0, event.y || 0);
|
|
|
|
}
|
|
|
|
|
|
|
|
export function put_stroke(stroke_id, desk_id, points, width, color) {
|
|
|
|
return queries.put_desk_stroke.get(stroke_id, desk_id, new Uint8Array(points.buffer, points.byteOffset, points.byteLength), width, color);
|
|
|
|
}
|
|
|
|
|
|
|
|
export function clear_events(desk_id) {
|
|
|
|
return queries.clear_desk_events.get(desk_id);
|
|
|
|
}
|
|
|
|
|
|
|
|
export function create_desk(desk_id, title = 'untitled') {
|
|
|
|
return queries.empty_desk.get(desk_id, title);
|
|
|
|
}
|
|
|
|
|
|
|
|
export function save_desk_sn(desk_id, sn) {
|
|
|
|
return queries.set_desk_sn.get(sn, desk_id);
|
|
|
|
}
|
|
|
|
|
|
|
|
export function create_session(session) {
|
|
|
|
return queries.create_session.get(session.id, session.user_id, session.desk_id);
|
|
|
|
}
|
|
|
|
|
|
|
|
export function create_user(user) {
|
|
|
|
return queries.create_user.get(user.id, user.login);
|
|
|
|
}
|
|
|
|
|
|
|
|
export function save_session_lsn(session_id, lsn) {
|
|
|
|
return queries.save_session_lsn.get(lsn, session_id);
|
|
|
|
}
|
|
|
|
|
|
|
|
export function put_image(image_id, desk_id) {
|
|
|
|
return queries.put_image.get(image_id, desk_id);
|
|
|
|
}
|