use crate::db::{
EntityFieldDescription, EntitySchemaDescription,
sql::table_render::{
render_count_lines, render_describe_lines, render_explain_lines, render_grouped_lines,
render_query_rows_lines, render_show_columns_lines, render_show_entities_lines,
render_show_indexes_lines,
},
};
use candid::CandidType;
use serde::Deserialize;
#[cfg_attr(doc, doc = "SqlProjectionRows\n\nRender-ready SQL projection rows.")]
#[derive(Clone, Debug, Eq, PartialEq)]
pub struct SqlProjectionRows {
columns: Vec<String>,
rows: Vec<Vec<String>>,
row_count: u32,
}
impl SqlProjectionRows {
#[must_use]
pub const fn new(columns: Vec<String>, rows: Vec<Vec<String>>, row_count: u32) -> Self {
Self {
columns,
rows,
row_count,
}
}
#[must_use]
pub const fn columns(&self) -> &[String] {
self.columns.as_slice()
}
#[must_use]
pub const fn rows(&self) -> &[Vec<String>] {
self.rows.as_slice()
}
#[must_use]
pub const fn row_count(&self) -> u32 {
self.row_count
}
#[must_use]
pub fn into_parts(self) -> (Vec<String>, Vec<Vec<String>>, u32) {
(self.columns, self.rows, self.row_count)
}
}
#[cfg_attr(doc, doc = "SqlQueryRowsOutput\n\nStructured SQL projection payload.")]
#[derive(CandidType, Clone, Debug, Deserialize, Eq, PartialEq)]
pub struct SqlQueryRowsOutput {
pub entity: String,
pub columns: Vec<String>,
pub rows: Vec<Vec<String>>,
pub row_count: u32,
}
impl SqlQueryRowsOutput {
#[must_use]
pub fn from_projection(entity: String, projection: SqlProjectionRows) -> Self {
let (columns, rows, row_count) = projection.into_parts();
Self {
entity,
columns,
rows,
row_count,
}
}
#[must_use]
pub fn as_projection_rows(&self) -> SqlProjectionRows {
SqlProjectionRows::new(self.columns.clone(), self.rows.clone(), self.row_count)
}
}
#[cfg_attr(doc, doc = "SqlGroupedRowsOutput\n\nStructured grouped SQL payload.")]
#[derive(CandidType, Clone, Debug, Deserialize, Eq, PartialEq)]
pub struct SqlGroupedRowsOutput {
pub entity: String,
pub columns: Vec<String>,
pub rows: Vec<Vec<String>>,
pub row_count: u32,
pub next_cursor: Option<String>,
}
#[cfg_attr(doc, doc = "SqlQueryResult\n\nUnified SQL endpoint result.")]
#[derive(CandidType, Clone, Debug, Deserialize, Eq, PartialEq)]
pub enum SqlQueryResult {
Count {
entity: String,
row_count: u32,
},
Projection(SqlQueryRowsOutput),
Grouped(SqlGroupedRowsOutput),
Explain {
entity: String,
explain: String,
},
Describe(EntitySchemaDescription),
ShowIndexes {
entity: String,
indexes: Vec<String>,
},
ShowColumns {
entity: String,
columns: Vec<EntityFieldDescription>,
},
ShowEntities {
entities: Vec<String>,
},
}
impl SqlQueryResult {
#[must_use]
pub fn render_lines(&self) -> Vec<String> {
match self {
Self::Count { entity, row_count } => render_count_lines(entity.as_str(), *row_count),
Self::Projection(rows) => render_query_rows_lines(rows),
Self::Grouped(rows) => render_grouped_lines(rows),
Self::Explain { explain, .. } => render_explain_lines(explain.as_str()),
Self::Describe(description) => render_describe_lines(description),
Self::ShowIndexes { entity, indexes } => {
render_show_indexes_lines(entity.as_str(), indexes.as_slice())
}
Self::ShowColumns { entity, columns } => {
render_show_columns_lines(entity.as_str(), columns.as_slice())
}
Self::ShowEntities { entities } => render_show_entities_lines(entities.as_slice()),
}
}
#[must_use]
pub fn render_text(&self) -> String {
self.render_lines().join("\n")
}
}