pub struct SqlStore { /* private fields */ }Expand description
SQL-backed Store implementation.
Implementations§
Source§impl SqlStore
impl SqlStore
Sourcepub fn new(pool: Pool<Any>) -> Self
pub fn new(pool: Pool<Any>) -> Self
Create a new SQL store wrapping an existing connection pool.
Sourcepub async fn migrate(&self) -> Result<(), StoreError>
pub async fn migrate(&self) -> Result<(), StoreError>
Run database migrations. Idempotent: a _migrations ledger records what
has been applied, so re-running is a no-op. Every column is a text type,
so the store holds no opaque binary and the DDL is identical for both
backends. Content-addressed ids and opaque saga bytes are stored as hex
TEXT, and JSON payloads as their TEXT serialization, keeping every
row legible for auditing.
Trait Implementations§
Source§impl AccountStore for SqlStore
impl AccountStore for SqlStore
Source§fn get_account<'life0, 'life1, 'async_trait>(
&'life0 self,
id: &'life1 AccountId,
) -> Pin<Box<dyn Future<Output = Result<Account, StoreError>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
fn get_account<'life0, 'life1, 'async_trait>(
&'life0 self,
id: &'life1 AccountId,
) -> Pin<Box<dyn Future<Output = Result<Account, StoreError>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
Fetch a single account by id.
Source§fn get_accounts<'life0, 'life1, 'async_trait>(
&'life0 self,
ids: &'life1 [AccountId],
) -> Pin<Box<dyn Future<Output = Result<Vec<Account>, StoreError>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
fn get_accounts<'life0, 'life1, 'async_trait>(
&'life0 self,
ids: &'life1 [AccountId],
) -> Pin<Box<dyn Future<Output = Result<Vec<Account>, StoreError>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
Fetch multiple accounts by id.
Source§fn create_account<'life0, 'async_trait>(
&'life0 self,
account: Account,
) -> Pin<Box<dyn Future<Output = Result<(), StoreError>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
fn create_account<'life0, 'async_trait>(
&'life0 self,
account: Account,
) -> Pin<Box<dyn Future<Output = Result<(), StoreError>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
Persist a new account (version 1).
Source§fn append_account_version<'life0, 'async_trait>(
&'life0 self,
account: Account,
) -> Pin<Box<dyn Future<Output = Result<(), StoreError>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
fn append_account_version<'life0, 'async_trait>(
&'life0 self,
account: Account,
) -> Pin<Box<dyn Future<Output = Result<(), StoreError>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
Append a new version to an existing account.
Source§fn get_account_history<'life0, 'life1, 'async_trait>(
&'life0 self,
id: &'life1 AccountId,
) -> Pin<Box<dyn Future<Output = Result<Vec<Account>, StoreError>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
fn get_account_history<'life0, 'life1, 'async_trait>(
&'life0 self,
id: &'life1 AccountId,
) -> Pin<Box<dyn Future<Output = Result<Vec<Account>, StoreError>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
Return the full version history for an account.
Source§impl BookStore for SqlStore
impl BookStore for SqlStore
Source§fn create_book<'life0, 'async_trait>(
&'life0 self,
book: Book,
) -> Pin<Box<dyn Future<Output = Result<(), StoreError>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
fn create_book<'life0, 'async_trait>(
&'life0 self,
book: Book,
) -> Pin<Box<dyn Future<Output = Result<(), StoreError>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
Create a new book.
Source§impl EventStore for SqlStore
impl EventStore for SqlStore
Source§fn append_event<'life0, 'life1, 'async_trait>(
&'life0 self,
event: &'life1 LedgerEvent,
) -> Pin<Box<dyn Future<Output = Result<u64, StoreError>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
fn append_event<'life0, 'life1, 'async_trait>(
&'life0 self,
event: &'life1 LedgerEvent,
) -> Pin<Box<dyn Future<Output = Result<u64, StoreError>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
Append an event and return its sequence number. Idempotent on the event’s
event_dedup_key: appending an event whose key already exists does not
insert a duplicate and returns the existing seq. The seq field on the
input is ignored – the store assigns it.Source§fn get_events_since<'life0, 'async_trait>(
&'life0 self,
after_seq: u64,
limit: u32,
) -> Pin<Box<dyn Future<Output = Result<Vec<LedgerEvent>, StoreError>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
fn get_events_since<'life0, 'async_trait>(
&'life0 self,
after_seq: u64,
limit: u32,
) -> Pin<Box<dyn Future<Output = Result<Vec<LedgerEvent>, StoreError>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
Return events with sequence numbers greater than
after_seq, up to limit.Source§impl PostingStore for SqlStore
impl PostingStore for SqlStore
Source§fn get_postings<'life0, 'life1, 'async_trait>(
&'life0 self,
ids: &'life1 [PostingId],
) -> Pin<Box<dyn Future<Output = Result<Vec<Posting>, StoreError>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
fn get_postings<'life0, 'life1, 'async_trait>(
&'life0 self,
ids: &'life1 [PostingId],
) -> Pin<Box<dyn Future<Output = Result<Vec<Posting>, StoreError>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
Fetch postings by their ids.
Source§fn get_postings_by_account<'life0, 'life1, 'life2, 'async_trait>(
&'life0 self,
account: &'life1 AccountId,
asset: Option<&'life2 AssetId>,
status: Option<PostingStatus>,
) -> Pin<Box<dyn Future<Output = Result<Vec<Posting>, StoreError>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
'life2: 'async_trait,
fn get_postings_by_account<'life0, 'life1, 'life2, 'async_trait>(
&'life0 self,
account: &'life1 AccountId,
asset: Option<&'life2 AssetId>,
status: Option<PostingStatus>,
) -> Pin<Box<dyn Future<Output = Result<Vec<Posting>, StoreError>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
'life2: 'async_trait,
Return postings owned by an account, optionally filtered by asset and/or status.
Source§fn query_postings<'life0, 'life1, 'async_trait>(
&'life0 self,
query: &'life1 PostingQuery,
) -> Pin<Box<dyn Future<Output = Result<Page<Posting>, StoreError>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
fn query_postings<'life0, 'life1, 'async_trait>(
&'life0 self,
query: &'life1 PostingQuery,
) -> Pin<Box<dyn Future<Output = Result<Page<Posting>, StoreError>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
Query postings with filtering and pagination.
Source§fn reserve_postings<'life0, 'life1, 'async_trait>(
&'life0 self,
ids: &'life1 [PostingId],
reservation: ReservationId,
) -> Pin<Box<dyn Future<Output = Result<u64, StoreError>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
fn reserve_postings<'life0, 'life1, 'async_trait>(
&'life0 self,
ids: &'life1 [PostingId],
reservation: ReservationId,
) -> Pin<Box<dyn Future<Output = Result<u64, StoreError>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
Reserve postings:
Active → PendingInactive, stamping reservation as
the owner token. A dumb instruction — each id flips only if still Active;
returns the number of rows reserved (0 ≤ n ≤ ids.len()). It does not
error on a short count; the caller (saga) interprets it.Source§fn release_postings<'life0, 'life1, 'async_trait>(
&'life0 self,
ids: &'life1 [PostingId],
reservation: ReservationId,
) -> Pin<Box<dyn Future<Output = Result<u64, StoreError>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
fn release_postings<'life0, 'life1, 'async_trait>(
&'life0 self,
ids: &'life1 [PostingId],
reservation: ReservationId,
) -> Pin<Box<dyn Future<Output = Result<u64, StoreError>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
Release postings:
PendingInactive owned by reservation → Active,
clearing the owner. A dumb instruction — only postings reserved by this
reservation flip; returns the number of rows released. Releasing an
Active (already released) or differently-owned posting simply does not
count. The caller interprets the result.Source§fn deactivate_postings<'life0, 'life1, 'async_trait>(
&'life0 self,
ids: &'life1 [PostingId],
reservation: Option<ReservationId>,
) -> Pin<Box<dyn Future<Output = Result<u64, StoreError>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
fn deactivate_postings<'life0, 'life1, 'async_trait>(
&'life0 self,
ids: &'life1 [PostingId],
reservation: Option<ReservationId>,
) -> Pin<Box<dyn Future<Output = Result<u64, StoreError>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
Deactivate postings: flip to
Inactive. A dumb instruction — it applies
the conditional update and returns the number of rows changed; it does
not decide whether that count is correct. The caller (saga) interprets it. Read moreSource§fn insert_postings<'life0, 'life1, 'async_trait>(
&'life0 self,
postings: &'life1 [Posting],
) -> Pin<Box<dyn Future<Output = Result<u64, StoreError>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
fn insert_postings<'life0, 'life1, 'async_trait>(
&'life0 self,
postings: &'life1 [Posting],
) -> Pin<Box<dyn Future<Output = Result<u64, StoreError>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
Insert postings if absent (idempotent). A dumb instruction — inserts each
posting unless one with the same id already exists, and returns the
number of rows inserted (already-present postings contribute 0). The
caller decides what a short count means.
Source§impl SagaStore for SqlStore
impl SagaStore for SqlStore
Source§fn save_saga<'life0, 'life1, 'async_trait>(
&'life0 self,
id: &'life1 i64,
data: Vec<u8>,
) -> Pin<Box<dyn Future<Output = Result<(), StoreError>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
fn save_saga<'life0, 'life1, 'async_trait>(
&'life0 self,
id: &'life1 i64,
data: Vec<u8>,
) -> Pin<Box<dyn Future<Output = Result<(), StoreError>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
Persist a saga execution state.
Source§impl TransferStore for SqlStore
impl TransferStore for SqlStore
Source§fn get_transfer<'life0, 'life1, 'async_trait>(
&'life0 self,
id: &'life1 EnvelopeId,
) -> Pin<Box<dyn Future<Output = Result<Option<EnvelopeRecord>, StoreError>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
fn get_transfer<'life0, 'life1, 'async_trait>(
&'life0 self,
id: &'life1 EnvelopeId,
) -> Pin<Box<dyn Future<Output = Result<Option<EnvelopeRecord>, StoreError>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
Fetch a transfer record by its content-addressed id.
Source§fn store_transfer<'life0, 'life1, 'async_trait>(
&'life0 self,
record: EnvelopeRecord,
involved: &'life1 [AccountId],
) -> Pin<Box<dyn Future<Output = Result<u64, StoreError>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
fn store_transfer<'life0, 'life1, 'async_trait>(
&'life0 self,
record: EnvelopeRecord,
involved: &'life1 [AccountId],
) -> Pin<Box<dyn Future<Output = Result<u64, StoreError>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
Persist a transfer record if absent (idempotent) and index it under every
account in
involved (both created and consumed owners — the caller
supplies the set so storage computes nothing). A dumb instruction:
returns 1 if the transfer row was newly inserted, 0 if it already
existed. The caller decides what 0 means.Source§fn get_transfers_for_account<'life0, 'life1, 'async_trait>(
&'life0 self,
account: &'life1 AccountId,
) -> Pin<Box<dyn Future<Output = Result<Vec<EnvelopeRecord>, StoreError>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
fn get_transfers_for_account<'life0, 'life1, 'async_trait>(
&'life0 self,
account: &'life1 AccountId,
) -> Pin<Box<dyn Future<Output = Result<Vec<EnvelopeRecord>, StoreError>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
Return all transfers involving the given account.
Source§fn query_transfers<'life0, 'life1, 'async_trait>(
&'life0 self,
query: &'life1 TransferQuery,
) -> Pin<Box<dyn Future<Output = Result<Page<EnvelopeRecord>, StoreError>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
fn query_transfers<'life0, 'life1, 'async_trait>(
&'life0 self,
query: &'life1 TransferQuery,
) -> Pin<Box<dyn Future<Output = Result<Page<EnvelopeRecord>, StoreError>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
Query transfers with filtering and pagination.
Auto Trait Implementations§
impl !Freeze for SqlStore
impl !RefUnwindSafe for SqlStore
impl !UnwindSafe for SqlStore
impl Send for SqlStore
impl Sync for SqlStore
impl Unpin for SqlStore
impl UnsafeUnpin for SqlStore
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
Mutably borrows from an owned value. Read more
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>
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 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>
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