Module: Gitlab::Database::GitlabSchema

Defined in:
lib/gitlab/database/gitlab_schema.rb

Constant Summary collapse

UnknownSchemaError =
Class.new(StandardError)
IMPLICIT_GITLAB_SCHEMAS =

Mainly used for test tables It maps table names prefixes to gitlab_schemas. The order of keys matter. Prefixes that contain other prefixes should come first.

{
  '_test_gitlab_main_clusterwide_' => :gitlab_main_clusterwide,
  '_test_gitlab_main_cell_' => :gitlab_main_cell,
  '_test_gitlab_main_' => :gitlab_main,
  '_test_gitlab_ci_' => :gitlab_ci,
  '_test_gitlab_embedding_' => :gitlab_embedding,
  '_test_gitlab_geo_' => :gitlab_geo,
  '_test_gitlab_pm_' => :gitlab_pm,
  '_test_' => :gitlab_shared,
  'pg_' => :gitlab_internal
}.freeze

Class Method Summary collapse

Class Method Details

.build_dictionary(scope) ⇒ Object



147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
# File 'lib/gitlab/database/gitlab_schema.rb', line 147

def self.build_dictionary(scope)
  Dir.glob(dictionary_path_globs(scope)).map do |file_path|
    data = YAML.load_file(file_path)

    key_name = data['table_name'] || data['view_name']

    # rubocop:disable Gitlab/DocUrl
    if data['gitlab_schema'].nil?
      raise(
        UnknownSchemaError,
        "#{file_path} must specify a valid gitlab_schema for #{key_name}. " \
        "See https://docs.gitlab.com/ee/development/database/database_dictionary.html"
      )
    end
    # rubocop:enable Gitlab/DocUrl

    [key_name, data['gitlab_schema'].to_sym]
  end
end

.cross_foreign_key_allowed?(table_schemas) ⇒ Boolean

Returns:

  • (Boolean)


106
107
108
# File 'lib/gitlab/database/gitlab_schema.rb', line 106

def self.cross_foreign_key_allowed?(table_schemas)
  self.cross_access_allowed?(:allow_cross_foreign_keys, table_schemas)
end

.cross_joins_allowed?(table_schemas) ⇒ Boolean

Returns:

  • (Boolean)


98
99
100
# File 'lib/gitlab/database/gitlab_schema.rb', line 98

def self.cross_joins_allowed?(table_schemas)
  table_schemas.empty? || self.cross_access_allowed?(:allow_cross_joins, table_schemas)
end

.cross_transactions_allowed?(table_schemas) ⇒ Boolean

Returns:

  • (Boolean)


102
103
104
# File 'lib/gitlab/database/gitlab_schema.rb', line 102

def self.cross_transactions_allowed?(table_schemas)
  table_schemas.empty? || self.cross_access_allowed?(:allow_cross_transactions, table_schemas)
end

.deleted_tables_to_schemaObject



127
128
129
# File 'lib/gitlab/database/gitlab_schema.rb', line 127

def self.deleted_tables_to_schema
  @deleted_tables_to_schema ||= self.build_dictionary('deleted_tables').to_h
end

.deleted_views_and_tables_to_schemaObject



123
124
125
# File 'lib/gitlab/database/gitlab_schema.rb', line 123

def self.deleted_views_and_tables_to_schema
  @deleted_views_and_tables_to_schema ||= self.deleted_tables_to_schema.merge(self.deleted_views_to_schema)
end

.deleted_views_to_schemaObject



131
132
133
# File 'lib/gitlab/database/gitlab_schema.rb', line 131

def self.deleted_views_to_schema
  @deleted_views_to_schema ||= self.build_dictionary('deleted_views').to_h
end

.dictionary_path_globs(scope) ⇒ Object



115
116
117
# File 'lib/gitlab/database/gitlab_schema.rb', line 115

def self.dictionary_path_globs(scope)
  self.dictionary_paths.map { |path| Rails.root.join(path, scope, '*.yml') }
end

.dictionary_pathsObject



110
111
112
113
# File 'lib/gitlab/database/gitlab_schema.rb', line 110

def self.dictionary_paths
  Gitlab::Database.all_database_connections
    .values.map(&:db_docs_dir).uniq
end

.schema_namesObject



143
144
145
# File 'lib/gitlab/database/gitlab_schema.rb', line 143

def self.schema_names
  @schema_names ||= self.views_and_tables_to_schema.values.to_set
end

.table_schema(name) ⇒ Object

rubocop:disable Metrics/CyclomaticComplexity



42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
# File 'lib/gitlab/database/gitlab_schema.rb', line 42

def self.table_schema(name)
  schema_name, table_name = name.split('.', 2) # Strip schema name like: `public.`

  # Most of names do not have schemas, ensure that this is table
  unless table_name
    table_name = schema_name
    schema_name = nil
  end

  # strip partition number of a form `loose_foreign_keys_deleted_records_1`
  table_name.gsub!(/_[0-9]+$/, '')

  # Tables and views that are properly mapped
  if gitlab_schema = views_and_tables_to_schema[table_name]
    return gitlab_schema
  end

  # Tables and views that are deleted, but we still need to reference them
  if gitlab_schema = deleted_views_and_tables_to_schema[table_name]
    return gitlab_schema
  end

  # Partitions that belong to the CI domain
  if table_name.start_with?('ci_') && gitlab_schema = views_and_tables_to_schema["p_#{table_name}"]
    return gitlab_schema
  end

  # All tables from `information_schema.` are marked as `internal`
  return :gitlab_internal if schema_name == 'information_schema'

  IMPLICIT_GITLAB_SCHEMAS.each do |prefix, gitlab_schema|
    return gitlab_schema if table_name.start_with?(prefix)
  end

  nil
end

.table_schema!(name) ⇒ Object

rubocop:enable Metrics/CyclomaticComplexity



80
81
82
83
84
85
86
87
88
# File 'lib/gitlab/database/gitlab_schema.rb', line 80

def self.table_schema!(name)
  # rubocop:disable Gitlab/DocUrl
  self.table_schema(name) || raise(
    UnknownSchemaError,
    "Could not find gitlab schema for table #{name}: Any new or deleted tables must be added to the database dictionary " \
    "See https://docs.gitlab.com/ee/development/database/database_dictionary.html"
  )
  # rubocop:enable Gitlab/DocUrl
end

.table_schemas!(tables) ⇒ Object



22
23
24
# File 'lib/gitlab/database/gitlab_schema.rb', line 22

def self.table_schemas!(tables)
  tables.map { |table| table_schema!(table) }.to_set
end

.tables_to_schemaObject



135
136
137
# File 'lib/gitlab/database/gitlab_schema.rb', line 135

def self.tables_to_schema
  @tables_to_schema ||= self.build_dictionary('').to_h
end

.views_and_tables_to_schemaObject



119
120
121
# File 'lib/gitlab/database/gitlab_schema.rb', line 119

def self.views_and_tables_to_schema
  @views_and_tables_to_schema ||= self.tables_to_schema.merge(self.views_to_schema)
end

.views_to_schemaObject



139
140
141
# File 'lib/gitlab/database/gitlab_schema.rb', line 139

def self.views_to_schema
  @views_to_schema ||= self.build_dictionary('views').to_h
end