#![cfg_attr(
feature = "sqlite",
doc = "
To create own operation implement trait for type
### Example
```rust,no_run
use sqlx_migrator::error::Error;
use sqlx_migrator::operation::Operation;
use sqlx::Sqlite;
struct ExampleOperation;
#[async_trait::async_trait]
impl Operation<Sqlite> for ExampleOperation {
async fn up(
&self,
connection: &mut sqlx::SqliteConnection,
) -> Result<(), Error> {
// Do some operations
Ok(())
}
// By default operation is irreversible and cannot be reversed if you want to support
// reverse of migration than add down function as well
async fn down(
&self,
connection: &mut sqlx::SqliteConnection,
) -> Result<(), Error> {
// Do some operations
Ok(())
}
}
```
"
)]
use sqlx::{AssertSqlSafe, Database};
use crate::error::Error;
#[async_trait::async_trait]
pub trait Operation<DB>: Send + Sync
where
DB: Database,
{
async fn up(&self, connection: &mut <DB as Database>::Connection) -> Result<(), Error>;
async fn down(&self, _connection: &mut <DB as Database>::Connection) -> Result<(), Error> {
Err(Error::IrreversibleOperation)
}
fn is_destructible(&self) -> bool {
false
}
}
#[async_trait::async_trait]
impl<DB, U, D> Operation<DB> for (U, D)
where
DB: Database,
U: AsRef<str> + Send + Sync,
D: AsRef<str> + Send + Sync,
<DB as Database>::Arguments: sqlx::IntoArguments<DB>,
for<'c> &'c mut <DB as Database>::Connection: sqlx::Executor<'c, Database = DB>,
{
async fn up(&self, connection: &mut <DB as Database>::Connection) -> Result<(), Error> {
let query = self.0.as_ref().to_string();
sqlx::query(AssertSqlSafe(query))
.execute(connection)
.await
.map_err(Error::from)?;
Ok(())
}
async fn down(&self, connection: &mut <DB as Database>::Connection) -> Result<(), Error> {
let query = self.1.as_ref().to_string();
sqlx::query(AssertSqlSafe(query))
.execute(connection)
.await
.map_err(Error::from)?;
Ok(())
}
}