obsidian_cli_inspector/db/
stats.rs1use rusqlite::Connection;
2
3#[derive(Debug)]
4pub struct DatabaseStats {
5 pub note_count: usize,
6 pub link_count: usize,
7 pub tag_count: usize,
8 pub chunk_count: usize,
9 pub unresolved_links: usize,
10}
11
12pub fn get_stats(conn: &Connection) -> rusqlite::Result<DatabaseStats> {
13 let note_count: i32 = conn.query_row("SELECT COUNT(*) FROM notes", [], |row| row.get(0))?;
14
15 let link_count: i32 = conn.query_row("SELECT COUNT(*) FROM links", [], |row| row.get(0))?;
16
17 let tag_count: i32 =
18 conn.query_row("SELECT COUNT(DISTINCT tag) FROM tags", [], |row| row.get(0))?;
19
20 let chunk_count: i32 = conn.query_row("SELECT COUNT(*) FROM chunks", [], |row| row.get(0))?;
21
22 let unresolved_links: i32 = conn.query_row(
23 "SELECT COUNT(*) FROM links WHERE dst_note_id IS NULL",
24 [],
25 |row| row.get(0),
26 )?;
27
28 Ok(DatabaseStats {
29 note_count: note_count as usize,
30 link_count: link_count as usize,
31 tag_count: tag_count as usize,
32 chunk_count: chunk_count as usize,
33 unresolved_links: unresolved_links as usize,
34 })
35}
36
37#[cfg(test)]
38mod tests {
39 use super::*;
40
41 fn create_test_db() -> Connection {
42 let conn = Connection::open_in_memory().unwrap();
43 conn.execute(
44 "CREATE TABLE notes (id INTEGER PRIMARY KEY, path TEXT, title TEXT, mtime INTEGER, hash TEXT, created_at TEXT, updated_at TEXT, frontmatter_json TEXT)",
45 [],
46 )
47 .unwrap();
48 conn.execute(
49 "CREATE TABLE links (id INTEGER PRIMARY KEY, src_note_id INTEGER, dst_note_id INTEGER, dst_text TEXT, kind TEXT, is_embed INTEGER, alias TEXT, heading_ref TEXT, block_ref TEXT)",
50 [],
51 )
52 .unwrap();
53 conn.execute(
54 "CREATE TABLE tags (id INTEGER PRIMARY KEY, note_id INTEGER, tag TEXT)",
55 [],
56 )
57 .unwrap();
58 conn.execute(
59 "CREATE TABLE chunks (id INTEGER PRIMARY KEY, note_id INTEGER, heading_path TEXT, text TEXT, byte_offset INTEGER, byte_length INTEGER)",
60 [],
61 )
62 .unwrap();
63 conn
64 }
65
66 #[test]
67 fn test_get_stats_empty_database() {
68 let conn = create_test_db();
69 let stats = get_stats(&conn).unwrap();
70 assert_eq!(stats.note_count, 0);
71 assert_eq!(stats.link_count, 0);
72 assert_eq!(stats.tag_count, 0);
73 assert_eq!(stats.chunk_count, 0);
74 assert_eq!(stats.unresolved_links, 0);
75 }
76
77 #[test]
78 fn test_database_stats_creation() {
79 let stats = DatabaseStats {
80 note_count: 10,
81 link_count: 20,
82 tag_count: 5,
83 chunk_count: 15,
84 unresolved_links: 2,
85 };
86 assert_eq!(stats.note_count, 10);
87 assert_eq!(stats.link_count, 20);
88 }
89}