#![allow(unused)]
use crate::config::Config;
use scylla::client::session::Session;
use scylla::client::session_builder::SessionBuilder;
use scylla::response::query_result::QueryResult;
use serde_json::{Map, Number, Value, json};
use scylla::deserialize::result::TypedRowIterator;
use scylla::response::query_result::{ColumnSpecs, QueryRowsResult};
use scylla::statement::Consistency;
use scylla::statement::Statement;
use scylla::value::{CqlValue, Row};
use std::collections::HashMap;
use std::error::Error;
#[allow(unused_variables)]
pub async fn execute_query(query: String) -> Result<(Vec<Value>, Vec<String>), Box<dyn Error>> {
let config: Config = Config::load().unwrap_or_else(|_| panic!("Failed to load config"));
let uri: String = config
.get_host("scylladb")
.unwrap_or(&"167.235.9.113:9042".to_string())
.clone();
let empty_map: HashMap<String, String> = HashMap::new();
let authenticator: &HashMap<String, String> =
config.get_authenticator("scylladb").unwrap_or(&empty_map);
let empty_string: String = String::new();
let session: Session = SessionBuilder::new()
.known_node("167.235.9.113:9042")
.build()
.await?;
let mut results: Vec<Value> = Vec::new();
let mut columns: Vec<String> = Vec::new();
let mut cql_query: Statement = Statement::new(query.as_str());
cql_query.set_consistency(Consistency::One);
cql_query.set_page_size(1);
let query_result: QueryResult = session.query_unpaged(cql_query, &[]).await?;
if query_result.is_rows() {
let rows_result: QueryRowsResult = query_result.into_rows_result()?;
let column_specs: ColumnSpecs<'_, '_> = rows_result.column_specs();
columns = column_specs
.iter()
.map(|spec| spec.name().to_string())
.collect();
let rows: TypedRowIterator<'_, '_, Row> = rows_result.rows::<Row>()?;
let mut row_count: i32 = 0;
for row_result in rows {
let row: Row = row_result?;
row_count += 1;
let mut row_map: Map<String, Value> = Map::new();
for (i, column_spec) in column_specs.iter().enumerate() {
let column_name: String = column_spec.name().to_string();
let value: Value = match row.columns.get(i) {
Some(Some(cql_value)) => {
match cql_value {
CqlValue::Text(s) => Value::String(s.clone()),
CqlValue::Int(i) => Value::Number((*i).into()),
CqlValue::BigInt(i) => Value::Number((*i).into()),
CqlValue::Boolean(b) => Value::Bool(*b),
CqlValue::Float(f) => Value::Number(
Number::from_f64(*f as f64).unwrap_or(Number::from(0)),
),
CqlValue::Double(d) => {
Value::Number(Number::from_f64(*d).unwrap_or(Number::from(0)))
}
CqlValue::Decimal(decimal) => {
let decimal_str: String = format!("{:?}", decimal);
let decimal_value: f64 =
if let Some(start) = decimal_str.find("value: ") {
let value_part: &str = &decimal_str[start + 7..];
if let Some(end) = value_part.find(',') {
value_part[..end].parse().unwrap_or(0.0)
} else {
0.0
}
} else {
0.0
};
Value::Number(
Number::from_f64(decimal_value).unwrap_or(Number::from(0)),
)
}
_ => Value::String(format!("{:?}", cql_value)),
}
}
Some(None) => Value::Null,
None => Value::Null,
};
row_map.insert(column_name, value);
}
results.push(Value::Object(row_map));
}
} else {
results.push(json!({
"status": "success",
"message": "Query executed successfully"
}));
}
Ok((results, columns))
}