1use super::{
4 dtos::{CreateTableCellDto, TableCellDto, UpdateTableCellDto},
5 units_of_work::{TableCellReadUoWFactory, TableCellWriteUoWFactory},
6};
7use crate::TableCellRelationshipDto;
8use anyhow::{Ok, Result};
9use common::direct_access::table_cell::TableCellRelationshipField;
10use common::direct_access::use_cases;
11use common::undo_redo::UndoRedoManager;
12use common::{database::db_context::DbContext, event::EventHub, types::EntityId};
13use std::sync::Arc;
14
15pub fn create_orphan(
16 db_context: &DbContext,
17 event_hub: &Arc<EventHub>,
18 undo_redo_manager: &mut UndoRedoManager,
19 stack_id: Option<u64>,
20 entity: &CreateTableCellDto,
21) -> Result<TableCellDto> {
22 let uow_factory = TableCellWriteUoWFactory::new(db_context, event_hub);
23 let mut uc = use_cases::UndoableCreateOrphanUseCase::new(uow_factory);
24 let entity_in: common::entities::TableCell = entity.into();
25 let result = uc.execute(&entity_in)?;
26 undo_redo_manager.add_command_to_stack(Box::new(uc), stack_id)?;
27 Ok(result.into())
28}
29
30pub fn create_orphan_multi(
31 db_context: &DbContext,
32 event_hub: &Arc<EventHub>,
33 undo_redo_manager: &mut UndoRedoManager,
34 stack_id: Option<u64>,
35 entities: &[CreateTableCellDto],
36) -> Result<Vec<TableCellDto>> {
37 let uow_factory = TableCellWriteUoWFactory::new(db_context, event_hub);
38 let entities_in: Vec<common::entities::TableCell> =
39 entities.iter().map(|dto| dto.into()).collect();
40 let mut uc = use_cases::UndoableCreateOrphanUseCase::new(uow_factory);
41 let result = uc.execute_multi(&entities_in)?;
42 undo_redo_manager.add_command_to_stack(Box::new(uc), stack_id)?;
43 Ok(result.into_iter().map(|e| e.into()).collect())
44}
45
46pub fn create(
47 db_context: &DbContext,
48 event_hub: &Arc<EventHub>,
49 undo_redo_manager: &mut UndoRedoManager,
50 stack_id: Option<u64>,
51 entity: &CreateTableCellDto,
52 owner_id: EntityId,
53 index: i32,
54) -> Result<TableCellDto> {
55 let uow_factory = TableCellWriteUoWFactory::new(db_context, event_hub);
56 let entity_in: common::entities::TableCell = entity.into();
57 let strategy = use_cases::OwnerStrategy::Appending;
58 let mut uc = use_cases::UndoableCreateUseCase::new(uow_factory, strategy);
59 let result = uc.execute(&entity_in, owner_id, index)?;
60 undo_redo_manager.add_command_to_stack(Box::new(uc), stack_id)?;
61 Ok(result.into())
62}
63
64pub fn create_multi(
65 db_context: &DbContext,
66 event_hub: &Arc<EventHub>,
67 undo_redo_manager: &mut UndoRedoManager,
68 stack_id: Option<u64>,
69 entities: &[CreateTableCellDto],
70 owner_id: EntityId,
71 index: i32,
72) -> Result<Vec<TableCellDto>> {
73 let uow_factory = TableCellWriteUoWFactory::new(db_context, event_hub);
74 let entities_in: Vec<common::entities::TableCell> =
75 entities.iter().map(|dto| dto.into()).collect();
76 let strategy = use_cases::OwnerStrategy::Appending;
77 let mut uc = use_cases::UndoableCreateUseCase::new(uow_factory, strategy);
78 let result = uc.execute_multi(&entities_in, owner_id, index)?;
79 undo_redo_manager.add_command_to_stack(Box::new(uc), stack_id)?;
80 Ok(result.into_iter().map(|e| e.into()).collect())
81}
82
83pub fn get(db_context: &DbContext, id: &EntityId) -> Result<Option<TableCellDto>> {
84 let uow_factory = TableCellReadUoWFactory::new(db_context);
85 let uc = use_cases::GetUseCase::new(uow_factory);
86 Ok(uc.execute(id)?.map(|e| e.into()))
87}
88
89pub fn get_all(db_context: &DbContext) -> Result<Vec<TableCellDto>> {
90 let uow_factory = TableCellReadUoWFactory::new(db_context);
91 let uc = use_cases::GetUseCase::new(uow_factory);
92 Ok(uc.execute_all()?.into_iter().map(|e| e.into()).collect())
93}
94
95pub fn get_multi(db_context: &DbContext, ids: &[EntityId]) -> Result<Vec<Option<TableCellDto>>> {
96 let uow_factory = TableCellReadUoWFactory::new(db_context);
97 let uc = use_cases::GetUseCase::new(uow_factory);
98 Ok(uc
99 .execute_multi(ids)?
100 .into_iter()
101 .map(|o| o.map(|e| e.into()))
102 .collect())
103}
104
105pub fn update(
106 db_context: &DbContext,
107 event_hub: &Arc<EventHub>,
108 undo_redo_manager: &mut UndoRedoManager,
109 stack_id: Option<u64>,
110 entity: &UpdateTableCellDto,
111) -> Result<TableCellDto> {
112 let uow_factory = TableCellWriteUoWFactory::new(db_context, event_hub);
113 let entity_in: common::entities::TableCell = entity.into();
114 let mut uc = use_cases::UndoableUpdateUseCase::new(uow_factory);
115 let result = uc.execute(&entity_in)?;
116 undo_redo_manager.add_command_to_stack(Box::new(uc), stack_id)?;
117 Ok(result.into())
118}
119
120pub fn update_multi(
121 db_context: &DbContext,
122 event_hub: &Arc<EventHub>,
123 undo_redo_manager: &mut UndoRedoManager,
124 stack_id: Option<u64>,
125 entities: &[UpdateTableCellDto],
126) -> Result<Vec<TableCellDto>> {
127 let uow_factory = TableCellWriteUoWFactory::new(db_context, event_hub);
128 let entities_in: Vec<common::entities::TableCell> =
129 entities.iter().map(|dto| dto.into()).collect();
130 let mut uc = use_cases::UndoableUpdateUseCase::new(uow_factory);
131 let result = uc.execute_multi(&entities_in)?;
132 undo_redo_manager.add_command_to_stack(Box::new(uc), stack_id)?;
133 Ok(result.into_iter().map(|e| e.into()).collect())
134}
135
136pub fn update_with_relationships(
137 db_context: &DbContext,
138 event_hub: &Arc<EventHub>,
139 undo_redo_manager: &mut UndoRedoManager,
140 stack_id: Option<u64>,
141 entity: &TableCellDto,
142) -> Result<TableCellDto> {
143 let uow_factory = TableCellWriteUoWFactory::new(db_context, event_hub);
144 let entity_in: common::entities::TableCell = entity.into();
145 let mut uc = use_cases::UndoableUpdateWithRelationshipsUseCase::new(uow_factory);
146 let result = uc.execute(&entity_in)?;
147 undo_redo_manager.add_command_to_stack(Box::new(uc), stack_id)?;
148 Ok(result.into())
149}
150
151pub fn update_with_relationships_multi(
152 db_context: &DbContext,
153 event_hub: &Arc<EventHub>,
154 undo_redo_manager: &mut UndoRedoManager,
155 stack_id: Option<u64>,
156 entities: &[TableCellDto],
157) -> Result<Vec<TableCellDto>> {
158 let uow_factory = TableCellWriteUoWFactory::new(db_context, event_hub);
159 let entities_in: Vec<common::entities::TableCell> =
160 entities.iter().map(|dto| dto.into()).collect();
161 let mut uc = use_cases::UndoableUpdateWithRelationshipsUseCase::new(uow_factory);
162 let result = uc.execute_multi(&entities_in)?;
163 undo_redo_manager.add_command_to_stack(Box::new(uc), stack_id)?;
164 Ok(result.into_iter().map(|e| e.into()).collect())
165}
166
167pub fn remove(
168 db_context: &DbContext,
169 event_hub: &Arc<EventHub>,
170 undo_redo_manager: &mut UndoRedoManager,
171 stack_id: Option<u64>,
172 id: &EntityId,
173) -> Result<()> {
174 let uow_factory = TableCellWriteUoWFactory::new(db_context, event_hub);
175 let mut uc = use_cases::UndoableRemoveUseCase::new(uow_factory);
176 uc.execute(id)?;
177 undo_redo_manager.add_command_to_stack(Box::new(uc), stack_id)?;
178 Ok(())
179}
180
181pub fn remove_multi(
182 db_context: &DbContext,
183 event_hub: &Arc<EventHub>,
184 undo_redo_manager: &mut UndoRedoManager,
185 stack_id: Option<u64>,
186 ids: &[EntityId],
187) -> Result<()> {
188 let uow_factory = TableCellWriteUoWFactory::new(db_context, event_hub);
189 let mut uc = use_cases::UndoableRemoveUseCase::new(uow_factory);
190 uc.execute_multi(ids)?;
191 undo_redo_manager.add_command_to_stack(Box::new(uc), stack_id)?;
192 Ok(())
193}
194
195pub fn get_relationship(
196 db_context: &DbContext,
197 id: &EntityId,
198 field: &TableCellRelationshipField,
199) -> Result<Vec<EntityId>> {
200 let uow_factory = TableCellReadUoWFactory::new(db_context);
201 let uc = use_cases::GetRelationshipUseCase::<TableCellRelationshipField, _>::new(uow_factory);
202 uc.execute(id, field)
203}
204
205pub fn get_relationship_many(
206 db_context: &DbContext,
207 ids: &[EntityId],
208 field: &TableCellRelationshipField,
209) -> Result<std::collections::HashMap<EntityId, Vec<EntityId>>> {
210 let uow_factory = TableCellReadUoWFactory::new(db_context);
211 let uc =
212 use_cases::GetRelationshipManyUseCase::<TableCellRelationshipField, _>::new(uow_factory);
213 uc.execute(ids, field)
214}
215
216pub fn get_relationship_count(
217 db_context: &DbContext,
218 id: &EntityId,
219 field: &TableCellRelationshipField,
220) -> Result<usize> {
221 let uow_factory = TableCellReadUoWFactory::new(db_context);
222 let uc =
223 use_cases::GetRelationshipCountUseCase::<TableCellRelationshipField, _>::new(uow_factory);
224 uc.execute(id, field)
225}
226
227pub fn get_relationship_in_range(
228 db_context: &DbContext,
229 id: &EntityId,
230 field: &TableCellRelationshipField,
231 offset: usize,
232 limit: usize,
233) -> Result<Vec<EntityId>> {
234 let uow_factory = TableCellReadUoWFactory::new(db_context);
235 let uc =
236 use_cases::GetRelationshipInRangeUseCase::<TableCellRelationshipField, _>::new(uow_factory);
237 uc.execute(id, field, offset, limit)
238}
239
240pub fn set_relationship(
241 db_context: &DbContext,
242 event_hub: &Arc<EventHub>,
243 undo_redo_manager: &mut UndoRedoManager,
244 stack_id: Option<u64>,
245 dto: &TableCellRelationshipDto,
246) -> Result<()> {
247 let uow_factory = TableCellWriteUoWFactory::new(db_context, event_hub);
248 let mut uc = use_cases::UndoableSetRelationshipUseCase::<TableCellRelationshipField, _>::new(
249 uow_factory,
250 );
251 uc.execute(&dto.id, &dto.field, dto.right_ids.as_slice())?;
252 undo_redo_manager.add_command_to_stack(Box::new(uc), stack_id)?;
253 Ok(())
254}
255
256pub fn move_relationship(
257 db_context: &DbContext,
258 event_hub: &Arc<EventHub>,
259 undo_redo_manager: &mut UndoRedoManager,
260 stack_id: Option<u64>,
261 id: &EntityId,
262 field: &TableCellRelationshipField,
263 ids_to_move: &[EntityId],
264 new_index: i32,
265) -> Result<Vec<EntityId>> {
266 let uow_factory = TableCellWriteUoWFactory::new(db_context, event_hub);
267 let mut uc = use_cases::UndoableMoveRelationshipUseCase::<TableCellRelationshipField, _>::new(
268 uow_factory,
269 );
270 let result = uc.execute(id, field, ids_to_move, new_index)?;
271 undo_redo_manager.add_command_to_stack(Box::new(uc), stack_id)?;
272 Ok(result)
273}
274
275#[cfg(test)]
276mod tests {
277 #![allow(dead_code)]
278 #![allow(unused_imports)]
279
280 use super::*;
281 use crate::document::document_controller;
282 use crate::document::dtos::CreateDocumentDto;
283 use crate::root::dtos::CreateRootDto;
284 use crate::root::root_controller;
285 use crate::table::dtos::CreateTableDto;
286 use crate::table::table_controller;
287 use common::database::db_context::DbContext;
288 use common::event::EventHub;
289 use common::types::EntityId;
290 use common::undo_redo::UndoRedoManager;
291 use std::sync::Arc;
292
293 struct TestContext {
294 db: DbContext,
295 hub: Arc<EventHub>,
296 undo: UndoRedoManager,
297 }
298
299 impl TestContext {
300 fn new() -> Self {
301 let db = DbContext::new().expect("Failed to create in-memory DB");
302 let hub = Arc::new(EventHub::new());
303 let mut undo = UndoRedoManager::new();
304 undo.set_event_hub(&hub);
305 TestContext { db, hub, undo }
306 }
307 }
308
309 fn create_owner_chain(ctx: &mut TestContext) -> EntityId {
311 let root =
312 root_controller::create_orphan(&ctx.db, &ctx.hub, &CreateRootDto::default()).unwrap();
313 let document = document_controller::create(
314 &ctx.db,
315 &ctx.hub,
316 &mut ctx.undo,
317 None,
318 &CreateDocumentDto::default(),
319 root.id,
320 -1,
321 )
322 .unwrap();
323 let table = table_controller::create(
324 &ctx.db,
325 &ctx.hub,
326 &mut ctx.undo,
327 None,
328 &CreateTableDto::default(),
329 document.id,
330 -1,
331 )
332 .unwrap();
333 table.id
334 }
335
336 fn create_one(ctx: &mut TestContext) -> TableCellDto {
338 create_orphan(
339 &ctx.db,
340 &ctx.hub,
341 &mut ctx.undo,
342 None,
343 &CreateTableCellDto::default(),
344 )
345 .unwrap()
346 }
347
348 #[test]
353 fn test_create_orphan_and_get() {
354 let mut ctx = TestContext::new();
355 let created = create_one(&mut ctx);
356 assert!(created.id > 0);
357
358 let fetched = get(&ctx.db, &created.id).unwrap();
359 assert!(fetched.is_some());
360 assert_eq!(fetched.unwrap().id, created.id);
361 }
362
363 #[test]
368 fn test_get_nonexistent() {
369 let ctx = TestContext::new();
370 assert!(get(&ctx.db, &999999).unwrap().is_none());
371 }
372
373 #[test]
378 fn test_get_all() {
379 let mut ctx = TestContext::new();
380 create_one(&mut ctx);
381 let all = get_all(&ctx.db).unwrap();
382 assert!(!all.is_empty());
383 }
384
385 #[test]
390 fn test_get_multi() {
391 let mut ctx = TestContext::new();
392 let a = create_one(&mut ctx);
393 let results = get_multi(&ctx.db, &[a.id, 999999]).unwrap();
394 assert_eq!(results.len(), 2);
395 assert!(results[0].is_some());
396 assert!(results[1].is_none());
397 }
398
399 #[test]
404 fn test_update() {
405 let mut ctx = TestContext::new();
406 let created = create_one(&mut ctx);
407 let update_dto: UpdateTableCellDto = created.into();
408 let updated = update(&ctx.db, &ctx.hub, &mut ctx.undo, None, &update_dto).unwrap();
409 assert_eq!(updated.id, update_dto.id);
410 }
411
412 #[test]
417 fn test_remove() {
418 let mut ctx = TestContext::new();
419 let created = create_one(&mut ctx);
420 remove(&ctx.db, &ctx.hub, &mut ctx.undo, None, &created.id).unwrap();
421 assert!(get(&ctx.db, &created.id).unwrap().is_none());
422 }
423
424 #[test]
429 fn test_remove_multi() {
430 let mut ctx = TestContext::new();
431 let a = create_one(&mut ctx);
432 remove_multi(&ctx.db, &ctx.hub, &mut ctx.undo, None, &[a.id]).unwrap();
433 assert!(get(&ctx.db, &a.id).unwrap().is_none());
434 }
435
436 #[test]
441 fn test_create_with_owner() {
442 let mut ctx = TestContext::new();
443 let owner_id = create_owner_chain(&mut ctx);
444 let created = create(
445 &ctx.db,
446 &ctx.hub,
447 &mut ctx.undo,
448 None,
449 &CreateTableCellDto::default(),
450 owner_id,
451 -1,
452 )
453 .unwrap();
454 assert!(created.id > 0);
455 let fetched = get(&ctx.db, &created.id).unwrap();
456 assert!(fetched.is_some());
457 }
458
459 #[test]
464 fn test_create_orphan_undo() {
465 let mut ctx = TestContext::new();
466 let created = create_one(&mut ctx);
467 assert!(get(&ctx.db, &created.id).unwrap().is_some());
468 ctx.undo.undo(None).unwrap();
469 assert!(get(&ctx.db, &created.id).unwrap().is_none());
470 }
471
472 #[test]
477 fn test_remove_undo() {
478 let mut ctx = TestContext::new();
479 let created = create_one(&mut ctx);
480 remove(&ctx.db, &ctx.hub, &mut ctx.undo, None, &created.id).unwrap();
481 assert!(get(&ctx.db, &created.id).unwrap().is_none());
482 ctx.undo.undo(None).unwrap();
483 assert!(get(&ctx.db, &created.id).unwrap().is_some());
484 }
485
486 #[test]
491 fn test_get_relationship_empty() {
492 let mut ctx = TestContext::new();
493 let created = create_one(&mut ctx);
494 let rel_ids =
495 get_relationship(&ctx.db, &created.id, &TableCellRelationshipField::CellFrame).unwrap();
496 assert!(rel_ids.is_empty());
497 }
498
499 #[test]
504 fn test_get_relationship_count_zero() {
505 let mut ctx = TestContext::new();
506 let created = create_one(&mut ctx);
507 let count =
508 get_relationship_count(&ctx.db, &created.id, &TableCellRelationshipField::CellFrame)
509 .unwrap();
510 assert_eq!(count, 0);
511 }
512}