# SCHEMA This file represents the initial schema for the various data structures to be stored in the database. These schema definitions target SQLite v3. # Persons Table The Persons table will contain data about Person entities (see MODELS.md) ``` sql CREATE TABLE Persons ( id TEXT(36), /* UUIDv4 */ remote_id TEXT, /* field to store an arbitrary remote identifier for this Person if they are not local */ name TEXT, /* "real" name */ handle TEXT, /* also commonly refered to as 'display_name' or 'screen_name', optional (if missing, name will be used as handle) */ is_active INTEGER DEFAULT (1), /* bool, default true */ is_blocked INTEGER DEFAULT (0), /* bool, default false */ created_at INTEGER, /* timestamp */ modified_at INTEGER, /* timestamp */ modified_by TEXT(36), /* UUIDv4 */ deleted_at INTEGER, /* timestamp */ deleted_by TEXT(36), /* UUIDv4 */ last_seen INTEGER, /* timestamp */ shipping_address TEXT, /* optional, should use \n between lines to keep localized format as needed */ CONSTRAINT Persons_PK PRIMARY KEY (id), CONSTRAINT Persons_FK FOREIGN KEY (modified_by) REFERENCES Persons(id), CONSTRAINT Persons_FK_1 FOREIGN KEY (deleted_by) REFERENCES Persons(id) ); CREATE UNIQUE INDEX Persons_remote_id_IDX ON Persons (remote_id); CREATE INDEX Persons_name_IDX ON Persons (name); CREATE INDEX Persons_handle_IDX ON Persons (handle); CREATE INDEX Persons_is_active_IDX ON Persons (is_active); CREATE INDEX Persons_is_blocked_IDX ON Persons (is_blocked); CREATE INDEX Persons_deleted_at_IDX ON Persons (deleted_at); ``` # PersonEmails Table The PersonEmails table is a one-to-many lookup table relating a Person to zero or more email addresses ``` sql CREATE TABLE PersonEmails ( person_id TEXT(36), email TEXT, is_verified INTEGER DEFAULT (0), is_primary INTEGER DEFAULT (0), CONSTRAINT PersonEmails_PK PRIMARY KEY (email), CONSTRAINT PersonEmails_FK FOREIGN KEY (person_id) REFERENCES Persons(id) ON DELETE CASCADE ); CREATE INDEX PersonEmails_person_id_IDX ON PersonEmails (person_id); CREATE INDEX PersonEmails_is_verified_IDX ON PersonEmails (is_verified); CREATE INDEX PersonEmails_is_primary_IDX ON PersonEmails (is_primary); ``` # PersonCredentialProvider The PersonCredentialProvider table will contain configuration for different authentication providers. ``` sql CREATE TABLE PersonCredentialProvider ( id TEXT(36), name TEXT, "type" TEXT, config TEXT, CONSTRAINT PersonCredentialProvider_PK PRIMARY KEY (id) ); CREATE INDEX PersonCredentialProvider_name_IDX ON PersonCredentialProvider (name); CREATE INDEX PersonCredentialProvider_type_IDX ON PersonCredentialProvider ("type"); ``` # PersonCredential The PersonCredential table will contain authentication credentials for Persons ``` sql CREATE TABLE PersonCredential ( id TEXT(36), person_id TEXT(36), provider_id TEXT(36), provider_user_id TEXT(36), is_enabled INTEGER DEFAULT (1), CONSTRAINT PersonCredential_PK PRIMARY KEY (id), CONSTRAINT PersonCredential_FK FOREIGN KEY (person_id) REFERENCES Persons(id) ON DELETE CASCADE, CONSTRAINT PersonCredential_FK_1 FOREIGN KEY (provider_id) REFERENCES PersonCredentialProvider(id) ON DELETE CASCADE ); CREATE INDEX PersonCredential_person_id_IDX ON PersonCredential (person_id); CREATE INDEX PersonCredential_provider_id_IDX ON PersonCredential (provider_id); CREATE INDEX PersonCredential_is_enabled_IDX ON PersonCredential (is_enabled); ``` # PersonLocal The PersonLocal table will contain hashed and salted passwords for users authenticating via PersonCredentialProvider.Local type provider ``` sql CREATE TABLE PersonLocal ( person_id TEXT(36), hash TEXT, modified_at INTEGER, modified_by TEXT(36), CONSTRAINT PersonLocal_PK PRIMARY KEY (person_id), CONSTRAINT PersonLocal_FK FOREIGN KEY (person_id) REFERENCES Persons(id) ON DELETE CASCADE ); ``` # Tags The Tags table will contain tags for categorization of other entities. Tags use the originating host and the tag name as a composite key to allow for us to search for commonalities across instances (for example, "show me Albums matching *::tag::jazz" to see all the jazz albums this instance is aware of, "show me Albums matching sundog-isle.reclaim.technology::tag::jazz" to see only albums tagged as jazz on that one specific instance named in the host field). ``` sql CREATE TABLE Tags ( id TEXT(36), host TEXT, tag TEXT, CONSTRAINT Tags_PK PRIMARY KEY (id) ); CREATE UNIQUE INDEX Tags_host_IDX ON Tags (host,tag); ``` # Labels The Labels table will contain data about record labels/imprints that manage one or more Artists and their content. ``` sql CREATE TABLE Labels ( id TEXT(36), name TEXT, description TEXT, website TEXT, is_enabled INTEGER DEFAULT (1), created_by TEXT(36), created_at INTEGER, modified_by TEXT(36), modified_at INTEGER, deleted_by TEXT(36), deleted_at INTEGER, CONSTRAINT Labels_PK PRIMARY KEY (id), CONSTRAINT Labels_FK FOREIGN KEY (created_by) REFERENCES Persons(id), CONSTRAINT Labels_FK_1 FOREIGN KEY (modified_at) REFERENCES Persons(id), CONSTRAINT Labels_FK_2 FOREIGN KEY (deleted_by) REFERENCES Persons(id) ); CREATE INDEX Labels_name_IDX ON Labels (name); CREATE INDEX Labels_description_IDX ON Labels (description); CREATE INDEX Labels_is_enabled_IDX ON Labels (is_enabled); CREATE INDEX Labels_created_by_IDX ON Labels (created_by); CREATE INDEX Labels_deleted_at_IDX ON Labels (deleted_at); ``` # LabelContacts The LabelContacts table will contain key-value pairs of methods to contact representatives of the Label (for example, "fediverse: sundog@toot-lab.reclaim.technology" or "email: sundog@reclaim.technology"). ``` sql CREATE TABLE LabelContacts ( id TEXT(36), label_id TEXT(36), "method" TEXT, address TEXT, created_by TEXT(36), created_at INTEGER, modified_by TEXT(36), modified_at INTEGER, deleted_by TEXT(36), deleted_at INTEGER, sort_order INTEGER, CONSTRAINT LabelContacts_PK PRIMARY KEY (id), CONSTRAINT LabelContacts_FK FOREIGN KEY (created_by) REFERENCES Persons(id), CONSTRAINT LabelContacts_FK_1 FOREIGN KEY (modified_by) REFERENCES Persons(id), CONSTRAINT LabelContacts_FK_2 FOREIGN KEY (deleted_by) REFERENCES Persons(id), CONSTRAINT LabelContacts_FK_3 FOREIGN KEY (label_id) REFERENCES Labels(id) ON DELETE CASCADE ); CREATE INDEX LabelContacts_sort_order_IDX ON LabelContacts (sort_order); ``` # LabelTags The LabelTags table will contain Tags that have been assigned to a Label. ``` sql CREATE TABLE LabelTags ( label_id TEXT(36), tag_id TEXT(36), is_approved INTEGER DEFAULT (0), CONSTRAINT LabelTags_PK PRIMARY KEY (label_id,tag_id), CONSTRAINT LabelTags_FK FOREIGN KEY (label_id) REFERENCES Labels(id) ON DELETE CASCADE, CONSTRAINT LabelTags_FK_1 FOREIGN KEY (tag_id) REFERENCES Tags(id) ON DELETE CASCADE ); CREATE INDEX LabelTags_is_approved_IDX ON LabelTags (is_approved); CREATE INDEX LabelTags_tag_id_IDX ON LabelTags (tag_id); CREATE INDEX LabelTags_label_id_IDX ON LabelTags (label_id); ``` # Artists The Artists table will contain Artists! ``` sql CREATE TABLE Artists ( id TEXT(36), name TEXT, bio TEXT, website TEXT, created_by TEXT(36), created_at INTEGER, modified_by TEXT(36), modified_at INTEGER, deleted_by TEXT(36), deleted_at INTEGER, is_enabled INTEGER DEFAULT (1), is_public INTEGER DEFAULT (1), CONSTRAINT Artists_PK PRIMARY KEY (id), CONSTRAINT Artists_FK FOREIGN KEY (created_by) REFERENCES Persons(id), CONSTRAINT Artists_FK_1 FOREIGN KEY (modified_by) REFERENCES Persons(id), CONSTRAINT Artists_FK_2 FOREIGN KEY (deleted_by) REFERENCES Persons(id) ); CREATE INDEX Artists_name_IDX ON Artists (name); CREATE INDEX Artists_is_enabled_IDX ON Artists (is_enabled); CREATE INDEX Artists_is_public_IDX ON Artists (is_public); ``` # ArtistTags The ArtistTags table will contain Tags that have been assigned to an Artist. ``` sql CREATE TABLE ArtistTags ( artist_id TEXT(36), tag_id TEXT(36), is_approved INTEGER DEFAULT (0), CONSTRAINT ArtistTags_PK PRIMARY KEY (artist_id,tag_id), CONSTRAINT ArtistTags_FK FOREIGN KEY (artist_id) REFERENCES Artists(id) ON DELETE CASCADE, CONSTRAINT ArtistTags_FK_1 FOREIGN KEY (tag_id) REFERENCES Tags(id) ON DELETE CASCADE ); CREATE INDEX ArtistTags_is_approved_IDX ON ArtistTags (is_approved); CREATE INDEX ArtistTags_artist_id_IDX ON ArtistTags (artist_id); CREATE INDEX ArtistTags_tag_id_IDX ON ArtistTags (tag_id); ``` # Tracks The Tracks table will contain Tracks! ``` sql CREATE TABLE Tracks ( id TEXT(36), title TEXT, description TEXT, duration REAL, is_public INTEGER, is_available INTEGER DEFAULT (1), preview_source TEXT, "source" TEXT, price INTEGER DEFAULT (0), created_by TEXT(36), created_at INTEGER, modified_by TEXT(36), modified_at INTEGER, deleted_by TEXT(36), deleted_at INTEGER, lyrics TEXT, CONSTRAINT Tracks_PK PRIMARY KEY (id), CONSTRAINT Tracks_FK FOREIGN KEY (created_by) REFERENCES Persons(id), CONSTRAINT Tracks_FK_1 FOREIGN KEY (modified_by) REFERENCES Persons(id), CONSTRAINT Tracks_FK_2 FOREIGN KEY (deleted_by) REFERENCES Persons(id) ); CREATE INDEX Tracks_title_IDX ON Tracks (title); CREATE INDEX Tracks_duration_IDX ON Tracks (duration); CREATE INDEX Tracks_is_public_IDX ON Tracks (is_public); CREATE INDEX Tracks_is_available_IDX ON Tracks (is_available); CREATE INDEX Tracks_price_IDX ON Tracks (price); CREATE INDEX Tracks_created_by_IDX ON Tracks (created_by); CREATE INDEX Tracks_deleted_at_IDX ON Tracks (deleted_at); CREATE INDEX Tracks_lyrics_IDX ON Tracks (lyrics); ``` # TrackArtists The TrackArtists table will be a one-to-many lookup table mapping Artists to a particular Track. ``` sql CREATE TABLE TrackArtists ( track_id TEXT(36), artist_id TEXT(36), is_primary INTEGER DEFAULT (0), CONSTRAINT TrackArtists_PK PRIMARY KEY (track_id,artist_id), CONSTRAINT TrackArtists_FK FOREIGN KEY (track_id) REFERENCES Tracks(id) ON DELETE CASCADE, CONSTRAINT TrackArtists_FK_1 FOREIGN KEY (artist_id) REFERENCES Artists(id) ON DELETE CASCADE ); CREATE INDEX TrackArtists_is_primary_IDX ON TrackArtists (is_primary); CREATE INDEX TrackArtists_track_id_IDX ON TrackArtists (track_id); CREATE INDEX TrackArtists_artist_id_IDX ON TrackArtists (artist_id); ``` # TrackTags The TrackTags table will contain Tags that have been assigned to a Track. ``` sql CREATE TABLE TrackTags ( track_id TEXT(36), tag_id TEXT(36), is_approved INTEGER DEFAULT (0), CONSTRAINT TrackTags_PK PRIMARY KEY (track_id,tag_id), CONSTRAINT TrackTags_FK FOREIGN KEY (track_id) REFERENCES Tracks(id) ON DELETE CASCADE, CONSTRAINT TrackTags_FK_1 FOREIGN KEY (tag_id) REFERENCES Tags(id) ON DELETE CASCADE ); CREATE INDEX TrackTags_is_approved_IDX ON TrackTags (is_approved); CREATE INDEX TrackTags_track_id_IDX ON TrackTags (track_id); CREATE INDEX TrackTags_tag_id_IDX ON TrackTags (tag_id); ``` # Albums The Albums table will contain Albums! ``` sql CREATE TABLE Albums ( id TEXT(36), title TEXT, description TEXT, is_public INTEGER DEFAULT (0), is_available INTEGER DEFAULT (1), preview_source TEXT, "source" TEXT, price INTEGER DEFAULT (0), created_by TEXT(36), created_at INTEGER, modified_by TEXT(36), modified_at INTEGER, deleted_by TEXT(36), deleted_at INTEGER, CONSTRAINT Albums_PK PRIMARY KEY (id), CONSTRAINT Albums_FK FOREIGN KEY (created_by) REFERENCES Persons(id), CONSTRAINT Albums_FK_1 FOREIGN KEY (modified_by) REFERENCES Persons(id), CONSTRAINT Albums_FK_2 FOREIGN KEY (deleted_by) REFERENCES Persons(id) ); CREATE INDEX Albums_title_IDX ON Albums (title); CREATE INDEX Albums_description_IDX ON Albums (description); CREATE INDEX Albums_is_public_IDX ON Albums (is_public); CREATE INDEX Albums_is_available_IDX ON Albums (is_available); CREATE INDEX Albums_price_IDX ON Albums (price); CREATE INDEX Albums_created_by_IDX ON Albums (created_by); CREATE INDEX Albums_deleted_at_IDX ON Albums (deleted_at); ``` # AlbumArtists # AlbumTags # Playlists # PlaylistTracks # PlaylistTags # Comments # LabelComments # ArtistComments # TrackComments # AlbumComments # PlaylistComments