Skip to main content

versatile_data/
operation.rs

1use std::num::NonZeroU32;
2
3use futures::FutureExt;
4use hashbrown::HashMap;
5use idx_binary::AvltrieeUpdate;
6use uuid::Uuid;
7
8use crate::{Data, FieldName};
9
10#[derive(Clone, Copy, PartialEq, Debug, Default)]
11pub enum Activity {
12    Inactive = 0,
13    #[default]
14    Active = 1,
15}
16
17#[derive(Debug, Clone, Default)]
18pub enum Term {
19    #[default]
20    Default,
21    Overwrite(u64),
22}
23
24pub fn create_uuid() -> u128 {
25    Uuid::new_v4().as_u128()
26}
27
28impl Data {
29    /// Delete row.
30    pub async fn insert(
31        &mut self,
32        activity: Activity,
33        term_begin: Term,
34        term_end: Term,
35        fields: HashMap<FieldName, Vec<u8>>,
36    ) -> NonZeroU32 {
37        let row = self.serial.next_row();
38        self.update(row, activity, term_begin, term_end, fields)
39            .await;
40        row
41    }
42
43    /// Update row.
44    pub async fn update(
45        &mut self,
46        row: NonZeroU32,
47        activity: Activity,
48        term_begin: Term,
49        term_end: Term,
50        fields: HashMap<FieldName, Vec<u8>>,
51    ) {
52        for (key, _) in &fields {
53            if !self.fields.contains_key(key) {
54                self.create_field(key);
55            }
56        }
57        futures::future::join_all([
58            async {
59                futures::future::join_all(self.fields.iter_mut().filter_map(|(name, field)| {
60                    fields
61                        .get(&name.clone())
62                        .map(|v| async { field.update(row, v) })
63                }))
64                .await;
65            }
66            .boxed_local(),
67            async {
68                if let Some(ref mut uuid) = self.uuid {
69                    if uuid.node(row).is_none() {
70                        uuid.update(row, &Uuid::new_v4().as_u128());
71                    }
72                }
73            }
74            .boxed_local(),
75            async {
76                if let Some(ref mut f) = self.last_updated {
77                    f.update(row, &Self::now());
78                }
79            }
80            .boxed_local(),
81            async {
82                if let Some(ref mut f) = self.activity {
83                    f.update(row, &(activity as u8));
84                }
85            }
86            .boxed_local(),
87            async {
88                if let Some(ref mut f) = self.term_begin {
89                    f.update(
90                        row,
91                        &if let Term::Overwrite(term) = term_begin {
92                            term
93                        } else {
94                            Self::now()
95                        },
96                    );
97                }
98            }
99            .boxed_local(),
100            async {
101                if let Some(ref mut f) = self.term_end {
102                    f.update(
103                        row,
104                        &if let Term::Overwrite(term) = term_end {
105                            term
106                        } else {
107                            0
108                        },
109                    );
110                }
111            }
112            .boxed_local(),
113        ])
114        .await;
115    }
116
117    /// Delete row.
118    pub async fn delete(&mut self, row: NonZeroU32) {
119        futures::future::join(
120            futures::future::join(async { self.serial.delete(row) }, async {
121                futures::future::join_all(self.fields.iter_mut().map(|(_name, v)| async {
122                    v.delete(row);
123                }))
124                .await
125            }),
126            async {
127                let mut futs = vec![];
128                if let Some(ref mut f) = self.uuid {
129                    futs.push(
130                        async {
131                            f.delete(row);
132                        }
133                        .boxed_local(),
134                    );
135                }
136                if let Some(ref mut f) = self.activity {
137                    futs.push(
138                        async {
139                            f.delete(row);
140                        }
141                        .boxed_local(),
142                    );
143                }
144                if let Some(ref mut f) = self.term_begin {
145                    futs.push(
146                        async {
147                            f.delete(row);
148                        }
149                        .boxed_local(),
150                    );
151                }
152                if let Some(ref mut f) = self.term_end {
153                    futs.push(
154                        async {
155                            f.delete(row);
156                        }
157                        .boxed_local(),
158                    );
159                }
160                if let Some(ref mut f) = self.last_updated {
161                    futs.push(
162                        async {
163                            f.delete(row);
164                        }
165                        .boxed_local(),
166                    );
167                }
168                futures::future::join_all(futs).await;
169            },
170        )
171        .await;
172    }
173}