⬆️ (seaorm): Actualiza sea-orm a 1.1

This commit is contained in:
Manuel Cillero 2026-05-10 21:42:19 +02:00
parent 8c861bff05
commit aa931ea052
9 changed files with 227 additions and 331 deletions

View file

@ -11,17 +11,7 @@ use sea_orm::{ConnectionTrait, DatabaseBackend, Statement};
mod dbconn;
pub(crate) use dbconn::{run_now, DBCONN};
// The migration module is a customized version of the sea_orm_migration module (v1.0.0)
// https://github.com/SeaQL/sea-orm/tree/1.0.0/sea-orm-migration to avoid errors caused by the
// package paradigm of PageTop. Files integrated from original:
//
// lib.rs => db/migration.rs . . . . . . . . . . . . . . (excluding some modules and exports)
// connection.rs => db/migration/connection.rs . . . . . . . . . . . . . . (full integration)
// manager.rs => db/migration/manager.rs . . . . . . . . . . . . . . . . . (full integration)
// migrator.rs => db/migration/migrator.rs . . . . . . . . . . . .(omitting error management)
// prelude.rs => db/migration/prelude.rs . . . . . . . . . . . . . . . . . . . (avoiding CLI)
// seaql_migrations.rs => db/migration/seaql_migrations.rs . . . . . . . . (full integration)
//
// Adaptación de `sea-orm-migration` (ver §Créditos en README.md).
mod migration;
pub use migration::prelude::*;
pub use migration::schema::*;

View file

@ -11,7 +11,7 @@ pub enum SchemaManagerConnection<'c> {
}
#[async_trait::async_trait]
impl<'c> ConnectionTrait for SchemaManagerConnection<'c> {
impl ConnectionTrait for SchemaManagerConnection<'_> {
fn get_database_backend(&self) -> DbBackend {
match self {
SchemaManagerConnection::Connection(conn) => conn.get_database_backend(),
@ -56,7 +56,7 @@ impl<'c> ConnectionTrait for SchemaManagerConnection<'c> {
}
#[async_trait::async_trait]
impl<'c> TransactionTrait for SchemaManagerConnection<'c> {
impl TransactionTrait for SchemaManagerConnection<'_> {
async fn begin(&self) -> Result<DatabaseTransaction, DbErr> {
match self {
SchemaManagerConnection::Connection(conn) => conn.begin().await,
@ -86,7 +86,7 @@ impl<'c> TransactionTrait for SchemaManagerConnection<'c> {
) -> Pin<Box<dyn Future<Output = Result<T, E>> + Send + 'a>>
+ Send,
T: Send,
E: std::error::Error + Send,
E: std::fmt::Display + std::fmt::Debug + Send,
{
match self {
SchemaManagerConnection::Connection(conn) => conn.transaction(callback).await,
@ -106,7 +106,7 @@ impl<'c> TransactionTrait for SchemaManagerConnection<'c> {
) -> Pin<Box<dyn Future<Output = Result<T, E>> + Send + 'a>>
+ Send,
T: Send,
E: std::error::Error + Send,
E: std::fmt::Display + std::fmt::Debug + Send,
{
match self {
SchemaManagerConnection::Connection(conn) => {

View file

@ -2,11 +2,12 @@ use super::{IntoSchemaManagerConnection, SchemaManagerConnection};
use sea_orm::sea_query::{
extension::postgres::{TypeAlterStatement, TypeCreateStatement, TypeDropStatement},
ForeignKeyCreateStatement, ForeignKeyDropStatement, IndexCreateStatement, IndexDropStatement,
TableAlterStatement, TableCreateStatement, TableDropStatement, TableRenameStatement,
TableTruncateStatement,
SelectStatement, TableAlterStatement, TableCreateStatement, TableDropStatement,
TableRenameStatement, TableTruncateStatement,
};
use sea_orm::{ConnectionTrait, DbBackend, DbErr, StatementBuilder};
use sea_schema::{mysql::MySql, postgres::Postgres, probe::SchemaProbe, sqlite::Sqlite};
#[allow(unused_imports)]
use sea_schema::probe::SchemaProbe;
/// Helper struct for writing migration scripts in migration file
pub struct SchemaManager<'c> {
@ -41,7 +42,7 @@ impl<'c> SchemaManager<'c> {
}
/// Schema Creation
impl<'c> SchemaManager<'c> {
impl SchemaManager<'_> {
pub async fn create_table(&self, stmt: TableCreateStatement) -> Result<(), DbErr> {
self.exec_stmt(stmt).await
}
@ -60,7 +61,7 @@ impl<'c> SchemaManager<'c> {
}
/// Schema Mutation
impl<'c> SchemaManager<'c> {
impl SchemaManager<'_> {
pub async fn alter_table(&self, stmt: TableAlterStatement) -> Result<(), DbErr> {
self.exec_stmt(stmt).await
}
@ -95,7 +96,7 @@ impl<'c> SchemaManager<'c> {
}
/// Schema Inspection.
impl<'c> SchemaManager<'c> {
impl SchemaManager<'_> {
pub async fn has_table<T>(&self, table: T) -> Result<bool, DbErr>
where
T: AsRef<str>,
@ -103,42 +104,54 @@ impl<'c> SchemaManager<'c> {
has_table(&self.conn, table).await
}
pub async fn has_column<T, C>(&self, table: T, column: C) -> Result<bool, DbErr>
pub async fn has_column<T, C>(&self, _table: T, _column: C) -> Result<bool, DbErr>
where
T: AsRef<str>,
C: AsRef<str>,
{
let stmt = match self.conn.get_database_backend() {
DbBackend::MySql => MySql.has_column(table, column),
DbBackend::Postgres => Postgres.has_column(table, column),
DbBackend::Sqlite => Sqlite.has_column(table, column),
let _stmt: SelectStatement = match self.conn.get_database_backend() {
#[cfg(feature = "mysql")]
DbBackend::MySql => sea_schema::mysql::MySql.has_column(_table, _column),
#[cfg(feature = "postgres")]
DbBackend::Postgres => sea_schema::postgres::Postgres.has_column(_table, _column),
#[cfg(feature = "sqlite")]
DbBackend::Sqlite => sea_schema::sqlite::Sqlite.has_column(_table, _column),
#[allow(unreachable_patterns)]
other => panic!("{other:?} feature is off"),
};
#[allow(unreachable_code)]
let builder = self.conn.get_database_backend();
let res = self
.conn
.query_one(builder.build(&stmt))
.query_one(builder.build(&_stmt))
.await?
.ok_or_else(|| DbErr::Custom("Failed to check column exists".to_owned()))?;
res.try_get("", "has_column")
}
pub async fn has_index<T, I>(&self, table: T, index: I) -> Result<bool, DbErr>
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 _stmt: SelectStatement = match self.conn.get_database_backend() {
#[cfg(feature = "mysql")]
DbBackend::MySql => sea_schema::mysql::MySql.has_index(_table, _index),
#[cfg(feature = "postgres")]
DbBackend::Postgres => sea_schema::postgres::Postgres.has_index(_table, _index),
#[cfg(feature = "sqlite")]
DbBackend::Sqlite => sea_schema::sqlite::Sqlite.has_index(_table, _index),
#[allow(unreachable_patterns)]
other => panic!("{other:?} feature is off"),
};
#[allow(unreachable_code)]
let builder = self.conn.get_database_backend();
let res = self
.conn
.query_one(builder.build(&stmt))
.query_one(builder.build(&_stmt))
.await?
.ok_or_else(|| DbErr::Custom("Failed to check index exists".to_owned()))?;
@ -146,20 +159,26 @@ impl<'c> SchemaManager<'c> {
}
}
pub(crate) async fn has_table<C, T>(conn: &C, table: T) -> Result<bool, DbErr>
pub(crate) async fn has_table<C, T>(conn: &C, _table: T) -> Result<bool, DbErr>
where
C: ConnectionTrait,
T: AsRef<str>,
{
let stmt = match conn.get_database_backend() {
DbBackend::MySql => MySql.has_table(table),
DbBackend::Postgres => Postgres.has_table(table),
DbBackend::Sqlite => Sqlite.has_table(table),
let _stmt: SelectStatement = match conn.get_database_backend() {
#[cfg(feature = "mysql")]
DbBackend::MySql => sea_schema::mysql::MySql.has_table(_table),
#[cfg(feature = "postgres")]
DbBackend::Postgres => sea_schema::postgres::Postgres.has_table(_table),
#[cfg(feature = "sqlite")]
DbBackend::Sqlite => sea_schema::sqlite::Sqlite.has_table(_table),
#[allow(unreachable_patterns)]
other => panic!("{other:?} feature is off"),
};
#[allow(unreachable_code)]
let builder = conn.get_database_backend();
let res = conn
.query_one(builder.build(&stmt))
.query_one(builder.build(&_stmt))
.await?
.ok_or_else(|| DbErr::Custom("Failed to check table exists".to_owned()))?;

View file

@ -7,7 +7,7 @@ use std::time::SystemTime;
use pagetop::trace::info;
use sea_orm::sea_query::{
self, extension::postgres::Type, Alias, Expr, ForeignKey, IntoIden, JoinType, Order, Query,
self, extension::postgres::Type, Alias, Expr, ExprTrait, ForeignKey, IntoIden, Order, Query,
SelectStatement, SimpleExpr, Table,
};
use sea_orm::{
@ -15,7 +15,8 @@ use sea_orm::{
DynIden, EntityTrait, FromQueryResult, Iterable, QueryFilter, Schema, Statement,
TransactionTrait,
};
use sea_schema::{mysql::MySql, postgres::Postgres, probe::SchemaProbe, sqlite::Sqlite};
#[allow(unused_imports)]
use sea_schema::probe::SchemaProbe;
use super::{seaql_migrations, IntoSchemaManagerConnection, MigrationTrait, SchemaManager};
@ -445,9 +446,14 @@ where
C: ConnectionTrait,
{
match db.get_database_backend() {
DbBackend::MySql => MySql.query_tables(),
DbBackend::Postgres => Postgres.query_tables(),
DbBackend::Sqlite => Sqlite.query_tables(),
#[cfg(feature = "mysql")]
DbBackend::MySql => sea_schema::mysql::MySql.query_tables(),
#[cfg(feature = "postgres")]
DbBackend::Postgres => sea_schema::postgres::Postgres.query_tables(),
#[cfg(feature = "sqlite")]
DbBackend::Sqlite => sea_schema::sqlite::Sqlite.query_tables(),
#[allow(unreachable_patterns)]
other => panic!("{other:?} feature is off"),
}
}
@ -456,9 +462,14 @@ where
C: ConnectionTrait,
{
match db.get_database_backend() {
DbBackend::MySql => MySql::get_current_schema(),
DbBackend::Postgres => Postgres::get_current_schema(),
DbBackend::Sqlite => unimplemented!(),
#[cfg(feature = "mysql")]
DbBackend::MySql => sea_schema::mysql::MySql::get_current_schema(),
#[cfg(feature = "postgres")]
DbBackend::Postgres => sea_schema::postgres::Postgres::get_current_schema(),
#[cfg(feature = "sqlite")]
DbBackend::Sqlite => sea_schema::sqlite::Sqlite::get_current_schema(),
#[allow(unreachable_patterns)]
other => panic!("{other:?} feature is off"),
}
}
@ -490,7 +501,7 @@ where
))
.cond_where(
Condition::all()
.add(Expr::expr(get_current_schema(db)).equals((
.add(get_current_schema(db).equals((
InformationSchema::TableConstraints,
InformationSchema::TableSchema,
)))
@ -508,11 +519,20 @@ where
#[derive(DeriveIden)]
enum PgType {
Table,
Oid,
Typname,
Typnamespace,
Typelem,
}
#[derive(DeriveIden)]
enum PgDepend {
Table,
Objid,
Deptype,
Refclassid,
}
#[derive(DeriveIden)]
enum PgNamespace {
Table,
@ -524,24 +544,28 @@ fn query_pg_types<C>(db: &C) -> SelectStatement
where
C: ConnectionTrait,
{
let mut stmt = Query::select();
stmt.column(PgType::Typname)
Query::select()
.column(PgType::Typname)
.from(PgType::Table)
.join(
JoinType::LeftJoin,
.left_join(
PgNamespace::Table,
Expr::col((PgNamespace::Table, PgNamespace::Oid))
.equals((PgType::Table, PgType::Typnamespace)),
)
.cond_where(
Condition::all()
.add(
Expr::expr(get_current_schema(db))
.equals((PgNamespace::Table, PgNamespace::Nspname)),
.left_join(
PgDepend::Table,
Expr::col((PgDepend::Table, PgDepend::Objid))
.equals((PgType::Table, PgType::Oid))
.and(
Expr::col((PgDepend::Table, PgDepend::Refclassid))
.eq(Expr::cust("'pg_extension'::regclass::oid")),
)
.add(Expr::col((PgType::Table, PgType::Typelem)).eq(0)),
);
stmt
.and(Expr::col((PgDepend::Table, PgDepend::Deptype)).eq(Expr::cust("'e'"))),
)
.and_where(get_current_schema(db).equals((PgNamespace::Table, PgNamespace::Nspname)))
.and_where(Expr::col((PgType::Table, PgType::Typelem)).eq(0))
.and_where(Expr::col((PgDepend::Table, PgDepend::Objid)).is_null())
.take()
}
trait QueryTable {

View file

@ -10,4 +10,3 @@ pub use sea_orm;
pub use sea_orm::sea_query;
pub use sea_orm::sea_query::*;
pub use sea_orm::DeriveIden;
pub use sea_orm::DeriveMigrationName;

View file

@ -73,6 +73,11 @@ pub fn pk_auto<T: IntoIden>(name: T) -> ColumnDef {
integer(name).auto_increment().primary_key().take()
}
/// Create a UUID primary key
pub fn pk_uuid<T: IntoIden>(name: T) -> ColumnDef {
uuid(name).primary_key().take()
}
pub fn char_len<T: IntoIden>(col: T, length: u32) -> ColumnDef {
ColumnDef::new(col).char_len(length).not_null().take()
}
@ -538,11 +543,11 @@ pub fn uuid_uniq<T: IntoIden>(col: T) -> ColumnDef {
uuid(col).unique_key().take()
}
pub fn custom<T: IntoIden>(col: T, name: T) -> ColumnDef {
pub fn custom<T: IntoIden, N: IntoIden>(col: T, name: N) -> ColumnDef {
ColumnDef::new(col).custom(name).not_null().take()
}
pub fn custom_null<T: IntoIden>(col: T, name: T) -> ColumnDef {
pub fn custom_null<T: IntoIden, N: IntoIden>(col: T, name: N) -> ColumnDef {
ColumnDef::new(col).custom(name).null().take()
}