pub struct SqlNoteStore { /* private fields */ }Expand description
A NoteStore backed by SQLite. Namespace is the caller’s responsibility.
UUID is globally unique — get/delete by ID alone. Query/count use the namespace parameter as passed. Read routing is always pool-backed; the constructor’s legacy file-backed flag is retained for API compatibility.
Implementations§
Source§impl SqlNoteStore
impl SqlNoteStore
Sourcepub fn new(pool: Arc<ConnectionPool>, _is_file_backed: bool) -> Self
pub fn new(pool: Arc<ConnectionPool>, _is_file_backed: bool) -> Self
Create a new store.
Trait Implementations§
Source§impl NoteStore for SqlNoteStore
impl NoteStore for SqlNoteStore
fn get_live_notes_by_key<'life0, 'life1, 'life2, 'life3, 'async_trait>(
&'life0 self,
namespace: &'life1 str,
key: &'life2 str,
kind: Option<&'life3 str>,
) -> Pin<Box<dyn Future<Output = StorageResult<Vec<Note>>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
'life2: 'async_trait,
'life3: 'async_trait,
fn query_keyed_notes<'life0, 'life1, 'life2, 'life3, 'life4, 'async_trait>(
&'life0 self,
namespace: &'life1 str,
filter: &'life2 NoteFilter,
prefix: &'life3 str,
after: Option<&'life4 NoteKeyCursor>,
page: PageRequest,
) -> Pin<Box<dyn Future<Output = StorageResult<(Vec<Note>, Option<NoteKeyCursor>)>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
'life2: 'async_trait,
'life3: 'async_trait,
'life4: 'async_trait,
Source§fn upsert_note<'life0, 'async_trait>(
&'life0 self,
note: Note,
) -> Pin<Box<dyn Future<Output = Result<(), StorageError>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
fn upsert_note<'life0, 'async_trait>(
&'life0 self,
note: Note,
) -> Pin<Box<dyn Future<Output = Result<(), StorageError>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
Insert or update a single note. Updates preserve the stored immutable key.
Source§fn insert_note_if_absent<'life0, 'async_trait>(
&'life0 self,
note: Note,
) -> Pin<Box<dyn Future<Output = Result<bool, StorageError>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
fn insert_note_if_absent<'life0, 'async_trait>(
&'life0 self,
note: Note,
) -> Pin<Box<dyn Future<Output = Result<bool, StorageError>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
Insert a note only if no row already holds its id, reporting whether
this call is the one that inserted it. Read more
Source§fn replace_note_if_unchanged<'life0, 'async_trait>(
&'life0 self,
note: Note,
expected_updated_at: i64,
expected_deleted_at: Option<i64>,
) -> Pin<Box<dyn Future<Output = Result<bool, StorageError>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
fn replace_note_if_unchanged<'life0, 'async_trait>(
&'life0 self,
note: Note,
expected_updated_at: i64,
expected_deleted_at: Option<i64>,
) -> Pin<Box<dyn Future<Output = Result<bool, StorageError>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
Replace a note only when the persisted row still matches the caller’s
read snapshot. Read more
Source§fn update_note_properties<'life0, 'async_trait>(
&'life0 self,
id: Uuid,
properties: Option<Value>,
updated_at: i64,
) -> Pin<Box<dyn Future<Output = Result<bool, StorageError>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
fn update_note_properties<'life0, 'async_trait>(
&'life0 self,
id: Uuid,
properties: Option<Value>,
updated_at: i64,
) -> Pin<Box<dyn Future<Output = Result<bool, StorageError>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
Patch
properties/updated_at on an existing note in place via a real
UPDATE, leaving every other column (including the row’s rowid)
untouched. Read moreSource§fn set_note_property<'life0, 'life1, 'async_trait>(
&'life0 self,
id: Uuid,
key: &'life1 str,
value: Value,
updated_at: i64,
) -> Pin<Box<dyn Future<Output = Result<bool, StorageError>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
fn set_note_property<'life0, 'life1, 'async_trait>(
&'life0 self,
id: Uuid,
key: &'life1 str,
value: Value,
updated_at: i64,
) -> Pin<Box<dyn Future<Output = Result<bool, StorageError>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
Atomically set one top-level key in a note’s JSON
properties object. Read moreSource§fn try_patch_note_property<'life0, 'life1, 'life2, 'life3, 'async_trait>(
&'life0 self,
id: Uuid,
namespace: &'life1 str,
filter: &'life2 NoteFilter,
json_path: &'life3 str,
value: Value,
updated_at: i64,
) -> Pin<Box<dyn Future<Output = Result<bool, StorageError>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
'life2: 'async_trait,
'life3: 'async_trait,
fn try_patch_note_property<'life0, 'life1, 'life2, 'life3, 'async_trait>(
&'life0 self,
id: Uuid,
namespace: &'life1 str,
filter: &'life2 NoteFilter,
json_path: &'life3 str,
value: Value,
updated_at: i64,
) -> Pin<Box<dyn Future<Output = Result<bool, StorageError>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
'life2: 'async_trait,
'life3: 'async_trait,
Atomically patch a single
properties JSON key on a note, but only
when the row’s current state (re-evaluated inside this same
statement, not a snapshot the caller fetched earlier) still satisfies
filter’s namespace/kind/property_filters. Read moreSource§fn patch_note_property_atomic<'life0, 'life1, 'life2, 'life3, 'async_trait>(
&'life0 self,
ids: Vec<Uuid>,
namespace: &'life1 str,
filter: &'life2 NoteFilter,
json_path: &'life3 str,
value: Value,
updated_at: i64,
) -> Pin<Box<dyn Future<Output = Result<(), StorageError>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
'life2: 'async_trait,
'life3: 'async_trait,
fn patch_note_property_atomic<'life0, 'life1, 'life2, 'life3, 'async_trait>(
&'life0 self,
ids: Vec<Uuid>,
namespace: &'life1 str,
filter: &'life2 NoteFilter,
json_path: &'life3 str,
value: Value,
updated_at: i64,
) -> Pin<Box<dyn Future<Output = Result<(), StorageError>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
'life2: 'async_trait,
'life3: 'async_trait,
Atomically patch one JSON property on every supplied note. Read more
Source§fn try_insert_note<'life0, 'async_trait>(
&'life0 self,
note: Note,
) -> Pin<Box<dyn Future<Output = Result<bool, StorageError>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
fn try_insert_note<'life0, 'async_trait>(
&'life0 self,
note: Note,
) -> Pin<Box<dyn Future<Output = Result<bool, StorageError>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
Attempt to insert a note without overwriting an existing row. Read more
Source§fn upsert_notes<'life0, 'async_trait>(
&'life0 self,
notes: Vec<Note>,
) -> Pin<Box<dyn Future<Output = Result<BatchWriteSummary, StorageError>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
fn upsert_notes<'life0, 'async_trait>(
&'life0 self,
notes: Vec<Note>,
) -> Pin<Box<dyn Future<Output = Result<BatchWriteSummary, StorageError>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
Insert or update a batch of notes. Updates preserve each stored immutable key.
Source§fn get_note<'life0, 'async_trait>(
&'life0 self,
id: Uuid,
) -> Pin<Box<dyn Future<Output = Result<Option<Note>, StorageError>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
fn get_note<'life0, 'async_trait>(
&'life0 self,
id: Uuid,
) -> Pin<Box<dyn Future<Output = Result<Option<Note>, StorageError>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
Fetch a note by UUID, returning
None if absent.Source§fn get_note_including_deleted<'life0, 'async_trait>(
&'life0 self,
id: Uuid,
) -> Pin<Box<dyn Future<Output = Result<Option<Note>, StorageError>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
fn get_note_including_deleted<'life0, 'async_trait>(
&'life0 self,
id: Uuid,
) -> Pin<Box<dyn Future<Output = Result<Option<Note>, StorageError>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
Fetch a note by UUID regardless of soft-deletion state. Read more
Source§fn note_sequence<'life0, 'async_trait>(
&'life0 self,
id: Uuid,
) -> Pin<Box<dyn Future<Output = Result<Option<i64>, StorageError>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
fn note_sequence<'life0, 'async_trait>(
&'life0 self,
id: Uuid,
) -> Pin<Box<dyn Future<Output = Result<Option<i64>, StorageError>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
Resolve a note id to its immutable insertion sequence.
Source§fn get_notes_batch<'life0, 'life1, 'async_trait>(
&'life0 self,
ids: &'life1 [Uuid],
) -> Pin<Box<dyn Future<Output = Result<Vec<Note>, StorageError>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
fn get_notes_batch<'life0, 'life1, 'async_trait>(
&'life0 self,
ids: &'life1 [Uuid],
) -> Pin<Box<dyn Future<Output = Result<Vec<Note>, StorageError>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
Fetch multiple notes by UUID in a single call.
Source§fn delete_note<'life0, 'async_trait>(
&'life0 self,
id: Uuid,
mode: DeleteMode,
) -> Pin<Box<dyn Future<Output = Result<bool, StorageError>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
fn delete_note<'life0, 'async_trait>(
&'life0 self,
id: Uuid,
mode: DeleteMode,
) -> Pin<Box<dyn Future<Output = Result<bool, StorageError>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
Delete a note by UUID using the specified delete mode.
Source§fn query_notes<'life0, 'life1, 'life2, 'async_trait>(
&'life0 self,
namespace: &'life1 str,
kind: Option<&'life2 str>,
page: PageRequest,
) -> Pin<Box<dyn Future<Output = Result<Page<Note>, StorageError>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
'life2: 'async_trait,
fn query_notes<'life0, 'life1, 'life2, 'async_trait>(
&'life0 self,
namespace: &'life1 str,
kind: Option<&'life2 str>,
page: PageRequest,
) -> Pin<Box<dyn Future<Output = Result<Page<Note>, StorageError>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
'life2: 'async_trait,
Query notes by namespace and optional kind with pagination.
The returned total and page items must come from one consistent
backend snapshot.
Source§fn query_notes_count_free<'life0, 'life1, 'life2, 'async_trait>(
&'life0 self,
namespace: &'life1 str,
kind: Option<&'life2 str>,
page: PageRequest,
) -> Pin<Box<dyn Future<Output = Result<Page<Note>, StorageError>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
'life2: 'async_trait,
fn query_notes_count_free<'life0, 'life1, 'life2, 'async_trait>(
&'life0 self,
namespace: &'life1 str,
kind: Option<&'life2 str>,
page: PageRequest,
) -> Pin<Box<dyn Future<Output = Result<Page<Note>, StorageError>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
'life2: 'async_trait,
Query notes by namespace and optional kind without computing an exact total. Read more
Source§fn query_notes_filtered<'life0, 'life1, 'life2, 'async_trait>(
&'life0 self,
namespace: &'life1 str,
filter: &'life2 NoteFilter,
page: PageRequest,
) -> Pin<Box<dyn Future<Output = Result<Page<Note>, StorageError>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
'life2: 'async_trait,
fn query_notes_filtered<'life0, 'life1, 'life2, 'async_trait>(
&'life0 self,
namespace: &'life1 str,
filter: &'life2 NoteFilter,
page: PageRequest,
) -> Pin<Box<dyn Future<Output = Result<Page<Note>, StorageError>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
'life2: 'async_trait,
Query notes with property-based filtering and custom sort.
The returned total and page items must come from one consistent
backend snapshot.
Source§fn query_notes_filtered_count_free<'life0, 'life1, 'life2, 'async_trait>(
&'life0 self,
namespace: &'life1 str,
filter: &'life2 NoteFilter,
page: PageRequest,
) -> Pin<Box<dyn Future<Output = Result<Page<Note>, StorageError>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
'life2: 'async_trait,
fn query_notes_filtered_count_free<'life0, 'life1, 'life2, 'async_trait>(
&'life0 self,
namespace: &'life1 str,
filter: &'life2 NoteFilter,
page: PageRequest,
) -> Pin<Box<dyn Future<Output = Result<Page<Note>, StorageError>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
'life2: 'async_trait,
Query a filtered note page without computing an exact total. Read more
Source§fn count_notes_filtered_in_snapshot<'life0, 'life1, 'life2, 'async_trait>(
&'life0 self,
namespace: &'life1 str,
filters: &'life2 [NoteFilter],
) -> Pin<Box<dyn Future<Output = Result<Vec<u64>, StorageError>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
'life2: 'async_trait,
fn count_notes_filtered_in_snapshot<'life0, 'life1, 'life2, 'async_trait>(
&'life0 self,
namespace: &'life1 str,
filters: &'life2 [NoteFilter],
) -> Pin<Box<dyn Future<Output = Result<Vec<u64>, StorageError>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
'life2: 'async_trait,
Count several filtered note populations in one consistent backend
snapshot. Backends that cannot provide that guarantee must return
crate::StorageError::Unsupported rather than composing independent
queries or treating an absent page total as zero. SQL backends should
override this operation so callers can retain separate index-friendly
predicates without racing between their counts.Source§fn count_notes_filtered_bounded_in_snapshot<'life0, 'life1, 'life2, 'async_trait>(
&'life0 self,
namespace: &'life1 str,
filters: &'life2 [NoteFilter],
cap: u32,
) -> Pin<Box<dyn Future<Output = Result<Vec<BoundedCount>, StorageError>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
'life2: 'async_trait,
fn count_notes_filtered_bounded_in_snapshot<'life0, 'life1, 'life2, 'async_trait>(
&'life0 self,
namespace: &'life1 str,
filters: &'life2 [NoteFilter],
cap: u32,
) -> Pin<Box<dyn Future<Output = Result<Vec<BoundedCount>, StorageError>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
'life2: 'async_trait,
Count several filtered note populations in one backend snapshot, with
each count bounded by
cap. Read moreSource§fn query_notes_filtered_after<'life0, 'life1, 'life2, 'async_trait>(
&'life0 self,
namespace: &'life1 str,
filter: &'life2 NoteFilter,
after: Option<SeekCursor>,
limit: u32,
) -> Pin<Box<dyn Future<Output = Result<SeekPage<Note>, StorageError>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
'life2: 'async_trait,
fn query_notes_filtered_after<'life0, 'life1, 'life2, 'async_trait>(
&'life0 self,
namespace: &'life1 str,
filter: &'life2 NoteFilter,
after: Option<SeekCursor>,
limit: u32,
) -> Pin<Box<dyn Future<Output = Result<SeekPage<Note>, StorageError>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
'life2: 'async_trait,
Query an immutable insertion-sequence keyset page with the same
predicates as
Self::query_notes_filtered.Source§fn query_notes_filtered_bounded<'life0, 'life1, 'life2, 'async_trait>(
&'life0 self,
namespace: &'life1 str,
filter: &'life2 NoteFilter,
max_rows: u32,
) -> Pin<Box<dyn Future<Output = Result<Vec<Note>, StorageError>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
'life2: 'async_trait,
fn query_notes_filtered_bounded<'life0, 'life1, 'life2, 'async_trait>(
&'life0 self,
namespace: &'life1 str,
filter: &'life2 NoteFilter,
max_rows: u32,
) -> Pin<Box<dyn Future<Output = Result<Vec<Note>, StorageError>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
'life2: 'async_trait,
Fetch up to
max_rows + 1 notes matching filter in a single
deterministically-ordered SQL statement, with no separate COUNT(*)
and no pagination loop. Read moreSource§fn count_notes<'life0, 'life1, 'life2, 'async_trait>(
&'life0 self,
namespace: &'life1 str,
kind: Option<&'life2 str>,
) -> Pin<Box<dyn Future<Output = Result<u64, StorageError>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
'life2: 'async_trait,
fn count_notes<'life0, 'life1, 'life2, 'async_trait>(
&'life0 self,
namespace: &'life1 str,
kind: Option<&'life2 str>,
) -> Pin<Box<dyn Future<Output = Result<u64, StorageError>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
'life2: 'async_trait,
Count notes in a namespace, optionally filtered by kind.
Source§fn count_notes_in_namespaces<'life0, 'life1, 'life2, 'async_trait>(
&'life0 self,
namespaces: &'life1 [String],
kind: Option<&'life2 str>,
) -> Pin<Box<dyn Future<Output = Result<u64, StorageError>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
'life2: 'async_trait,
fn count_notes_in_namespaces<'life0, 'life1, 'life2, 'async_trait>(
&'life0 self,
namespaces: &'life1 [String],
kind: Option<&'life2 str>,
) -> Pin<Box<dyn Future<Output = Result<u64, StorageError>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
'life2: 'async_trait,
Count notes across the given namespaces, optionally filtered by kind.
The default preserves compatibility by summing the existing
single-namespace operation; SQL backends should override this with one
IN aggregate.Auto Trait Implementations§
impl !RefUnwindSafe for SqlNoteStore
impl !UnwindSafe for SqlNoteStore
impl Freeze for SqlNoteStore
impl Send for SqlNoteStore
impl Sync for SqlNoteStore
impl Unpin for SqlNoteStore
impl UnsafeUnpin for SqlNoteStore
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