Skip to main content

PgExperimentChangeRepository

Struct PgExperimentChangeRepository 

Source
pub struct PgExperimentChangeRepository { /* private fields */ }
Expand description

The generated repository.

Implementations§

Source§

impl PgExperimentChangeRepository

Source

pub fn from_shard(db: &ShardedDb) -> Self

Construct this repository from a ShardedDb extractor, preserving the full request instrumentation — statement timeout, slow-query threshold, and route metric label — from the shard context:

ⓘ
#[post("/bookmarks")]
async fn create(db: ShardedDb, Json(body): Json<Body>) -> AutumnResult<Json<Bookmark>> {
    let repo = BookmarkRepository::from_shard(&db);
    // repo carries the same timeout / slow-query / route label as `db`
    let bookmark = repo.save(&body.into()).await?;
    Ok(Json(bookmark))
}

Read-only methods route to the shard’s read replica when one is configured and healthy (honoring the shard’s replica_fallback policy); mutating methods always use the shard’s primary. Pin a single call chain to the primary with on_primary.

Use this constructor as the standard way to build a repository on a shard; prefer with_pool_untracked only when you intentionally want to bypass request instrumentation.

Source

pub fn with_pool_untracked(pool: Pool<RuntimeConnection>) -> Self

Construct this repository over an explicit pool, bypassing request instrumentation.

Statement timeout, slow-query threshold, and route metric labels are reset to framework defaults (no timeout, 500 ms threshold, no route label). Prefer from_shard when you have a ShardedDb available; use this constructor only when you need an explicit pool without any request context:

ⓘ
let repo = BookmarkRepository::with_pool_untracked(pool.clone());
Source

pub async fn recompute_counter_caches(&self) -> AutumnResult<usize>

Recompute every counter cache this model maintains, for all parent rows, from the source of truth (#1325).

Idempotent: running it twice leaves the same values. Returns the number of parent rows updated, summed across every counter-cached association (0 when the model declares none).

§Errors

Propagates any database error from the recompute UPDATEs.

Source

pub async fn recompute_counter_caches_for( &self, parent_id: i64, ) -> AutumnResult<usize>

Recompute every counter cache this model maintains for a single parent row (#1325), leaving every other parent untouched.

§Errors

Propagates any database error from the recompute UPDATEs.

Source

pub fn on_primary(&self) -> Self

Returns a clone of this repository whose generated read methods are pinned to the primary pool for the rest of the call chain — the read-your-writes escape hatch (#971).

Use immediately after a write when replication lag would make a replica read stale:

ⓘ
let created = repo.save(&new).await?;
let fresh = repo.on_primary().find_by_id(created.id).await?;

Mutating methods are unaffected — they always run on the primary.

Source

pub fn find_in_batches(&self, batch_size: usize) -> FindInBatches<'_, Self>

Iterate the whole table in bounded-memory chunks of at most batch_size rows, using a primary-key keyset cursor (not LIMIT/OFFSET), so deep iteration stays flat and is stable under concurrent inserts of rows ordered after the current position.

Soft-delete filtering, tenant scoping and read routing match find_all. Drive the returned handle with next_batch() in a while let loop; drop each chunk before requesting the next to hold at most batch_size models at a time.

Iteration ends at the first short batch; rows inserted after that point require a new iteration. Errors are retryable: the cursor only advances on success, so calling next_batch() again after an Err retries the same batch (Ok(None) always means completion). A batch_size of 0 yields an error on every next_batch().

ⓘ
let mut batches = repo.find_in_batches(1_000);
while let Some(chunk) = batches.next_batch().await? {
    repo.upsert_many(&recompute(chunk)).await?;
}

(upsert_many is not generated on repositories with hooks configured; use per-row update there.)

Source

pub fn find_each(&self, batch_size: usize) -> FindEach<'_, Self>

Iterate the whole table one model at a time while still fetching in bounded batch_size chunks — a convenience over find_in_batches.

ⓘ
let mut each = repo.find_each(500);
while let Some(row) = each.next().await? {
    repo.update(row.id, &patch).await?;
}
Source

pub fn count_grouped_by_experiment<'__agg>( &'__agg self, ) -> GroupedAggregate<'__agg, String, i64>

Grouped aggregate count_grouped_by_experiment → lazy GroupedAggregate<'_, K, V> builder (issue #1364).

Chain .order_by_aggregate_desc()/.limit(n) for top-N, .filter_eq(..)/.filter_range(lo, hi) to scope before grouping, or .bucket(DateBucket::Day) for a time series, then .load().await.

Source

pub async fn preload<__Model, __Spec>( &self, records: Vec<__Model>, spec: __Spec, ) -> AutumnResult<Vec<Preloaded<__Model>>>
where __Model: Preloadable<Spec = __Spec>, __Spec: Send + Sync,

Eager-load associations for records returned by a finder.

Wraps each record in Preloaded and loads every association named in spec with at most one batched WHERE ... IN (...) query per association level (plus one per nested level). No per-row fetches, and no implicit lazy loading — an un-preloaded association accessor returns NotLoaded.

Preload SQL runs on the same read role as the finder (the repository’s snapshotted ReadRoute), so a replica-routed list keeps its preloads on the replica.

ⓘ
let posts = repo.find_by_subreddit_id(id).await?;
let posts = repo
    .preload(posts, Post::preload().author().comments_with(Comment::preload().author()))
    .await?;
for post in &posts {
    let author = post.author()?;        // typed accessor
    for comment in post.comments()? { /* ... */ }
}
Source

pub async fn with_lock<F, T>(&self, id: i64, f: F) -> AutumnResult<T>
where F: for<'c> FnOnce(ExperimentChange, &'c mut RuntimeConnection) -> ScopedBoxFuture<'c, 'c, AutumnResult<T>> + Send + 'static, T: Send + 'static,

Pessimistic lock helper: SELECT FOR UPDATE the row with the given id inside a transaction, then call f with the locked record and the transaction connection.

Returns 404 Not Found if no row with id exists.

Trait Implementations§

Source§

impl BatchSource for PgExperimentChangeRepository

Source§

type Model = ExperimentChange

The model type yielded by iteration.
Source§

async fn fetch_batch_after( &self, after_id: Option<i64>, limit: i64, ) -> AutumnResult<Vec<ExperimentChange>>

Fetch up to limit models with id > after_id (or from the start of the table when after_id is None), ordered by id ascending.
Source§

fn batch_key(model: &ExperimentChange) -> i64

The primary key of a model, used to advance the keyset cursor.
Source§

impl Clone for PgExperimentChangeRepository

Source§

fn clone(&self) -> Self

Returns a duplicate of the value. Read more
1.0.0 (const: unstable) · Source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
Source§

impl ExperimentChangeRepository for PgExperimentChangeRepository

Source§

async fn find_by_id(&self, id: i64) -> AutumnResult<Option<ExperimentChange>>

Source§

async fn find_all(&self) -> AutumnResult<Vec<ExperimentChange>>

Source§

async fn save( &self, new: &NewExperimentChange, ) -> AutumnResult<ExperimentChange>

Source§

async fn update( &self, id: i64, changes: &UpdateExperimentChange, ) -> AutumnResult<ExperimentChange>

Source§

async fn delete_by_id(&self, id: i64) -> AutumnResult<()>

Source§

async fn count(&self) -> AutumnResult<i64>

Source§

async fn exists_by_id(&self, id: i64) -> AutumnResult<bool>

Source§

async fn page(&self, req: &PageRequest) -> AutumnResult<Page<ExperimentChange>>

Fetch one page of records using offset pagination. Read more
Source§

async fn list( &self, query: &ListQuery, req: &PageRequest, ) -> AutumnResult<Page<ExperimentChange>>

Fetch one page of records applying allowlisted sort + equality filters from a ::autumn_web::pagination::ListQuery, with offset pagination from a ::autumn_web::pagination::PageRequest. Read more
Source§

async fn list_rows( &self, query: &ListQuery, limit: usize, ) -> AutumnResult<Vec<ExperimentChange>>

Load up to limit records in list order, with the same allowlisted sort, filters and scope. Read more
Source§

async fn save_many( &self, new: &[NewExperimentChange], ) -> AutumnResult<Vec<ExperimentChange>>

Source§

async fn save_many_skip_invalid( &self, new: &[NewExperimentChange], ) -> AutumnResult<(Vec<ExperimentChange>, Vec<(usize, AutumnError)>)>

Source§

async fn update_many( &self, ids: &[i64], changes: &UpdateExperimentChange, ) -> AutumnResult<Vec<ExperimentChange>>

Source§

async fn delete_many(&self, ids: &[i64]) -> AutumnResult<()>

Bulk-delete the given ids in one statement. Read more
Source§

async fn upsert_many( &self, records: &[ExperimentChange], ) -> AutumnResult<Vec<ExperimentChange>>

Source§

impl FromRequestParts<AppState> for PgExperimentChangeRepository

Source§

type Rejection = AutumnError

If the extractor fails it’ll use this “rejection” type. A rejection is a kind of error that can be converted into a response.
Source§

async fn from_request_parts( _parts: &mut Parts, state: &AppState, ) -> Result<Self, Self::Rejection>

Perform the extraction.

Auto Trait Implementations§

Blanket Implementations§

Source§

impl<T> AggregateExpressionMethods for T

Source§

fn aggregate_distinct(self) -> Self::Output
where Self: DistinctDsl,

DISTINCT modifier for aggregate functions Read more
Source§

fn aggregate_all(self) -> Self::Output
where Self: AllDsl,

ALL modifier for aggregate functions Read more
Source§

fn aggregate_filter<P>(self, f: P) -> Self::Output
where P: AsExpression<Bool>, Self: FilterDsl<<P as AsExpression<Bool>>::Expression>,

Add an aggregate function filter Read more
Source§

fn aggregate_order<O>(self, o: O) -> Self::Output
where Self: OrderAggregateDsl<O>,

Add an aggregate function order Read more
Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> AutumnCounterCaches for T
where T: 'static,

Source§

const HAS_COUNTER_CACHES: bool = false

Whether this model has any counter cache at all. Read more
Source§

fn counter_caches() -> &'static [CounterCacheSpec<Self>]

The model’s counter-cache specs, in declaration order.
Source§

impl<T> AutumnDependents for T
where T: ?Sized,

Source§

fn dependents() -> &'static [RuntimeDependentSpec]

The model’s dependent-cascade specs, in declaration order. Defaults to none; #[model] overrides via an inherent shadow when dependents exist.
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<ST, DT> CastableFrom<ST, Initialized, Initialized> for DT
where ST: ?Sized, DT: ?Sized,

Source§

impl<ST, DT> CastableFrom<ST, Uninit, Uninit> for DT
where ST: ?Sized, DT: ?Sized,

Source§

impl<T> CloneToUninit for T
where T: Clone,

Source§

unsafe fn clone_to_uninit(&self, dest: *mut u8)

🔬This is a nightly-only experimental API. (clone_to_uninit)
Performs copy-assignment from self to dest. Read more
Source§

impl<T> Downcast for T
where T: Any,

Source§

fn into_any(self: Box<T>) -> Box<dyn Any>

Converts Box<dyn Trait> (where Trait: Downcast) to Box<dyn Any>, which can then be downcast into Box<dyn ConcreteType> where ConcreteType implements Trait.
Source§

fn into_any_rc(self: Rc<T>) -> Rc<dyn Any>

Converts Rc<Trait> (where Trait: Downcast) to Rc<Any>, which can then be further downcast into Rc<ConcreteType> where ConcreteType implements Trait.
Source§

fn as_any(&self) -> &(dyn Any + 'static)

Converts &Trait (where Trait: Downcast) to &Any. This is needed since Rust cannot generate &Any’s vtable from &Trait’s.
Source§

fn as_any_mut(&mut self) -> &mut (dyn Any + 'static)

Converts &mut Trait (where Trait: Downcast) to &Any. This is needed since Rust cannot generate &mut Any’s vtable from &mut Trait’s.
Source§

impl<T> DowncastSend for T
where T: Any + Send,

Source§

fn into_any_send(self: Box<T>) -> Box<dyn Any + Send>

Converts Box<Trait> (where Trait: DowncastSend) to Box<dyn Any + Send>, which can then be downcast into Box<ConcreteType> where ConcreteType implements Trait.
Source§

impl<T> DowncastSync for T
where T: Any + Send + Sync,

Source§

fn into_any_sync(self: Box<T>) -> Box<dyn Any + Sync + Send>

Converts Box<Trait> (where Trait: DowncastSync) to Box<dyn Any + Send + Sync>, which can then be downcast into Box<ConcreteType> where ConcreteType implements Trait.
Source§

fn into_any_arc(self: Arc<T>) -> Arc<dyn Any + Sync + Send> ⓘ

Converts Arc<Trait> (where Trait: DowncastSync) to Arc<Any>, which can then be downcast into Arc<ConcreteType> where ConcreteType implements Trait.
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T> FromRef<T> for T
where T: Clone,

Source§

fn from_ref(input: &T) -> T

Converts to this type from a reference to the input type.
Source§

impl<S, T> FromRequest<S, ViaParts> for T
where S: Send + Sync, T: FromRequestParts<S>,

Source§

type Rejection = <T as FromRequestParts<S>>::Rejection

If the extractor fails it’ll use this “rejection” type. A rejection is a kind of error that can be converted into a response.
Source§

fn from_request( req: Request<Body>, state: &S, ) -> impl Future<Output = Result<T, <T as FromRequest<S, ViaParts>>::Rejection>>

Perform the extraction.
Source§

impl<T> Instrument for T

Source§

fn instrument(self, span: Span) -> Instrumented<Self> ⓘ

Instruments this type with the provided Span, returning an Instrumented wrapper. Read more
Source§

fn in_current_span(self) -> Instrumented<Self> ⓘ

Instruments this type with the current Span, returning an Instrumented wrapper. Read more
Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> IntoSql for T

Source§

fn into_sql<T>(self) -> Self::Expression

Convert self to an expression for Diesel’s query builder. Read more
Source§

fn as_sql<'a, T>(&'a self) -> <&'a Self as AsExpression<T>>::Expression
where &'a Self: AsExpression<T>, T: SqlType + TypedExpressionType,

Convert &self to an expression for Diesel’s query builder. Read more
Source§

impl<T> Pointable for T

Source§

const ALIGN: usize

The alignment of pointer.
Source§

type Init = T

The type for initializers.
Source§

unsafe fn init(init: <T as Pointable>::Init) -> usize

Initializes a with the given initializer. Read more
Source§

unsafe fn deref<'a>(ptr: usize) -> &'a T

Dereferences the given pointer. Read more
Source§

unsafe fn deref_mut<'a>(ptr: usize) -> &'a mut T

Mutably dereferences the given pointer. Read more
Source§

unsafe fn drop(ptr: usize)

Drops the object pointed to by the given pointer. Read more
Source§

impl<T> PolicyExt for T
where T: ?Sized,

Source§

fn and<P, B, E>(self, other: P) -> And<T, P>
where T: Sized + Policy<B, E>, P: Policy<B, E>,

Create a new Policy that returns Action::Follow only if self and other return Action::Follow. Read more
Source§

fn or<P, B, E>(self, other: P) -> Or<T, P>
where T: Sized + Policy<B, E>, P: Policy<B, E>,

Create a new Policy that returns Action::Follow if either self or other returns Action::Follow. Read more
Source§

impl<T> Read<Exclusive, BecauseExclusive> for T
where T: ?Sized,

Source§

impl<T> RepositoryHooksClone for T
where T: Clone,

Source§

fn autumn_clone(&self) -> T

Clone hook state for generated repository values.
Source§

impl<T, Conn> RunQueryDsl<Conn> for T

Source§

fn execute<'conn, 'query>( self, conn: &'conn mut Conn, ) -> <Conn as AsyncConnectionCore>::ExecuteFuture<'conn, 'query>
where Conn: AsyncConnectionCore + Send, Self: ExecuteDsl<Conn> + 'query,

Executes the given command, returning the number of rows affected. Read more
Source§

fn load<'query, 'conn, U>( self, conn: &'conn mut Conn, ) -> AndThen<Self::LoadFuture<'conn>, TryCollect<Self::Stream<'conn>, Vec<U>>>
where U: Send, Conn: AsyncConnectionCore, Self: LoadQuery<'query, Conn, U> + 'query,

Executes the given query, returning a Vec with the returned rows. Read more
Source§

fn load_stream<'conn, 'query, U>( self, conn: &'conn mut Conn, ) -> Self::LoadFuture<'conn>
where Conn: AsyncConnectionCore, U: 'conn, Self: LoadQuery<'query, Conn, U> + 'query,

Executes the given query, returning a [Stream] with the returned rows. Read more
Source§

fn get_result<'query, 'conn, U>( self, conn: &'conn mut Conn, ) -> AndThen<Self::LoadFuture<'conn>, LoadNext<Pin<Box<Self::Stream<'conn>>>>>
where U: Send + 'conn, Conn: AsyncConnectionCore, Self: LoadQuery<'query, Conn, U> + 'query,

Runs the command, and returns the affected row. Read more
Source§

fn get_results<'query, 'conn, U>( self, conn: &'conn mut Conn, ) -> AndThen<Self::LoadFuture<'conn>, TryCollect<Self::Stream<'conn>, Vec<U>>>
where U: Send, Conn: AsyncConnectionCore, Self: LoadQuery<'query, Conn, U> + 'query,

Runs the command, returning an Vec with the affected rows. Read more
Source§

fn first<'query, 'conn, U>( self, conn: &'conn mut Conn, ) -> AndThen<<Self::Output as LoadQuery<'query, Conn, U>>::LoadFuture<'conn>, LoadNext<Pin<Box<<Self::Output as LoadQuery<'query, Conn, U>>::Stream<'conn>>>>>
where U: Send + 'conn, Conn: AsyncConnectionCore, Self: LimitDsl, Self::Output: LoadQuery<'query, Conn, U> + Send + 'query,

Attempts to load a single record. Read more
Source§

impl<T> Same for T

Source§

type Output = T

Should always be Self
Source§

impl<T> Scoped for T
where T: Send + Sync + 'static,

Source§

fn scope(ctx: &PolicyContext) -> ScopeQuery<'_, Self>

Open a deferred ScopeQuery for this type. Resolves the registered scope at .load() time, not here.
Source§

impl<T> TaskExtractor for T

Source§

fn from_task_parts<'a>( parts: &'a mut Parts, state: &'a AppState, ) -> Pin<Box<dyn Future<Output = Result<T, AutumnError>> + Send + 'a>>

Resolve an argument from task request parts and app state.
Source§

impl<T> ToOwned for T
where T: Clone,

Source§

type Owned = T

The resulting type after obtaining ownership.
Source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
Source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = !

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, !>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
Source§

impl<V, T> VZip<V> for T
where V: MultiLane<T>,

Source§

fn vzip(self) -> V

Source§

impl<T> WindowExpressionMethods for T

Source§

fn over(self) -> Self::Output
where Self: OverDsl,

Turn a function call into a window function call Read more
Source§

fn window_filter<P>(self, f: P) -> Self::Output
where P: AsExpression<Bool>, Self: FilterDsl<<P as AsExpression<Bool>>::Expression>,

Add a filter to the current window function Read more
Source§

fn partition_by<E>(self, expr: E) -> Self::Output
where Self: PartitionByDsl<E>,

Add a partition clause to the current window function Read more
Source§

fn window_order<E>(self, expr: E) -> Self::Output
where Self: OrderWindowDsl<E>,

Add a order clause to the current window function Read more
Source§

fn frame_by<E>(self, expr: E) -> Self::Output
where Self: FrameDsl<E>,

Add a frame clause to the current window function Read more
Source§

impl<T> WithSubscriber for T

Source§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self> ⓘ
where S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a WithDispatch wrapper. Read more
Source§

fn with_current_subscriber(self) -> WithDispatch<Self> ⓘ

Attaches the current default Subscriber to this type, returning a WithDispatch wrapper. Read more