mas_storage/
repository.rs

1// Copyright 2024, 2025 New Vector Ltd.
2// Copyright 2022-2024 The Matrix.org Foundation C.I.C.
3//
4// SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-Element-Commercial
5// Please see LICENSE files in the repository root for full details.
6
7use async_trait::async_trait;
8use futures_util::future::BoxFuture;
9use thiserror::Error;
10
11use crate::{
12    app_session::AppSessionRepository,
13    compat::{
14        CompatAccessTokenRepository, CompatRefreshTokenRepository, CompatSessionRepository,
15        CompatSsoLoginRepository,
16    },
17    oauth2::{
18        OAuth2AccessTokenRepository, OAuth2AuthorizationGrantRepository, OAuth2ClientRepository,
19        OAuth2DeviceCodeGrantRepository, OAuth2RefreshTokenRepository, OAuth2SessionRepository,
20    },
21    policy_data::PolicyDataRepository,
22    queue::{QueueJobRepository, QueueScheduleRepository, QueueWorkerRepository},
23    upstream_oauth2::{
24        UpstreamOAuthLinkRepository, UpstreamOAuthProviderRepository,
25        UpstreamOAuthSessionRepository,
26    },
27    user::{
28        BrowserSessionRepository, UserEmailRepository, UserPasswordRepository,
29        UserRecoveryRepository, UserRegistrationRepository, UserRegistrationTokenRepository,
30        UserRepository, UserTermsRepository,
31    },
32};
33
34/// A [`RepositoryFactory`] is a factory that can create a [`BoxRepository`]
35// XXX(quenting): this could be generic over the repository type, but it's annoying to make it
36// dyn-safe
37#[async_trait]
38pub trait RepositoryFactory {
39    /// Create a new [`BoxRepository`]
40    async fn create(&self) -> Result<BoxRepository, RepositoryError>;
41}
42
43/// A type-erased [`RepositoryFactory`]
44pub type BoxRepositoryFactory = Box<dyn RepositoryFactory + Send + Sync + 'static>;
45
46/// A [`Repository`] helps interacting with the underlying storage backend.
47pub trait Repository<E>:
48    RepositoryAccess<Error = E> + RepositoryTransaction<Error = E> + Send
49where
50    E: std::error::Error + Send + Sync + 'static,
51{
52}
53
54/// An opaque, type-erased error
55#[derive(Debug, Error)]
56#[error(transparent)]
57pub struct RepositoryError {
58    source: Box<dyn std::error::Error + Send + Sync + 'static>,
59}
60
61impl RepositoryError {
62    /// Construct a [`RepositoryError`] from any error kind
63    pub fn from_error<E>(value: E) -> Self
64    where
65        E: std::error::Error + Send + Sync + 'static,
66    {
67        Self {
68            source: Box::new(value),
69        }
70    }
71}
72
73/// A type-erased [`Repository`]
74pub type BoxRepository = Box<dyn Repository<RepositoryError> + Send + Sync + 'static>;
75
76/// A [`RepositoryTransaction`] can be saved or cancelled, after a series
77/// of operations.
78pub trait RepositoryTransaction {
79    /// The error type used by the [`Self::save`] and [`Self::cancel`] functions
80    type Error;
81
82    /// Commit the transaction
83    ///
84    /// # Errors
85    ///
86    /// Returns an error if the underlying storage backend failed to commit the
87    /// transaction.
88    fn save(self: Box<Self>) -> BoxFuture<'static, Result<(), Self::Error>>;
89
90    /// Rollback the transaction
91    ///
92    /// # Errors
93    ///
94    /// Returns an error if the underlying storage backend failed to rollback
95    /// the transaction.
96    fn cancel(self: Box<Self>) -> BoxFuture<'static, Result<(), Self::Error>>;
97}
98
99/// Access the various repositories the backend implements.
100///
101/// All the methods return a boxed trait object, which can be used to access a
102/// particular repository. The lifetime of the returned object is bound to the
103/// lifetime of the whole repository, so that only one mutable reference to the
104/// repository is used at a time.
105///
106/// When adding a new repository, you should add a new method to this trait, and
107/// update the implementations for [`crate::MapErr`] and [`Box<R>`] below.
108///
109/// Note: this used to have generic associated types to avoid boxing all the
110/// repository traits, but that was removed because it made almost impossible to
111/// box the trait object. This might be a shortcoming of the initial
112/// implementation of generic associated types, and might be fixed in the
113/// future.
114pub trait RepositoryAccess: Send {
115    /// The backend-specific error type used by each repository.
116    type Error: std::error::Error + Send + Sync + 'static;
117
118    /// Get an [`UpstreamOAuthLinkRepository`]
119    fn upstream_oauth_link<'c>(
120        &'c mut self,
121    ) -> Box<dyn UpstreamOAuthLinkRepository<Error = Self::Error> + 'c>;
122
123    /// Get an [`UpstreamOAuthProviderRepository`]
124    fn upstream_oauth_provider<'c>(
125        &'c mut self,
126    ) -> Box<dyn UpstreamOAuthProviderRepository<Error = Self::Error> + 'c>;
127
128    /// Get an [`UpstreamOAuthSessionRepository`]
129    fn upstream_oauth_session<'c>(
130        &'c mut self,
131    ) -> Box<dyn UpstreamOAuthSessionRepository<Error = Self::Error> + 'c>;
132
133    /// Get an [`UserRepository`]
134    fn user<'c>(&'c mut self) -> Box<dyn UserRepository<Error = Self::Error> + 'c>;
135
136    /// Get an [`UserEmailRepository`]
137    fn user_email<'c>(&'c mut self) -> Box<dyn UserEmailRepository<Error = Self::Error> + 'c>;
138
139    /// Get an [`UserPasswordRepository`]
140    fn user_password<'c>(&'c mut self)
141    -> Box<dyn UserPasswordRepository<Error = Self::Error> + 'c>;
142
143    /// Get an [`UserRecoveryRepository`]
144    fn user_recovery<'c>(&'c mut self)
145    -> Box<dyn UserRecoveryRepository<Error = Self::Error> + 'c>;
146
147    /// Get an [`UserRegistrationRepository`]
148    fn user_registration<'c>(
149        &'c mut self,
150    ) -> Box<dyn UserRegistrationRepository<Error = Self::Error> + 'c>;
151
152    /// Get an [`UserRegistrationTokenRepository`]
153    fn user_registration_token<'c>(
154        &'c mut self,
155    ) -> Box<dyn UserRegistrationTokenRepository<Error = Self::Error> + 'c>;
156
157    /// Get an [`UserTermsRepository`]
158    fn user_terms<'c>(&'c mut self) -> Box<dyn UserTermsRepository<Error = Self::Error> + 'c>;
159
160    /// Get a [`BrowserSessionRepository`]
161    fn browser_session<'c>(
162        &'c mut self,
163    ) -> Box<dyn BrowserSessionRepository<Error = Self::Error> + 'c>;
164
165    /// Get a [`AppSessionRepository`]
166    fn app_session<'c>(&'c mut self) -> Box<dyn AppSessionRepository<Error = Self::Error> + 'c>;
167
168    /// Get an [`OAuth2ClientRepository`]
169    fn oauth2_client<'c>(&'c mut self)
170    -> Box<dyn OAuth2ClientRepository<Error = Self::Error> + 'c>;
171
172    /// Get an [`OAuth2AuthorizationGrantRepository`]
173    fn oauth2_authorization_grant<'c>(
174        &'c mut self,
175    ) -> Box<dyn OAuth2AuthorizationGrantRepository<Error = Self::Error> + 'c>;
176
177    /// Get an [`OAuth2SessionRepository`]
178    fn oauth2_session<'c>(
179        &'c mut self,
180    ) -> Box<dyn OAuth2SessionRepository<Error = Self::Error> + 'c>;
181
182    /// Get an [`OAuth2AccessTokenRepository`]
183    fn oauth2_access_token<'c>(
184        &'c mut self,
185    ) -> Box<dyn OAuth2AccessTokenRepository<Error = Self::Error> + 'c>;
186
187    /// Get an [`OAuth2RefreshTokenRepository`]
188    fn oauth2_refresh_token<'c>(
189        &'c mut self,
190    ) -> Box<dyn OAuth2RefreshTokenRepository<Error = Self::Error> + 'c>;
191
192    /// Get an [`OAuth2DeviceCodeGrantRepository`]
193    fn oauth2_device_code_grant<'c>(
194        &'c mut self,
195    ) -> Box<dyn OAuth2DeviceCodeGrantRepository<Error = Self::Error> + 'c>;
196
197    /// Get a [`CompatSessionRepository`]
198    fn compat_session<'c>(
199        &'c mut self,
200    ) -> Box<dyn CompatSessionRepository<Error = Self::Error> + 'c>;
201
202    /// Get a [`CompatSsoLoginRepository`]
203    fn compat_sso_login<'c>(
204        &'c mut self,
205    ) -> Box<dyn CompatSsoLoginRepository<Error = Self::Error> + 'c>;
206
207    /// Get a [`CompatAccessTokenRepository`]
208    fn compat_access_token<'c>(
209        &'c mut self,
210    ) -> Box<dyn CompatAccessTokenRepository<Error = Self::Error> + 'c>;
211
212    /// Get a [`CompatRefreshTokenRepository`]
213    fn compat_refresh_token<'c>(
214        &'c mut self,
215    ) -> Box<dyn CompatRefreshTokenRepository<Error = Self::Error> + 'c>;
216
217    /// Get a [`QueueWorkerRepository`]
218    fn queue_worker<'c>(&'c mut self) -> Box<dyn QueueWorkerRepository<Error = Self::Error> + 'c>;
219
220    /// Get a [`QueueJobRepository`]
221    fn queue_job<'c>(&'c mut self) -> Box<dyn QueueJobRepository<Error = Self::Error> + 'c>;
222
223    /// Get a [`QueueScheduleRepository`]
224    fn queue_schedule<'c>(
225        &'c mut self,
226    ) -> Box<dyn QueueScheduleRepository<Error = Self::Error> + 'c>;
227
228    /// Get a [`PolicyDataRepository`]
229    fn policy_data<'c>(&'c mut self) -> Box<dyn PolicyDataRepository<Error = Self::Error> + 'c>;
230}
231
232/// Implementations of the [`RepositoryAccess`], [`RepositoryTransaction`] and
233/// [`Repository`] for the [`crate::MapErr`] wrapper and [`Box<R>`]
234mod impls {
235    use futures_util::{FutureExt, TryFutureExt, future::BoxFuture};
236
237    use super::RepositoryAccess;
238    use crate::{
239        MapErr, Repository, RepositoryTransaction,
240        app_session::AppSessionRepository,
241        compat::{
242            CompatAccessTokenRepository, CompatRefreshTokenRepository, CompatSessionRepository,
243            CompatSsoLoginRepository,
244        },
245        oauth2::{
246            OAuth2AccessTokenRepository, OAuth2AuthorizationGrantRepository,
247            OAuth2ClientRepository, OAuth2DeviceCodeGrantRepository, OAuth2RefreshTokenRepository,
248            OAuth2SessionRepository,
249        },
250        policy_data::PolicyDataRepository,
251        queue::{QueueJobRepository, QueueScheduleRepository, QueueWorkerRepository},
252        upstream_oauth2::{
253            UpstreamOAuthLinkRepository, UpstreamOAuthProviderRepository,
254            UpstreamOAuthSessionRepository,
255        },
256        user::{
257            BrowserSessionRepository, UserEmailRepository, UserPasswordRepository,
258            UserRegistrationRepository, UserRegistrationTokenRepository, UserRepository,
259            UserTermsRepository,
260        },
261    };
262
263    // --- Repository ---
264    impl<R, F, E1, E2> Repository<E2> for MapErr<R, F>
265    where
266        R: Repository<E1> + RepositoryAccess<Error = E1> + RepositoryTransaction<Error = E1>,
267        F: FnMut(E1) -> E2 + Send + Sync + 'static,
268        E1: std::error::Error + Send + Sync + 'static,
269        E2: std::error::Error + Send + Sync + 'static,
270    {
271    }
272
273    // --- RepositoryTransaction --
274    impl<R, F, E> RepositoryTransaction for MapErr<R, F>
275    where
276        R: RepositoryTransaction,
277        R::Error: 'static,
278        F: FnMut(R::Error) -> E + Send + Sync + 'static,
279        E: std::error::Error,
280    {
281        type Error = E;
282
283        fn save(self: Box<Self>) -> BoxFuture<'static, Result<(), Self::Error>> {
284            Box::new(self.inner).save().map_err(self.mapper).boxed()
285        }
286
287        fn cancel(self: Box<Self>) -> BoxFuture<'static, Result<(), Self::Error>> {
288            Box::new(self.inner).cancel().map_err(self.mapper).boxed()
289        }
290    }
291
292    // --- RepositoryAccess --
293    impl<R, F, E> RepositoryAccess for MapErr<R, F>
294    where
295        R: RepositoryAccess,
296        R::Error: 'static,
297        F: FnMut(R::Error) -> E + Send + Sync + 'static,
298        E: std::error::Error + Send + Sync + 'static,
299    {
300        type Error = E;
301
302        fn upstream_oauth_link<'c>(
303            &'c mut self,
304        ) -> Box<dyn UpstreamOAuthLinkRepository<Error = Self::Error> + 'c> {
305            Box::new(MapErr::new(
306                self.inner.upstream_oauth_link(),
307                &mut self.mapper,
308            ))
309        }
310
311        fn upstream_oauth_provider<'c>(
312            &'c mut self,
313        ) -> Box<dyn UpstreamOAuthProviderRepository<Error = Self::Error> + 'c> {
314            Box::new(MapErr::new(
315                self.inner.upstream_oauth_provider(),
316                &mut self.mapper,
317            ))
318        }
319
320        fn upstream_oauth_session<'c>(
321            &'c mut self,
322        ) -> Box<dyn UpstreamOAuthSessionRepository<Error = Self::Error> + 'c> {
323            Box::new(MapErr::new(
324                self.inner.upstream_oauth_session(),
325                &mut self.mapper,
326            ))
327        }
328
329        fn user<'c>(&'c mut self) -> Box<dyn UserRepository<Error = Self::Error> + 'c> {
330            Box::new(MapErr::new(self.inner.user(), &mut self.mapper))
331        }
332
333        fn user_email<'c>(&'c mut self) -> Box<dyn UserEmailRepository<Error = Self::Error> + 'c> {
334            Box::new(MapErr::new(self.inner.user_email(), &mut self.mapper))
335        }
336
337        fn user_password<'c>(
338            &'c mut self,
339        ) -> Box<dyn UserPasswordRepository<Error = Self::Error> + 'c> {
340            Box::new(MapErr::new(self.inner.user_password(), &mut self.mapper))
341        }
342
343        fn user_recovery<'c>(
344            &'c mut self,
345        ) -> Box<dyn crate::user::UserRecoveryRepository<Error = Self::Error> + 'c> {
346            Box::new(MapErr::new(self.inner.user_recovery(), &mut self.mapper))
347        }
348
349        fn user_registration<'c>(
350            &'c mut self,
351        ) -> Box<dyn UserRegistrationRepository<Error = Self::Error> + 'c> {
352            Box::new(MapErr::new(
353                self.inner.user_registration(),
354                &mut self.mapper,
355            ))
356        }
357
358        fn user_registration_token<'c>(
359            &'c mut self,
360        ) -> Box<dyn UserRegistrationTokenRepository<Error = Self::Error> + 'c> {
361            Box::new(MapErr::new(
362                self.inner.user_registration_token(),
363                &mut self.mapper,
364            ))
365        }
366
367        fn user_terms<'c>(&'c mut self) -> Box<dyn UserTermsRepository<Error = Self::Error> + 'c> {
368            Box::new(MapErr::new(self.inner.user_terms(), &mut self.mapper))
369        }
370
371        fn browser_session<'c>(
372            &'c mut self,
373        ) -> Box<dyn BrowserSessionRepository<Error = Self::Error> + 'c> {
374            Box::new(MapErr::new(self.inner.browser_session(), &mut self.mapper))
375        }
376
377        fn app_session<'c>(
378            &'c mut self,
379        ) -> Box<dyn AppSessionRepository<Error = Self::Error> + 'c> {
380            Box::new(MapErr::new(self.inner.app_session(), &mut self.mapper))
381        }
382
383        fn oauth2_client<'c>(
384            &'c mut self,
385        ) -> Box<dyn OAuth2ClientRepository<Error = Self::Error> + 'c> {
386            Box::new(MapErr::new(self.inner.oauth2_client(), &mut self.mapper))
387        }
388
389        fn oauth2_authorization_grant<'c>(
390            &'c mut self,
391        ) -> Box<dyn OAuth2AuthorizationGrantRepository<Error = Self::Error> + 'c> {
392            Box::new(MapErr::new(
393                self.inner.oauth2_authorization_grant(),
394                &mut self.mapper,
395            ))
396        }
397
398        fn oauth2_session<'c>(
399            &'c mut self,
400        ) -> Box<dyn OAuth2SessionRepository<Error = Self::Error> + 'c> {
401            Box::new(MapErr::new(self.inner.oauth2_session(), &mut self.mapper))
402        }
403
404        fn oauth2_access_token<'c>(
405            &'c mut self,
406        ) -> Box<dyn OAuth2AccessTokenRepository<Error = Self::Error> + 'c> {
407            Box::new(MapErr::new(
408                self.inner.oauth2_access_token(),
409                &mut self.mapper,
410            ))
411        }
412
413        fn oauth2_refresh_token<'c>(
414            &'c mut self,
415        ) -> Box<dyn OAuth2RefreshTokenRepository<Error = Self::Error> + 'c> {
416            Box::new(MapErr::new(
417                self.inner.oauth2_refresh_token(),
418                &mut self.mapper,
419            ))
420        }
421
422        fn oauth2_device_code_grant<'c>(
423            &'c mut self,
424        ) -> Box<dyn OAuth2DeviceCodeGrantRepository<Error = Self::Error> + 'c> {
425            Box::new(MapErr::new(
426                self.inner.oauth2_device_code_grant(),
427                &mut self.mapper,
428            ))
429        }
430
431        fn compat_session<'c>(
432            &'c mut self,
433        ) -> Box<dyn CompatSessionRepository<Error = Self::Error> + 'c> {
434            Box::new(MapErr::new(self.inner.compat_session(), &mut self.mapper))
435        }
436
437        fn compat_sso_login<'c>(
438            &'c mut self,
439        ) -> Box<dyn CompatSsoLoginRepository<Error = Self::Error> + 'c> {
440            Box::new(MapErr::new(self.inner.compat_sso_login(), &mut self.mapper))
441        }
442
443        fn compat_access_token<'c>(
444            &'c mut self,
445        ) -> Box<dyn CompatAccessTokenRepository<Error = Self::Error> + 'c> {
446            Box::new(MapErr::new(
447                self.inner.compat_access_token(),
448                &mut self.mapper,
449            ))
450        }
451
452        fn compat_refresh_token<'c>(
453            &'c mut self,
454        ) -> Box<dyn CompatRefreshTokenRepository<Error = Self::Error> + 'c> {
455            Box::new(MapErr::new(
456                self.inner.compat_refresh_token(),
457                &mut self.mapper,
458            ))
459        }
460
461        fn queue_worker<'c>(
462            &'c mut self,
463        ) -> Box<dyn QueueWorkerRepository<Error = Self::Error> + 'c> {
464            Box::new(MapErr::new(self.inner.queue_worker(), &mut self.mapper))
465        }
466
467        fn queue_job<'c>(&'c mut self) -> Box<dyn QueueJobRepository<Error = Self::Error> + 'c> {
468            Box::new(MapErr::new(self.inner.queue_job(), &mut self.mapper))
469        }
470
471        fn queue_schedule<'c>(
472            &'c mut self,
473        ) -> Box<dyn QueueScheduleRepository<Error = Self::Error> + 'c> {
474            Box::new(MapErr::new(self.inner.queue_schedule(), &mut self.mapper))
475        }
476
477        fn policy_data<'c>(
478            &'c mut self,
479        ) -> Box<dyn PolicyDataRepository<Error = Self::Error> + 'c> {
480            Box::new(MapErr::new(self.inner.policy_data(), &mut self.mapper))
481        }
482    }
483
484    impl<R: RepositoryAccess + ?Sized> RepositoryAccess for Box<R> {
485        type Error = R::Error;
486
487        fn upstream_oauth_link<'c>(
488            &'c mut self,
489        ) -> Box<dyn UpstreamOAuthLinkRepository<Error = Self::Error> + 'c> {
490            (**self).upstream_oauth_link()
491        }
492
493        fn upstream_oauth_provider<'c>(
494            &'c mut self,
495        ) -> Box<dyn UpstreamOAuthProviderRepository<Error = Self::Error> + 'c> {
496            (**self).upstream_oauth_provider()
497        }
498
499        fn upstream_oauth_session<'c>(
500            &'c mut self,
501        ) -> Box<dyn UpstreamOAuthSessionRepository<Error = Self::Error> + 'c> {
502            (**self).upstream_oauth_session()
503        }
504
505        fn user<'c>(&'c mut self) -> Box<dyn UserRepository<Error = Self::Error> + 'c> {
506            (**self).user()
507        }
508
509        fn user_email<'c>(&'c mut self) -> Box<dyn UserEmailRepository<Error = Self::Error> + 'c> {
510            (**self).user_email()
511        }
512
513        fn user_password<'c>(
514            &'c mut self,
515        ) -> Box<dyn UserPasswordRepository<Error = Self::Error> + 'c> {
516            (**self).user_password()
517        }
518
519        fn user_recovery<'c>(
520            &'c mut self,
521        ) -> Box<dyn crate::user::UserRecoveryRepository<Error = Self::Error> + 'c> {
522            (**self).user_recovery()
523        }
524
525        fn user_registration<'c>(
526            &'c mut self,
527        ) -> Box<dyn UserRegistrationRepository<Error = Self::Error> + 'c> {
528            (**self).user_registration()
529        }
530
531        fn user_registration_token<'c>(
532            &'c mut self,
533        ) -> Box<dyn UserRegistrationTokenRepository<Error = Self::Error> + 'c> {
534            (**self).user_registration_token()
535        }
536
537        fn user_terms<'c>(&'c mut self) -> Box<dyn UserTermsRepository<Error = Self::Error> + 'c> {
538            (**self).user_terms()
539        }
540
541        fn browser_session<'c>(
542            &'c mut self,
543        ) -> Box<dyn BrowserSessionRepository<Error = Self::Error> + 'c> {
544            (**self).browser_session()
545        }
546
547        fn app_session<'c>(
548            &'c mut self,
549        ) -> Box<dyn AppSessionRepository<Error = Self::Error> + 'c> {
550            (**self).app_session()
551        }
552
553        fn oauth2_client<'c>(
554            &'c mut self,
555        ) -> Box<dyn OAuth2ClientRepository<Error = Self::Error> + 'c> {
556            (**self).oauth2_client()
557        }
558
559        fn oauth2_authorization_grant<'c>(
560            &'c mut self,
561        ) -> Box<dyn OAuth2AuthorizationGrantRepository<Error = Self::Error> + 'c> {
562            (**self).oauth2_authorization_grant()
563        }
564
565        fn oauth2_session<'c>(
566            &'c mut self,
567        ) -> Box<dyn OAuth2SessionRepository<Error = Self::Error> + 'c> {
568            (**self).oauth2_session()
569        }
570
571        fn oauth2_access_token<'c>(
572            &'c mut self,
573        ) -> Box<dyn OAuth2AccessTokenRepository<Error = Self::Error> + 'c> {
574            (**self).oauth2_access_token()
575        }
576
577        fn oauth2_refresh_token<'c>(
578            &'c mut self,
579        ) -> Box<dyn OAuth2RefreshTokenRepository<Error = Self::Error> + 'c> {
580            (**self).oauth2_refresh_token()
581        }
582
583        fn oauth2_device_code_grant<'c>(
584            &'c mut self,
585        ) -> Box<dyn OAuth2DeviceCodeGrantRepository<Error = Self::Error> + 'c> {
586            (**self).oauth2_device_code_grant()
587        }
588
589        fn compat_session<'c>(
590            &'c mut self,
591        ) -> Box<dyn CompatSessionRepository<Error = Self::Error> + 'c> {
592            (**self).compat_session()
593        }
594
595        fn compat_sso_login<'c>(
596            &'c mut self,
597        ) -> Box<dyn CompatSsoLoginRepository<Error = Self::Error> + 'c> {
598            (**self).compat_sso_login()
599        }
600
601        fn compat_access_token<'c>(
602            &'c mut self,
603        ) -> Box<dyn CompatAccessTokenRepository<Error = Self::Error> + 'c> {
604            (**self).compat_access_token()
605        }
606
607        fn compat_refresh_token<'c>(
608            &'c mut self,
609        ) -> Box<dyn CompatRefreshTokenRepository<Error = Self::Error> + 'c> {
610            (**self).compat_refresh_token()
611        }
612
613        fn queue_worker<'c>(
614            &'c mut self,
615        ) -> Box<dyn QueueWorkerRepository<Error = Self::Error> + 'c> {
616            (**self).queue_worker()
617        }
618
619        fn queue_job<'c>(&'c mut self) -> Box<dyn QueueJobRepository<Error = Self::Error> + 'c> {
620            (**self).queue_job()
621        }
622
623        fn queue_schedule<'c>(
624            &'c mut self,
625        ) -> Box<dyn QueueScheduleRepository<Error = Self::Error> + 'c> {
626            (**self).queue_schedule()
627        }
628
629        fn policy_data<'c>(
630            &'c mut self,
631        ) -> Box<dyn PolicyDataRepository<Error = Self::Error> + 'c> {
632            (**self).policy_data()
633        }
634    }
635}