···1895189518961896export function getStats(): DatastoreStats {
18971897 const d = getDb();
18981898+18991899+ // Helper to safely count rows (returns 0 if table doesn't exist or query fails)
19001900+ const safeCount = (sql: string): number => {
19011901+ try {
19021902+ return (d.prepare(sql).get() as { count: number }).count;
19031903+ } catch {
19041904+ return 0;
19051905+ }
19061906+ };
19071907+19081908+ const safeAvg = (sql: string): number => {
19091909+ try {
19101910+ return (d.prepare(sql).get() as { avg: number | null }).avg || 0;
19111911+ } catch {
19121912+ return 0;
19131913+ }
19141914+ };
19151915+18981916 return {
18991899- totalAddresses: (d.prepare('SELECT COUNT(*) as count FROM addresses').get() as { count: number }).count,
19001900- totalVisits: (d.prepare('SELECT COUNT(*) as count FROM visits').get() as { count: number }).count,
19011901- avgVisitDuration: (d.prepare('SELECT AVG(duration) as avg FROM visits').get() as { avg: number | null }).avg || 0,
19021902- totalContent: (d.prepare('SELECT COUNT(*) as count FROM content').get() as { count: number }).count,
19031903- syncedContent: (d.prepare('SELECT COUNT(*) as count FROM content WHERE synced = 1').get() as { count: number }).count,
19041904- totalItems: (d.prepare('SELECT COUNT(*) as count FROM items').get() as { count: number }).count,
19051905- totalTags: (d.prepare('SELECT COUNT(*) as count FROM tags').get() as { count: number }).count,
19171917+ totalAddresses: safeCount('SELECT COUNT(*) as count FROM addresses'),
19181918+ totalVisits: safeCount('SELECT COUNT(*) as count FROM visits'),
19191919+ avgVisitDuration: safeAvg('SELECT AVG(duration) as avg FROM visits'),
19201920+ totalContent: safeCount('SELECT COUNT(*) as count FROM content'),
19211921+ syncedContent: safeCount('SELECT COUNT(*) as count FROM content WHERE synced = 1'),
19221922+ totalItems: safeCount('SELECT COUNT(*) as count FROM items'),
19231923+ totalTags: safeCount('SELECT COUNT(*) as count FROM tags'),
19061924 };
19071925}
19081926
+1-1
schema/generated/sqlite-full.sql
···11-- Generated by schema/codegen.js
22-- Schema version: 1
33--- Generated: 2026-02-02T08:01:19.478Z
33+-- Generated: 2026-02-03T16:59:11.716Z
44-- DO NOT EDIT - regenerate with: yarn schema:codegen
5566-- Unified content storage - URLs, text notes, tagsets, and images
+1-1
schema/generated/sqlite-sync.sql
···11-- Generated by schema/codegen.js
22-- Schema version: 1
33--- Generated: 2026-02-02T08:01:19.479Z
33+-- Generated: 2026-02-03T16:59:11.716Z
44-- DO NOT EDIT - regenerate with: yarn schema:codegen
5566-- Unified content storage - URLs, text notes, tagsets, and images
+1-1
schema/generated/types.rs
···11// Generated by schema/codegen.js
22// Schema version: 1
33-// Generated: 2026-02-02T08:01:19.479Z
33+// Generated: 2026-02-03T16:59:11.717Z
44// DO NOT EDIT - regenerate with: yarn schema:codegen
5566use serde::{Deserialize, Serialize};