use saya_connectors::sql_references;
use saya_types::{ProfileIdentity, SqlDialect};
use serde_json::Value;
use super::observations::{ObservationLog, ObservationOutcome, ToolObservation};
impl ObservationLog {
pub(crate) fn record_query(
&self,
tool: &str,
sql: &str,
dialect: SqlDialect,
profile_id: Option<&str>,
result: Option<&Value>,
) {
let refs = sql_references(sql, dialect).unwrap_or_default();
let (objects, columns, references_partial) = (refs.objects, refs.columns, refs.partial);
let (outcome, row_count, truncated) = match result {
Some(value) => (
ObservationOutcome::Succeeded,
value
.get("row_count")
.and_then(Value::as_u64)
.map(|n| n as usize),
value.get("truncated").and_then(Value::as_bool),
),
None => (ObservationOutcome::Failed, None, None),
};
self.record(ToolObservation {
tool: tool.into(),
outcome,
profile: profile_id.and_then(parse_identity),
objects,
columns,
row_count,
truncated,
references_partial,
});
}
pub(crate) fn record_schema(&self, tool: &str, profile_id: Option<&str>, succeeded: bool) {
self.record(ToolObservation {
tool: tool.into(),
outcome: if succeeded {
ObservationOutcome::Succeeded
} else {
ObservationOutcome::Failed
},
profile: profile_id.and_then(parse_identity),
objects: Vec::new(),
columns: Vec::new(),
row_count: None,
truncated: None,
references_partial: false,
});
}
}
fn parse_identity(value: &str) -> Option<ProfileIdentity> {
ProfileIdentity::parse(value).ok()
}