pub struct DbCache<C = PostcardCodec>where
C: CacheCodec,{ /* private fields */ }Expand description
A database-oriented view over a HydraCache instance.
DbCache groups query result keys under a namespace while keeping all
cache storage, single-flight, tags, TTL, and stats in the shared local cache.
§Example
use std::time::Duration;
use hydracache::HydraCache;
use hydracache_db::DbCache;
use serde::{Deserialize, Serialize};
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
struct User {
id: i64,
name: String,
}
let local = HydraCache::local().build();
let queries = DbCache::new(local, "db");
let user = queries
.entity::<User>("user", 42)
// Later, invalidate_tag("user:42") removes this result.
.collection_tag("users")
.ttl(Duration::from_secs(60))
.fetch_with(|| async {
// Replace this block with code from sqlx, diesel, sea-orm, or any
// other database client. It is called only when the cache does not
// already contain "db:user:42" or when the cached value has expired.
Ok::<_, std::io::Error>(User {
id: 42,
name: "Ada".to_owned(),
})
})
.await?;
assert_eq!(user.id, 42);Implementations§
Source§impl<C> DbCache<C>where
C: CacheCodec,
impl<C> DbCache<C>where
C: CacheCodec,
Sourcepub fn new(cache: HydraCache<C>, namespace: impl Into<String>) -> DbCache<C>
pub fn new(cache: HydraCache<C>, namespace: impl Into<String>) -> DbCache<C>
Create a database query cache adapter over an existing local cache.
Sourcepub fn cache(&self) -> &HydraCache<C>
pub fn cache(&self) -> &HydraCache<C>
Return the underlying local cache.
Sourcepub fn cached<T>(&self) -> DbQuery<T, C>
pub fn cached<T>(&self) -> DbQuery<T, C>
Start describing a cacheable database-loaded value.
This is the preferred entry point when the query is already visible
inside the fetch_with loader through a database client, ORM, or
repository method.
Sourcepub fn cached_with<T>(&self, policy: QueryCachePolicy) -> DbQuery<T, C>
pub fn cached_with<T>(&self, policy: QueryCachePolicy) -> DbQuery<T, C>
Start describing a cacheable database-loaded value with a reusable
QueryCachePolicy.
This is useful when the same key/tag/TTL pattern is shared by a repository method, a SQLx call site, and a future ORM adapter.
Sourcepub fn entity<T>(&self, kind: impl ToString, id: impl ToString) -> DbQuery<T, C>
pub fn entity<T>(&self, kind: impl ToString, id: impl ToString) -> DbQuery<T, C>
Start describing an entity-shaped cached value.
This is a convenience layer over DbCache::cached that sets both the
logical key and the entity invalidation tag from escaped key segments.
For example, entity::<User>("user", 42) creates key user:42 and tag
user:42; with namespace db, the physical cache key is db:user:42.
§Example
use hydracache::HydraCache;
use hydracache_db::DbCache;
use serde::{Deserialize, Serialize};
#[derive(Debug, Clone, Serialize, Deserialize)]
struct User {
id: i64,
}
let queries = DbCache::new(HydraCache::local().build(), "db");
let query = queries.entity::<User>("user", 42);
assert_eq!(query.key_value(), Some("user:42"));
assert_eq!(query.tags_value(), &["user:42".to_owned()]);
assert_eq!(query.physical_key(), Some("db:user:42".to_owned()));Sourcepub fn for_entity<T>(&self, id: <T as CacheEntity>::Id) -> DbQuery<T, C>where
T: CacheEntity,
pub fn for_entity<T>(&self, id: <T as CacheEntity>::Id) -> DbQuery<T, C>where
T: CacheEntity,
Start describing an entity-shaped cached value from CacheEntity
metadata.
This helper removes repeated entity and collection literals from call
sites. It sets the logical key, entity tag, and optional collection tag
defined by T.
§Example
use hydracache::HydraCache;
use hydracache_db::{CacheEntity, DbCache};
use serde::{Deserialize, Serialize};
#[derive(Debug, Clone, Serialize, Deserialize)]
struct User {
id: i64,
}
impl CacheEntity for User {
type Id = i64;
const ENTITY: &'static str = "user";
const COLLECTION: Option<&'static str> = Some("users");
}
let queries = DbCache::new(HydraCache::local().build(), "db");
let query = queries.for_entity::<User>(42);
assert_eq!(query.key_value(), Some("user:42"));
assert_eq!(
query.tags_value(),
&["user:42".to_owned(), "users".to_owned()]
);Sourcepub fn collection<T>(&self, name: impl ToString) -> DbQuery<T, C>
pub fn collection<T>(&self, name: impl ToString) -> DbQuery<T, C>
Start describing a collection-shaped cached value.
This sets both the logical key and the collection invalidation tag to
the escaped collection name. For example, collection::<User>("users")
creates key users and tag users.
§Example
use hydracache::HydraCache;
use hydracache_db::DbCache;
use serde::{Deserialize, Serialize};
#[derive(Debug, Clone, Serialize, Deserialize)]
struct User {
id: i64,
}
let queries = DbCache::new(HydraCache::local().build(), "db");
let query = queries.collection::<User>("users:active");
assert_eq!(query.key_value(), Some("users%3Aactive"));
assert_eq!(query.tags_value(), &["users%3Aactive".to_owned()]);
assert_eq!(query.physical_key(), Some("db:users%3Aactive".to_owned()));Sourcepub fn named<T>(&self, name: impl Into<String>) -> DbQuery<T, C>
pub fn named<T>(&self, name: impl Into<String>) -> DbQuery<T, C>
Start describing a cacheable database-loaded value with a diagnostic name.
Sourcepub fn query_as<T>(&self, sql: impl Into<String>) -> DbQuery<T, C>
pub fn query_as<T>(&self, sql: impl Into<String>) -> DbQuery<T, C>
Start describing a cacheable SQL query result.
Prefer DbCache::cached or DbCache::named when writing new code.
This method remains useful if you want the SQL text itself to be the
diagnostic label for errors and logs.
Trait Implementations§
Source§impl<C> Clone for DbCache<C>where
C: CacheCodec,
impl<C> Clone for DbCache<C>where
C: CacheCodec,
Auto Trait Implementations§
impl<C = PostcardCodec> !RefUnwindSafe for DbCache<C>
impl<C = PostcardCodec> !UnwindSafe for DbCache<C>
impl<C> Freeze for DbCache<C>
impl<C> Send for DbCache<C>
impl<C> Sync for DbCache<C>
impl<C> Unpin for DbCache<C>
impl<C> UnsafeUnpin for DbCache<C>
Blanket Implementations§
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
Source§impl<T> CloneToUninit for Twhere
T: Clone,
impl<T> CloneToUninit for Twhere
T: Clone,
Source§impl<T> Instrument for T
impl<T> Instrument for T
Source§fn instrument(self, span: Span) -> Instrumented<Self>
fn instrument(self, span: Span) -> Instrumented<Self>
Source§fn in_current_span(self) -> Instrumented<Self>
fn in_current_span(self) -> Instrumented<Self>
Source§impl<T> IntoEither for T
impl<T> IntoEither for T
Source§fn into_either(self, into_left: bool) -> Either<Self, Self>
fn into_either(self, into_left: bool) -> Either<Self, Self>
self into a Left variant of Either<Self, Self>
if into_left is true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read moreSource§fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
self into a Left variant of Either<Self, Self>
if into_left(&self) returns true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read more