# frozen_string_literal: true

class <%= @migration_class_name %> < ActiveRecord::Migration<%= ActiveRecord::VERSION::MAJOR < 5 ? '' : '[5.0]' %>
  def up
    execute <<-SQL
    CREATE OR REPLACE FUNCTION metka_refresh_<%= view_name %>_materialized_view() RETURNS trigger LANGUAGE plpgsql AS $$
      BEGIN
        IF TG_OP = 'INSERT' AND NEW.<%= source_column_name %> IS NOT NULL THEN
          REFRESH MATERIALIZED VIEW CONCURRENTLY <%= view_name %>;
        END IF;

        IF TG_OP = 'UPDATE' AND OLD.<%= source_column_name %> != NEW.<%= source_column_name %> THEN
          REFRESH MATERIALIZED VIEW CONCURRENTLY <%= view_name %>;
        END IF;

        IF TG_OP = 'DELETE' AND OLD.<%= source_column_name %> IS NOT NULL THEN
          REFRESH MATERIALIZED VIEW CONCURRENTLY <%= view_name %>;
        END IF;
        RETURN NEW;
      END $$;

    DROP MATERIALIZED VIEW IF EXISTS <%= view_name %>;
    CREATE MATERIALIZED VIEW <%= view_name %> AS
      SELECT UNNEST
        ( <%= source_column_name %> ) AS <%= source_column_name.singularize %>_name,
        COUNT ( * ) AS taggings_count
      FROM
        <%= source_table_name %>
      GROUP BY
        <%= source_column_name.singularize %>_name;

    CREATE UNIQUE INDEX idx_<%= source_table_name %>_<%= source_column_name %> ON <%= view_name %>(<%= source_column_name.singularize %>_name);

    CREATE TRIGGER metka_on_<%= source_table_name %>
    AFTER UPDATE OR INSERT OR DELETE ON <%= source_table_name %> FOR EACH ROW
    EXECUTE PROCEDURE metka_refresh_<%= view_name %>_materialized_view();
    SQL
  end

  def down
    execute <<-SQL
      DROP TRIGGER IF EXISTS metka_on_<%= source_table_name %> ON <%= source_table_name %>;
      DROP FUNCTION IF EXISTS metka_refresh_<%= view_name %>_materialized_view;
      DROP MATERIALIZED VIEW IF EXISTS <%= view_name %>;
    SQL
  end
end