pub struct Manager<T> { /* private fields */ }Expand description
Entry point for queries on a model.
Manager<T> wraps a freshly-constructed QuerySet<T> and exposes
the same chainable surface. The user never constructs one directly;
Post::objects() is the only door.
Implementations§
Source§impl<T: Model> Manager<T>
Manager convenience shims so callers can write
Post::objects().load_fixture(...) and dump_fixture(...)
without importing the free functions.
impl<T: Model> Manager<T>
Manager convenience shims so callers can write
Post::objects().load_fixture(...) and dump_fixture(...)
without importing the free functions.
Sourcepub async fn load_fixture<P: AsRef<Path>>(
&self,
path: P,
) -> Result<usize, FixtureError>
pub async fn load_fixture<P: AsRef<Path>>( &self, path: P, ) -> Result<usize, FixtureError>
See load_fixture.
Sourcepub async fn dump_fixture<P: AsRef<Path>>(
&self,
path: P,
) -> Result<usize, FixtureError>
pub async fn dump_fixture<P: AsRef<Path>>( &self, path: P, ) -> Result<usize, FixtureError>
See dump_fixture.
Source§impl<T> Manager<T>
impl<T> Manager<T>
Sourcepub fn atomic(self) -> Self
pub fn atomic(self) -> Self
Wrap every write terminal that hangs off this Manager in a
transaction. Equivalent to calling .atomic() on each
QuerySet derived from it. Per-call .non_atomic() overrides.
Sourcepub fn non_atomic(self) -> Self
pub fn non_atomic(self) -> Self
Opt this Manager (and every QuerySet derived from it) out of
the global App::builder().atomic_transactions(true) default.
Source§impl<T: Model> Manager<T>
Delegating chainable + terminal surface on Manager<T>.
impl<T: Model> Manager<T>
Delegating chainable + terminal surface on Manager<T>.
Lets users write Post::objects().filter(...).fetch().await without
a separate .query() hop. Each method constructs the initial
SelectStatement against T::TABLE with one column per
T::FIELDS entry, wraps it in a fresh QuerySet<T>, and forwards.
Sourcepub fn all(&self) -> QuerySet<T>
pub fn all(&self) -> QuerySet<T>
A bare QuerySet over every row — the Model::objects().all() form.
The entry point when you need a QuerySet terminal without a
filter: a grouped aggregate over the whole table, an unfiltered
aggregate, or just an explicit “all rows” for readability.
Sourcepub async fn aggregate(
&self,
aggs: &[(&str, Aggregate)],
) -> Result<JsonValue, Error>
pub async fn aggregate( &self, aggs: &[(&str, Aggregate)], ) -> Result<JsonValue, Error>
See QuerySet::aggregate — single-row aggregate over every row.
Forwards from the manager so Model::objects().aggregate(...)
works without an intervening .filter(...) / .on(...).
Sourcepub async fn annotate(
&self,
group_cols: &[&str],
aggs: &[(&str, Aggregate)],
) -> Result<Vec<JsonValue>, Error>
pub async fn annotate( &self, group_cols: &[&str], aggs: &[(&str, Aggregate)], ) -> Result<Vec<JsonValue>, Error>
See QuerySet::annotate — grouped aggregate (GROUP BY <group_cols>).
Forwards from the manager so the documented
Model::objects().annotate(&["status"], &[("count", Aggregate::count())])
(a grouped count over "status") compiles
directly, without a filter first.
Sourcepub fn with_deleted(&self) -> QuerySet<T>
pub fn with_deleted(&self) -> QuerySet<T>
Feature #72 — see QuerySet::with_deleted.
Sourcepub fn only_deleted(&self) -> QuerySet<T>
pub fn only_deleted(&self) -> QuerySet<T>
Feature #72 — see QuerySet::only_deleted.
Sourcepub fn only(&self, cols: &[&str]) -> QuerySet<T>
pub fn only(&self, cols: &[&str]) -> QuerySet<T>
Gap #111 — see QuerySet::only.
Sourcepub fn hard_delete(&self) -> QuerySet<T>
pub fn hard_delete(&self) -> QuerySet<T>
Feature #72 — see QuerySet::hard_delete.
Sourcepub fn into_subquery(&self, col_name: &str) -> Subquery
pub fn into_subquery(&self, col_name: &str) -> Subquery
See QuerySet::into_subquery.
Sourcepub fn on(&self, pool: &SqlitePool) -> QuerySet<T>
pub fn on(&self, pool: &SqlitePool) -> QuerySet<T>
See QuerySet::on.
See QuerySet::annotate_related — starts an annotated chain
from the manager, like filter does.
Sourcepub fn annotate_count(&self, relation: &str) -> QuerySet<T>
pub fn annotate_count(&self, relation: &str) -> QuerySet<T>
Sourcepub fn annotate_count_where<C: Model>(
&self,
alias: &str,
relation: &str,
pred: Predicate<C>,
) -> QuerySet<T>
pub fn annotate_count_where<C: Model>( &self, alias: &str, relation: &str, pred: Predicate<C>, ) -> QuerySet<T>
See QuerySet::annotate_count_where — starts a filtered
annotated chain from the manager.
Sourcepub async fn values(&self, columns: &[&str]) -> Result<Vec<JsonValue>, Error>
pub async fn values(&self, columns: &[&str]) -> Result<Vec<JsonValue>, Error>
See QuerySet::values.
Sourcepub async fn get(&self, p: Predicate<T>) -> Result<T, GetError>
pub async fn get(&self, p: Predicate<T>) -> Result<T, GetError>
.get(predicate) — sugar for .filter(predicate).get().
The one-liner: User::objects().get(user::ID.eq(1)).
See QuerySet::get for error-variant semantics.
Sourcepub async fn first_pg(&self, pool: &PgPool) -> Result<Option<T>, Error>
pub async fn first_pg(&self, pool: &PgPool) -> Result<Option<T>, Error>
See QuerySet::first_pg.
Sourcepub async fn get_pg(
&self,
pool: &PgPool,
p: Predicate<T>,
) -> Result<T, GetError>
pub async fn get_pg( &self, pool: &PgPool, p: Predicate<T>, ) -> Result<T, GetError>
Postgres-only sugar for .filter(predicate).get_pg(pool).
Sourcepub async fn create(&self, instance: T) -> Result<T, WriteError>
pub async fn create(&self, instance: T) -> Result<T, WriteError>
INSERT one row, return the row as it now exists in the
database (with any autoincrement PK populated). Uses the
ambient pool via Manager::queryset().resolve_pool.
Sourcepub async fn bulk_create(&self, instances: Vec<T>) -> Result<u64, WriteError>where
T: Serialize,
pub async fn bulk_create(&self, instances: Vec<T>) -> Result<u64, WriteError>where
T: Serialize,
INSERT many rows in a single statement. Returns the number of
rows inserted. The full populated rows aren’t materialised —
use a follow-up Model::objects().filter(...).fetch() if you
need them.
Empty input is a no-op (returns Ok(0)) — the alternative
(building an INSERT INTO t () VALUES () and failing at the
DB) doesn’t help anyone.
Fires bulk_post_save:<table> once with { ids, created: true, actor } when at least one row was inserted. Per-row
pre_save / post_save are NOT fired — use Self::save
when per-row signal semantics are required.
Sourcepub async fn get_or_create(
&self,
predicate: Predicate<T>,
defaults: T,
) -> Result<(T, bool), WriteError>
pub async fn get_or_create( &self, predicate: Predicate<T>, defaults: T, ) -> Result<(T, bool), WriteError>
The get_or_create terminal: fetch the first row matching predicate;
if none exists, insert defaults and return it. Returns
(row, created) so the caller can branch on whether the write
happened. Two queries on the miss path (filter+first then create),
one query on the hit path.
§Concurrency
Convergent under concurrent callers: if two callers both miss the
SELECT and race to INSERT, the one that loses gets a
UniqueViolation; that error is caught here and the existing row
is re-fetched, so both callers return the same row with
created = false for the loser. A UNIQUE constraint on the
predicate columns is required for true at-most-one semantics — the
constraint is what makes the convergence deterministic.
Sourcepub async fn update_or_create(
&self,
predicate: Predicate<T>,
defaults: T,
) -> Result<(T, bool), WriteError>
pub async fn update_or_create( &self, predicate: Predicate<T>, defaults: T, ) -> Result<(T, bool), WriteError>
The update_or_create terminal: fetch the first row matching
predicate; if found, update its non-PK columns with the
defaults instance’s values and return the fresh row;
otherwise insert defaults and return it. Returns
(row, created) so the caller can branch on the path taken.
The defaults’ PK is intentionally ignored on the update path —
the matched row keeps its original PK. On the insert path the
defaults’ PK is honoured (autoincrement sentinel 0 → DB
assigns; explicit value → DB uses it).
§Concurrency
Convergent under concurrent callers: if two callers both miss the
SELECT and race to INSERT, the loser gets a UniqueViolation; that
error is caught here and the existing row is re-fetched, then the
update is applied to it. Both callers converge on the same row, with
created = false for the loser. A UNIQUE constraint on the predicate
columns is required for deterministic convergence.
Implementation: 2 queries on the hit path (first + UPDATE + re-fetch),
2 queries on the miss+create path (first + create), or
4 queries on the miss+race path (first + failed-INSERT + first
- UPDATE + re-fetch).
Sourcepub async fn upsert(&self, instance: T) -> Result<T, WriteError>
pub async fn upsert(&self, instance: T) -> Result<T, WriteError>
INSERT-or-UPDATE keyed on the primary key. The row’s PK column is the conflict target; on a hit, every non-PK column is overwritten with the supplied value. Returns the row as the DB stored it (post-upsert).
Both backends use INSERT ... ON CONFLICT(<pk>) DO UPDATE SET col = excluded.col, .... The SQLite and Postgres syntax happens
to match exactly here so a single sea-query OnConflict builder
covers both.
Sourcepub async fn create_pg(
&self,
instance: T,
pool: &PgPool,
) -> Result<T, WriteError>
pub async fn create_pg( &self, instance: T, pool: &PgPool, ) -> Result<T, WriteError>
create against an explicit Postgres pool. The Postgres
counterpart of Self::create for models with Postgres-only
field types (Array, Inet, MacAddr, FullText), whose FromRow
impl exists only for PgRow.
Sourcepub async fn bulk_update(&self, instances: Vec<T>) -> Result<u64, WriteError>where
T: Serialize,
pub async fn bulk_update(&self, instances: Vec<T>) -> Result<u64, WriteError>where
T: Serialize,
Apply per-row differing values to a list of instances in one
statement. Each instance carries its own PK and its own
column values; the generated SQL uses one CASE pk WHEN ... THEN ... END per non-PK column, plus a WHERE pk IN (...)
to scope the update.
A bulk_update(objs, fields) that
updates every non-PK column rather than asking the caller to
list them. Returns the number of rows affected.
Empty input is a no-op (returns 0). The pattern works on both
SQLite and Postgres — the CASE expression is SQL-standard.
Limitations:
- All instances must have a non-default PK (the caller has already loaded the rows). Default-PK instances are skipped.
- Bulk-write signals are NOT fired by this path — it’s the
Manager::bulk_createanalogue for UPDATE, deliberately silent for speed.
Sourcepub async fn raw(&self, sql: &str) -> Result<Vec<T>, Error>
pub async fn raw(&self, sql: &str) -> Result<Vec<T>, Error>
Run a hand-written SQL query and return typed Vec<T> rows.
The escape hatch for queries the QuerySet builder can’t (or
shouldn’t) model — CTEs, vendor-specific functions, ad-hoc
reporting. Delegates to sqlx::query_as against the ambient
pool and dispatches on backend, so user code stays portable.
The string is sent verbatim; no parameter binding (use
Predicate / the typed query path for parameterised
queries). Inject input only after manual sanitisation.
Skips the select_related / prefetch_related chain — those
only apply to the typed QuerySet build path.
Sourcepub async fn bulk_create_pg(
&self,
instances: Vec<T>,
pool: &PgPool,
) -> Result<u64, WriteError>where
T: Serialize,
pub async fn bulk_create_pg(
&self,
instances: Vec<T>,
pool: &PgPool,
) -> Result<u64, WriteError>where
T: Serialize,
bulk_create against an explicit Postgres pool.
Source§impl<T: Model> Manager<T>
impl<T: Model> Manager<T>
Sourcepub fn on_tx<'a>(&self, tx: &'a mut Transaction) -> QuerySetTx<'a, T>
pub fn on_tx<'a>(&self, tx: &'a mut Transaction) -> QuerySetTx<'a, T>
Begin a new query on this manager attached to the given open transaction.
Sugar for T::objects().on_tx(tx) — lets callers skip the intermediate
QuerySet construction when they want to go straight to a terminal:
umbral::db::transaction(|tx| async move {
let post = Post::objects().on_tx(tx).create(new_post).await?;
Ok::<_, MyError>(post)
}).await?;Sourcepub async fn create_in_tx(
&self,
instance: T,
tx: &mut Transaction,
) -> Result<T, WriteError>
pub async fn create_in_tx( &self, instance: T, tx: &mut Transaction, ) -> Result<T, WriteError>
INSERT one row inside tx and return the populated row.
This is the primary Manager-level entry point for transactional writes.
Equivalent to Post::objects().on_tx(tx).create(instance) but more
ergonomic when you only need the one INSERT (no filter chain needed).
umbral::db::transaction(|tx| async move {
let post = Post::objects().create_in_tx(new_post, tx).await?;
Ok::<_, MyError>(post)
}).await?;Sourcepub async fn bulk_create_in_tx(
&self,
instances: Vec<T>,
tx: &mut Transaction,
) -> Result<u64, WriteError>where
T: Serialize,
pub async fn bulk_create_in_tx(
&self,
instances: Vec<T>,
tx: &mut Transaction,
) -> Result<u64, WriteError>where
T: Serialize,
INSERT many rows inside tx.
Returns the number of rows inserted. Empty input is a no-op.
Sourcepub async fn save(&self, instance: T) -> Result<T, SaveError>
pub async fn save(&self, instance: T) -> Result<T, SaveError>
Save one instance, firing pre_save + post_save signals.
Determines INSERT vs UPDATE by checking whether the primary key
is the autoincrement sentinel (0 for integers, nil UUID, empty
string). If it is, an INSERT is performed (created = true);
otherwise an UPDATE ... WHERE pk = <value> is run (created = false).
Returns the row as it exists in the database after the write (populated PK for inserts, same row for updates).
§Signal contract
pre_save:<table>fires before the database write with{ "instance": ..., "created": bool, "actor": ... }.post_save:<table>fires after the database write with the DB-read-back row and the same envelope keys.
The "actor" value is set by the nearest enclosing
crate::signals::with_actor scope; Value::Null when no
scope is active.
§Bulk paths fire bulk signals, not per-row signals
Manager::create, Manager::bulk_create, and
QuerySet::update_values / QuerySet::delete do NOT fire
per-row post_save / post_delete. They fire
bulk_post_save:<table> / bulk_post_delete:<table> once per
statement with the affected PKs in the payload. Use save /
delete_instance when per-row signal semantics are needed.
Sourcepub async fn delete_instance(&self, instance: &T) -> Result<u64, SaveError>where
T: Serialize,
pub async fn delete_instance(&self, instance: &T) -> Result<u64, SaveError>where
T: Serialize,
Delete one instance by primary key, firing pre_delete +
post_delete signals.
Issues DELETE FROM <table> WHERE <pk> = <value>. Returns the
number of rows affected (0 if the row was already gone, 1 otherwise).
§Signal contract
pre_delete:<table>fires before the DELETE with{ "instance": ..., "actor": ... }.post_delete:<table>fires after the DELETE with the same payload shape.
The "actor" value is set by the nearest enclosing
crate::signals::with_actor scope; Value::Null when no
scope is active. The instance value passed to both signals is
the value supplied by the caller — not a DB read-back. If you
need the freshest DB state before deletion, fetch it first with
.get(...) then pass to this method.
§Bulk paths fire bulk signals
QuerySet::delete() (the filter-chain DELETE) fires
bulk_post_delete:<table> with the list of affected PKs, not
per-row pre_delete / post_delete. Use delete_instance for
per-row signal semantics.
Trait Implementations§
Auto Trait Implementations§
impl<T> Freeze for Manager<T>
impl<T> RefUnwindSafe for Manager<T>where
T: RefUnwindSafe,
impl<T> Send for Manager<T>where
T: Send,
impl<T> Sync for Manager<T>where
T: Sync,
impl<T> Unpin for Manager<T>where
T: Unpin,
impl<T> UnsafeUnpin for Manager<T>
impl<T> UnwindSafe for Manager<T>where
T: UnwindSafe,
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
impl<ST, DT> CastableFrom<ST, Initialized, Initialized> for DT
impl<ST, DT> CastableFrom<ST, Uninit, Uninit> for DT
impl<A, B, T> HttpServerConnExec<A, B> for Twhere
B: Body,
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>
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>
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 moreSource§impl<T> Paint for Twhere
T: ?Sized,
impl<T> Paint for Twhere
T: ?Sized,
Source§fn fg(&self, value: Color) -> Painted<&T>
fn fg(&self, value: Color) -> Painted<&T>
Returns a styled value derived from self with the foreground set to
value.
This method should be used rarely. Instead, prefer to use color-specific
builder methods like red() and
green(), which have the same functionality but are
pithier.
§Example
Set foreground color to white using fg():
use yansi::{Paint, Color};
painted.fg(Color::White);Set foreground color to white using white().
use yansi::Paint;
painted.white();Source§fn bright_black(&self) -> Painted<&T>
fn bright_black(&self) -> Painted<&T>
Source§fn bright_red(&self) -> Painted<&T>
fn bright_red(&self) -> Painted<&T>
Source§fn bright_green(&self) -> Painted<&T>
fn bright_green(&self) -> Painted<&T>
Source§fn bright_yellow(&self) -> Painted<&T>
fn bright_yellow(&self) -> Painted<&T>
Source§fn bright_blue(&self) -> Painted<&T>
fn bright_blue(&self) -> Painted<&T>
Source§fn bright_magenta(&self) -> Painted<&T>
fn bright_magenta(&self) -> Painted<&T>
Source§fn bright_cyan(&self) -> Painted<&T>
fn bright_cyan(&self) -> Painted<&T>
Source§fn bright_white(&self) -> Painted<&T>
fn bright_white(&self) -> Painted<&T>
Source§fn bg(&self, value: Color) -> Painted<&T>
fn bg(&self, value: Color) -> Painted<&T>
Returns a styled value derived from self with the background set to
value.
This method should be used rarely. Instead, prefer to use color-specific
builder methods like on_red() and
on_green(), which have the same functionality but
are pithier.
§Example
Set background color to red using fg():
use yansi::{Paint, Color};
painted.bg(Color::Red);Set background color to red using on_red().
use yansi::Paint;
painted.on_red();Source§fn on_primary(&self) -> Painted<&T>
fn on_primary(&self) -> Painted<&T>
Source§fn on_magenta(&self) -> Painted<&T>
fn on_magenta(&self) -> Painted<&T>
Source§fn on_bright_black(&self) -> Painted<&T>
fn on_bright_black(&self) -> Painted<&T>
Source§fn on_bright_red(&self) -> Painted<&T>
fn on_bright_red(&self) -> Painted<&T>
Source§fn on_bright_green(&self) -> Painted<&T>
fn on_bright_green(&self) -> Painted<&T>
Source§fn on_bright_yellow(&self) -> Painted<&T>
fn on_bright_yellow(&self) -> Painted<&T>
Source§fn on_bright_blue(&self) -> Painted<&T>
fn on_bright_blue(&self) -> Painted<&T>
Source§fn on_bright_magenta(&self) -> Painted<&T>
fn on_bright_magenta(&self) -> Painted<&T>
Source§fn on_bright_cyan(&self) -> Painted<&T>
fn on_bright_cyan(&self) -> Painted<&T>
Source§fn on_bright_white(&self) -> Painted<&T>
fn on_bright_white(&self) -> Painted<&T>
Source§fn attr(&self, value: Attribute) -> Painted<&T>
fn attr(&self, value: Attribute) -> Painted<&T>
Enables the styling Attribute value.
This method should be used rarely. Instead, prefer to use
attribute-specific builder methods like bold() and
underline(), which have the same functionality
but are pithier.
§Example
Make text bold using attr():
use yansi::{Paint, Attribute};
painted.attr(Attribute::Bold);Make text bold using using bold().
use yansi::Paint;
painted.bold();Source§fn rapid_blink(&self) -> Painted<&T>
fn rapid_blink(&self) -> Painted<&T>
Source§fn quirk(&self, value: Quirk) -> Painted<&T>
fn quirk(&self, value: Quirk) -> Painted<&T>
Enables the yansi Quirk value.
This method should be used rarely. Instead, prefer to use quirk-specific
builder methods like mask() and
wrap(), which have the same functionality but are
pithier.
§Example
Enable wrapping using .quirk():
use yansi::{Paint, Quirk};
painted.quirk(Quirk::Wrap);Enable wrapping using wrap().
use yansi::Paint;
painted.wrap();Source§fn clear(&self) -> Painted<&T>
👎Deprecated since 1.0.1: renamed to resetting() due to conflicts with Vec::clear().
The clear() method will be removed in a future release.
fn clear(&self) -> Painted<&T>
renamed to resetting() due to conflicts with Vec::clear().
The clear() method will be removed in a future release.
Source§fn whenever(&self, value: Condition) -> Painted<&T>
fn whenever(&self, value: Condition) -> Painted<&T>
Conditionally enable styling based on whether the Condition value
applies. Replaces any previous condition.
See the crate level docs for more details.
§Example
Enable styling painted only when both stdout and stderr are TTYs:
use yansi::{Paint, Condition};
painted.red().on_yellow().whenever(Condition::STDOUTERR_ARE_TTY);