|
|
|
@ -92,12 +92,22 @@ impl Storage { |
|
|
|
|
return Err(StorageError::NotExist(format!("related object model {}", rel.related).into())); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
if self.rel_models.iter().find(|(_, t)| t.name == rel.name && t.object == rel.object).is_some() { |
|
|
|
|
if let Some((_, colliding)) = self.rel_models.iter().find(|(_, other)| { |
|
|
|
|
(other.name == rel.name && other.object == rel.object) // Exact match
|
|
|
|
|
|| (other.name == rel.reciprocal_name && other.object == rel.related) // Our reciprocal name collides with related's own relation name
|
|
|
|
|
|| (other.reciprocal_name == rel.name && other.related == rel.object) // Our name name collides with a reciprocal name on the other relation
|
|
|
|
|
|| (other.reciprocal_name == rel.reciprocal_name && other.related == rel.related) // Reciprocal names collide for the same destination
|
|
|
|
|
}) { |
|
|
|
|
return Err(StorageError::ConstraintViolation( |
|
|
|
|
format!("relation with the name \"{}\" and on model {} already exists", rel.name, rel.object).into())); |
|
|
|
|
format!("name collision (\"{}\" / \"{}\") with existing relation (\"{}\" / \"{}\")", |
|
|
|
|
rel.name, rel.reciprocal_name, |
|
|
|
|
colliding.name, colliding.reciprocal_name |
|
|
|
|
).into())); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
debug!("Define relation model \"{}\" from {} to {}", rel.name, self.describe_model(rel.object), self.describe_model(rel.related)); |
|
|
|
|
debug!("Define relation model \"{}\" from {} to {}, reciprocal name \"{}\"", |
|
|
|
|
rel.name, self.describe_model(rel.object), self.describe_model(rel.related), rel.reciprocal_name); |
|
|
|
|
|
|
|
|
|
let id = next_id(); |
|
|
|
|
rel.id = id; |
|
|
|
|
self.rel_models.insert(id, rel); |
|
|
|
|