Add GitLab::Database::MigrationHelpers to Customers Portal

### Problem
In the GitLab codebase, it is recommended to use [database helpers](https://gitlab.com/gitlab-org/gitlab/blob/44d881b91a0ed366a7aec019481840da001cbf5c/lib/gitlab/database/migration_helpers.rb) like `add_column_with_defaults`.  In the Customers portal code, we have some database helpers [defined here](https://gitlab.com/gitlab-org/customers-gitlab-com/blob/d08fb068c42c73a857947302c26863020db74edc/lib/database/migrations_helper.rb) but it's not the full set of helpers like GitLab.

### Proposal
The ideal solution would be to move these database helpers in GitLab to a library or gem so it can be easily shared and updated in other applications like Customers.  The easier but less elegant solution could be to simply copy the library over to Customers.

### Result
Access to more migration helpers making migrations safer and follow standards recommended in the development docs.

-------

@vshumilo added:

**First...**

There had to make the choice between copying `Gitlab::Database::MigrationHelpers` and its tests
to the customers app or creating a gem.
After a short analysis it was decided to move with the easiest (less time consuming) approach
of copying the file because:
- It solved the immediate need to have the migration helpers available
- It was less time consuming as it required much less process (we had a time budget in mind)
- Creating the gem then required Gitlab to be updated to reference and use it as part of the same
issue otherwise those logics will diverge (again, we had a time budget in mind)
- Gitlab migration helpers are quite tangled with other modules, lasses and helpers which added challenge to extract all that code
- :keycap_asterisk: There is already at attempt to [move the helpers into a gem](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/27307/diffs) in progress so feels like doubling a lot of effors 

------------------------------------------------------------------------------------------
**Then...**

The original intention of moving the entire `Gitlab::Database::MigrationHelpers`
resulted to be an effort bigger than the budget in time and the needs we present at the moment.
- A lot of the helpers at the `Gitlab` end are very specific. Ex: `backfill_iids`
- A lot of the helpers at the `Gitlab` end rely on other modules that need to be moved along if we want to move the helpers

As a result [a half way migration of the helpers into costumers](https://gitlab.com/gitlab-org/customers-gitlab-com/-/merge_requests/1433) was resulting in ~4000 new lines of code and a lot of work pending related to fixing the specs by copying the missing dependencies, updating references (some other magnitud of thousands lines). 

This "size" overflows the current appetite for this change.

------------------------------------------------------------------------------------------
**Now...**

As a result the agreement was to pick 10 methods and move them along as a first iteration.

:exclamation: Try to make sure the methods we pick are methods we might end up needing.

This is a list of the current methods on the Gitlab end and highlighten are
those that count with a counterpart on our end created by copying and adjusting the
original method's logic:


- def add_timestamps_with_timezone(table_name, options = {})
- def remove_timestamps(table_name, options = {})
- **def add_concurrent_index(table_name, column_name, options = {})**
- **def remove_concurrent_index(table_name, column_name, options = {})**
- def remove_concurrent_index_by_name(table_name, index_name, options = {})
- **def add_concurrent_foreign_key(source, target, column:, on_delete: :cascade, name: nil, validate: true)**
- def validate_foreign_key(source, column, name: nil)
- **def foreign_key_exists?(source, target = nil, options)**
- **def concurrent_foreign_key_name(table, column, prefix: 'fk_')**
- **def disable_statement_timeout**
- def with_lock_retries(**args, &block)
- def true_value
- def false_value
- def update_column_in_batches(table, column, value, batch_size: nil, batch_column_name: :id)
- def add_column_with_default(table, column, type, default:, limit: nil, allow_null: false)
- def rename_column_concurrently(table, old, new, type: nil, batch_column_name: :id)
- def undo_rename_column_concurrently(table, old, new)
- def install_rename_triggers(table, old_column, new_column)
- def change_column_type_concurrently(table, column, new_type)
- def cleanup_concurrent_column_type_change(table, column)
- def cleanup_concurrent_column_rename(table, old, new)
- def undo_cleanup_concurrent_column_rename(table, old, new, type: nil, batch_column_name: :id)
- def change_column_type_using_background_migration(
- def rename_column_using_background_migration(
- def perform_background_migration_inline?
- def install_rename_triggers_for_postgresql(trigger, table, old, new)
- def remove_rename_triggers_for_postgresql(table, trigger)
- def rename_trigger_name(table, old, new)
- def indexes_for(table, column)
- def foreign_keys_for(table, column)
- def copy_indexes(table, old, new)
- def copy_foreign_keys(table, old, new)
- def column_for(table, name)
- def replace_sql(column, pattern, replacement)
- def remove_foreign_key_if_exists(*args)
- **def remove_foreign_key_without_error(*args)**
- def sidekiq_queue_migrate(queue_from, to:)
- def sidekiq_queue_length(queue_name)
- def check_trigger_permissions!(table)
- def bulk_queue_background_migration_jobs_by_range(model_class, job_class_name, batch_size: BACKGROUND_MIGRATION_BATCH_SIZE)
- def queue_background_migration_jobs_by_range_at_intervals(model_class, job_class_name, delay_interval, batch_size: BACKGROUND_MIGRATION_BATCH_SIZE, other_job_arguments: [], initial_delay: 0)
- def index_exists_by_name?(table, index)
- def postgres_exists_by_name?(table, name)
- def create_or_update_plan_limit(limit_name, plan_name, limit_value)
- def backfill_iids(table)
- def migrate_async(*args)
- def migrate_in(*args)
- def bulk_migrate_in(*args)
- def bulk_migrate_async(*args)
- def check_constraint_name(table, column, type)
- def check_constraint_exists?(table, constraint_name)
- def add_check_constraint(table, check, constraint_name, validate: true)
- def validate_check_constraint(table, constraint_name)
- def remove_check_constraint(table, constraint_name)
- def add_text_limit(table, column, limit, constraint_name: nil, validate: true)
- def validate_text_limit(table, column, constraint_name: nil)
- def remove_text_limit(table, column, constraint_name: nil)
- def check_text_limit_exists?(table, column, constraint_name: nil)
- def add_not_null_constraint(table, column, constraint_name: nil, validate: true)
- def validate_not_null_constraint(table, column, constraint_name: nil)
- def remove_not_null_constraint(table, column, constraint_name: nil)
- def check_not_null_constraint_exists?(table, column, constraint_name: nil)
- def statement_timeout_disabled?
- def column_is_nullable?(table, column)
- def text_limit_name(table, column, name: nil)
- def not_null_constraint_name(table, column, name: nil)
- def missing_schema_object_message(table, type, name)
- def tables_match?(target_table, foreign_key_table)
- def options_match?(foreign_key_options, options)
- def on_delete_statement(on_delete)
- def create_column_from(table, old, new, type: nil, batch_column_name: :id)
- def validate_timestamp_column_name!(column_name)
- def validate_not_in_transaction!(method_name, modifier = nil)
- def with_migration_context(&block)

------------------------------------------------------------------------------------------

Out of the 74 methods availabe in Gitlab we have moved 7 and adjusted those to our current needs.

I will take on the quest to action on 10 more.

Resulting:

**Existing Methods:**

- def add_concurrent_foreign_key(source, target, column:, on_delete: :cascade)
- def foreign_key_exists?(source, target = nil, column: nil)
- def concurrent_foreign_key_name(table, column)
- def disable_statement_timeout
- def remove_foreign_key_without_error(*args)
- def add_concurrent_index(table_name, column_name, options = {})
- def remove_concurrent_index(table_name, column_name, options = {})

#### **New Additions:**
- :white_check_mark: def add_timestamps_with_timezone
- :white_check_mark: def remove_timestamps
- :x: def index_exists_by_name? **DEPRECATED** :lion_face: 
- :white_check_mark: def remove_concurrent_index_by_name
- :white_check_mark: def true_value
- :white_check_mark: def false_value
- :white_check_mark: def update_column_in_batches
- :x: def add_column_with_default **DEPRECATED** :whale: 
- :white_check_mark: def add_column_with_default
- :white_check_mark: def validate_timestamp_column_name

Disclaimer: Some methods might require to move some small helper methods along

:warning: Important: Moved in a MR per method, or very closed couple of methods to facilitate review and in aims of iteration

### References
:lion_face: `remove_concurrent_index_by_name` within `Gitlab::Database::MigrationHelpers` is using a [custom implementation](https://gitlab.com/gitlab-org/gitlab/-/blob/master/lib/gitlab/database/migration_helpers.rb#L1084) to check if an index exists by name for the provided table.
It is and old implementation and was based on the lack of Rails support to check this AND had a note to be updated as soon as the app was upgraded to Rails > 5.1.7 which introduces [index_name_exists?](https://apidock.com/rails/v5.2.3/ActiveRecord/ConnectionAdapters/SchemaStatements/index_name_exists%3F)

Created a [tech-debt issue](https://gitlab.com/gitlab-org/gitlab/-/issues/219285) in the Gitlab context as a reminder so this can be updated on that end too.


:whale: Since PostgreSQL 11, adding columns with a default does not lead to a table rewrite anymore. As such, this method is not needed anymore and the default `add_column` helper should be used.

Story points: 2.0