1use std::collections::HashMap;
2use std::path::{Path, PathBuf};
3
4use crate::error::{DbError, DiffError, ScanError};
5use crate::model::{
6 Config, DepLevel, DepType, Dependency, File, ImpactEntry, ParseResult, ParseStatus, PathStep,
7 Symbol, SymbolKind, SymbolResult, SymbolWithParent, VcsFileChange,
8};
9
10pub trait ConfigStore {
14 fn config_get(&self, key: &str) -> Result<Option<String>, DbError>;
15 fn config_set(&self, key: &str, value: &str) -> Result<(), DbError>;
16 fn config_list(&self) -> Result<Vec<Config>, DbError>;
17}
18
19pub trait SymbolLookup {
21 fn get_file_id(&self, path: &str) -> Result<Option<i64>, DbError>;
22 fn get_symbol_by_id(&self, symbol_id: i64) -> Result<Option<Symbol>, DbError>;
23 fn search_symbols_by_name(&self, name: &str, limit: i64) -> Result<Vec<SymbolResult>, DbError>;
24 fn get_symbols_for_file(&self, file_id: i64) -> Result<Vec<Symbol>, DbError>;
25 fn get_children(&self, symbol_id: i64) -> Result<Vec<Symbol>, DbError>;
26 fn impact_analysis(&self, symbol_id: i64, max_depth: i64) -> Result<Vec<ImpactEntry>, DbError>;
27 fn stats(&self) -> Result<(i64, i64, i64), DbError>;
28}
29
30#[allow(clippy::too_many_arguments)]
32pub trait ScanStore: ConfigStore + SymbolLookup {
33 fn begin_scan(&self) -> Result<i64, DbError>;
34 fn complete_scan(
35 &self,
36 scan_id: i64,
37 file_count: i64,
38 symbol_count: i64,
39 dep_count: i64,
40 ) -> Result<(), DbError>;
41 fn upsert_file(
42 &self,
43 scan_id: i64,
44 path: &str,
45 language: &str,
46 size_bytes: i64,
47 content_hash: &str,
48 last_modified: u64,
49 parse_status: ParseStatus,
50 ) -> Result<i64, DbError>;
51 fn get_file_hash(&self, path: &str) -> Result<Option<String>, DbError>;
52 fn get_all_file_paths(&self) -> Result<HashMap<String, i64>, DbError>;
53 fn delete_file(&self, file_id: i64) -> Result<(), DbError>;
54 fn insert_symbol(
55 &self,
56 file_id: i64,
57 parent_id: Option<i64>,
58 name: &str,
59 kind: SymbolKind,
60 signature: Option<&str>,
61 start_line: i64,
62 end_line: i64,
63 start_byte: i64,
64 end_byte: i64,
65 ) -> Result<i64, DbError>;
66 fn delete_symbols_for_file(&self, file_id: i64) -> Result<(), DbError>;
67 fn insert_dependency(
68 &self,
69 source_file_id: i64,
70 source_symbol_id: Option<i64>,
71 target_file_id: Option<i64>,
72 target_symbol_id: Option<i64>,
73 dep_type: DepType,
74 level: DepLevel,
75 raw_import: Option<&str>,
76 ) -> Result<i64, DbError>;
77 fn delete_deps_for_file(&self, file_id: i64) -> Result<(), DbError>;
78}
79
80pub trait QueryStore: ConfigStore + SymbolLookup {
82 fn search_symbols(&self, query: &str, limit: i64) -> Result<Vec<SymbolResult>, DbError>;
83 fn find_path(
84 &self,
85 from_symbol_id: i64,
86 to_symbol_id: i64,
87 max_depth: i64,
88 ) -> Result<Vec<PathStep>, DbError>;
89}
90
91pub trait DiffStore: ConfigStore + SymbolLookup {
93 fn symbols_in_line_range(
94 &self,
95 file_path: &str,
96 start_line: i64,
97 end_line: i64,
98 ) -> Result<Vec<SymbolResult>, DbError>;
99 fn all_symbols_for_file(&self, file_path: &str) -> Result<Vec<SymbolWithParent>, DbError>;
100}
101
102pub trait ExportStore: SymbolLookup {
104 fn list_files(&self, pattern: Option<&str>) -> Result<Vec<File>, DbError>;
105 fn get_deps_for_file(&self, file_id: i64) -> Result<Vec<Dependency>, DbError>;
106}
107
108pub trait VcsProvider {
112 fn working_tree_changes(&self, base_ref: Option<&str>)
114 -> Result<Vec<VcsFileChange>, DiffError>;
115 fn changes_between_refs(
117 &self,
118 from_ref: &str,
119 to_ref: &str,
120 ) -> Result<Vec<VcsFileChange>, DiffError>;
121 fn read_file_at_ref(&self, path: &str, git_ref: &str) -> Result<Option<String>, DiffError>;
123 fn commit_count(&self, from_ref: &str, to_ref: &str) -> Result<usize, DiffError>;
125 fn resolve_ref(&self, refspec: &str) -> Result<bool, DiffError>;
127 fn head_sha(&self) -> Result<String, DiffError>;
129 fn root_commit_sha(&self) -> Result<Option<String>, DiffError>;
131}
132
133pub trait FileDiscovery: Send + Sync {
137 fn discover_files(
138 &self,
139 project_dir: &Path,
140 supported_ext: &[&str],
141 ) -> Result<Vec<PathBuf>, ScanError>;
142}
143
144pub trait LanguageParser: Send + Sync {
148 fn parse(&self, source: &str, file_path: &Path) -> ParseResult;
149 fn language_name(&self) -> &str;
150}
151
152pub trait LanguageResolver: Send + Sync {
154 fn resolve_import(
155 &self,
156 import_path: &str,
157 source_file: &str,
158 project_root: &Path,
159 ) -> Option<PathBuf>;
160}
161
162pub struct SiblingExpansion {
165 pub prefix: String,
167 pub extension: String,
169 pub root_only: bool,
171}
172
173pub trait LanguageRegistry: Send + Sync {
175 fn parser_for(&self, ext: &str) -> Option<&dyn LanguageParser>;
176 fn resolver_for(&self, ext: &str, root: &Path) -> Option<Box<dyn LanguageResolver>>;
177 fn supported_extensions(&self) -> &[&str];
178 fn config_files(&self) -> &[&str];
179 fn sibling_expansion(&self, rel_path: &str) -> Option<SiblingExpansion>;
180}