use nodedb_types::result::QueryResult;
use nodedb_types::value::Value;
use crate::error::LiteError;
use crate::query::engine::LiteQueryEngine;
use crate::storage::engine::StorageEngine;
use super::parser::parse_strict_create_sql;
impl<S: StorageEngine> LiteQueryEngine<S> {
pub(in crate::query) async fn handle_create_columnar(
&self,
sql: &str,
) -> Result<QueryResult, LiteError> {
let (name, strict_schema) = parse_strict_create_sql(sql)?;
let mut columnar_schema =
nodedb_types::columnar::ColumnarSchema::new(strict_schema.columns)
.map_err(|e| LiteError::Query(e.to_string()))?;
let upper = sql.to_uppercase();
let profile = if upper.contains("PROFILE") && upper.contains("SPATIAL") {
let geom_col = columnar_schema
.columns
.iter()
.find(|c| matches!(c.column_type, nodedb_types::columnar::ColumnType::Geometry))
.map(|c| c.name.clone())
.unwrap_or_default();
let has_geohash = columnar_schema.columns.iter().any(|c| c.name == "_geohash");
if !has_geohash {
columnar_schema
.columns
.push(nodedb_types::columnar::ColumnDef::nullable(
"_geohash",
nodedb_types::columnar::ColumnType::String,
));
}
nodedb_types::columnar::ColumnarProfile::Spatial {
geometry_column: geom_col,
auto_rtree: true,
auto_geohash: true,
}
} else {
nodedb_types::columnar::ColumnarProfile::Plain
};
let bitemporal = {
let u = sql.to_uppercase();
u.contains("BITEMPORAL")
&& (u.contains("TRUE") || u.contains("=TRUE") || u.contains("= TRUE"))
};
let collection_type = match &profile {
nodedb_types::columnar::ColumnarProfile::Spatial {
geometry_column, ..
} => nodedb_types::collection::CollectionType::spatial(geometry_column.as_str()),
_ => nodedb_types::collection::CollectionType::columnar(),
};
let fields: Vec<(String, String)> = columnar_schema
.columns
.iter()
.map(|c| (c.name.clone(), c.column_type.to_string()))
.collect();
self.columnar
.create_collection(&name, columnar_schema, profile, bitemporal)
.await?;
self.register_columnar_collection(&name);
self.persist_engine_collection_meta(&name, collection_type, fields, bitemporal)
.await?;
Ok(QueryResult {
columns: vec!["result".into()],
rows: vec![vec![Value::String(format!(
"columnar collection '{name}' created"
))]],
rows_affected: 0,
command: None,
})
}
pub(in crate::query) async fn handle_drop_columnar(
&self,
name: &str,
) -> Result<QueryResult, LiteError> {
self.columnar.drop_collection(name).await?;
self.remove_engine_collection_meta(name).await?;
Ok(QueryResult {
columns: vec!["result".into()],
rows: vec![vec![Value::String(format!(
"columnar collection '{name}' dropped"
))]],
rows_affected: 0,
command: None,
})
}
}