text_document_common/direct_access/block/
block_table.rs1use crate::database::hashmap_store::{
2 HashMapStore, delete_from_backward_junction, junction_get, junction_remove, junction_set,
3};
4use crate::entities::*;
5use crate::error::RepositoryError;
6use crate::types::EntityId;
7use crate::{impl_relationship_methods, impl_write_relationship_methods};
8use std::collections::HashMap;
9use std::sync::RwLock;
10
11use super::block_repository::{BlockRelationshipField, BlockTable, BlockTableRO};
12
13pub struct BlockHashMapTable<'a> {
14 store: &'a HashMapStore,
15}
16
17impl<'a> BlockHashMapTable<'a> {
18 pub fn new(store: &'a HashMapStore) -> Self {
19 Self { store }
20 }
21
22 fn resolve_junction(
23 &self,
24 field: &BlockRelationshipField,
25 ) -> &RwLock<HashMap<EntityId, Vec<EntityId>>> {
26 match field {
27 BlockRelationshipField::Elements => &self.store.jn_inline_element_from_block_elements,
28 BlockRelationshipField::List => &self.store.jn_list_from_block_list,
29 }
30 }
31
32 fn hydrate(&self, entity: &mut Block) {
33 entity.elements = junction_get(
34 &self.store.jn_inline_element_from_block_elements,
35 &entity.id,
36 );
37 entity.list = junction_get(&self.store.jn_list_from_block_list, &entity.id)
38 .into_iter()
39 .next();
40 }
41}
42
43impl<'a> BlockTable for BlockHashMapTable<'a> {
44 fn create(&mut self, entity: &Block) -> Result<Block, RepositoryError> {
45 self.create_multi(std::slice::from_ref(entity))
46 .map(|v| v.into_iter().next().unwrap())
47 }
48
49 fn create_multi(&mut self, entities: &[Block]) -> Result<Vec<Block>, RepositoryError> {
50 let mut created = Vec::with_capacity(entities.len());
51 let mut blocks = self.store.blocks.write().unwrap();
52
53 for entity in entities {
54 let new_entity = if entity.id == EntityId::default() {
55 let id = self.store.next_id("block");
56 Block {
57 id,
58 ..entity.clone()
59 }
60 } else {
61 if blocks.contains_key(&entity.id) {
62 return Err(RepositoryError::DuplicateId {
63 entity: "Block",
64 id: entity.id,
65 });
66 }
67 entity.clone()
68 };
69
70 blocks.insert(new_entity.id, new_entity.clone());
71 junction_set(
72 &self.store.jn_inline_element_from_block_elements,
73 new_entity.id,
74 new_entity.elements.clone(),
75 );
76 junction_set(
77 &self.store.jn_list_from_block_list,
78 new_entity.id,
79 new_entity.list.into_iter().collect(),
80 );
81 created.push(new_entity);
82 }
83 Ok(created)
84 }
85
86 fn get(&self, id: &EntityId) -> Result<Option<Block>, RepositoryError> {
87 let blocks = self.store.blocks.read().unwrap();
88 match blocks.get(id) {
89 Some(entity) => {
90 let mut e = entity.clone();
91 drop(blocks);
92 self.hydrate(&mut e);
93 Ok(Some(e))
94 }
95 None => Ok(None),
96 }
97 }
98
99 fn get_multi(&self, ids: &[EntityId]) -> Result<Vec<Option<Block>>, RepositoryError> {
100 let mut result = Vec::with_capacity(ids.len());
101 for id in ids {
102 result.push(self.get(id)?);
103 }
104 Ok(result)
105 }
106
107 fn get_all(&self) -> Result<Vec<Block>, RepositoryError> {
108 let blocks = self.store.blocks.read().unwrap();
109 let entries: Vec<Block> = blocks.values().cloned().collect();
110 drop(blocks);
111 let mut result = Vec::with_capacity(entries.len());
112 for mut entity in entries {
113 self.hydrate(&mut entity);
114 result.push(entity);
115 }
116 Ok(result)
117 }
118
119 fn update(&mut self, entity: &Block) -> Result<Block, RepositoryError> {
120 self.update_multi(std::slice::from_ref(entity))
121 .map(|v| v.into_iter().next().unwrap())
122 }
123
124 fn update_multi(&mut self, entities: &[Block]) -> Result<Vec<Block>, RepositoryError> {
125 let mut blocks = self.store.blocks.write().unwrap();
126 for entity in entities {
127 blocks.insert(entity.id, entity.clone());
128 }
129 drop(blocks);
130 let ids: Vec<EntityId> = entities.iter().map(|e| e.id).collect();
131 let result = self.get_multi(&ids)?;
132 Ok(result.into_iter().flatten().collect())
133 }
134
135 fn update_with_relationships(&mut self, entity: &Block) -> Result<Block, RepositoryError> {
136 self.update_with_relationships_multi(std::slice::from_ref(entity))
137 .map(|v| v.into_iter().next().unwrap())
138 }
139
140 fn update_with_relationships_multi(
141 &mut self,
142 entities: &[Block],
143 ) -> Result<Vec<Block>, RepositoryError> {
144 let mut blocks = self.store.blocks.write().unwrap();
145 for entity in entities {
146 blocks.insert(entity.id, entity.clone());
147 junction_set(
148 &self.store.jn_inline_element_from_block_elements,
149 entity.id,
150 entity.elements.clone(),
151 );
152 junction_set(
153 &self.store.jn_list_from_block_list,
154 entity.id,
155 entity.list.into_iter().collect(),
156 );
157 }
158 drop(blocks);
159 let ids: Vec<EntityId> = entities.iter().map(|e| e.id).collect();
160 let result = self.get_multi(&ids)?;
161 Ok(result.into_iter().flatten().collect())
162 }
163
164 fn remove(&mut self, id: &EntityId) -> Result<(), RepositoryError> {
165 self.remove_multi(std::slice::from_ref(id))
166 }
167
168 fn remove_multi(&mut self, ids: &[EntityId]) -> Result<(), RepositoryError> {
169 let mut blocks = self.store.blocks.write().unwrap();
170 for id in ids {
171 blocks.remove(id);
172 junction_remove(&self.store.jn_inline_element_from_block_elements, id);
173 junction_remove(&self.store.jn_list_from_block_list, id);
174 delete_from_backward_junction(&self.store.jn_back_frame_blocks, id);
175 }
176 Ok(())
177 }
178
179 impl_write_relationship_methods!(BlockHashMapTable<'a>, BlockRelationshipField);
180}
181
182pub struct BlockHashMapTableRO<'a> {
183 store: &'a HashMapStore,
184}
185
186impl<'a> BlockHashMapTableRO<'a> {
187 pub fn new(store: &'a HashMapStore) -> Self {
188 Self { store }
189 }
190
191 fn resolve_junction(
192 &self,
193 field: &BlockRelationshipField,
194 ) -> &RwLock<HashMap<EntityId, Vec<EntityId>>> {
195 match field {
196 BlockRelationshipField::Elements => &self.store.jn_inline_element_from_block_elements,
197 BlockRelationshipField::List => &self.store.jn_list_from_block_list,
198 }
199 }
200
201 fn hydrate(&self, entity: &mut Block) {
202 entity.elements = junction_get(
203 &self.store.jn_inline_element_from_block_elements,
204 &entity.id,
205 );
206 entity.list = junction_get(&self.store.jn_list_from_block_list, &entity.id)
207 .into_iter()
208 .next();
209 }
210}
211
212impl<'a> BlockTableRO for BlockHashMapTableRO<'a> {
213 fn get(&self, id: &EntityId) -> Result<Option<Block>, RepositoryError> {
214 let blocks = self.store.blocks.read().unwrap();
215 match blocks.get(id) {
216 Some(entity) => {
217 let mut e = entity.clone();
218 drop(blocks);
219 self.hydrate(&mut e);
220 Ok(Some(e))
221 }
222 None => Ok(None),
223 }
224 }
225
226 fn get_multi(&self, ids: &[EntityId]) -> Result<Vec<Option<Block>>, RepositoryError> {
227 let mut result = Vec::with_capacity(ids.len());
228 for id in ids {
229 result.push(self.get(id)?);
230 }
231 Ok(result)
232 }
233
234 fn get_all(&self) -> Result<Vec<Block>, RepositoryError> {
235 let blocks = self.store.blocks.read().unwrap();
236 let entries: Vec<Block> = blocks.values().cloned().collect();
237 drop(blocks);
238 let mut result = Vec::with_capacity(entries.len());
239 for mut entity in entries {
240 self.hydrate(&mut entity);
241 result.push(entity);
242 }
243 Ok(result)
244 }
245
246 impl_relationship_methods!(BlockHashMapTableRO<'a>, BlockRelationshipField);
247}