Add migrations and save createdAt in local time
parent
3575c910f4
commit
ccdaa571d8
|
@ -1,6 +1,8 @@
|
||||||
import { Database } from 'bun:sqlite';
|
import { Database } from 'bun:sqlite';
|
||||||
import { DB_PATH } from './config';
|
import { DB_PATH } from './config';
|
||||||
import { logger } from './globals';
|
import { logger } from './globals';
|
||||||
|
import { readdir, readFile } from "fs/promises";
|
||||||
|
import { join } from "path";
|
||||||
|
|
||||||
export let FTS5Enabled = true;
|
export let FTS5Enabled = true;
|
||||||
|
|
||||||
|
@ -18,56 +20,45 @@ export const initializeDB = () => {
|
||||||
logger.warn("Failed to load FTS5 extension. Disabling FTS5");
|
logger.warn("Failed to load FTS5 extension. Disabling FTS5");
|
||||||
FTS5Enabled = false;
|
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;
|
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}`);
|
logger.info(`Loading database at ${DB_PATH}`);
|
||||||
|
|
||||||
export const db = new Database(DB_PATH);
|
export const db = new Database(DB_PATH);
|
||||||
|
|
||||||
|
|
||||||
initializeDB();
|
initializeDB();
|
||||||
|
migrate();
|
|
@ -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'
|
||||||
|
);
|
|
@ -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;
|
Loading…
Reference in New Issue