pub struct KvStore { /* private fields */ }Expand description
PostgreSQL-backed key-value store.
Provides a simple get/set/delete/set_if_absent/increment API over
forge_kv and forge_kv_counters tables. All operations are atomic.
TTLs are enforced both at read time (expired keys return None) and
via periodic cleanup.
Keys are automatically namespaced with the configured prefix to prevent collisions between different subsystems sharing the same database.
Implementations§
Source§impl KvStore
impl KvStore
pub fn new(pool: PgPool, namespace: &'static str) -> Self
Sourcepub async fn get(&self, key: &str) -> Result<Option<Vec<u8>>>
pub async fn get(&self, key: &str) -> Result<Option<Vec<u8>>>
Get a value by key. Returns None if the key doesn’t exist or is expired.
Sourcepub async fn set(
&self,
key: &str,
value: &[u8],
ttl: Option<Duration>,
) -> Result<()>
pub async fn set( &self, key: &str, value: &[u8], ttl: Option<Duration>, ) -> Result<()>
Set a key to a value. Overwrites any existing value.
Sourcepub async fn set_if_absent(
&self,
key: &str,
value: &[u8],
ttl: Option<Duration>,
) -> Result<bool>
pub async fn set_if_absent( &self, key: &str, value: &[u8], ttl: Option<Duration>, ) -> Result<bool>
Set a key only if it doesn’t already exist (or is expired).
Returns true if the key was set, false if it already existed.
Uses ON CONFLICT DO UPDATE ... WHERE to atomically treat expired rows
as absent within a single statement (no CTE snapshot isolation issues).
Sourcepub async fn delete(&self, key: &str) -> Result<bool>
pub async fn delete(&self, key: &str) -> Result<bool>
Delete a key. Returns true if the key existed.
Sourcepub async fn increment(
&self,
key: &str,
delta: i64,
ttl: Option<Duration>,
) -> Result<i64>
pub async fn increment( &self, key: &str, delta: i64, ttl: Option<Duration>, ) -> Result<i64>
Atomically increment a counter by delta. Creates the counter at 0 if
it doesn’t exist. Returns the new value. When ttl is None, an
existing counter’s TTL is preserved (pass Some to override it).
Expired counters are treated as non-existent (value resets to delta).
Uses ON CONFLICT DO UPDATE ... WHERE to handle expired rows atomically
without CTE snapshot isolation issues.
Sourcepub async fn cleanup_expired(&self) -> Result<u64>
pub async fn cleanup_expired(&self) -> Result<u64>
Remove expired keys from both tables. Returns total rows cleaned up.
Trait Implementations§
Source§impl KvHandle for KvStore
impl KvHandle for KvStore
Source§fn get<'a>(
&'a self,
key: &'a str,
) -> Pin<Box<dyn Future<Output = Result<Option<Vec<u8>>>> + Send + 'a>>
fn get<'a>( &'a self, key: &'a str, ) -> Pin<Box<dyn Future<Output = Result<Option<Vec<u8>>>> + Send + 'a>>
None if the key doesn’t exist or is expired.Source§fn set<'a>(
&'a self,
key: &'a str,
value: &'a [u8],
ttl: Option<Duration>,
) -> Pin<Box<dyn Future<Output = Result<()>> + Send + 'a>>
fn set<'a>( &'a self, key: &'a str, value: &'a [u8], ttl: Option<Duration>, ) -> Pin<Box<dyn Future<Output = Result<()>> + Send + 'a>>
Source§fn set_if_absent<'a>(
&'a self,
key: &'a str,
value: &'a [u8],
ttl: Option<Duration>,
) -> Pin<Box<dyn Future<Output = Result<bool>> + Send + 'a>>
fn set_if_absent<'a>( &'a self, key: &'a str, value: &'a [u8], ttl: Option<Duration>, ) -> Pin<Box<dyn Future<Output = Result<bool>> + Send + 'a>>
true if the value was stored, false if a live entry already existed.Auto Trait Implementations§
impl Freeze for KvStore
impl !RefUnwindSafe for KvStore
impl Send for KvStore
impl Sync for KvStore
impl Unpin for KvStore
impl UnsafeUnpin for KvStore
impl !UnwindSafe for KvStore
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> 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