* Note: This function currently implements defective behavior. * Storing an array schema that does not have a URI attached to it should * _not_ succeed. Users should be aware of this behavior and avoid storage of * schemas with empty URIs. * This defect is scheduled for fix asap, but must be documented in the interim. */
| 159 | * This defect is scheduled for fix asap, but must be documented in the interim. |
| 160 | */ |
| 161 | void store_array_schema( |
| 162 | ContextResources& resources, |
| 163 | const shared_ptr<ArraySchema>& array_schema, |
| 164 | const EncryptionKey& encryption_key) { |
| 165 | const URI schema_uri = array_schema->uri(); |
| 166 | |
| 167 | // Serialize |
| 168 | SizeComputationSerializer size_computation_serializer; |
| 169 | serialize_array_schema(size_computation_serializer, *array_schema); |
| 170 | |
| 171 | auto tile{WriterTile::from_generic( |
| 172 | size_computation_serializer.size(), |
| 173 | resources.ephemeral_memory_tracker())}; |
| 174 | Serializer serializer(tile->data(), tile->size()); |
| 175 | serialize_array_schema(serializer, *array_schema); |
| 176 | resources.stats().add_counter("write_array_schema_size", tile->size()); |
| 177 | |
| 178 | // Delete file if it exists already |
| 179 | if (resources.vfs().is_file(schema_uri)) { |
| 180 | resources.vfs().remove_file(schema_uri); |
| 181 | } |
| 182 | |
| 183 | // Check if the array schema directory exists |
| 184 | // If not create it, this is caused by a pre-v10 array |
| 185 | URI array_schema_dir_uri = |
| 186 | array_schema->array_uri().join_path(constants::array_schema_dir_name); |
| 187 | if (!resources.vfs().is_dir(array_schema_dir_uri)) { |
| 188 | resources.vfs().create_dir(array_schema_dir_uri); |
| 189 | } |
| 190 | |
| 191 | GenericTileIO::store_data(resources, schema_uri, tile, encryption_key); |
| 192 | |
| 193 | // Create the `__enumerations` directory under `__schema` if it doesn't |
| 194 | // exist. This might happen if someone tries to add an enumeration to an |
| 195 | // array created before version 19. |
| 196 | URI array_enumerations_dir_uri = |
| 197 | array_schema_dir_uri.join_path(constants::array_enumerations_dir_name); |
| 198 | if (!resources.vfs().is_dir(array_enumerations_dir_uri)) { |
| 199 | resources.vfs().create_dir(array_enumerations_dir_uri); |
| 200 | } |
| 201 | |
| 202 | // Serialize all enumerations into the `__enumerations` directory |
| 203 | for (auto& enmr_name : array_schema->get_loaded_enumeration_names()) { |
| 204 | auto enmr = array_schema->get_enumeration(enmr_name); |
| 205 | if (enmr == nullptr) { |
| 206 | throw std::runtime_error( |
| 207 | "Error serializing enumeration; Loaded enumeration is null"); |
| 208 | } |
| 209 | |
| 210 | SizeComputationSerializer enumeration_size_serializer; |
| 211 | enmr->serialize(enumeration_size_serializer); |
| 212 | |
| 213 | auto tile{WriterTile::from_generic( |
| 214 | enumeration_size_serializer.size(), |
| 215 | resources.ephemeral_memory_tracker())}; |
| 216 | Serializer serializer(tile->data(), tile->size()); |
| 217 | enmr->serialize(serializer); |
| 218 |