diff --git a/src/migration.rs b/src/migration.rs index e5faec55..f90d4bf8 100644 --- a/src/migration.rs +++ b/src/migration.rs @@ -1,4 +1,7 @@ -//! Module defining migration trait +//! Module for defining the `Migration` trait, which represents a database +//! migration. +//! +//! This module provides the necessary abstractions for defining migrations #![cfg_attr( feature = "sqlite", doc = r##" @@ -41,6 +44,10 @@ impl Migration for ExampleMigration { fn is_atomic(&self) -> bool { true } + + fn is_virtual(&self) -> bool { + false + } } ``` "## @@ -50,52 +57,78 @@ use std::hash::Hash; use crate::operation::Operation; -/// Trait for migration +/// Trait for defining database migration +/// +/// A migration represents a set of operations that can be applied to or +/// reverted from a database. Each migration has an associated application name, +/// migration name, and may depend on other migrations. +/// +/// Migrations can also replace existing migrations, enforce ordering with +/// run before and parents, and control atomicity and virtualization. #[allow(clippy::module_name_repetitions)] pub trait Migration: Send + Sync { - /// Migration app name. Can be name of folder or library where migration is - /// located + /// Returns the application name associated with the migration. + /// This can be the name of the folder or library where the migration is + /// located. fn app(&self) -> &str; - /// Migration name. Can be file name without extension + /// Returns the migration name, typically the file name without the + /// extension. fn name(&self) -> &str; - /// Parents of migration (migrations that should be applied before this - /// migration) + /// Returns the list of parent migrations. + /// + /// Parent migrations must be applied before this migration can be applied. + /// If no parent migrations are required, return an empty vector. fn parents(&self) -> Vec>>; - /// Operation performed for migration (create, drop, etc.). Migration can - /// contains multiple operation within each other which are interrelated + /// Returns the operations associated with this migration. + /// + /// A migration can include multiple operations (e.g., create, drop) that + /// are related. fn operations(&self) -> Vec>>; - /// Replace certain migrations. If any one of listed migration is applied - /// than migration will not be applied else migration will apply/revert - /// instead of applying/reverting those migration. + /// Returns the list of migrations that this migration replaces. + /// + /// If any of these migrations have been applied, this migration will not be + /// applied. Instead, it will either be applied or reverted in place of + /// those migrations. + /// + /// The default implementation returns an empty vector. fn replaces(&self) -> Vec>> { vec![] } - /// Run before(for applying)/after(for reverting) certain migration. This - /// can be helpful in condition where other library migration need to be - /// applied after this migration or reverted before this migration + /// Returns the list of migrations that this migration must run before(when + /// applying) or after (when reverting). + /// + /// This can be useful when a migration from another library needs to be + /// applied after this migration or reverted before this migration. + /// + /// The default implementation returns an empty vector. fn run_before(&self) -> Vec>> { vec![] } - /// Whether migration is atomic or not. By default it is atomic so this - /// function returns `true`. If you make migration non atomic all its - /// operation will be non atomic if any operation needs to be atomic it is - /// recommended to split migration so one migration will have atomic - /// operation where as another have non atomic operation + /// Indicates whether the migration is atomic. + /// By default, this function returns `true`, meaning the migration is + /// atomic. + /// + /// If the migration is non-atomic, all its operations will be non-atomic as + /// well. For migrations requiring mixed atomicity, it's recommended to + /// split them into separate migrations, each handling atomic and + /// non-atomic operations respectively. fn is_atomic(&self) -> bool { true } - /// Whether migration is virtual or not. By default migration are not - /// virtual. If migration is virtual than it expects another migration with - /// same app and name present inside migration list which is not virtual. - /// For virtual migration all other methods gets ignored since it is - /// reference to actual migration instead of actual migration + /// Indicates whether the migration is virtual. + /// By default, this function returns `false`, meaning the migration is not + /// virtual. + /// + /// A virtual migration serves as a reference to another migration with the + /// same app and name. If the migration is virtual, all other methods + /// are ignored. fn is_virtual(&self) -> bool { false } @@ -142,9 +175,10 @@ where } } -/// Migration struct created from sql table. Struct contains 4 fields which maps -/// to `id`, `app`, `name`, `applied_time` sql fields. It is used to list -/// applied migrations +/// Struct representing a migration row from the database. +/// +/// This struct corresponds to the id, app, name, and applied time fields in the +/// database. It is used to list the migrations that have been applied. #[derive(sqlx::FromRow, Clone)] pub struct AppliedMigrationSqlRow { id: i32, diff --git a/src/migrator/mod.rs b/src/migrator/mod.rs index 259509b9..80ae9462 100644 --- a/src/migrator/mod.rs +++ b/src/migrator/mod.rs @@ -178,8 +178,10 @@ enum PlanType { Apply, Revert, } - -/// Struct which determine type of plan to use +/// Struct that determines the type of migration plan to execute. +/// +/// A `Plan` can specify whether to apply or revert migrations, and may target +/// all migrations, specific migrations, or a limited number of migrations. #[derive(Debug)] pub struct Plan { plan_type: PlanType, @@ -200,25 +202,25 @@ impl Plan { } } - /// Create new plan for apply all + /// Creates a new plan to apply all migrations. #[must_use] pub fn apply_all() -> Self { Self::new(PlanType::Apply, None, None) } - /// Create new plan for apply for provided app and migration name + /// Creates a new plan to apply a specific migration by name. #[must_use] pub fn apply_name(app: &str, name: &Option) -> Self { Self::new(PlanType::Apply, Some((app.to_string(), name.clone())), None) } - /// Create new plan for apply count + /// Creates a new plan to apply a limited number of migrations. #[must_use] pub fn apply_count(count: usize) -> Self { Self::new(PlanType::Apply, None, Some(count)) } - /// Create new plan for revert all + /// Creates a new plan to revert all migrations. #[must_use] pub fn revert_all() -> Self { Self::new(PlanType::Revert, None, None) @@ -234,33 +236,37 @@ impl Plan { ) } - /// Create new plan for revert count + /// Creates a new plan to revert a limited number of migrations. #[must_use] pub fn revert_count(count: usize) -> Self { Self::new(PlanType::Revert, None, Some(count)) } } -/// Info trait which implements some of database agnostic methods to add -/// migration or returns immutable or mutable migrations list +/// The `Info` trait provides database-agnostic methods for managing migrations +/// and interacting with migration states. pub trait Info { - /// Return state used in migrator + /// Returns the current state used by the migrator. fn state(&self) -> &State; - /// Return migrations + /// Returns a reference to the list of migrations. fn migrations(&self) -> &Vec>; - /// Return mutable reference of migrations + /// Returns a mutable reference to the list of migrations. fn migrations_mut(&mut self) -> &mut Vec>; - /// Add vector of migrations to Migrator object + /// Adds a list of migrations to the migrator. + /// + /// This method accepts a vector of migrations and adds each one + /// individually to ensure proper handling of migration relationships + /// and duplicates. fn add_migrations(&mut self, migrations: Vec>) { for migration in migrations { self.add_migration(migration); } } - /// Add single migration to migrator object + /// Adds a single migration to the migrator. fn add_migration(&mut self, migration: BoxMigration) { // if virtual migration is present in list with same app and name than remove // virtual migration from list @@ -301,9 +307,13 @@ pub trait Info { } } -/// Trait which is implemented for database for performing different -/// operations/action on database. Usually this trait is implemented for -/// database to support database along with info trait +/// The `DatabaseOperation` trait defines a set of methods for performing +/// operations related to migration management on the database. +/// +/// This trait is typically implemented for a database to support migration +/// operations, such as ensuring the migration table exists, adding or +/// removing migrations from the table, and locking the database during +/// migration processes. #[async_trait::async_trait] pub trait DatabaseOperation where @@ -322,7 +332,7 @@ where connection: &mut ::Connection, ) -> Result<(), Error>; - /// Add migration to migration db table + /// Adds a migration record to the migration table in the database. #[allow(clippy::borrowed_box)] async fn add_migration_to_db_table( &self, @@ -330,7 +340,7 @@ where migration: &BoxMigration, ) -> Result<(), Error>; - /// Delete migration from migration db table + /// Removes a migration record from the migration table in the database. #[allow(clippy::borrowed_box)] async fn delete_migration_from_db_table( &self, @@ -338,7 +348,8 @@ where migration: &BoxMigration, ) -> Result<(), Error>; - /// List all applied migrations from database as struct + /// Fetches the list of applied migrations from the migration table in the + /// database. async fn fetch_applied_migration_from_db( &self, connection: &mut ::Connection, @@ -537,20 +548,23 @@ fn get_recursive<'get, DB, State>( } recursive_vec } - -/// Migrate trait which migrate a database according to requirements. This trait -/// implements all methods which depends on `DatabaseOperation` trait and `Info` -/// trait. This trait doesn't requires to implement any method since all -/// function have default implementation and all methods are database agnostics +/// The `Migrate` trait defines methods to manage and apply database migrations +/// according to a given plan. +/// +/// This trait combines the functionalities of the `Info` and +/// `DatabaseOperation` traits, providing a full set of migration capabilities. +/// All methods have default implementations, meaning no explicit implementation +/// is required. Additionally, all methods are database-agnostic. #[async_trait::async_trait] pub trait Migrate: Info + DatabaseOperation + Send + Sync where DB: sqlx::Database, State: Send + Sync, { - /// Generate migration plan according to plan. Returns a vector of - /// migration. If plan is none than it will generate plan with all - /// migrations in chronological order of apply + /// Generate migration plan according to plan. + /// + /// Returns a vector of migration. If plan is none than it will generate + /// plan with all migrations in order of apply #[allow(clippy::too_many_lines)] async fn generate_migration_plan( &self, diff --git a/src/operation.rs b/src/operation.rs index 4856b272..d26b7e17 100644 --- a/src/operation.rs +++ b/src/operation.rs @@ -1,4 +1,8 @@ -//! Operation module +//! Module for defining the `Operation` trait +//! +//! This module provides the `Operation` trait, allowing users to define +//! database operations that can be executed as part of a migration process. +//! These operations can be applied (`up`) or optionally reverted (`down`). #![cfg_attr( feature = "sqlite", doc = r##" @@ -40,7 +44,15 @@ impl Operation for ExampleOperation { use crate::error::Error; -/// Trait for operation +/// Trait for defining a database operation. +/// +/// An Operation represents action that can be applied to or reverted from a +/// database during a migration. Each operation can have an up method for +/// applying the change and an optional down method for rolling it back. +/// +/// Operations can also specify whether they are "destructible," meaning that +/// they require user confirmation before being applied, due to potential data +/// loss or irreversible changes #[allow(clippy::module_name_repetitions)] #[async_trait::async_trait] pub trait Operation: Send + Sync @@ -48,15 +60,23 @@ where DB: sqlx::Database, State: Send + Sync, { - /// Up command to be executed during migration apply + /// The up method executes the operation when applying the migration. + /// + /// This method is called when the migration is being applied to the + /// database. Implement this method to define the changes you want to + /// apply. async fn up( &self, connection: &mut ::Connection, state: &State, ) -> Result<(), Error>; - /// Down command to be executed during migration rollback. If it is not - /// implemented than operation is irreversible operation. + /// The `down` method reverses the operation when rolling back the + /// migration. + /// + /// This method is called when the migration is being rolled back. Implement + /// this method if you want to make the operation reversible. If not + /// implemented, the operation is considered irreversible. async fn down( &self, connection: &mut ::Connection, @@ -67,10 +87,13 @@ where return Err(Error::IrreversibleOperation); } - /// Whether up operation is destructible or not. If operation is - /// destructible than user should answer before running migration through - /// cli. By default up operation are false. Down operation are always - /// destructible and cannot be changed + /// Indicates whether the `up` operation is destructible. + /// + /// If the operation is destructible, the user will be prompted for + /// confirmation before running the migration via the CLI, due to the + /// potential for data loss or irreversible changes. By default, `up` + /// operations are considered non-destructible. Note that `down` operations + /// are always considered destructible and cannot be changed. fn is_destructible(&self) -> bool { false }