@@ -56,7 +56,7 @@ use matrix_sdk_common::executor::{spawn, JoinHandle};
56
56
use ruma:: {
57
57
events:: { AnyRoomAccountDataEvent , AnySyncEphemeralRoomEvent } ,
58
58
serde:: Raw ,
59
- OwnedEventId , OwnedRoomId , RoomId ,
59
+ EventId , OwnedEventId , OwnedRoomId , RoomId ,
60
60
} ;
61
61
use tokio:: sync:: {
62
62
broadcast:: { error:: RecvError , Receiver , Sender } ,
@@ -196,6 +196,23 @@ impl EventCache {
196
196
Ok ( ( ) )
197
197
}
198
198
199
+ /// Try to find an event by its ID in all the rooms.
200
+ // NOTE: this does a linear scan, so it could be slow. If performance
201
+ // requires it, we could use a direct mapping of event id -> event, and keep it
202
+ // in memory until we store it on disk (and this becomes a SQL query by id).
203
+ pub async fn event ( & self , event_id : & EventId ) -> Option < SyncTimelineEvent > {
204
+ let by_room = self . inner . by_room . read ( ) . await ;
205
+ for room in by_room. values ( ) {
206
+ let events = room. inner . events . read ( ) . await ;
207
+ for ( _pos, event) in events. revents ( ) {
208
+ if event. event_id ( ) . as_deref ( ) == Some ( event_id) {
209
+ return Some ( event. clone ( ) ) ;
210
+ }
211
+ }
212
+ }
213
+ None
214
+ }
215
+
199
216
#[ instrument( skip_all) ]
200
217
async fn ignore_user_list_update_task (
201
218
inner : Arc < EventCacheInner > ,
@@ -759,13 +776,13 @@ pub enum EventsOrigin {
759
776
mod tests {
760
777
use assert_matches2:: assert_matches;
761
778
use futures_util:: FutureExt as _;
762
- use matrix_sdk_base:: sync:: JoinedRoomUpdate ;
779
+ use matrix_sdk_base:: sync:: { JoinedRoomUpdate , RoomUpdates , Timeline } ;
763
780
use matrix_sdk_test:: async_test;
764
- use ruma:: { room_id, serde:: Raw } ;
781
+ use ruma:: { event_id , room_id, serde:: Raw , user_id } ;
765
782
use serde_json:: json;
766
783
767
784
use super :: { EventCacheError , RoomEventCacheUpdate } ;
768
- use crate :: test_utils:: logged_in_client;
785
+ use crate :: test_utils:: { assert_event_matches_msg , events :: EventFactory , logged_in_client} ;
769
786
770
787
#[ async_test]
771
788
async fn test_must_explicitly_subscribe ( ) {
@@ -828,4 +845,60 @@ mod tests {
828
845
829
846
assert ! ( stream. recv( ) . now_or_never( ) . is_none( ) ) ;
830
847
}
848
+
849
+ #[ async_test]
850
+ async fn test_get_event_by_id ( ) {
851
+ let client = logged_in_client ( None ) . await ;
852
+ let room1 = room_id ! ( "!galette:saucisse.bzh" ) ;
853
+ let room2 = room_id ! ( "!crepe:saucisse.bzh" ) ;
854
+
855
+ let event_cache = client. event_cache ( ) ;
856
+ event_cache. subscribe ( ) . unwrap ( ) ;
857
+
858
+ // Insert two rooms with a few events.
859
+ let f = EventFactory :: new ( ) . room ( room1) . sender ( user_id ! ( "@ben:saucisse.bzh" ) ) ;
860
+
861
+ let eid1 = event_id ! ( "$1" ) ;
862
+ let eid2 = event_id ! ( "$2" ) ;
863
+ let eid3 = event_id ! ( "$3" ) ;
864
+
865
+ let joined_room_update1 = JoinedRoomUpdate {
866
+ timeline : Timeline {
867
+ events : vec ! [
868
+ f. text_msg( "hey" ) . event_id( eid1) . into( ) ,
869
+ f. text_msg( "you" ) . event_id( eid2) . into( ) ,
870
+ ] ,
871
+ ..Default :: default ( )
872
+ } ,
873
+ ..Default :: default ( )
874
+ } ;
875
+
876
+ let joined_room_update2 = JoinedRoomUpdate {
877
+ timeline : Timeline {
878
+ events : vec ! [ f. text_msg( "bjr" ) . event_id( eid3) . into( ) ] ,
879
+ ..Default :: default ( )
880
+ } ,
881
+ ..Default :: default ( )
882
+ } ;
883
+
884
+ let mut updates = RoomUpdates :: default ( ) ;
885
+ updates. join . insert ( room1. to_owned ( ) , joined_room_update1) ;
886
+ updates. join . insert ( room2. to_owned ( ) , joined_room_update2) ;
887
+
888
+ // Have the event cache handle them.
889
+ event_cache. inner . handle_room_updates ( updates) . await . unwrap ( ) ;
890
+
891
+ // Now retrieve all the events one by one.
892
+ let found1 = event_cache. event ( eid1) . await . unwrap ( ) ;
893
+ assert_event_matches_msg ( & found1, "hey" ) ;
894
+
895
+ let found2 = event_cache. event ( eid2) . await . unwrap ( ) ;
896
+ assert_event_matches_msg ( & found2, "you" ) ;
897
+
898
+ let found3 = event_cache. event ( eid3) . await . unwrap ( ) ;
899
+ assert_event_matches_msg ( & found3, "bjr" ) ;
900
+
901
+ // An unknown event won't be found.
902
+ assert ! ( event_cache. event( event_id!( "$unknown" ) ) . await . is_none( ) ) ;
903
+ }
831
904
}
0 commit comments