chore: add support transactional ddl for client
I didn't know that mysql doesn't support transactional ddl. It means that we cannot create table, alter table and etc. in transaction. At the moment migra supports only postgres client, that can be use transaction for ddl.
This commit is contained in:
parent
f98dd4f0c8
commit
7ae5eec2c3
12 changed files with 27 additions and 74 deletions
|
@ -10,7 +10,7 @@ pub struct MySqlConnection {
|
||||||
|
|
||||||
impl OpenDatabaseConnection for MySqlConnection {
|
impl OpenDatabaseConnection for MySqlConnection {
|
||||||
fn open(connection_string: &str) -> StdResult<Self> {
|
fn open(connection_string: &str) -> StdResult<Self> {
|
||||||
let pool = Pool::new(connection_string)?;
|
let pool = Pool::new_manual(1, 1, connection_string)?;
|
||||||
let conn = pool.get_conn()?;
|
let conn = pool.get_conn()?;
|
||||||
Ok(MySqlConnection { conn })
|
Ok(MySqlConnection { conn })
|
||||||
}
|
}
|
||||||
|
@ -25,6 +25,8 @@ impl DatabaseStatements for MySqlConnection {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl SupportsTransactionalDDL for MySqlConnection {}
|
||||||
|
|
||||||
impl DatabaseConnection for MySqlConnection {
|
impl DatabaseConnection for MySqlConnection {
|
||||||
fn batch_execute(&mut self, query: &str) -> StdResult<()> {
|
fn batch_execute(&mut self, query: &str) -> StdResult<()> {
|
||||||
self.conn.query_drop(query)?;
|
self.conn.query_drop(query)?;
|
||||||
|
|
|
@ -23,6 +23,13 @@ impl DatabaseStatements for PostgresConnection {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl SupportsTransactionalDDL for PostgresConnection {
|
||||||
|
#[inline]
|
||||||
|
fn supports_transactional_ddl(&self) -> bool {
|
||||||
|
true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl DatabaseConnection for PostgresConnection {
|
impl DatabaseConnection for PostgresConnection {
|
||||||
fn batch_execute(&mut self, query: &str) -> StdResult<()> {
|
fn batch_execute(&mut self, query: &str) -> StdResult<()> {
|
||||||
self.client.batch_execute(query)?;
|
self.client.batch_execute(query)?;
|
||||||
|
|
|
@ -13,7 +13,14 @@ pub trait DatabaseStatements {
|
||||||
fn create_migration_table_stmt(&self) -> &'static str;
|
fn create_migration_table_stmt(&self) -> &'static str;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub trait DatabaseConnection: DatabaseStatements {
|
pub trait SupportsTransactionalDDL {
|
||||||
|
#[inline]
|
||||||
|
fn supports_transactional_ddl(&self) -> bool {
|
||||||
|
false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub trait DatabaseConnection: DatabaseStatements + SupportsTransactionalDDL {
|
||||||
fn batch_execute(&mut self, query: &str) -> StdResult<()>;
|
fn batch_execute(&mut self, query: &str) -> StdResult<()>;
|
||||||
|
|
||||||
fn execute<'b>(&mut self, query: &str, params: ToSqlParams<'b>) -> StdResult<u64>;
|
fn execute<'b>(&mut self, query: &str, params: ToSqlParams<'b>) -> StdResult<u64>;
|
||||||
|
|
|
@ -9,6 +9,7 @@ pub mod prelude {
|
||||||
pub use super::adapter::{ToSql, ToSqlParams, TryFromSql};
|
pub use super::adapter::{ToSql, ToSqlParams, TryFromSql};
|
||||||
pub use super::connection::{
|
pub use super::connection::{
|
||||||
AnyConnection, DatabaseConnection, DatabaseStatements, OpenDatabaseConnection,
|
AnyConnection, DatabaseConnection, DatabaseStatements, OpenDatabaseConnection,
|
||||||
|
SupportsTransactionalDDL,
|
||||||
};
|
};
|
||||||
pub use super::migration::ManageMigration;
|
pub use super::migration::ManageMigration;
|
||||||
pub use super::transaction::ManageTransaction;
|
pub use super::transaction::ManageTransaction;
|
||||||
|
|
|
@ -48,14 +48,14 @@ where
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn maybe_with_transaction<TrxFnMut, Res>(
|
pub fn maybe_with_transaction<TrxFnMut, Res>(
|
||||||
with: bool,
|
is_needed: bool,
|
||||||
conn: &mut AnyConnection,
|
conn: &mut AnyConnection,
|
||||||
trx_fn: &mut TrxFnMut,
|
trx_fn: &mut TrxFnMut,
|
||||||
) -> StdResult<Res>
|
) -> StdResult<Res>
|
||||||
where
|
where
|
||||||
TrxFnMut: FnMut(&mut AnyConnection) -> StdResult<Res>,
|
TrxFnMut: FnMut(&mut AnyConnection) -> StdResult<Res>,
|
||||||
{
|
{
|
||||||
if with {
|
if is_needed && conn.supports_transactional_ddl() {
|
||||||
with_transaction(conn, trx_fn)
|
with_transaction(conn, trx_fn)
|
||||||
} else {
|
} else {
|
||||||
trx_fn(conn)
|
trx_fn(conn)
|
||||||
|
|
|
@ -481,22 +481,6 @@ mod upgrade {
|
||||||
Ok(())
|
Ok(())
|
||||||
})?;
|
})?;
|
||||||
|
|
||||||
#[cfg(feature = "mysql")]
|
|
||||||
inner("mysql_invalid", || {
|
|
||||||
use mysql::prelude::*;
|
|
||||||
|
|
||||||
let pool = mysql::Pool::new(MYSQL_URL)?;
|
|
||||||
let mut conn = pool.get_conn()?;
|
|
||||||
|
|
||||||
let articles_res = conn.query_drop("SELECT a.id FROM articles AS a");
|
|
||||||
let persons_res = conn.query_drop("SELECT p.id FROM persons AS p");
|
|
||||||
|
|
||||||
assert!(articles_res.is_ok());
|
|
||||||
assert!(persons_res.is_err());
|
|
||||||
|
|
||||||
Ok(())
|
|
||||||
})?;
|
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -533,23 +517,6 @@ mod upgrade {
|
||||||
Ok(())
|
Ok(())
|
||||||
})?;
|
})?;
|
||||||
|
|
||||||
// TODO: Need to investigate how fix single transaction for Mysql
|
|
||||||
// #[cfg(feature = "mysql")]
|
|
||||||
// inner("mysql_invalid", || {
|
|
||||||
// use mysql::prelude::*;
|
|
||||||
|
|
||||||
// let pool = mysql::Pool::new(MYSQL_URL)?;
|
|
||||||
// let mut conn = pool.get_conn()?;
|
|
||||||
|
|
||||||
// let articles_res = conn.query_drop("SELECT a.id FROM articles AS a");
|
|
||||||
// let persons_res = conn.query_drop("SELECT p.id FROM persons AS p");
|
|
||||||
|
|
||||||
// assert!(articles_res.is_err());
|
|
||||||
// assert!(persons_res.is_err());
|
|
||||||
|
|
||||||
// Ok(())
|
|
||||||
// })?;
|
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,4 +0,0 @@
|
||||||
root = "./mysql_invalid"
|
|
||||||
|
|
||||||
[database]
|
|
||||||
connection = "mysql://mysql:mysql@localhost:6001/migra_tests"
|
|
|
@ -1,3 +0,0 @@
|
||||||
-- This file should undo anything in `up.sql`
|
|
||||||
|
|
||||||
DROP TABLE articles;
|
|
|
@ -1,8 +0,0 @@
|
||||||
-- Your SQL goes here
|
|
||||||
|
|
||||||
CREATE TABLE articles (
|
|
||||||
id int AUTO_INCREMENT PRIMARY KEY,
|
|
||||||
title text NOT NULL CHECK (length(title) > 0),
|
|
||||||
content text NOT NULL,
|
|
||||||
created_at timestamp NOT NULL DEFAULT current_timestamp
|
|
||||||
);
|
|
|
@ -1,6 +0,0 @@
|
||||||
-- This file should undo anything in `up.sql`
|
|
||||||
|
|
||||||
ALTER TABLE articles
|
|
||||||
DROP COLUMN author_person_id;
|
|
||||||
|
|
||||||
DROP TABLE persons;
|
|
|
@ -1,12 +0,0 @@
|
||||||
-- Your SQL goes here
|
|
||||||
|
|
||||||
CREATE TABLE persons (
|
|
||||||
id int AUTO_INCREMENT PRIMARY KEY
|
|
||||||
email varchar(256) NOT NULL UNIQUE
|
|
||||||
display_name text NOT NULL
|
|
||||||
created_at timestamp NOT NULL DEFAULT current_timestamp
|
|
||||||
);
|
|
||||||
|
|
||||||
ALTER TABLE articles
|
|
||||||
ADD COLUMN author_person_id int NULL
|
|
||||||
REFERENCES persons (id) ON UPDATE CASCADE ON DELETE CASCADE;
|
|
|
@ -1,12 +1,14 @@
|
||||||
-- Your SQL goes here
|
-- Your SQL goes here
|
||||||
|
|
||||||
CREATE TABLE persons (
|
CREATE TABLE persons (
|
||||||
id SERIAL PRIMARY KEY
|
id SERIAL PRIMARY KEY,
|
||||||
email text NOT NULL UNIQUE
|
email text NOT NULL UNIQUE,
|
||||||
display_name text NOT NULL
|
display_name text NOT NULL,
|
||||||
created_at timestamp NOT NULL DEFAULT current_timestamp
|
created_at timestamp NOT NULL DEFAULT current_timestamp
|
||||||
);
|
);
|
||||||
|
|
||||||
ALTER TABLE articles
|
/* This table doesn't exist
|
||||||
|
↓↓↓↓↓↓↓ */
|
||||||
|
ALTER TABLE recipes
|
||||||
ADD COLUMN author_person_id int NULL
|
ADD COLUMN author_person_id int NULL
|
||||||
REFERENCES persons (id) ON UPDATE CASCADE ON DELETE CASCADE;
|
REFERENCES persons (id) ON UPDATE CASCADE ON DELETE CASCADE;
|
||||||
|
|
Reference in a new issue