refac: add additional trait for migration names
This commit is contained in:
parent
109c9ce52f
commit
33f392e18e
5 changed files with 44 additions and 34 deletions
|
@ -1,6 +1,6 @@
|
||||||
use crate::config::Config;
|
use crate::config::Config;
|
||||||
use crate::database::PostgresConnection;
|
use crate::database::PostgresConnection;
|
||||||
use crate::migration::{DatabaseMigrationManager, MigrationManager};
|
use crate::migration::{DatabaseMigrationManager, MigrationManager, MigrationNames};
|
||||||
use crate::StdResult;
|
use crate::StdResult;
|
||||||
use std::convert::TryFrom;
|
use std::convert::TryFrom;
|
||||||
|
|
||||||
|
|
|
@ -3,6 +3,7 @@ use crate::database::{DatabaseConnection, PostgresConnection};
|
||||||
use crate::error::{ErrorKind, StdResult};
|
use crate::error::{ErrorKind, StdResult};
|
||||||
use crate::migration::{
|
use crate::migration::{
|
||||||
filter_pending_migrations, DatabaseMigrationManager, Migration, MigrationManager,
|
filter_pending_migrations, DatabaseMigrationManager, Migration, MigrationManager,
|
||||||
|
MigrationNames,
|
||||||
};
|
};
|
||||||
|
|
||||||
const EM_DASH: char = '—';
|
const EM_DASH: char = '—';
|
||||||
|
|
|
@ -1,6 +1,8 @@
|
||||||
use crate::database::{DatabaseConnection, PostgresConnection};
|
use crate::database::PostgresConnection;
|
||||||
use crate::migration::Migration;
|
use crate::migration::{
|
||||||
use crate::migration::{filter_pending_migrations, DatabaseMigrationManager, MigrationManager};
|
filter_pending_migrations, DatabaseMigrationManager, Migration, MigrationManager,
|
||||||
|
MigrationNames,
|
||||||
|
};
|
||||||
use crate::Config;
|
use crate::Config;
|
||||||
use crate::StdResult;
|
use crate::StdResult;
|
||||||
use std::convert::TryFrom;
|
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()
|
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,
|
mut manager: ManagerT,
|
||||||
pending_migrations: &[Migration],
|
pending_migrations: &[Migration],
|
||||||
) -> StdResult<()>
|
) -> StdResult<()>
|
||||||
where
|
where
|
||||||
Conn: DatabaseConnection,
|
ManagerT: Sized + DatabaseMigrationManager,
|
||||||
ManagerT: Sized + DatabaseMigrationManager<Conn>,
|
|
||||||
{
|
{
|
||||||
for migration in pending_migrations.iter() {
|
for migration in pending_migrations.iter() {
|
||||||
println!("upgrade {}...", migration.name());
|
println!("upgrade {}...", migration.name());
|
||||||
|
|
|
@ -17,6 +17,13 @@ pub trait TryFromSql<QueryResultRow>: Sized {
|
||||||
fn try_from_sql(row: QueryResultRow) -> StdResult<Self>;
|
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 {
|
pub trait DatabaseConnection: Sized {
|
||||||
type QueryResultRow;
|
type QueryResultRow;
|
||||||
type QueryResult;
|
type QueryResult;
|
||||||
|
|
|
@ -1,4 +1,3 @@
|
||||||
use crate::database::TryFromSql;
|
|
||||||
use crate::database::{DatabaseConnection, PostgresConnection};
|
use crate::database::{DatabaseConnection, PostgresConnection};
|
||||||
use crate::path::PathBuilder;
|
use crate::path::PathBuilder;
|
||||||
use crate::StdResult;
|
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"#)
|
.contains(r#"relation "migrations" does not exist"#)
|
||||||
}
|
}
|
||||||
|
|
||||||
impl TryFromSql<postgres::Row> for String {
|
pub trait DatabaseMigrationManager {
|
||||||
fn try_from_sql(row: postgres::Row) -> StdResult<Self> {
|
|
||||||
let res: String = row.get(0);
|
|
||||||
Ok(res)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub trait DatabaseMigrationManager<Conn: DatabaseConnection> {
|
|
||||||
const CREATE_MIGRATIONS_STMT: &'static str = r#"
|
const CREATE_MIGRATIONS_STMT: &'static str = r#"
|
||||||
CREATE TABLE IF NOT EXISTS migrations (
|
CREATE TABLE IF NOT EXISTS migrations (
|
||||||
id serial PRIMARY KEY,
|
id serial PRIMARY KEY,
|
||||||
|
@ -88,8 +80,6 @@ pub trait DatabaseMigrationManager<Conn: DatabaseConnection> {
|
||||||
|
|
||||||
fn apply_sql(&mut self, sql_content: &str) -> StdResult<()>;
|
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 create_migrations_table(&mut self) -> StdResult<()>;
|
||||||
|
|
||||||
fn insert_migration_info(&mut self, name: &str) -> StdResult<u64>;
|
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<()> {
|
fn apply_sql(&mut self, sql_content: &str) -> StdResult<()> {
|
||||||
self.conn.batch_execute(sql_content)
|
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<()> {
|
fn create_migrations_table(&mut self) -> StdResult<()> {
|
||||||
self.conn.batch_execute(Self::CREATE_MIGRATIONS_STMT)
|
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(
|
pub fn filter_pending_migrations(
|
||||||
migrations: Vec<Migration>,
|
migrations: Vec<Migration>,
|
||||||
applied_migration_names: &[String],
|
applied_migration_names: &[String],
|
||||||
|
|
Reference in a new issue