Modèle de données
Le catalogue de bae est du SQLite ordinaire, déclaré à coven table par table : les tables synchronisées vont sur chaque appareil qui peut les lire ; les tables non déclarées ne quittent jamais l’appareil. Cette séparation est la décision la plus déterminante du modèle de données, donc cette page est organisée autour d’elle.
Le graphe du catalogue
Lien vers cette sectionLe cœur synchronisé du schéma :
artists,albums,works: la couche de groupement. Un album agrège ses sorties et pointe vers une sortie principale ; les œuvres forment un graphe parent/enfant pour la structure classique.releases: l’entité centrale, une ligne par copie importée. Contient les faits de frappage (étiquette, numéro de catalogue, code-barres, pays, format, année), la provenance des métadonnées optionnelles, un hachage du contenu du dossier importé, et le volume de l’album mesuré. Aucune provenance signifie que les métadonnées ont été saisies directement ; la provenance externe nomme la sortie source exacte, tandis que Tags des fichiers enregistre une source locale d’instantané.release_identities: les identités externes exactes de ce qu’une version est. Aucune ligne ne signifie aucune identité externe. Chaque ligne nomme une version et un groupe de versions MusicBrainz ou Discogs, et une version peut contenir des identités dans les deux sources à la fois. Ceci est distinct de la provenance : l’identité peut changer sans prétendre que les métadonnées éditables actuelles ont été réinitialisées à partir de cette source.tracksavectrack_artists, plusrelease_artist_rolesettrack_artist_roles: listes de pistes et crédits, chaque crédit étant marqué avec sa source.track_works,work_parts,work_artists: enregistrements liés aux œuvres qu’ils interprètent.audio_formatsetaudio_format_segments: les spécifications de lecture. Par piste : codec, fréquence d’échantillonnage, profondeur de bits, canaux, niveau sonore et pic mesurés, et longueurs de pregap. Les segments placent une piste sur des fenêtres d’octets et d’échantillons ordonnées de ses fichiers sources ; c’est ainsi que la piste d’un rip CUE, pregap compris, peut couvrir des régions d’un gros fichier, ou de plusieurs fichiers.release_files,covers,artist_images: tables portant des blobs. Les lignes sont des entrées de catalogue ; les octets vivent dans la couche de blobs de coven (voir ci-dessous).people,ratings,history,playlists,playlist_entries: le profil de chaque personne et ce qu’elle enregistre pour elle-même. Ce sont des tables de propriétaire : seuls les appareils de leur auteur peuvent les modifier. Les lignes dehistoryetplaylistsvivent chacune soit dans le stockage partagé du foyer, soit dans le cercle privé de la personne.
Synchronisé et local
Lien vers cette sectionChaque table ci-dessus se synchronise, sans condition : les lignes d’une sortie locale atteignent chaque appareil comme celles de toute autre sortie, donc chaque appareil sait ce que possède le foyer, et une note ou une entrée de liste qui pointe vers une piste d’une sortie locale pointe vers une ligne que chaque appareil peut lire. Seuls l’audio de la sortie et les chemins où il se trouve restent sur l’appareil importateur. Chaque table est déclarée avec son identité de ligne, son audience, le fait qu’elle soit ou non une table de propriétaire et les fichiers qu’elle porte ; un test maintient les déclarations exactement sur cette liste.
Tables entièrement locales, jamais déclarées à coven :
playback_state: piste en cours, position, file d’attente, volume, lecture aléatoire et répétition. La lecture est un fait d’appareil.- Les tables d’analyse et d’importation : dossiers surveillés, analyses, candidats à l’importation et leurs brouillons.
source_releaseet les tables qui en dépendent : ce que bae a extrait de chaque sortie MusicBrainz et Discogs qu’il a récupérée — informations d’album et de pressage, liste complète des pistes avec crédits et œuvres, choix de pochette et nom que lui donnent les autres catalogues — codé par la version du fournisseur plutôt que par une version locale. Le JSON brut n’est pas conservé ; n’importe quel appareil peut récupérer une sortie à nouveau.local_release_files: les chemins de fichiers et dates de modification d’une sortie locale sur cet appareil.local_history: les écoutes d’avant que la personne de cet appareil ait un profil, déplacées dans son cercle privé lorsqu’il est créé.
Les modifications de deux appareils fusionnent cellule par cellule, la modification la plus tardive l’emportant sur une cellule que les deux ont changée. coven tient la comptabilité de fusion dans ses propres tables, donc les tables de bae ne portent aucune colonne d’horloge.
Audio et images sont des fichiers coven, chaque type formant un espace de noms avec sa propre limite de cache par appareil : release_files (20 GiB), covers (512 MiB), artist_images (256 MiB) et avatars (64 MiB). Une ligne référence son fichier par l’identifiant du fichier coven : file dans release_files, covers et artist_images, et avatar_id dans people. La taille, l’empreinte du contenu et l’emplacement du fichier appartiennent à coven et se lisent par une jointure avec coven_files.
Les fichiers de sortie appartiennent à l’utilisateur : les fichiers d’une sortie locale sont les fichiers de l’utilisateur à leurs chemins d’origine, enregistrés dans local_release_files, et ses lignes ne référencent aucun fichier coven. Déplacer la sortie vers le cloud prépare chaque fichier auprès de coven en une seule écriture et fait pointer chaque ligne vers son fichier ; une fois le dernier stocké, coven les bascule tous ensemble vers le cloud, et les autres appareils récupèrent chacun d’eux dans le cache à la première lecture. Les pochettes, images d’artistes et avatars appartiennent à bae : bae produit les octets (les pochettes sont rerendues en vignettes JPEG d’au plus 600 px de large), et un appareil récupère chacun d’eux la première fois qu’il est affiché et le garde jusqu’à ce que la limite de son espace de noms l’évince.
Chaque fichier est envoyé chiffré sous un nom aléatoire, à un chemin fixé quand il est préparé, afin qu’un renommage ultérieur ne déplace jamais l’objet. Un fichier ne change jamais ses octets : une nouvelle image est un nouveau fichier.
Identité d’un rip
Lien vers cette sectionChaque import crée une sortie avec un nouvel identifiant aléatoire et ses propres lignes de pistes et de fichiers. Chaque appareil enregistre dans local_release_origin un SHA-256 des chemins relatifs triés, tailles et dates de modification des fichiers lus par chacun de ses imports ; cet enregistrement n’est jamais synchronisé. Un dossier dont cet appareil a enregistré le hachage figure dans l’onglet des imports terminés, où qu’il ait été déplacé, et sa ligne nomme la seule sortie importée depuis ce dossier. Importer à nouveau les mêmes fichiers sur cet appareil échoue, et l’onglet des imports terminés ne propose aucune action de réimportation.