Trait UpdatableRepository

Source
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 the Model 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

  1. Required method: update_query - Defines how a model is translated into an UPDATE statement
  2. Provided methods:
  3. All batch operations use transactions to ensure data consistency
  4. All methods assume the model has a valid ID (typically checked by the Model::get_id method)
  5. Performance is optimized through batching and connection pooling

Required Methods§

Source

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:

  1. Include a WHERE clause matching the model’s ID
  2. Only update columns that can be modified
  3. Preserve any timestamp or audit fields as required

Provided Methods§

Source

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,

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 query
  • 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:

  1. Gets the update query from update_query
  2. Executes it using the connection pool
  3. Handles any potential database errors
Source

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,

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 query
  • 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:

  1. Gets the update query from update_query
  2. Executes it using the connection pool
  3. Handles any potential database errors
Source

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:

  1. Gets the update query from update_query
  2. Executes it using the connection pool
  3. Handles any potential database errors
Source

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:

  1. Gets the update query from update_query
  2. Executes it using the connection pool
  3. Handles any potential database errors
Source

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
Source

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.

Implementors§