pub struct DbQuery<T, C = PostcardCodec>where
C: CacheCodec,{ /* private fields */ }Expand description
A cacheable database query descriptor.
The descriptor is deliberately explicit: callers choose the key, tags, and
TTL that match their freshness model. An operation name is optional and used
only for diagnostics. fetch_with executes the supplied loader only on a
cache miss.
Implementations§
Source§impl<T, C> DbQuery<T, C>where
C: CacheCodec,
impl<T, C> DbQuery<T, C>where
C: CacheCodec,
Sourcepub fn with_name(self, name: impl Into<String>) -> DbQuery<T, C>
pub fn with_name(self, name: impl Into<String>) -> DbQuery<T, C>
Set or replace the diagnostic operation name.
Sourcepub fn physical_key(&self) -> Option<String>
pub fn physical_key(&self) -> Option<String>
Return the physical cache key, including the adapter namespace.
Return the configured tags.
Sourcepub fn key(self, key: impl Into<String>) -> DbQuery<T, C>
pub fn key(self, key: impl Into<String>) -> DbQuery<T, C>
Set the logical cache key for this query result.
Sourcepub fn key_builder(self, key: CacheKeyBuilder) -> DbQuery<T, C>
pub fn key_builder(self, key: CacheKeyBuilder) -> DbQuery<T, C>
Set the logical cache key from a segmented key builder.
Sourcepub fn for_entity(self, kind: impl ToString, id: impl ToString) -> DbQuery<T, C>
pub fn for_entity(self, kind: impl ToString, id: impl ToString) -> DbQuery<T, C>
Set the logical key and add an entity invalidation tag.
for_entity("user", 42) sets the key to user:42 and adds the tag
user:42. Both segments are escaped with CacheKeyBuilder, so : and
% inside one segment cannot accidentally create extra key segments.
§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
.cached::<User>()
.tag("users")
.for_entity("user", 42);
assert_eq!(query.key_value(), Some("user:42"));
assert_eq!(
query.tags_value(),
&["users".to_owned(), "user:42".to_owned()]
);Sourcepub fn for_cache_entity(self, id: <T as CacheEntity>::Id) -> DbQuery<T, C>where
T: CacheEntity,
pub fn for_cache_entity(self, id: <T as CacheEntity>::Id) -> DbQuery<T, C>where
T: CacheEntity,
Set the logical key and tags from CacheEntity metadata.
This is the metadata-driven equivalent of DbQuery::for_entity. It
preserves any existing tags, then adds the 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
.cached::<User>()
.tag("tenant:7")
.for_cache_entity(42);
assert_eq!(query.key_value(), Some("user:42"));
assert_eq!(
query.tags_value(),
&[
"tenant:7".to_owned(),
"user:42".to_owned(),
"users".to_owned()
]
);Sourcepub fn collection_tag(self, name: impl ToString) -> DbQuery<T, C>
pub fn collection_tag(self, name: impl ToString) -> DbQuery<T, C>
Add a collection invalidation tag from one escaped key segment.
Use this with DbCache::entity or DbQuery::for_entity when one
entity result also belongs to a broader list or query group.
§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)
.collection_tag("users:active");
assert_eq!(
query.tags_value(),
&["user:42".to_owned(), "users%3Aactive".to_owned()]
);Add several invalidation tags.
Sourcepub fn tag_set(self, tags: TagSet) -> DbQuery<T, C>
pub fn tag_set(self, tags: TagSet) -> DbQuery<T, C>
Replace invalidation tags from a reusable TagSet.
Sourcepub async fn fetch_with<E, F, Fut>(self, loader: F) -> Result<T, DbCacheError>
pub async fn fetch_with<E, F, Fut>(self, loader: F) -> Result<T, DbCacheError>
Fetch a cached value or run the supplied database loader on miss.
The loader is intentionally caller-supplied so the database library remains responsible for pools, transactions, compile-time checked queries, and row mapping. HydraCache owns only the cache boundary.
Sourcepub async fn fetch_value_with<U, E, F, Fut>(
self,
loader: F,
) -> Result<U, DbCacheError>
pub async fn fetch_value_with<U, E, F, Fut>( self, loader: F, ) -> Result<U, DbCacheError>
Fetch a cached value with an output type chosen by an adapter.
Most application code should use DbQuery::fetch_with. This method is
intended for adapter crates that keep the descriptor type focused on a
database row while caching shapes such as Option<T> or Vec<T>.
Trait Implementations§
Source§impl<T, C> Clone for DbQuery<T, C>where
C: CacheCodec,
impl<T, C> Clone for DbQuery<T, C>where
C: CacheCodec,
Source§impl<T, C> Debug for DbQuery<T, C>where
C: CacheCodec,
impl<T, C> Debug for DbQuery<T, C>where
C: CacheCodec,
Source§impl<T, C> SqlxQueryExt<T, C> for DbQuery<T, C>where
C: CacheCodec,
impl<T, C> SqlxQueryExt<T, C> for DbQuery<T, C>where
C: CacheCodec,
Source§fn fetch_one<'q, 'async_trait, DB, A, E>(
self,
executor: E,
query: QueryAs<'q, DB, T, A>,
) -> Pin<Box<dyn Future<Output = Result<T>> + Send + 'async_trait>>where
T: Serialize + DeserializeOwned + Send + Unpin + for<'r> FromRow<'r, DB::Row> + 'static,
DB: Database + Send + Sync + 'static + 'async_trait,
A: IntoArguments<'q, DB> + Send + 'static + 'async_trait,
E: Send + Sync + 'static + 'async_trait,
for<'c> &'c E: Executor<'c, Database = DB>,
Self: 'async_trait,
'q: 'static + 'async_trait,
fn fetch_one<'q, 'async_trait, DB, A, E>(
self,
executor: E,
query: QueryAs<'q, DB, T, A>,
) -> Pin<Box<dyn Future<Output = Result<T>> + Send + 'async_trait>>where
T: Serialize + DeserializeOwned + Send + Unpin + for<'r> FromRow<'r, DB::Row> + 'static,
DB: Database + Send + Sync + 'static + 'async_trait,
A: IntoArguments<'q, DB> + Send + 'static + 'async_trait,
E: Send + Sync + 'static + 'async_trait,
for<'c> &'c E: Executor<'c, Database = DB>,
Self: 'async_trait,
'q: 'static + 'async_trait,
Source§fn fetch_optional<'q, 'async_trait, DB, A, E>(
self,
executor: E,
query: QueryAs<'q, DB, T, A>,
) -> Pin<Box<dyn Future<Output = Result<Option<T>>> + Send + 'async_trait>>where
T: Serialize + DeserializeOwned + Send + Unpin + for<'r> FromRow<'r, DB::Row> + 'static,
DB: Database + Send + Sync + 'static + 'async_trait,
A: IntoArguments<'q, DB> + Send + 'static + 'async_trait,
E: Send + Sync + 'static + 'async_trait,
for<'c> &'c E: Executor<'c, Database = DB>,
Self: 'async_trait,
'q: 'static + 'async_trait,
fn fetch_optional<'q, 'async_trait, DB, A, E>(
self,
executor: E,
query: QueryAs<'q, DB, T, A>,
) -> Pin<Box<dyn Future<Output = Result<Option<T>>> + Send + 'async_trait>>where
T: Serialize + DeserializeOwned + Send + Unpin + for<'r> FromRow<'r, DB::Row> + 'static,
DB: Database + Send + Sync + 'static + 'async_trait,
A: IntoArguments<'q, DB> + Send + 'static + 'async_trait,
E: Send + Sync + 'static + 'async_trait,
for<'c> &'c E: Executor<'c, Database = DB>,
Self: 'async_trait,
'q: 'static + 'async_trait,
None.Source§fn fetch_all<'q, 'async_trait, DB, A, E>(
self,
executor: E,
query: QueryAs<'q, DB, T, A>,
) -> Pin<Box<dyn Future<Output = Result<Vec<T>>> + Send + 'async_trait>>where
T: Serialize + DeserializeOwned + Send + Unpin + for<'r> FromRow<'r, DB::Row> + 'static,
DB: Database + Send + Sync + 'static + 'async_trait,
A: IntoArguments<'q, DB> + Send + 'static + 'async_trait,
E: Send + Sync + 'static + 'async_trait,
for<'c> &'c E: Executor<'c, Database = DB>,
Self: 'async_trait,
'q: 'static + 'async_trait,
fn fetch_all<'q, 'async_trait, DB, A, E>(
self,
executor: E,
query: QueryAs<'q, DB, T, A>,
) -> Pin<Box<dyn Future<Output = Result<Vec<T>>> + Send + 'async_trait>>where
T: Serialize + DeserializeOwned + Send + Unpin + for<'r> FromRow<'r, DB::Row> + 'static,
DB: Database + Send + Sync + 'static + 'async_trait,
A: IntoArguments<'q, DB> + Send + 'static + 'async_trait,
E: Send + Sync + 'static + 'async_trait,
for<'c> &'c E: Executor<'c, Database = DB>,
Self: 'async_trait,
'q: 'static + 'async_trait,
Auto Trait Implementations§
impl<T, C> Freeze for DbQuery<T, C>
impl<T, C = PostcardCodec> !RefUnwindSafe for DbQuery<T, C>
impl<T, C> Send for DbQuery<T, C>
impl<T, C> Sync for DbQuery<T, C>
impl<T, C> Unpin for DbQuery<T, C>
impl<T, C> UnsafeUnpin for DbQuery<T, C>
impl<T, C = PostcardCodec> !UnwindSafe for DbQuery<T, 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