1
+ use crate :: application:: order_materialized_view:: OrderMeterializedView ;
1
2
use crate :: application:: order_restaurant_aggregate:: OrderAndRestaurantAggregate ;
2
3
use crate :: application:: restaurant_materialized_view:: RestaurantMeterializedView ;
4
+ use crate :: domain:: order_view:: order_view;
3
5
use crate :: domain:: restaurant_view:: restaurant_view;
4
6
use crate :: domain:: {
5
- event_to_restaurant_event, order_restaurant_decider, order_restaurant_saga, Command , Event ,
7
+ event_to_order_event, event_to_restaurant_event, order_restaurant_decider,
8
+ order_restaurant_saga, Command , Event ,
6
9
} ;
7
10
use crate :: framework:: infrastructure:: errors:: { ErrorMessage , TriggerError } ;
8
11
use crate :: framework:: infrastructure:: to_payload;
9
12
use crate :: infrastructure:: order_restaurant_event_repository:: OrderAndRestaurantEventRepository ;
13
+ use crate :: infrastructure:: order_view_state_repository:: OrderViewStateRepository ;
10
14
use crate :: infrastructure:: restaurant_view_state_repository:: RestaurantViewStateRepository ;
11
15
use pgrx:: prelude:: * ;
12
16
use pgrx:: JsonB ;
@@ -59,7 +63,7 @@ fn handle_all(commands: Vec<Command>) -> Result<Vec<Event>, ErrorMessage> {
59
63
. map ( |res| res. into_iter ( ) . map ( |( e, _) | e. clone ( ) ) . collect ( ) )
60
64
}
61
65
62
- /// Event handler for Restaurant events / Trigger function that handles events and updates the materialized view.
66
+ /// Event handler for Restaurant events / Trigger function that handles restaurant related events and updates the materialized view/table .
63
67
#[ pg_trigger]
64
68
fn handle_restaurant_events < ' a > (
65
69
trigger : & ' a PgTrigger < ' a > ,
@@ -105,6 +109,52 @@ extension_sql!(
105
109
requires = [ handle_restaurant_events]
106
110
) ;
107
111
112
+ /// Event handler for Order events / Trigger function that handles order related events and updates the materialized view/table.
113
+ #[ pg_trigger]
114
+ fn handle_order_events < ' a > (
115
+ trigger : & ' a PgTrigger < ' a > ,
116
+ ) -> Result < Option < PgHeapTuple < ' a , impl WhoAllocated > > , TriggerError > {
117
+ let new = trigger
118
+ . new ( )
119
+ . ok_or ( TriggerError :: NullTriggerTuple ) ?
120
+ . into_owned ( ) ;
121
+ let event: JsonB = new
122
+ . get_by_name :: < JsonB > ( "data" ) ?
123
+ . ok_or ( TriggerError :: NullTriggerTuple ) ?;
124
+ let materialized_view =
125
+ OrderMeterializedView :: new ( OrderViewStateRepository :: new ( ) , order_view ( ) ) ;
126
+
127
+ match event_to_order_event (
128
+ & to_payload :: < Event > ( event)
129
+ . map_err ( |err| TriggerError :: EventHandlingError ( err. to_string ( ) ) ) ?,
130
+ ) {
131
+ // If the event is not a Restaurant event, we do nothing
132
+ None => return Ok ( Some ( new) ) ,
133
+ // If the event is a Restaurant event, we handle it
134
+ Some ( e) => {
135
+ materialized_view
136
+ . handle ( & e)
137
+ . map_err ( |err| TriggerError :: EventHandlingError ( err. message ) ) ?;
138
+ }
139
+ }
140
+ Ok ( Some ( new) )
141
+ }
142
+
143
+ // Materialized view / Table for the Order query side model
144
+ // This table is updated by the trigger function / event handler `handle_order_events`
145
+ extension_sql ! (
146
+ r#"
147
+ CREATE TABLE IF NOT EXISTS orders (
148
+ id UUID PRIMARY KEY,
149
+ data JSONB
150
+ );
151
+
152
+ CREATE TRIGGER order_event_handler_trigger AFTER INSERT ON events FOR EACH ROW EXECUTE PROCEDURE handle_order_events();
153
+ "# ,
154
+ name = "order_event_handler_trigger" ,
155
+ requires = [ handle_order_events]
156
+ ) ;
157
+
108
158
#[ cfg( any( test, feature = "pg_test" ) ) ]
109
159
#[ pg_schema]
110
160
mod tests {
@@ -115,7 +165,10 @@ mod tests {
115
165
VALUES ('RestaurantCreated', '5f8bdf95-c95b-4e4b-8535-d2ac4663bea9', 'Restaurant', 'e48d4d9e-403e-453f-b1ba-328e0ce23737', '{"type": "RestaurantCreated","identifier": "e48d4d9e-403e-453f-b1ba-328e0ce23737", "name": "Pljeska", "menu": {"menu_id": "02f09a3f-1624-3b1d-8409-44eff7708210", "items": [{"id": "02f09a3f-1624-3b1d-8409-44eff7708210","name": "supa","price": 10},{"id": "02f09a3f-1624-3b1d-8409-44eff7708210","name": "sarma","price": 20 }],"cuisine": "Vietnamese"}, "final": false }', 'e48d4d9e-403e-453f-b1ba-328e0ce23737', NULL, FALSE);
116
166
"# ,
117
167
name = "data_insert" ,
118
- requires = [ "restaurant_event_handler_trigger" ]
168
+ requires = [
169
+ "restaurant_event_handler_trigger" ,
170
+ "order_event_handler_trigger"
171
+ ]
119
172
) ;
120
173
use crate :: domain:: api:: {
121
174
ChangeRestaurantMenu , CreateRestaurant , OrderCreated , OrderLineItem , OrderPlaced ,
0 commit comments