use crate::dsl::Source;
use salsa::Database;
use std::collections::HashMap;
use std::path::PathBuf;
use std::time::SystemTime;
pub type DatabaseImpl = salsa::DatabaseImpl;
#[salsa::input]
pub struct SourceFile {
pub path: PathBuf,
pub content_hash: u64,
pub modified_time: SystemTime,
}
#[salsa::tracked]
pub fn source_metadata(db: &dyn salsa::Database, source_file: SourceFile) -> String {
let path = source_file.path(db);
let temp_source = Source {
id: "temp".to_string(),
path: path.clone(),
format: if path.extension().and_then(|s| s.to_str()) == Some("csv") {
"csv".to_string()
} else {
"tsv".to_string()
},
};
match crate::engine::DataReader::get_schema(&temp_source) {
Ok(schema) => {
let schema_map: std::collections::HashMap<String, String> = schema
.iter()
.map(|(name, dtype)| (name.to_string(), format!("{:?}", dtype)))
.collect();
serde_json::to_string(&schema_map).unwrap_or_default()
},
Err(_) => "error".to_string(),
}
}
#[salsa::tracked]
pub fn parsed_source_id(db: &dyn salsa::Database, source_file: SourceFile) -> String {
let _metadata = source_metadata(db, source_file);
format!("df_{}", source_file.content_hash(db))
}
#[salsa::tracked]
pub fn execute_query_cached(
db: &dyn salsa::Database,
query_json: String,
source_files: Vec<SourceFile>,
) -> String {
for source_file in &source_files {
let _parsed_id = parsed_source_id(db, *source_file);
let _metadata = source_metadata(db, *source_file);
}
use std::collections::hash_map::DefaultHasher;
use std::hash::{Hash, Hasher};
let mut hasher = DefaultHasher::new();
query_json.hash(&mut hasher);
for sf in &source_files {
sf.content_hash(db).hash(&mut hasher);
}
format!("result_{}", hasher.finish())
}
pub fn invalidate_source_in_db(db: &mut DatabaseImpl, _path: &PathBuf) {
db.synthetic_write(salsa::Durability::LOW);
}
pub fn get_cache_stats(_db: &DatabaseImpl) -> HashMap<String, usize> {
let mut stats = HashMap::new();
stats.insert("total_inputs".to_string(), 0);
stats.insert("computed_values".to_string(), 0);
stats
}