Add migrations and save createdAt in local time

main
Talon 2024-08-24 12:51:11 +02:00
parent 3575c910f4
commit ccdaa571d8
3 changed files with 115 additions and 44 deletions

View File

@ -1,6 +1,8 @@
import { Database } from 'bun:sqlite';
import { DB_PATH } from './config';
import { logger } from './globals';
import { readdir, readFile } from "fs/promises";
import { join } from "path";
export let FTS5Enabled = true;
@ -18,56 +20,45 @@ export const initializeDB = () => {
logger.warn("Failed to load FTS5 extension. Disabling FTS5");
FTS5Enabled = false;
}
}
db.run(`
CREATE TABLE IF NOT EXISTS channels (
id INTEGER PRIMARY KEY AUTOINCREMENT,
name TEXT NOT NULL,
createdAt DATETIME DEFAULT CURRENT_TIMESTAMP
)
`);
db.run(`
CREATE TABLE IF NOT EXISTS files (
id INTEGER PRIMARY KEY AUTOINCREMENT,
channelId INTEGER,
filePath TEXT,
fileType TEXT,
fileSize INTEGER,
originalName TEXT,
createdAt DATETIME DEFAULT CURRENT_TIMESTAMP,
FOREIGN KEY (channelId) REFERENCES channels (id) ON DELETE CASCADE
)
`);
db.run(`
CREATE TABLE IF NOT EXISTS messages (
id INTEGER PRIMARY KEY AUTOINCREMENT,
channelId INTEGER,
content TEXT,
fileId INTEGER NULL,
createdAt DATETIME DEFAULT CURRENT_TIMESTAMP,
FOREIGN KEY (channelId) REFERENCES channels (id) ON DELETE CASCADE,
FOREIGN KEY (fileId) REFERENCES files (id) ON DELETE SET NULL
)
`);
db.run(`
CREATE VIRTUAL TABLE IF NOT EXISTS messages_fts USING fts5(
content,
content='messages',
content_rowid='id'
);
`)
return FTS5Enabled;
}
export const migrate = async () => {
logger.info(`Checking for migrations...`);
const result = db.query(`SELECT name FROM sqlite_master WHERE type='table' AND name='meta'`);
if (result.all().length === 0) {
logger.info(`Creating meta table...`);
db.run(`CREATE TABLE meta (version INTEGER)`);
db.run(`INSERT INTO meta (version) VALUES (0)`);
}
const version = db.query(`SELECT version FROM meta`).get() as { version: number };
logger.info(`Migration version: ${version.version}`);
// we are in bun.js. use its API's to read the file list.
logger.info(`Searching for migrations in ${join(__dirname, "migrations")}`);
const files = await readdir(join(__dirname, "migrations"));
for (const file of files) {
const [fileVersion, ...rest] = file.split("_");
logger.info(`Found migration ${fileVersion}`);
if (fileVersion && Number(fileVersion) > version.version) {
logger.info(`Running migration ${file}`);
const sql = new TextDecoder().decode(await readFile(join(__dirname, `migrations/${file}`)));
db.run(sql);
const query = db.query(`UPDATE meta SET version = $version`);
const res = query.run( {$version: Number(fileVersion)})
logger.info(`Migration ${file} done`);
}
}
logger.info(`Migrations done`);
}
logger.info(`Loading database at ${DB_PATH}`);
export const db = new Database(DB_PATH);
initializeDB();
migrate();

View File

@ -0,0 +1,28 @@
CREATE TABLE IF NOT EXISTS channels (
id INTEGER PRIMARY KEY AUTOINCREMENT,
name TEXT NOT NULL,
createdAt DATETIME DEFAULT CURRENT_TIMESTAMP
) CREATE TABLE IF NOT EXISTS files (
id INTEGER PRIMARY KEY AUTOINCREMENT,
channelId INTEGER,
filePath TEXT,
fileType TEXT,
fileSize INTEGER,
originalName TEXT,
createdAt DATETIME DEFAULT CURRENT_TIMESTAMP,
FOREIGN KEY (channelId) REFERENCES channels (id) ON DELETE CASCADE
) CREATE TABLE IF NOT EXISTS messages (
id INTEGER PRIMARY KEY AUTOINCREMENT,
channelId INTEGER,
content TEXT,
fileId INTEGER NULL,
createdAt DATETIME DEFAULT CURRENT_TIMESTAMP,
FOREIGN KEY (channelId) REFERENCES channels (id) ON DELETE CASCADE,
FOREIGN KEY (fileId) REFERENCES files (id) ON DELETE
SET
NULL
) CREATE VIRTUAL TABLE IF NOT EXISTS messages_fts USING fts5(
content,
content = 'messages',
content_rowid = 'id'
);

View File

@ -0,0 +1,52 @@
-- 1. Create a backup of the existing tables
CREATE TABLE channels_backup AS SELECT * FROM channels;
CREATE TABLE files_backup AS SELECT * FROM files;
CREATE TABLE messages_backup AS SELECT * FROM messages;
-- 2. Drop the existing tables
DROP TABLE channels;
DROP TABLE files;
DROP TABLE messages;
-- 3. Recreate the tables with the updated schema
CREATE TABLE IF NOT EXISTS channels (
id INTEGER PRIMARY KEY AUTOINCREMENT,
name TEXT NOT NULL,
createdAt DATETIME DEFAULT (datetime('now', 'localtime'))
);
CREATE TABLE IF NOT EXISTS files (
id INTEGER PRIMARY KEY AUTOINCREMENT,
channelId INTEGER,
filePath TEXT,
fileType TEXT,
fileSize INTEGER,
originalName TEXT,
createdAt DATETIME DEFAULT (datetime('now', 'localtime')),
FOREIGN KEY (channelId) REFERENCES channels (id) ON DELETE CASCADE
);
CREATE TABLE IF NOT EXISTS messages (
id INTEGER PRIMARY KEY AUTOINCREMENT,
channelId INTEGER,
content TEXT,
fileId INTEGER NULL,
createdAt DATETIME DEFAULT (datetime('now', 'localtime')),
FOREIGN KEY (channelId) REFERENCES channels (id) ON DELETE CASCADE,
FOREIGN KEY (fileId) REFERENCES files (id) ON DELETE SET NULL
);
-- 4. Migrate the data back from the backup tables
INSERT INTO channels (id, name, createdAt)
SELECT id, name, createdAt FROM channels_backup;
INSERT INTO files (id, channelId, filePath, fileType, fileSize, originalName, createdAt)
SELECT id, channelId, filePath, fileType, fileSize, originalName, createdAt FROM files_backup;
INSERT INTO messages (id, channelId, content, fileId, createdAt)
SELECT id, channelId, content, fileId, createdAt FROM messages_backup;
-- 5. Drop the backup tables
DROP TABLE channels_backup;
DROP TABLE files_backup;
DROP TABLE messages_backup;