pub trait NoteStore:
Send
+ Sync
+ 'static {
Show 17 methods
// Required methods
fn upsert_note<'life0, 'async_trait>(
&'life0 self,
note: Note,
) -> Pin<Box<dyn Future<Output = StorageResult<()>> + 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 = StorageResult<BatchWriteSummary>> + 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 = StorageResult<Option<Note>>> + 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 = StorageResult<Option<Note>>> + 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 = StorageResult<bool>> + 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 = StorageResult<bool>> + Send + 'async_trait>>
where Self: 'async_trait,
'life0: '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 = StorageResult<bool>> + Send + 'async_trait>>
where Self: 'async_trait,
'life0: 'async_trait,
'life1: '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 = StorageResult<bool>> + Send + 'async_trait>>
where Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
'life2: 'async_trait,
'life3: '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 = StorageResult<Page<Note>>> + 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 = StorageResult<Page<Note>>> + 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 = StorageResult<Vec<Note>>> + 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 = StorageResult<u64>> + Send + 'async_trait>>
where Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
'life2: 'async_trait;
fn try_insert_note<'life0, 'async_trait>(
&'life0 self,
note: Note,
) -> Pin<Box<dyn Future<Output = StorageResult<bool>> + Send + 'async_trait>>
where Self: 'async_trait,
'life0: 'async_trait;
// Provided methods
fn note_sequence<'life0, 'async_trait>(
&'life0 self,
_id: Uuid,
) -> Pin<Box<dyn Future<Output = StorageResult<Option<i64>>> + Send + 'async_trait>>
where Self: 'async_trait,
'life0: '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 = StorageResult<SeekPage<Note>>> + 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 = StorageResult<u64>> + Send + 'async_trait>>
where Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
'life2: 'async_trait { ... }
fn get_notes_batch<'life0, 'life1, 'async_trait>(
&'life0 self,
ids: &'life1 [Uuid],
) -> Pin<Box<dyn Future<Output = StorageResult<Vec<Note>>> + Send + 'async_trait>>
where Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait { ... }
}Expand description
Temporal-referential note CRUD over the notes substrate table.
Required Methods§
Sourcefn upsert_note<'life0, 'async_trait>(
&'life0 self,
note: Note,
) -> Pin<Box<dyn Future<Output = StorageResult<()>> + 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 = StorageResult<()>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
Insert or update a single note.
Sourcefn upsert_notes<'life0, 'async_trait>(
&'life0 self,
notes: Vec<Note>,
) -> Pin<Box<dyn Future<Output = StorageResult<BatchWriteSummary>> + 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 = StorageResult<BatchWriteSummary>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
Insert or update a batch of notes.
Sourcefn get_note<'life0, 'async_trait>(
&'life0 self,
id: Uuid,
) -> Pin<Box<dyn Future<Output = StorageResult<Option<Note>>> + 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 = StorageResult<Option<Note>>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
Fetch a note by UUID, returning None if absent.
Sourcefn get_note_including_deleted<'life0, 'async_trait>(
&'life0 self,
id: Uuid,
) -> Pin<Box<dyn Future<Output = StorageResult<Option<Note>>> + 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 = StorageResult<Option<Note>>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
Fetch a note by UUID regardless of soft-deletion state.
Returns the note row even when deleted_at is set. Callers use this
to distinguish “soft-deleted” from “never existed”.
Sourcefn delete_note<'life0, 'async_trait>(
&'life0 self,
id: Uuid,
mode: DeleteMode,
) -> Pin<Box<dyn Future<Output = StorageResult<bool>> + 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 = StorageResult<bool>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
Delete a note by UUID using the specified delete mode.
Sourcefn update_note_properties<'life0, 'async_trait>(
&'life0 self,
id: Uuid,
properties: Option<Value>,
updated_at: i64,
) -> Pin<Box<dyn Future<Output = StorageResult<bool>> + 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 = StorageResult<bool>> + 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.
Unlike upsert_note, which writes the complete note shape, this leaves
every non-property column untouched. It also never churns the row’s
implicit rowid, which is required by callers relying on stable row
identity (#780).
Returns true when a live (non-soft-deleted) row with this id was
found and updated, false otherwise.
Sourcefn set_note_property<'life0, 'life1, 'async_trait>(
&'life0 self,
id: Uuid,
key: &'life1 str,
value: Value,
updated_at: i64,
) -> Pin<Box<dyn Future<Output = StorageResult<bool>> + 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 = StorageResult<bool>> + 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.
The backend must perform the read/modify/write as one storage operation
so concurrent writes to different keys cannot overwrite each other.
value keeps its JSON type, including explicit JSON null. A SQL-NULL
property document is initialized as an empty object. A live row whose
stored document is a non-object is not modified and returns false, as
do missing and soft-deleted rows. Keys containing U+0000 must be
rejected: SQLite JSON-path labels cannot address them without risking
mutation of a shorter sibling key.
Sourcefn 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 = StorageResult<bool>> + 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 = StorageResult<bool>> + 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.
Unlike set_note_property (which patches unconditionally once the row
is live) or update_note_properties (which replaces the whole
properties column with a value the caller already computed — safe
only when nothing else can have written to the row since the caller’s
read), this also rechecks filter against the row’s live state before
writing, so a target that stopped matching an eligibility predicate
between validation and this call is not mutated. Any other property
written concurrently between the caller’s read and this call survives
untouched either way. A live row whose stored properties document is
a non-object (scalar, array, or otherwise) is not modified and returns
false, mirroring set_note_property. Returns Ok(false) — not an
error — when no live row currently matches filter (id not found,
soft-deleted, an eligibility property changed since the caller last
validated it, or the stored document is not a JSON object); the
caller degrades that the same way as update_note_properties’s
Ok(false).
Sourcefn query_notes<'life0, 'life1, 'life2, 'async_trait>(
&'life0 self,
namespace: &'life1 str,
kind: Option<&'life2 str>,
page: PageRequest,
) -> Pin<Box<dyn Future<Output = StorageResult<Page<Note>>> + 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 = StorageResult<Page<Note>>> + 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.
Sourcefn query_notes_filtered<'life0, 'life1, 'life2, 'async_trait>(
&'life0 self,
namespace: &'life1 str,
filter: &'life2 NoteFilter,
page: PageRequest,
) -> Pin<Box<dyn Future<Output = StorageResult<Page<Note>>> + 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 = StorageResult<Page<Note>>> + 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.
Sourcefn 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 = StorageResult<Vec<Note>>> + 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 = StorageResult<Vec<Note>>> + 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.
A single statement observes one consistent snapshot for its entire
execution, so the result cannot be split across a concurrent insert
the way a COUNT(*) followed by independent LIMIT/OFFSET pages
can. Callers detect the over-bound case by checking whether the
returned Vec has more than max_rows items — that means at least
max_rows + 1 rows matched and the caller must reject the query
rather than silently return a truncated, possibly priority-incomplete
set.
Sourcefn count_notes<'life0, 'life1, 'life2, 'async_trait>(
&'life0 self,
namespace: &'life1 str,
kind: Option<&'life2 str>,
) -> Pin<Box<dyn Future<Output = StorageResult<u64>> + 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 = StorageResult<u64>> + 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.
Sourcefn try_insert_note<'life0, 'async_trait>(
&'life0 self,
note: Note,
) -> Pin<Box<dyn Future<Output = StorageResult<bool>> + 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 = StorageResult<bool>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
Attempt to insert a note without overwriting an existing row.
Returns true when the row was newly written. Returns false only
when a live note with the same non-empty external_id already exists in
the same namespace and kind (confirmed dedup hit). Any other constraint
violation (e.g. a primary key collision) is surfaced as a StorageError
so that callers do not misinterpret unexpected failures as deduplication.
Provided Methods§
Sourcefn note_sequence<'life0, 'async_trait>(
&'life0 self,
_id: Uuid,
) -> Pin<Box<dyn Future<Output = StorageResult<Option<i64>>> + 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 = StorageResult<Option<i64>>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
Resolve a note id to its immutable insertion sequence.
Sourcefn 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 = StorageResult<SeekPage<Note>>> + 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 = StorageResult<SeekPage<Note>>> + 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.
Sourcefn count_notes_in_namespaces<'life0, 'life1, 'life2, 'async_trait>(
&'life0 self,
namespaces: &'life1 [String],
kind: Option<&'life2 str>,
) -> Pin<Box<dyn Future<Output = StorageResult<u64>> + 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 = StorageResult<u64>> + 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.
Sourcefn get_notes_batch<'life0, 'life1, 'async_trait>(
&'life0 self,
ids: &'life1 [Uuid],
) -> Pin<Box<dyn Future<Output = StorageResult<Vec<Note>>> + 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 = StorageResult<Vec<Note>>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
Fetch multiple notes by UUID in a single call.
Dyn Compatibility§
This trait is dyn compatible.
In older versions of Rust, dyn compatibility was called "object safety".