Skip to main content

KvStore

Struct KvStore 

Source
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

Source

pub fn new(pool: PgPool, namespace: &'static str) -> Self

Source

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.

Source

pub async fn set( &self, key: &str, value: &[u8], ttl: Option<Duration>, ) -> Result<()>

Set a key to a value. Overwrites any existing value.

Source

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).

Source

pub async fn delete(&self, key: &str) -> Result<bool>

Delete a key. Returns true if the key existed.

Source

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.

Source

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

Source§

fn get<'a>( &'a self, key: &'a str, ) -> Pin<Box<dyn Future<Output = Result<Option<Vec<u8>>>> + Send + 'a>>

Get a value by key. Returns 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>>

Set a key to a value, optionally with a TTL. Overwrites any existing value.
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>>

Set a key only if it doesn’t already exist (or is expired). Returns true if the value was stored, false if a live entry already existed.
Source§

fn delete<'a>( &'a self, key: &'a str, ) -> Pin<Box<dyn Future<Output = Result<bool>> + Send + 'a>>

Delete a key. Returns true if the key existed.
Source§

fn increment<'a>( &'a self, key: &'a str, delta: i64, ttl: Option<Duration>, ) -> Pin<Box<dyn Future<Output = Result<i64>> + Send + 'a>>

Atomically increment a counter by delta. Read more

Auto Trait Implementations§

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T> Instrument for T

Source§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided Span, returning an Instrumented wrapper. Read more
Source§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an Instrumented wrapper. Read more
Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> IntoEither for T

Source§

fn into_either(self, into_left: bool) -> Either<Self, Self>

Converts 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 more
Source§

fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
where F: FnOnce(&Self) -> bool,

Converts 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
Source§

impl<T> PolicyExt for T
where T: ?Sized,

Source§

fn and<P, B, E>(self, other: P) -> And<T, P>
where T: Policy<B, E>, P: Policy<B, E>,

Create a new Policy that returns Action::Follow only if self and other return Action::Follow. Read more
Source§

fn or<P, B, E>(self, other: P) -> Or<T, P>
where T: Policy<B, E>, P: Policy<B, E>,

Create a new Policy that returns Action::Follow if either self or other returns Action::Follow. Read more
Source§

impl<T> Same for T

Source§

type Output = T

Should always be Self
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
Source§

impl<V, T> VZip<V> for T
where V: MultiLane<T>,

Source§

fn vzip(self) -> V

Source§

impl<T> WithSubscriber for T

Source§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a WithDispatch wrapper. Read more
Source§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a WithDispatch wrapper. Read more