#![cfg_attr(coverage_nightly, coverage(off))]
use super::helpers::is_keyword;
use rusqlite::{params, Connection};
#[allow(clippy::cast_possible_truncation)]
#[provable_contracts_macros::contract("pmat-core.yaml", equation = "check_compliance")]
pub(crate) fn fts5_search(
conn: &Connection,
query: &str,
limit: usize,
) -> Result<Vec<(usize, f32)>, String> {
let fts_query = tokenize_query_for_fts5(query);
if fts_query.is_empty() {
return Ok(Vec::new());
}
let mut stmt = conn
.prepare_cached(
"SELECT rowid, rank
FROM functions_fts
WHERE functions_fts MATCH ?1
ORDER BY rank
LIMIT ?2",
)
.map_err(|e| format!("FTS5 query failed: {e}"))?;
let results: Vec<(usize, f32)> = stmt
.query_map(params![fts_query, limit as i64], |row| {
let rowid: i64 = row.get(0)?;
let rank: f64 = row.get(1)?;
Ok((
(rowid - 1) as usize, (-rank) as f32,
))
})
.map_err(|e| format!("FTS5 query_map failed: {e}"))?
.filter_map(|r| r.ok())
.collect();
let max_score = results.iter().map(|(_, s)| *s).fold(0.0f32, f32::max);
if max_score > 0.0 {
Ok(results
.into_iter()
.map(|(idx, s)| (idx, s / max_score))
.collect())
} else {
Ok(results)
}
}
#[provable_contracts_macros::contract("pmat-core.yaml", equation = "check_compliance")]
pub(crate) fn tokenize_query_for_fts5(query: &str) -> String {
query
.split(|c: char| !c.is_alphanumeric() && c != '_')
.filter(|s| s.len() >= 2 && !is_keyword(s))
.map(|s| format!("\"{}\"", s.to_lowercase()))
.collect::<Vec<_>>()
.join(" ")
}
#[provable_contracts_macros::contract("pmat-core.yaml", equation = "check_compliance")]
pub(crate) fn query_callees(conn: &Connection, func_idx: usize) -> Result<Vec<usize>, String> {
let caller_id = (func_idx + 1) as i64;
let mut stmt = conn
.prepare_cached("SELECT callee_id FROM call_graph WHERE caller_id = ?1")
.map_err(|e| format!("Failed to prepare callees query: {e}"))?;
let rows = stmt
.query_map(params![caller_id], |row| {
let id: i64 = row.get(0)?;
Ok((id - 1) as usize)
})
.map_err(|e| format!("Failed to query callees: {e}"))?;
rows.collect::<Result<Vec<_>, _>>()
.map_err(|e| format!("Bad callee row: {e}"))
}
#[provable_contracts_macros::contract("pmat-core.yaml", equation = "check_compliance")]
pub(crate) fn query_callers(conn: &Connection, func_idx: usize) -> Result<Vec<usize>, String> {
let callee_id = (func_idx + 1) as i64;
let mut stmt = conn
.prepare_cached("SELECT caller_id FROM call_graph WHERE callee_id = ?1")
.map_err(|e| format!("Failed to prepare callers query: {e}"))?;
let rows = stmt
.query_map(params![callee_id], |row| {
let id: i64 = row.get(0)?;
Ok((id - 1) as usize)
})
.map_err(|e| format!("Failed to query callers: {e}"))?;
rows.collect::<Result<Vec<_>, _>>()
.map_err(|e| format!("Bad caller row: {e}"))
}