Skip to main content

text_document_direct_access/block/
block_controller.rs

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