Skip to content

Commit 903224a

Browse files
committed
bump sea-orm-sync
1 parent 41d74f1 commit 903224a

12 files changed

Lines changed: 442 additions & 20 deletions

File tree

sea-orm-sync/Cargo.toml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -54,15 +54,15 @@ sea-orm-arrow = { version = "2.0.0-rc", path = "../sea-orm-arrow", default-featu
5454
sea-orm-macros = { version = "~2.0.0-rc.37", path = "../sea-orm-macros", default-features = false, features = [
5555
"strum",
5656
] }
57-
sea-query = { version = "=1.0.0-rc.32", default-features = false, features = [
57+
sea-query = { version = "=1.0.0-rc.33", default-features = false, features = [
5858
"thread-safe",
5959
"hashable-value",
6060
"backend-mysql",
6161
"backend-postgres",
6262
"backend-sqlite",
6363
"sea-orm",
6464
] }
65-
sea-query-rusqlite = { version = "0.8.0-rc.14", optional = true }
65+
sea-query-rusqlite = { version = "0.8.0-rc.15", optional = true }
6666
sea-schema-sync = { version = "0.17.0-rc.15", default-features = false, features = [
6767
"sync",
6868
"discovery",

sea-orm-sync/src/database/mod.rs

Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
use std::{sync::Arc, time::Duration};
22

3+
#[cfg(not(feature = "sync"))]
34
#[cfg(feature = "sqlx-mysql")]
45
use sqlx::mysql::MySqlConnectOptions;
56
#[cfg(feature = "sqlx-postgres")]
@@ -53,6 +54,19 @@ pub struct Database;
5354
#[cfg(feature = "sync")]
5455
type BoxFuture<'a, T> = T;
5556

57+
#[cfg(feature = "sqlx-mysql")]
58+
type MapMySqlPoolOptsFn =
59+
Arc<dyn Fn(sqlx::pool::PoolOptions<sqlx::MySql>) -> sqlx::pool::PoolOptions<sqlx::MySql>>;
60+
61+
#[cfg(feature = "sqlx-postgres")]
62+
type MapPgPoolOptsFn =
63+
Arc<dyn Fn(sqlx::pool::PoolOptions<sqlx::Postgres>) -> sqlx::pool::PoolOptions<sqlx::Postgres>>;
64+
65+
#[cfg(feature = "sqlx-sqlite")]
66+
type MapSqlitePoolOptsFn = Option<
67+
Arc<dyn Fn(sqlx::pool::PoolOptions<sqlx::Sqlite>) -> sqlx::pool::PoolOptions<sqlx::Sqlite>>,
68+
>;
69+
5670
type AfterConnectCallback =
5771
Option<Arc<dyn Fn(DatabaseConnection) -> BoxFuture<'static, Result<(), DbErr>> + 'static>>;
5872

@@ -99,6 +113,15 @@ pub struct ConnectOptions {
99113
#[debug(skip)]
100114
pub(crate) after_connect: AfterConnectCallback,
101115

116+
#[cfg(feature = "sqlx-mysql")]
117+
#[debug(skip)]
118+
pub(crate) mysql_pool_opts_fn: Option<MapMySqlPoolOptsFn>,
119+
#[cfg(feature = "sqlx-postgres")]
120+
#[debug(skip)]
121+
pub(crate) pg_pool_opts_fn: Option<MapPgPoolOptsFn>,
122+
#[cfg(feature = "sqlx-sqlite")]
123+
#[debug(skip)]
124+
pub(crate) sqlite_pool_opts_fn: MapSqlitePoolOptsFn,
102125
#[cfg(feature = "sqlx-mysql")]
103126
#[debug(skip)]
104127
pub(crate) mysql_opts_fn: Option<Arc<dyn Fn(MySqlConnectOptions) -> MySqlConnectOptions>>,
@@ -219,6 +242,12 @@ impl ConnectOptions {
219242
connect_lazy: false,
220243
after_connect: None,
221244
#[cfg(feature = "sqlx-mysql")]
245+
mysql_pool_opts_fn: None,
246+
#[cfg(feature = "sqlx-postgres")]
247+
pg_pool_opts_fn: None,
248+
#[cfg(feature = "sqlx-sqlite")]
249+
sqlite_pool_opts_fn: None,
250+
#[cfg(feature = "sqlx-mysql")]
222251
mysql_opts_fn: None,
223252
#[cfg(feature = "sqlx-postgres")]
224253
pg_opts_fn: None,
@@ -431,6 +460,19 @@ impl ConnectOptions {
431460
self
432461
}
433462

463+
#[cfg(feature = "sqlx-mysql")]
464+
#[cfg_attr(docsrs, doc(cfg(feature = "sqlx-mysql")))]
465+
/// Apply a function to modify the underlying [`sqlx::pool::PoolOptions<sqlx::MySql>`]
466+
/// before creating the connection pool.
467+
pub fn map_sqlx_mysql_pool_opts<F>(&mut self, f: F) -> &mut Self
468+
where
469+
F: Fn(sqlx::pool::PoolOptions<sqlx::MySql>) -> sqlx::pool::PoolOptions<sqlx::MySql>
470+
+ 'static,
471+
{
472+
self.mysql_pool_opts_fn = Some(Arc::new(f));
473+
self
474+
}
475+
434476
#[cfg(feature = "sqlx-postgres")]
435477
#[cfg_attr(docsrs, doc(cfg(feature = "sqlx-postgres")))]
436478
/// Apply a function to modify the underlying [`PgConnectOptions`] before
@@ -443,6 +485,19 @@ impl ConnectOptions {
443485
self
444486
}
445487

488+
#[cfg(feature = "sqlx-postgres")]
489+
#[cfg_attr(docsrs, doc(cfg(feature = "sqlx-postgres")))]
490+
/// Apply a function to modify the underlying [`sqlx::pool::PoolOptions<sqlx::Postgres>`]
491+
/// before creating the connection pool.
492+
pub fn map_sqlx_postgres_pool_opts<F>(&mut self, f: F) -> &mut Self
493+
where
494+
F: Fn(sqlx::pool::PoolOptions<sqlx::Postgres>) -> sqlx::pool::PoolOptions<sqlx::Postgres>
495+
+ 'static,
496+
{
497+
self.pg_pool_opts_fn = Some(Arc::new(f));
498+
self
499+
}
500+
446501
#[cfg(feature = "sqlx-sqlite")]
447502
#[cfg_attr(docsrs, doc(cfg(feature = "sqlx-sqlite")))]
448503
/// Apply a function to modify the underlying [`SqliteConnectOptions`] before
@@ -454,4 +509,17 @@ impl ConnectOptions {
454509
self.sqlite_opts_fn = Some(Arc::new(f));
455510
self
456511
}
512+
513+
#[cfg(feature = "sqlx-sqlite")]
514+
#[cfg_attr(docsrs, doc(cfg(feature = "sqlx-sqlite")))]
515+
/// Apply a function to modify the underlying [`sqlx::pool::PoolOptions<sqlx::Sqlite>`]
516+
/// before creating the connection pool.
517+
pub fn map_sqlx_sqlite_pool_opts<F>(&mut self, f: F) -> &mut Self
518+
where
519+
F: Fn(sqlx::pool::PoolOptions<sqlx::Sqlite>) -> sqlx::pool::PoolOptions<sqlx::Sqlite>
520+
+ 'static,
521+
{
522+
self.sqlite_pool_opts_fn = Some(Arc::new(f));
523+
self
524+
}
457525
}

sea-orm-sync/src/driver/sqlx_mysql.rs

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -81,14 +81,17 @@ impl SqlxMySqlConnector {
8181
if let Some(f) = &options.mysql_opts_fn {
8282
sqlx_opts = f(sqlx_opts);
8383
}
84-
8584
let after_connect = options.after_connect.clone();
86-
87-
let pool = if options.connect_lazy {
88-
options.sqlx_pool_options().connect_lazy_with(sqlx_opts)
85+
let connect_lazy = options.connect_lazy;
86+
let mysql_pool_opts_fn = options.mysql_pool_opts_fn.clone();
87+
let mut pool_options = options.sqlx_pool_options();
88+
if let Some(f) = &mysql_pool_opts_fn {
89+
pool_options = f(pool_options);
90+
}
91+
let pool = if connect_lazy {
92+
pool_options.connect_lazy_with(sqlx_opts)
8993
} else {
90-
options
91-
.sqlx_pool_options()
94+
pool_options
9295
.connect_with(sqlx_opts)
9396
.map_err(sqlx_error_to_conn_err)?
9497
};

sea-orm-sync/src/driver/sqlx_postgres.rs

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -110,6 +110,7 @@ impl SqlxPostgresConnector {
110110

111111
let lazy = options.connect_lazy;
112112
let after_connect = options.after_connect.clone();
113+
let pg_pool_opts_fn = options.pg_pool_opts_fn.clone();
113114
let mut pool_options = options.sqlx_pool_options();
114115

115116
if let Some(sql) = set_search_path_sql {
@@ -118,7 +119,9 @@ impl SqlxPostgresConnector {
118119
({ sqlx::Executor::execute(conn, sql.as_str()).map(|_| ()) })
119120
});
120121
}
121-
122+
if let Some(f) = &pg_pool_opts_fn {
123+
pool_options = f(pool_options);
124+
}
122125
let pool = if lazy {
123126
pool_options.connect_lazy_with(sqlx_opts)
124127
} else {

sea-orm-sync/src/driver/sqlx_sqlite.rs

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -91,12 +91,18 @@ impl SqlxSqliteConnector {
9191
}
9292

9393
let after_conn = options.after_connect.clone();
94+
let connect_lazy = options.connect_lazy;
95+
let sqlite_pool_opts_fn = options.sqlite_pool_opts_fn.clone();
96+
let mut pool_options = options.sqlx_pool_options();
9497

95-
let pool = if options.connect_lazy {
96-
options.sqlx_pool_options().connect_lazy_with(sqlx_opts)
98+
if let Some(f) = &sqlite_pool_opts_fn {
99+
pool_options = f(pool_options);
100+
}
101+
102+
let pool = if connect_lazy {
103+
pool_options.connect_lazy_with(sqlx_opts)
97104
} else {
98-
options
99-
.sqlx_pool_options()
105+
pool_options
100106
.connect_with(sqlx_opts)
101107
.map_err(sqlx_error_to_conn_err)?
102108
};

sea-orm-sync/src/entity/active_enum.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -205,6 +205,9 @@ impl TryGetable for sea_query::Enum {
205205
fn try_get_by<I: ColIdx>(res: &QueryResult, idx: I) -> Result<Self, TryGetError> {
206206
let value: String = <String as TryGetable>::try_get_by(res, idx)?;
207207
Ok(Self {
208+
// `DeriveActiveEnum` overwrites `type_name` when constructing values for queries, but we
209+
// can't reliably recover the enum type name from `QueryResult`. Keeping it empty may
210+
// still cause issues if this value is later reused to build SQL (e.g. missing casts).
208211
type_name: "".into(),
209212
value: value.into(),
210213
})
@@ -219,6 +222,7 @@ impl ActiveEnumValue for sea_query::Enum {
219222
Ok(values
220223
.into_iter()
221224
.map(|value| Self {
225+
// See comment in `TryGetable for sea_query::Enum` about empty `type_name`.
222226
type_name: "".into(),
223227
value: value.into(),
224228
})

sea-orm-sync/src/executor/query.rs

Lines changed: 32 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ use crate::debug_print;
1717
#[cfg(feature = "sqlx-dep")]
1818
use crate::driver::*;
1919
#[cfg(feature = "sqlx-dep")]
20-
use sqlx::Row;
20+
use sqlx::{Row, TypeInfo, ValueRef};
2121

2222
/// Defines the result of a query operation on a Model
2323
#[derive(Debug)]
@@ -81,6 +81,37 @@ impl From<DbErr> for TryGetError {
8181
// QueryResult //
8282

8383
impl QueryResult {
84+
#[doc(hidden)]
85+
#[cfg(feature = "sqlx-postgres")]
86+
pub fn try_get_from_sqlx_postgres<T, I>(&self, idx: I) -> Option<Result<T, TryGetError>>
87+
where
88+
T: sqlx::Type<sqlx::Postgres> + for<'r> sqlx::Decode<'r, sqlx::Postgres>,
89+
I: ColIdx,
90+
{
91+
match &self.row {
92+
QueryResultRow::SqlxPostgres(row) => {
93+
let value = match row.try_get_raw(idx.as_sqlx_postgres_index()) {
94+
Ok(value) => value,
95+
Err(err) => return Some(Err(sqlx_error_to_query_err(err).into())),
96+
};
97+
98+
if !value.is_null() {
99+
let ty = value.type_info();
100+
if !ty.is_null() && !T::compatible(&ty) {
101+
return None;
102+
}
103+
}
104+
105+
Some(
106+
row.try_get::<Option<T>, _>(idx.as_sqlx_postgres_index())
107+
.map_err(|e| sqlx_error_to_query_err(e).into())
108+
.and_then(|opt| opt.ok_or_else(|| err_null_idx_col(idx))),
109+
)
110+
}
111+
_ => None,
112+
}
113+
}
114+
84115
/// Get a value from the query result with an ColIdx
85116
pub fn try_get_by<T, I>(&self, index: I) -> Result<T, DbErr>
86117
where

sea-orm-sync/src/schema/builder.rs

Lines changed: 22 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -537,10 +537,29 @@ impl EntitySchemaInfo {
537537
}
538538
}
539539
if !has_index {
540-
if let Some(drop_existing) =
541-
existing_index.get_index_spec().get_name().map(|s| s.to_owned())
540+
if let Some(drop_existing) = existing_index
541+
.get_index_spec()
542+
.get_name()
543+
.map(|s| s.to_owned())
542544
{
543-
db.execute(sea_query::Index::drop().name(drop_existing))?;
545+
if db_backend == DbBackend::Postgres {
546+
// On PostgreSQL, unique indexes created via column-level UNIQUE
547+
// (e.g. ADD COLUMN ... UNIQUE) are backed by a named constraint.
548+
// DROP INDEX fails on constraint-owned indexes; use
549+
// ALTER TABLE ... DROP CONSTRAINT instead.
550+
db.execute(
551+
TableAlterStatement::new()
552+
.table(
553+
self.table
554+
.get_table_name()
555+
.expect("Checked above")
556+
.clone(),
557+
)
558+
.drop_constraint(drop_existing),
559+
)?;
560+
} else {
561+
db.execute(sea_query::Index::drop().name(drop_existing))?;
562+
}
544563
}
545564
}
546565
}

0 commit comments

Comments
 (0)