pub trait UpdatableRepository<M: Model>: Repository<M> {
// Required method
fn update_query(model: &M) -> Query<'_>;
// Provided methods
fn update_with_executor<'c, 'life0, 'async_trait, E>(
&'life0 self,
tx: E,
model: M,
) -> Pin<Box<dyn Future<Output = Result<M>> + Send + 'async_trait>>
where M: 'async_trait,
E: Executor<'c, Database = Database> + Send + 'async_trait,
Self: Sync + 'async_trait,
'c: 'async_trait,
'life0: 'async_trait { ... }
fn update_ref_with_executor<'c, 'life0, 'life1, 'async_trait, E>(
&'life0 self,
tx: E,
model: &'life1 M,
) -> Pin<Box<dyn Future<Output = Result<()>> + Send + 'async_trait>>
where M: 'async_trait,
E: Executor<'c, Database = Database> + Send + 'async_trait,
Self: Sync + 'async_trait,
'c: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait { ... }
fn update<'life0, 'async_trait>(
&'life0 self,
model: M,
) -> Pin<Box<dyn Future<Output = Result<M>> + Send + 'async_trait>>
where M: 'async_trait,
Self: Sync + 'async_trait,
'life0: 'async_trait { ... }
fn update_ref<'life0, 'life1, 'async_trait>(
&'life0 self,
model: &'life1 M,
) -> Pin<Box<dyn Future<Output = Result<()>> + Send + 'async_trait>>
where M: 'async_trait,
Self: Sync + 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait { ... }
fn update_many<'life0, 'async_trait, I>(
&'life0 self,
models: I,
) -> Pin<Box<dyn Future<Output = Result<()>> + Send + 'async_trait>>
where I: IntoIterator<Item = M> + Send + 'async_trait,
I::IntoIter: Send,
Self: Sync + 'async_trait,
'life0: 'async_trait { ... }
fn update_batch<'life0, 'async_trait, const N: usize, I>(
&'life0 self,
models: I,
) -> Pin<Box<dyn Future<Output = Result<()>> + Send + 'async_trait>>
where I: IntoIterator<Item = M> + Send + 'async_trait,
I::IntoIter: Send,
Self: Sync + 'async_trait,
'life0: 'async_trait { ... }
}
Expand description
Trait for repositories that can update existing records in the database.
The UpdatableRepository
trait extends the base Repository
trait with methods
for updating existing records. It provides standardized ways to update both individual
models and batches of models, optimizing database interactions while maintaining data
integrity.
§Type Parameters
M
- The model type that this repository updates. Must implement theModel
trait.
§Examples
Basic implementation:
impl UpdatableRepository<User> for UserRepository {
fn update_query(user: &User) -> Query<'_> {
sqlx::query("UPDATE users SET name = $1 WHERE id = $2")
.bind(&user.name)
.bind(user.id)
}
}
// Usage
// Update a single user
repo.update_ref(user).await?;
// Update multiple users
let users = vec![
User { id: 1, name: String::from("Updated Alice") },
User { id: 2, name: String::from("Updated Bob") }
];
repo.update_many(users).await?;
Using the macro for simpler implementation:
repository! {
UserRepository<User>;
// if you need to override any method other than `Repository::pool` they will go here
}
repository_update! {
UserRepository<User>;
update_query(user) {
sqlx::query("UPDATE users SET name = $1 WHERE id = $2")
.bind(&user.name)
.bind(user.id)
}
}
§Implementation Notes
- Required method:
update_query
- Defines how a model is translated into an UPDATE statement - Provided methods:
update_with_executor
- updates a single model using anyExecutor
update
- Updates a single modelupdate_many
- Updates multiple models using the default batch sizeupdate_batch
- Updates multiple models with a custom batch size
- All batch operations use transactions to ensure data consistency
- All methods assume the model has a valid ID (typically checked by the
Model::get_id
method) - Performance is optimized through batching and connection pooling
Required Methods§
Sourcefn update_query(model: &M) -> Query<'_>
fn update_query(model: &M) -> Query<'_>
Creates a SQL query to update an existing model in the database.
This method constructs an UPDATE statement that will modify an existing database record to match the current state of the model. It should use the model’s ID to identify the record to update and include all relevant fields in the SET clause.
§Parameters
model
- A reference to the model instance containing updated values
§Returns
Query
- A prepared SQL UPDATE query
§Implementation Notes
The query should:
- Include a WHERE clause matching the model’s ID
- Only update columns that can be modified
- Preserve any timestamp or audit fields as required
Provided Methods§
Sourcefn update_with_executor<'c, 'life0, 'async_trait, E>(
&'life0 self,
tx: E,
model: M,
) -> Pin<Box<dyn Future<Output = Result<M>> + Send + 'async_trait>>
fn update_with_executor<'c, 'life0, 'async_trait, E>( &'life0 self, tx: E, model: M, ) -> Pin<Box<dyn Future<Output = Result<M>> + Send + 'async_trait>>
Executes an update operation for a single model instance.
This method takes the query generated by update_query
and executes it against the Executor
tx
.
It’s a higher-level wrapper that handles the actual database interaction, providing a simpler
interface for updating records.
§Parameters
tx
- The executor to use for the querymodel
- A reference to the model instance to update
§Returns
crate::Result<()>
- Success if the update was executed, or an error if the operation failed
§Implementation Details
The method:
- Gets the update query from
update_query
- Executes it using the connection pool
- Handles any potential database errors
Sourcefn update_ref_with_executor<'c, 'life0, 'life1, 'async_trait, E>(
&'life0 self,
tx: E,
model: &'life1 M,
) -> Pin<Box<dyn Future<Output = Result<()>> + Send + 'async_trait>>
fn update_ref_with_executor<'c, 'life0, 'life1, 'async_trait, E>( &'life0 self, tx: E, model: &'life1 M, ) -> Pin<Box<dyn Future<Output = Result<()>> + Send + 'async_trait>>
Executes an update operation for a single model instance.
This method takes the query generated by update_query
and executes it against the Executor
tx
.
It’s a higher-level wrapper that handles the actual database interaction, providing a simpler
interface for updating records.
§Parameters
tx
- The executor to use for the querymodel
- A reference to the model instance to update
§Returns
crate::Result<()>
- Success if the update was executed, or an error if the operation failed
§Implementation Details
The method:
- Gets the update query from
update_query
- Executes it using the connection pool
- Handles any potential database errors
Sourcefn update<'life0, 'async_trait>(
&'life0 self,
model: M,
) -> Pin<Box<dyn Future<Output = Result<M>> + Send + 'async_trait>>where
M: 'async_trait,
Self: Sync + 'async_trait,
'life0: 'async_trait,
fn update<'life0, 'async_trait>(
&'life0 self,
model: M,
) -> Pin<Box<dyn Future<Output = Result<M>> + Send + 'async_trait>>where
M: 'async_trait,
Self: Sync + 'async_trait,
'life0: 'async_trait,
Executes an update operation for a single model instance.
This method takes the query generated by update_query
and executes it against the database.
It’s a higher-level wrapper that handles the actual database interaction, providing a simpler
interface for updating records.
§Parameters
model
- A reference to the model instance to update
§Returns
crate::Result<()>
- Success if the update was executed, or an error if the operation failed
§Implementation Details
The method:
- Gets the update query from
update_query
- Executes it using the connection pool
- Handles any potential database errors
Sourcefn update_ref<'life0, 'life1, 'async_trait>(
&'life0 self,
model: &'life1 M,
) -> Pin<Box<dyn Future<Output = Result<()>> + Send + 'async_trait>>where
M: 'async_trait,
Self: Sync + 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
fn update_ref<'life0, 'life1, 'async_trait>(
&'life0 self,
model: &'life1 M,
) -> Pin<Box<dyn Future<Output = Result<()>> + Send + 'async_trait>>where
M: 'async_trait,
Self: Sync + 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
Executes an update operation for a single model instance.
This method takes the query generated by update_query
and executes it against the database.
It’s a higher-level wrapper that handles the actual database interaction, providing a simpler
interface for updating records.
§Parameters
model
- A reference to the model instance to update
§Returns
crate::Result<()>
- Success if the update was executed, or an error if the operation failed
§Implementation Details
The method:
- Gets the update query from
update_query
- Executes it using the connection pool
- Handles any potential database errors
Sourcefn update_many<'life0, 'async_trait, I>(
&'life0 self,
models: I,
) -> Pin<Box<dyn Future<Output = Result<()>> + Send + 'async_trait>>where
I: IntoIterator<Item = M> + Send + 'async_trait,
I::IntoIter: Send,
Self: Sync + 'async_trait,
'life0: 'async_trait,
fn update_many<'life0, 'async_trait, I>(
&'life0 self,
models: I,
) -> Pin<Box<dyn Future<Output = Result<()>> + Send + 'async_trait>>where
I: IntoIterator<Item = M> + Send + 'async_trait,
I::IntoIter: Send,
Self: Sync + 'async_trait,
'life0: 'async_trait,
Updates multiple models using the default batch size.
This is a convenience wrapper around update_batch
that uses DEFAULT_BATCH_SIZE
.
It simplifies bulk update operations when the default batch size is suitable.
§Parameters
models
- An iterator yielding model instances to update
§Returns
crate::Result<()>
- Success if all updates were executed, or an error if any operation failed
Sourcefn update_batch<'life0, 'async_trait, const N: usize, I>(
&'life0 self,
models: I,
) -> Pin<Box<dyn Future<Output = Result<()>> + Send + 'async_trait>>where
I: IntoIterator<Item = M> + Send + 'async_trait,
I::IntoIter: Send,
Self: Sync + 'async_trait,
'life0: 'async_trait,
fn update_batch<'life0, 'async_trait, const N: usize, I>(
&'life0 self,
models: I,
) -> Pin<Box<dyn Future<Output = Result<()>> + Send + 'async_trait>>where
I: IntoIterator<Item = M> + Send + 'async_trait,
I::IntoIter: Send,
Self: Sync + 'async_trait,
'life0: 'async_trait,
Performs a batched update operation with a specified batch size.
Similar to insert_batch
, this method uses BatchOperator
to efficiently process
large numbers of updates in chunks, preventing memory overflow and maintaining
optimal database performance.
§Type Parameters
N
- The size of each batch to process
§Parameters
models
- An iterator yielding model instances to update
§Returns
crate::Result<()>
- Success if all batches were processed, or an error if any operation failed
§Performance Considerations
Consider batch size carefully:
- Too small: More overhead from multiple transactions
- Too large: Higher memory usage and longer transactions times
Dyn Compatibility§
This trait is not dyn compatible.
In older versions of Rust, dyn compatibility was called "object safety", so this trait is not object safe.