@@ -5,7 +5,8 @@ use eventually::{
55 aggregate,
66 aggregate:: Aggregate ,
77 serde:: { Deserializer , Serde , Serializer } ,
8- version:: { ConflictError , Version } ,
8+ version,
9+ version:: Version ,
910} ;
1011use sqlx:: { PgPool , Postgres , Row } ;
1112
@@ -56,19 +57,25 @@ where
5657}
5758
5859#[ derive( Debug , thiserror:: Error ) ]
59- pub enum RepositoryError {
60+ pub enum GetError {
6061 #[ error( "failed to fetch the aggregate state row: {0}" ) ]
6162 FetchAggregateRow ( #[ source] sqlx:: Error ) ,
6263 #[ error( "failed to deserialize the aggregate state from the database row: {0}" ) ]
6364 DeserializeAggregate ( #[ source] Box < dyn std:: error:: Error + Send + Sync + ' static > ) ,
6465 #[ error( "failed to convert the aggregate state into its domain type: {0}" ) ]
6566 ConvertAggregate ( #[ source] Box < dyn std:: error:: Error + Send + Sync + ' static > ) ,
67+ #[ error( "database returned an error: {0}" ) ]
68+ Database ( #[ from] sqlx:: Error ) ,
69+ }
70+
71+ #[ derive( Debug , thiserror:: Error ) ]
72+ pub enum SaveError {
6673 #[ error( "failed to begin a new transaction: {0}" ) ]
6774 BeginTransaction ( #[ source] sqlx:: Error ) ,
6875 #[ error( "conflict error detected: {0})" ) ]
69- Conflict ( #[ source] ConflictError ) ,
76+ Conflict ( #[ source] version :: ConflictError ) ,
7077 #[ error( "concurrent update detected, represented as a conflict error: {0})" ) ]
71- Concurrency ( #[ source] ConflictError ) ,
78+ Concurrency ( #[ source] version :: ConflictError ) ,
7279 #[ error( "failed to save the new aggregate state: {0}" ) ]
7380 SaveAggregateState ( #[ source] sqlx:: Error ) ,
7481 #[ error( "failed to append a new domain event: {0}" ) ]
@@ -79,11 +86,11 @@ pub enum RepositoryError {
7986 Database ( #[ from] sqlx:: Error ) ,
8087}
8188
82- impl From < RepositoryError > for Option < ConflictError > {
83- fn from ( err : RepositoryError ) -> Self {
89+ impl From < SaveError > for Option < version :: ConflictError > {
90+ fn from ( err : SaveError ) -> Self {
8491 match err {
85- RepositoryError :: Conflict ( v) => Some ( v) ,
86- RepositoryError :: Concurrency ( v) => Some ( v) ,
92+ SaveError :: Conflict ( v) => Some ( v) ,
93+ SaveError :: Concurrency ( v) => Some ( v) ,
8794 _ => None ,
8895 }
8996 }
@@ -104,7 +111,7 @@ where
104111 aggregate_id : & str ,
105112 expected_version : Version ,
106113 root : & mut aggregate:: Root < T > ,
107- ) -> Result < ( ) , RepositoryError > {
114+ ) -> Result < ( ) , SaveError > {
108115 let out_state = root. to_aggregate_type :: < OutT > ( ) ;
109116 let bytes_state = self . aggregate_serde . serialize ( out_state) ;
110117
@@ -117,13 +124,15 @@ where
117124 . execute ( tx)
118125 . await
119126 . map_err ( |err| match crate :: check_for_conflict_error ( & err) {
120- Some ( err) => RepositoryError :: Conflict ( err) ,
127+ Some ( err) => SaveError :: Conflict ( err) ,
121128 None => match err. as_database_error ( ) . and_then ( |err| err. code ( ) ) {
122- Some ( code) if code == "40001" => RepositoryError :: Concurrency ( ConflictError {
123- expected : expected_version,
124- actual : root. version ( ) ,
125- } ) ,
126- _ => RepositoryError :: SaveAggregateState ( err) ,
129+ Some ( code) if code == "40001" => {
130+ SaveError :: Concurrency ( version:: ConflictError {
131+ expected : expected_version,
132+ actual : root. version ( ) ,
133+ } )
134+ }
135+ _ => SaveError :: SaveAggregateState ( err) ,
127136 } ,
128137 } ) ?;
129138
@@ -132,7 +141,7 @@ where
132141}
133142
134143#[ async_trait]
135- impl < T , OutT , OutEvt , TSerde , EvtSerde > aggregate:: Repository < T >
144+ impl < T , OutT , OutEvt , TSerde , EvtSerde > aggregate:: Getter < T >
136145 for Repository < T , OutT , OutEvt , TSerde , EvtSerde >
137146where
138147 T : Aggregate + TryFrom < OutT > + Send + Sync ,
@@ -144,7 +153,7 @@ where
144153 <TSerde as Deserializer < OutT > >:: Error : std:: error:: Error + Send + Sync + ' static ,
145154 EvtSerde : Serializer < OutEvt > + Send + Sync ,
146155{
147- type Error = RepositoryError ;
156+ type Error = GetError ;
148157
149158 async fn get (
150159 & self ,
@@ -163,25 +172,41 @@ where
163172 . await
164173 . map_err ( |err| match err {
165174 sqlx:: Error :: RowNotFound => aggregate:: RepositoryGetError :: AggregateRootNotFound ,
166- _ => aggregate:: RepositoryGetError :: Inner ( RepositoryError :: FetchAggregateRow ( err) ) ,
175+ _ => aggregate:: RepositoryGetError :: Inner ( GetError :: FetchAggregateRow ( err) ) ,
167176 } ) ?;
168177
169- let version: i32 = row. try_get ( "version" ) . map_err ( RepositoryError :: Database ) ?;
170- let bytes_state: Vec < u8 > = row. try_get ( "state" ) . map_err ( RepositoryError :: Database ) ?;
178+ let version: i32 = row. try_get ( "version" ) . map_err ( GetError :: Database ) ?;
179+ let bytes_state: Vec < u8 > = row. try_get ( "state" ) . map_err ( GetError :: Database ) ?;
171180
172181 let aggregate: T = self
173182 . aggregate_serde
174183 . deserialize ( bytes_state)
175- . map_err ( |err| RepositoryError :: DeserializeAggregate ( Box :: new ( err) ) )
184+ . map_err ( |err| GetError :: DeserializeAggregate ( Box :: new ( err) ) )
176185 . and_then ( |out_t| {
177- T :: try_from ( out_t) . map_err ( |err| RepositoryError :: ConvertAggregate ( Box :: new ( err) ) )
186+ T :: try_from ( out_t) . map_err ( |err| GetError :: ConvertAggregate ( Box :: new ( err) ) )
178187 } ) ?;
179188
180189 Ok ( aggregate:: Root :: rehydrate_from_state (
181190 version as Version ,
182191 aggregate,
183192 ) )
184193 }
194+ }
195+
196+ #[ async_trait]
197+ impl < T , OutT , OutEvt , TSerde , EvtSerde > aggregate:: Saver < T >
198+ for Repository < T , OutT , OutEvt , TSerde , EvtSerde >
199+ where
200+ T : Aggregate + TryFrom < OutT > + Send + Sync ,
201+ <T as Aggregate >:: Id : ToString ,
202+ <T as TryFrom < OutT > >:: Error : std:: error:: Error + Send + Sync + ' static ,
203+ OutT : From < T > + Send + Sync ,
204+ OutEvt : From < T :: Event > + Send + Sync ,
205+ TSerde : Serde < OutT > + Send + Sync ,
206+ <TSerde as Deserializer < OutT > >:: Error : std:: error:: Error + Send + Sync + ' static ,
207+ EvtSerde : Serializer < OutEvt > + Send + Sync ,
208+ {
209+ type Error = SaveError ;
185210
186211 async fn store ( & self , root : & mut aggregate:: Root < T > ) -> Result < ( ) , Self :: Error > {
187212 let events_to_commit = root. take_uncommitted_events ( ) ;
@@ -194,7 +219,7 @@ where
194219 . pool
195220 . begin ( )
196221 . await
197- . map_err ( RepositoryError :: BeginTransaction ) ?;
222+ . map_err ( SaveError :: BeginTransaction ) ?;
198223
199224 sqlx:: query ( "SET TRANSACTION ISOLATION LEVEL SERIALIZABLE DEFERRABLE" )
200225 . execute ( & mut tx)
@@ -214,11 +239,9 @@ where
214239 events_to_commit,
215240 )
216241 . await
217- . map_err ( RepositoryError :: AppendEvent ) ?;
242+ . map_err ( SaveError :: AppendEvent ) ?;
218243
219- tx. commit ( )
220- . await
221- . map_err ( RepositoryError :: CommitTransaction ) ?;
244+ tx. commit ( ) . await . map_err ( SaveError :: CommitTransaction ) ?;
222245
223246 Ok ( ( ) )
224247 }
0 commit comments