module PGTrunk::Operations::CheckConstraints

@private Definitions for check constraints

@!parse

class ActiveRecord::Migration
  # Add a check constraint to the table
  #
  # @param [#to_s] table (nil) The qualified name of the table
  # @param [#to_s] expression (nil) The SQL expression
  # @option options [#to_s] :name (nil) The optional name of the constraint
  # @option options [Boolean] :inherit (true) If the constraint should be inherited by subtables
  # @option options [#to_s] :comment (nil) The comment describing the constraint
  # @yield [c] the block with the constraint's definition
  # @yieldparam Object receiver of methods specifying the constraint
  # @return [void]
  #
  # The name of the new constraint can be set explicitly
  #
  # ```ruby
  # add_check_constraint :users, "length(phone) > 10",
  #                      name: "phone_is_long_enough",
  #                      inherit: false,
  #                      comment: "Phone is 10+ chars long"
  # ```
  #
  # The name can also be skipped (it will be generated by default):
  #
  # ```ruby
  # add_check_constraint :users, "length(phone) > 1"
  # ```
  #
  # The block syntax can be used for any argument as usual:
  #
  # ```ruby
  # add_check_constraint do |c|
  #   c.table "users"
  #   c.expression "length(phone) > 10"
  #   c.name "phone_is_long_enough"
  #   c.inherit false
  #   c.comment "Phone is 10+ chars long"
  # end
  # ```
  #
  # The operation is always reversible.
  def add_check_constraint(table, expression = nil, **options, &block); end
end

@!parse

class ActiveRecord::Migration
  # Remove a check constraint from the table
  #
  # @param [#to_s] table (nil) The qualified name of the table
  # @param [#to_s] expression (nil) The SQL expression
  # @option options [Boolean] :if_exists (false) Suppress the error when the constraint is absent
  # @option options [#to_s] :name (nil) The optional name of the constraint
  # @option options [Boolean] :inherit (true) If the constraint should be inherited by subtables
  # @option options [#to_s] :comment (nil) The comment describing the constraint
  # @yield [c] the block with the constraint's definition
  # @yieldparam Object receiver of methods specifying the constraint
  # @return [void]
  #
  # Definition for the `drop_check_constraint` operation
  #
  # The constraint can be identified by the table and explicit name
  #
  # ```ruby
  # drop_check_constraint :users, name: "phone_is_long_enough"
  # ```
  #
  # Alternatively the name can be got from the expression.
  # Be careful! the expression must have exactly the same form
  # as stored in the database:
  #
  # ```ruby
  # drop_check_constraint :users, "length((phone::text) > 10)"
  # ```
  #
  # To made operation reversible the expression must be provided:
  #
  # ```ruby
  # drop_check_constraint "users" do |c|
  #   c.expression "length((phone::text) > 10)"
  #   c.inherit false
  #   c.comment "The phone is 10+ chars long"
  # end
  # ```
  #
  # The operation can be called with `if_exists` option.
  #
  # ```ruby
  # drop_check_constraint :users,
  #                       name: "phone_is_long_enough",
  #                       if_exists: true
  # ```
  #
  # In this case the operation is always irreversible due to
  # uncertainty of the previous state of the database.
  def drop_check_constraint(table, expression = nil, **options, &block); end
end

@!parse

class ActiveRecord::Migration
  # Rename a check constraint
  #
  # @param [#to_s] table (nil) The qualified name of the table
  # @param [#to_s] expression (nil) The SQL expression
  # @option options [#to_s] :name (nil) The current name of the constraint
  # @option options [#to_s] :to (nil) The new name for the constraint
  # @yield [c] the block with the constraint's definition
  # @yieldparam Object receiver of methods specifying the constraint
  # @return [void]
  #
  # A constraint can be identified by the table and explicit name
  #
  # ```ruby
  # rename_check_constraint :users,
  #                         name: "phone_is_long_enough",
  #                         to: "phones.long_enough"
  # ```
  #
  # Alternatively the name can be got from the expression.
  # Be careful! the expression must have exactly the same form
  # as stored in the database:
  #
  # ```ruby
  # rename_check_constraint :users, "length((phone::text) > 10)",
  #                         to: "long_enough"
  # ```
  #
  # The name can be reset to auto-generated when
  # the `:to` option is missed or blank:
  #
  # ```ruby
  # rename_check_constraint :users, "phone_is_long_enough"
  # ```
  #
  # The operation is always reversible.
  def rename_check_constraint(table, expression = nil, **options, &block); end
end

@!parse

class ActiveRecord::Migration
  # Validate an invalid check constraint
  #
  # @param [#to_s] table (nil) The qualified name of the table
  # @param [#to_s] expression (nil) The SQL expression
  # @option options [#to_s] :name (nil) The optional name of the constraint
  # @yield [c] the block with the constraint's definition
  # @yieldparam Object receiver of methods specifying the constraint
  # @return [void]
  #
  # The invalid constraint can be identified by table and explicit name:
  #
  # ```ruby
  # validate_check_constraint :users, name: "phone_is_long_enough"
  # ```
  #
  # Alternatively it can be specified by expression. In this case
  # you must ensure the expression has the same form as it is stored
  # in the database (after parsing the source).
  #
  # ```ruby
  # validate_check_constraint :users, "length((phone::text) > 10)"
  # ```
  #
  # Notice that it is invertible but the inverted operation does nothing.
  def validate_check_constraint(table, expression = nil, **options, &block); end
end