Module: Gitlab::Database::SchemaHelpers
- Included in:
- MigrationHelpers::LooseForeignKeyHelpers, MigrationHelpers::Swapping, Migrations::Observers::QueryStatistics, PartitioningMigrationHelpers::ForeignKeyHelpers, PartitioningMigrationHelpers::IndexHelpers, PartitioningMigrationHelpers::TableManagementHelpers, PartitioningMigrationHelpers::UniquenessHelpers, Triggers::AssignDesiredShardingKey
- Defined in:
- lib/gitlab/database/schema_helpers.rb
Instance Method Summary collapse
- #assert_not_in_transaction_block(scope:) ⇒ Object
- #create_comment(type, name, text) ⇒ Object
- #create_trigger(table_name, name, function_name, fires:) ⇒ Object
- #create_trigger_function(name, replace: true) ⇒ Object
- #drop_function(name, if_exists: true) ⇒ Object
- #drop_trigger(table_name, name, if_exists: true) ⇒ Object
- #find_all_id_columns_sql ⇒ Object
- #function_exists?(name) ⇒ Boolean
- #object_name(table, type) ⇒ Object
- #reset_all_trigger_functions(table_name) ⇒ Object
- #reset_trigger_function(function_name) ⇒ Object
- #tmp_table_name(base) ⇒ Object
- #trigger_exists?(table_name, name, schema = nil) ⇒ Boolean
Instance Method Details
#assert_not_in_transaction_block(scope:) ⇒ Object
88 89 90 91 92 93 94 |
# File 'lib/gitlab/database/schema_helpers.rb', line 88 def assert_not_in_transaction_block(scope:) return unless transaction_open? raise "#{scope} operations can not be run inside a transaction block, " \ "you can disable transaction blocks by calling disable_ddl_transaction! " \ "in the body of your migration class" end |
#create_comment(type, name, text) ⇒ Object
71 72 73 |
# File 'lib/gitlab/database/schema_helpers.rb', line 71 def create_comment(type, name, text) execute("COMMENT ON #{type} #{name} IS '#{text}'") end |
#create_trigger(table_name, name, function_name, fires:) ⇒ Object
35 36 37 38 39 40 41 42 43 |
# File 'lib/gitlab/database/schema_helpers.rb', line 35 def create_trigger(table_name, name, function_name, fires:) execute(<<~SQL) CREATE TRIGGER #{name} #{fires} ON #{table_name} FOR EACH ROW #{yield if block_given?} EXECUTE FUNCTION #{function_name}() SQL end |
#create_trigger_function(name, replace: true) ⇒ Object
6 7 8 9 10 11 12 13 14 15 16 17 |
# File 'lib/gitlab/database/schema_helpers.rb', line 6 def create_trigger_function(name, replace: true) replace_clause = optional_clause(replace, "OR REPLACE") execute(<<~SQL) CREATE #{replace_clause} FUNCTION #{name}() RETURNS TRIGGER AS $$ BEGIN #{yield} END $$ LANGUAGE PLPGSQL SQL end |
#drop_function(name, if_exists: true) ⇒ Object
61 62 63 64 |
# File 'lib/gitlab/database/schema_helpers.rb', line 61 def drop_function(name, if_exists: true) exists_clause = optional_clause(if_exists, "IF EXISTS") execute("DROP FUNCTION #{exists_clause} #{name}()") end |
#drop_trigger(table_name, name, if_exists: true) ⇒ Object
66 67 68 69 |
# File 'lib/gitlab/database/schema_helpers.rb', line 66 def drop_trigger(table_name, name, if_exists: true) exists_clause = optional_clause(if_exists, "IF EXISTS") execute("DROP TRIGGER #{exists_clause} #{name} ON #{table_name}") end |
#find_all_id_columns_sql ⇒ Object
96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 |
# File 'lib/gitlab/database/schema_helpers.rb', line 96 def find_all_id_columns_sql <<~SQL.strip SELECT table_name, column_name, data_type, column_default FROM information_schema.columns a WHERE a.table_schema = 'public' AND ( -- columns like "id" and "project_id" (a.data_type = 'integer' AND (a.column_name = 'id' OR a.column_name LIKE '%\\_id')) OR -- columns like "traversal_ids" (a.data_type = 'ARRAY' AND a.udt_name = '_int4' AND a.column_name LIKE '%\\_ids') ) AND NOT EXISTS ( -- skip columns when migration is in progress SELECT 1 FROM information_schema.columns b WHERE b.table_schema = a.table_schema AND b.table_name = a.table_name AND b.data_type = 'bigint' AND b.column_name = (a.column_name || '_convert_to_bigint') ) AND NOT EXISTS ( -- skip columns from partitioned tables SELECT 1 FROM postgres_partitions c WHERE c.schema = 'public' AND c.name = a.table_name ) ORDER BY table_schema, table_name, column_name SQL end |
#function_exists?(name) ⇒ Boolean
31 32 33 |
# File 'lib/gitlab/database/schema_helpers.rb', line 31 def function_exists?(name) !!connection.select_value("SELECT 1 FROM pg_proc WHERE proname = '#{name}'") end |
#object_name(table, type) ⇒ Object
81 82 83 84 85 86 |
# File 'lib/gitlab/database/schema_helpers.rb', line 81 def object_name(table, type) identifier = "#{table}_#{type}" hashed_identifier = Digest::SHA256.hexdigest(identifier).first(10) "#{type}_#{hashed_identifier}" end |
#reset_all_trigger_functions(table_name) ⇒ Object
23 24 25 26 27 28 29 |
# File 'lib/gitlab/database/schema_helpers.rb', line 23 def reset_all_trigger_functions(table_name) triggers = find_table_triggers(table_name) triggers.each do |trigger| reset_trigger_function(trigger['function_name']) end end |
#reset_trigger_function(function_name) ⇒ Object
19 20 21 |
# File 'lib/gitlab/database/schema_helpers.rb', line 19 def reset_trigger_function(function_name) execute("ALTER FUNCTION #{quote_table_name(function_name)} RESET ALL") end |
#tmp_table_name(base) ⇒ Object
75 76 77 78 79 |
# File 'lib/gitlab/database/schema_helpers.rb', line 75 def tmp_table_name(base) hashed_base = Digest::SHA256.hexdigest(base).first(10) "#{base}_#{hashed_base}" end |
#trigger_exists?(table_name, name, schema = nil) ⇒ Boolean
45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 |
# File 'lib/gitlab/database/schema_helpers.rb', line 45 def trigger_exists?(table_name, name, schema = nil) result = connection.select_value(<<~SQL.squish) SELECT true FROM pg_catalog.pg_trigger trgr INNER JOIN pg_catalog.pg_class rel ON trgr.tgrelid = rel.oid INNER JOIN pg_catalog.pg_namespace nsp ON nsp.oid = rel.relnamespace WHERE nsp.nspname = #{connection.quote(schema || connection.current_schema)} AND rel.relname = #{connection.quote(table_name)} AND trgr.tgname = #{connection.quote(name)} SQL !!result end |