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
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; |
|
} |
|
}
|
|
|