coven_database/
database_changes.rs1use crate::DbError;
3
4pub struct DatabaseChanges {
6 commits: crate::observation::CommitSubscription,
7 reads: crate::observation::ReadSet,
8 first: bool,
9}
10impl DatabaseChanges {
11 pub(crate) fn new(
14 commits: crate::observation::CommitSubscription,
15 reads: crate::observation::ReadSet,
16 first: bool,
17 ) -> Self {
18 Self { commits, reads, first }
19 }
20
21 pub fn take_changed(&mut self) -> Result<bool, DbError> {
24 let state = self.commits.state();
25 if let Some(error) = state.error() {
26 return Err(error);
27 }
28 if self.first || state.changed {
29 self.first = false;
30 self.commits.begin();
31 self.commits.finish(self.reads.clone());
32 return Ok(true);
33 }
34 Ok(false)
35 }
36
37 pub fn changed(&self) -> impl std::future::Future<Output = ()> + Send + 'static {
42 let mut commits = self.commits.clone();
43 let first = self.first;
44 async move {
45 loop {
46 let state = commits.state();
47 if first || state.changed || state.error().is_some() {
48 return;
49 }
50 commits.changed().await;
51 }
52 }
53 }
54
55 pub async fn next(&mut self) -> Result<(), DbError> {
57 loop {
58 let state = self.commits.state();
59 if let Some(error) = state.error() {
60 return Err(error);
61 }
62 if self.first || state.changed {
63 self.first = false;
64 self.commits.begin();
65 self.commits.finish(self.reads.clone());
66 return Ok(());
67 }
68 self.commits.changed().await;
69 }
70 }
71}
72
73#[cfg(test)]
74#[path = "database_changes_tests.rs"]
75pub(crate) mod tests;