Archived
1
0
Fork 0

feat: add managers

This commit is contained in:
Dmitriy Pleshevskiy 2021-05-30 23:27:42 +03:00
parent 65ec318e9d
commit 1a59331ecf
4 changed files with 95 additions and 14 deletions

View file

@ -1,11 +1,13 @@
use crate::error::MigraResult; use crate::error::MigraResult;
use crate::migration; use crate::migration;
use crate::migration::{DOWNGRADE_MIGRATION_FILE_NAME, UPGRADE_MIGRATION_FILE_NAME};
use std::io; use std::io;
use std::path::Path; use std::path::Path;
#[must_use] #[must_use]
pub fn is_migration_dir(path: &Path) -> bool { pub fn is_migration_dir(path: &Path) -> bool {
path.join("up.sql").exists() && path.join("down.sql").exists() path.join(UPGRADE_MIGRATION_FILE_NAME).exists()
&& path.join(DOWNGRADE_MIGRATION_FILE_NAME).exists()
} }
pub fn get_all_migrations(dir_path: &Path) -> MigraResult<migration::List> { pub fn get_all_migrations(dir_path: &Path) -> MigraResult<migration::List> {

View file

@ -2,12 +2,15 @@
#![deny(clippy::all, clippy::pedantic)] #![deny(clippy::all, clippy::pedantic)]
#![allow(clippy::missing_errors_doc)] #![allow(clippy::missing_errors_doc)]
mod error;
pub mod fs; pub mod fs;
pub mod managers;
pub mod migration; pub mod migration;
mod error;
pub use error::{Error, MigraResult as Result}; pub use error::{Error, MigraResult as Result};
pub use migration::Migration;
/* /*
# list # list

41
migra/src/managers.rs Normal file
View file

@ -0,0 +1,41 @@
use crate::error::MigraResult;
use crate::migration::{self, Migration};
pub trait ManageTransaction {
fn begin_transaction(&mut self) -> MigraResult<()>;
fn rollback_transaction(&mut self) -> MigraResult<()>;
fn commit_transaction(&mut self) -> MigraResult<()>;
}
pub trait ManageMigrations {
fn apply_sql(&mut self, sql_content: &str) -> MigraResult<()>;
fn create_migrations_table(&mut self) -> MigraResult<()>;
fn insert_migration(&mut self, name: &str) -> MigraResult<u64>;
fn delete_migration(&mut self, name: &str) -> MigraResult<u64>;
fn applied_migrations(&mut self) -> MigraResult<migration::List>;
fn apply_upgrade_migration(&mut self, migration: &Migration) -> MigraResult<()> {
let content = migration.read_upgrade_migration_sql()?;
self.create_migrations_table()?;
self.apply_sql(&content)?;
self.insert_migration(migration.name())?;
Ok(())
}
fn apply_downgrade_migration(&mut self, migration: &Migration) -> MigraResult<()> {
let content = migration.read_downgrade_migration_sql()?;
self.apply_sql(&content)?;
self.delete_migration(migration.name())?;
Ok(())
}
}

View file

@ -1,15 +1,27 @@
use std::fs;
use std::io;
use std::iter::FromIterator; use std::iter::FromIterator;
use std::path::{Path, PathBuf};
pub(crate) const UPGRADE_MIGRATION_FILE_NAME: &str = "up.sql";
pub(crate) const DOWNGRADE_MIGRATION_FILE_NAME: &str = "down.sql";
#[derive(Debug, Clone, Default, PartialEq, Eq)] #[derive(Debug, Clone, Default, PartialEq, Eq)]
pub struct Migration { pub struct Migration {
path: PathBuf,
name: String, name: String,
} }
impl Migration { impl Migration {
#[must_use] #[must_use]
pub fn new(name: &str) -> Self { pub fn new(path: &Path) -> Self {
Migration { Migration {
name: name.to_owned(), path: PathBuf::from(path),
name: path
.file_name()
.and_then(std::ffi::OsStr::to_str)
.expect("Cannot read migration name")
.to_string(),
} }
} }
@ -17,6 +29,14 @@ impl Migration {
pub fn name(&self) -> &String { pub fn name(&self) -> &String {
&self.name &self.name
} }
pub fn read_upgrade_migration_sql(&self) -> io::Result<String> {
fs::read_to_string(self.path.join(UPGRADE_MIGRATION_FILE_NAME))
}
pub fn read_downgrade_migration_sql(&self) -> io::Result<String> {
fs::read_to_string(self.path.join(DOWNGRADE_MIGRATION_FILE_NAME))
}
} }
#[derive(Debug, Clone, Default, PartialEq, Eq)] #[derive(Debug, Clone, Default, PartialEq, Eq)]
@ -24,7 +44,7 @@ pub struct List {
inner: Vec<Migration>, inner: Vec<Migration>,
} }
impl<T: AsRef<str>> From<Vec<T>> for List { impl<T: AsRef<Path>> From<Vec<T>> for List {
fn from(list: Vec<T>) -> Self { fn from(list: Vec<T>) -> Self {
List { List {
inner: list.iter().map(AsRef::as_ref).map(Migration::new).collect(), inner: list.iter().map(AsRef::as_ref).map(Migration::new).collect(),
@ -50,8 +70,8 @@ impl List {
self.inner.push(migration) self.inner.push(migration)
} }
pub fn push_name(&mut self, name: &str) { pub fn push_name<P: AsRef<Path>>(&mut self, path: P) {
self.inner.push(Migration::new(name)) self.inner.push(Migration::new(path.as_ref()))
} }
#[must_use] #[must_use]
@ -67,7 +87,16 @@ impl List {
} }
#[must_use] #[must_use]
pub fn maybe_next<'a>(&self, name: &'a str) -> Option<&'a str> { pub fn maybe_contains<'a>(&self, name: &'a str) -> Option<&'a str> {
if self.contains_name(name) {
Some(name)
} else {
None
}
}
#[must_use]
pub fn maybe_missed<'a>(&self, name: &'a str) -> Option<&'a str> {
if self.contains_name(name) { if self.contains_name(name) {
None None
} else { } else {
@ -118,10 +147,10 @@ mod tests {
fn push_migration_to_list() { fn push_migration_to_list() {
let mut list = List::new(); let mut list = List::new();
list.push(Migration::new(FIRST_MIGRATION)); list.push(Migration::new(&PathBuf::from(FIRST_MIGRATION)));
assert_eq!(list, List::from(vec![FIRST_MIGRATION])); assert_eq!(list, List::from(vec![FIRST_MIGRATION]));
list.push(Migration::new(&String::from(SECOND_MIGRATION))); list.push(Migration::new(&PathBuf::from(SECOND_MIGRATION)));
assert_eq!(list, List::from(vec![FIRST_MIGRATION, SECOND_MIGRATION])) assert_eq!(list, List::from(vec![FIRST_MIGRATION, SECOND_MIGRATION]))
} }
@ -140,8 +169,14 @@ mod tests {
fn contains_migration() { fn contains_migration() {
let list = List::from(vec![FIRST_MIGRATION]); let list = List::from(vec![FIRST_MIGRATION]);
assert_eq!(list.contains(&Migration::new(FIRST_MIGRATION)), true); assert_eq!(
assert_eq!(list.contains(&Migration::new(SECOND_MIGRATION)), false); list.contains(&Migration::new(&PathBuf::from(FIRST_MIGRATION))),
true
);
assert_eq!(
list.contains(&Migration::new(&PathBuf::from(SECOND_MIGRATION))),
false
);
} }
#[test] #[test]
@ -156,8 +191,8 @@ mod tests {
fn maybe_next_migration_name() { fn maybe_next_migration_name() {
let list = List::from(vec![FIRST_MIGRATION]); let list = List::from(vec![FIRST_MIGRATION]);
assert_eq!(list.maybe_next(FIRST_MIGRATION), None); assert_eq!(list.maybe_missed(FIRST_MIGRATION), None);
assert_eq!(list.maybe_next(SECOND_MIGRATION), Some(SECOND_MIGRATION)); assert_eq!(list.maybe_missed(SECOND_MIGRATION), Some(SECOND_MIGRATION));
} }
#[test] #[test]