165 lines
3.4 KiB
JavaScript
165 lines
3.4 KiB
JavaScript
import initSqlJs from 'sql.js';
|
|
import { fileURLToPath } from 'url';
|
|
import { dirname, join } from 'path';
|
|
import fs from 'fs';
|
|
|
|
const __filename = fileURLToPath(import.meta.url);
|
|
const __dirname = dirname(__filename);
|
|
|
|
const DB_PATH = join(__dirname, '../data/messages.db');
|
|
|
|
let db = null;
|
|
|
|
export async function initDatabase() {
|
|
const SQL = await initSqlJs();
|
|
|
|
// Load existing database or create new one
|
|
let dbBuffer;
|
|
if (fs.existsSync(DB_PATH)) {
|
|
dbBuffer = fs.readFileSync(DB_PATH);
|
|
db = new SQL.Database(dbBuffer);
|
|
} else {
|
|
db = new SQL.Database();
|
|
}
|
|
|
|
// Create tables
|
|
db.run(`
|
|
CREATE TABLE IF NOT EXISTS messages (
|
|
id TEXT PRIMARY KEY,
|
|
channel_id TEXT NOT NULL,
|
|
author_id TEXT NOT NULL,
|
|
author_name TEXT NOT NULL,
|
|
content TEXT NOT NULL,
|
|
created_at INTEGER NOT NULL,
|
|
fetched_at INTEGER NOT NULL
|
|
)
|
|
`);
|
|
|
|
db.run(`CREATE INDEX IF NOT EXISTS idx_channel ON messages(channel_id)`);
|
|
db.run(`CREATE INDEX IF NOT EXISTS idx_created_at ON messages(created_at)`);
|
|
db.run(`CREATE INDEX IF NOT EXISTS idx_fetched_at ON messages(fetched_at)`);
|
|
|
|
saveDatabase();
|
|
}
|
|
|
|
function saveDatabase() {
|
|
const data = db.export();
|
|
const buffer = Buffer.from(data);
|
|
fs.writeFileSync(DB_PATH, buffer);
|
|
}
|
|
|
|
export function saveMessage(message) {
|
|
db.run(
|
|
`INSERT OR REPLACE INTO messages (id, channel_id, author_id, author_name, content, created_at, fetched_at)
|
|
VALUES (?, ?, ?, ?, ?, ?, ?)`,
|
|
[
|
|
message.id,
|
|
message.channelId,
|
|
message.authorId,
|
|
message.authorName,
|
|
message.content,
|
|
message.createdAt,
|
|
Date.now(),
|
|
]
|
|
);
|
|
saveDatabase();
|
|
}
|
|
|
|
export function saveMessages(messages) {
|
|
db.run('BEGIN TRANSACTION');
|
|
|
|
const stmt = db.prepare(
|
|
`INSERT OR REPLACE INTO messages (id, channel_id, author_id, author_name, content, created_at, fetched_at)
|
|
VALUES (?, ?, ?, ?, ?, ?, ?)`
|
|
);
|
|
|
|
for (const msg of messages) {
|
|
stmt.run([
|
|
msg.id,
|
|
msg.channelId,
|
|
msg.authorId,
|
|
msg.authorName,
|
|
msg.content,
|
|
msg.createdAt,
|
|
Date.now(),
|
|
]);
|
|
}
|
|
|
|
stmt.free();
|
|
db.run('COMMIT');
|
|
saveDatabase();
|
|
}
|
|
|
|
export function getMessagesByChannel(channelId, limit = 50) {
|
|
const stmt = db.prepare(
|
|
`SELECT * FROM messages
|
|
WHERE channel_id = ?
|
|
ORDER BY created_at DESC
|
|
LIMIT ?`
|
|
);
|
|
|
|
stmt.bind([channelId, limit]);
|
|
const results = [];
|
|
|
|
while (stmt.step()) {
|
|
const row = stmt.getAsObject();
|
|
results.push(row);
|
|
}
|
|
|
|
stmt.free();
|
|
return results;
|
|
}
|
|
|
|
export function getAllChannels() {
|
|
const stmt = db.prepare(
|
|
`SELECT DISTINCT channel_id, author_name as last_author
|
|
FROM messages
|
|
ORDER BY fetched_at DESC`
|
|
);
|
|
|
|
const results = [];
|
|
while (stmt.step()) {
|
|
results.push(stmt.getAsObject());
|
|
}
|
|
stmt.free();
|
|
|
|
return results;
|
|
}
|
|
|
|
export function getAllMessages(limit = 50) {
|
|
const stmt = db.prepare(
|
|
`SELECT * FROM messages
|
|
ORDER BY created_at DESC
|
|
LIMIT ?`
|
|
);
|
|
|
|
stmt.bind([limit]);
|
|
const results = [];
|
|
|
|
while (stmt.step()) {
|
|
const row = stmt.getAsObject();
|
|
results.push(row);
|
|
}
|
|
|
|
stmt.free();
|
|
return results;
|
|
}
|
|
|
|
export function getLatestMessageTime(channelId) {
|
|
const stmt = db.prepare(
|
|
`SELECT MAX(created_at) as latest FROM messages WHERE channel_id = ?`
|
|
);
|
|
|
|
stmt.bind([channelId]);
|
|
let result = null;
|
|
|
|
if (stmt.step()) {
|
|
result = stmt.getAsObject();
|
|
}
|
|
|
|
stmt.free();
|
|
return result?.latest || 0;
|
|
}
|
|
|
|
export { db };
|