dpp/data_contract/v0/methods/
schema.rs

1use crate::data_contract::accessors::v0::DataContractV0Getters;
2use crate::data_contract::document_type::accessors::DocumentTypeV0Getters;
3use crate::data_contract::document_type::DocumentType;
4use crate::data_contract::schema::DataContractSchemaMethodsV0;
5use crate::data_contract::v0::DataContractV0;
6use crate::data_contract::{DefinitionName, DocumentName};
7use crate::validation::operations::ProtocolValidationOperation;
8use crate::ProtocolError;
9use platform_value::Value;
10use platform_version::version::PlatformVersion;
11use std::collections::BTreeMap;
12
13impl DataContractSchemaMethodsV0 for DataContractV0 {
14    fn set_document_schemas(
15        &mut self,
16        schemas: BTreeMap<DocumentName, Value>,
17        defs: Option<BTreeMap<DefinitionName, Value>>,
18        full_validation: bool,
19        validation_operations: &mut Vec<ProtocolValidationOperation>,
20        platform_version: &PlatformVersion,
21    ) -> Result<(), ProtocolError> {
22        self.document_types = DocumentType::create_document_types_from_document_schemas(
23            self.id,
24            self.system_version_type(),
25            self.config.version(),
26            schemas,
27            defs.as_ref(),
28            &BTreeMap::new(),
29            &self.config,
30            full_validation,
31            false,
32            validation_operations,
33            platform_version,
34        )?;
35
36        Ok(())
37    }
38
39    fn set_document_schema(
40        &mut self,
41        name: &str,
42        schema: Value,
43        full_validation: bool,
44        validation_operations: &mut Vec<ProtocolValidationOperation>,
45        platform_version: &PlatformVersion,
46    ) -> Result<(), ProtocolError> {
47        let document_type = DocumentType::try_from_schema(
48            self.id,
49            self.system_version_type(),
50            self.config.version(),
51            name,
52            schema,
53            self.schema_defs.as_ref(),
54            &BTreeMap::new(),
55            &self.config,
56            full_validation,
57            validation_operations,
58            platform_version,
59        )?;
60
61        self.document_types
62            .insert(document_type.name().clone(), document_type);
63
64        Ok(())
65    }
66
67    fn document_schemas(&self) -> BTreeMap<DocumentName, &Value> {
68        self.document_types
69            .iter()
70            .map(|(name, document_type)| (name.to_owned(), document_type.schema()))
71            .collect()
72    }
73
74    fn schema_defs(&self) -> Option<&BTreeMap<DefinitionName, Value>> {
75        self.schema_defs.as_ref()
76    }
77
78    fn set_schema_defs(
79        &mut self,
80        defs: Option<BTreeMap<DefinitionName, Value>>,
81        full_validation: bool,
82        validation_operations: &mut Vec<ProtocolValidationOperation>,
83        platform_version: &PlatformVersion,
84    ) -> Result<(), ProtocolError> {
85        let document_schemas = self
86            .document_types
87            .iter()
88            .map(|(name, document_type)| (name.to_owned(), document_type.schema().to_owned()))
89            .collect();
90
91        self.set_document_schemas(
92            document_schemas,
93            defs.clone(),
94            full_validation,
95            validation_operations,
96            platform_version,
97        )?;
98
99        self.schema_defs = defs;
100
101        Ok(())
102    }
103}
104
105#[cfg(test)]
106mod test {
107    use super::*;
108    use crate::data_contract::config::DataContractConfig;
109    use crate::data_contract::serialized_version::v0::DataContractInSerializationFormatV0;
110    use crate::data_contract::v0::DataContractV0;
111    use platform_value::{platform_value, Identifier};
112
113    #[test]
114    fn should_set_a_new_schema_defs() {
115        let platform_version = PlatformVersion::latest();
116
117        let config = DataContractConfig::default_for_version(platform_version)
118            .expect("should create a default config");
119
120        let schema = platform_value!({
121            "type": "object",
122            "properties": {
123                "a": {
124                    "type": "string",
125                    "maxLength": 10,
126                    "position": 0
127                }
128            },
129            "additionalProperties": false,
130        });
131
132        let serialization_format = DataContractInSerializationFormatV0 {
133            id: Identifier::random(),
134            config,
135            version: 0,
136            owner_id: Default::default(),
137            schema_defs: None,
138            document_schemas: BTreeMap::from([("document_type_name".to_string(), schema.clone())]),
139        };
140
141        let mut data_contract = DataContractV0::try_from_platform_versioned(
142            serialization_format.into(),
143            true,
144            &mut vec![],
145            platform_version,
146        )
147        .expect("should create a contract from serialization format");
148
149        let defs = platform_value!({
150            "test": {
151                "type": "string",
152            },
153        });
154
155        let defs_map = Some(defs.into_btree_string_map().expect("should convert to map"));
156
157        data_contract
158            .set_schema_defs(defs_map.clone(), true, &mut vec![], platform_version)
159            .expect("should set defs");
160
161        assert_eq!(defs_map.as_ref(), data_contract.schema_defs())
162    }
163
164    #[test]
165    fn should_set_empty_schema_defs() {
166        let platform_version = PlatformVersion::latest();
167
168        let config = DataContractConfig::default_for_version(platform_version)
169            .expect("should create a default config");
170
171        let defs = platform_value!({
172            "test": {
173                "type": "string",
174            },
175        });
176
177        let defs_map = Some(defs.into_btree_string_map().expect("should convert to map"));
178
179        let schema = platform_value!({
180            "type": "object",
181            "properties": {
182                "a": {
183                    "type": "string",
184                    "maxLength": 10,
185                    "position": 0
186                }
187            },
188            "additionalProperties": false,
189        });
190
191        let serialization_format = DataContractInSerializationFormatV0 {
192            id: Identifier::random(),
193            config,
194            version: 0,
195            owner_id: Default::default(),
196            schema_defs: defs_map,
197            document_schemas: BTreeMap::from([("document_type_name".to_string(), schema)]),
198        };
199
200        let mut data_contract = DataContractV0::try_from_platform_versioned(
201            serialization_format.into(),
202            true,
203            &mut vec![],
204            platform_version,
205        )
206        .expect("should create a contract from serialization format");
207
208        data_contract
209            .set_schema_defs(None, true, &mut vec![], platform_version)
210            .expect("should set defs");
211
212        assert_eq!(None, data_contract.schema_defs());
213        assert_eq!(
214            1,
215            data_contract.document_types().len(),
216            "document types should be preserved after clearing schema defs"
217        );
218    }
219}