161 lines
6.2 KiB
JavaScript
161 lines
6.2 KiB
JavaScript
"use strict";
|
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
exports.ThreadsDAO = void 0;
|
|
const uuid_1 = require("uuid");
|
|
class ThreadsDAO {
|
|
dbManager;
|
|
constructor(dbManager) {
|
|
this.dbManager = dbManager;
|
|
}
|
|
get db() {
|
|
return this.dbManager.getDatabase();
|
|
}
|
|
create(input) {
|
|
const id = input.id || (0, uuid_1.v4)();
|
|
const now = new Date();
|
|
const thread = {
|
|
id,
|
|
sessionId: input.sessionId || id,
|
|
title: input.title || 'New Thread',
|
|
description: input.description,
|
|
gitBranch: input.gitBranch,
|
|
createdAt: input.createdAt || now,
|
|
updatedAt: input.updatedAt || now,
|
|
messageCount: input.messageCount || 0,
|
|
isActive: input.isActive || false,
|
|
metadata: {
|
|
filesChanged: input.metadata?.filesChanged || 0,
|
|
linesAdded: input.metadata?.linesAdded || 0,
|
|
linesDeleted: input.metadata?.linesDeleted || 0,
|
|
tags: input.metadata?.tags || []
|
|
}
|
|
};
|
|
const stmt = this.db.prepare(`
|
|
INSERT INTO threads (
|
|
id, session_id, git_branch, title, description, created_at, updated_at,
|
|
message_count, is_active, files_changed,
|
|
lines_added, lines_deleted, tags
|
|
) VALUES (
|
|
?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?
|
|
)
|
|
`);
|
|
stmt.run(thread.id, thread.sessionId, thread.gitBranch || null, thread.title, thread.description || null, thread.createdAt.getTime(), thread.updatedAt.getTime(), thread.messageCount, thread.isActive ? 1 : 0, thread.metadata.filesChanged, thread.metadata.linesAdded, thread.metadata.linesDeleted, JSON.stringify(thread.metadata.tags || []));
|
|
return thread;
|
|
}
|
|
findById(id) {
|
|
const stmt = this.db.prepare('SELECT * FROM threads WHERE id = ?');
|
|
const row = stmt.get(id);
|
|
if (!row)
|
|
return null;
|
|
return this.mapRowToThread(row);
|
|
}
|
|
findAll(options) {
|
|
const { limit = 50, offset = 0, sortBy = 'updatedAt', order = 'desc', tags } = options || {};
|
|
let query = 'SELECT * FROM threads';
|
|
let countQuery = 'SELECT COUNT(*) as total FROM threads';
|
|
const params = [];
|
|
const conditions = [];
|
|
if (tags && tags.length > 0) {
|
|
// Note: This is a simple implementation. Ideally use FTS or separate tags table.
|
|
// For now, using LIKE on JSON string which is suboptimal but works for MVP.
|
|
const tagConditions = tags.map(tag => {
|
|
params.push(`%"${tag}"%`);
|
|
return 'tags LIKE ?';
|
|
});
|
|
conditions.push(`(${tagConditions.join(' OR ')})`);
|
|
}
|
|
if (conditions.length > 0) {
|
|
const whereClause = ` WHERE ${conditions.join(' AND ')}`;
|
|
query += whereClause;
|
|
countQuery += whereClause;
|
|
}
|
|
const sortColumn = sortBy === 'updatedAt' ? 'updated_at' :
|
|
sortBy === 'createdAt' ? 'created_at' : 'message_count';
|
|
query += ` ORDER BY ${sortColumn} ${order.toUpperCase()}`;
|
|
query += ` LIMIT ? OFFSET ?`;
|
|
// params for where clause + limit + offset
|
|
const queryParams = [...params, limit, offset];
|
|
const rows = this.db.prepare(query).all(...queryParams);
|
|
const totalRow = this.db.prepare(countQuery).get(...params);
|
|
return {
|
|
threads: rows.map(this.mapRowToThread),
|
|
total: totalRow.total
|
|
};
|
|
}
|
|
update(id, updates) {
|
|
const current = this.findById(id);
|
|
if (!current)
|
|
return null;
|
|
// Merge updates
|
|
const updated = { ...current, ...updates };
|
|
updated.updatedAt = new Date(); // Always update updatedAt
|
|
// Ensure metadata is merged correctly if provided
|
|
if (updates.metadata) {
|
|
updated.metadata = { ...current.metadata, ...updates.metadata };
|
|
}
|
|
const stmt = this.db.prepare(`
|
|
UPDATE threads SET
|
|
title = ?,
|
|
description = ?,
|
|
git_branch = ?,
|
|
updated_at = ?,
|
|
message_count = ?,
|
|
is_active = ?,
|
|
files_changed = ?,
|
|
lines_added = ?,
|
|
lines_deleted = ?,
|
|
tags = ?
|
|
WHERE id = ?
|
|
`);
|
|
stmt.run(updated.title, updated.description || null, updated.gitBranch || null, updated.updatedAt.getTime(), updated.messageCount, updated.isActive ? 1 : 0, updated.metadata.filesChanged, updated.metadata.linesAdded, updated.metadata.linesDeleted, JSON.stringify(updated.metadata.tags || []), id);
|
|
return updated;
|
|
}
|
|
delete(id) {
|
|
const stmt = this.db.prepare('DELETE FROM threads WHERE id = ?');
|
|
const result = stmt.run(id);
|
|
return result.changes > 0;
|
|
}
|
|
setActive(id) {
|
|
const trx = this.db.transaction(() => {
|
|
// Deactivate all
|
|
this.db.prepare('UPDATE threads SET is_active = 0').run();
|
|
// Activate target
|
|
const result = this.db.prepare('UPDATE threads SET is_active = 1 WHERE id = ?').run(id);
|
|
return result.changes > 0;
|
|
});
|
|
return trx();
|
|
}
|
|
getActive() {
|
|
const stmt = this.db.prepare('SELECT * FROM threads WHERE is_active = 1 LIMIT 1');
|
|
const row = stmt.get();
|
|
if (!row)
|
|
return null;
|
|
return this.mapRowToThread(row);
|
|
}
|
|
findByPrefix(prefix) {
|
|
const stmt = this.db.prepare(`SELECT * FROM threads WHERE id LIKE ? || '%'`);
|
|
const rows = stmt.all(prefix);
|
|
return rows.map(this.mapRowToThread);
|
|
}
|
|
mapRowToThread(row) {
|
|
return {
|
|
id: row.id,
|
|
sessionId: row.session_id || row.id,
|
|
title: row.title,
|
|
description: row.description || undefined,
|
|
gitBranch: row.git_branch || undefined,
|
|
createdAt: new Date(row.created_at),
|
|
updatedAt: new Date(row.updated_at),
|
|
messageCount: row.message_count,
|
|
isActive: Boolean(row.is_active),
|
|
metadata: {
|
|
filesChanged: row.files_changed,
|
|
linesAdded: row.lines_added,
|
|
linesDeleted: row.lines_deleted,
|
|
tags: JSON.parse(row.tags || '[]')
|
|
}
|
|
};
|
|
}
|
|
}
|
|
exports.ThreadsDAO = ThreadsDAO;
|