refac: move postgres initialization to separate dir
This commit is contained in:
parent
9679519380
commit
d4106c50e6
9 changed files with 106 additions and 97 deletions
|
@ -1,5 +1,5 @@
|
|||
use crate::config::Config;
|
||||
use crate::database::PostgresConnection;
|
||||
use crate::databases::*;
|
||||
use crate::migration::{DatabaseMigrationManager, MigrationManager};
|
||||
use crate::opts::ApplyCommandOpt;
|
||||
use crate::path::PathBuilder;
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
use crate::config::Config;
|
||||
use crate::database::PostgresConnection;
|
||||
use crate::migration::{DatabaseMigrationManager, MigrationManager, MigrationNames};
|
||||
use crate::databases::*;
|
||||
use crate::StdResult;
|
||||
use std::convert::TryFrom;
|
||||
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
use crate::config::Config;
|
||||
use crate::database::{DatabaseConnection, PostgresConnection};
|
||||
use crate::database::DatabaseConnection;
|
||||
use crate::databases::*;
|
||||
use crate::error::{ErrorKind, StdResult};
|
||||
use crate::migration::{filter_pending_migrations, Migration, MigrationManager, MigrationNames};
|
||||
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
use crate::database::PostgresConnection;
|
||||
use crate::databases::*;
|
||||
use crate::migration::{
|
||||
filter_pending_migrations, DatabaseMigrationManager, Migration, MigrationManager,
|
||||
MigrationNames,
|
||||
|
|
|
@ -1,7 +1,4 @@
|
|||
use crate::config::Config;
|
||||
use crate::StdResult;
|
||||
use postgres::{Client, NoTls};
|
||||
use std::convert::TryFrom;
|
||||
|
||||
pub trait ToSql {
|
||||
fn to_sql(&self) -> String;
|
||||
|
@ -17,13 +14,6 @@ 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;
|
||||
|
@ -42,67 +32,3 @@ pub trait DatabaseConnection: Sized {
|
|||
where
|
||||
OutputItem: ?Sized + TryFromSql<Self::QueryResultRow>;
|
||||
}
|
||||
|
||||
pub struct PostgresConnection {
|
||||
client: Client,
|
||||
}
|
||||
|
||||
impl TryFrom<&Config> for PostgresConnection {
|
||||
type Error = Box<dyn std::error::Error>;
|
||||
|
||||
fn try_from(config: &Config) -> Result<Self, Self::Error> {
|
||||
PostgresConnection::open(&config.database_connection_string()?)
|
||||
}
|
||||
}
|
||||
|
||||
impl DatabaseConnection for PostgresConnection {
|
||||
type QueryResultRow = postgres::Row;
|
||||
type QueryResult = Vec<Self::QueryResultRow>;
|
||||
|
||||
fn open(connection_string: &str) -> StdResult<Self> {
|
||||
let client = Client::connect(connection_string, NoTls)?;
|
||||
Ok(PostgresConnection { client })
|
||||
}
|
||||
|
||||
fn batch_execute(&mut self, query: &str) -> StdResult<()> {
|
||||
self.client.batch_execute(query)?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn execute<'b>(&mut self, query: &str, params: &'b [&'b dyn ToSql]) -> StdResult<u64> {
|
||||
let stmt = params
|
||||
.iter()
|
||||
.enumerate()
|
||||
.fold(query.to_string(), |acc, (i, p)| {
|
||||
str::replace(&acc, &format!("${}", i), &p.to_sql())
|
||||
});
|
||||
|
||||
let res = self.client.execute(stmt.as_str(), &[])?;
|
||||
Ok(res)
|
||||
}
|
||||
|
||||
fn query<'b, OutputItem>(
|
||||
&mut self,
|
||||
query: &str,
|
||||
params: &'b [&'b dyn ToSql],
|
||||
) -> StdResult<Vec<OutputItem>>
|
||||
where
|
||||
OutputItem: ?Sized + TryFromSql<Self::QueryResultRow>,
|
||||
{
|
||||
let stmt = params
|
||||
.iter()
|
||||
.enumerate()
|
||||
.fold(query.to_string(), |acc, (i, p)| {
|
||||
str::replace(&acc, &format!("${}", i), &p.to_sql())
|
||||
});
|
||||
|
||||
let res: Self::QueryResult = self.client.query(stmt.as_str(), &[])?;
|
||||
|
||||
let res = res
|
||||
.into_iter()
|
||||
.map(OutputItem::try_from_sql)
|
||||
.collect::<Result<Vec<OutputItem>, _>>()?;
|
||||
|
||||
Ok(res)
|
||||
}
|
||||
}
|
||||
|
|
3
migra-cli/src/databases/mod.rs
Normal file
3
migra-cli/src/databases/mod.rs
Normal file
|
@ -0,0 +1,3 @@
|
|||
mod postgres;
|
||||
|
||||
pub use self::postgres::*;
|
95
migra-cli/src/databases/postgres.rs
Normal file
95
migra-cli/src/databases/postgres.rs
Normal file
|
@ -0,0 +1,95 @@
|
|||
|
||||
use crate::migration::{MigrationNames, MigrationManager, is_migrations_table_not_found};
|
||||
use postgres::{Client, NoTls};
|
||||
use crate::config::Config;
|
||||
use std::convert::TryFrom;
|
||||
use crate::error::StdResult;
|
||||
use crate::database::{TryFromSql, ToSql, DatabaseConnection};
|
||||
|
||||
pub struct PostgresConnection {
|
||||
client: Client,
|
||||
}
|
||||
|
||||
impl TryFrom<&Config> for PostgresConnection {
|
||||
type Error = Box<dyn std::error::Error>;
|
||||
|
||||
fn try_from(config: &Config) -> Result<Self, Self::Error> {
|
||||
PostgresConnection::open(&config.database_connection_string()?)
|
||||
}
|
||||
}
|
||||
|
||||
impl DatabaseConnection for PostgresConnection {
|
||||
type QueryResultRow = postgres::Row;
|
||||
type QueryResult = Vec<Self::QueryResultRow>;
|
||||
|
||||
fn open(connection_string: &str) -> StdResult<Self> {
|
||||
let client = Client::connect(connection_string, NoTls)?;
|
||||
Ok(PostgresConnection { client })
|
||||
}
|
||||
|
||||
fn batch_execute(&mut self, query: &str) -> StdResult<()> {
|
||||
self.client.batch_execute(query)?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn execute<'b>(&mut self, query: &str, params: &'b [&'b dyn ToSql]) -> StdResult<u64> {
|
||||
let stmt = params
|
||||
.iter()
|
||||
.enumerate()
|
||||
.fold(query.to_string(), |acc, (i, p)| {
|
||||
str::replace(&acc, &format!("${}", i), &p.to_sql())
|
||||
});
|
||||
|
||||
let res = self.client.execute(stmt.as_str(), &[])?;
|
||||
Ok(res)
|
||||
}
|
||||
|
||||
fn query<'b, OutputItem>(
|
||||
&mut self,
|
||||
query: &str,
|
||||
params: &'b [&'b dyn ToSql],
|
||||
) -> StdResult<Vec<OutputItem>>
|
||||
where
|
||||
OutputItem: ?Sized + TryFromSql<Self::QueryResultRow>,
|
||||
{
|
||||
let stmt = params
|
||||
.iter()
|
||||
.enumerate()
|
||||
.fold(query.to_string(), |acc, (i, p)| {
|
||||
str::replace(&acc, &format!("${}", i), &p.to_sql())
|
||||
});
|
||||
|
||||
let res: Self::QueryResult = self.client.query(stmt.as_str(), &[])?;
|
||||
|
||||
let res = res
|
||||
.into_iter()
|
||||
.map(OutputItem::try_from_sql)
|
||||
.collect::<Result<Vec<OutputItem>, _>>()?;
|
||||
|
||||
Ok(res)
|
||||
}
|
||||
}
|
||||
|
||||
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())
|
||||
}
|
||||
}
|
||||
|
||||
impl TryFromSql<postgres::Row> for String {
|
||||
fn try_from_sql(row: postgres::Row) -> StdResult<Self> {
|
||||
let res: String = row.get(0);
|
||||
Ok(res)
|
||||
}
|
||||
}
|
|
@ -3,6 +3,7 @@
|
|||
mod commands;
|
||||
mod config;
|
||||
mod database;
|
||||
mod databases;
|
||||
mod error;
|
||||
mod migration;
|
||||
mod opts;
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
use crate::database::{DatabaseConnection, PostgresConnection};
|
||||
use crate::database::DatabaseConnection;
|
||||
use crate::path::PathBuilder;
|
||||
use crate::StdResult;
|
||||
use std::fs;
|
||||
|
@ -51,7 +51,7 @@ impl Migration {
|
|||
}
|
||||
|
||||
pub struct MigrationManager<Conn: DatabaseConnection> {
|
||||
conn: Conn,
|
||||
pub(crate) conn: Conn,
|
||||
}
|
||||
|
||||
impl<Conn: DatabaseConnection> MigrationManager<Conn> {
|
||||
|
@ -129,23 +129,6 @@ pub trait MigrationNames {
|
|||
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],
|
||||
|
|
Reference in a new issue