Skip to main content

mirage/router/
sqlite.rs

1//! SQLite Backend Router Implementation
2//!
3//! This module implements the BackendRouter trait for SQLite databases.
4//! It wraps the existing MirageDb and Storage implementations.
5
6use super::*;
7use crate::storage::MirageDb;
8use anyhow::Result;
9use std::path::Path;
10
11/// SQLite backend router
12pub struct SqliteRouter {
13    db: MirageDb,
14}
15
16impl BackendRouter for SqliteRouter {
17    fn open(db_path: &Path) -> Result<Self> {
18        let db = MirageDb::open(db_path)?;
19        Ok(Self { db })
20    }
21
22    fn status(&self) -> Result<DatabaseStatus> {
23        let status = self.db.status()?;
24        Ok(DatabaseStatus {
25            cfg_blocks: status.cfg_blocks,
26            cfg_paths: status.cfg_paths,
27            cfg_dominators: status.cfg_dominators,
28            mirage_schema_version: status.mirage_schema_version,
29            magellan_schema_version: status.magellan_schema_version,
30        })
31    }
32
33    fn load_cfg(&self, function_id: i64) -> Result<crate::cfg::Cfg> {
34        crate::storage::load_cfg_from_db(&self.db, function_id)
35    }
36
37    fn resolve_function(&self, name_or_id: &str) -> Result<i64> {
38        self.db.resolve_function_name(name_or_id)
39    }
40
41    fn get_function_name(&self, function_id: i64) -> Option<String> {
42        self.db.get_function_name(function_id)
43    }
44
45    fn get_function_file(&self, function_id: i64) -> Option<String> {
46        self.db.get_function_file(function_id)
47    }
48
49    fn function_exists(&self, function_id: i64) -> bool {
50        // Try to resolve by ID and check if it exists
51        self.db
52            .resolve_function_name(&function_id.to_string())
53            .is_ok()
54    }
55
56    fn enumerate_paths(&self, function_id: i64, max_paths: usize) -> Result<Vec<ExecutionPath>> {
57        // Load CFG for the function
58        let cfg = self.load_cfg(function_id)?;
59
60        // Use the cfg::paths module to enumerate paths
61        use crate::cfg::paths::{enumerate_paths, PathLimits};
62
63        let limits = PathLimits {
64            max_paths,
65            max_length: 100,      // Default max path length
66            loop_unroll_limit: 3, // Default loop unrolling
67        };
68
69        let paths = enumerate_paths(&cfg, &limits);
70
71        // Convert cfg::paths::Path to router::ExecutionPath
72        let execution_paths: Vec<ExecutionPath> = paths
73            .into_iter()
74            .map(|path| ExecutionPath {
75                path_id: path.path_id,
76                blocks: path.blocks.iter().map(|&b| b as i64).collect(),
77                length: path.blocks.len(),
78            })
79            .collect();
80
81        Ok(execution_paths)
82    }
83
84    fn get_cfg_blocks(&self, function_id: i64) -> Result<Vec<CfgBlockInfo>> {
85        let blocks = self.db.storage().get_cfg_blocks(function_id)?;
86
87        Ok(blocks
88            .into_iter()
89            .map(|b| CfgBlockInfo {
90                id: b.id,
91                kind: b.kind,
92                terminator: Some(b.terminator),
93                byte_start: b.byte_start,
94                byte_end: b.byte_end,
95                start_line: b.start_line,
96                start_col: b.start_col,
97                end_line: b.end_line,
98                end_col: b.end_col,
99            })
100            .collect())
101    }
102
103    fn get_dominators(&self, _function_id: i64) -> Result<DominatorTree> {
104        // TODO: Implement using cfg::dominators module
105        anyhow::bail!("Dominators not yet implemented for SQLite router")
106    }
107
108    fn get_loops(&self, _function_id: i64) -> Result<Vec<NaturalLoop>> {
109        // TODO: Implement using cfg::loops module
110        anyhow::bail!("Loops not yet implemented for SQLite router")
111    }
112
113    fn find_unreachable(&self, _within_functions: bool) -> Result<Vec<UnreachableCode>> {
114        // TODO: Implement using analysis module
115        anyhow::bail!("Unreachable code detection not yet implemented for SQLite router")
116    }
117
118    fn get_patterns(&self, _function_id: i64) -> Result<Vec<BranchPattern>> {
119        // TODO: Implement using cfg::patterns module
120        anyhow::bail!("Pattern detection not yet implemented for SQLite router")
121    }
122
123    fn get_frontiers(&self, _function_id: i64) -> Result<DominanceFrontiers> {
124        // TODO: Implement using cfg::dominance_frontiers module
125        anyhow::bail!("Dominance frontiers not yet implemented for SQLite router")
126    }
127
128    fn find_cycles(&self) -> Result<Vec<CallCycle>> {
129        // TODO: Implement using analysis module
130        anyhow::bail!("Cycle detection not yet implemented for SQLite router")
131    }
132
133    fn get_blast_zone(&self, _function_id: i64, _block_id: Option<i64>) -> Result<BlastZone> {
134        // TODO: Implement using analysis module
135        anyhow::bail!("Blast zone not yet implemented for SQLite router")
136    }
137
138    fn slice(&self, _symbol: &str, _direction: SliceDirection) -> Result<SliceResult> {
139        // TODO: Implement using analysis module
140        anyhow::bail!("Program slicing not yet implemented for SQLite router")
141    }
142
143    fn get_hotspots(&self) -> Result<Vec<Hotspot>> {
144        // TODO: Implement using analysis module
145        anyhow::bail!("Hotspots not yet implemented for SQLite router")
146    }
147
148    fn get_hotpaths(&self, _function_id: Option<i64>) -> Result<Vec<HotPath>> {
149        // TODO: Implement using analysis module
150        anyhow::bail!("Hot paths not yet implemented for SQLite router")
151    }
152
153    fn verify_path(&self, _path_id: &str) -> Result<PathVerification> {
154        // TODO: Implement using analysis module
155        anyhow::bail!("Path verification not yet implemented for SQLite router")
156    }
157
158    fn get_icfg(&self, function_id: i64) -> Result<InterProceduralCfg> {
159        use crate::cfg::icfg::{build_icfg, IcfgOptions};
160
161        let options = IcfgOptions::default();
162        let icfg = build_icfg(self.db.storage(), self.db.backend(), function_id, options)?;
163        Ok(crate::cfg::icfg::IcfgJson::to_inter_procedural_cfg(&icfg))
164    }
165
166    fn get_call_graph(&self) -> Result<CallGraph> {
167        // TODO: Implement using analysis module
168        anyhow::bail!("Call graph not yet implemented for SQLite router")
169    }
170}