Trait DeleteRepository

Source
pub trait DeleteRepository<M: Model>: Repository<M> {
    // Required methods
    fn delete_by_id_query(id: &M::Id) -> Query<'_>;
    fn delete_by_filter_query<'args>(
        filter: impl SqlFilter<'args>,
    ) -> QueryBuilder<'args, Database>;

    // Provided methods
    fn delete_by_id_with_executor<'c, 'life0, 'async_trait, E>(
        &'life0 self,
        tx: E,
        id: impl 'async_trait + Into<M::Id> + Send,
    ) -> Pin<Box<dyn Future<Output = Result<()>> + Send + 'async_trait>>
       where E: Executor<'c, Database = Database> + Send + 'async_trait,
             Self: Sync + 'async_trait,
             'c: 'async_trait,
             'life0: 'async_trait { ... }
    fn delete_by_id<'life0, 'async_trait>(
        &'life0 self,
        id: impl 'async_trait + Into<M::Id> + Send,
    ) -> Pin<Box<dyn Future<Output = Result<()>> + Send + 'async_trait>>
       where Self: Sync + 'async_trait,
             'life0: 'async_trait { ... }
    fn delete_many_by_id<'life0, 'async_trait, I>(
        &'life0 self,
        ids: I,
    ) -> Pin<Box<dyn Future<Output = Result<()>> + Send + 'async_trait>>
       where I: IntoIterator<Item = M::Id> + Send + 'async_trait,
             I::IntoIter: Send,
             Self: Sync + 'async_trait,
             'life0: 'async_trait { ... }
    fn delete_batch_by_id<'life0, 'async_trait, const N: usize, I>(
        &'life0 self,
        ids: I,
    ) -> Pin<Box<dyn Future<Output = Result<()>> + Send + 'async_trait>>
       where I: IntoIterator<Item = M::Id> + Send + 'async_trait,
             I::IntoIter: Send,
             Self: Sync + 'async_trait,
             'life0: 'async_trait { ... }
    fn delete_by_filter_with_executor<'c, 'life0, 'life1, 'async_trait, E>(
        &'life0 self,
        tx: E,
        filter: impl 'async_trait + SqlFilter<'life1> + Send,
    ) -> Pin<Box<dyn Future<Output = Result<()>> + Send + 'async_trait>>
       where E: Executor<'c, Database = Database> + Send + 'async_trait,
             Self: Sync + 'async_trait,
             'c: 'async_trait,
             'life0: 'async_trait,
             'life1: 'async_trait { ... }
    fn delete_by_filter<'life0, 'life1, 'async_trait>(
        &'life0 self,
        filter: impl 'async_trait + SqlFilter<'life1> + Send,
    ) -> Pin<Box<dyn Future<Output = Result<()>> + Send + 'async_trait>>
       where Self: Sync + 'async_trait,
             'life0: 'async_trait,
             'life1: 'async_trait { ... }
}
Expand description

Trait for repositories that can delete records from the database.

The DeleteRepository trait extends the base Repository trait with methods for deleting records. It provides standardized ways to delete both individual records and batches of records, optimizing database interactions while maintaining data integrity.

§Type Parameters

  • M - The model type that this repository deletes. Must implement the Model trait.

§Examples

Basic implementation:

use sqlx_utils::traits::{Model, Repository, DeleteRepository};

impl DeleteRepository<User> for UserRepository {
    fn delete_by_id_query(id: &i32) -> Query<'_> {
        sqlx::query("DELETE FROM users WHERE id = $1")
            .bind(id)
    }

    fn delete_by_filter_query<'args>(filter: impl SqlFilter<'args>) -> QueryBuilder<'args> {
        let mut builder = QueryBuilder::new("DELETE FROM users");

        if filter.should_apply_filter() {
            builder.push("WHERE ");
            filter.apply_filter(&mut builder);
        }

        builder
    }
}

// Usage
// Delete a single user
repo.delete_by_id(1).await?;

// Delete multiple users
let ids = vec![1, 2, 3];
repo.delete_many_by_id(ids).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_delete! {
    UserRepository<User>;

    delete_by_id_query(id) {
        sqlx::query("DELETE FROM users WHERE id = $1")
            .bind(id)
    }

    delete_by_filter_query(filter) {
        let mut builder = QueryBuilder::new("DELETE FROM users");

        if filter.should_apply_filter() {
            builder.push("WHERE ");
            filter.apply_filter(&mut builder);
        }

        builder
    }
}

§Implementation Notes

  1. Required method: delete_by_id_query - Defines how to create a deletion query for a model ID
  2. Provided methods:
  3. All batch operations use transactions to ensure data consistency
  4. Performance is optimized through batching and connection pooling
  5. Consider implementing soft deletes if required by your application

Required Methods§

Source

fn delete_by_id_query(id: &M::Id) -> Query<'_>

Creates a SQL query to delete a record by its ID.

This method generates a DELETE statement that will remove exactly one record from the database based on its primary key. It’s designed to be both safe and efficient by using parameterized queries.

§Parameters
  • id - A reference to the ID of the record to delete
§Returns
  • Query - A prepared SQL DELETE query
§Implementation Notes

Consider:

  1. Handling soft deletes if required
  2. Checking foreign key constraints
  3. Implementing cascading deletes if needed
Source

fn delete_by_filter_query<'args>( filter: impl SqlFilter<'args>, ) -> QueryBuilder<'args, Database>

Creates a SQL query to delete a record by a given SqlFilter.

This method generates a DELETE statement that will remove all records that match a given SqlFilter. It’s designed to be both safe and efficient by using parameterized queries. The query can do a soft delete or a complete remove of it, that detail is up to the implementor, the rest of the Trait expects the query to not return anything however and the query should reflect that.

§Parameters
  • filter - The filter used when generating the query.
§Returns
  • Query - A prepared SQL query to DELETE records or soft delete them
§Implementation Notes

Consider:

  1. Handling soft deletes if required
  2. Checking foreign key constraints
  3. Implementing cascading deletes if needed
  4. If called via the default implementation of delete_by_filter_with_executor the filter will be guaranteed to be applied.

Provided Methods§

Source

fn delete_by_id_with_executor<'c, 'life0, 'async_trait, E>( &'life0 self, tx: E, id: impl 'async_trait + Into<M::Id> + Send, ) -> Pin<Box<dyn Future<Output = Result<()>> + Send + 'async_trait>>
where E: Executor<'c, Database = Database> + Send + 'async_trait, Self: Sync + 'async_trait, 'c: 'async_trait, 'life0: 'async_trait,

Removes a single record from the database by its identifier.

This method executes the deletion query generated by delete_by_id_query and uses the Executor tx for doing it. It provides a simple interface for removing individual records while handling all necessary database interactions and error management.

§Parameters
  • tx - The executor to use for the query
  • id - Any value that can be converted into the model’s ID type
§Returns
  • crate::Result<()> - Success if the deletion was executed, or an error if the operation failed
§Example
async fn remove_user(repo: &UserRepository, user_id: i32) -> crate::Result<()> {
    repo.delete_by_id_with_executor(repo.pool(), user_id).await
}
Source

fn delete_by_id<'life0, 'async_trait>( &'life0 self, id: impl 'async_trait + Into<M::Id> + Send, ) -> Pin<Box<dyn Future<Output = Result<()>> + Send + 'async_trait>>
where Self: Sync + 'async_trait, 'life0: 'async_trait,

Removes a single record from the database by its identifier.

This method executes the deletion query generated by delete_by_id_query. It provides a simple interface for removing individual records while handling all necessary database interactions and error management.

§Parameters
  • id - Any value that can be converted into the model’s ID type
§Returns
  • crate::Result<()> - Success if the deletion was executed, or an error if the operation failed
§Example
async fn remove_user(repo: &UserRepository, user_id: i32) -> crate::Result<()> {
    repo.delete_by_id(user_id).await
}
Source

fn delete_many_by_id<'life0, 'async_trait, I>( &'life0 self, ids: I, ) -> Pin<Box<dyn Future<Output = Result<()>> + Send + 'async_trait>>
where I: IntoIterator<Item = M::Id> + Send + 'async_trait, I::IntoIter: Send, Self: Sync + 'async_trait, 'life0: 'async_trait,

Deletes multiple records using the default batch size.

This is a convenience wrapper around delete_batch that uses DEFAULT_BATCH_SIZE. It provides a simpler interface for bulk deletions when the default batch size is appropriate.

§Parameters
  • ids - An iterator yielding IDs of records to delete
§Returns
  • crate::Result<()> - Success if all deletions were executed, or an error if any operation failed
Source

fn delete_batch_by_id<'life0, 'async_trait, const N: usize, I>( &'life0 self, ids: I, ) -> Pin<Box<dyn Future<Output = Result<()>> + Send + 'async_trait>>
where I: IntoIterator<Item = M::Id> + Send + 'async_trait, I::IntoIter: Send, Self: Sync + 'async_trait, 'life0: 'async_trait,

Performs a batched deletion operation with a specified batch size.

Similar to other batch operations, this method uses BatchOperator to efficiently process large numbers of deletions in chunks, maintaining optimal performance and preventing resource exhaustion.

§Type Parameters
  • N - The size of each batch to process
§Parameters
  • ids - An iterator yielding IDs of records to delete
§Returns
  • crate::Result<()> - Success if all batches were processed, or an error if any operation failed
§Implementation Details

The method:

  1. Chunks the input IDs into batches of size N
  2. Processes each batch in a transactions using delete_query_by_id
  3. Maintains ACID properties within each batch
§Performance Considerations

Consider batch size carefully:

  • Too small: More overhead from multiple transactions
  • Too large: Higher memory usage and longer transactions times
Source

fn delete_by_filter_with_executor<'c, 'life0, 'life1, 'async_trait, E>( &'life0 self, tx: E, filter: impl 'async_trait + SqlFilter<'life1> + Send, ) -> Pin<Box<dyn Future<Output = Result<()>> + Send + 'async_trait>>
where E: Executor<'c, Database = Database> + Send + 'async_trait, Self: Sync + 'async_trait, 'c: 'async_trait, 'life0: 'async_trait, 'life1: 'async_trait,

Removes records from the database by a filter.

This method executes the deletion query generated by delete_by_filter_query and uses the Executor tx for doing it. It provides a simple interface for removing records with a filter while handling all necessary database interactions and error management.

§Parameters
  • tx - The executor to use for the query
  • filter - A SqlFilter to define what records should be deleted
§Returns
  • crate::Result<()> - Success if the deletion was executed, or an error if the operation failed
§Example
async fn remove_user(repo: &UserRepository, filter: impl SqlFilter<'_>) -> crate::Result<()> {
    repo.delete_by_filter_with_executor(repo.pool(), filter).await
}
Source

fn delete_by_filter<'life0, 'life1, 'async_trait>( &'life0 self, filter: impl 'async_trait + SqlFilter<'life1> + Send, ) -> Pin<Box<dyn Future<Output = Result<()>> + Send + 'async_trait>>
where Self: Sync + 'async_trait, 'life0: 'async_trait, 'life1: 'async_trait,

Removes records from the database by a filter.

This method executes the deletion query generated by delete_by_filter_query and uses the Repository::pool as a Executor. It provides a simple interface for removing records with a filter while handling all necessary database interactions and error management.

§Parameters
  • filter - A SqlFilter to define what records should be deleted
§Returns
  • crate::Result<()> - Success if the deletion was executed, or an error if the operation failed
§Example
async fn remove_user(repo: &UserRepository, filter: impl SqlFilter<'_>) -> crate::Result<()> {
    repo.delete_by_filter(filter).await
}

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§