perf: server-side search + pagination for topics (30 per page)
Loads only 30 topics at a time with server-side search instead of fetching all 6000+ topics. Debounced search input, pagination, selected-only filter. Much faster for large Victron brokers. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -11,11 +11,15 @@ import { getDb } from '../../db/index';
|
||||
|
||||
const router = Router({ mergeParams: true });
|
||||
|
||||
// GET /api/mqtt/brokers/:brokerId/topics
|
||||
// GET /api/mqtt/brokers/:brokerId/topics?search=grid&selected=1&limit=50&offset=0
|
||||
router.get('/', (req, res): void => {
|
||||
try {
|
||||
const brokerId = parseInt(req.params.brokerId);
|
||||
res.json(getTopicsForBroker(brokerId));
|
||||
const search = req.query.search as string | undefined;
|
||||
const selectedOnly = req.query.selected === '1';
|
||||
const limit = parseInt(req.query.limit as string) || 50;
|
||||
const offset = parseInt(req.query.offset as string) || 0;
|
||||
res.json(getTopicsForBroker(brokerId, { search, selectedOnly, limit, offset }));
|
||||
} catch (err) {
|
||||
res.status(500).json({ error: (err as Error).message });
|
||||
}
|
||||
|
||||
@@ -19,11 +19,32 @@ export interface UpdateTopicData {
|
||||
ignored?: number;
|
||||
}
|
||||
|
||||
export function getTopicsForBroker(brokerId: number): MqttTopic[] {
|
||||
export function getTopicsForBroker(brokerId: number, opts?: { search?: string; selectedOnly?: boolean; limit?: number; offset?: number }): { topics: MqttTopic[]; total: number } {
|
||||
const db = getDb();
|
||||
return db
|
||||
.prepare('SELECT * FROM mqtt_topics WHERE broker_id = ? ORDER BY id ASC')
|
||||
.all(brokerId) as MqttTopic[];
|
||||
const conditions = ['broker_id = ?'];
|
||||
const params: any[] = [brokerId];
|
||||
|
||||
if (opts?.search) {
|
||||
conditions.push('topic LIKE ?');
|
||||
params.push(`%${opts.search}%`);
|
||||
}
|
||||
if (opts?.selectedOnly) {
|
||||
conditions.push('selected = 1');
|
||||
}
|
||||
conditions.push('ignored = 0');
|
||||
|
||||
const where = conditions.join(' AND ');
|
||||
const total = (db.prepare(`SELECT count(*) as c FROM mqtt_topics WHERE ${where}`).get(...params) as any).c;
|
||||
|
||||
const limit = opts?.limit || 50;
|
||||
const offset = opts?.offset || 0;
|
||||
params.push(limit, offset);
|
||||
|
||||
const topics = db
|
||||
.prepare(`SELECT * FROM mqtt_topics WHERE ${where} ORDER BY selected DESC, last_payload IS NOT NULL DESC, topic ASC LIMIT ? OFFSET ?`)
|
||||
.all(...params) as MqttTopic[];
|
||||
|
||||
return { topics, total };
|
||||
}
|
||||
|
||||
export function updateTopic(id: number, data: UpdateTopicData): MqttTopic | undefined {
|
||||
|
||||
Reference in New Issue
Block a user