1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
use std::collections::HashMap;

use versatile_data::{Activity, KeyValue, Operation, Term};

use crate::{
    session::{SessionCollectionRow, SessionData, SessionOperation},
    CollectionRow, Database,
};

pub fn commit(
    main_database: &mut Database,
    session_data: &SessionData,
) -> Result<(), std::io::Error> {
    let mut session_collection_row_map: HashMap<u32, CollectionRow> = HashMap::new();

    let mut relation: HashMap<u32, Vec<(u32, SessionCollectionRow)>> = HashMap::new();
    for row in 1..session_data.relation.rows.session_row.max_rows() {
        if let (Some(session_row), Some(depend)) = (
            session_data.relation.rows.session_row.value(row),
            session_data.relation.rows.depend.value(row),
        ) {
            let m = relation.entry(session_row).or_insert(Vec::new());
            m.push((row, depend));
        }
    }
    for session_row in 1..session_data.sequence.max_rows() {
        if let (Some(op), Some(collection_id), Some(row)) = (
            session_data.operation.value(session_row),
            session_data.collection_id.value(session_row),
            session_data.row.value(session_row),
        ) {
            if let Some(collection) = main_database.collection_mut(collection_id) {
                match op {
                    SessionOperation::New | SessionOperation::Update => {
                        let mut fields: Vec<KeyValue> = Vec::new();
                        for (key, ref field_data) in &session_data.fields {
                            if let Some(val) = field_data.get(session_row) {
                                fields.push(KeyValue::new(key, val));
                            }
                        }
                        let activity = if session_data.activity.value(session_row).unwrap() == 1 {
                            Activity::Active
                        } else {
                            Activity::Inactive
                        };
                        let term_begin =
                            Term::Overwrite(session_data.term_begin.value(session_row).unwrap());
                        let term_end =
                            Term::Overwrite(session_data.term_end.value(session_row).unwrap());
                        let row = if row == 0 {
                            //new
                            collection.create_row(&activity, &term_begin, &term_end, &fields)
                        } else {
                            assert!(row > 0);
                            let row = row as u32;
                            collection.update_row(row, &activity, &term_begin, &term_end, &fields);
                            row
                        };
                        let collection_row = CollectionRow::new(collection_id, row);
                        session_collection_row_map.insert(session_row, collection_row);
                        if let Some(depend_rows) = relation.get(&session_row) {
                            for (session_row, depend) in depend_rows {
                                let key =
                                    session_data.relation.rows.key.value(*session_row).unwrap();
                                let key = unsafe { session_data.relation.key_names.str(key) };

                                if depend.row < 0 {
                                    if let Some(depend) =
                                        session_collection_row_map.get(&((-depend.row) as u32))
                                    {
                                        main_database.relation.insert(
                                            key,
                                            *depend,
                                            collection_row,
                                        )?;
                                    }
                                } else {
                                    main_database.relation.insert(
                                        key,
                                        CollectionRow::new(depend.collection_id, depend.row as u32),
                                        collection_row,
                                    )?;
                                };
                            }
                        }
                    }
                    SessionOperation::Delete => {
                        //todo!("セッション考慮の削除処理");
                        delete_recursive(
                            main_database,
                            &SessionCollectionRow::new(collection_id, row),
                        );
                    }
                }
            }
        }
    }
    Ok(())
}

pub(super) fn delete_recursive(database: &mut Database, target: &SessionCollectionRow) {
    if target.row > 0 {
        let depend = CollectionRow::new(target.collection_id, target.row as u32);
        let c = database.relation.index_depend().select_by_value(&depend);
        for relation_row in c {
            if let Some(collection_row) = database.relation.index_pend().value(relation_row) {
                delete_recursive(
                    database,
                    &SessionCollectionRow::new(
                        collection_row.collection_id(),
                        collection_row.row() as i64,
                    ),
                );
                if let Some(collection) = database.collection_mut(collection_row.collection_id()) {
                    collection.update(&Operation::Delete {
                        row: collection_row.row(),
                    });
                }
            }
            database.relation.delete(relation_row);
        }
    }
}