-- Generated by CompileSchemaScripts.pl from:
-- 20211203-mbs-11312.sql
-- 20220802-mbs-12497.sql
-- 20220927-mbs-12573.sql
-- 20221114-mbs-12704.sql
-- 20230320-mbs-12800.sql
\set ON_ERROR_STOP 1
BEGIN;
SET search_path = musicbrainz, public;
SET LOCAL statement_timeout = 0;
--------------------------------------------------------------------------------
SELECT '20211203-mbs-11312.sql';


DO $$
BEGIN
  PERFORM 1 FROM pg_type
  WHERE typname = 'edit_note_status';

  IF NOT FOUND THEN
    CREATE TYPE edit_note_status AS ENUM ('deleted', 'edited');
  END IF;
END
$$;

CREATE TABLE edit_note_change
(
    id                  SERIAL, -- PK
    status              edit_note_status,
    edit_note           INTEGER NOT NULL, -- references edit_note.id
    change_editor       INTEGER NOT NULL, -- references editor.id
    change_time         TIMESTAMP WITH TIME ZONE DEFAULT NOW(),
    old_note            TEXT NOT NULL,
    new_note            TEXT NOT NULL,
    reason              TEXT NOT NULL DEFAULT ''
);

-- Primary keys

ALTER TABLE edit_note_change ADD CONSTRAINT edit_note_change_pkey PRIMARY KEY (id);

-- Indexes

CREATE INDEX edit_note_change_idx_edit_note ON edit_note_change (edit_note);

--------------------------------------------------------------------------------
SELECT '20220802-mbs-12497.sql';


CREATE TABLE IF NOT EXISTS unreferenced_row_log (
    table_name          VARCHAR NOT NULL, -- PK
    row_id              INTEGER NOT NULL, -- PK
    inserted            TIMESTAMP WITH TIME ZONE DEFAULT NOW()
);

CREATE OR REPLACE FUNCTION dec_ref_count(tbl varchar, row_id integer, val integer) RETURNS void AS $$
DECLARE
    ref_count integer;
BEGIN
    -- decrement ref_count for the old name,
    -- or prepare it for deletion if ref_count would drop to 0
    EXECUTE 'SELECT ref_count FROM ' || tbl || ' WHERE id = ' || row_id || ' FOR UPDATE' INTO ref_count;
    IF ref_count <= val THEN
        EXECUTE 'INSERT INTO unreferenced_row_log (table_name, row_id) VALUES ($1, $2)' USING tbl, row_id;
    END IF;
    EXECUTE 'UPDATE ' || tbl || ' SET ref_count = ref_count - ' || val || ' WHERE id = ' || row_id;
    RETURN;
END;
$$ LANGUAGE 'plpgsql';

CREATE INDEX IF NOT EXISTS unreferenced_row_log_idx_inserted ON unreferenced_row_log USING BRIN (inserted);

--------------------------------------------------------------------------------
SELECT '20220927-mbs-12573.sql';


ALTER TABLE cdtoc DROP COLUMN degraded CASCADE;

--------------------------------------------------------------------------------
SELECT '20221114-mbs-12704.sql';


DROP TRIGGER IF EXISTS a_ins_editor ON editor;

DROP FUNCTION a_ins_editor();

DROP TABLE editor_watch_artist;
DROP TABLE editor_watch_preferences;
DROP TABLE editor_watch_release_group_type;
DROP TABLE editor_watch_release_status;

--------------------------------------------------------------------------------
SELECT '20230320-mbs-12800.sql';


-- Update the release update function to reset dates when status set to/from cancelled
CREATE OR REPLACE FUNCTION a_upd_release() RETURNS trigger AS $$
BEGIN
    IF NEW.artist_credit != OLD.artist_credit THEN
        PERFORM dec_ref_count('artist_credit', OLD.artist_credit, 1);
        PERFORM inc_ref_count('artist_credit', NEW.artist_credit, 1);
    END IF;
    IF (
        NEW.status IS DISTINCT FROM OLD.status AND
        (NEW.status = 6 OR OLD.status = 6)
    ) THEN
        PERFORM set_release_first_release_date(NEW.id);

        -- avoid executing it twice as this will be executed a few lines below if RG changes
        IF NEW.release_group = OLD.release_group THEN
            PERFORM set_release_group_first_release_date(NEW.release_group);
        END IF;

        PERFORM set_releases_recordings_first_release_dates(ARRAY[NEW.id]);
    END IF;
    IF NEW.release_group != OLD.release_group THEN
        -- release group is changed, decrement release_count in the original RG, increment in the new one
        UPDATE release_group_meta SET release_count = release_count - 1 WHERE id = OLD.release_group;
        UPDATE release_group_meta SET release_count = release_count + 1 WHERE id = NEW.release_group;
        PERFORM set_release_group_first_release_date(OLD.release_group);
        PERFORM set_release_group_first_release_date(NEW.release_group);
    END IF;
    IF (
        NEW.status IS DISTINCT FROM OLD.status OR
        NEW.release_group != OLD.release_group OR
        NEW.artist_credit != OLD.artist_credit
    ) THEN
        INSERT INTO artist_release_group_pending_update
        VALUES (NEW.release_group), (OLD.release_group);
    END IF;
    IF (
        NEW.barcode IS DISTINCT FROM OLD.barcode OR
        NEW.name != OLD.name OR
        NEW.artist_credit != OLD.artist_credit
    ) THEN
        INSERT INTO artist_release_pending_update VALUES (OLD.id);
    END IF;
    RETURN NULL;
END;
$$ LANGUAGE 'plpgsql';

-- Update the release dates function to ignore cancelled releases
CREATE OR REPLACE FUNCTION get_release_first_release_date_rows(condition TEXT)
RETURNS SETOF release_first_release_date AS $$
BEGIN
    RETURN QUERY EXECUTE '
        SELECT DISTINCT ON (release) release,
            date_year AS year,
            date_month AS month,
            date_day AS day
        FROM (
            SELECT release, date_year, date_month, date_day FROM release_country
            WHERE (date_year IS NOT NULL OR date_month IS NOT NULL OR date_day IS NOT NULL)
            UNION ALL
            SELECT release, date_year, date_month, date_day FROM release_unknown_country
        ) all_dates
        WHERE ' || condition ||
        ' AND NOT EXISTS (
          SELECT TRUE
            FROM release
           WHERE release.id = all_dates.release
             AND status = 6
        )
        ORDER BY release, year NULLS LAST, month NULLS LAST, day NULLS LAST';
END;
$$ LANGUAGE 'plpgsql' STRICT;

-- Delete rows already in release_first_release_date for cancelled releases
DELETE FROM release_first_release_date
WHERE release IN (
  SELECT id
    FROM release
   WHERE status = 6
);

-- Rerun set_release_group_first_release_date for release groups with cancelled releases
SELECT set_release_group_first_release_date(release_group) FROM (
  SELECT DISTINCT release_group
    FROM release
   WHERE status = 6
) rgs_with_cancelled_releases;

-- Rerun set_releases_recordings_first_release_dates for cancelled releases
SELECT set_releases_recordings_first_release_dates(array_agg(id))
  FROM release
 WHERE status = 6;

COMMIT;
