gobby_code/vector/code_symbols/
repository.rs1use postgres::{GenericClient, types::ToSql};
2
3use crate::db;
4use crate::models::Symbol;
5
6pub fn fetch_symbols_for_file(
7 conn: &mut impl GenericClient,
8 project_id: &str,
9 file_path: &str,
10) -> anyhow::Result<Vec<Symbol>> {
11 fetch_symbols_where(
12 conn,
13 SymbolPredicate::File {
14 project_id,
15 file_path,
16 },
17 )
18}
19
20pub fn fetch_symbols_for_project(
21 conn: &mut impl GenericClient,
22 project_id: &str,
23) -> anyhow::Result<Vec<Symbol>> {
24 fetch_symbols_where(conn, SymbolPredicate::Project { project_id })
25}
26
27enum SymbolPredicate<'a> {
28 Project {
29 project_id: &'a str,
30 },
31 File {
32 project_id: &'a str,
33 file_path: &'a str,
34 },
35}
36
37impl SymbolPredicate<'_> {
38 fn where_clause(&self) -> &'static str {
39 match self {
40 Self::Project { .. } => "project_id = $1",
41 Self::File { .. } => "project_id = $1 AND file_path = $2",
42 }
43 }
44
45 fn params(&self) -> Vec<&(dyn ToSql + Sync)> {
46 match self {
47 Self::Project { project_id } => vec![project_id as &(dyn ToSql + Sync)],
48 Self::File {
49 project_id,
50 file_path,
51 } => vec![
52 project_id as &(dyn ToSql + Sync),
53 file_path as &(dyn ToSql + Sync),
54 ],
55 }
56 }
57}
58
59fn fetch_symbols_where(
60 conn: &mut impl GenericClient,
61 predicate: SymbolPredicate<'_>,
62) -> anyhow::Result<Vec<Symbol>> {
63 let columns = db::symbol_select_columns("");
64 let params = predicate.params();
65 conn.query(
66 &format!(
67 "SELECT {columns} FROM code_symbols
68 WHERE {}
69 ORDER BY file_path, byte_start, id",
70 predicate.where_clause()
71 ),
72 ¶ms,
73 )?
74 .into_iter()
75 .map(|row| Symbol::from_row(&row))
76 .collect()
77}