|
|
@ -1,4 +1,5 @@ |
|
|
|
#[macro_use] extern crate serde_json; |
|
|
|
#[macro_use] extern crate serde_json; |
|
|
|
|
|
|
|
#[macro_use] extern crate log; |
|
|
|
|
|
|
|
|
|
|
|
use std::borrow::Cow; |
|
|
|
use std::borrow::Cow; |
|
|
|
use std::collections::HashMap; |
|
|
|
use std::collections::HashMap; |
|
|
@ -63,16 +64,15 @@ impl Storage { |
|
|
|
|
|
|
|
|
|
|
|
/// Define a data object
|
|
|
|
/// Define a data object
|
|
|
|
pub fn define_object(&mut self, mut tpl: model::ObjectModel) -> Result<ID, StorageError> { |
|
|
|
pub fn define_object(&mut self, mut tpl: model::ObjectModel) -> Result<ID, StorageError> { |
|
|
|
if let Some(pid) = tpl.parent { |
|
|
|
if tpl.name.is_empty() { |
|
|
|
if !self.obj_models.contains_key(&pid) { |
|
|
|
return Err(StorageError::ConstraintViolation("name must not be empty".into())); |
|
|
|
return Err(StorageError::NotExist(format!("parent object model {}", pid).into())); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
if self.obj_models.iter().find(|(_, t)| t.name == tpl.name).is_some() { |
|
|
|
if self.obj_models.iter().find(|(_, t)| t.name == tpl.name).is_some() { |
|
|
|
return Err(StorageError::ConstraintViolation(format!("object model with the name \"{}\" already exists", tpl.name).into())); |
|
|
|
return Err(StorageError::ConstraintViolation(format!("object model with the name \"{}\" already exists", tpl.name).into())); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
debug!("Define object model \"{}\"", tpl.name); |
|
|
|
let id = next_id(); |
|
|
|
let id = next_id(); |
|
|
|
tpl.id = id; |
|
|
|
tpl.id = id; |
|
|
|
self.obj_models.insert(id, tpl); |
|
|
|
self.obj_models.insert(id, tpl); |
|
|
@ -81,6 +81,10 @@ impl Storage { |
|
|
|
|
|
|
|
|
|
|
|
/// Define a relation between two data objects
|
|
|
|
/// Define a relation between two data objects
|
|
|
|
pub fn define_relation(&mut self, mut rel: model::RelationModel) -> Result<ID, StorageError> { |
|
|
|
pub fn define_relation(&mut self, mut rel: model::RelationModel) -> Result<ID, StorageError> { |
|
|
|
|
|
|
|
if rel.name.is_empty() { |
|
|
|
|
|
|
|
return Err(StorageError::ConstraintViolation("name must not be empty".into())); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
if !self.obj_models.contains_key(&rel.object) { |
|
|
|
if !self.obj_models.contains_key(&rel.object) { |
|
|
|
return Err(StorageError::NotExist(format!("source object model {}", rel.object).into())); |
|
|
|
return Err(StorageError::NotExist(format!("source object model {}", rel.object).into())); |
|
|
|
} |
|
|
|
} |
|
|
@ -93,6 +97,7 @@ impl Storage { |
|
|
|
format!("relation with the name \"{}\" and on model {} already exists", rel.name, rel.object).into())); |
|
|
|
format!("relation with the name \"{}\" and on model {} already exists", rel.name, rel.object).into())); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
debug!("Define relation model \"{}\" from {} to {}", rel.name, self.describe_model(rel.object), self.describe_model(rel.related)); |
|
|
|
let id = next_id(); |
|
|
|
let id = next_id(); |
|
|
|
rel.id = id; |
|
|
|
rel.id = id; |
|
|
|
self.rel_models.insert(id, rel); |
|
|
|
self.rel_models.insert(id, rel); |
|
|
@ -101,6 +106,10 @@ impl Storage { |
|
|
|
|
|
|
|
|
|
|
|
/// Define a property attached to an object or a relation
|
|
|
|
/// Define a property attached to an object or a relation
|
|
|
|
pub fn define_property(&mut self, mut prop: model::PropertyModel) -> Result<ID, StorageError> { |
|
|
|
pub fn define_property(&mut self, mut prop: model::PropertyModel) -> Result<ID, StorageError> { |
|
|
|
|
|
|
|
if prop.name.is_empty() { |
|
|
|
|
|
|
|
return Err(StorageError::ConstraintViolation("name must not be empty".into())); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
if !self.obj_models.contains_key(&prop.object) { |
|
|
|
if !self.obj_models.contains_key(&prop.object) { |
|
|
|
// Maybe it's attached to a relation?
|
|
|
|
// Maybe it's attached to a relation?
|
|
|
|
if !self.rel_models.contains_key(&prop.object) { |
|
|
|
if !self.rel_models.contains_key(&prop.object) { |
|
|
@ -121,6 +130,7 @@ impl Storage { |
|
|
|
}); |
|
|
|
}); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
debug!("Define property model \"{}\" of {}", prop.name, self.describe_model(prop.object)); |
|
|
|
let id = next_id(); |
|
|
|
let id = next_id(); |
|
|
|
prop.id = id; |
|
|
|
prop.id = id; |
|
|
|
self.prop_models.insert(id, prop); |
|
|
|
self.prop_models.insert(id, prop); |
|
|
@ -130,6 +140,7 @@ impl Storage { |
|
|
|
/// Delete an object definition and associated data
|
|
|
|
/// Delete an object definition and associated data
|
|
|
|
pub fn undefine_object(&mut self, id: ID) -> Result<ObjectModel, StorageError> { |
|
|
|
pub fn undefine_object(&mut self, id: ID) -> Result<ObjectModel, StorageError> { |
|
|
|
return if let Some(t) = self.obj_models.remove(&id) { |
|
|
|
return if let Some(t) = self.obj_models.remove(&id) { |
|
|
|
|
|
|
|
debug!("Undefine object model \"{}\"", t.name); |
|
|
|
// Remove relation templates
|
|
|
|
// Remove relation templates
|
|
|
|
let removed_relation_ids = map_drain_filter(&mut self.rel_models, |_k, v| v.object == id || v.related == id) |
|
|
|
let removed_relation_ids = map_drain_filter(&mut self.rel_models, |_k, v| v.object == id || v.related == id) |
|
|
|
.keys(); |
|
|
|
.keys(); |
|
|
@ -158,6 +169,8 @@ impl Storage { |
|
|
|
/// Delete a relation definition and associated data
|
|
|
|
/// Delete a relation definition and associated data
|
|
|
|
pub fn undefine_relation(&mut self, id: ID) -> Result<model::RelationModel, StorageError> { |
|
|
|
pub fn undefine_relation(&mut self, id: ID) -> Result<model::RelationModel, StorageError> { |
|
|
|
return if let Some(t) = self.rel_models.remove(&id) { |
|
|
|
return if let Some(t) = self.rel_models.remove(&id) { |
|
|
|
|
|
|
|
debug!("Undefine relation model \"{}\"", t.name); |
|
|
|
|
|
|
|
|
|
|
|
// Remove relations
|
|
|
|
// Remove relations
|
|
|
|
let _ = map_drain_filter(&mut self.relations, |_k, v| v.model == id).keys(); |
|
|
|
let _ = map_drain_filter(&mut self.relations, |_k, v| v.model == id).keys(); |
|
|
|
|
|
|
|
|
|
|
@ -177,6 +190,8 @@ impl Storage { |
|
|
|
/// Delete a property definition and associated data
|
|
|
|
/// Delete a property definition and associated data
|
|
|
|
pub fn undefine_property(&mut self, id: ID) -> Result<model::PropertyModel, StorageError> { |
|
|
|
pub fn undefine_property(&mut self, id: ID) -> Result<model::PropertyModel, StorageError> { |
|
|
|
return if let Some(t) = self.prop_models.remove(&id) { |
|
|
|
return if let Some(t) = self.prop_models.remove(&id) { |
|
|
|
|
|
|
|
debug!("Undefine property model \"{}\"", t.name); |
|
|
|
|
|
|
|
|
|
|
|
// Remove relations
|
|
|
|
// Remove relations
|
|
|
|
let _ = map_drain_filter(&mut self.properties, |_k, v| v.model == id); |
|
|
|
let _ = map_drain_filter(&mut self.properties, |_k, v| v.model == id); |
|
|
|
Ok(t) |
|
|
|
Ok(t) |
|
|
@ -214,6 +229,7 @@ impl Storage { |
|
|
|
/// Insert object with relations, validating the data model constraints
|
|
|
|
/// Insert object with relations, validating the data model constraints
|
|
|
|
pub fn insert_object(&mut self, insobj: InsertObj) -> Result<ID, StorageError> { |
|
|
|
pub fn insert_object(&mut self, insobj: InsertObj) -> Result<ID, StorageError> { |
|
|
|
let obj_model_id = insobj.model_id; |
|
|
|
let obj_model_id = insobj.model_id; |
|
|
|
|
|
|
|
debug!("Insert object {:?}", insobj); |
|
|
|
|
|
|
|
|
|
|
|
let obj_model = match self.obj_models.get(&obj_model_id) { |
|
|
|
let obj_model = match self.obj_models.get(&obj_model_id) { |
|
|
|
Some(m) => m, |
|
|
|
Some(m) => m, |
|
|
|