mirror of
https://github.com/launchbadge/sqlx
synced 2024-11-10 14:34:19 +00:00
Caching methods in Connection
This commit is contained in:
parent
eba82e3fc1
commit
2c2a277666
15 changed files with 74 additions and 74 deletions
|
@ -1,13 +0,0 @@
|
||||||
use futures_core::future::BoxFuture;
|
|
||||||
|
|
||||||
use crate::error::Error;
|
|
||||||
|
|
||||||
/// A connection that is capable of caching prepared statements.
|
|
||||||
pub trait CachingConnection: Send {
|
|
||||||
/// The number of statements currently cached in the connection.
|
|
||||||
fn cached_statements_count(&self) -> usize;
|
|
||||||
|
|
||||||
/// Removes all statements from the cache, closing them on the server if
|
|
||||||
/// needed.
|
|
||||||
fn clear_cached_statements(&mut self) -> BoxFuture<'_, Result<(), Error>>;
|
|
||||||
}
|
|
|
@ -49,6 +49,7 @@ impl<T> StatementCache<T> {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Clear all cached statements from the cache.
|
/// Clear all cached statements from the cache.
|
||||||
|
#[cfg(any(feature = "postgres", feature = "sqlite"))]
|
||||||
pub fn clear(&mut self) {
|
pub fn clear(&mut self) {
|
||||||
self.inner.clear();
|
self.inner.clear();
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,7 +3,7 @@ use std::str::FromStr;
|
||||||
use futures_core::future::BoxFuture;
|
use futures_core::future::BoxFuture;
|
||||||
use futures_core::Future;
|
use futures_core::Future;
|
||||||
|
|
||||||
use crate::database::Database;
|
use crate::database::{Database, HasStatementCache};
|
||||||
use crate::error::{BoxDynError, Error};
|
use crate::error::{BoxDynError, Error};
|
||||||
use crate::transaction::Transaction;
|
use crate::transaction::Transaction;
|
||||||
|
|
||||||
|
@ -64,6 +64,23 @@ pub trait Connection: Send {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// The number of statements currently cached in the connection.
|
||||||
|
fn cached_statements_size(&self) -> usize
|
||||||
|
where
|
||||||
|
Self::Database: HasStatementCache,
|
||||||
|
{
|
||||||
|
0
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Removes all statements from the cache, closing them on the server if
|
||||||
|
/// needed.
|
||||||
|
fn clear_cached_statements(&mut self) -> BoxFuture<'_, Result<(), Error>>
|
||||||
|
where
|
||||||
|
Self::Database: HasStatementCache,
|
||||||
|
{
|
||||||
|
Box::pin(async move { Ok(()) })
|
||||||
|
}
|
||||||
|
|
||||||
#[doc(hidden)]
|
#[doc(hidden)]
|
||||||
fn flush(&mut self) -> BoxFuture<'_, Result<(), Error>>;
|
fn flush(&mut self) -> BoxFuture<'_, Result<(), Error>>;
|
||||||
|
|
||||||
|
|
|
@ -74,3 +74,5 @@ pub trait HasArguments<'q> {
|
||||||
/// The concrete type used as a buffer for arguments while encoding.
|
/// The concrete type used as a buffer for arguments while encoding.
|
||||||
type ArgumentBuffer: Default;
|
type ArgumentBuffer: Default;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub trait HasStatementCache {}
|
||||||
|
|
|
@ -29,7 +29,6 @@ pub mod arguments;
|
||||||
#[macro_use]
|
#[macro_use]
|
||||||
pub mod pool;
|
pub mod pool;
|
||||||
|
|
||||||
pub mod caching_connection;
|
|
||||||
pub mod connection;
|
pub mod connection;
|
||||||
|
|
||||||
#[macro_use]
|
#[macro_use]
|
||||||
|
|
|
@ -6,7 +6,6 @@ use futures_core::future::BoxFuture;
|
||||||
use futures_util::FutureExt;
|
use futures_util::FutureExt;
|
||||||
use hashbrown::HashMap;
|
use hashbrown::HashMap;
|
||||||
|
|
||||||
use crate::caching_connection::CachingConnection;
|
|
||||||
use crate::common::StatementCache;
|
use crate::common::StatementCache;
|
||||||
use crate::connection::{Connect, Connection};
|
use crate::connection::{Connect, Connection};
|
||||||
use crate::error::Error;
|
use crate::error::Error;
|
||||||
|
@ -46,22 +45,6 @@ pub struct MySqlConnection {
|
||||||
scratch_row_column_names: Arc<HashMap<UStr, usize>>,
|
scratch_row_column_names: Arc<HashMap<UStr, usize>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl CachingConnection for MySqlConnection {
|
|
||||||
fn cached_statements_count(&self) -> usize {
|
|
||||||
self.cache_statement.len()
|
|
||||||
}
|
|
||||||
|
|
||||||
fn clear_cached_statements(&mut self) -> BoxFuture<'_, Result<(), Error>> {
|
|
||||||
Box::pin(async move {
|
|
||||||
while let Some(statement) = self.cache_statement.remove_lru() {
|
|
||||||
self.stream.send_packet(StmtClose { statement }).await?;
|
|
||||||
}
|
|
||||||
|
|
||||||
Ok(())
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Debug for MySqlConnection {
|
impl Debug for MySqlConnection {
|
||||||
fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
|
fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
|
||||||
f.debug_struct("MySqlConnection").finish()
|
f.debug_struct("MySqlConnection").finish()
|
||||||
|
@ -94,6 +77,20 @@ impl Connection for MySqlConnection {
|
||||||
self.stream.wait_until_ready().boxed()
|
self.stream.wait_until_ready().boxed()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn cached_statements_size(&self) -> usize {
|
||||||
|
self.cache_statement.len()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn clear_cached_statements(&mut self) -> BoxFuture<'_, Result<(), Error>> {
|
||||||
|
Box::pin(async move {
|
||||||
|
while let Some(statement) = self.cache_statement.remove_lru() {
|
||||||
|
self.stream.send_packet(StmtClose { statement }).await?;
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
#[doc(hidden)]
|
#[doc(hidden)]
|
||||||
fn should_flush(&self) -> bool {
|
fn should_flush(&self) -> bool {
|
||||||
!self.stream.wbuf.is_empty()
|
!self.stream.wbuf.is_empty()
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
use crate::database::{Database, HasArguments, HasValueRef};
|
use crate::database::{Database, HasArguments, HasStatementCache, HasValueRef};
|
||||||
use crate::mysql::value::{MySqlValue, MySqlValueRef};
|
use crate::mysql::value::{MySqlValue, MySqlValueRef};
|
||||||
use crate::mysql::{
|
use crate::mysql::{
|
||||||
MySqlArguments, MySqlConnection, MySqlRow, MySqlTransactionManager, MySqlTypeInfo,
|
MySqlArguments, MySqlConnection, MySqlRow, MySqlTransactionManager, MySqlTypeInfo,
|
||||||
|
@ -33,3 +33,5 @@ impl HasArguments<'_> for MySql {
|
||||||
|
|
||||||
type ArgumentBuffer = Vec<u8>;
|
type ArgumentBuffer = Vec<u8>;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl HasStatementCache for MySql {}
|
||||||
|
|
|
@ -5,7 +5,6 @@ use futures_core::future::BoxFuture;
|
||||||
use futures_util::{FutureExt, TryFutureExt};
|
use futures_util::{FutureExt, TryFutureExt};
|
||||||
use hashbrown::HashMap;
|
use hashbrown::HashMap;
|
||||||
|
|
||||||
use crate::caching_connection::CachingConnection;
|
|
||||||
use crate::common::StatementCache;
|
use crate::common::StatementCache;
|
||||||
use crate::connection::{Connect, Connection};
|
use crate::connection::{Connect, Connection};
|
||||||
use crate::error::Error;
|
use crate::error::Error;
|
||||||
|
@ -98,19 +97,6 @@ impl Debug for PgConnection {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl CachingConnection for PgConnection {
|
|
||||||
fn cached_statements_count(&self) -> usize {
|
|
||||||
self.cache_statement.len()
|
|
||||||
}
|
|
||||||
|
|
||||||
fn clear_cached_statements(&mut self) -> BoxFuture<'_, Result<(), Error>> {
|
|
||||||
Box::pin(async move {
|
|
||||||
self.cache_statement.clear();
|
|
||||||
Ok(())
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Connection for PgConnection {
|
impl Connection for PgConnection {
|
||||||
type Database = Postgres;
|
type Database = Postgres;
|
||||||
|
|
||||||
|
@ -134,6 +120,17 @@ impl Connection for PgConnection {
|
||||||
self.execute("/* SQLx ping */").map_ok(|_| ()).boxed()
|
self.execute("/* SQLx ping */").map_ok(|_| ()).boxed()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn cached_statements_size(&self) -> usize {
|
||||||
|
self.cache_statement.len()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn clear_cached_statements(&mut self) -> BoxFuture<'_, Result<(), Error>> {
|
||||||
|
Box::pin(async move {
|
||||||
|
self.cache_statement.clear();
|
||||||
|
Ok(())
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
#[doc(hidden)]
|
#[doc(hidden)]
|
||||||
fn flush(&mut self) -> BoxFuture<'_, Result<(), Error>> {
|
fn flush(&mut self) -> BoxFuture<'_, Result<(), Error>> {
|
||||||
self.wait_until_ready().boxed()
|
self.wait_until_ready().boxed()
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
use crate::database::{Database, HasArguments, HasValueRef};
|
use crate::database::{Database, HasArguments, HasStatementCache, HasValueRef};
|
||||||
use crate::postgres::arguments::PgArgumentBuffer;
|
use crate::postgres::arguments::PgArgumentBuffer;
|
||||||
use crate::postgres::value::{PgValue, PgValueRef};
|
use crate::postgres::value::{PgValue, PgValueRef};
|
||||||
use crate::postgres::{PgArguments, PgConnection, PgRow, PgTransactionManager, PgTypeInfo};
|
use crate::postgres::{PgArguments, PgConnection, PgRow, PgTransactionManager, PgTypeInfo};
|
||||||
|
@ -32,3 +32,5 @@ impl HasArguments<'_> for Postgres {
|
||||||
|
|
||||||
type ArgumentBuffer = PgArgumentBuffer;
|
type ArgumentBuffer = PgArgumentBuffer;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl HasStatementCache for Postgres {}
|
||||||
|
|
|
@ -6,7 +6,6 @@ use futures_util::future;
|
||||||
use hashbrown::HashMap;
|
use hashbrown::HashMap;
|
||||||
use libsqlite3_sys::sqlite3;
|
use libsqlite3_sys::sqlite3;
|
||||||
|
|
||||||
use crate::caching_connection::CachingConnection;
|
|
||||||
use crate::common::StatementCache;
|
use crate::common::StatementCache;
|
||||||
use crate::connection::{Connect, Connection};
|
use crate::connection::{Connect, Connection};
|
||||||
use crate::error::Error;
|
use crate::error::Error;
|
||||||
|
@ -49,19 +48,6 @@ impl Debug for SqliteConnection {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl CachingConnection for SqliteConnection {
|
|
||||||
fn cached_statements_count(&self) -> usize {
|
|
||||||
self.statements.len()
|
|
||||||
}
|
|
||||||
|
|
||||||
fn clear_cached_statements(&mut self) -> BoxFuture<'_, Result<(), Error>> {
|
|
||||||
Box::pin(async move {
|
|
||||||
self.statements.clear();
|
|
||||||
Ok(())
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Connection for SqliteConnection {
|
impl Connection for SqliteConnection {
|
||||||
type Database = Sqlite;
|
type Database = Sqlite;
|
||||||
|
|
||||||
|
@ -75,6 +61,17 @@ impl Connection for SqliteConnection {
|
||||||
Box::pin(future::ok(()))
|
Box::pin(future::ok(()))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn cached_statements_size(&self) -> usize {
|
||||||
|
self.statements.len()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn clear_cached_statements(&mut self) -> BoxFuture<'_, Result<(), Error>> {
|
||||||
|
Box::pin(async move {
|
||||||
|
self.statements.clear();
|
||||||
|
Ok(())
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
#[doc(hidden)]
|
#[doc(hidden)]
|
||||||
fn flush(&mut self) -> BoxFuture<'_, Result<(), Error>> {
|
fn flush(&mut self) -> BoxFuture<'_, Result<(), Error>> {
|
||||||
// For SQLite, FLUSH does effectively nothing
|
// For SQLite, FLUSH does effectively nothing
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
use crate::database::{Database, HasArguments, HasValueRef};
|
use crate::database::{Database, HasArguments, HasStatementCache, HasValueRef};
|
||||||
use crate::sqlite::{
|
use crate::sqlite::{
|
||||||
SqliteArgumentValue, SqliteArguments, SqliteConnection, SqliteRow, SqliteTransactionManager,
|
SqliteArgumentValue, SqliteArguments, SqliteConnection, SqliteRow, SqliteTransactionManager,
|
||||||
SqliteTypeInfo, SqliteValue, SqliteValueRef,
|
SqliteTypeInfo, SqliteValue, SqliteValueRef,
|
||||||
|
@ -33,3 +33,5 @@ impl<'q> HasArguments<'q> for Sqlite {
|
||||||
|
|
||||||
type ArgumentBuffer = Vec<SqliteArgumentValue<'q>>;
|
type ArgumentBuffer = Vec<SqliteArgumentValue<'q>>;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl HasStatementCache for Sqlite {}
|
||||||
|
|
|
@ -1,7 +1,6 @@
|
||||||
#![cfg_attr(docsrs, feature(doc_cfg))]
|
#![cfg_attr(docsrs, feature(doc_cfg))]
|
||||||
|
|
||||||
pub use sqlx_core::arguments::{Arguments, IntoArguments};
|
pub use sqlx_core::arguments::{Arguments, IntoArguments};
|
||||||
pub use sqlx_core::caching_connection::CachingConnection;
|
|
||||||
pub use sqlx_core::connection::{Connect, Connection};
|
pub use sqlx_core::connection::{Connect, Connection};
|
||||||
pub use sqlx_core::database::{self, Database};
|
pub use sqlx_core::database::{self, Database};
|
||||||
pub use sqlx_core::executor::{Execute, Executor};
|
pub use sqlx_core::executor::{Execute, Executor};
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
use futures::TryStreamExt;
|
use futures::TryStreamExt;
|
||||||
use sqlx::mysql::{MySql, MySqlPool, MySqlRow};
|
use sqlx::mysql::{MySql, MySqlPool, MySqlRow};
|
||||||
use sqlx::{CachingConnection, Connection, Executor, Row};
|
use sqlx::{Connection, Executor, Row};
|
||||||
use sqlx_test::new;
|
use sqlx_test::new;
|
||||||
|
|
||||||
#[sqlx_macros::test]
|
#[sqlx_macros::test]
|
||||||
|
@ -193,9 +193,9 @@ async fn it_caches_statements() -> anyhow::Result<()> {
|
||||||
assert_eq!(i, val);
|
assert_eq!(i, val);
|
||||||
}
|
}
|
||||||
|
|
||||||
assert_eq!(1, conn.cached_statements_count());
|
assert_eq!(1, conn.cached_statements_size());
|
||||||
conn.clear_cached_statements().await?;
|
conn.clear_cached_statements().await?;
|
||||||
assert_eq!(0, conn.cached_statements_count());
|
assert_eq!(0, conn.cached_statements_size());
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,7 +1,6 @@
|
||||||
use futures::TryStreamExt;
|
use futures::TryStreamExt;
|
||||||
use sqlx::postgres::PgRow;
|
use sqlx::postgres::PgRow;
|
||||||
use sqlx::postgres::{PgDatabaseError, PgErrorPosition, PgSeverity};
|
use sqlx::postgres::{PgDatabaseError, PgErrorPosition, PgSeverity};
|
||||||
use sqlx::CachingConnection;
|
|
||||||
use sqlx::{postgres::Postgres, Connection, Executor, PgPool, Row};
|
use sqlx::{postgres::Postgres, Connection, Executor, PgPool, Row};
|
||||||
use sqlx_test::new;
|
use sqlx_test::new;
|
||||||
use std::time::Duration;
|
use std::time::Duration;
|
||||||
|
@ -504,9 +503,9 @@ async fn it_caches_statements() -> anyhow::Result<()> {
|
||||||
assert_eq!(i, val);
|
assert_eq!(i, val);
|
||||||
}
|
}
|
||||||
|
|
||||||
assert_eq!(1, conn.cached_statements_count());
|
assert_eq!(1, conn.cached_statements_size());
|
||||||
conn.clear_cached_statements().await?;
|
conn.clear_cached_statements().await?;
|
||||||
assert_eq!(0, conn.cached_statements_count());
|
assert_eq!(0, conn.cached_statements_size());
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,7 +1,6 @@
|
||||||
use futures::TryStreamExt;
|
use futures::TryStreamExt;
|
||||||
use sqlx::{
|
use sqlx::{
|
||||||
query, sqlite::Sqlite, CachingConnection, Connect, Connection, Executor, Row, SqliteConnection,
|
query, sqlite::Sqlite, Connect, Connection, Executor, Row, SqliteConnection, SqlitePool,
|
||||||
SqlitePool,
|
|
||||||
};
|
};
|
||||||
use sqlx_test::new;
|
use sqlx_test::new;
|
||||||
|
|
||||||
|
@ -286,9 +285,9 @@ async fn it_caches_statements() -> anyhow::Result<()> {
|
||||||
assert_eq!(i, val);
|
assert_eq!(i, val);
|
||||||
}
|
}
|
||||||
|
|
||||||
assert_eq!(1, conn.cached_statements_count());
|
assert_eq!(1, conn.cached_statements_size());
|
||||||
conn.clear_cached_statements().await?;
|
conn.clear_cached_statements().await?;
|
||||||
assert_eq!(0, conn.cached_statements_count());
|
assert_eq!(0, conn.cached_statements_size());
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue