pub trait Repository<M>:
Send
+ Sync
+ 'staticwhere
M: Model,{
Show 22 methods
// Required methods
fn all<'life0, 'async_trait>(
&'life0 self,
) -> Pin<Box<dyn Future<Output = Result<Vec<M>, Error>> + Send + 'async_trait>>
where 'life0: 'async_trait,
Self: 'async_trait;
fn find<'life0, 'async_trait>(
&'life0 self,
key: Value,
) -> Pin<Box<dyn Future<Output = Result<Option<M>, Error>> + Send + 'async_trait>>
where 'life0: 'async_trait,
Self: 'async_trait;
fn find_by<'life0, 'life1, 'async_trait>(
&'life0 self,
column: &'life1 str,
value: Value,
) -> Pin<Box<dyn Future<Output = Result<Vec<M>, Error>> + Send + 'async_trait>>
where 'life0: 'async_trait,
'life1: 'async_trait,
Self: 'async_trait;
fn first_by<'life0, 'life1, 'async_trait>(
&'life0 self,
column: &'life1 str,
value: Value,
) -> Pin<Box<dyn Future<Output = Result<Option<M>, Error>> + Send + 'async_trait>>
where 'life0: 'async_trait,
'life1: 'async_trait,
Self: 'async_trait;
fn matching<'life0, 'async_trait>(
&'life0 self,
criteria: Criteria,
) -> Pin<Box<dyn Future<Output = Result<Vec<M>, Error>> + Send + 'async_trait>>
where 'life0: 'async_trait,
Self: 'async_trait;
fn first_matching<'life0, 'async_trait>(
&'life0 self,
criteria: Criteria,
) -> Pin<Box<dyn Future<Output = Result<Option<M>, Error>> + Send + 'async_trait>>
where 'life0: 'async_trait,
Self: 'async_trait;
fn count_matching<'life0, 'async_trait>(
&'life0 self,
criteria: Criteria,
) -> Pin<Box<dyn Future<Output = Result<u64, Error>> + Send + 'async_trait>>
where 'life0: 'async_trait,
Self: 'async_trait;
fn paginate_matching<'life0, 'async_trait>(
&'life0 self,
criteria: Criteria,
page: u64,
per_page: u64,
) -> Pin<Box<dyn Future<Output = Result<Paginated<M>, Error>> + Send + 'async_trait>>
where 'life0: 'async_trait,
Self: 'async_trait;
fn create<'life0, 'async_trait>(
&'life0 self,
model: M,
) -> Pin<Box<dyn Future<Output = Result<M, Error>> + Send + 'async_trait>>
where 'life0: 'async_trait,
Self: 'async_trait;
fn update<'life0, 'life1, 'async_trait>(
&'life0 self,
model: &'life1 M,
) -> Pin<Box<dyn Future<Output = Result<u64, Error>> + Send + 'async_trait>>
where 'life0: 'async_trait,
'life1: 'async_trait,
Self: 'async_trait;
fn upsert<'life0, 'life1, 'life2, 'life3, 'life4, 'life5, 'async_trait>(
&'life0 self,
model: &'life1 M,
conflict_columns: &'life2 [&'life3 str],
update_columns: &'life4 [&'life5 str],
) -> Pin<Box<dyn Future<Output = Result<u64, Error>> + Send + 'async_trait>>
where 'life0: 'async_trait,
'life1: 'async_trait,
'life2: 'async_trait,
'life3: 'async_trait,
'life4: 'async_trait,
'life5: 'async_trait,
Self: 'async_trait;
fn delete<'life0, 'async_trait>(
&'life0 self,
key: Value,
) -> Pin<Box<dyn Future<Output = Result<u64, Error>> + Send + 'async_trait>>
where 'life0: 'async_trait,
Self: 'async_trait;
fn delete_matching<'life0, 'async_trait>(
&'life0 self,
criteria: Criteria,
) -> Pin<Box<dyn Future<Output = Result<u64, Error>> + Send + 'async_trait>>
where 'life0: 'async_trait,
Self: 'async_trait;
// Provided methods
fn count_grouped<'life0, 'life1, 'async_trait>(
&'life0 self,
column: &'life1 str,
criteria: Criteria,
) -> Pin<Box<dyn Future<Output = Result<Vec<(RelationKey, u64)>, Error>> + Send + 'async_trait>>
where 'life0: 'async_trait,
'life1: 'async_trait,
Self: 'async_trait { ... }
fn pivot_links<'life0, 'async_trait>(
&'life0 self,
query: PivotQuery,
) -> Pin<Box<dyn Future<Output = Result<Vec<(Value, Value)>, Error>> + Send + 'async_trait>>
where 'life0: 'async_trait,
Self: 'async_trait { ... }
fn find_key<'life0, 'async_trait>(
&'life0 self,
key: impl Into<Value> + Send + 'async_trait,
) -> Pin<Box<dyn Future<Output = Result<Option<M>, Error>> + Send + 'async_trait>>
where 'life0: 'async_trait,
Self: Sized + 'async_trait { ... }
fn find_or_fail<'life0, 'async_trait>(
&'life0 self,
key: impl Into<Value> + Send + 'async_trait,
) -> Pin<Box<dyn Future<Output = Result<M, Error>> + Send + 'async_trait>>
where 'life0: 'async_trait,
Self: Sized + 'async_trait { ... }
fn find_by_route_key<'life0, 'async_trait>(
&'life0 self,
value: impl Into<Value> + Send + 'async_trait,
) -> Pin<Box<dyn Future<Output = Result<Option<M>, Error>> + Send + 'async_trait>>
where 'life0: 'async_trait,
Self: Sized + 'async_trait { ... }
fn where_eq<'life0, 'life1, 'async_trait>(
&'life0 self,
column: &'life1 str,
value: impl Into<Value> + Send + 'async_trait,
) -> Pin<Box<dyn Future<Output = Result<Vec<M>, Error>> + Send + 'async_trait>>
where 'life0: 'async_trait,
'life1: 'async_trait,
Self: Sized + 'async_trait { ... }
fn count<'life0, 'async_trait>(
&'life0 self,
) -> Pin<Box<dyn Future<Output = Result<u64, Error>> + Send + 'async_trait>>
where 'life0: 'async_trait,
Self: Sized + 'async_trait { ... }
fn paginate<'life0, 'async_trait>(
&'life0 self,
page: u64,
per_page: u64,
) -> Pin<Box<dyn Future<Output = Result<Paginated<M>, Error>> + Send + 'async_trait>>
where 'life0: 'async_trait,
Self: Sized + 'async_trait { ... }
fn exists<'life0, 'async_trait>(
&'life0 self,
criteria: Criteria,
) -> Pin<Box<dyn Future<Output = Result<bool, Error>> + Send + 'async_trait>>
where 'life0: 'async_trait,
Self: Sized + 'async_trait { ... }
}Expand description
Read and write access to one model’s rows.
Object-safe: keys and values arrive as Value rather than through
generic parameters, so Arc<dyn Repository<Post>> is a usable dependency.
The ergonomic generic wrappers are provided methods bounded on
Self: Sized, which keeps them out of the vtable.
Required Methods§
Sourcefn all<'life0, 'async_trait>(
&'life0 self,
) -> Pin<Box<dyn Future<Output = Result<Vec<M>, Error>> + Send + 'async_trait>>where
'life0: 'async_trait,
Self: 'async_trait,
fn all<'life0, 'async_trait>(
&'life0 self,
) -> Pin<Box<dyn Future<Output = Result<Vec<M>, Error>> + Send + 'async_trait>>where
'life0: 'async_trait,
Self: 'async_trait,
Every row. Prefer paginate for anything unbounded.
Sourcefn find<'life0, 'async_trait>(
&'life0 self,
key: Value,
) -> Pin<Box<dyn Future<Output = Result<Option<M>, Error>> + Send + 'async_trait>>where
'life0: 'async_trait,
Self: 'async_trait,
fn find<'life0, 'async_trait>(
&'life0 self,
key: Value,
) -> Pin<Box<dyn Future<Output = Result<Option<M>, Error>> + Send + 'async_trait>>where
'life0: 'async_trait,
Self: 'async_trait,
The row with this primary key.
Sourcefn find_by<'life0, 'life1, 'async_trait>(
&'life0 self,
column: &'life1 str,
value: Value,
) -> Pin<Box<dyn Future<Output = Result<Vec<M>, Error>> + Send + 'async_trait>>where
'life0: 'async_trait,
'life1: 'async_trait,
Self: 'async_trait,
fn find_by<'life0, 'life1, 'async_trait>(
&'life0 self,
column: &'life1 str,
value: Value,
) -> Pin<Box<dyn Future<Output = Result<Vec<M>, Error>> + Send + 'async_trait>>where
'life0: 'async_trait,
'life1: 'async_trait,
Self: 'async_trait,
Every row where column equals value — how a relationship is
traversed, since the ORM keeps foreign keys as flat columns.
Sourcefn first_by<'life0, 'life1, 'async_trait>(
&'life0 self,
column: &'life1 str,
value: Value,
) -> Pin<Box<dyn Future<Output = Result<Option<M>, Error>> + Send + 'async_trait>>where
'life0: 'async_trait,
'life1: 'async_trait,
Self: 'async_trait,
fn first_by<'life0, 'life1, 'async_trait>(
&'life0 self,
column: &'life1 str,
value: Value,
) -> Pin<Box<dyn Future<Output = Result<Option<M>, Error>> + Send + 'async_trait>>where
'life0: 'async_trait,
'life1: 'async_trait,
Self: 'async_trait,
The first row where column equals value.
Sourcefn matching<'life0, 'async_trait>(
&'life0 self,
criteria: Criteria,
) -> Pin<Box<dyn Future<Output = Result<Vec<M>, Error>> + Send + 'async_trait>>where
'life0: 'async_trait,
Self: 'async_trait,
fn matching<'life0, 'async_trait>(
&'life0 self,
criteria: Criteria,
) -> Pin<Box<dyn Future<Output = Result<Vec<M>, Error>> + Send + 'async_trait>>where
'life0: 'async_trait,
Self: 'async_trait,
Every row matching criteria.
Sourcefn first_matching<'life0, 'async_trait>(
&'life0 self,
criteria: Criteria,
) -> Pin<Box<dyn Future<Output = Result<Option<M>, Error>> + Send + 'async_trait>>where
'life0: 'async_trait,
Self: 'async_trait,
fn first_matching<'life0, 'async_trait>(
&'life0 self,
criteria: Criteria,
) -> Pin<Box<dyn Future<Output = Result<Option<M>, Error>> + Send + 'async_trait>>where
'life0: 'async_trait,
Self: 'async_trait,
The first row matching criteria.
Sourcefn count_matching<'life0, 'async_trait>(
&'life0 self,
criteria: Criteria,
) -> Pin<Box<dyn Future<Output = Result<u64, Error>> + Send + 'async_trait>>where
'life0: 'async_trait,
Self: 'async_trait,
fn count_matching<'life0, 'async_trait>(
&'life0 self,
criteria: Criteria,
) -> Pin<Box<dyn Future<Output = Result<u64, Error>> + Send + 'async_trait>>where
'life0: 'async_trait,
Self: 'async_trait,
How many rows match criteria, ignoring its paging.
Sourcefn paginate_matching<'life0, 'async_trait>(
&'life0 self,
criteria: Criteria,
page: u64,
per_page: u64,
) -> Pin<Box<dyn Future<Output = Result<Paginated<M>, Error>> + Send + 'async_trait>>where
'life0: 'async_trait,
Self: 'async_trait,
fn paginate_matching<'life0, 'async_trait>(
&'life0 self,
criteria: Criteria,
page: u64,
per_page: u64,
) -> Pin<Box<dyn Future<Output = Result<Paginated<M>, Error>> + Send + 'async_trait>>where
'life0: 'async_trait,
Self: 'async_trait,
One page of rows matching criteria.
Sourcefn create<'life0, 'async_trait>(
&'life0 self,
model: M,
) -> Pin<Box<dyn Future<Output = Result<M, Error>> + Send + 'async_trait>>where
'life0: 'async_trait,
Self: 'async_trait,
fn create<'life0, 'async_trait>(
&'life0 self,
model: M,
) -> Pin<Box<dyn Future<Output = Result<M, Error>> + Send + 'async_trait>>where
'life0: 'async_trait,
Self: 'async_trait,
Insert a row, returning it with any database-assigned key.
Sourcefn update<'life0, 'life1, 'async_trait>(
&'life0 self,
model: &'life1 M,
) -> Pin<Box<dyn Future<Output = Result<u64, Error>> + Send + 'async_trait>>where
'life0: 'async_trait,
'life1: 'async_trait,
Self: 'async_trait,
fn update<'life0, 'life1, 'async_trait>(
&'life0 self,
model: &'life1 M,
) -> Pin<Box<dyn Future<Output = Result<u64, Error>> + Send + 'async_trait>>where
'life0: 'async_trait,
'life1: 'async_trait,
Self: 'async_trait,
Update every non-key column of a row, matched by its primary key.
Sourcefn upsert<'life0, 'life1, 'life2, 'life3, 'life4, 'life5, 'async_trait>(
&'life0 self,
model: &'life1 M,
conflict_columns: &'life2 [&'life3 str],
update_columns: &'life4 [&'life5 str],
) -> Pin<Box<dyn Future<Output = Result<u64, Error>> + Send + 'async_trait>>where
'life0: 'async_trait,
'life1: 'async_trait,
'life2: 'async_trait,
'life3: 'async_trait,
'life4: 'async_trait,
'life5: 'async_trait,
Self: 'async_trait,
fn upsert<'life0, 'life1, 'life2, 'life3, 'life4, 'life5, 'async_trait>(
&'life0 self,
model: &'life1 M,
conflict_columns: &'life2 [&'life3 str],
update_columns: &'life4 [&'life5 str],
) -> Pin<Box<dyn Future<Output = Result<u64, Error>> + Send + 'async_trait>>where
'life0: 'async_trait,
'life1: 'async_trait,
'life2: 'async_trait,
'life3: 'async_trait,
'life4: 'async_trait,
'life5: 'async_trait,
Self: 'async_trait,
Insert, or update on a conflict with conflict_columns. An empty
update_columns makes it insert-or-ignore.
Provided Methods§
Sourcefn count_grouped<'life0, 'life1, 'async_trait>(
&'life0 self,
column: &'life1 str,
criteria: Criteria,
) -> Pin<Box<dyn Future<Output = Result<Vec<(RelationKey, u64)>, Error>> + Send + 'async_trait>>where
'life0: 'async_trait,
'life1: 'async_trait,
Self: 'async_trait,
fn count_grouped<'life0, 'life1, 'async_trait>(
&'life0 self,
column: &'life1 str,
criteria: Criteria,
) -> Pin<Box<dyn Future<Output = Result<Vec<(RelationKey, u64)>, Error>> + Send + 'async_trait>>where
'life0: 'async_trait,
'life1: 'async_trait,
Self: 'async_trait,
SELECT column, COUNT(*) GROUP BY column — how many rows share each
value of column.
What Relation::count is: one query
for every parent’s child count, rather than one per parent.
The default loads the rows and tallies them, which is correct for any
implementation and wrong only in what it transfers.
EntityRepository overrides it with a real GROUP BY.
Sourcefn pivot_links<'life0, 'async_trait>(
&'life0 self,
query: PivotQuery,
) -> Pin<Box<dyn Future<Output = Result<Vec<(Value, Value)>, Error>> + Send + 'async_trait>>where
'life0: 'async_trait,
Self: 'async_trait,
fn pivot_links<'life0, 'async_trait>(
&'life0 self,
query: PivotQuery,
) -> Pin<Box<dyn Future<Output = Result<Vec<(Value, Value)>, Error>> + Send + 'async_trait>>where
'life0: 'async_trait,
Self: 'async_trait,
Read a pivot table’s (parent, related) links.
A pivot is two columns and no model, so it cannot go through the typed
path. It lives on this trait rather than on Database so that a fake
repository can answer it — a many-to-many is not testable otherwise.
The default returns nothing, which is what a repository with no database behind it honestly has.
Sourcefn find_key<'life0, 'async_trait>(
&'life0 self,
key: impl Into<Value> + Send + 'async_trait,
) -> Pin<Box<dyn Future<Output = Result<Option<M>, Error>> + Send + 'async_trait>>where
'life0: 'async_trait,
Self: Sized + 'async_trait,
fn find_key<'life0, 'async_trait>(
&'life0 self,
key: impl Into<Value> + Send + 'async_trait,
) -> Pin<Box<dyn Future<Output = Result<Option<M>, Error>> + Send + 'async_trait>>where
'life0: 'async_trait,
Self: Sized + 'async_trait,
find with a key of any convertible type.
Sourcefn find_or_fail<'life0, 'async_trait>(
&'life0 self,
key: impl Into<Value> + Send + 'async_trait,
) -> Pin<Box<dyn Future<Output = Result<M, Error>> + Send + 'async_trait>>where
'life0: 'async_trait,
Self: Sized + 'async_trait,
fn find_or_fail<'life0, 'async_trait>(
&'life0 self,
key: impl Into<Value> + Send + 'async_trait,
) -> Pin<Box<dyn Future<Output = Result<M, Error>> + Send + 'async_trait>>where
'life0: 'async_trait,
Self: Sized + 'async_trait,
find, failing with a 404 naming the model when there
is no such row — what a controller almost always wants.
Sourcefn find_by_route_key<'life0, 'async_trait>(
&'life0 self,
value: impl Into<Value> + Send + 'async_trait,
) -> Pin<Box<dyn Future<Output = Result<Option<M>, Error>> + Send + 'async_trait>>where
'life0: 'async_trait,
Self: Sized + 'async_trait,
fn find_by_route_key<'life0, 'async_trait>(
&'life0 self,
value: impl Into<Value> + Send + 'async_trait,
) -> Pin<Box<dyn Future<Output = Result<Option<M>, Error>> + Send + 'async_trait>>where
'life0: 'async_trait,
Self: Sized + 'async_trait,
The row whose route key equals value —
route-model binding’s lookup.
Sourcefn where_eq<'life0, 'life1, 'async_trait>(
&'life0 self,
column: &'life1 str,
value: impl Into<Value> + Send + 'async_trait,
) -> Pin<Box<dyn Future<Output = Result<Vec<M>, Error>> + Send + 'async_trait>>where
'life0: 'async_trait,
'life1: 'async_trait,
Self: Sized + 'async_trait,
fn where_eq<'life0, 'life1, 'async_trait>(
&'life0 self,
column: &'life1 str,
value: impl Into<Value> + Send + 'async_trait,
) -> Pin<Box<dyn Future<Output = Result<Vec<M>, Error>> + Send + 'async_trait>>where
'life0: 'async_trait,
'life1: 'async_trait,
Self: Sized + 'async_trait,
Every row where column equals a value of any convertible type.
Sourcefn count<'life0, 'async_trait>(
&'life0 self,
) -> Pin<Box<dyn Future<Output = Result<u64, Error>> + Send + 'async_trait>>where
'life0: 'async_trait,
Self: Sized + 'async_trait,
fn count<'life0, 'async_trait>(
&'life0 self,
) -> Pin<Box<dyn Future<Output = Result<u64, Error>> + Send + 'async_trait>>where
'life0: 'async_trait,
Self: Sized + 'async_trait,
How many rows there are in total.
Dyn Compatibility§
This trait is dyn compatible.
In older versions of Rust, dyn compatibility was called "object safety".