1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121
//! Module defining migration trait
//!
//! To create own implement migration trait for type
//!
//! ### Example
//!
//! ```rust,no_run
//! use sqlx_migrator::error::Error;
//! use sqlx_migrator::migration::Migration;
//! use sqlx_migrator::operation::Operation;
//!
//! struct ExampleMigration;
//! #[async_trait::async_trait]
//! impl Migration for ExampleMigration {
//! type Database = sqlx_migrator::sqlx::Sqlite;
//!
//! fn app(&self) -> &str {
//! "example"
//! }
//!
//! fn name(&self) -> &str {
//! "first_migration"
//! }
//!
//! fn parents(&self) -> Vec<Box<dyn Migration<Database = Self::Database>>> {
//! vec![]
//! }
//!
//! fn operations(&self) -> Vec<Box<dyn Operation<Database = Self::Database>>> {
//! vec![]
//! }
//!
//! fn replaces(&self) -> Vec<Box<dyn Migration<Database = Self::Database>>> {
//! vec![]
//! }
//!
//! fn run_before(&self) -> Vec<Box<dyn Migration<Database = Self::Database>>> {
//! vec![]
//! }
//!
//! fn is_atomic(&self) -> bool {
//! true
//! }
//! }
//! ```
use std::hash::Hash;
use crate::operation::Operation;
/// Trait for migration
pub trait Migration: Send + Sync {
/// Type of database to be used
type Database: sqlx::Database;
/// Migration app name. Can be name of folder or library where migration is
/// located
fn app(&self) -> &str;
/// Migration name. Can be file name without extension
fn name(&self) -> &str;
/// Parents of migration (migrations that should be applied before this
/// migration)
fn parents(&self) -> Vec<Box<dyn Migration<Database = Self::Database>>> {
vec![]
}
/// Operation performed for migration (create, drop, etc.)
fn operations(&self) -> Vec<Box<dyn Operation<Database = Self::Database>>> {
vec![]
}
/// Replace certain migrations. If any one of listed migration is applied
/// than migration will not be applied else migration will apply instead of
/// applying those migration.
fn replaces(&self) -> Vec<Box<dyn Migration<Database = Self::Database>>> {
vec![]
}
/// Run before certain migration. This can be helpful in condition where
/// other library migration need to be applied after this migration
fn run_before(&self) -> Vec<Box<dyn Migration<Database = Self::Database>>> {
vec![]
}
/// Whether migration is atomic or not. By default it is true
fn is_atomic(&self) -> bool {
true
}
}
impl<DB> PartialEq for dyn Migration<Database = DB>
where
DB: sqlx::Database,
{
fn eq(&self, other: &Self) -> bool {
self.app() == other.app() && self.name() == other.name()
}
}
impl<DB> Eq for dyn Migration<Database = DB> where DB: sqlx::Database {}
impl<DB> Hash for dyn Migration<Database = DB>
where
DB: sqlx::Database,
{
fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
self.app().hash(state);
self.name().hash(state);
}
}
impl<DB> PartialEq<(String, String)> for &Box<dyn Migration<Database = DB>>
where
DB: sqlx::Database,
{
fn eq(&self, other: &(String, String)) -> bool {
self.app() == other.0 && self.name() == other.1
}
}