mirror of https://github.com/synctv-org/synctv
You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
135 lines
6.2 KiB
SQL
135 lines
6.2 KiB
SQL
CREATE TABLE IF NOT EXISTS room_playback_progress (
|
|
id BIGSERIAL PRIMARY KEY,
|
|
room_id BIGINT NOT NULL REFERENCES rooms(id) ON DELETE CASCADE,
|
|
media_id BIGINT NULL,
|
|
playlist_id BIGINT NULL,
|
|
target JSONB NULL,
|
|
target_hash TEXT NOT NULL,
|
|
"position" DOUBLE PRECISION NOT NULL DEFAULT 0.0,
|
|
created_at TIMESTAMPTZ NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
|
updated_at TIMESTAMPTZ NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
|
version BIGINT NOT NULL DEFAULT 0,
|
|
CONSTRAINT room_playback_progress_position_non_negative
|
|
CHECK ("position" >= 0),
|
|
CONSTRAINT room_playback_progress_has_supported_source
|
|
CHECK (
|
|
(media_id IS NOT NULL AND target IS NULL)
|
|
OR (media_id IS NULL AND playlist_id IS NOT NULL AND target IS NOT NULL)
|
|
),
|
|
CONSTRAINT room_playback_progress_target_hash_sha256
|
|
CHECK (target_hash ~ '^[0-9a-f]{64}$'),
|
|
CONSTRAINT room_playback_progress_target_object
|
|
CHECK (target IS NULL OR jsonb_typeof(target) = 'object'),
|
|
CONSTRAINT room_playback_progress_media_same_room_fk
|
|
FOREIGN KEY (media_id, room_id)
|
|
REFERENCES media(id, room_id)
|
|
ON DELETE CASCADE,
|
|
CONSTRAINT room_playback_progress_playlist_same_room_fk
|
|
FOREIGN KEY (playlist_id, room_id)
|
|
REFERENCES playlists(id, room_id)
|
|
ON DELETE CASCADE
|
|
);
|
|
|
|
CREATE UNIQUE INDEX IF NOT EXISTS room_playback_progress_source_unique
|
|
ON room_playback_progress(
|
|
room_id,
|
|
COALESCE(media_id, 0),
|
|
COALESCE(playlist_id, 0),
|
|
target_hash
|
|
);
|
|
CREATE INDEX IF NOT EXISTS idx_room_playback_progress_media_id ON room_playback_progress(media_id);
|
|
CREATE INDEX IF NOT EXISTS idx_room_playback_progress_playlist_id ON room_playback_progress(playlist_id);
|
|
CREATE INDEX IF NOT EXISTS idx_room_playback_progress_updated_at ON room_playback_progress(updated_at);
|
|
|
|
CREATE TRIGGER update_room_playback_progress_updated_at
|
|
BEFORE UPDATE ON room_playback_progress
|
|
FOR EACH ROW
|
|
EXECUTE FUNCTION update_updated_at_column();
|
|
|
|
CREATE TABLE IF NOT EXISTS room_playback_history (
|
|
id BIGSERIAL,
|
|
room_id BIGINT NOT NULL REFERENCES rooms(id) ON DELETE CASCADE,
|
|
sequence BIGINT NOT NULL,
|
|
media_id BIGINT NULL,
|
|
playlist_id BIGINT NULL,
|
|
target JSONB NULL,
|
|
target_hash TEXT NOT NULL,
|
|
media_name TEXT NULL,
|
|
playlist_name TEXT NULL,
|
|
position_seconds DOUBLE PRECISION NOT NULL DEFAULT 0.0,
|
|
selected_by_user_id BIGINT NULL REFERENCES users(id) ON DELETE SET NULL,
|
|
created_at TIMESTAMPTZ NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
|
updated_at TIMESTAMPTZ NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
|
PRIMARY KEY (room_id, id, created_at),
|
|
CONSTRAINT room_playback_history_position_seconds_non_negative CHECK (position_seconds >= 0),
|
|
CONSTRAINT room_playback_history_has_supported_source CHECK (
|
|
(media_id IS NOT NULL AND target IS NULL)
|
|
OR (media_id IS NULL AND playlist_id IS NOT NULL AND target IS NOT NULL)
|
|
),
|
|
CONSTRAINT room_playback_history_target_hash_sha256
|
|
CHECK (target_hash ~ '^[0-9a-f]{64}$'),
|
|
CONSTRAINT room_playback_history_target_object
|
|
CHECK (target IS NULL OR jsonb_typeof(target) = 'object'),
|
|
CONSTRAINT room_playback_history_media_same_room_fk
|
|
FOREIGN KEY (media_id, room_id) REFERENCES media(id, room_id) ON DELETE CASCADE,
|
|
CONSTRAINT room_playback_history_playlist_same_room_fk
|
|
FOREIGN KEY (playlist_id, room_id) REFERENCES playlists(id, room_id) ON DELETE CASCADE
|
|
) PARTITION BY RANGE (created_at);
|
|
|
|
CREATE INDEX IF NOT EXISTS idx_room_playback_history_room_sequence
|
|
ON room_playback_history(room_id, sequence DESC);
|
|
CREATE INDEX IF NOT EXISTS idx_room_playback_history_created_at
|
|
ON room_playback_history(created_at, room_id, id);
|
|
|
|
CREATE TRIGGER update_room_playback_history_updated_at
|
|
BEFORE UPDATE ON room_playback_history
|
|
FOR EACH ROW
|
|
EXECUTE FUNCTION update_updated_at_column();
|
|
|
|
CREATE TABLE IF NOT EXISTS room_playback_state (
|
|
room_id BIGINT PRIMARY KEY REFERENCES rooms(id) ON DELETE RESTRICT,
|
|
playing_media_id BIGINT NULL,
|
|
playing_playlist_id BIGINT NULL,
|
|
target JSONB NULL,
|
|
current_progress_id BIGINT NULL REFERENCES room_playback_progress(id) ON DELETE SET NULL,
|
|
history_cursor_id BIGINT NULL,
|
|
history_cursor_created_at TIMESTAMPTZ NULL,
|
|
speed DOUBLE PRECISION NOT NULL DEFAULT 1.0,
|
|
is_playing BOOLEAN NOT NULL DEFAULT FALSE,
|
|
playback_generation BIGINT NOT NULL,
|
|
updated_at TIMESTAMPTZ NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
|
version BIGINT NOT NULL DEFAULT 0,
|
|
CONSTRAINT room_playback_state_target_object
|
|
CHECK (target IS NULL OR jsonb_typeof(target) = 'object'),
|
|
CONSTRAINT room_playback_state_generation_non_negative
|
|
CHECK (playback_generation >= 0),
|
|
CONSTRAINT playback_media_same_room_fk
|
|
FOREIGN KEY (playing_media_id, room_id)
|
|
REFERENCES media(id, room_id)
|
|
ON DELETE RESTRICT,
|
|
CONSTRAINT playback_playlist_same_room_fk
|
|
FOREIGN KEY (playing_playlist_id, room_id)
|
|
REFERENCES playlists(id, room_id)
|
|
ON DELETE RESTRICT,
|
|
CONSTRAINT room_playback_state_history_same_room_fk
|
|
FOREIGN KEY (room_id, history_cursor_id, history_cursor_created_at)
|
|
REFERENCES room_playback_history(room_id, id, created_at)
|
|
ON DELETE SET NULL (history_cursor_id, history_cursor_created_at),
|
|
CONSTRAINT room_playback_state_history_cursor_complete
|
|
CHECK (
|
|
(history_cursor_id IS NULL AND history_cursor_created_at IS NULL)
|
|
OR (history_cursor_id IS NOT NULL AND history_cursor_created_at IS NOT NULL)
|
|
)
|
|
);
|
|
|
|
CREATE INDEX IF NOT EXISTS idx_room_playback_state_media_id ON room_playback_state(playing_media_id);
|
|
CREATE INDEX IF NOT EXISTS idx_room_playback_state_playlist_id ON room_playback_state(playing_playlist_id);
|
|
CREATE INDEX IF NOT EXISTS idx_room_playback_state_current_progress_id ON room_playback_state(current_progress_id);
|
|
CREATE INDEX IF NOT EXISTS idx_room_playback_state_history_cursor_id ON room_playback_state(history_cursor_id);
|
|
CREATE INDEX IF NOT EXISTS idx_room_playback_state_updated_at ON room_playback_state(updated_at);
|
|
|
|
CREATE TRIGGER update_room_playback_state_updated_at
|
|
BEFORE UPDATE ON room_playback_state
|
|
FOR EACH ROW
|
|
EXECUTE FUNCTION update_updated_at_column();
|