# frozen_string_literal: true

# Create a PL/pgSQL function and trigger it on records update.
# This function will update the Project::search_vector according to the saved project
class UpdateSearchVectorOfProjects < ActiveRecord::Migration[5.2]
  # PostgreSQL only
  def up
    execute <<-SQL
      CREATE OR REPLACE FUNCTION fill_search_vector_for_project() RETURNS trigger LANGUAGE plpgsql AS $$
      declare
        step_title record;
        step_description record;

      begin
        select title into step_title from project_steps where project_id = new.id;
        select string_agg(description, ' ') as content into step_description from project_steps where project_id = new.id;

        new.search_vector :=
          setweight(to_tsvector('pg_catalog.#{Rails.application.secrets.postgresql_language_analyzer}', unaccent(coalesce(new.name, ''))), 'A') ||
          setweight(to_tsvector('pg_catalog.#{Rails.application.secrets.postgresql_language_analyzer}', unaccent(coalesce(new.tags, ''))), 'B') ||
          setweight(to_tsvector('pg_catalog.#{Rails.application.secrets.postgresql_language_analyzer}', unaccent(coalesce(new.description, ''))), 'D') ||
          setweight(to_tsvector('pg_catalog.#{Rails.application.secrets.postgresql_language_analyzer}', unaccent(coalesce(step_title.title, ''))), 'C') ||
          setweight(to_tsvector('pg_catalog.#{Rails.application.secrets.postgresql_language_analyzer}', unaccent(coalesce(step_description.content, ''))), 'D');

        return new;
      end
      $$;
    SQL

    execute <<-SQL
      CREATE TRIGGER projects_search_content_trigger BEFORE INSERT OR UPDATE
        ON projects FOR EACH ROW EXECUTE PROCEDURE fill_search_vector_for_project();
    SQL

    Project.find_each(&:touch)
  end

  def down
    execute <<-SQL
      DROP TRIGGER projects_search_content_trigger ON projects;
      DROP FUNCTION fill_search_vector_for_project();
    SQL
  end
end