diff --git a/contrib/sync_db_pools/lib/Cargo.toml b/contrib/sync_db_pools/lib/Cargo.toml index 7d2a027f..765ece2e 100644 --- a/contrib/sync_db_pools/lib/Cargo.toml +++ b/contrib/sync_db_pools/lib/Cargo.toml @@ -19,7 +19,7 @@ diesel_postgres_pool = ["diesel/postgres", "diesel/r2d2"] diesel_mysql_pool = ["diesel/mysql", "diesel/r2d2"] sqlite_pool = ["rusqlite", "r2d2_sqlite"] postgres_pool = ["postgres", "r2d2_postgres"] -memcache_pool = ["memcache", "r2d2-memcache"] +memcache_pool = ["memcache"] [dependencies] r2d2 = "0.8" @@ -34,8 +34,7 @@ r2d2_postgres = { version = "0.18", optional = true } rusqlite = { version = "0.31.0", optional = true } r2d2_sqlite = { version = "0.24.0", optional = true } -memcache = { version = "0.15.2", optional = true } -r2d2-memcache = { version = "0.6", optional = true } +memcache = { version = "0.17.2", optional = true } [dependencies.rocket_sync_db_pools_codegen] version = "0.1.0" diff --git a/contrib/sync_db_pools/lib/src/lib.rs b/contrib/sync_db_pools/lib/src/lib.rs index e68ed581..7c35e3b0 100644 --- a/contrib/sync_db_pools/lib/src/lib.rs +++ b/contrib/sync_db_pools/lib/src/lib.rs @@ -318,7 +318,7 @@ //! | MySQL | [Diesel] | `2` | [`diesel::MysqlConnection`] | `diesel_mysql_pool` | //! | Postgres | [Rust-Postgres] | `0.19` | [`postgres::Client`] | `postgres_pool` | //! | Sqlite | [`Rusqlite`] | `0.31` | [`rusqlite::Connection`] | `sqlite_pool` | -//! | Memcache | [`memcache`] | `0.15` | [`memcache::Client`] | `memcache_pool` | +//! | Memcache | [`memcache`] | `0.17` | [`memcache::Client`] | `memcache_pool` | //! //! [Diesel]: https://diesel.rs //! [`diesel::SqliteConnection`]: https://docs.rs/diesel/2/diesel/sqlite/struct.SqliteConnection.html @@ -327,10 +327,10 @@ //! [Rust-Postgres]: https://github.com/sfackler/rust-postgres //! [`postgres::Client`]: https://docs.rs/postgres/0.19/postgres/struct.Client.html //! [`Rusqlite`]: https://github.com/jgallagher/rusqlite -//! [`rusqlite::Connection`]: https://docs.rs/rusqlite/0.27/rusqlite/struct.Connection.html +//! [`rusqlite::Connection`]: https://docs.rs/rusqlite/0.31/rusqlite/struct.Connection.html //! [`diesel::PgConnection`]: http://docs.diesel.rs/diesel/pg/struct.PgConnection.html //! [`memcache`]: https://github.com/aisk/rust-memcache -//! [`memcache::Client`]: https://docs.rs/memcache/0.15/memcache/struct.Client.html +//! [`memcache::Client`]: https://docs.rs/memcache/0.17/memcache/struct.Client.html //! //! The above table lists all the supported database adapters in this library. //! In order to use particular `Poolable` type that's included in this library, @@ -372,7 +372,6 @@ pub use diesel; #[cfg(feature = "sqlite_pool")] pub use r2d2_sqlite; #[cfg(feature = "memcache_pool")] pub use memcache; -#[cfg(feature = "memcache_pool")] pub use r2d2_memcache; pub use r2d2; diff --git a/contrib/sync_db_pools/lib/src/poolable.rs b/contrib/sync_db_pools/lib/src/poolable.rs index ebe50994..8700f6b9 100644 --- a/contrib/sync_db_pools/lib/src/poolable.rs +++ b/contrib/sync_db_pools/lib/src/poolable.rs @@ -13,11 +13,12 @@ use crate::{Config, Error}; /// /// Implementations of `Poolable` are provided for the following types: /// -/// * `diesel::MysqlConnection` -/// * `diesel::PgConnection` -/// * `diesel::SqliteConnection` -/// * `postgres::Connection` -/// * `rusqlite::Connection` +/// * [`diesel::MysqlConnection`](diesel::MysqlConnection) +/// * [`diesel::PgConnection`](diesel::PgConnection) +/// * [`diesel::SqliteConnection`](diesel::SqliteConnection) +/// * [`postgres::Client`](postgres::Client) +/// * [`rusqlite::Connection`](rusqlite::Connection) +/// * [`memcache::Client`](memcache::Client) /// /// # Implementation Guide /// @@ -263,19 +264,52 @@ impl Poolable for rusqlite::Connection { } #[cfg(feature = "memcache_pool")] -impl Poolable for memcache::Client { - type Manager = r2d2_memcache::MemcacheConnectionManager; - // Unused, but we might want it in the future without a breaking change. - type Error = memcache::MemcacheError; +mod memcache_pool { + use memcache::{Client, Connectable, MemcacheError}; - fn pool(db_name: &str, rocket: &Rocket) -> PoolResult { - let config = Config::from(db_name, rocket)?; - let manager = r2d2_memcache::MemcacheConnectionManager::new(&*config.url); - let pool = r2d2::Pool::builder() - .max_size(config.pool_size) - .connection_timeout(Duration::from_secs(config.timeout as u64)) - .build(manager)?; + use super::*; - Ok(pool) + #[derive(Debug)] + pub struct ConnectionManager { + urls: Vec, + } + + impl ConnectionManager { + pub fn new(target: C) -> Self { + Self { urls: target.get_urls(), } + } + } + + impl r2d2::ManageConnection for ConnectionManager { + type Connection = Client; + type Error = MemcacheError; + + fn connect(&self) -> Result { + Client::connect(self.urls.clone()) + } + + fn is_valid(&self, connection: &mut Client) -> Result<(), MemcacheError> { + connection.version().map(|_| ()) + } + + fn has_broken(&self, _connection: &mut Client) -> bool { + false + } + } + + impl super::Poolable for memcache::Client { + type Manager = ConnectionManager; + type Error = MemcacheError; + + fn pool(db_name: &str, rocket: &Rocket) -> PoolResult { + let config = Config::from(db_name, rocket)?; + let manager = ConnectionManager::new(&*config.url); + let pool = r2d2::Pool::builder() + .max_size(config.pool_size) + .connection_timeout(Duration::from_secs(config.timeout as u64)) + .build(manager)?; + + Ok(pool) + } } } diff --git a/contrib/sync_db_pools/lib/tests/databases.rs b/contrib/sync_db_pools/lib/tests/databases.rs index ae72a6c2..9a58c791 100644 --- a/contrib/sync_db_pools/lib/tests/databases.rs +++ b/contrib/sync_db_pools/lib/tests/databases.rs @@ -11,6 +11,16 @@ mod databases_tests { struct PrimaryDb(diesel::PgConnection); } +#[cfg(feature = "memcache_pool")] +mod memcache_pool_tests { + #![allow(dead_code)] + + use rocket_sync_db_pools::database; + + #[database("test_db")] + struct MemcacheDb(memcache::Client); +} + #[cfg(test)] #[cfg(all(feature = "sqlite_pool"))] mod rusqlite_integration_test {