add: scripts to migrate to V3 schema TODO: fix processEncodingTasks() in `encoding.ts` TODO: write docs for V3 schema
159 lines
4.1 KiB
TypeScript
159 lines
4.1 KiB
TypeScript
import * as path from "path";
|
|
import { Database } from "better-sqlite3";
|
|
import DB from "better-sqlite3";
|
|
import { __dirname } from "../dirname.js";
|
|
import { getDatabaseDir } from "../utils/backend.js";
|
|
import { migrate } from "./migrate/index.js";
|
|
|
|
function getLibSimpleExtensionPath() {
|
|
switch (process.platform) {
|
|
case "win32":
|
|
return path.join(__dirname, "bin", process.platform, "libsimple", "simple.dll");
|
|
case "darwin":
|
|
return path.join(__dirname, "bin", process.platform, "libsimple", "libsimple.dylib");
|
|
case "linux":
|
|
return path.join(__dirname, "bin", process.platform, "libsimple", "libsimple.so");
|
|
default:
|
|
throw new Error("Unsupported platform");
|
|
}
|
|
}
|
|
|
|
function databaseInitialized(db: Database) {
|
|
return db.prepare(`SELECT name FROM sqlite_master WHERE type='table' AND name='frame';`).get()
|
|
!== undefined;
|
|
}
|
|
|
|
function init(db: Database) {
|
|
db.exec(`
|
|
CREATE TABLE IF NOT EXISTS frame (
|
|
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
createdAt REAL,
|
|
imgFilename TEXT,
|
|
segmentID INTEGER NULL,
|
|
videoPath TEXT NULL,
|
|
videoFrameIndex INTEGER NULL,
|
|
collectionID INTEGER NULL,
|
|
encodeStatus INTEGER DEFAULT 0,
|
|
FOREIGN KEY (segmentID) REFERENCES segments (id)
|
|
);
|
|
`);
|
|
|
|
db.exec(`
|
|
CREATE TABLE IF NOT EXISTS recognition_data (
|
|
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
frameID INTEGER,
|
|
data TEXT,
|
|
text TEXT,
|
|
FOREIGN KEY (frameID) REFERENCES frame (id)
|
|
);
|
|
`);
|
|
|
|
db.exec(`
|
|
CREATE TABLE IF NOT EXISTS segments(
|
|
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
startedAt REAL,
|
|
endedAt REAL,
|
|
title TEXT,
|
|
appName TEXT,
|
|
appPath TEXT,
|
|
text TEXT,
|
|
type TEXT,
|
|
appBundleID TEXT NULL,
|
|
url TEXT NULL
|
|
);
|
|
`);
|
|
|
|
db.exec(`
|
|
CREATE VIRTUAL TABLE IF NOT EXISTS text_search USING fts5(
|
|
id UNINDEXED,
|
|
frameID UNINDEXED,
|
|
data,
|
|
text
|
|
);
|
|
`);
|
|
|
|
db.exec(`
|
|
CREATE TRIGGER IF NOT EXISTS recognition_data_after_insert AFTER INSERT ON recognition_data
|
|
BEGIN
|
|
INSERT INTO text_search (id, frameID, data, text)
|
|
VALUES (NEW.id, NEW.frameID, NEW.data, NEW.text);
|
|
END;
|
|
`);
|
|
|
|
db.exec(`
|
|
CREATE TRIGGER IF NOT EXISTS recognition_data_after_update AFTER UPDATE ON recognition_data
|
|
BEGIN
|
|
UPDATE text_search
|
|
SET frameID = NEW.frameID, data = NEW.data, text = NEW.text
|
|
WHERE id = NEW.id;
|
|
END;
|
|
`);
|
|
|
|
db.exec(`
|
|
CREATE TRIGGER IF NOT EXISTS recognition_data_after_delete AFTER DELETE ON recognition_data
|
|
BEGIN
|
|
DELETE FROM text_search WHERE id = OLD.id;
|
|
END;
|
|
`);
|
|
|
|
db.exec(`
|
|
CREATE TABLE config (
|
|
key TEXT PRIMARY KEY,
|
|
value TEXT
|
|
);
|
|
`);
|
|
|
|
db.exec(`
|
|
CREATE TABLE IF NOT EXISTS encoding_task (
|
|
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
createdAt REAL,
|
|
status INT DEFAULT 0
|
|
);
|
|
`);
|
|
|
|
db.exec(`
|
|
CREATE TABLE IF NOT EXISTS encoding_task_data (
|
|
encodingTaskID INTEGER,
|
|
frame ID INTEGER PRIMARY KEY,
|
|
FOREIGN KEY (encodingTaskID) REFERENCES encoding_task(id),
|
|
FOREIGN KEY (frame) REFERENCES frame(id)
|
|
);
|
|
`);
|
|
|
|
db.exec(`
|
|
CREATE TRIGGER IF NOT EXISTS delete_encoding_task
|
|
AFTER UPDATE OF status
|
|
ON encoding_task
|
|
BEGIN
|
|
DELETE FROM encoding_task_data
|
|
WHERE encodingTaskID = OLD.id AND NEW.status = 2;
|
|
|
|
DELETE FROM encoding_task
|
|
WHERE id = OLD.id AND NEW.status = 2;
|
|
END;
|
|
`);
|
|
|
|
db.exec(`
|
|
INSERT INTO config (key, value) VALUES ('version', '3');
|
|
`);
|
|
}
|
|
|
|
export async function initDatabase() {
|
|
const dbPath = getDatabaseDir();
|
|
const db = new DB(dbPath, { verbose: console.log });
|
|
const libSimpleExtensionPath = getLibSimpleExtensionPath();
|
|
|
|
db.loadExtension(libSimpleExtensionPath);
|
|
|
|
if (!databaseInitialized(db)) {
|
|
init(db);
|
|
}
|
|
else {
|
|
migrate(db);
|
|
}
|
|
|
|
db.exec("PRAGMA journal_mode=WAL;");
|
|
|
|
return db;
|
|
}
|