diff options
| -rw-r--r-- | Cargo.lock | 198 | ||||
| -rw-r--r-- | Cargo.toml | 8 | ||||
| -rw-r--r-- | src/db/mod.rs | 88 |
3 files changed, 205 insertions, 89 deletions
@@ -515,6 +515,16 @@ dependencies = [ ] [[package]] +name = "darling" +version = "0.21.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9cdf337090841a411e2a7f3deb9187445851f91b309c0c0a29e05f74a00a48c0" +dependencies = [ + "darling_core 0.21.3", + "darling_macro 0.21.3", +] + +[[package]] name = "darling_core" version = "0.10.2" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -543,6 +553,20 @@ dependencies = [ ] [[package]] +name = "darling_core" +version = "0.21.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1247195ecd7e3c85f83c8d2a366e4210d588e802133e1e355180a9870b517ea4" +dependencies = [ + "fnv", + "ident_case", + "proc-macro2", + "quote", + "strsim 0.11.1", + "syn 2.0.111", +] + +[[package]] name = "darling_macro" version = "0.10.2" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -565,6 +589,17 @@ dependencies = [ ] [[package]] +name = "darling_macro" +version = "0.21.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d38308df82d1080de0afee5d069fa14b0326a88c14f15c5ccda35b4a6c414c81" +dependencies = [ + "darling_core 0.21.3", + "quote", + "syn 2.0.111", +] + +[[package]] name = "dashmap" version = "5.5.3" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -600,19 +635,6 @@ checksum = "2a2330da5de22e8a3cb63252ce2abb30116bf5265e89c0e01bc17015ce30a476" [[package]] name = "deadpool" -version = "0.9.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "421fe0f90f2ab22016f32a9881be5134fdd71c65298917084b0c7477cbc3856e" -dependencies = [ - "async-trait", - "deadpool-runtime", - "num_cpus", - "retain_mut", - "tokio", -] - -[[package]] -name = "deadpool" version = "0.12.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0be2b1d1d6ec8d846f05e137292d0b89133caf95ef33695424c09568bdd39b1b" @@ -630,7 +652,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3d697d376cbfa018c23eb4caab1fd1883dd9c906a8c034e8d9a3cb06a7e0bef9" dependencies = [ "async-trait", - "deadpool 0.12.3", + "deadpool", "getrandom 0.2.16", "tokio", "tokio-postgres", @@ -707,26 +729,28 @@ dependencies = [ [[package]] name = "diesel" -version = "2.1.6" +version = "2.3.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ff236accb9a5069572099f0b350a92e9560e8e63a9b8d546162f4a5e03026bb2" +checksum = "0c415189028b232660655e4893e8bc25ca7aee8e96888db66d9edb400535456a" dependencies = [ "bitflags 2.10.0", "byteorder", "chrono", "diesel_derives", + "downcast-rs", "itoa", ] [[package]] name = "diesel-async" -version = "0.4.1" +version = "0.7.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "acada1517534c92d3f382217b485db8a8638f111b0e3f2a2a8e26165050f77be" +checksum = "13096fb8dae53f2d411c4b523bec85f45552ed3044a2ab4d85fb2092d9cb4f34" dependencies = [ - "async-trait", - "deadpool 0.9.5", + "deadpool", "diesel", + "diesel_migrations", + "futures-core", "futures-util", "scoped-futures", "tokio", @@ -734,45 +758,34 @@ dependencies = [ ] [[package]] -name = "diesel_async_migrations" -version = "0.12.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a700d6b83a17973b94d3065970fd2b36f1036c3fe08adcbdce1c9beb8fb25553" -dependencies = [ - "diesel", - "diesel-async", - "diesel_async_migrations_macros", - "scoped-futures", - "tracing", -] - -[[package]] -name = "diesel_async_migrations_macros" -version = "0.12.0" +name = "diesel_derives" +version = "2.3.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "05de210f31e6ac18162501b03c37f839af9f9fd6dd6de2bb4031ae6691c47679" +checksum = "8587cbca3c929fb198e7950d761d31ca72b80aa6e07c1b7bec5879d187720436" dependencies = [ + "diesel_table_macro_syntax", + "dsl_auto_type", "proc-macro2", "quote", + "syn 2.0.111", ] [[package]] -name = "diesel_derives" -version = "2.1.4" +name = "diesel_migrations" +version = "2.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "14701062d6bed917b5c7103bdffaee1e4609279e240488ad24e7bd979ca6866c" +checksum = "745fd255645f0f1135f9ec55c7b00e0882192af9683ab4731e4bba3da82b8f9c" dependencies = [ - "diesel_table_macro_syntax", - "proc-macro2", - "quote", - "syn 2.0.111", + "diesel", + "migrations_internals", + "migrations_macros", ] [[package]] name = "diesel_table_macro_syntax" -version = "0.1.0" +version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fc5557efc453706fed5e4fa85006fe9817c224c3f480a34c7e5959fd700921c5" +checksum = "fe2444076b48641147115697648dc743c2c00b61adade0f01ce67133c7babe8c" dependencies = [ "syn 2.0.111", ] @@ -816,6 +829,26 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "77c90badedccf4105eca100756a0b1289e191f6fcbdadd3cee1d2f614f97da8f" [[package]] +name = "downcast-rs" +version = "2.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "117240f60069e65410b3ae1bb213295bd828f707b5bec6596a1afc8793ce0cbc" + +[[package]] +name = "dsl_auto_type" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dd122633e4bef06db27737f21d3738fb89c8f6d5360d6d9d7635dda142a7757e" +dependencies = [ + "darling 0.21.3", + "either", + "heck 0.5.0", + "proc-macro2", + "quote", + "syn 2.0.111", +] + +[[package]] name = "either" version = "1.15.0" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -1765,6 +1798,27 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f52b00d39961fc5b2736ea853c9cc86238e165017a493d1d5c8eac6bdc4cc273" [[package]] +name = "migrations_internals" +version = "2.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "36c791ecdf977c99f45f23280405d7723727470f6689a5e6dbf513ac547ae10d" +dependencies = [ + "serde", + "toml", +] + +[[package]] +name = "migrations_macros" +version = "2.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "36fc5ac76be324cfd2d3f2cf0fdf5d5d3c4f14ed8aaebadb09e304ba42282703" +dependencies = [ + "migrations_internals", + "proc-macro2", + "quote", +] + +[[package]] name = "mime" version = "0.3.17" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -2657,12 +2711,6 @@ dependencies = [ ] [[package]] -name = "retain_mut" -version = "0.1.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4389f1d5789befaf6029ebd9f7dac4af7f7e3d61b69d4f30e2ac02b57e7712b0" - -[[package]] name = "ring" version = "0.17.14" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -3069,6 +3117,15 @@ dependencies = [ ] [[package]] +name = "serde_spanned" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f8bbf91e5a4d6315eee45e704372590b30e260ee83af6639d64557f51b067776" +dependencies = [ + "serde_core", +] + +[[package]] name = "serde_urlencoded" version = "0.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -3819,7 +3876,7 @@ dependencies = [ "deadpool-postgres", "diesel", "diesel-async", - "diesel_async_migrations", + "diesel_migrations", "dotenv", "envconfig", "fnv", @@ -4090,6 +4147,37 @@ dependencies = [ ] [[package]] +name = "toml" +version = "0.9.10+spec-1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0825052159284a1a8b4d6c0c86cbc801f2da5afd2b225fa548c72f2e74002f48" +dependencies = [ + "serde_core", + "serde_spanned", + "toml_datetime", + "toml_parser", + "winnow", +] + +[[package]] +name = "toml_datetime" +version = "0.7.5+spec-1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "92e1cfed4a3038bc5a127e35a2d360f145e1f4b971b551a2ba5fd7aedf7e1347" +dependencies = [ + "serde_core", +] + +[[package]] +name = "toml_parser" +version = "1.0.6+spec-1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a3198b4b0a8e11f09dd03e133c0280504d0801269e9afa46362ffde1cbeebf44" +dependencies = [ + "winnow", +] + +[[package]] name = "tower" version = "0.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -5026,6 +5114,12 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d6bbff5f0aada427a1e5a6da5f1f98158182f26556f345ac9e04d36d0ebed650" [[package]] +name = "winnow" +version = "0.7.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5a5364e9d77fcdeeaa6062ced926ee3381faa2ee02d3eb83a5c27a8825540829" + +[[package]] name = "winreg" version = "0.50.0" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -24,7 +24,7 @@ required-features = ["db"] [features] default = ["db", "games", "windows_autostart_postgres"] -db = ["dep:diesel", "dep:diesel-async", "dep:diesel_async_migrations", "dep:tokio-postgres", "dep:deadpool-postgres"] +db = ["dep:diesel", "dep:diesel-async", "dep:tokio-postgres", "dep:deadpool-postgres"] games = [] windows_autostart_postgres = [] @@ -73,9 +73,9 @@ symphonia = { version = "0.5", features = ["all"] } # reminder: needed for songb poise = "0.6" -diesel = { version = "2.1", features = ["chrono"], optional = true } -diesel-async = { version = "0.4", optional = true, features = ["deadpool", "postgres"] } -diesel_async_migrations = { version = "0.12", optional = true } +diesel = { version = "2.3", features = ["chrono"], optional = true } +diesel_migrations = "2.3" +diesel-async = { version = "0.7", optional = true, features = ["deadpool", "postgres", "migrations"] } tokio-postgres = { version = "0.7", optional = true, features = ["with-chrono-0_4"] } deadpool-postgres = { version = "0.14", optional = true } diff --git a/src/db/mod.rs b/src/db/mod.rs index eb69d7b..cfa0599 100644 --- a/src/db/mod.rs +++ b/src/db/mod.rs @@ -1,12 +1,3 @@ -use std::{ - convert::{ - AsRef, - From, - }, - env, - str::FromStr, -}; - use anyhow::{ Error, Result, @@ -29,10 +20,12 @@ use diesel::{ NotFound, PgTextExpressionMethods, QueryDsl, + migration::Migration, prelude::*, }; use diesel_async::{ AsyncConnection, + AsyncMigrationHarness, AsyncPgConnection, RunQueryDsl, pooled_connection::{ @@ -41,9 +34,21 @@ use diesel_async::{ }, scoped_futures::ScopedFutureExt, }; +use diesel_migrations::MigrationHarness; use grate::tracing; use rand::prelude::IndexedRandom; -use serenity::FutureExt; +use std::{ + convert::{ + AsRef, + From, + }, + env, + str::FromStr, + sync::atomic::{ + AtomicBool, + Ordering, + }, +}; use tokio_postgres::types::FromSql; use self::schema::*; @@ -55,12 +60,24 @@ mod schema; pub use self::models::*; -static MIGRATIONS: diesel_async_migrations::EmbeddedMigrations = - diesel_async_migrations::embed_migrations!(); +static MIGRATIONS: diesel_migrations::EmbeddedMigrations = diesel_migrations::embed_migrations!(); -lazy_static::lazy_static! { - static ref MIGRATE: tokio::sync::OnceCell<()> = tokio::sync::OnceCell::new(); +struct EmbeddedMigrationWrapper<'a> { + inner: &'a diesel_migrations::EmbeddedMigrations, +} + +impl<'a, D> diesel::migration::MigrationSource<D> for EmbeddedMigrationWrapper<'a> +where + D: diesel::backend::Backend, +{ + fn migrations(&self) -> diesel::migration::Result<Vec<Box<dyn Migration<D>>>> { + self.inner.migrations() + } +} +static MIGRATED: AtomicBool = AtomicBool::new(false); + +lazy_static::lazy_static! { static ref DB_URL: String = env::var("DATABASE_URL").expect("no database url in environment"); @@ -82,35 +99,40 @@ lazy_static::lazy_static! { }; } +type PooledConn = diesel_async::pooled_connection::deadpool::Object<AsyncPgConnection>; + #[inline] -pub async fn connection() --> Result<diesel_async::pooled_connection::deadpool::Object<AsyncPgConnection>> { - POOL.get() - .then(|mut conn| async move { - if let Ok(ref mut conn) = conn { - do_migrate(conn).await; - } +pub async fn connection() -> Result<PooledConn> { + let conn = POOL.get().await?; + let conn = do_migrate(conn); - conn - }) - .await - .map_err(Error::from) + Ok(conn) } -async fn do_migrate(conn: &mut AsyncPgConnection) { - MIGRATE - .get_or_init(|| async move { - tracing::info!("running migrations"); - MIGRATIONS.run_pending_migrations(conn).await.expect("failed running migrations"); - tracing::info!("migrations complete"); +fn do_migrate(conn: PooledConn) -> PooledConn { + if MIGRATED.fetch_or(true, Ordering::SeqCst) { + return conn; + } + + tracing::info!("running migrations"); + + let mut harness = AsyncMigrationHarness::new(conn); + + let versions = harness + .run_pending_migrations(EmbeddedMigrationWrapper { + inner: &MIGRATIONS, }) - .await; + .expect("failed running migrations"); + + tracing::info!(ran = ?versions, "migrations complete"); + + harness.into_inner() } #[inline] async fn raw_connection() -> Result<deadpool_postgres::Object> { // HACK - if !MIGRATE.initialized() { + if !AtomicBool::load(&MIGRATED, Ordering::SeqCst) { let _ = connection().await?; } |
