sqlx_migrator/operation.rs
1//! Module for defining the [`Operation`] trait
2//!
3//! This module provides the [`Operation`] trait, allowing users to define
4//! database operations that can be executed as part of a migration process.
5//! These operations can be applied (`up`) or optionally reverted (`down`).
6#![cfg_attr(
7 feature = "sqlite",
8 doc = "
9To create own operation implement trait for type
10
11### Example
12```rust,no_run
13use sqlx_migrator::error::Error;
14use sqlx_migrator::operation::Operation;
15use sqlx::Sqlite;
16
17struct ExampleOperation;
18
19#[async_trait::async_trait]
20impl Operation<Sqlite> for ExampleOperation {
21 async fn up(
22 &self,
23 connection: &mut sqlx::SqliteConnection,
24 ) -> Result<(), Error> {
25 // Do some operations
26 Ok(())
27 }
28
29 // By default operation is irreversible and cannot be reversed if you want to support
30 // reverse of migration than add down function as well
31 async fn down(
32 &self,
33 connection: &mut sqlx::SqliteConnection,
34 ) -> Result<(), Error> {
35 // Do some operations
36 Ok(())
37 }
38}
39```
40"
41)]
42
43use sqlx::Database;
44
45use crate::error::Error;
46
47/// Trait for defining a database operation.
48///
49/// An Operation represents action that can be applied to or reverted from a
50/// database during a migration. Each operation can have an up method for
51/// applying the change and an optional down method for rolling it back.
52///
53/// Operations can also specify whether they are destructible meaning that they
54/// require user confirmation before being applied, due to potential data loss
55/// or irreversible changes
56#[async_trait::async_trait]
57pub trait Operation<DB>: Send + Sync
58where
59 DB: Database,
60{
61 /// The up method executes the operation when applying the migration.
62 ///
63 /// This method is called when the migration is being applied to the
64 /// database. Implement this method to define the changes you want to
65 /// apply.
66 async fn up(&self, connection: &mut <DB as Database>::Connection) -> Result<(), Error>;
67
68 /// The down method reverses the operation when rolling back the
69 /// migration.
70 ///
71 /// This method is called when the migration is being rolled back. Implement
72 /// this method if you want to make the operation reversible. If not
73 /// implemented, the operation is considered irreversible.
74 async fn down(&self, connection: &mut <DB as Database>::Connection) -> Result<(), Error> {
75 let _connection = connection;
76 return Err(Error::IrreversibleOperation);
77 }
78
79 /// Indicates whether the `up` operation is destructible.
80 ///
81 /// If the operation is destructible, the user will be prompted for
82 /// confirmation before running the migration via the CLI, due to the
83 /// potential for data loss or irreversible changes. By default, `up`
84 /// operations are considered non-destructible. Note that `down` operations
85 /// are always considered destructible and cannot be changed.
86 fn is_destructible(&self) -> bool {
87 false
88 }
89}
90
91#[async_trait::async_trait]
92impl<DB, U, D> Operation<DB> for (U, D)
93where
94 DB: Database,
95 U: AsRef<str> + Send + Sync,
96 D: AsRef<str> + Send + Sync,
97 for<'c> &'c mut <DB as Database>::Connection: sqlx::Executor<'c, Database = DB>,
98 for<'q> <DB as Database>::Arguments<'q>: sqlx::IntoArguments<'q, DB>,
99{
100 async fn up(&self, connection: &mut <DB as Database>::Connection) -> Result<(), Error> {
101 sqlx::query(self.0.as_ref())
102 .execute(connection)
103 .await
104 .map_err(Error::from)?;
105 Ok(())
106 }
107
108 async fn down(&self, connection: &mut <DB as Database>::Connection) -> Result<(), Error> {
109 sqlx::query(self.1.as_ref())
110 .execute(connection)
111 .await
112 .map_err(Error::from)?;
113 Ok(())
114 }
115}