pub async fn revert(&mut self, version: u64) -> Result<MigrationSummary, Error> {
        self.local_migration(version)?;

        self.check_migrations().await?;

        let db_migrations = self.conn.list_migrations(&self.table).await?;

        let to_revert = self
            .migrations
            .iter()
            .enumerate()
            .skip_while(|(idx, _)| idx + 1 < version as _)
            .take_while(|(idx, _)| *idx < db_migrations.len())
            .collect::<Vec<_>>()
            .into_iter()
            .rev();

        let mut tx = self.conn.begin().await?;

        for (idx, mig) in to_revert {
            let version = idx as u64 + 1;

            let start = Instant::now();

            tracing::info!(
                version,
                name = %mig.name,
                "reverting migration"
            );

            match &mig.down {
                Some(down) => {
                    down(&mut tx).await.map_err(|error| Error::Revert {
                        name: mig.name.clone(),
                        version,
                        error,
                    })?;
                }
                None => {
                    tracing::warn!(
                        version,
                        name = %mig.name,
                        "no down migration found"
                    );
                }
            }

            let execution_time = Instant::now() - start;

            DB::Connection::remove_migration(&self.table, version, &mut tx).await?;

            tracing::info!(
                version,
                name = %mig.name,
                execution_time = %humantime::Duration::from(execution_time),
                "migration reverted"
            );
        }

        tracing::info!("committing changes");
        tx.commit().await?;

        Ok(MigrationSummary {
            old_version: if db_migrations.is_empty() {
                None
            } else {
                Some(db_migrations.len() as _)
            },
            new_version: if version == 1 {
                None
            } else {
                Some(version - 1)
            },
        })
    }
/// Revert all migrations after and including the given version.
///
/// Any migrations that are "not reversible" and have no revert functions will be ignored.
///
/// # Errors
///
/// Whenever a migration fails, and error is returned and no database
/// changes will be made.    
Revert all migrations after and including the given version.
Any migrations that are "not reversible" and have no revert functions will be ignored.
Revert all migrations after and including the given version . Any migrations that are " not reversible " and have no revert functions will be ignored .
pub async fn revert(&mut self, version: u64) -> Result<MigrationSummary, Error> {
        self.local_migration(version)?;
        self.check_migrations().await?;
        let db_migrations = self.conn.list_migrations(&self.table).await?;
        let to_revert = self
            .migrations
            .iter()
            .enumerate()
            .skip_while(|(idx, _)| idx + 1 < version as _)
            .take_while(|(idx, _)| *idx < db_migrations.len())
            .collect::<Vec<_>>()
            .into_iter()
            .rev();
        let mut tx = self.conn.begin().await?;
        for (idx, mig) in to_revert {
            let version = idx as u64 + 1;
            let start = Instant::now();
            tracing::info!(
                version,
                name = %mig.name,
                "reverting migration"
            );
            match &mig.down {
                Some(down) => {
                    down(&mut tx).await.map_err(|error| Error::Revert {
                        name: mig.name.clone(),
                        version,
                        error,
                    })?;
                }
                None => {
                    tracing::warn!(
                        version,
                        name = %mig.name,
                        "no down migration found"
                    );
                }
            }
            let execution_time = Instant::now() - start;
            DB::Connection::remove_migration(&self.table, version, &mut tx).await?;
            tracing::info!(
                version,
                name = %mig.name,
                execution_time = %humantime::Duration::from(execution_time),
                "migration reverted"
            );
        }
        tracing::info!("committing changes");
        tx.commit().await?;
        Ok(MigrationSummary {
            old_version: if db_migrations.is_empty() {
                None
            } else {
                Some(db_migrations.len() as _)
            },
            new_version: if version == 1 {
                None
            } else {
                Some(version - 1)
            },
        })
    }
pub async fn revert ( & mut self , version : u64 ) -> Result < MigrationSummary , Error > { self . local_migration ( version ) ? ; self . check_migrations ( ) . await ? ; let db_migrations = self . conn . list_migrations ( & self . table ) . await ? ; let to_revert = self . migrations . iter ( ) . enumerate ( ) . skip_while ( | ( idx , _ ) | idx + 1 < version as _ ) . take_while ( | ( idx , _ ) | * idx < db_migrations . len ( ) ) . collect :: < Vec < _ > > ( ) . into_iter ( ) . rev ( ) ; let mut tx = self . conn . begin ( ) . await ? ; for ( idx , mig ) in to_revert { let version = idx as u64 + 1 ; let start = Instant :: now ( ) ; tracing :: info ! ( version name mig name " " ) ; match & mig . down { Some ( down ) => { down ( & mut tx ) . await . map_err ( | error | Error :: Revert { name : mig . name . clone ( ) , version , error , } ) ? ; } None => { tracing :: warn ! ( version name mig name " " ) ; } } let execution_time = Instant :: now ( ) - start ; DB :: Connection :: remove_migration ( & self . table , version , & mut tx ) . await ? ; tracing :: info ! ( version name mig name execution_time humantime Duration from ( execution_time ) " " ) ; } tracing :: info ! ( " " ) ; tx . commit ( ) . await ? ; Ok ( MigrationSummary { old_version : if db_migrations . is_empty ( ) { None } else { Some ( db_migrations . len ( ) as _ ) } , new_version : if version == 1 { None } else { Some ( version - 1 ) } , } ) }
Revert all migrations after and including the given version.
Revert all migrations after and including the given version .
&mut self
version
u64
&mut self
version
u64
errors
Whenever a migration fails, and error is returned and no database
changes will be made.
Whenever a migration fails and error is returned and no database changes will be made .