use crate::db::{
RowProjectionOutput,
sql::{
SqlConstraintValidationOutput, SqlGroupedRowsOutput, SqlQueryResult,
value_render::{render_projection_value_text, sql_projection_output_rows},
},
};
use icydb_core::db::{GroupedRow, SqlStatementResult};
pub(crate) fn sql_query_result_from_statement(
result: SqlStatementResult,
entity_name: String,
) -> SqlQueryResult {
match result {
SqlStatementResult::Count { row_count } => SqlQueryResult::Count {
entity: entity_name,
row_count,
},
SqlStatementResult::Projection {
columns,
fixed_scales,
rows,
row_count,
} => {
let rows = sql_projection_output_rows(fixed_scales.as_slice(), rows);
SqlQueryResult::Projection(RowProjectionOutput {
entity: entity_name,
columns,
rows,
row_count,
})
}
SqlStatementResult::Grouped {
columns,
fixed_scales,
rows,
row_count,
next_cursor,
} => SqlQueryResult::Grouped(sql_grouped_rows_output(
entity_name,
columns,
fixed_scales,
rows,
row_count,
next_cursor,
)),
#[cfg(feature = "sql")]
SqlStatementResult::Explain(explain) => SqlQueryResult::Explain {
entity: entity_name,
explain,
},
SqlStatementResult::Describe(output) => SqlQueryResult::Describe(output),
SqlStatementResult::ShowConstraints(constraints) => SqlQueryResult::ShowConstraints {
entity: entity_name,
constraints,
},
SqlStatementResult::ShowIndexes(indexes) => SqlQueryResult::ShowIndexes {
entity: entity_name,
indexes,
},
SqlStatementResult::ShowColumns(output) => SqlQueryResult::ShowColumns(output),
SqlStatementResult::ShowRelations(output) => SqlQueryResult::ShowRelations(output),
SqlStatementResult::ShowEntities { entities, verbose } => {
SqlQueryResult::ShowEntities { entities, verbose }
}
SqlStatementResult::ShowStores { stores, verbose } => {
SqlQueryResult::ShowStores { stores, verbose }
}
SqlStatementResult::ShowMemory(memory) => SqlQueryResult::ShowMemory { memory },
SqlStatementResult::Ddl(report) => SqlQueryResult::Ddl {
entity: entity_name,
mutation_kind: report.mutation_kind().as_str().to_string(),
target_index: report.target_index().to_string(),
target_store: report.target_store().to_string(),
field_path: report.field_path().to_vec(),
status: report.execution_status().as_str().to_string(),
rows_scanned: usize_to_u64_saturating(report.rows_scanned()),
index_keys_written: usize_to_u64_saturating(report.index_keys_written()),
constraint_validation: report.constraint_validation().map(|validation| {
SqlConstraintValidationOutput {
constraint_id: validation.constraint_id(),
activation_epoch: validation.activation_epoch(),
page_sequence: validation.page_sequence(),
state: validation.state().as_str().to_string(),
revision_status: validation.revision_status().as_str().to_string(),
rows_scanned: validation.rows_scanned(),
findings: validation.findings().to_vec(),
complete: validation.complete(),
}
}),
},
}
}
fn usize_to_u64_saturating(value: usize) -> u64 {
u64::try_from(value).unwrap_or(u64::MAX)
}
fn sql_grouped_rows_output(
entity_name: String,
columns: Vec<String>,
fixed_scales: Vec<Option<u32>>,
rows: Vec<GroupedRow>,
row_count: u32,
next_cursor: Option<String>,
) -> SqlGroupedRowsOutput {
let rows = rows
.into_iter()
.map(|row| {
row.group_key()
.iter()
.chain(row.aggregate_values().iter())
.enumerate()
.map(|(index, value)| {
render_projection_value_text(fixed_scales.get(index).copied().flatten(), value)
})
.collect::<Vec<_>>()
})
.collect::<Vec<_>>();
SqlGroupedRowsOutput {
entity: entity_name,
columns,
rows,
row_count,
next_cursor,
}
}