use std::collections::HashMap;
use crate::types::VelesError;
#[derive(Debug, Clone, uniffi::Enum)]
pub enum QueryResultKind {
Rows,
Mutation,
Deletion,
Ddl,
Train,
Admin,
}
#[derive(Debug, Clone, uniffi::Record)]
pub struct QueryResultRow {
pub id: u64,
pub score: f32,
pub data_json: String,
}
#[derive(Debug, Clone, uniffi::Record)]
pub struct QueryResult {
pub kind: QueryResultKind,
pub rows: Vec<QueryResultRow>,
pub row_count: u32,
pub message: String,
}
pub(crate) fn classify_query(query: &velesdb_core::velesql::Query) -> QueryResultKind {
if query.is_train() {
QueryResultKind::Train
} else if query.is_ddl_query() {
QueryResultKind::Ddl
} else if query.is_admin_query() {
QueryResultKind::Admin
} else if query.is_dml_query() {
classify_dml(query)
} else {
QueryResultKind::Rows
}
}
fn classify_dml(query: &velesdb_core::velesql::Query) -> QueryResultKind {
use velesdb_core::velesql::DmlStatement;
match query.dml.as_ref() {
Some(DmlStatement::Delete(_) | DmlStatement::DeleteEdge(_)) => QueryResultKind::Deletion,
_ => QueryResultKind::Mutation,
}
}
pub(crate) fn to_result_row(
result: &velesdb_core::SearchResult,
) -> Result<QueryResultRow, VelesError> {
let mut map = serde_json::Map::new();
map.insert("id".to_string(), serde_json::json!(result.point.id));
map.insert("score".to_string(), serde_json::json!(result.score));
if let Some(serde_json::Value::Object(payload)) = &result.point.payload {
for (k, v) in payload {
if k != "id" && k != "score" {
map.insert(k.clone(), v.clone());
}
}
}
let data_json = serde_json::to_string(&serde_json::Value::Object(map))
.map_err(|e| VelesError::database(format!("Failed to serialize row to JSON: {e}")))?;
Ok(QueryResultRow {
id: result.point.id,
score: result.score,
data_json,
})
}
pub(crate) fn build_message(kind: &QueryResultKind, row_count: u32) -> String {
match kind {
QueryResultKind::Rows => format!("{row_count} row(s) returned"),
QueryResultKind::Mutation => format!("{row_count} row(s) affected"),
QueryResultKind::Deletion => format!("{row_count} row(s) deleted"),
QueryResultKind::Ddl => "DDL statement executed successfully".to_string(),
QueryResultKind::Train => "Training completed successfully".to_string(),
QueryResultKind::Admin => "Admin command executed successfully".to_string(),
}
}
pub(crate) fn parse_params(
params_json: Option<String>,
) -> Result<HashMap<String, serde_json::Value>, VelesError> {
params_json
.map(|json| {
serde_json::from_str(&json)
.map_err(|e| VelesError::database(format!("Invalid params JSON: {e}")))
})
.transpose()
.map(Option::unwrap_or_default)
}
#[cfg(test)]
#[path = "query_tests.rs"]
mod integration_tests;
#[cfg(test)]
#[path = "query_unit_tests.rs"]
mod tests;