Skip to main content

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