class PGTrunk::Operations::ForeignKeys::AddForeignKey

@private

Public Instance Methods

invert() click to toggle source
# File lib/pg_trunk/operations/foreign_keys/add_foreign_key.rb, line 143
def invert
  irreversible!("if_not_exists: true") if if_not_exists
  DropForeignKey.new(**to_h)
end
to_sql(_version) click to toggle source
# File lib/pg_trunk/operations/foreign_keys/add_foreign_key.rb, line 134
def to_sql(_version)
  # Notice that in Rails the key `if_not_exists: true` means
  # the constraint should not be created if the table has ANY other
  # foreign key with the same reference <table>.
  return if if_not_exists && added?

  [add_constraint, create_comment, register_fk].join(" ")
end

Private Instance Methods

add_constraint() click to toggle source
# File lib/pg_trunk/operations/foreign_keys/add_foreign_key.rb, line 150
def add_constraint
  sql = "ALTER TABLE #{table.to_sql} ADD CONSTRAINT #{name.lean.inspect}"
  sql << " FOREIGN KEY (#{columns.map(&:inspect).join(', ')})"
  sql << " REFERENCES #{reference.to_sql} (#{primary_key.map(&:inspect).join(', ')})"
  sql << " MATCH #{match.to_s.upcase}" if match&.!= :simple
  sql << " ON DELETE #{sql_action(on_delete)}"
  sql << " ON UPDATE #{sql_action(on_update)}"
  sql << " NOT VALID" unless validate
  sql << ";"
end
create_comment() click to toggle source
# File lib/pg_trunk/operations/foreign_keys/add_foreign_key.rb, line 161
    def create_comment
      return if comment.blank?

      <<~SQL
        COMMENT ON CONSTRAINT #{name.lean.inspect} ON #{table.to_sql}
        IS $comment$#{comment}$comment$;
      SQL
    end
register_fk() click to toggle source

Rely on the fact the (schema.table, schema.name) is unique

# File lib/pg_trunk/operations/foreign_keys/add_foreign_key.rb, line 171
    def register_fk
      <<~SQL
        INSERT INTO pg_trunk (oid, classid)
          SELECT c.oid, 'pg_constraint'::regclass
          FROM pg_constraint c JOIN pg_class r ON r.oid = c.conrelid
          WHERE r.relname = #{table.quoted}
            AND r.relnamespace = #{table.namespace}
            AND c.conname = #{name.quoted}
        ON CONFLICT DO NOTHING;
      SQL
    end