pub struct Repository<M: Model, A: DatabaseAdapter> { /* private fields */ }Expand description
Typed, high-level repository for a single model type M.
Repository is the main entry point for CRUD operations. It wraps an
Arc-shared DatabaseAdapter so multiple repositories (or threads)
can share one connection pool.
§Obtaining a repository
use rusticx::prelude::*;
use std::sync::Arc;
let adapter = PostgresAdapter::connect_url("postgres://localhost/mydb").await?;
let repo: Repository<User, _> = Repository::new(Arc::new(adapter));§Thread safety
Repository is Clone and Send + Sync — share it freely across tasks
and threads. The underlying connection pool handles concurrency.
Implementations§
Source§impl<M: Model, A: DatabaseAdapter> Repository<M, A>
impl<M: Model, A: DatabaseAdapter> Repository<M, A>
pub fn new(adapter: Arc<A>) -> Self
pub fn adapter(&self) -> &A
Sourcepub async fn migrate(&self) -> Result<()>
pub async fn migrate(&self) -> Result<()>
Create the table / collection for M if it does not already exist.
Safe to call on every startup — it is idempotent (CREATE TABLE IF NOT EXISTS).
Sourcepub async fn insert(&self, model: &M) -> Result<M>
pub async fn insert(&self, model: &M) -> Result<M>
Insert one model instance and return it with any generated fields filled in (e.g. database-generated timestamps, auto-increment IDs).
Sourcepub async fn insert_many(&self, models: &[M]) -> Result<u64>
pub async fn insert_many(&self, models: &[M]) -> Result<u64>
Insert a slice of models in a single transaction. Returns the count inserted.
Sourcepub async fn find_all(&self) -> Result<Vec<M>>
pub async fn find_all(&self) -> Result<Vec<M>>
Fetch every row in the table. Use find with a QueryBuilder for filtering.
Caution: can return very large result sets on big tables.
Sourcepub async fn find_by_id(&self, id: impl Into<Value>) -> Result<Option<M>>
pub async fn find_by_id(&self, id: impl Into<Value>) -> Result<Option<M>>
Find a single record by primary key. Returns None if not found.
Sourcepub async fn find_one(&self, qb: QueryBuilder) -> Result<Option<M>>
pub async fn find_one(&self, qb: QueryBuilder) -> Result<Option<M>>
Find the first record matching the given query. Returns None if no match.
Sourcepub async fn find(&self, qb: QueryBuilder) -> Result<Vec<M>>
pub async fn find(&self, qb: QueryBuilder) -> Result<Vec<M>>
Find all records matching the given query.
Build the query with Repository::query for ergonomic chaining:
let results = repo.find(
repo.query()
.r#where("age", CondOp::Gte, 18)
.order_by("name", Direction::Asc)
.limit(50)
).await?;Sourcepub async fn paginate(&self, page: u64, per_page: u64) -> Result<Vec<M>>
pub async fn paginate(&self, page: u64, per_page: u64) -> Result<Vec<M>>
Fetch one page of results. page is 1-indexed.
// Page 2, 20 records per page
let page = repo.paginate(2, 20).await?;Sourcepub async fn count(&self, qb: Option<QueryBuilder>) -> Result<u64>
pub async fn count(&self, qb: Option<QueryBuilder>) -> Result<u64>
Count records. Pass None to count all rows, or Some(qb) to count
only rows matching the query.
Sourcepub async fn update(&self, qb: QueryBuilder) -> Result<u64>
pub async fn update(&self, qb: QueryBuilder) -> Result<u64>
Update rows matching the query. Returns the number of rows affected.
Use .set(column, value) on the query builder to specify new values:
repo.update(
repo.query()
.r#where("email", CondOp::Eq, "alice@example.com")
.set("age", 31)
.set("active", false)
).await?;Sourcepub async fn save(&self, model: &M) -> Result<M>
pub async fn save(&self, model: &M) -> Result<M>
Upsert: insert if the primary key is null/absent, update if it is set.
This is the idiomatic way to persist a model without knowing whether it already exists in the database.
Sourcepub async fn delete_by_id(&self, id: impl Into<Value>) -> Result<u64>
pub async fn delete_by_id(&self, id: impl Into<Value>) -> Result<u64>
Delete the record with the given primary key. Returns 1 if deleted, 0 if not found.
Sourcepub async fn delete(&self, qb: QueryBuilder) -> Result<u64>
pub async fn delete(&self, qb: QueryBuilder) -> Result<u64>
Delete all records matching the query. Returns the count deleted.
Sourcepub fn query(&self) -> QueryBuilder
pub fn query(&self) -> QueryBuilder
Start building a query pre-scoped to this model’s table.
This is the idiomatic starting point for all filtered operations:
repo.find(repo.query().r#where("active", CondOp::Eq, true)).await?