⬆️ Upgrade to sea-orm 0.12.8
This commit is contained in:
parent
cf335081f7
commit
02be4264d0
5 changed files with 130 additions and 34 deletions
|
|
@ -15,7 +15,7 @@
|
||||||
[SeaQuery](https://github.com/SeaQL/sea-query) para interactuar con bases de datos. Sin embargo,
|
[SeaQuery](https://github.com/SeaQL/sea-query) para interactuar con bases de datos. Sin embargo,
|
||||||
para restringir las migraciones a módulos, se ha integrado en el código una versión modificada de
|
para restringir las migraciones a módulos, se ha integrado en el código una versión modificada de
|
||||||
[SeaORM Migration](https://github.com/SeaQL/sea-orm/tree/master/sea-orm-migration) (versión
|
[SeaORM Migration](https://github.com/SeaQL/sea-orm/tree/master/sea-orm-migration) (versión
|
||||||
[0.11.3](https://github.com/SeaQL/sea-orm/tree/0.11.3/sea-orm-migration/src)).
|
[0.12.8](https://github.com/SeaQL/sea-orm/tree/0.12.8/sea-orm-migration/src)).
|
||||||
|
|
||||||
|
|
||||||
# 🗚 FIGfonts
|
# 🗚 FIGfonts
|
||||||
|
|
|
||||||
|
|
@ -70,13 +70,13 @@ version = "0.3.29"
|
||||||
optional = true
|
optional = true
|
||||||
|
|
||||||
[dependencies.sea-orm]
|
[dependencies.sea-orm]
|
||||||
version = "0.11.3"
|
version = "0.12.8"
|
||||||
features = ["debug-print", "macros", "runtime-async-std-native-tls"]
|
features = ["debug-print", "macros", "runtime-async-std-native-tls"]
|
||||||
default-features = false
|
default-features = false
|
||||||
optional = true
|
optional = true
|
||||||
|
|
||||||
[dependencies.sea-schema]
|
[dependencies.sea-schema]
|
||||||
version = "0.11.0"
|
version = "0.14.1"
|
||||||
optional = true
|
optional = true
|
||||||
|
|
||||||
[build-dependencies]
|
[build-dependencies]
|
||||||
|
|
|
||||||
|
|
@ -136,4 +136,25 @@ impl<'c> SchemaManager<'c> {
|
||||||
|
|
||||||
res.try_get("", "has_column")
|
res.try_get("", "has_column")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub async fn has_index<T, I>(&self, table: T, index: I) -> Result<bool, DbErr>
|
||||||
|
where
|
||||||
|
T: AsRef<str>,
|
||||||
|
I: AsRef<str>,
|
||||||
|
{
|
||||||
|
let stmt = match self.conn.get_database_backend() {
|
||||||
|
DbBackend::MySql => MySql::has_index(table, index),
|
||||||
|
DbBackend::Postgres => Postgres::has_index(table, index),
|
||||||
|
DbBackend::Sqlite => Sqlite::has_index(table, index),
|
||||||
|
};
|
||||||
|
|
||||||
|
let builder = self.conn.get_database_backend();
|
||||||
|
let res = self
|
||||||
|
.conn
|
||||||
|
.query_one(builder.build(&stmt))
|
||||||
|
.await?
|
||||||
|
.ok_or_else(|| DbErr::Custom("Failed to check index exists".to_owned()))?;
|
||||||
|
|
||||||
|
res.try_get("", "has_index")
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -6,18 +6,19 @@ use std::time::SystemTime;
|
||||||
use tracing::info;
|
use tracing::info;
|
||||||
|
|
||||||
use sea_orm::sea_query::{
|
use sea_orm::sea_query::{
|
||||||
self, extension::postgres::Type, Alias, Expr, ForeignKey, Iden, JoinType, Query,
|
self, extension::postgres::Type, Alias, Expr, ForeignKey, IntoIden, JoinType, Order, Query,
|
||||||
SelectStatement, SimpleExpr, Table,
|
SelectStatement, SimpleExpr, Table,
|
||||||
};
|
};
|
||||||
use sea_orm::{
|
use sea_orm::{
|
||||||
ActiveModelTrait, ActiveValue, ColumnTrait, Condition, ConnectionTrait, DbBackend, DbErr,
|
ActiveModelTrait, ActiveValue, Condition, ConnectionTrait, DbBackend, DbErr, DeriveIden,
|
||||||
EntityTrait, QueryFilter, QueryOrder, Schema, Statement, TransactionTrait,
|
DynIden, EntityTrait, FromQueryResult, Iterable, QueryFilter, Schema, Statement,
|
||||||
|
TransactionTrait,
|
||||||
};
|
};
|
||||||
use sea_schema::{mysql::MySql, postgres::Postgres, probe::SchemaProbe, sqlite::Sqlite};
|
use sea_schema::{mysql::MySql, postgres::Postgres, probe::SchemaProbe, sqlite::Sqlite};
|
||||||
|
|
||||||
use super::{seaql_migrations, IntoSchemaManagerConnection, MigrationTrait, SchemaManager};
|
use super::{seaql_migrations, IntoSchemaManagerConnection, MigrationTrait, SchemaManager};
|
||||||
|
|
||||||
#[derive(Debug, PartialEq, Eq)]
|
#[derive(Copy, Clone, Debug, PartialEq, Eq)]
|
||||||
/// Status of migration
|
/// Status of migration
|
||||||
pub enum MigrationStatus {
|
pub enum MigrationStatus {
|
||||||
/// Not yet applied
|
/// Not yet applied
|
||||||
|
|
@ -26,11 +27,6 @@ pub enum MigrationStatus {
|
||||||
Applied,
|
Applied,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct Migration {
|
|
||||||
migration: Box<dyn MigrationTrait>,
|
|
||||||
status: MigrationStatus,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Display for MigrationStatus {
|
impl Display for MigrationStatus {
|
||||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||||
let status = match self {
|
let status = match self {
|
||||||
|
|
@ -41,12 +37,34 @@ impl Display for MigrationStatus {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub struct Migration {
|
||||||
|
migration: Box<dyn MigrationTrait>,
|
||||||
|
status: MigrationStatus,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Migration {
|
||||||
|
/// Get migration name from MigrationName trait implementation
|
||||||
|
pub fn name(&self) -> &str {
|
||||||
|
self.migration.name()
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Get migration status
|
||||||
|
pub fn status(&self) -> MigrationStatus {
|
||||||
|
self.status
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// Performing migrations on a database
|
/// Performing migrations on a database
|
||||||
#[async_trait::async_trait]
|
#[async_trait::async_trait]
|
||||||
pub trait MigratorTrait: Send {
|
pub trait MigratorTrait: Send {
|
||||||
/// Vector of migrations in time sequence
|
/// Vector of migrations in time sequence
|
||||||
fn migrations() -> Vec<Box<dyn MigrationTrait>>;
|
fn migrations() -> Vec<Box<dyn MigrationTrait>>;
|
||||||
|
|
||||||
|
/// Name of the migration table, it is `seaql_migrations` by default
|
||||||
|
fn migration_table_name() -> DynIden {
|
||||||
|
seaql_migrations::Entity.into_iden()
|
||||||
|
}
|
||||||
|
|
||||||
/// Get list of migrations wrapped in `Migration` struct
|
/// Get list of migrations wrapped in `Migration` struct
|
||||||
fn get_migration_files() -> Vec<Migration> {
|
fn get_migration_files() -> Vec<Migration> {
|
||||||
Self::migrations()
|
Self::migrations()
|
||||||
|
|
@ -64,8 +82,13 @@ pub trait MigratorTrait: Send {
|
||||||
C: ConnectionTrait,
|
C: ConnectionTrait,
|
||||||
{
|
{
|
||||||
Self::install(db).await?;
|
Self::install(db).await?;
|
||||||
seaql_migrations::Entity::find()
|
let stmt = Query::select()
|
||||||
.order_by_asc(seaql_migrations::Column::Version)
|
.table_name(Self::migration_table_name())
|
||||||
|
.columns(seaql_migrations::Column::iter().map(IntoIden::into_iden))
|
||||||
|
.order_by(seaql_migrations::Column::Version, Order::Asc)
|
||||||
|
.to_owned();
|
||||||
|
let builder = db.get_database_backend();
|
||||||
|
seaql_migrations::Model::find_by_statement(builder.build(&stmt))
|
||||||
.all(db)
|
.all(db)
|
||||||
.await
|
.await
|
||||||
}
|
}
|
||||||
|
|
@ -142,7 +165,9 @@ pub trait MigratorTrait: Send {
|
||||||
{
|
{
|
||||||
let builder = db.get_database_backend();
|
let builder = db.get_database_backend();
|
||||||
let schema = Schema::new(builder);
|
let schema = Schema::new(builder);
|
||||||
let mut stmt = schema.create_table_from_entity(seaql_migrations::Entity);
|
let mut stmt = schema
|
||||||
|
.create_table_from_entity(seaql_migrations::Entity)
|
||||||
|
.table_name(Self::migration_table_name());
|
||||||
stmt.if_not_exists();
|
stmt.if_not_exists();
|
||||||
db.execute(builder.build(&stmt)).await.map(|_| ())
|
db.execute(builder.build(&stmt)).await.map(|_| ())
|
||||||
}
|
}
|
||||||
|
|
@ -168,7 +193,7 @@ pub trait MigratorTrait: Send {
|
||||||
where
|
where
|
||||||
C: IntoSchemaManagerConnection<'c>,
|
C: IntoSchemaManagerConnection<'c>,
|
||||||
{
|
{
|
||||||
exec_with_connection::<'_, _, _, Self>(db, move |manager| {
|
exec_with_connection::<'_, _, _>(db, move |manager| {
|
||||||
Box::pin(async move { exec_fresh::<Self>(manager).await })
|
Box::pin(async move { exec_fresh::<Self>(manager).await })
|
||||||
})
|
})
|
||||||
.await
|
.await
|
||||||
|
|
@ -179,7 +204,7 @@ pub trait MigratorTrait: Send {
|
||||||
where
|
where
|
||||||
C: IntoSchemaManagerConnection<'c>,
|
C: IntoSchemaManagerConnection<'c>,
|
||||||
{
|
{
|
||||||
exec_with_connection::<'_, _, _, Self>(db, move |manager| {
|
exec_with_connection::<'_, _, _>(db, move |manager| {
|
||||||
Box::pin(async move {
|
Box::pin(async move {
|
||||||
exec_down::<Self>(manager, None).await?;
|
exec_down::<Self>(manager, None).await?;
|
||||||
exec_up::<Self>(manager, None).await
|
exec_up::<Self>(manager, None).await
|
||||||
|
|
@ -193,7 +218,7 @@ pub trait MigratorTrait: Send {
|
||||||
where
|
where
|
||||||
C: IntoSchemaManagerConnection<'c>,
|
C: IntoSchemaManagerConnection<'c>,
|
||||||
{
|
{
|
||||||
exec_with_connection::<'_, _, _, Self>(db, move |manager| {
|
exec_with_connection::<'_, _, _>(db, move |manager| {
|
||||||
Box::pin(async move { exec_down::<Self>(manager, None).await })
|
Box::pin(async move { exec_down::<Self>(manager, None).await })
|
||||||
})
|
})
|
||||||
.await
|
.await
|
||||||
|
|
@ -204,7 +229,7 @@ pub trait MigratorTrait: Send {
|
||||||
where
|
where
|
||||||
C: IntoSchemaManagerConnection<'c>,
|
C: IntoSchemaManagerConnection<'c>,
|
||||||
{
|
{
|
||||||
exec_with_connection::<'_, _, _, Self>(db, move |manager| {
|
exec_with_connection::<'_, _, _>(db, move |manager| {
|
||||||
Box::pin(async move { exec_up::<Self>(manager, steps).await })
|
Box::pin(async move { exec_up::<Self>(manager, steps).await })
|
||||||
})
|
})
|
||||||
.await
|
.await
|
||||||
|
|
@ -215,21 +240,19 @@ pub trait MigratorTrait: Send {
|
||||||
where
|
where
|
||||||
C: IntoSchemaManagerConnection<'c>,
|
C: IntoSchemaManagerConnection<'c>,
|
||||||
{
|
{
|
||||||
exec_with_connection::<'_, _, _, Self>(db, move |manager| {
|
exec_with_connection::<'_, _, _>(db, move |manager| {
|
||||||
Box::pin(async move { exec_down::<Self>(manager, steps).await })
|
Box::pin(async move { exec_down::<Self>(manager, steps).await })
|
||||||
})
|
})
|
||||||
.await
|
.await
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[allow(clippy::extra_unused_type_parameters)]
|
async fn exec_with_connection<'c, C, F>(db: C, f: F) -> Result<(), DbErr>
|
||||||
async fn exec_with_connection<'c, C, F, M>(db: C, f: F) -> Result<(), DbErr>
|
|
||||||
where
|
where
|
||||||
C: IntoSchemaManagerConnection<'c>,
|
C: IntoSchemaManagerConnection<'c>,
|
||||||
F: for<'b> Fn(
|
F: for<'b> Fn(
|
||||||
&'b SchemaManager<'_>,
|
&'b SchemaManager<'_>,
|
||||||
) -> Pin<Box<dyn Future<Output = Result<(), DbErr>> + Send + 'b>>,
|
) -> Pin<Box<dyn Future<Output = Result<(), DbErr>> + Send + 'b>>,
|
||||||
M: MigratorTrait + ?Sized,
|
|
||||||
{
|
{
|
||||||
let db = db.into_schema_manager_connection();
|
let db = db.into_schema_manager_connection();
|
||||||
|
|
||||||
|
|
@ -311,7 +334,7 @@ where
|
||||||
let type_name: String = row.try_get("", "typname")?;
|
let type_name: String = row.try_get("", "typname")?;
|
||||||
info!("Dropping type '{}'", type_name);
|
info!("Dropping type '{}'", type_name);
|
||||||
let mut stmt = Type::drop();
|
let mut stmt = Type::drop();
|
||||||
stmt.name(Alias::new(&type_name as &str));
|
stmt.name(Alias::new(&type_name));
|
||||||
db.execute(db_backend.build(&stmt)).await?;
|
db.execute(db_backend.build(&stmt)).await?;
|
||||||
info!("Type '{}' has been dropped", type_name);
|
info!("Type '{}' has been dropped", type_name);
|
||||||
}
|
}
|
||||||
|
|
@ -363,11 +386,12 @@ where
|
||||||
let now = SystemTime::now()
|
let now = SystemTime::now()
|
||||||
.duration_since(SystemTime::UNIX_EPOCH)
|
.duration_since(SystemTime::UNIX_EPOCH)
|
||||||
.expect("SystemTime before UNIX EPOCH!");
|
.expect("SystemTime before UNIX EPOCH!");
|
||||||
seaql_migrations::ActiveModel {
|
seaql_migrations::Entity::insert(seaql_migrations::ActiveModel {
|
||||||
version: ActiveValue::Set(migration.name().to_owned()),
|
version: ActiveValue::Set(migration.name().to_owned()),
|
||||||
applied_at: ActiveValue::Set(now.as_secs() as i64),
|
applied_at: ActiveValue::Set(now.as_secs() as i64),
|
||||||
}
|
})
|
||||||
.insert(db)
|
.table_name(M::migration_table_name())
|
||||||
|
.exec(db)
|
||||||
.await?;
|
.await?;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -403,7 +427,8 @@ where
|
||||||
migration.down(manager).await?;
|
migration.down(manager).await?;
|
||||||
info!("Migration '{}' has been rollbacked", migration.name());
|
info!("Migration '{}' has been rollbacked", migration.name());
|
||||||
seaql_migrations::Entity::delete_many()
|
seaql_migrations::Entity::delete_many()
|
||||||
.filter(seaql_migrations::Column::Version.eq(migration.name()))
|
.filter(Expr::col(seaql_migrations::Column::Version).eq(migration.name()))
|
||||||
|
.table_name(M::migration_table_name())
|
||||||
.exec(db)
|
.exec(db)
|
||||||
.await?;
|
.await?;
|
||||||
}
|
}
|
||||||
|
|
@ -433,13 +458,13 @@ where
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Iden)]
|
#[derive(DeriveIden)]
|
||||||
enum InformationSchema {
|
enum InformationSchema {
|
||||||
#[iden = "information_schema"]
|
#[sea_orm(iden = "information_schema")]
|
||||||
Schema,
|
Schema,
|
||||||
#[iden = "TABLE_NAME"]
|
#[sea_orm(iden = "TABLE_NAME")]
|
||||||
TableName,
|
TableName,
|
||||||
#[iden = "CONSTRAINT_NAME"]
|
#[sea_orm(iden = "CONSTRAINT_NAME")]
|
||||||
ConstraintName,
|
ConstraintName,
|
||||||
TableConstraints,
|
TableConstraints,
|
||||||
TableSchema,
|
TableSchema,
|
||||||
|
|
@ -476,7 +501,7 @@ where
|
||||||
stmt
|
stmt
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Iden)]
|
#[derive(DeriveIden)]
|
||||||
enum PgType {
|
enum PgType {
|
||||||
Table,
|
Table,
|
||||||
Typname,
|
Typname,
|
||||||
|
|
@ -484,7 +509,7 @@ enum PgType {
|
||||||
Typelem,
|
Typelem,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Iden)]
|
#[derive(DeriveIden)]
|
||||||
enum PgNamespace {
|
enum PgNamespace {
|
||||||
Table,
|
Table,
|
||||||
Oid,
|
Oid,
|
||||||
|
|
@ -514,3 +539,51 @@ where
|
||||||
);
|
);
|
||||||
stmt
|
stmt
|
||||||
}
|
}
|
||||||
|
|
||||||
|
trait QueryTable {
|
||||||
|
type Statement;
|
||||||
|
|
||||||
|
fn table_name(self, table_name: DynIden) -> Self::Statement;
|
||||||
|
}
|
||||||
|
|
||||||
|
impl QueryTable for SelectStatement {
|
||||||
|
type Statement = SelectStatement;
|
||||||
|
|
||||||
|
fn table_name(mut self, table_name: DynIden) -> SelectStatement {
|
||||||
|
self.from(table_name);
|
||||||
|
self
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl QueryTable for sea_query::TableCreateStatement {
|
||||||
|
type Statement = sea_query::TableCreateStatement;
|
||||||
|
|
||||||
|
fn table_name(mut self, table_name: DynIden) -> sea_query::TableCreateStatement {
|
||||||
|
self.table(table_name);
|
||||||
|
self
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<A> QueryTable for sea_orm::Insert<A>
|
||||||
|
where
|
||||||
|
A: ActiveModelTrait,
|
||||||
|
{
|
||||||
|
type Statement = sea_orm::Insert<A>;
|
||||||
|
|
||||||
|
fn table_name(mut self, table_name: DynIden) -> sea_orm::Insert<A> {
|
||||||
|
sea_orm::QueryTrait::query(&mut self).into_table(table_name);
|
||||||
|
self
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<E> QueryTable for sea_orm::DeleteMany<E>
|
||||||
|
where
|
||||||
|
E: EntityTrait,
|
||||||
|
{
|
||||||
|
type Statement = sea_orm::DeleteMany<E>;
|
||||||
|
|
||||||
|
fn table_name(mut self, table_name: DynIden) -> sea_orm::DeleteMany<E> {
|
||||||
|
sea_orm::QueryTrait::query(&mut self).from_table(table_name);
|
||||||
|
self
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -9,5 +9,7 @@ pub use async_trait;
|
||||||
pub use sea_orm;
|
pub use sea_orm;
|
||||||
pub use sea_orm::sea_query;
|
pub use sea_orm::sea_query;
|
||||||
pub use sea_orm::sea_query::*;
|
pub use sea_orm::sea_query::*;
|
||||||
|
pub use sea_orm::ConnectionTrait;
|
||||||
pub use sea_orm::DbErr;
|
pub use sea_orm::DbErr;
|
||||||
|
pub use sea_orm::DeriveIden;
|
||||||
pub use sea_orm::DeriveMigrationName;
|
pub use sea_orm::DeriveMigrationName;
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue