HydraCache 0.27.0
HydraCache 0.27.0
Status: published.
Validated and published on 2026-06-12.
0.27.0 focuses on prepared database query cache policies. The goal is to make
repository-style database caching easier to reuse and cheaper on hot paths by
precomputing stable metadata once.
Highlights
- Added database-neutral prepared policy/descriptor API in
hydracache-db. - Precomputed diagnostic names, TTLs, static keys, entity key prefixes, and
collection tags. - Added prepared
DbCachedescriptors that bind dynamic ids into ordinaryDbQuery
values. - Added SQLx re-exports and examples that use the adapter-neutral prepared path.
- Added real Postgres testcontainers coverage and real SQLite in-memory integration
coverage. - Added README, rustdoc, and testing-doc updates for future Diesel and SeaORM
wrappers.
Intended Shape
Application code should be able to prepare stable metadata once:
use std::time::Duration;
use hydracache::HydraCache;
use hydracache_db::{DbCache, HydraCacheEntity, PreparedQueryPolicy};
use serde::{Deserialize, Serialize};
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize, HydraCacheEntity)]
#[hydracache(entity = "user", collection = "users", id = i64)]
struct User {
id: i64,
name: String,
}
# async fn example() -> hydracache_db::Result<()> {
let queries = DbCache::new(HydraCache::local().build(), "db");
let load_user = queries.prepare::<User>(
PreparedQueryPolicy::for_cache_entity::<User>()
.with_name("load-user")
.ttl(Duration::from_secs(60)),
);
let user = load_user
.load_id(42, || async {
Ok::<_, std::io::Error>(User {
id: 42,
name: "Ada".to_owned(),
})
})
.await?;
assert_eq!(user.id, 42);
# Ok(())
# }The loader remains caller-owned, so SQLx, Diesel, SeaORM, or a hand-written
repository can still own database execution and row mapping.
SQLx users can execute the prepared descriptor through the existing
SqlxQueryExt helpers:
use hydracache_sqlx::{PreparedQueryPolicy, SqlxQueryExt};
# async fn example(
# queries: hydracache_sqlx::DbCache,
# pool: sqlx::PgPool,
# ) -> hydracache_sqlx::Result<()> {
let load_user = queries.prepare::<(i64, String)>(
PreparedQueryPolicy::for_cache_entity::<User>().with_name("load-user"),
);
let (id, name) = load_user
.for_id(42)
.fetch_one(
pool.clone(),
sqlx::query_as("select id, name from users where id = $1").bind(42_i64),
)
.await?;
assert_eq!(id, 42);
assert!(!name.is_empty());
# Ok(())
# }Validation
Focused checks:
cargo test -p hydracache-db --locked prepared
cargo test -p hydracache-sqlx --locked prepared
cargo test -p hydracache-sqlx --test sqlite_prepared --locked
cargo test -p hydracache-sqlx --test postgres_testcontainers --locked
cargo test --doc -p hydracache-db --locked
cargo test --doc -p hydracache-sqlx --lockedFull release gate passed:
cargo fmt --all -- --check
cargo check --workspace --all-targets --locked
cargo test --workspace --locked
cargo clippy --workspace --all-targets --all-features --locked -- -D warnings
cargo test --doc --workspace --locked
$env:RUSTDOCFLAGS='-D warnings'; cargo doc --workspace --no-deps --lockedBootstrap package dry-run passed:
.\scripts\package-publishable.ps1 -Set bootstrap -AllowDirtyFor staged publishing, publish hydracache-core and hydracache-macros first,
wait for the crates.io index to update, then run the runtime and adapter package
checks before publishing those sets.
Published packages:
hydracache-core 0.27.0hydracache-macros 0.27.0hydracache 0.27.0hydracache-cluster-chitchat 0.27.0hydracache-cluster-raft 0.27.0hydracache-cluster 0.27.0hydracache-cluster-transport-axum 0.27.0hydracache-observability 0.27.0hydracache-actuator-axum 0.27.0hydracache-db 0.27.0hydracache-sqlx 0.27.0
hydracache-sandbox remains publish = false; it is a local/manual sandbox,
not a crates.io package.
See
the 0.27.0 plan
for the implementation checklist.