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§
Sourcefn 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 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.
Sourcefn 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 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.)
Sourcefn 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 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.json → X.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.
Sourcefn 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_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.
Sourcefn 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 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).
Sourcefn 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 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.
Sourcefn 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 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".
Sourcefn 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 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).
Sourcefn 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 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.
Sourcefn 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 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).
Sourcefn 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 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.
Sourcefn 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 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.
Sourcefn 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 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.
Sourcefn 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 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.
Sourcefn 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 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.
Sourcefn 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 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.
Sourcefn 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 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.
Sourcefn 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 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.
Sourcefn 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 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.
Sourcefn 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 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()).
Sourcefn 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 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).
Sourcefn 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 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).
Sourcefn 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 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.
Sourcefn 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 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)).
Sourcefn 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_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.
Sourcefn 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_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.
Sourcefn 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_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).
Sourcefn 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_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.
Sourcefn 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 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.
Sourcefn 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 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.
Sourcefn 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 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.
Sourcefn 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 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).
Sourcefn 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 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.
Sourcefn 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 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.
Sourcefn 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_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.
Sourcefn 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,
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".