pub struct InMemoryRepository<E>where
E: PersistentEntity,{ /* private fields */ }Expand description
Generic in-memory repository
Provides thread-safe storage for any entity implementing PersistentEntity.
All data is stored in memory and lost when the application restarts.
§Example
ⓘ
use backbone_core::persistence::{InMemoryRepository, PersistentEntity};
#[derive(Clone, Debug, Serialize, Deserialize)]
struct User {
id: String,
name: String,
created_at: Option<DateTime<Utc>>,
updated_at: Option<DateTime<Utc>>,
deleted_at: Option<DateTime<Utc>>,
}
impl PersistentEntity for User { /* ... */ }
let repo = InMemoryRepository::<User>::new();Implementations§
Source§impl<E> InMemoryRepository<E>where
E: PersistentEntity,
impl<E> InMemoryRepository<E>where
E: PersistentEntity,
Trait Implementations§
Source§impl<E> CrudRepository<E> for InMemoryRepository<E>where
E: PersistentEntity,
impl<E> CrudRepository<E> for InMemoryRepository<E>where
E: PersistentEntity,
Source§fn create<'life0, 'async_trait>(
&'life0 self,
entity: E,
) -> Pin<Box<dyn Future<Output = Result<E, RepositoryError>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
fn create<'life0, 'async_trait>(
&'life0 self,
entity: E,
) -> Pin<Box<dyn Future<Output = Result<E, RepositoryError>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
Create a new entity
Source§fn find_by_id<'life0, 'life1, 'async_trait>(
&'life0 self,
id: &'life1 str,
) -> Pin<Box<dyn Future<Output = Result<Option<E>, RepositoryError>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
fn find_by_id<'life0, 'life1, 'async_trait>(
&'life0 self,
id: &'life1 str,
) -> Pin<Box<dyn Future<Output = Result<Option<E>, RepositoryError>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
Find entity by ID (excluding soft-deleted)
Source§fn find_by_id_including_deleted<'life0, 'life1, 'async_trait>(
&'life0 self,
id: &'life1 str,
) -> Pin<Box<dyn Future<Output = Result<Option<E>, RepositoryError>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
fn find_by_id_including_deleted<'life0, 'life1, 'async_trait>(
&'life0 self,
id: &'life1 str,
) -> Pin<Box<dyn Future<Output = Result<Option<E>, RepositoryError>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
Find entity by ID (including soft-deleted, for trash operations)
Source§fn update<'life0, 'async_trait>(
&'life0 self,
entity: E,
) -> Pin<Box<dyn Future<Output = Result<E, RepositoryError>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
fn update<'life0, 'async_trait>(
&'life0 self,
entity: E,
) -> Pin<Box<dyn Future<Output = Result<E, RepositoryError>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
Update an existing entity
Source§fn soft_delete<'life0, 'life1, 'async_trait>(
&'life0 self,
id: &'life1 str,
) -> Pin<Box<dyn Future<Output = Result<bool, RepositoryError>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
fn soft_delete<'life0, 'life1, 'async_trait>(
&'life0 self,
id: &'life1 str,
) -> Pin<Box<dyn Future<Output = Result<bool, RepositoryError>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
Soft delete an entity
Source§fn restore<'life0, 'life1, 'async_trait>(
&'life0 self,
id: &'life1 str,
) -> Pin<Box<dyn Future<Output = Result<Option<E>, RepositoryError>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
fn restore<'life0, 'life1, 'async_trait>(
&'life0 self,
id: &'life1 str,
) -> Pin<Box<dyn Future<Output = Result<Option<E>, RepositoryError>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
Restore a soft-deleted entity
Source§fn hard_delete<'life0, 'life1, 'async_trait>(
&'life0 self,
id: &'life1 str,
) -> Pin<Box<dyn Future<Output = Result<bool, RepositoryError>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
fn hard_delete<'life0, 'life1, 'async_trait>(
&'life0 self,
id: &'life1 str,
) -> Pin<Box<dyn Future<Output = Result<bool, RepositoryError>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
Permanently delete an entity
Source§fn list<'life0, 'async_trait>(
&'life0 self,
page: u32,
limit: u32,
) -> Pin<Box<dyn Future<Output = Result<(Vec<E>, u64), RepositoryError>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
fn list<'life0, 'async_trait>(
&'life0 self,
page: u32,
limit: u32,
) -> Pin<Box<dyn Future<Output = Result<(Vec<E>, u64), RepositoryError>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
List entities with pagination (excluding soft-deleted)
Source§fn list_deleted<'life0, 'async_trait>(
&'life0 self,
page: u32,
limit: u32,
) -> Pin<Box<dyn Future<Output = Result<(Vec<E>, u64), RepositoryError>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
fn list_deleted<'life0, 'async_trait>(
&'life0 self,
page: u32,
limit: u32,
) -> Pin<Box<dyn Future<Output = Result<(Vec<E>, u64), RepositoryError>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
List soft-deleted entities with pagination
Source§fn count<'life0, 'async_trait>(
&'life0 self,
) -> Pin<Box<dyn Future<Output = Result<u64, RepositoryError>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
fn count<'life0, 'async_trait>(
&'life0 self,
) -> Pin<Box<dyn Future<Output = Result<u64, RepositoryError>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
Count all entities (excluding soft-deleted)
Source§fn count_deleted<'life0, 'async_trait>(
&'life0 self,
) -> Pin<Box<dyn Future<Output = Result<u64, RepositoryError>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
fn count_deleted<'life0, 'async_trait>(
&'life0 self,
) -> Pin<Box<dyn Future<Output = Result<u64, RepositoryError>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
Count soft-deleted entities
Source§fn bulk_create<'life0, 'async_trait>(
&'life0 self,
entities: Vec<E>,
) -> Pin<Box<dyn Future<Output = Result<Vec<E>, RepositoryError>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
fn bulk_create<'life0, 'async_trait>(
&'life0 self,
entities: Vec<E>,
) -> Pin<Box<dyn Future<Output = Result<Vec<E>, RepositoryError>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
Bulk create entities
Source§fn empty_trash<'life0, 'async_trait>(
&'life0 self,
) -> Pin<Box<dyn Future<Output = Result<u64, RepositoryError>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
fn empty_trash<'life0, 'async_trait>(
&'life0 self,
) -> Pin<Box<dyn Future<Output = Result<u64, RepositoryError>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
Permanently delete all soft-deleted entities
Source§fn update_changed<'life0, 'life1, 'async_trait>(
&'life0 self,
before: &'life1 E,
after: E,
) -> Pin<Box<dyn Future<Output = Result<Option<E>, RepositoryError>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
fn update_changed<'life0, 'life1, 'async_trait>(
&'life0 self,
before: &'life1 E,
after: E,
) -> Pin<Box<dyn Future<Output = Result<Option<E>, RepositoryError>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
Update an entity from
before (the row as read) to after, writing only the fields
whose value differs between the two. Ok(None) when the row no longer exists or was
soft-deleted since it was read — the write must never revive it. Read moreSource§fn list_deleted_filtered<'life0, 'async_trait>(
&'life0 self,
page: u32,
limit: u32,
filters: HashMap<String, String>,
) -> Pin<Box<dyn Future<Output = Result<(Vec<E>, u64), RepositoryError>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
fn list_deleted_filtered<'life0, 'async_trait>(
&'life0 self,
page: u32,
limit: u32,
filters: HashMap<String, String>,
) -> Pin<Box<dyn Future<Output = Result<(Vec<E>, u64), RepositoryError>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
List soft-deleted entities with pagination, filters and search — the trash twin of
list_filtered. Read moreSource§fn list_filtered<'life0, 'async_trait>(
&'life0 self,
page: u32,
limit: u32,
filters: HashMap<String, String>,
) -> Pin<Box<dyn Future<Output = Result<(Vec<E>, u64), RepositoryError>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
fn list_filtered<'life0, 'async_trait>(
&'life0 self,
page: u32,
limit: u32,
filters: HashMap<String, String>,
) -> Pin<Box<dyn Future<Output = Result<(Vec<E>, u64), RepositoryError>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
List entities with pagination and filters (excluding soft-deleted) Read more
Source§fn list_filtered_with_info<'life0, 'async_trait>(
&'life0 self,
page: u32,
limit: u32,
filters: HashMap<String, String>,
) -> Pin<Box<dyn Future<Output = Result<(Vec<E>, PaginationInfo), RepositoryError>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
fn list_filtered_with_info<'life0, 'async_trait>(
&'life0 self,
page: u32,
limit: u32,
filters: HashMap<String, String>,
) -> Pin<Box<dyn Future<Output = Result<(Vec<E>, PaginationInfo), RepositoryError>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
list_filtered, carrying the pagination info (cursor positions
included) so the HTTP layer can surface keyset paging. Default: the
tuple form with the cursor fields absent; the generated Postgres
repositories override this with the real keyset walk.Source§fn table_name(&self) -> Option<&str>
fn table_name(&self) -> Option<&str>
Group and reduce entities under the same filters as
list_filtered. Read morefn aggregate_filtered<'life0, 'life1, 'async_trait>(
&'life0 self,
spec: &'life1 AggregateSpec,
filters: HashMap<String, String>,
) -> Pin<Box<dyn Future<Output = Result<AggregateResult, RepositoryError>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
Hydrate
?include= relations: fetch rows from table by id list, as JSON
(raw row_to_json). table comes from EntityRepoMeta::relations()
(generator-emitted), never client input. Default: no expansion. The
Postgres-backed generated repos override this via impl_crud_repository!.Source§fn reference_visible<'life0, 'life1, 'life2, 'life3, 'async_trait>(
&'life0 self,
table: &'life1 str,
column: &'life2 str,
value: &'life3 Value,
) -> Pin<Box<dyn Future<Output = Result<Option<bool>, RepositoryError>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
'life2: 'async_trait,
'life3: 'async_trait,
fn reference_visible<'life0, 'life1, 'life2, 'life3, 'async_trait>(
&'life0 self,
table: &'life1 str,
column: &'life2 str,
value: &'life3 Value,
) -> Pin<Box<dyn Future<Output = Result<Option<bool>, RepositoryError>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
'life2: 'async_trait,
'life3: 'async_trait,
Whether the row of
table whose column holds value is visible to the caller:
read on the request’s own connection and scope, so a row row-level security hides
counts as absent. table comes from PersistentEntity::references
(generator-emitted), never from client input. Read moreSource§fn exists<'life0, 'life1, 'async_trait>(
&'life0 self,
id: &'life1 str,
) -> Pin<Box<dyn Future<Output = Result<bool, RepositoryError>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
fn exists<'life0, 'life1, 'async_trait>(
&'life0 self,
id: &'life1 str,
) -> Pin<Box<dyn Future<Output = Result<bool, RepositoryError>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
Check if an entity exists by ID
Source§fn bulk_soft_delete<'life0, 'life1, 'async_trait>(
&'life0 self,
ids: &'life1 [String],
) -> Pin<Box<dyn Future<Output = Result<u64, RepositoryError>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
fn bulk_soft_delete<'life0, 'life1, 'async_trait>(
&'life0 self,
ids: &'life1 [String],
) -> Pin<Box<dyn Future<Output = Result<u64, RepositoryError>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
Soft-delete many entities by id. Returns the number affected.
Source§fn bulk_restore<'life0, 'life1, 'async_trait>(
&'life0 self,
ids: &'life1 [String],
) -> Pin<Box<dyn Future<Output = Result<Vec<E>, RepositoryError>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
fn bulk_restore<'life0, 'life1, 'async_trait>(
&'life0 self,
ids: &'life1 [String],
) -> Pin<Box<dyn Future<Output = Result<Vec<E>, RepositoryError>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
Restore many soft-deleted entities by id. Returns the restored entities.
Source§fn bulk_hard_delete<'life0, 'life1, 'async_trait>(
&'life0 self,
ids: &'life1 [String],
) -> Pin<Box<dyn Future<Output = Result<u64, RepositoryError>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
fn bulk_hard_delete<'life0, 'life1, 'async_trait>(
&'life0 self,
ids: &'life1 [String],
) -> Pin<Box<dyn Future<Output = Result<u64, RepositoryError>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
Permanently delete many entities by id. Returns the number affected.
Source§fn restore_all<'life0, 'async_trait>(
&'life0 self,
) -> Pin<Box<dyn Future<Output = Result<Vec<E>, RepositoryError>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
fn restore_all<'life0, 'async_trait>(
&'life0 self,
) -> Pin<Box<dyn Future<Output = Result<Vec<E>, RepositoryError>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
Restore every soft-deleted entity. Returns the restored entities.
Source§fn bulk_update<'life0, 'async_trait>(
&'life0 self,
entities: Vec<E>,
) -> Pin<Box<dyn Future<Output = Result<Vec<E>, RepositoryError>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
fn bulk_update<'life0, 'async_trait>(
&'life0 self,
entities: Vec<E>,
) -> Pin<Box<dyn Future<Output = Result<Vec<E>, RepositoryError>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
Update many entities atomically. Returns the updated entities.
Source§fn bulk_update_changed<'life0, 'async_trait>(
&'life0 self,
pairs: Vec<(E, E)>,
) -> Pin<Box<dyn Future<Output = Result<Vec<E>, RepositoryError>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
fn bulk_update_changed<'life0, 'async_trait>(
&'life0 self,
pairs: Vec<(E, E)>,
) -> Pin<Box<dyn Future<Output = Result<Vec<E>, RepositoryError>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
Update many entities from
(before, after) pairs, writing for each only the fields that
changed — the batch twin of update_changed, and the path the
generic bulk PUT and bulk PATCH take. A row missing or deleted since it was read fails
the batch, with the error placed on that item. Read moreSource§impl<E> Default for InMemoryRepository<E>where
E: PersistentEntity,
impl<E> Default for InMemoryRepository<E>where
E: PersistentEntity,
Source§impl<E> SearchableRepository<E> for InMemoryRepository<E>where
E: PersistentEntity,
impl<E> SearchableRepository<E> for InMemoryRepository<E>where
E: PersistentEntity,
Source§fn search<'life0, 'async_trait>(
&'life0 self,
filters: HashMap<String, String>,
page: u32,
limit: u32,
) -> Pin<Box<dyn Future<Output = Result<(Vec<E>, u64), RepositoryError>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
fn search<'life0, 'async_trait>(
&'life0 self,
filters: HashMap<String, String>,
page: u32,
limit: u32,
) -> Pin<Box<dyn Future<Output = Result<(Vec<E>, u64), RepositoryError>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
Search entities with filters
Source§fn find_by_field<'life0, 'life1, 'life2, 'async_trait>(
&'life0 self,
field: &'life1 str,
value: &'life2 str,
) -> Pin<Box<dyn Future<Output = Result<Option<E>, RepositoryError>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
'life2: 'async_trait,
fn find_by_field<'life0, 'life1, 'life2, 'async_trait>(
&'life0 self,
field: &'life1 str,
value: &'life2 str,
) -> Pin<Box<dyn Future<Output = Result<Option<E>, RepositoryError>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
'life2: 'async_trait,
Find by a specific field value
Source§fn find_all_by_field<'life0, 'life1, 'life2, 'async_trait>(
&'life0 self,
field: &'life1 str,
value: &'life2 str,
page: u32,
limit: u32,
) -> Pin<Box<dyn Future<Output = Result<(Vec<E>, u64), RepositoryError>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
'life2: 'async_trait,
fn find_all_by_field<'life0, 'life1, 'life2, 'async_trait>(
&'life0 self,
field: &'life1 str,
value: &'life2 str,
page: u32,
limit: u32,
) -> Pin<Box<dyn Future<Output = Result<(Vec<E>, u64), RepositoryError>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
'life2: 'async_trait,
Find all by a specific field value
Auto Trait Implementations§
impl<E> !Freeze for InMemoryRepository<E>
impl<E> RefUnwindSafe for InMemoryRepository<E>
impl<E> Send for InMemoryRepository<E>
impl<E> Sync for InMemoryRepository<E>
impl<E> Unpin for InMemoryRepository<E>
impl<E> UnsafeUnpin for InMemoryRepository<E>
impl<E> UnwindSafe for InMemoryRepository<E>
Blanket Implementations§
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
Mutably borrows from an owned value. Read more
impl<ST, DT> CastableFrom<ST, Initialized, Initialized> for DT
impl<ST, DT> CastableFrom<ST, Uninit, Uninit> for DT
Source§impl<T> Instrument for T
impl<T> Instrument for T
Source§fn instrument(self, span: Span) -> Instrumented<Self> ⓘ
fn instrument(self, span: Span) -> Instrumented<Self> ⓘ
Source§fn in_current_span(self) -> Instrumented<Self> ⓘ
fn in_current_span(self) -> Instrumented<Self> ⓘ
Source§impl<T> IntoEither for T
impl<T> IntoEither for T
Source§fn into_either(self, into_left: bool) -> Either<Self, Self> ⓘ
fn into_either(self, into_left: bool) -> Either<Self, Self> ⓘ
Converts
self into a Left variant of Either<Self, Self>
if into_left is true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read moreSource§fn into_either_with<F>(self, into_left: F) -> Either<Self, Self> ⓘ
fn into_either_with<F>(self, into_left: F) -> Either<Self, Self> ⓘ
Converts
self into a Left variant of Either<Self, Self>
if into_left(&self) returns true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read more