Extract database operations into separate db.ts module

- src/db.ts: initDatabase, closeDatabase, storeMessage, getNewMessages
- Removes SQL from index.ts
- Database initialization happens once at startup

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
gavrielc
2026-01-31 19:20:41 +02:00
parent 78426c764d
commit 0691601469
2 changed files with 86 additions and 73 deletions

78
src/db.ts Normal file
View File

@@ -0,0 +1,78 @@
import Database from 'better-sqlite3';
import fs from 'fs';
import path from 'path';
import { proto } from '@whiskeysockets/baileys';
import { NewMessage } from './types.js';
import { STORE_DIR } from './config.js';
let db: Database.Database;
export function initDatabase(): void {
const dbPath = path.join(STORE_DIR, 'messages.db');
fs.mkdirSync(path.dirname(dbPath), { recursive: true });
db = new Database(dbPath);
db.exec(`
CREATE TABLE IF NOT EXISTS chats (
jid TEXT PRIMARY KEY,
name TEXT,
last_message_time TEXT
);
CREATE TABLE IF NOT EXISTS messages (
id TEXT,
chat_jid TEXT,
sender TEXT,
content TEXT,
timestamp TEXT,
is_from_me INTEGER,
PRIMARY KEY (id, chat_jid),
FOREIGN KEY (chat_jid) REFERENCES chats(jid)
);
CREATE INDEX IF NOT EXISTS idx_timestamp ON messages(timestamp);
`);
}
export function closeDatabase(): void {
db.close();
}
export function storeMessage(msg: proto.IWebMessageInfo, chatJid: string, isFromMe: boolean): void {
if (!msg.key) return;
const content =
msg.message?.conversation ||
msg.message?.extendedTextMessage?.text ||
msg.message?.imageMessage?.caption ||
msg.message?.videoMessage?.caption ||
'';
const timestamp = new Date(Number(msg.messageTimestamp) * 1000).toISOString();
const sender = msg.key.participant || msg.key.remoteJid || '';
const msgId = msg.key.id || '';
db.prepare(`INSERT OR REPLACE INTO chats (jid, name, last_message_time) VALUES (?, ?, ?)`)
.run(chatJid, chatJid, timestamp);
db.prepare(`INSERT OR REPLACE INTO messages (id, chat_jid, sender, content, timestamp, is_from_me) VALUES (?, ?, ?, ?, ?, ?)`)
.run(msgId, chatJid, sender, content, timestamp, isFromMe ? 1 : 0);
}
export function getNewMessages(jids: string[], lastTimestamp: string): { messages: NewMessage[]; newTimestamp: string } {
if (jids.length === 0) return { messages: [], newTimestamp: lastTimestamp };
const placeholders = jids.map(() => '?').join(',');
const sql = `
SELECT id, chat_jid, sender, content, timestamp
FROM messages
WHERE timestamp > ? AND chat_jid IN (${placeholders})
ORDER BY timestamp
`;
const rows = db.prepare(sql).all(lastTimestamp, ...jids) as NewMessage[];
let newTimestamp = lastTimestamp;
for (const row of rows) {
if (row.timestamp > newTimestamp) newTimestamp = row.timestamp;
}
return { messages: rows, newTimestamp };
}