Skip to content

Commit 7f31cf2

Browse files
authored
refactor: rename aggregate::Saver method, move repositories into aggregate::repository mod (#249)
* refactor: rename aggregate::Saver::store in aggregate::Saver::save * refactor: move aggregate::{Saver, Getter} to aggregate::repository::{Getter, Saver} * feat: add .editorconfig * chore: update CONTRIBUTING.md guidelines doc * test(eventually-postgres): unmask errors with the integration test when conflict error is not detected
1 parent 2558e59 commit 7f31cf2

File tree

11 files changed

+101
-97
lines changed

11 files changed

+101
-97
lines changed

.editorconfig

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
root = true
2+
3+
[*]
4+
charset = utf-8
5+
end_of_line = lf
6+
indent_size = 4
7+
indent_style = space
8+
insert_final_newline = true
9+
max_line_length = 160
10+
tab_width = 4
11+
trim_trailing_whitespace = true
12+
13+
[*.{json, md, yaml, yml, proto}]
14+
indent_size = 2
15+

CONTRIBUTING.md

Lines changed: 17 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -2,14 +2,14 @@
22

33
Thank you so much for considering contributing to `eventually`! :tada:
44

5-
- [Contributing to `eventually`](#contributing-to-eventually)
6-
- [What should I know before I get started?](#what-should-i-know-before-i-get-started)
7-
- [I want to contribute, but I don't know what can I contribute to...](#i-want-to-contribute-but-i-dont-know-what-can-i-contribute-to)
8-
- [Pull Requests](#pull-requests)
9-
- [How should my Pull Request look like?](#how-should-my-pull-request-look-like)
10-
- [Describe the scope of the PR](#describe-the-scope-of-the-pr)
11-
- [Git commit messages](#git-commit-messages)
12-
- [Rust styleguide](#rust-styleguide)
5+
- [Contributing to `eventually`](#contributing-to-eventually)
6+
- [What should I know before I get started?](#what-should-i-know-before-i-get-started)
7+
- [I want to contribute, but I don't know what can I contribute to...](#i-want-to-contribute-but-i-dont-know-what-can-i-contribute-to)
8+
- [Pull Requests](#pull-requests)
9+
- [How should my Pull Request look like?](#how-should-my-pull-request-look-like)
10+
- [Describe the scope of the PR](#describe-the-scope-of-the-pr)
11+
- [Git commit messages](#git-commit-messages)
12+
- [Rust styleguide](#rust-styleguide)
1313

1414
## What should I know before I get started?
1515

@@ -18,27 +18,22 @@ where all the crates share the same dependencies and lock file.
1818
(This might be changed in the future)
1919

2020
The workspace has the following crates:
21-
- [`eventually`]\: the main crate, users should depend solely on this crate
22-
- [`eventually-app-example`]\: an example application to showcase a (not-so) real-world example of how to use the library
2321

24-
Although `eventually-postgres` and `eventually-redis` are currently in the workspace, they might be moved outside the repository, into their own respective repository inside the organization. (For more info, check out #131 and #132)
22+
- [`eventually`]\: the main crate, users should depend solely on this crate
23+
- [`eventually-macros`]\: the crate that contains procedural macros to make the development experience nicer for users,
24+
- [`eventually-postgres`]\: the crate that contains implementations of abstractions from `eventually` for PostgreSQL databases,
2525

2626
When submitting a PR involving one or more of these crates, please make sure to use the **corresponding label**.
2727

2828
### I want to contribute, but I don't know what can I contribute to...
2929

3030
If you want to contribute but you have no idea how, or what specific features are
31-
missing, please check the [_What next?_ tracking issue](https://github.com/get-eventually/eventually-rs/issues/133).
31+
missing, please check the [issues] page: we usually have some issues that are marked as "good for
32+
beginners".
3233

3334
Being an open-source project, we are always looking for new contributors, so no matter
3435
your level of Event Sourcing skills or language mastery, your PRs are always welcome :heart:
3536

36-
If you want to experiment and/or get familiar with the library, you can consider
37-
trying to write a small application using the crate and send a message to our
38-
[Gitter chat][gitter] to give visibility: we can add your example project to the
39-
repository's `README` in order for other users to find it and draw inspiration
40-
from your experience.
41-
4237
## Pull Requests
4338

4439
Before opening a Pull Request, check the [Issues section][issues] for an issue that might describe the feature you're considering adding.
@@ -48,11 +43,12 @@ implementation before the code review process. You can also reach out to our [Gi
4843
features or other technical aspects of the crate.
4944

5045
In order to submit a PR, follow these steps:
46+
5147
1. **Fork** the repository
5248
2. **Clone** your fork of the repository in your local machine
5349
3. Add the upstream repository in your local machine copy:
5450
```bash
55-
git remote add upstream git@github.com:eventually-rs/eventually-rs
51+
git remote add upstream git@github.com:get-eventually/eventually-rs
5652
git fetch upstream
5753
```
5854
4. Create a new branch starting from `upstream/main`:
@@ -98,8 +94,8 @@ Make sure you run `rustfmt` **before committing any changes**, as failing to do
9894
9995
[workspace]: https://doc.rust-lang.org/book/ch14-03-cargo-workspaces.html
10096
[`eventually`]: ./eventually
101-
[`eventually-app-example`]: ./eventually-app-example
97+
[`eventually-macros`]: ./eventually-macros
98+
[`eventually-postgres`]: ./eventually-postgres
10299
[issues]: https://github.com/get-eventually/eventually-rs/issues
103100
[new-issue]: https://github.com/get-eventually/eventually-rs/issues/new
104-
[gitter]: https://gitter.im/eventually-rs/community
105101
[conventional-commits]: https://www.conventionalcommits.org/en/v1.0.0/

eventually-postgres/src/aggregate.rs

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -141,7 +141,7 @@ where
141141
}
142142

143143
#[async_trait]
144-
impl<T, OutT, OutEvt, TSerde, EvtSerde> aggregate::Getter<T>
144+
impl<T, OutT, OutEvt, TSerde, EvtSerde> aggregate::repository::Getter<T>
145145
for Repository<T, OutT, OutEvt, TSerde, EvtSerde>
146146
where
147147
T: Aggregate + TryFrom<OutT> + Send + Sync,
@@ -158,7 +158,7 @@ where
158158
async fn get(
159159
&self,
160160
id: &T::Id,
161-
) -> Result<aggregate::Root<T>, aggregate::RepositoryGetError<Self::Error>> {
161+
) -> Result<aggregate::Root<T>, aggregate::repository::GetError<Self::Error>> {
162162
let aggregate_id = id.to_string();
163163

164164
let row = sqlx::query(
@@ -171,8 +171,8 @@ where
171171
.fetch_one(&self.pool)
172172
.await
173173
.map_err(|err| match err {
174-
sqlx::Error::RowNotFound => aggregate::RepositoryGetError::AggregateRootNotFound,
175-
_ => aggregate::RepositoryGetError::Inner(GetError::FetchAggregateRow(err)),
174+
sqlx::Error::RowNotFound => aggregate::repository::GetError::NotFound,
175+
_ => aggregate::repository::GetError::Inner(GetError::FetchAggregateRow(err)),
176176
})?;
177177

178178
let version: i32 = row.try_get("version").map_err(GetError::Database)?;
@@ -194,7 +194,7 @@ where
194194
}
195195

196196
#[async_trait]
197-
impl<T, OutT, OutEvt, TSerde, EvtSerde> aggregate::Saver<T>
197+
impl<T, OutT, OutEvt, TSerde, EvtSerde> aggregate::repository::Saver<T>
198198
for Repository<T, OutT, OutEvt, TSerde, EvtSerde>
199199
where
200200
T: Aggregate + TryFrom<OutT> + Send + Sync,
@@ -208,7 +208,7 @@ where
208208
{
209209
type Error = SaveError;
210210

211-
async fn store(&self, root: &mut aggregate::Root<T>) -> Result<(), Self::Error> {
211+
async fn save(&self, root: &mut aggregate::Root<T>) -> Result<(), Self::Error> {
212212
let events_to_commit = root.take_uncommitted_events();
213213

214214
if events_to_commit.is_empty() {

eventually-postgres/tests/aggregate_repository.rs

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
use eventually::{
2-
aggregate::{Getter, RepositoryGetError, Saver},
2+
aggregate::repository::{GetError, Getter, Saver},
33
serde::json::Json,
44
version,
55
};
@@ -31,7 +31,7 @@ async fn it_works() {
3131
.expect_err("should fail");
3232

3333
match result {
34-
RepositoryGetError::AggregateRootNotFound => (),
34+
GetError::NotFound => (),
3535
_ => panic!(
3636
"unexpected error received, should be 'not found': {:?}",
3737
result
@@ -45,7 +45,7 @@ async fn it_works() {
4545
root.delete().unwrap();
4646

4747
aggregate_repository
48-
.store(&mut root)
48+
.save(&mut root)
4949
.await
5050
.expect("storing the new aggregate root should be successful");
5151

@@ -86,10 +86,10 @@ async fn it_detects_data_races_and_returns_conflict_error() {
8686

8787
let result = futures::join!(
8888
aggregate_repository
89-
.store(&mut root)
89+
.save(&mut root)
9090
.map_err(Option::<version::ConflictError>::from),
9191
aggregate_repository
92-
.store(&mut cloned_root)
92+
.save(&mut cloned_root)
9393
.map_err(Option::<version::ConflictError>::from),
9494
);
9595

eventually-postgres/tests/event_store.rs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -185,8 +185,9 @@ async fn it_handles_concurrent_writes_to_the_same_stream() {
185185
);
186186

187187
match result {
188-
(Ok(_), Err(Some(_))) => (),
189-
(Err(Some(_)), Ok(_)) => (),
188+
(Ok(_), Err(err)) | (Err(err), Ok(_)) => {
189+
assert!(Option::<version::ConflictError>::from(err).is_some())
190+
}
190191
(first, second) => panic!(
191192
"invalid state detected, first: {:?}, second: {:?}",
192193
first, second

eventually/src/aggregate.rs

Lines changed: 15 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -27,11 +27,9 @@
2727
2828
use crate::{event, message, version::Version};
2929

30-
mod repository;
31-
pub use repository::{
32-
EventSourced as EventSourcedRepository, GetError as RepositoryGetError, Getter, Repository,
33-
Saver,
34-
};
30+
pub mod repository;
31+
32+
pub use repository::{EventSourced as EventSourcedRepository, Repository};
3533

3634
/// An Aggregate represents a Domain Model that, through an Aggregate [Root],
3735
/// acts as a _transactional boundary_.
@@ -390,8 +388,8 @@ mod test {
390388

391389
use crate::{
392390
aggregate,
391+
aggregate::repository::{Getter, Saver},
393392
aggregate::test_user_domain::{User, UserEvent},
394-
aggregate::{Getter, Saver},
395393
event,
396394
event::store::EventStoreExt,
397395
version,
@@ -411,9 +409,9 @@ mod test {
411409
.expect("user should be created successfully");
412410

413411
user_repository
414-
.store(&mut user)
412+
.save(&mut user)
415413
.await
416-
.expect("user should be stored successfully");
414+
.expect("user should be saved successfully");
417415

418416
let expected_events = vec![event::Persisted {
419417
stream_id: email.clone(),
@@ -438,9 +436,9 @@ mod test {
438436
.expect("user should be created successfully");
439437

440438
user_repository
441-
.store(&mut user)
439+
.save(&mut user)
442440
.await
443-
.expect("user should be stored successfully");
441+
.expect("user should be saved successfully");
444442

445443
// Reset the event recorded while storing the User for the first time.
446444
tracking_event_store.reset_recorded_events();
@@ -456,9 +454,9 @@ mod test {
456454
.expect("user password should be changed successfully");
457455

458456
user_repository
459-
.store(&mut user)
457+
.save(&mut user)
460458
.await
461-
.expect("new user version should be stored successfully");
459+
.expect("new user version should be saved successfully");
462460

463461
let expected_events = vec![event::Persisted {
464462
stream_id: email.clone(),
@@ -489,16 +487,15 @@ mod test {
489487

490488
// Saving the first User to the Repository.
491489
user_repository
492-
.store(&mut user)
490+
.save(&mut user)
493491
.await
494-
.expect("user should be stored successfully");
492+
.expect("user should be saved successfully");
495493

496494
// Simulating data race by duplicating the call to the Repository
497495
// with the same UserRoot instance that has already been committeed.
498-
let error = user_repository
499-
.store(&mut cloned_user)
500-
.await
501-
.expect_err("the repository should fail on the second store call with the cloned user");
496+
let error = user_repository.save(&mut cloned_user).await.expect_err(
497+
"the repository should fail on the second .save() call with the cloned user",
498+
);
502499

503500
let error: Box<dyn Error> = error.into();
504501

eventually/src/aggregate/repository.rs

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ pub enum GetError<I> {
1212
/// This error is retured by [`Repository::get`] when the
1313
/// desired Aggregate [Root] could not be found in the data store.
1414
#[error("aggregate root was not found")]
15-
AggregateRootNotFound,
15+
NotFound,
1616
#[error(transparent)]
1717
Inner(#[from] I),
1818
}
@@ -36,8 +36,8 @@ where
3636
{
3737
type Error: Send + Sync;
3838

39-
/// Stores a new version of an Aggregate Root instance to the data store.
40-
async fn store(&self, root: &mut aggregate::Root<T>) -> Result<(), Self::Error>;
39+
/// Saves a new version of an Aggregate Root instance to the data store.
40+
async fn save(&self, root: &mut aggregate::Root<T>) -> Result<(), Self::Error>;
4141
}
4242

4343
/// A Repository is an object that allows to load and save
@@ -141,7 +141,7 @@ where
141141
})
142142
.await?;
143143

144-
ctx.ok_or(GetError::AggregateRootNotFound)
144+
ctx.ok_or(GetError::NotFound)
145145
}
146146
}
147147

@@ -159,7 +159,7 @@ where
159159
<S as event::Appender<T::Id, T::Event>>::Error,
160160
>;
161161

162-
async fn store(&self, root: &mut aggregate::Root<T>) -> Result<(), Self::Error> {
162+
async fn save(&self, root: &mut aggregate::Root<T>) -> Result<(), Self::Error> {
163163
let events_to_commit = root.take_uncommitted_events();
164164
let aggregate_id = root.aggregate_id();
165165

eventually/src/command.rs

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -85,12 +85,12 @@ mod test_user_domain {
8585

8686
struct CreateUserHandler<R>(R)
8787
where
88-
R: aggregate::Saver<User>;
88+
R: aggregate::repository::Saver<User>;
8989

9090
#[async_trait]
9191
impl<R> command::Handler<CreateUser> for CreateUserHandler<R>
9292
where
93-
R: aggregate::Saver<User>,
93+
R: aggregate::repository::Saver<User>,
9494
R::Error: std::error::Error + Send + Sync + 'static,
9595
{
9696
type Error = anyhow::Error;
@@ -99,7 +99,7 @@ mod test_user_domain {
9999
let command = command.message;
100100
let mut user = aggregate::Root::<User>::create(command.email, command.password)?;
101101

102-
self.0.store(&mut user).await?;
102+
self.0.save(&mut user).await?;
103103

104104
Ok(())
105105
}
@@ -124,8 +124,9 @@ mod test_user_domain {
124124
impl<R> command::Handler<ChangeUserPassword> for ChangeUserPasswordHandler<R>
125125
where
126126
R: aggregate::Repository<User>,
127-
<R as aggregate::Getter<User>>::Error: std::error::Error + Send + Sync + 'static,
128-
<R as aggregate::Saver<User>>::Error: std::error::Error + Send + Sync + 'static,
127+
<R as aggregate::repository::Getter<User>>::Error:
128+
std::error::Error + Send + Sync + 'static,
129+
<R as aggregate::repository::Saver<User>>::Error: std::error::Error + Send + Sync + 'static,
129130
{
130131
type Error = anyhow::Error;
131132

@@ -139,7 +140,7 @@ mod test_user_domain {
139140

140141
user.change_password(command.password)?;
141142

142-
self.0.store(&mut user).await?;
143+
self.0.save(&mut user).await?;
143144

144145
Ok(())
145146
}

0 commit comments

Comments
 (0)