1use crate::backend::Backend;
4use crate::connection::{BoxableConnection, Connection};
5use crate::deserialize::{FromSql, FromSqlRow};
6use crate::expression::AsExpression;
7use crate::result::QueryResult;
8use crate::serialize::ToSql;
9use crate::sql_types::Text;
10use std::borrow::Cow;
11use std::error::Error;
12use std::fmt::Display;
13
14pub type Result<T> = std::result::Result<T, Box<dyn Error + Send + Sync>>;
17
18#[derive(#[automatically_derived]
impl<'a> ::core::fmt::Debug for MigrationVersion<'a> {
#[inline]
fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
::core::fmt::Formatter::debug_tuple_field1_finish(f,
"MigrationVersion", &&self.0)
}
}Debug, #[automatically_derived]
impl<'a> ::core::hash::Hash for MigrationVersion<'a> {
#[inline]
fn hash<__H: ::core::hash::Hasher>(&self, state: &mut __H) -> () {
::core::hash::Hash::hash(&self.0, state)
}
}Hash, #[automatically_derived]
impl<'a> ::core::cmp::PartialEq for MigrationVersion<'a> {
#[inline]
fn eq(&self, other: &MigrationVersion<'a>) -> bool { self.0 == other.0 }
}PartialEq, #[automatically_derived]
impl<'a> ::core::cmp::Eq for MigrationVersion<'a> {
#[inline]
#[doc(hidden)]
#[coverage(off)]
fn assert_receiver_is_total_eq(&self) -> () {
let _: ::core::cmp::AssertParamIsEq<Cow<'a, str>>;
}
}Eq, #[automatically_derived]
impl<'a> ::core::cmp::PartialOrd for MigrationVersion<'a> {
#[inline]
fn partial_cmp(&self, other: &MigrationVersion<'a>)
-> ::core::option::Option<::core::cmp::Ordering> {
::core::cmp::PartialOrd::partial_cmp(&self.0, &other.0)
}
}PartialOrd, #[automatically_derived]
impl<'a> ::core::cmp::Ord for MigrationVersion<'a> {
#[inline]
fn cmp(&self, other: &MigrationVersion<'a>) -> ::core::cmp::Ordering {
::core::cmp::Ord::cmp(&self.0, &other.0)
}
}Ord, const _: () =
{
use diesel;
impl<'a, __DB, __ST> diesel::deserialize::Queryable<__ST, __DB> for
MigrationVersion<'a> where __DB: diesel::backend::Backend,
__ST: diesel::sql_types::SingleValue,
Self: diesel::deserialize::FromSql<__ST, __DB> {
type Row = Self;
fn build(row: Self) -> diesel::deserialize::Result<Self> {
diesel::deserialize::Result::Ok(row)
}
}
};FromSqlRow, const _: () =
{
use diesel;
impl<'a, '__expr> diesel::expression::AsExpression<Text> for
&'__expr MigrationVersion<'a> {
type Expression =
diesel::internal::derives::as_expression::Bound<Text, Self>;
fn as_expression(self)
->
<Self as
diesel::expression::AsExpression<Text>>::Expression {
diesel::internal::derives::as_expression::Bound::new(self)
}
}
impl<'a, '__expr>
diesel::expression::AsExpression<diesel::sql_types::Nullable<Text>>
for &'__expr MigrationVersion<'a> {
type Expression =
diesel::internal::derives::as_expression::Bound<diesel::sql_types::Nullable<Text>,
Self>;
fn as_expression(self)
->
<Self as
diesel::expression::AsExpression<diesel::sql_types::Nullable<Text>>>::Expression {
diesel::internal::derives::as_expression::Bound::new(self)
}
}
impl<'a, '__expr, '__expr2> diesel::expression::AsExpression<Text> for
&'__expr2 &'__expr MigrationVersion<'a> {
type Expression =
diesel::internal::derives::as_expression::Bound<Text, Self>;
fn as_expression(self)
->
<Self as
diesel::expression::AsExpression<Text>>::Expression {
diesel::internal::derives::as_expression::Bound::new(self)
}
}
impl<'a, '__expr, '__expr2>
diesel::expression::AsExpression<diesel::sql_types::Nullable<Text>>
for &'__expr2 &'__expr MigrationVersion<'a> {
type Expression =
diesel::internal::derives::as_expression::Bound<diesel::sql_types::Nullable<Text>,
Self>;
fn as_expression(self)
->
<Self as
diesel::expression::AsExpression<diesel::sql_types::Nullable<Text>>>::Expression {
diesel::internal::derives::as_expression::Bound::new(self)
}
}
impl<'a, __DB>
diesel::serialize::ToSql<diesel::sql_types::Nullable<Text>, __DB>
for MigrationVersion<'a> where __DB: diesel::backend::Backend,
Self: diesel::serialize::ToSql<Text, __DB> {
fn to_sql<'__b>(&'__b self,
out: &mut diesel::serialize::Output<'__b, '_, __DB>)
-> diesel::serialize::Result {
diesel::serialize::ToSql::<Text, __DB>::to_sql(self, out)
}
}
impl<'a> diesel::expression::AsExpression<Text> for
MigrationVersion<'a> {
type Expression =
diesel::internal::derives::as_expression::Bound<Text, Self>;
fn as_expression(self)
->
<Self as
diesel::expression::AsExpression<Text>>::Expression {
diesel::internal::derives::as_expression::Bound::new(self)
}
}
impl<'a>
diesel::expression::AsExpression<diesel::sql_types::Nullable<Text>>
for MigrationVersion<'a> {
type Expression =
diesel::internal::derives::as_expression::Bound<diesel::sql_types::Nullable<Text>,
Self>;
fn as_expression(self)
->
<Self as
diesel::expression::AsExpression<diesel::sql_types::Nullable<Text>>>::Expression {
diesel::internal::derives::as_expression::Bound::new(self)
}
}
};AsExpression)]
24#[diesel(sql_type = Text)]
25pub struct MigrationVersion<'a>(Cow<'a, str>);
26
27impl MigrationVersion<'_> {
28 pub fn as_owned(&self) -> MigrationVersion<'static> {
31 MigrationVersion(Cow::Owned(self.0.as_ref().to_owned()))
32 }
33}
34
35impl<DB> FromSql<Text, DB> for MigrationVersion<'_>
36where
37 String: FromSql<Text, DB>,
38 DB: Backend,
39{
40 fn from_sql(bytes: DB::RawValue<'_>) -> crate::deserialize::Result<Self> {
41 let s = String::from_sql(bytes)?;
42 Ok(Self(Cow::Owned(s)))
43 }
44}
45
46impl<'a, DB> ToSql<Text, DB> for MigrationVersion<'a>
47where
48 Cow<'a, str>: ToSql<Text, DB>,
49 DB: Backend,
50{
51 fn to_sql<'b>(
52 &'b self,
53 out: &mut crate::serialize::Output<'b, '_, DB>,
54 ) -> crate::serialize::Result {
55 self.0.to_sql(out)
56 }
57}
58
59impl From<String> for MigrationVersion<'_> {
60 fn from(s: String) -> Self {
61 MigrationVersion(Cow::Owned(s))
62 }
63}
64
65impl<'a> From<&'a str> for MigrationVersion<'a> {
66 fn from(s: &'a str) -> Self {
67 MigrationVersion(Cow::Borrowed(s))
68 }
69}
70
71impl<'a> From<&'a String> for MigrationVersion<'a> {
72 fn from(s: &'a String) -> Self {
73 MigrationVersion(Cow::Borrowed(s))
74 }
75}
76
77impl Display for MigrationVersion<'_> {
78 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
79 f.write_str(self.0.as_ref())
80 }
81}
82
83pub trait MigrationName: Display {
90 fn version(&self) -> MigrationVersion<'_>;
92}
93
94pub trait Migration<DB: Backend> {
96 fn run(&self, conn: &mut dyn BoxableConnection<DB>) -> Result<()>;
98
99 fn revert(&self, conn: &mut dyn BoxableConnection<DB>) -> Result<()>;
101
102 fn metadata(&self) -> &dyn MigrationMetadata;
104
105 fn name(&self) -> &dyn MigrationName;
112}
113
114pub trait MigrationMetadata {
123 fn run_in_transaction(&self) -> bool {
131 true
132 }
133}
134
135pub trait MigrationSource<DB: Backend> {
138 fn migrations(&self) -> Result<Vec<Box<dyn Migration<DB>>>>;
141}
142
143impl<DB: Backend> Migration<DB> for Box<dyn Migration<DB> + '_> {
144 fn run(&self, conn: &mut dyn BoxableConnection<DB>) -> Result<()> {
145 (**self).run(conn)
146 }
147
148 fn revert(&self, conn: &mut dyn BoxableConnection<DB>) -> Result<()> {
149 (**self).revert(conn)
150 }
151
152 fn metadata(&self) -> &dyn MigrationMetadata {
153 (**self).metadata()
154 }
155
156 fn name(&self) -> &dyn MigrationName {
157 (**self).name()
158 }
159}
160
161impl<DB: Backend> Migration<DB> for &dyn Migration<DB> {
162 fn run(&self, conn: &mut dyn BoxableConnection<DB>) -> Result<()> {
163 (**self).run(conn)
164 }
165
166 fn revert(&self, conn: &mut dyn BoxableConnection<DB>) -> Result<()> {
167 (**self).revert(conn)
168 }
169
170 fn metadata(&self) -> &dyn MigrationMetadata {
171 (**self).metadata()
172 }
173
174 fn name(&self) -> &dyn MigrationName {
175 (**self).name()
176 }
177}
178
179pub const CREATE_MIGRATIONS_TABLE: &str = "CREATE TABLE IF NOT EXISTS __diesel_schema_migrations (\n version VARCHAR(50) PRIMARY KEY NOT NULL,\n run_on TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP\n);\n"include_str!("setup_migration_table.sql");
182
183pub trait MigrationConnection: Connection {
187 fn setup(&mut self) -> QueryResult<usize>;
199}
200
201#[cfg(feature = "postgres")]
202impl MigrationConnection for crate::pg::PgConnection {
203 fn setup(&mut self) -> QueryResult<usize> {
204 use crate::RunQueryDsl;
205 crate::sql_query(CREATE_MIGRATIONS_TABLE).execute(self)
206 }
207}
208
209#[cfg(feature = "mysql")]
210impl MigrationConnection for crate::mysql::MysqlConnection {
211 fn setup(&mut self) -> QueryResult<usize> {
212 use crate::RunQueryDsl;
213 crate::sql_query(CREATE_MIGRATIONS_TABLE).execute(self)
214 }
215}
216
217#[cfg(feature = "sqlite")]
218impl MigrationConnection for crate::sqlite::SqliteConnection {
219 fn setup(&mut self) -> QueryResult<usize> {
220 use crate::RunQueryDsl;
221 crate::sql_query(CREATE_MIGRATIONS_TABLE).execute(self)
222 }
223}