Skip to main content

Storage

Trait Storage 

Source
pub trait Storage: ReadStore {
Show 36 methods // Required methods fn save_config<'life0, 'life1, 'async_trait>( &'life0 self, cfg: &'life1 AppConfig, ) -> Pin<Box<dyn Future<Output = Result<(), DbError>> + Send + 'async_trait>> where Self: 'async_trait, 'life0: 'async_trait, 'life1: 'async_trait; fn import_legacy_json<'life0, 'life1, 'async_trait>( &'life0 self, config_dir: &'life1 Path, ) -> Pin<Box<dyn Future<Output = Result<ImportReport, DbError>> + Send + 'async_trait>> where Self: 'async_trait, 'life0: 'async_trait, 'life1: 'async_trait; fn finalize_migration<'life0, 'life1, 'async_trait>( &'life0 self, config_dir: &'life1 Path, ) -> Pin<Box<dyn Future<Output = Result<usize, DbError>> + Send + 'async_trait>> where Self: 'async_trait, 'life0: 'async_trait, 'life1: 'async_trait; fn delete_tracks<'life0, 'life1, 'life2, 'async_trait>( &'life0 self, source: &'life1 Source, keys: &'life2 [String], ) -> Pin<Box<dyn Future<Output = Result<u64, DbError>> + Send + 'async_trait>> where Self: 'async_trait, 'life0: 'async_trait, 'life1: 'async_trait, 'life2: 'async_trait; fn delete_album<'life0, 'life1, 'life2, 'async_trait>( &'life0 self, source: &'life1 Source, album_id: &'life2 str, ) -> Pin<Box<dyn Future<Output = Result<(), DbError>> + Send + 'async_trait>> where Self: 'async_trait, 'life0: 'async_trait, 'life1: 'async_trait, 'life2: 'async_trait; fn prune_source<'life0, 'life1, 'life2, 'life3, 'async_trait>( &'life0 self, source: &'life1 Source, keep_track_keys: &'life2 [String], keep_album_ids: &'life3 [String], ) -> Pin<Box<dyn Future<Output = Result<(), DbError>> + Send + 'async_trait>> where Self: 'async_trait, 'life0: 'async_trait, 'life1: 'async_trait, 'life2: 'async_trait, 'life3: 'async_trait; fn set_artist_image<'life0, 'life1, 'life2, 'life3, 'async_trait>( &'life0 self, artist_norm: &'life1 str, kind: &'life2 str, image_ref: Option<&'life3 str>, ) -> Pin<Box<dyn Future<Output = Result<(), DbError>> + Send + 'async_trait>> where Self: 'async_trait, 'life0: 'async_trait, 'life1: 'async_trait, 'life2: 'async_trait, 'life3: 'async_trait; fn update_album_cover<'life0, 'life1, 'life2, 'life3, 'async_trait>( &'life0 self, source: &'life1 Source, album_id: &'life2 str, cover_path: Option<&'life3 str>, manual: bool, ) -> Pin<Box<dyn Future<Output = Result<(), DbError>> + Send + 'async_trait>> where Self: 'async_trait, 'life0: 'async_trait, 'life1: 'async_trait, 'life2: 'async_trait, 'life3: 'async_trait; fn upsert_playlist_meta<'life0, 'life1, 'life2, 'life3, 'life4, 'life5, 'async_trait>( &'life0 self, source: &'life1 Source, pl_id: &'life2 str, name: &'life3 str, cover_path: Option<&'life4 str>, image_tag: Option<&'life5 str>, ) -> Pin<Box<dyn Future<Output = Result<(), DbError>> + Send + 'async_trait>> where Self: 'async_trait, 'life0: 'async_trait, 'life1: 'async_trait, 'life2: 'async_trait, 'life3: 'async_trait, 'life4: 'async_trait, 'life5: 'async_trait; fn delete_playlist<'life0, 'life1, 'life2, 'async_trait>( &'life0 self, source: &'life1 Source, pl_id: &'life2 str, ) -> Pin<Box<dyn Future<Output = Result<(), DbError>> + Send + 'async_trait>> where Self: 'async_trait, 'life0: 'async_trait, 'life1: 'async_trait, 'life2: 'async_trait; fn set_playlist_tracks<'life0, 'life1, 'life2, 'life3, 'async_trait>( &'life0 self, source: &'life1 Source, pl_id: &'life2 str, refs: &'life3 [String], ) -> Pin<Box<dyn Future<Output = Result<(), DbError>> + Send + 'async_trait>> where Self: 'async_trait, 'life0: 'async_trait, 'life1: 'async_trait, 'life2: 'async_trait, 'life3: 'async_trait; fn add_playlist_tracks<'life0, 'life1, 'life2, 'life3, 'async_trait>( &'life0 self, source: &'life1 Source, pl_id: &'life2 str, refs: &'life3 [String], ) -> Pin<Box<dyn Future<Output = Result<(), DbError>> + Send + 'async_trait>> where Self: 'async_trait, 'life0: 'async_trait, 'life1: 'async_trait, 'life2: 'async_trait, 'life3: 'async_trait; fn remove_playlist_tracks<'life0, 'life1, 'life2, 'life3, 'async_trait>( &'life0 self, source: &'life1 Source, pl_id: &'life2 str, refs: &'life3 [String], ) -> Pin<Box<dyn Future<Output = Result<(), DbError>> + Send + 'async_trait>> where Self: 'async_trait, 'life0: 'async_trait, 'life1: 'async_trait, 'life2: 'async_trait, 'life3: 'async_trait; fn upsert_playlist_tracks_page<'life0, 'life1, 'life2, 'life3, 'async_trait>( &'life0 self, source: &'life1 Source, pl_id: &'life2 str, refs: &'life3 [String], start_position: i64, epoch: i64, ) -> Pin<Box<dyn Future<Output = Result<(), DbError>> + Send + 'async_trait>> where Self: 'async_trait, 'life0: 'async_trait, 'life1: 'async_trait, 'life2: 'async_trait, 'life3: 'async_trait; fn sweep_playlist_tracks<'life0, 'life1, 'life2, 'async_trait>( &'life0 self, source: &'life1 Source, pl_id: &'life2 str, epoch: i64, ) -> Pin<Box<dyn Future<Output = Result<(), DbError>> + Send + 'async_trait>> where Self: 'async_trait, 'life0: 'async_trait, 'life1: 'async_trait, 'life2: 'async_trait; fn create_folder<'life0, 'life1, 'life2, 'async_trait>( &'life0 self, id: &'life1 str, name: &'life2 str, ) -> Pin<Box<dyn Future<Output = Result<(), DbError>> + Send + 'async_trait>> where Self: 'async_trait, 'life0: 'async_trait, 'life1: 'async_trait, 'life2: 'async_trait; fn rename_folder<'life0, 'life1, 'life2, 'async_trait>( &'life0 self, id: &'life1 str, name: &'life2 str, ) -> Pin<Box<dyn Future<Output = Result<(), DbError>> + Send + 'async_trait>> where Self: 'async_trait, 'life0: 'async_trait, 'life1: 'async_trait, 'life2: 'async_trait; fn delete_folder<'life0, 'life1, 'async_trait>( &'life0 self, id: &'life1 str, ) -> Pin<Box<dyn Future<Output = Result<(), DbError>> + Send + 'async_trait>> where Self: 'async_trait, 'life0: 'async_trait, 'life1: 'async_trait; fn set_playlist_folder<'life0, 'life1, 'life2, 'async_trait>( &'life0 self, playlist_ref: &'life1 str, folder_id: Option<&'life2 str>, ) -> Pin<Box<dyn Future<Output = Result<(), DbError>> + Send + 'async_trait>> where Self: 'async_trait, 'life0: 'async_trait, 'life1: 'async_trait, 'life2: 'async_trait; fn bump_listen_count<'life0, 'life1, 'async_trait>( &'life0 self, track_uid: &'life1 str, ) -> Pin<Box<dyn Future<Output = Result<(), DbError>> + Send + 'async_trait>> where Self: 'async_trait, 'life0: 'async_trait, 'life1: 'async_trait; fn push_recent<'life0, 'life1, 'life2, 'async_trait>( &'life0 self, source: &'life1 Source, track_key: &'life2 str, ) -> Pin<Box<dyn Future<Output = Result<(), DbError>> + Send + 'async_trait>> where Self: 'async_trait, 'life0: 'async_trait, 'life1: 'async_trait, 'life2: 'async_trait; fn set_offline_track<'life0, 'life1, 'life2, 'async_trait>( &'life0 self, id: &'life1 str, path: Option<&'life2 str>, ) -> Pin<Box<dyn Future<Output = Result<(), DbError>> + Send + 'async_trait>> where Self: 'async_trait, 'life0: 'async_trait, 'life1: 'async_trait, 'life2: 'async_trait; fn save_queue<'life0, 'life1, 'async_trait>( &'life0 self, snap: &'life1 QueueSnapshot, ) -> Pin<Box<dyn Future<Output = Result<(), DbError>> + Send + 'async_trait>> where Self: 'async_trait, 'life0: 'async_trait, 'life1: 'async_trait; fn meta_put<'life0, 'life1, 'life2, 'life3, 'async_trait>( &'life0 self, cache_key: &'life1 str, kind: &'life2 str, payload: &'life3 str, ) -> Pin<Box<dyn Future<Output = Result<(), DbError>> + Send + 'async_trait>> where Self: 'async_trait, 'life0: 'async_trait, 'life1: 'async_trait, 'life2: 'async_trait, 'life3: 'async_trait; fn debug_reset<'life0, 'life1, 'async_trait>( &'life0 self, db_path: &'life1 Path, ) -> Pin<Box<dyn Future<Output = Result<(), DbError>> + Send + 'async_trait>> where Self: 'async_trait, 'life0: 'async_trait, 'life1: 'async_trait; fn debug_load_release<'life0, 'life1, 'life2, 'async_trait>( &'life0 self, release_path: &'life1 Path, db_path: &'life2 Path, ) -> Pin<Box<dyn Future<Output = Result<(), DbError>> + Send + 'async_trait>> where Self: 'async_trait, 'life0: 'async_trait, 'life1: 'async_trait, 'life2: 'async_trait; fn debug_seed_synthetic<'life0, 'async_trait>( &'life0 self, n: u32, ) -> Pin<Box<dyn Future<Output = Result<(), DbError>> + Send + 'async_trait>> where Self: 'async_trait, 'life0: 'async_trait; fn debug_info<'life0, 'async_trait>( &'life0 self, ) -> Pin<Box<dyn Future<Output = Result<String, DbError>> + Send + 'async_trait>> where Self: 'async_trait, 'life0: 'async_trait; fn debug_vacuum<'life0, 'async_trait>( &'life0 self, ) -> Pin<Box<dyn Future<Output = Result<(), DbError>> + Send + 'async_trait>> where Self: 'async_trait, 'life0: 'async_trait; fn set_favorite<'life0, 'life1, 'life2, 'async_trait>( &'life0 self, server_id: &'life1 str, ref_: &'life2 str, on: bool, ) -> Pin<Box<dyn Future<Output = Result<(), DbError>> + Send + 'async_trait>> where Self: 'async_trait, 'life0: 'async_trait, 'life1: 'async_trait, 'life2: 'async_trait; fn clear_favorite_dirty<'life0, 'life1, 'life2, 'async_trait>( &'life0 self, server_id: &'life1 str, ref_: &'life2 str, ) -> Pin<Box<dyn Future<Output = Result<(), DbError>> + Send + 'async_trait>> where Self: 'async_trait, 'life0: 'async_trait, 'life1: 'async_trait, 'life2: 'async_trait; fn replace_favorites_clean<'life0, 'life1, 'life2, 'async_trait>( &'life0 self, server_id: &'life1 str, refs: &'life2 [String], ) -> Pin<Box<dyn Future<Output = Result<(), DbError>> + Send + 'async_trait>> where Self: 'async_trait, 'life0: 'async_trait, 'life1: 'async_trait, 'life2: 'async_trait; fn upsert_favorites_page<'life0, 'life1, 'life2, 'async_trait>( &'life0 self, server_id: &'life1 str, refs: &'life2 [String], start_rank: i64, epoch: i64, ) -> Pin<Box<dyn Future<Output = Result<(), DbError>> + Send + 'async_trait>> where Self: 'async_trait, 'life0: 'async_trait, 'life1: 'async_trait, 'life2: 'async_trait; fn sweep_favorites<'life0, 'life1, 'async_trait>( &'life0 self, server_id: &'life1 str, epoch: i64, ) -> Pin<Box<dyn Future<Output = Result<(), DbError>> + Send + 'async_trait>> where Self: 'async_trait, 'life0: 'async_trait, 'life1: 'async_trait; fn upsert_tracks<'life0, 'life1, 'life2, 'async_trait>( &'life0 self, source: &'life1 Source, tracks: &'life2 [Track], ) -> Pin<Box<dyn Future<Output = Result<(), DbError>> + Send + 'async_trait>> where Self: 'async_trait, 'life0: 'async_trait, 'life1: 'async_trait, 'life2: 'async_trait; fn upsert_albums<'life0, 'life1, 'life2, 'async_trait>( &'life0 self, source: &'life1 Source, albums: &'life2 [Album], ) -> Pin<Box<dyn Future<Output = Result<(), DbError>> + Send + 'async_trait>> where Self: 'async_trait, 'life0: 'async_trait, 'life1: 'async_trait, 'life2: 'async_trait;
}
Expand description

The persistence API: every mutation plus admin/dev ops, layered on top of the read-only ReadStore. One impl per target (sqlx native / in-mem stub).

Required Methods§

Source

fn save_config<'life0, 'life1, 'async_trait>( &'life0 self, cfg: &'life1 AppConfig, ) -> Pin<Box<dyn Future<Output = Result<(), DbError>> + Send + 'async_trait>>
where Self: 'async_trait, 'life0: 'async_trait, 'life1: 'async_trait,

Persist the whole AppConfig as the single-row JSON blob.

Source

fn import_legacy_json<'life0, 'life1, 'async_trait>( &'life0 self, config_dir: &'life1 Path, ) -> Pin<Box<dyn Future<Output = Result<ImportReport, DbError>> + Send + 'async_trait>>
where Self: 'async_trait, 'life0: 'async_trait, 'life1: 'async_trait,

One-shot import of the legacy *.json store at config_dir into the DB, then rename each imported file to *.json.bak and drop a sentinel. No-op if the DB already holds data or the sentinel exists. Idempotent; safe to call on every launch. (Native only; the wasm stub no-ops.)

Source

fn finalize_migration<'life0, 'life1, 'async_trait>( &'life0 self, config_dir: &'life1 Path, ) -> Pin<Box<dyn Future<Output = Result<usize, DbError>> + Send + 'async_trait>>
where Self: 'async_trait, 'life0: 'async_trait, 'life1: 'async_trait,

Point of no return: rename each imported X.jsonX.json.bak (kept for downgrade). Call only once every domain reads from the DB. Idempotent; no-op until a real import has happened. Returns how many files moved.

Source

fn delete_tracks<'life0, 'life1, 'life2, 'async_trait>( &'life0 self, source: &'life1 Source, keys: &'life2 [String], ) -> Pin<Box<dyn Future<Output = Result<u64, DbError>> + Send + 'async_trait>>
where Self: 'async_trait, 'life0: 'async_trait, 'life1: 'async_trait, 'life2: 'async_trait,

Delete tracks by key for a source. Returns rows removed.

Source

fn delete_album<'life0, 'life1, 'life2, 'async_trait>( &'life0 self, source: &'life1 Source, album_id: &'life2 str, ) -> Pin<Box<dyn Future<Output = Result<(), DbError>> + Send + 'async_trait>>
where Self: 'async_trait, 'life0: 'async_trait, 'life1: 'async_trait, 'life2: 'async_trait,

Delete an album AND its tracks (matches the legacy Library::remove_album).

Source

fn prune_source<'life0, 'life1, 'life2, 'life3, 'async_trait>( &'life0 self, source: &'life1 Source, keep_track_keys: &'life2 [String], keep_album_ids: &'life3 [String], ) -> Pin<Box<dyn Future<Output = Result<(), DbError>> + Send + 'async_trait>>
where Self: 'async_trait, 'life0: 'async_trait, 'life1: 'async_trait, 'life2: 'async_trait, 'life3: 'async_trait,

After a full sync: drop this source’s tracks/albums that were NOT in the sync (keep_* = the synced identities). The sync-side replacement for the old clear-and-repopulate.

Source

fn set_artist_image<'life0, 'life1, 'life2, 'life3, 'async_trait>( &'life0 self, artist_norm: &'life1 str, kind: &'life2 str, image_ref: Option<&'life3 str>, ) -> Pin<Box<dyn Future<Output = Result<(), DbError>> + Send + 'async_trait>>
where Self: 'async_trait, 'life0: 'async_trait, 'life1: 'async_trait, 'life2: 'async_trait, 'life3: 'async_trait,

Set (Some) or remove (None) one artist image. kind is "server" | "local" | "custom".

Source

fn update_album_cover<'life0, 'life1, 'life2, 'life3, 'async_trait>( &'life0 self, source: &'life1 Source, album_id: &'life2 str, cover_path: Option<&'life3 str>, manual: bool, ) -> Pin<Box<dyn Future<Output = Result<(), DbError>> + Send + 'async_trait>>
where Self: 'async_trait, 'life0: 'async_trait, 'life1: 'async_trait, 'life2: 'async_trait, 'life3: 'async_trait,

Set/clear an album’s cover (manual covers survive non-manual updates).

Source

fn upsert_playlist_meta<'life0, 'life1, 'life2, 'life3, 'life4, 'life5, 'async_trait>( &'life0 self, source: &'life1 Source, pl_id: &'life2 str, name: &'life3 str, cover_path: Option<&'life4 str>, image_tag: Option<&'life5 str>, ) -> Pin<Box<dyn Future<Output = Result<(), DbError>> + Send + 'async_trait>>
where Self: 'async_trait, 'life0: 'async_trait, 'life1: 'async_trait, 'life2: 'async_trait, 'life3: 'async_trait, 'life4: 'async_trait, 'life5: 'async_trait,

Upsert one playlist’s metadata (name/cover/image_tag), keeping membership.

Source

fn delete_playlist<'life0, 'life1, 'life2, 'async_trait>( &'life0 self, source: &'life1 Source, pl_id: &'life2 str, ) -> Pin<Box<dyn Future<Output = Result<(), DbError>> + Send + 'async_trait>>
where Self: 'async_trait, 'life0: 'async_trait, 'life1: 'async_trait, 'life2: 'async_trait,

Delete one playlist (membership cascades).

Source

fn set_playlist_tracks<'life0, 'life1, 'life2, 'life3, 'async_trait>( &'life0 self, source: &'life1 Source, pl_id: &'life2 str, refs: &'life3 [String], ) -> Pin<Box<dyn Future<Output = Result<(), DbError>> + Send + 'async_trait>>
where Self: 'async_trait, 'life0: 'async_trait, 'life1: 'async_trait, 'life2: 'async_trait, 'life3: 'async_trait,

Replace ONE playlist’s membership (creates the playlist row if absent). For reorders and full rebuilds; prefer the incremental variants below for single add/remove so a big playlist isn’t rewritten wholesale.

Source

fn add_playlist_tracks<'life0, 'life1, 'life2, 'life3, 'async_trait>( &'life0 self, source: &'life1 Source, pl_id: &'life2 str, refs: &'life3 [String], ) -> Pin<Box<dyn Future<Output = Result<(), DbError>> + Send + 'async_trait>>
where Self: 'async_trait, 'life0: 'async_trait, 'life1: 'async_trait, 'life2: 'async_trait, 'life3: 'async_trait,

Append refs to one playlist (creating it if absent), skipping any already present so a track is never duplicated.

Source

fn remove_playlist_tracks<'life0, 'life1, 'life2, 'life3, 'async_trait>( &'life0 self, source: &'life1 Source, pl_id: &'life2 str, refs: &'life3 [String], ) -> Pin<Box<dyn Future<Output = Result<(), DbError>> + Send + 'async_trait>>
where Self: 'async_trait, 'life0: 'async_trait, 'life1: 'async_trait, 'life2: 'async_trait, 'life3: 'async_trait,

Remove every occurrence of each ref from one playlist. No-op for absent playlists/refs.

Source

fn upsert_playlist_tracks_page<'life0, 'life1, 'life2, 'life3, 'async_trait>( &'life0 self, source: &'life1 Source, pl_id: &'life2 str, refs: &'life3 [String], start_position: i64, epoch: i64, ) -> Pin<Box<dyn Future<Output = Result<(), DbError>> + Send + 'async_trait>>
where Self: 'async_trait, 'life0: 'async_trait, 'life1: 'async_trait, 'life2: 'async_trait, 'life3: 'async_trait,

Streaming upsert of one page of a playlist’s entries (creating the playlist row if absent): each ref is written at start_position + i and stamped with the current walk’s epoch. On position conflict the ref and epoch are overwritten — so re-walking in order applies adds, reorders, and (with the trailing sweep) removals, all without rewriting the whole list up front.

Source

fn sweep_playlist_tracks<'life0, 'life1, 'life2, 'async_trait>( &'life0 self, source: &'life1 Source, pl_id: &'life2 str, epoch: i64, ) -> Pin<Box<dyn Future<Output = Result<(), DbError>> + Send + 'async_trait>>
where Self: 'async_trait, 'life0: 'async_trait, 'life1: 'async_trait, 'life2: 'async_trait,

End-of-walk sweep: drop one playlist’s rows NOT re-stamped with epoch — entries removed remotely, plus the stale tail when the playlist shrank.

Source

fn create_folder<'life0, 'life1, 'life2, 'async_trait>( &'life0 self, id: &'life1 str, name: &'life2 str, ) -> Pin<Box<dyn Future<Output = Result<(), DbError>> + Send + 'async_trait>>
where Self: 'async_trait, 'life0: 'async_trait, 'life1: 'async_trait, 'life2: 'async_trait,

Create one (local) playlist folder.

Source

fn rename_folder<'life0, 'life1, 'life2, 'async_trait>( &'life0 self, id: &'life1 str, name: &'life2 str, ) -> Pin<Box<dyn Future<Output = Result<(), DbError>> + Send + 'async_trait>>
where Self: 'async_trait, 'life0: 'async_trait, 'life1: 'async_trait, 'life2: 'async_trait,

Rename one folder.

Source

fn delete_folder<'life0, 'life1, 'async_trait>( &'life0 self, id: &'life1 str, ) -> Pin<Box<dyn Future<Output = Result<(), DbError>> + Send + 'async_trait>>
where Self: 'async_trait, 'life0: 'async_trait, 'life1: 'async_trait,

Delete one folder; its playlist memberships cascade away.

Source

fn set_playlist_folder<'life0, 'life1, 'life2, 'async_trait>( &'life0 self, playlist_ref: &'life1 str, folder_id: Option<&'life2 str>, ) -> Pin<Box<dyn Future<Output = Result<(), DbError>> + Send + 'async_trait>>
where Self: 'async_trait, 'life0: 'async_trait, 'life1: 'async_trait, 'life2: 'async_trait,

Move one playlist into folder_id, or out of every folder when None. Folder membership is single-folder per playlist.

Source

fn bump_listen_count<'life0, 'life1, 'async_trait>( &'life0 self, track_uid: &'life1 str, ) -> Pin<Box<dyn Future<Output = Result<(), DbError>> + Send + 'async_trait>>
where Self: 'async_trait, 'life0: 'async_trait, 'life1: 'async_trait,

Increment one track’s play count (single-row upsert; key = TrackId::uid()).

Source

fn push_recent<'life0, 'life1, 'life2, 'async_trait>( &'life0 self, source: &'life1 Source, track_key: &'life2 str, ) -> Pin<Box<dyn Future<Output = Result<(), DbError>> + Send + 'async_trait>>
where Self: 'async_trait, 'life0: 'async_trait, 'life1: 'async_trait, 'life2: 'async_trait,

Record a play for this source’s recently-played history (caps + trims).

Source

fn set_offline_track<'life0, 'life1, 'life2, 'async_trait>( &'life0 self, id: &'life1 str, path: Option<&'life2 str>, ) -> Pin<Box<dyn Future<Output = Result<(), DbError>> + Send + 'async_trait>>
where Self: 'async_trait, 'life0: 'async_trait, 'life1: 'async_trait, 'life2: 'async_trait,

Register/unregister one offline download in the config blob (single json_set/json_remove — the downloads hot path must not rewrite the whole config per finished song).

Source

fn save_queue<'life0, 'life1, 'async_trait>( &'life0 self, snap: &'life1 QueueSnapshot, ) -> Pin<Box<dyn Future<Output = Result<(), DbError>> + Send + 'async_trait>>
where Self: 'async_trait, 'life0: 'async_trait, 'life1: 'async_trait,

Persist the queue/progress snapshot to the single queue_state row.

Source

fn meta_put<'life0, 'life1, 'life2, 'life3, 'async_trait>( &'life0 self, cache_key: &'life1 str, kind: &'life2 str, payload: &'life3 str, ) -> Pin<Box<dyn Future<Output = Result<(), DbError>> + Send + 'async_trait>>
where Self: 'async_trait, 'life0: 'async_trait, 'life1: 'async_trait, 'life2: 'async_trait, 'life3: 'async_trait,

Generic metadata-cache write (upsert of payload for (cache_key, kind)).

Source

fn debug_reset<'life0, 'life1, 'async_trait>( &'life0 self, db_path: &'life1 Path, ) -> Pin<Box<dyn Future<Output = Result<(), DbError>> + Send + 'async_trait>>
where Self: 'async_trait, 'life0: 'async_trait, 'life1: 'async_trait,

Delete the database files at db_path, re-init an empty schema there, and hot-swap the live pool onto it.

Source

fn debug_load_release<'life0, 'life1, 'life2, 'async_trait>( &'life0 self, release_path: &'life1 Path, db_path: &'life2 Path, ) -> Pin<Box<dyn Future<Output = Result<(), DbError>> + Send + 'async_trait>>
where Self: 'async_trait, 'life0: 'async_trait, 'life1: 'async_trait, 'life2: 'async_trait,

Copy the release database over db_path (running any pending migrations on the copy) and hot-swap the live pool onto it.

Source

fn debug_seed_synthetic<'life0, 'async_trait>( &'life0 self, n: u32, ) -> Pin<Box<dyn Future<Output = Result<(), DbError>> + Send + 'async_trait>>
where Self: 'async_trait, 'life0: 'async_trait,

Insert n synthetic local tracks (perf testing the windowed queries).

Source

fn debug_info<'life0, 'async_trait>( &'life0 self, ) -> Pin<Box<dyn Future<Output = Result<String, DbError>> + Send + 'async_trait>>
where Self: 'async_trait, 'life0: 'async_trait,

Human-readable DB info: applied migrations + row counts.

Source

fn debug_vacuum<'life0, 'async_trait>( &'life0 self, ) -> Pin<Box<dyn Future<Output = Result<(), DbError>> + Send + 'async_trait>>
where Self: 'async_trait, 'life0: 'async_trait,

VACUUM.

Source

fn set_favorite<'life0, 'life1, 'life2, 'async_trait>( &'life0 self, server_id: &'life1 str, ref_: &'life2 str, on: bool, ) -> Pin<Box<dyn Future<Output = Result<(), DbError>> + Send + 'async_trait>>
where Self: 'async_trait, 'life0: 'async_trait, 'life1: 'async_trait, 'life2: 'async_trait,

Toggle a favorite locally, optimistically. on upserts the row as a pending-like (dirty=1). !on deletes a never-pushed like outright and turns a synced row into a pending-unlike tombstone (dirty=2) so the removal can be pushed later. Works while unauthenticated — the reconciler flushes pending rows once a server is active.

Source

fn clear_favorite_dirty<'life0, 'life1, 'life2, 'async_trait>( &'life0 self, server_id: &'life1 str, ref_: &'life2 str, ) -> Pin<Box<dyn Future<Output = Result<(), DbError>> + Send + 'async_trait>>
where Self: 'async_trait, 'life0: 'async_trait, 'life1: 'async_trait, 'life2: 'async_trait,

Resolve a ref after a successful remote push: a pending-like becomes clean, a pending-unlike tombstone is deleted.

Source

fn replace_favorites_clean<'life0, 'life1, 'life2, 'async_trait>( &'life0 self, server_id: &'life1 str, refs: &'life2 [String], ) -> Pin<Box<dyn Future<Output = Result<(), DbError>> + Send + 'async_trait>>
where Self: 'async_trait, 'life0: 'async_trait, 'life1: 'async_trait, 'life2: 'async_trait,

Replace a server’s favorites with the remote set (a sync pull): rows not in refs and not dirty are dropped, rows in refs are added clean. Dirty local rows are preserved (push-before-pull hasn’t flushed them yet).

Source

fn upsert_favorites_page<'life0, 'life1, 'life2, 'async_trait>( &'life0 self, server_id: &'life1 str, refs: &'life2 [String], start_rank: i64, epoch: i64, ) -> Pin<Box<dyn Future<Output = Result<(), DbError>> + Send + 'async_trait>>
where Self: 'async_trait, 'life0: 'async_trait, 'life1: 'async_trait, 'life2: 'async_trait,

Upsert one page of a streaming favorites sync: refs become clean rows at start_rank + offset (remote order), stamped with epoch. Existing rows update in place; dirty rows keep their flag. Pair with sweep_favorites at stream end. Lets the list grow live during the walk.

Source

fn sweep_favorites<'life0, 'life1, 'async_trait>( &'life0 self, server_id: &'life1 str, epoch: i64, ) -> Pin<Box<dyn Future<Output = Result<(), DbError>> + Send + 'async_trait>>
where Self: 'async_trait, 'life0: 'async_trait, 'life1: 'async_trait,

End-of-stream sweep for upsert_favorites_page: drop clean rows not stamped with the current epoch (unliked remotely). Dirty rows survive.

Source

fn upsert_tracks<'life0, 'life1, 'life2, 'async_trait>( &'life0 self, source: &'life1 Source, tracks: &'life2 [Track], ) -> Pin<Box<dyn Future<Output = Result<(), DbError>> + Send + 'async_trait>>
where Self: 'async_trait, 'life0: 'async_trait, 'life1: 'async_trait, 'life2: 'async_trait,

Batch upsert tracks for a source (one transaction). Identity is (source, track_key); an existing row is updated in place. Used by the streaming scan/sync so a batch lands atomically.

Source

fn upsert_albums<'life0, 'life1, 'life2, 'async_trait>( &'life0 self, source: &'life1 Source, albums: &'life2 [Album], ) -> Pin<Box<dyn Future<Output = Result<(), DbError>> + Send + 'async_trait>>
where Self: 'async_trait, 'life0: 'async_trait, 'life1: 'async_trait, 'life2: 'async_trait,

Batch upsert albums for a source (one transaction).

Dyn Compatibility§

This trait is dyn compatible.

In older versions of Rust, dyn compatibility was called "object safety".

Implementors§