Skip to main content

weavatrix_memory/store/
mod.rs

1mod file;
2pub(crate) mod frame;
3mod in_memory;
4mod subscription;
5
6pub use file::{Durability, FileEventStore, FileStoreOptions, RecoveryPolicy};
7pub use in_memory::InMemoryStore;
8pub use subscription::{CatchUpSubscription, SubscriptionCheckpoint};
9
10use crate::{
11    error::Result,
12    event::{NewEvent, StoredEvent},
13    id::StreamId,
14};
15
16#[derive(Debug, Clone, Copy, Default, PartialEq, Eq)]
17pub struct AppendReceipt {
18    pub event_count: usize,
19    pub first_stream_version: Option<u64>,
20    pub last_stream_version: Option<u64>,
21    pub first_global_position: Option<u64>,
22    pub last_global_position: Option<u64>,
23}
24
25impl AppendReceipt {
26    fn from_events<E>(events: &[StoredEvent<E>]) -> Self {
27        Self {
28            event_count: events.len(),
29            first_stream_version: events.first().map(|event| event.metadata.stream_version),
30            last_stream_version: events.last().map(|event| event.metadata.stream_version),
31            first_global_position: events.first().map(|event| event.metadata.global_position),
32            last_global_position: events.last().map(|event| event.metadata.global_position),
33        }
34    }
35}
36
37#[derive(Debug, Clone, Copy, PartialEq, Eq)]
38pub enum ExpectedVersion {
39    Any,
40    NoStream,
41    Exact(u64),
42}
43
44pub trait EventStore<E: Clone> {
45    /// Atomically appends a batch to one stream.
46    ///
47    /// # Errors
48    ///
49    /// Returns a version conflict, duplicate event, or capacity error without
50    /// committing a partial batch.
51    fn append(
52        &mut self,
53        stream: &StreamId,
54        expected: ExpectedVersion,
55        events: &[NewEvent<E>],
56    ) -> Result<Vec<StoredEvent<E>>>;
57
58    /// Appends an owned batch without requiring callers to retain the inputs.
59    ///
60    /// Stores may override this to move payloads into committed envelopes and
61    /// avoid the input clone required by [`Self::append`].
62    ///
63    /// # Errors
64    ///
65    /// Returns the same version, duplicate-event, capacity, or persistence
66    /// errors as [`Self::append`].
67    fn append_owned(
68        &mut self,
69        stream: &StreamId,
70        expected: ExpectedVersion,
71        events: Vec<NewEvent<E>>,
72    ) -> Result<Vec<StoredEvent<E>>> {
73        self.append(stream, expected, &events)
74    }
75
76    /// Appends an owned batch and returns positions without cloning committed
77    /// payloads back to the caller.
78    ///
79    /// Stores may override this high-throughput path to move the committed
80    /// envelopes directly into storage.
81    ///
82    /// # Errors
83    ///
84    /// Returns the same errors as [`Self::append_owned`].
85    fn append_owned_receipt(
86        &mut self,
87        stream: &StreamId,
88        expected: ExpectedVersion,
89        events: Vec<NewEvent<E>>,
90    ) -> Result<AppendReceipt> {
91        self.append_owned(stream, expected, events)
92            .map(|events| AppendReceipt::from_events(&events))
93    }
94
95    fn load_stream(&self, stream: &StreamId, after: Option<u64>) -> Vec<StoredEvent<E>>;
96
97    fn load_all(&self, after: Option<u64>, limit: usize) -> Vec<StoredEvent<E>>;
98
99    fn stream_version(&self, stream: &StreamId) -> Option<u64>;
100
101    fn len(&self) -> usize;
102
103    fn is_empty(&self) -> bool {
104        self.len() == 0
105    }
106}