dpp/data_contract/v1/methods/
schema.rs1use crate::data_contract::accessors::v0::DataContractV0Getters;
2use crate::data_contract::accessors::v1::DataContractV1Getters;
3use crate::data_contract::document_type::accessors::DocumentTypeV0Getters;
4use crate::data_contract::document_type::DocumentType;
5use crate::data_contract::schema::DataContractSchemaMethodsV0;
6use crate::data_contract::{DataContractV1, 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 DataContractV1 {
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 &self.tokens,
29 &self.config,
30 full_validation,
31 !self.tokens.is_empty(),
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 self.tokens(),
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::v1::DataContractV1;
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 = DataContractV1::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 = DataContractV1::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}