operations.rs 5.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141
  1. use crate::{Error, InputPropertyValue, InputValue, PropertyId, SchemaId, Trait, VecInputValue};
  2. use codec::{Decode, Encode};
  3. use sp_std::collections::btree_map::BTreeMap;
  4. use sp_std::prelude::*;
  5. /// Parametrized entity property value
  6. #[derive(Encode, Decode, Eq, PartialEq, Clone)]
  7. pub enum ParametrizedPropertyValue<T: Trait> {
  8. /// Same fields as normal InputPropertyValue
  9. InputPropertyValue(InputPropertyValue<T>),
  10. /// This is the index of an operation creating an entity in the transaction/batch operations
  11. InternalEntityJustAdded(u32), // should really be usize but it doesn't have Encode/Decode support
  12. /// Vector of mix of Entities already existing and just added in a recent operation
  13. InternalEntityVec(Vec<ParameterizedEntity<T>>),
  14. }
  15. /// Parametrized entity
  16. #[derive(Encode, Decode, Eq, PartialEq, Clone)]
  17. pub enum ParameterizedEntity<T: Trait> {
  18. InternalEntityJustAdded(u32),
  19. ExistingEntity(T::EntityId),
  20. }
  21. /// Parametrized class property value
  22. #[derive(Encode, Decode, Eq, PartialEq, Clone)]
  23. pub struct ParametrizedClassPropertyValue<T: Trait> {
  24. /// Index is into properties vector of class.
  25. pub in_class_index: PropertyId,
  26. /// InputValue of property with index `in_class_index` in a given class.
  27. pub value: ParametrizedPropertyValue<T>,
  28. }
  29. /// Operation, that represents `Entity` creation
  30. #[derive(Encode, Decode, Eq, PartialEq, Clone)]
  31. pub struct CreateEntityOperation<T: Trait> {
  32. /// Class of an Entity
  33. pub class_id: T::ClassId,
  34. }
  35. /// Operation, that represents property values update
  36. #[derive(Encode, Decode, Eq, PartialEq, Clone)]
  37. pub struct UpdatePropertyValuesOperation<T: Trait> {
  38. /// Entity id to perfrom operation
  39. pub entity_id: ParameterizedEntity<T>,
  40. /// Property values, that should be updated
  41. pub new_parametrized_property_values: Vec<ParametrizedClassPropertyValue<T>>,
  42. }
  43. /// Operation, that represents adding `Entity` `Schema` support
  44. #[derive(Encode, Decode, Eq, PartialEq, Clone)]
  45. pub struct AddSchemaSupportToEntityOperation<T: Trait> {
  46. /// Entity id to perfrom operation
  47. pub entity_id: ParameterizedEntity<T>,
  48. /// Schema id defined on `Class` level to be added to the `Entity`
  49. pub schema_id: SchemaId,
  50. /// Property values, that should be added for the underlying schema_id
  51. pub parametrized_property_values: Vec<ParametrizedClassPropertyValue<T>>,
  52. }
  53. /// The type of operation performed
  54. #[derive(Encode, Decode, Eq, PartialEq, Clone)]
  55. pub enum OperationType<T: Trait> {
  56. CreateEntity(CreateEntityOperation<T>),
  57. UpdatePropertyValues(UpdatePropertyValuesOperation<T>),
  58. AddSchemaSupportToEntity(AddSchemaSupportToEntityOperation<T>),
  59. }
  60. impl<T: Trait> core::fmt::Debug for OperationType<T> {
  61. fn fmt(&self, formatter: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
  62. write!(formatter, "OperationType {:?}", self)
  63. }
  64. }
  65. /// Retrieve entity_id of parametrized `Entity`
  66. pub fn parametrized_entity_to_entity_id<T: Trait>(
  67. created_entities: &BTreeMap<usize, T::EntityId>,
  68. entity: ParameterizedEntity<T>,
  69. ) -> Result<T::EntityId, Error<T>> {
  70. match entity {
  71. ParameterizedEntity::ExistingEntity(entity_id) => Ok(entity_id),
  72. ParameterizedEntity::InternalEntityJustAdded(op_index_u32) => {
  73. let op_index = op_index_u32 as usize;
  74. Ok(*created_entities
  75. .get(&op_index)
  76. .ok_or(Error::<T>::EntityNotCreatedByOperation)?)
  77. }
  78. }
  79. }
  80. /// Convert parametrized property values into property values
  81. pub fn parametrized_property_values_to_property_values<T: Trait>(
  82. created_entities: &BTreeMap<usize, T::EntityId>,
  83. parametrized_property_values: Vec<ParametrizedClassPropertyValue<T>>,
  84. ) -> Result<BTreeMap<PropertyId, InputPropertyValue<T>>, Error<T>> {
  85. let mut class_property_values = BTreeMap::new();
  86. for parametrized_class_property_value in parametrized_property_values.into_iter() {
  87. let property_value = match parametrized_class_property_value.value {
  88. ParametrizedPropertyValue::InputPropertyValue(value) => value,
  89. ParametrizedPropertyValue::InternalEntityJustAdded(
  90. entity_created_in_operation_index,
  91. ) => {
  92. // Verify that referenced entity was indeed created created
  93. let op_index = entity_created_in_operation_index as usize;
  94. let entity_id = created_entities
  95. .get(&op_index)
  96. .ok_or(Error::<T>::EntityNotCreatedByOperation)?;
  97. InputPropertyValue::Single(InputValue::Reference(*entity_id))
  98. }
  99. ParametrizedPropertyValue::InternalEntityVec(parametrized_entities) => {
  100. let mut entities: Vec<T::EntityId> = vec![];
  101. for parametrized_entity in parametrized_entities.into_iter() {
  102. match parametrized_entity {
  103. ParameterizedEntity::ExistingEntity(id) => entities.push(id),
  104. ParameterizedEntity::InternalEntityJustAdded(
  105. entity_created_in_operation_index,
  106. ) => {
  107. let op_index = entity_created_in_operation_index as usize;
  108. let entity_id = created_entities
  109. .get(&op_index)
  110. .ok_or(Error::<T>::EntityNotCreatedByOperation)?;
  111. entities.push(*entity_id);
  112. }
  113. }
  114. }
  115. InputPropertyValue::Vector(VecInputValue::Reference(entities))
  116. }
  117. };
  118. class_property_values.insert(
  119. parametrized_class_property_value.in_class_index,
  120. property_value,
  121. );
  122. }
  123. Ok(class_property_values)
  124. }