2021-02-13 23:44:41 +03:00
|
|
|
use crate::config::Config;
|
|
|
|
use crate::StdResult;
|
2021-01-31 14:49:34 +03:00
|
|
|
use postgres::{Client, Error, NoTls};
|
2021-02-13 23:44:41 +03:00
|
|
|
use std::convert::TryFrom;
|
2021-01-31 13:39:00 +03:00
|
|
|
|
2021-02-14 12:10:12 +03:00
|
|
|
pub struct PostgresConnection {
|
2021-02-13 23:44:41 +03:00
|
|
|
client: Client,
|
2021-01-31 13:39:00 +03:00
|
|
|
}
|
|
|
|
|
2021-02-14 12:10:12 +03:00
|
|
|
impl TryFrom<&Config> for PostgresConnection {
|
2021-02-13 23:44:41 +03:00
|
|
|
type Error = Box<dyn std::error::Error>;
|
|
|
|
|
|
|
|
fn try_from(config: &Config) -> Result<Self, Self::Error> {
|
2021-02-14 12:10:12 +03:00
|
|
|
PostgresConnection::open(&config.database_connection_string()?)
|
2021-02-13 23:44:41 +03:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-02-14 12:10:12 +03:00
|
|
|
impl PostgresConnection {
|
|
|
|
pub fn open(connection_string: &str) -> StdResult<PostgresConnection> {
|
2021-02-13 23:44:41 +03:00
|
|
|
let client = Client::connect(connection_string, NoTls)?;
|
2021-02-14 12:10:12 +03:00
|
|
|
Ok(PostgresConnection { client })
|
2021-02-13 23:44:41 +03:00
|
|
|
}
|
2021-01-31 13:39:00 +03:00
|
|
|
}
|
2021-02-06 01:22:00 +03:00
|
|
|
|
2021-02-08 23:39:22 +03:00
|
|
|
pub fn is_migrations_table_not_found(e: &Error) -> bool {
|
2021-02-06 01:22:00 +03:00
|
|
|
e.to_string()
|
|
|
|
.contains(r#"relation "migrations" does not exist"#)
|
|
|
|
}
|
|
|
|
|
2021-02-14 12:10:12 +03:00
|
|
|
impl PostgresConnection {
|
2021-02-13 23:44:41 +03:00
|
|
|
pub fn apply_sql(&mut self, sql_content: &str) -> Result<(), Error> {
|
|
|
|
self.client.batch_execute(sql_content)
|
|
|
|
}
|
2021-02-06 01:22:00 +03:00
|
|
|
|
2021-02-13 23:44:41 +03:00
|
|
|
pub fn applied_migration_names(&mut self) -> Result<Vec<String>, Error> {
|
|
|
|
let res = self
|
|
|
|
.client
|
|
|
|
.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)
|
|
|
|
}
|
|
|
|
})?;
|
2021-02-06 01:22:00 +03:00
|
|
|
|
2021-02-13 23:44:41 +03:00
|
|
|
Ok(res.into_iter().map(|row| row.get(0)).collect())
|
|
|
|
}
|
|
|
|
|
|
|
|
pub fn create_migrations_table(&mut self) -> Result<(), Error> {
|
|
|
|
self.apply_sql(
|
|
|
|
r#"CREATE TABLE IF NOT EXISTS migrations (
|
|
|
|
id serial PRIMARY KEY,
|
|
|
|
name text NOT NULL UNIQUE
|
|
|
|
)"#,
|
|
|
|
)
|
|
|
|
}
|
|
|
|
|
|
|
|
pub fn insert_migration_info(&mut self, name: &str) -> Result<u64, Error> {
|
|
|
|
self.client
|
|
|
|
.execute("INSERT INTO migrations (name) VALUES ($1)", &[&name])
|
|
|
|
}
|
2021-02-06 01:37:30 +03:00
|
|
|
|
2021-02-13 23:44:41 +03:00
|
|
|
pub fn delete_migration_info(&mut self, name: &str) -> Result<u64, Error> {
|
|
|
|
self.client
|
|
|
|
.execute("DELETE FROM migrations WHERE name = $1", &[&name])
|
|
|
|
}
|
2021-02-06 01:37:30 +03:00
|
|
|
}
|