use jammi_db::store::mutable::{
MutableIndexDef, MutableTableDefinition, MutableTableDefinitionBuilder, MutableTableId,
};
use jammi_db::TenantId;
use tonic::Status;
use crate::encode_ipc_stream;
use crate::proto::catalog as pb;
pub fn definition_from_proto(
def: pb::MutableTableDefinition,
tenant: Option<TenantId>,
) -> Result<MutableTableDefinition, Status> {
let id = parse_table_id(&def.id)?;
let schema = super::decode_ipc_schema(&def.schema)?;
let mut builder = MutableTableDefinitionBuilder::new(id, schema)
.primary_key(def.primary_key)
.tenant(tenant);
for idx in def.indexes {
builder = builder.index(MutableIndexDef {
name: idx.name,
columns: idx.columns,
unique: idx.unique,
});
}
if !def.order_column.is_empty() {
builder = builder.order_column(def.order_column);
}
if def.chunk_size != 0 {
builder = builder.chunk_size(def.chunk_size as usize);
}
if !def.user_metadata.is_empty() {
let value: serde_json::Value = serde_json::from_str(&def.user_metadata)
.map_err(|e| Status::invalid_argument(format!("user_metadata is not JSON: {e}")))?;
builder = builder.user_metadata(value);
}
builder
.build()
.map_err(|e| Status::invalid_argument(e.to_string()))
}
pub fn definition_to_proto(
def: &MutableTableDefinition,
) -> Result<pb::MutableTableDefinition, Status> {
let schema = encode_ipc_stream(&def.schema, &[])?;
Ok(pb::MutableTableDefinition {
id: def.id.to_string(),
schema,
primary_key: def.primary_key.clone(),
indexes: def
.indexes
.iter()
.map(|idx| pb::MutableIndex {
name: idx.name.clone(),
columns: idx.columns.clone(),
unique: idx.unique,
})
.collect(),
order_column: def.order_column.clone().unwrap_or_default(),
chunk_size: def.chunk_size as u64,
user_metadata: def.user_metadata.to_string(),
})
}
pub fn definition_list_from_proto(
def: pb::MutableTableDefinition,
) -> Result<MutableTableDefinition, Status> {
definition_from_proto(def, None)
}
pub fn parse_table_id(id: &str) -> Result<MutableTableId, Status> {
if id.is_empty() {
return Err(Status::invalid_argument("mutable_table_id is required"));
}
MutableTableId::new(id).map_err(|e| Status::invalid_argument(e.to_string()))
}