module PolymorphicConstraints::ConnectionAdapters::Mysql2Adapter

Public Instance Methods

add_polymorphic_constraints(relation, associated_table, options = {}) click to toggle source
# File lib/polymorphic_constraints/connection_adapters/mysql2_adapter.rb, line 15
def add_polymorphic_constraints(relation, associated_table, options = {})
  polymorphic_models = options.fetch(:polymorphic_models) { get_polymorphic_models(relation) }

  statements = constraints_remove_statements(relation)
  statements << generate_insert_constraints(relation, associated_table, polymorphic_models)
  statements << generate_update_constraints(relation, associated_table, polymorphic_models)

  polymorphic_models.each do |polymorphic_model|
    statements << generate_delete_constraints(relation, associated_table, polymorphic_model)
  end

  statements.each { |statement| execute statement }
end
remove_polymorphic_constraints(relation) click to toggle source
# File lib/polymorphic_constraints/connection_adapters/mysql2_adapter.rb, line 29
def remove_polymorphic_constraints(relation)
  statements = constraints_remove_statements(relation)
  statements.each { |statement| execute statement }
end
supports_polymorphic_constraints?() click to toggle source
# File lib/polymorphic_constraints/connection_adapters/mysql2_adapter.rb, line 11
def supports_polymorphic_constraints?
  true
end
update_polymorphic_constraints(relation, associated_table, options = {})

Private Instance Methods

common_upsert_sql(relation, polymorphic_models) click to toggle source
# File lib/polymorphic_constraints/connection_adapters/mysql2_adapter.rb, line 120
      def common_upsert_sql(relation, polymorphic_models)
        polymorphic_models = polymorphic_models.map(&:to_s)

        sql = <<-SQL
          FOR EACH ROW
          BEGIN
            IF
        SQL

        polymorphic_models.each do |polymorphic_model|
          sql << <<-SQL
            NEW.#{relation}_type != '#{polymorphic_model.classify}'
          SQL

          unless polymorphic_model == polymorphic_models.last
            sql << <<-SQL
              AND
            SQL
          end
        end

        sql << <<-SQL
          THEN SIGNAL SQLSTATE '45000'
            SET MESSAGE_TEXT = 'Polymorphic record not found. No model by that name.';
        SQL


        polymorphic_models.each do |polymorphic_model|
          sql << <<-SQL
            ELSEIF NEW.#{relation}_type = '#{polymorphic_model.classify}' AND
                   NOT EXISTS (SELECT id FROM #{polymorphic_model.classify.constantize.table_name}
                               WHERE id = NEW.#{relation}_id) THEN

              SIGNAL SQLSTATE '45000'
                SET MESSAGE_TEXT = 'Polymorphic record not found. No #{polymorphic_model.classify} with that id.';
          SQL
        end

        sql << <<-SQL
            END IF;
          END;
        SQL
      end
constraints_remove_statements(relation) click to toggle source
# File lib/polymorphic_constraints/connection_adapters/mysql2_adapter.rb, line 38
def constraints_remove_statements(relation)
  polymorphic_models = get_polymorphic_models(relation)

  statements = []
  statements << drop_trigger(relation, 'insert')
  statements << drop_trigger(relation, 'update')

  polymorphic_models.each do |polymorphic_model|
    statements << drop_delete_trigger(relation, polymorphic_model)
  end

  statements
end
drop_delete_trigger(relation, polymorphic_model) click to toggle source
# File lib/polymorphic_constraints/connection_adapters/mysql2_adapter.rb, line 60
      def drop_delete_trigger(relation, polymorphic_model)
        table_name = polymorphic_model.to_s.classify.constantize.table_name

        sql = <<-SQL
          DROP TRIGGER IF EXISTS check_#{relation}_#{table_name}_delete_integrity;
        SQL

        strip_non_essential_spaces(sql)
      end
drop_trigger(relation, action) click to toggle source
# File lib/polymorphic_constraints/connection_adapters/mysql2_adapter.rb, line 52
      def drop_trigger(relation, action)
        sql = <<-SQL
          DROP TRIGGER IF EXISTS check_#{relation}_#{action}_integrity;
        SQL

        strip_non_essential_spaces(sql)
      end
generate_delete_constraints(relation, associated_table, polymorphic_model) click to toggle source
# File lib/polymorphic_constraints/connection_adapters/mysql2_adapter.rb, line 96
      def generate_delete_constraints(relation, associated_table, polymorphic_model)
        associated_table = associated_table.to_s
        polymorphic_model = polymorphic_model.to_s

        sql = <<-SQL
          CREATE TRIGGER check_#{relation}_#{polymorphic_model.classify.constantize.table_name}_delete_integrity
            BEFORE DELETE ON #{polymorphic_model.classify.constantize.table_name}
            FOR EACH ROW
            BEGIN
              IF EXISTS (SELECT id FROM #{associated_table}
                         WHERE #{relation}_type = '#{polymorphic_model.classify}'
                         AND #{relation}_id = OLD.id) THEN
                SIGNAL SQLSTATE '45000'
                  SET MESSAGE_TEXT = 'Polymorphic reference exists.
                                      There are records in the #{associated_table} table that refer to the
                                      table #{polymorphic_model.classify.constantize.table_name}.
                                      You must delete those records of table #{associated_table} first.';
              END IF;
            END;
        SQL

        strip_non_essential_spaces(sql)
      end
generate_insert_constraints(relation, associated_table, polymorphic_models) click to toggle source
# File lib/polymorphic_constraints/connection_adapters/mysql2_adapter.rb, line 70
      def generate_insert_constraints(relation, associated_table, polymorphic_models)
        associated_table = associated_table.to_s

        sql = <<-SQL
          CREATE TRIGGER check_#{relation}_insert_integrity
            BEFORE INSERT ON #{associated_table}
        SQL

        sql << common_upsert_sql(relation, polymorphic_models)

        strip_non_essential_spaces(sql)
      end
generate_update_constraints(relation, associated_table, polymorphic_models) click to toggle source
# File lib/polymorphic_constraints/connection_adapters/mysql2_adapter.rb, line 83
      def generate_update_constraints(relation, associated_table, polymorphic_models)
        associated_table = associated_table.to_s

        sql = <<-SQL
          CREATE TRIGGER check_#{relation}_update_integrity
            BEFORE UPDATE ON #{associated_table}
        SQL

        sql << common_upsert_sql(relation, polymorphic_models)

        strip_non_essential_spaces(sql)
      end