Skip to main content

NoteStore

Trait NoteStore 

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

Source

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.

Source

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.

Source

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.

Source

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

Source

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.

Source

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.

Source

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.

Source

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

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

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

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

Source

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.

Source

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§

Source

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.

Source

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.

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

Source

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

Implementors§