refac: add additional trait for migration names

This commit is contained in:
Dmitriy Pleshevskiy 2021-02-15 13:47:45 +03:00
parent 109c9ce52f
commit 33f392e18e
5 changed files with 44 additions and 34 deletions

View File

@ -1,6 +1,6 @@
use crate::config::Config;
use crate::database::PostgresConnection;
use crate::migration::{DatabaseMigrationManager, MigrationManager};
use crate::migration::{DatabaseMigrationManager, MigrationManager, MigrationNames};
use crate::StdResult;
use std::convert::TryFrom;

View File

@ -3,6 +3,7 @@ use crate::database::{DatabaseConnection, PostgresConnection};
use crate::error::{ErrorKind, StdResult};
use crate::migration::{
filter_pending_migrations, DatabaseMigrationManager, Migration, MigrationManager,
MigrationNames,
};
const EM_DASH: char = '—';

View File

@ -1,6 +1,8 @@
use crate::database::{DatabaseConnection, PostgresConnection};
use crate::migration::Migration;
use crate::migration::{filter_pending_migrations, DatabaseMigrationManager, MigrationManager};
use crate::database::PostgresConnection;
use crate::migration::{
filter_pending_migrations, DatabaseMigrationManager, Migration, MigrationManager,
MigrationNames,
};
use crate::Config;
use crate::StdResult;
use std::convert::TryFrom;
@ -25,13 +27,12 @@ fn is_up_to_date_migrations(migrations: &[Migration], applied_migration_names: &
migrations.is_empty() || migrations.last().map(|m| m.name()) == applied_migration_names.first()
}
fn upgrade_all_pending_migrations<Conn, ManagerT>(
fn upgrade_all_pending_migrations<ManagerT>(
mut manager: ManagerT,
pending_migrations: &[Migration],
) -> StdResult<()>
where
Conn: DatabaseConnection,
ManagerT: Sized + DatabaseMigrationManager<Conn>,
ManagerT: Sized + DatabaseMigrationManager,
{
for migration in pending_migrations.iter() {
println!("upgrade {}...", migration.name());

View File

@ -17,6 +17,13 @@ pub trait TryFromSql<QueryResultRow>: Sized {
fn try_from_sql(row: QueryResultRow) -> StdResult<Self>;
}
impl TryFromSql<postgres::Row> for String {
fn try_from_sql(row: postgres::Row) -> StdResult<Self> {
let res: String = row.get(0);
Ok(res)
}
}
pub trait DatabaseConnection: Sized {
type QueryResultRow;
type QueryResult;

View File

@ -1,4 +1,3 @@
use crate::database::TryFromSql;
use crate::database::{DatabaseConnection, PostgresConnection};
use crate::path::PathBuilder;
use crate::StdResult;
@ -67,14 +66,7 @@ pub fn is_migrations_table_not_found<D: std::fmt::Display>(error: D) -> bool {
.contains(r#"relation "migrations" does not exist"#)
}
impl TryFromSql<postgres::Row> for String {
fn try_from_sql(row: postgres::Row) -> StdResult<Self> {
let res: String = row.get(0);
Ok(res)
}
}
pub trait DatabaseMigrationManager<Conn: DatabaseConnection> {
pub trait DatabaseMigrationManager {
const CREATE_MIGRATIONS_STMT: &'static str = r#"
CREATE TABLE IF NOT EXISTS migrations (
id serial PRIMARY KEY,
@ -88,8 +80,6 @@ pub trait DatabaseMigrationManager<Conn: DatabaseConnection> {
fn apply_sql(&mut self, sql_content: &str) -> StdResult<()>;
fn applied_migration_names(&mut self) -> StdResult<Vec<String>>;
fn create_migrations_table(&mut self) -> StdResult<()>;
fn insert_migration_info(&mut self, name: &str) -> StdResult<u64>;
@ -116,26 +106,14 @@ pub trait DatabaseMigrationManager<Conn: DatabaseConnection> {
}
}
impl DatabaseMigrationManager<PostgresConnection> for MigrationManager<PostgresConnection> {
impl<Conn> DatabaseMigrationManager for MigrationManager<Conn>
where
Conn: DatabaseConnection,
{
fn apply_sql(&mut self, sql_content: &str) -> StdResult<()> {
self.conn.batch_execute(sql_content)
}
fn applied_migration_names(&mut self) -> StdResult<Vec<String>> {
let res = self
.conn
.query("SELECT name FROM migrations ORDER BY id DESC", &[])
.or_else(|e| {
if is_migrations_table_not_found(&e) {
Ok(Vec::new())
} else {
Err(e)
}
})?;
Ok(res.into_iter().collect())
}
fn create_migrations_table(&mut self) -> StdResult<()> {
self.conn.batch_execute(Self::CREATE_MIGRATIONS_STMT)
}
@ -149,6 +127,29 @@ impl DatabaseMigrationManager<PostgresConnection> for MigrationManager<PostgresC
}
}
pub trait MigrationNames {
const APPLIED_MIGRATIONS_STMT: &'static str = "SELECT name FROM migrations ORDER BY id DESC";
fn applied_migration_names(&mut self) -> StdResult<Vec<String>>;
}
impl MigrationNames for MigrationManager<PostgresConnection> {
fn applied_migration_names(&mut self) -> StdResult<Vec<String>> {
let res = self
.conn
.query(Self::APPLIED_MIGRATIONS_STMT, &[])
.or_else(|e| {
if is_migrations_table_not_found(&e) {
Ok(Vec::new())
} else {
Err(e)
}
})?;
Ok(res.into_iter().collect())
}
}
pub fn filter_pending_migrations(
migrations: Vec<Migration>,
applied_migration_names: &[String],