oxisql-cache 0.4.1

SQL query-result and prepared-statement plan caching for oxisql (LRU + TTL, backed by oxistore-cache)
Documentation
  • Coverage
  • 100%
    44 out of 44 items documented3 out of 39 items with examples
  • Size
  • Source code size: 38.9 kB This is the summed size of all the files inside the crates.io package for this release.
  • Documentation size: 271.5 kB This is the summed size of all files generated by rustdoc for all configured targets
  • Ø build duration
  • this release: 9s Average build duration of successful builds.
  • all releases: 9s Average build duration of successful builds in releases after 2024-10-23.
  • Links
  • cool-japan/oxisql
    2 0 0
  • crates.io
  • Dependencies
  • Versions
  • Owners
  • cool-japan

oxisql-cache — SQL query-result and prepared-plan caching for OxiSQL

Crates.io License

LRU + TTL caching for SQL query result sets and prepared-statement plans, built on top of oxistore-cache's Pure-Rust LRU primitive.

Status: Stable.

What it is

oxisql-cache provides two focused caches for oxisql-backed connections:

  • SqlQueryCache — caches RowSet results, keyed by normalised SQL text.
  • SqlPlanCache<P> — caches an opaque, caller-supplied prepared-statement representation P (a compiled plan, a byte buffer, or any Clone type).

Both support optional per-entry TTL and are wrapped by CachedQueryRunner, a read-through adapter that turns any FnMut(&str) -> Result<RowSet, E> executor into a caching one.

This crate supersedes the former sql feature of oxistore-cache. The SQL-layer cache types now live on the oxisql side of the dependency graph — oxisql-cache depends on oxistore-cache, not the other way around — which breaks the cross-repo dependency cycle that previously existed between the oxisql and oxistore repositories.

Neither cache is thread-safe on its own; wrap one in oxistore_cache::sync::SyncCache or oxistore_cache::sharded::ShardedCache for concurrent use.

Installation

[dependencies]
oxisql-cache = "0.4.1"

MSRV 1.89 · edition 2021 · Apache-2.0 · #![forbid(unsafe_code)].

Quick start

use oxisql_core::{Row, RowSet, Value};
use oxisql_cache::SqlQueryCache;

let mut cache = SqlQueryCache::new(256);
let rows = vec![Row::new(vec!["id".into()], vec![Value::I64(1)])];
let rs = RowSet::from_rows(rows);
cache.put("SELECT id FROM t WHERE id = 1", rs.clone());

// Equivalent queries (different whitespace/case) hit the same entry.
assert!(cache.get("select  id  from  t  where  id = 1").is_some());

Read-through caching with CachedQueryRunner

use oxisql_core::{Row, RowSet, Value};
use oxisql_cache::CachedQueryRunner;

let mut runner = CachedQueryRunner::new(32, |sql: &str| -> Result<RowSet, String> {
    // Simulated DB hit.
    Ok(RowSet::from_rows(vec![Row::new(vec!["n".into()], vec![Value::I64(1)])]))
});

let r1 = runner.run("SELECT 1").unwrap();
let r2 = runner.run("SELECT 1").unwrap(); // served from cache
assert_eq!(r1.len(), r2.len());
assert_eq!(runner.hits(), 1);
assert_eq!(runner.misses(), 1);

Key API

Item Description
SqlQueryCache::new(capacity) New LRU query-result cache
SqlQueryCache::get(sql) / put(sql, rows) / put_with_ttl(sql, rows, ttl) Lookup / insert / insert-with-expiry
SqlQueryCache::invalidate(sql) / clear() / contains(sql) Explicit eviction and membership check
SqlQueryCache::stats() QueryCacheStats snapshot (hits, misses, len, cap)
SqlPlanCache::<P>::new(capacity) New LRU plan cache, generic over the plan type P
SqlPlanCache::get/put/put_with_ttl/invalidate/clear/contains Same shape as SqlQueryCache, returning &P on lookup
SqlPlanCache::hits() / misses() / hit_rate() Running hit/miss counters
CachedQueryRunner::new(capacity, executor) Wrap an executor closure with a SqlQueryCache
CachedQueryRunner::run(sql) / run_with_ttl(sql, ttl) Execute-or-serve-from-cache
CachedQueryRunner::invalidate(sql) / clear() / hits() / misses() / stats() Cache management + counters

Cache keys are normalised SQL text: leading/trailing whitespace trimmed, internal whitespace runs collapsed to a single space, and ASCII letters upper-cased — so select id from t and SELECT ID FROM T share the same entry.

Test coverage

23 unit tests + 3 doc tests pass, 0 failed, covering key normalisation, hit/miss accounting, TTL expiry, resizing, invalidation, and the CachedQueryRunner read-through path (including executor-error propagation).

See also

This crate is part of the OxiSQL Pure-Rust workspace. See the workspace README. The underlying eviction primitives (LRU, ARC, LFU, W-TinyLFU) live in oxistore-cache.

License

Apache-2.0 — Copyright © 2024–2026 COOLJAPAN OU (Team Kitasan).