Skip to main content

text_document_common/direct_access/block/
block_table.rs

1use 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}