use std::sync::Arc;
use serde::Deserialize;
use serde_json::Value;
use super::{columns::ExaColumns, to_row_major};
use crate::{column::ExaColumn, error::ExaProtocolError};
#[derive(Debug, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct MultiResults {
pub results: Vec<QueryResult>,
}
#[derive(Debug, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct SingleResult {
pub results: [QueryResult; 1],
}
impl From<SingleResult> for QueryResult {
fn from(value: SingleResult) -> Self {
value
.results
.into_iter()
.next()
.expect("query result array must have one element")
}
}
#[derive(Debug, Deserialize)]
#[serde(tag = "resultType")]
#[serde(rename_all = "camelCase")]
pub enum QueryResult {
#[serde(rename_all = "camelCase")]
ResultSet { result_set: ResultSet },
#[serde(rename_all = "camelCase")]
RowCount { row_count: u64 },
}
impl QueryResult {
pub fn handle(&self) -> Option<u16> {
let result_set = match self {
QueryResult::ResultSet { result_set } => result_set,
QueryResult::RowCount { .. } => return None,
};
match result_set.output {
ResultSetOutput::Handle(handle) => Some(handle),
ResultSetOutput::Data(_) => None,
}
}
}
#[derive(Debug, Deserialize)]
#[serde(try_from = "ResultSetDe")]
pub struct ResultSet {
pub total_rows_num: usize,
pub total_rows_pos: usize,
pub output: ResultSetOutput,
pub columns: Arc<[ExaColumn]>,
}
impl TryFrom<ResultSetDe> for ResultSet {
type Error = ExaProtocolError;
fn try_from(value: ResultSetDe) -> Result<Self, Self::Error> {
let data = match value.result_set_handle {
None => ResultSetOutput::Data(value.data),
Some(handle) => ResultSetOutput::Handle(handle),
};
let result_set = Self {
total_rows_num: value.num_rows,
total_rows_pos: value.num_rows_in_message,
output: data,
columns: value.columns.0.into(),
};
Ok(result_set)
}
}
#[derive(Debug)]
pub enum ResultSetOutput {
Handle(u16),
Data(Vec<Vec<Value>>),
}
#[derive(Debug, Deserialize)]
#[serde(rename_all = "camelCase")]
struct ResultSetDe {
num_rows: usize,
result_set_handle: Option<u16>,
#[serde(default)]
#[serde(deserialize_with = "to_row_major")]
data: Vec<Vec<Value>>,
columns: ExaColumns,
num_rows_in_message: usize,
}