pub struct ChangeExecutor;Expand description
Executes INSERT/UPDATE/DELETE for tracked entities within a transaction.
Implementations§
Source§impl ChangeExecutor
impl ChangeExecutor
Sourcepub async fn execute_inserts<E, F>(
conn: &mut dyn IAsyncConnection,
provider: &dyn IDatabaseProvider,
entities: &[(&E, &EntityTypeMeta)],
on_key_backfill: F,
) -> EFResult<usize>
pub async fn execute_inserts<E, F>( conn: &mut dyn IAsyncConnection, provider: &dyn IDatabaseProvider, entities: &[(&E, &EntityTypeMeta)], on_key_backfill: F, ) -> EFResult<usize>
Executes INSERT statements for all added entities.
Rows are batched into multi-value INSERT INTO ... VALUES (...), (...)
statements to minimize round trips. Batches are sized so that the total
parameter count stays ≤ 900 (SQLite’s variable limit is 999; we use a
conservative ceiling that also fits MySQL/PG). Auto-increment columns
are excluded from the column list (the DB assigns them).
on_key_backfill is invoked once per inserted row with the
database-generated auto-increment PK (when present). For PostgreSQL the
PKs are read from the RETURNING * result set; for SQLite/MySQL a
follow-up last_insert_rowid() / LAST_INSERT_ID() query retrieves
the first/last ID and the remaining batch keys are computed by
sequential increment.
Sourcepub async fn execute_upserts<E>(
conn: &mut dyn IAsyncConnection,
provider: &dyn IDatabaseProvider,
entities: &[(&E, &EntityTypeMeta)],
) -> EFResult<usize>
pub async fn execute_upserts<E>( conn: &mut dyn IAsyncConnection, provider: &dyn IDatabaseProvider, entities: &[(&E, &EntityTypeMeta)], ) -> EFResult<usize>
Executes UPSERT statements (INSERT … ON CONFLICT DO UPDATE) for
entities marked via DbSet::upsert.
Unlike execute_inserts, ALL mapped columns (including auto-increment
PKs) are included in the INSERT column list so the caller-provided PK
value participates in the conflict check. The conflict target is the PK
column(s). The UPDATE SET clause covers all non-PK columns.
No PK backfill is performed — upsert callers are expected to know the key.
Source§impl ChangeExecutor
impl ChangeExecutor
Sourcepub async fn execute_updates<E>(
conn: &mut dyn IAsyncConnection,
provider: &dyn IDatabaseProvider,
entities: &[(&E, &EntityTypeMeta, Option<&HashMap<String, DbValue>>, &[String])],
query_filter: Option<&BoolExpr>,
) -> EFResult<usize>
pub async fn execute_updates<E>( conn: &mut dyn IAsyncConnection, provider: &dyn IDatabaseProvider, entities: &[(&E, &EntityTypeMeta, Option<&HashMap<String, DbValue>>, &[String])], query_filter: Option<&BoolExpr>, ) -> EFResult<usize>
Executes UPDATE statements for all modified entities.
When no concurrency tokens are present and the entity has a single-column
primary key, rows are batched into a single UPDATE ... SET col = CASE pk WHEN ? THEN ? ... END WHERE pk IN (...) statement (≤900 params per
batch) to minimize round trips. Otherwise (concurrency tokens, composite
PK), falls back to per-row UPDATE so optimistic-concurrency checks run
on each row.
When modified_properties is populated (via detect_changes), only the
dirty columns are SET. When empty (entity marked Modified via update()
without detection), all non-PK columns are SET (backward compatible).
When query_filter is Some, the filter is AND-ed into the WHERE
clause so updates cannot cross the filter boundary (multi-tenant /
soft-delete isolation).
Sourcepub async fn execute_deletes<E>(
conn: &mut dyn IAsyncConnection,
provider: &dyn IDatabaseProvider,
entities: &[(&E, &EntityTypeMeta, Option<&HashMap<String, DbValue>>)],
query_filter: Option<&BoolExpr>,
) -> EFResult<usize>where
E: IEntityType + IGetKeyValues,
pub async fn execute_deletes<E>(
conn: &mut dyn IAsyncConnection,
provider: &dyn IDatabaseProvider,
entities: &[(&E, &EntityTypeMeta, Option<&HashMap<String, DbValue>>)],
query_filter: Option<&BoolExpr>,
) -> EFResult<usize>where
E: IEntityType + IGetKeyValues,
Executes DELETE statements for all deleted entities.
When no concurrency tokens are present and the entity has a single-column
primary key, rows are batched into DELETE ... WHERE pk IN (?, ?, ...)
statements (≤900 params per batch) to minimize round trips. Otherwise
(concurrency tokens, composite PK), falls back to per-row DELETE so
optimistic-concurrency checks run on each row.
When query_filter is Some, the filter is AND-ed into the WHERE
clause so deletes cannot cross the filter boundary.