module PGTrunk::Operations::Sequences

@private Namespace for operations with sequences

@!parse

class ActiveRecord::Migration
  # Modify a sequence
  #
  # @param [#to_s] name (nil) The qualified name of the sequence.
  # @option options [Boolean] :if_exists (false) Suppress the error when the sequence is absent.
  # @yield [s] the block with the sequence's definition.
  # @yieldparam Object receiver of methods specifying the sequence.
  # @return [void]
  #
  # The operation enables to alter a sequence without recreating it.
  # PostgreSQL allows any setting to be modified. The comment can be
  # changed as well.
  #
  # ```ruby
  # change_sequence "my_schema.global_id" do |s|
  #   s.owned_by "", "", from: %w[users gid]
  #   s.type "smallint", from: "integer"
  #   s.iterate_by 1, from: 2
  #   s.min_value 1, from: 0
  #   s.max_value 2000, from: 1999
  #   s.start_with 2, from: 1
  #   s.cache 1, from: 10
  #   s.cycle false
  #   s.comment "Identifier", from: "Global identifier"
  # end
  # ```
  #
  # As in the snippet above, to make the change invertible,
  # you have to define from option for every changed attribute,
  # except for the boolean `cycle`.
  #
  # With the `if_exists: true` option, the operation won't raise
  # when the sequence is absent.
  #
  # ```ruby
  # change_sequence "my_schema.global_id", if_exists: true do |s|
  #   s.type "smallint"
  #   s.iterate_by 1
  #   s.min_value 1
  #   s.max_value 2000
  #   s.start_with 2
  #   s.cache 1
  #   s.cycle false
  #   s.comment "Identifier"
  # end
  # ```
  #
  # This option makes a migration irreversible due to uncertainty
  # of the previous state of the database. That's why in the last
  # example no `from:` option was added (they are useless).
  def change_sequence(name, **options, &block); end
end

@!parse

class ActiveRecord::Migration
  # Create a sequence
  #
  # @param [#to_s] name (nil) The qualified name of the sequence
  # @option options [#to_s] :as ("bigint") The type of the sequence's value
  #   Supported values: "bigint" (or "int8", default), "integer" (or "int4"), "smallint" ("int2").
  # @option options [Boolean] :if_not_exists (false)
  #   Suppress the error when the sequence already existed.
  # @option options [Integer] :increment_by (1) Non-zero step of the sequence (either positive or negative).
  # @option options [Integer] :min_value (nil) Minimum value of the sequence.
  # @option options [Integer] :max_value (nil) Maximum value of the sequence.
  # @option options [Integer] :start_with (nil) The first value of the sequence.
  # @option options [Integer] :cache (1) The number of values to be generated and cached.
  # @option options [Boolean] :cycle (false) If the sequence should be reset to start
  #   after its value reaches min/max value.
  # @option options [#to_s] :comment (nil) The comment describing the sequence.
  # @yield [s] the block with the sequence's definition
  # @yieldparam Object receiver of methods specifying the sequence
  # @return [void]
  #
  # The sequence can be created by its qualified name only
  #
  # ```ruby
  # create_sequence "my_schema.global_id"
  # ```
  #
  # we also support all PostgreSQL settings for the sequence:
  #
  # ```ruby
  # create_sequence "my_schema.global_id", as: "integer" do |s|
  #   s.iterate_by 2
  #   s.min_value 0
  #   s.max_value 1999
  #   s.start_with 1
  #   s.cache 10
  #   s.cycle true
  #   s.comment "Global identifier"
  # end
  # ```
  #
  # Using a block method `s.owned_by` you can bind the sequence to
  # some table's column. This means the sequence is dependent from
  # the column and will be dropped along with it. Notice that the
  # name of the table is NOT qualified because the table MUST belong
  # to the same schema as the sequence itself.
  #
  # ```ruby
  # create_table "users" do |t|
  #   t.bigint :gid
  # end
  #
  # create_sequence "my_schema.global_id" do |s|
  #   s.owned_by "users", "gid"
  # end
  # ```
  #
  # With the `if_not_exists: true` option the operation wouldn't raise
  # an exception in case the sequence has been already created.
  #
  # ```ruby
  # create_sequence "my_schema.global_id", if_not_exists: true
  # ```
  #
  # This option makes the migration irreversible due to uncertainty
  # of the previous state of the database.
  def create_sequence(name, **options, &block); end
end

@!parse

class ActiveRecord::Migration
  # Drop a sequence
  #
  # @param [#to_s] name (nil) The qualified name of the sequence
  # @option options [#to_s] :as ("bigint") The type of the sequence's value
  #   Supported values: "bigint" (or "int8", default), "integer" (or "int4"), "smallint" ("int2").
  # @option options [Boolean] :if_exists (false) Suppress the error when the sequence is absent.
  # @option options [Symbol] :force (:restrict) Define how to process dependent objects
  #   Supported values: :restrict (default), :cascade.
  # @option options [Integer] :increment_by (1) Non-zero step of the sequence (either positive or negative).
  # @option options [Integer] :min_value (nil) Minimum value of the sequence.
  # @option options [Integer] :max_value (nil) Maximum value of the sequence.
  # @option options [Integer] :start_with (nil) The first value of the sequence.
  # @option options [Integer] :cache (1) The number of values to be generated and cached.
  # @option options [Boolean] :cycle (false) If the sequence should be reset to start
  #   after its value reaches min/max value.
  # @option options [#to_s] :comment (nil) The comment describing the sequence.
  # @yield [s] the block with the sequence's definition
  # @yieldparam Object receiver of methods specifying the sequence
  # @return [void]
  #
  # The sequence can be dropped by its qualified name only
  #
  # ```ruby
  # drop_sequence "global_number"
  # ```
  #
  # For inversion provide options for the `create_sequence` operation as well:
  #
  # ```ruby
  # drop_sequence "global_id", as: "int2" do |s|
  #   s.iterate_by 2
  #   s.min_value 0
  #   s.max_value 1999
  #   s.start_with 1
  #   s.cache 10
  #   s.cycle true
  #   s.comment "Global identifier"
  # end
  # ```
  #
  # The operation can be called with `if_exists` option to suppress
  # the exception in case when the sequence is absent:
  #
  # ```ruby
  # drop_sequence "global_number", if_exists: true
  # ```
  #
  # With the `force: :cascade` option the operation would remove
  # all the objects that use the sequence.
  #
  # ```ruby
  # drop_sequence "global_number", force: :cascade
  # ```
  #
  # In both cases the operation becomes irreversible due to
  # uncertainty of the previous state of the database.
  def drop_sequence(name, **options, &block); end
end

@!parse

class ActiveRecord::Migration
  # Rename a sequence
  #
  # @param [#to_s] name (nil) The current qualified name of the sequence
  # @option options [#to_s] :to (nil) The new qualified name for the sequence
  # @option options [Boolean] :if_exists (false) Suppress the error when the sequence is absent.
  # @return [void]
  #
  # The operation allows to change both name and schema
  #
  # ```ruby
  # rename_sequence "global_num", to: "sequences.global_number"
  # ```
  #
  # With the `if_exists: true` option the operation wouldn't raise
  # an exception in case the sequence hasn't been created yet.
  #
  # ```ruby
  # create_sequence "my_schema.global_id", if_exists: true
  # ```
  #
  # This option makes the migration irreversible due to uncertainty
  # of the previous state of the database.
  def rename_sequence(name, **options, &block); end
end