1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
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
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
|
# frozen_string_literal: true
module Gitlab
module Database
GitlabSchemaInfoAllowCross = Struct.new(
:specific_tables,
keyword_init: true
)
GitlabSchemaInfo = Struct.new(
:name,
:description,
:allow_cross_joins,
:allow_cross_transactions,
:allow_cross_foreign_keys,
:file_path,
keyword_init: true
) do
def initialize(*)
super
self.name = name.to_sym
self.allow_cross_joins = convert_array_to_hash(allow_cross_joins)
self.allow_cross_transactions = convert_array_to_hash(allow_cross_transactions)
self.allow_cross_foreign_keys = convert_array_to_hash(allow_cross_foreign_keys)
end
def self.load_file(yaml_file)
content = YAML.load_file(yaml_file)
new(**content.deep_symbolize_keys.merge(file_path: yaml_file))
end
def allow_cross_joins?(table_schemas, all_tables)
allowed_schemas = allow_cross_joins || {}
allowed_for?(allowed_schemas, table_schemas, all_tables)
end
def allow_cross_transactions?(table_schemas, all_tables)
allowed_schemas = allow_cross_transactions || {}
allowed_for?(allowed_schemas, table_schemas, all_tables)
end
def allow_cross_foreign_keys?(table_schemas, all_tables)
allowed_schemas = allow_cross_foreign_keys || {}
allowed_for?(allowed_schemas, table_schemas, all_tables)
end
private
def allowed_for?(allowed_schemas, table_schemas, all_tables)
denied_schemas = table_schemas - [name]
denied_schemas -= allowed_schemas.keys
return false unless denied_schemas.empty?
all_tables.all? do |table|
table_schema = ::Gitlab::Database::GitlabSchema.table_schema!(table)
allowed_tables = allowed_schemas[table_schema]
allowed_tables.nil? || allowed_tables.specific_tables.include?(table)
end
end
# Convert from:
# - schema_a
# - schema_b:
# specific_tables:
# - table_b_of_schema_b
# - table_c_of_schema_b
#
# To:
# { :schema_a => nil,
# :schema_b => { specific_tables : [:table_b_of_schema_b, :table_c_of_schema_b] }
# }
#
def convert_array_to_hash(subject)
result = {}
subject&.each do |item|
if item.is_a?(Hash)
item.each do |key, value|
result[key.to_sym] = GitlabSchemaInfoAllowCross.new(value || {})
end
else
result[item.to_sym] = nil
end
end
result.freeze
end
end
end
end
|