Class: Gitlab::Database::Reflection
- Inherits:
-
Object
- Object
- Gitlab::Database::Reflection
- Defined in:
- lib/gitlab/database/reflection.rb
Overview
A class for reflecting upon a database and its settings, such as the adapter name, PostgreSQL version, and the presence of tables or columns.
Instance Attribute Summary collapse
-
#model ⇒ Object
readonly
Returns the value of attribute model.
Instance Method Summary collapse
- #adapter_name ⇒ Object
- #cached_column_exists?(column_name) ⇒ Boolean
- #cached_table_exists? ⇒ Boolean
- #config ⇒ Object
- #database_name ⇒ Object
- #database_version ⇒ Object
- #exists? ⇒ Boolean
- #flavor ⇒ Object
- #human_adapter_name ⇒ Object
-
#initialize(model) ⇒ Reflection
constructor
A new instance of Reflection.
- #postgresql? ⇒ Boolean
- #postgresql_minimum_supported_version? ⇒ Boolean
- #primary? ⇒ Boolean
-
#recovery? ⇒ Boolean
Check whether the server is in recovery mode (recovering from a backup or archive).
- #system_id ⇒ Object
- #username ⇒ Object
- #version ⇒ Object
Constructor Details
#initialize(model) ⇒ Reflection
Returns a new instance of Reflection.
10 11 12 13 |
# File 'lib/gitlab/database/reflection.rb', line 10 def initialize(model) @model = model @version = nil end |
Instance Attribute Details
#model ⇒ Object (readonly)
Returns the value of attribute model.
8 9 10 |
# File 'lib/gitlab/database/reflection.rb', line 8 def model @model end |
Instance Method Details
#adapter_name ⇒ Object
36 37 38 |
# File 'lib/gitlab/database/reflection.rb', line 36 def adapter_name config[:adapter] end |
#cached_column_exists?(column_name) ⇒ Boolean
75 76 77 78 79 |
# File 'lib/gitlab/database/reflection.rb', line 75 def cached_column_exists?(column_name) connection .schema_cache.columns_hash(model.table_name) .has_key?(column_name.to_s) end |
#cached_table_exists? ⇒ Boolean
81 82 83 |
# File 'lib/gitlab/database/reflection.rb', line 81 def cached_table_exists? exists? && connection.schema_cache.data_source_exists?(model.table_name) end |
#config ⇒ Object
15 16 17 18 19 20 21 22 23 24 25 26 |
# File 'lib/gitlab/database/reflection.rb', line 15 def config # The result of this method must not be cached, as other methods may use # it after making configuration changes and expect those changes to be # present. For example, `disable_prepared_statements` expects the # configuration settings to always be up to date. # # See the following for more information: # # - https://gitlab.com/gitlab-org/release/retrospectives/-/issues/39 # - https://gitlab.com/gitlab-com/gl-infra/production/-/issues/5238 model.connection_db_config.configuration_hash.with_indifferent_access end |
#database_name ⇒ Object
32 33 34 |
# File 'lib/gitlab/database/reflection.rb', line 32 def database_name config[:database] end |
#database_version ⇒ Object
67 68 69 |
# File 'lib/gitlab/database/reflection.rb', line 67 def database_version connection.select_value("SELECT VERSION()").to_s end |
#exists? ⇒ Boolean
85 86 87 88 89 90 91 92 93 94 |
# File 'lib/gitlab/database/reflection.rb', line 85 def exists? # We can't _just_ check if `connection` raises an error, as it will # point to a `ConnectionProxy`, and obtaining those doesn't involve any # database queries. So instead we obtain the database version, which is # cached after the first call. connection.database_version true rescue StandardError false end |
#flavor ⇒ Object
100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 |
# File 'lib/gitlab/database/reflection.rb', line 100 def flavor { # Based on https://aws.amazon.com/premiumsupport/knowledge-center/aurora-version-number/ 'Amazon Aurora PostgreSQL' => { statement: 'SELECT AURORA_VERSION()', error: /PG::UndefinedFunction/ }, # Based on https://docs.aws.amazon.com/AmazonRDS/latest/UserGuide/CHAP_PostgreSQL.html#PostgreSQL.Concepts.General.FeatureSupport.Extensions, # this is also available for both Aurora and RDS, so we need to check for the former first. 'PostgreSQL on Amazon RDS' => { statement: 'SHOW rds.extensions', error: /PG::UndefinedObject/ }, # Based on https://cloud.google.com/sql/docs/postgres/flags#postgres-c this should be specific # to Cloud SQL for PostgreSQL 'Cloud SQL for PostgreSQL' => { statement: 'SHOW cloudsql.iam_authentication', error: /PG::UndefinedObject/ }, # Based on # - https://docs.microsoft.com/en-us/azure/postgresql/flexible-server/concepts-extensions # - https://docs.microsoft.com/en-us/azure/postgresql/concepts-extensions # this should be available only for Azure Database for PostgreSQL - Flexible Server. 'Azure Database for PostgreSQL - Flexible Server' => { statement: 'SHOW azure.extensions', error: /PG::UndefinedObject/ }, # Based on # - https://docs.microsoft.com/en-us/azure/postgresql/flexible-server/concepts-servers # - https://docs.microsoft.com/en-us/azure/postgresql/concepts-servers#managing-your-server # this database is present on both Flexible and Single server, so we should check the former first. 'Azure Database for PostgreSQL - Single Server' => { statement: "SELECT datname FROM pg_database WHERE datname = 'azure_maintenance'" }, # Based on # - https://cloud.google.com/sql/docs/postgres/flags # running a query to detect flag names that begin with 'alloydb 'AlloyDB for PostgreSQL' => { statement: "SELECT name FROM pg_settings WHERE name LIKE 'alloydb%'" } }.each do |flavor, conditions| return flavor if connection.execute(conditions[:statement]).to_a.present? rescue ActiveRecord::StatementInvalid => e raise if conditions[:error] && !e..match?(conditions[:error]) end nil end |
#human_adapter_name ⇒ Object
40 41 42 43 44 45 46 |
# File 'lib/gitlab/database/reflection.rb', line 40 def human_adapter_name if postgresql? 'PostgreSQL' else 'Unknown' end end |
#postgresql? ⇒ Boolean
48 49 50 |
# File 'lib/gitlab/database/reflection.rb', line 48 def postgresql? adapter_name.casecmp('postgresql') == 0 end |
#postgresql_minimum_supported_version? ⇒ Boolean
71 72 73 |
# File 'lib/gitlab/database/reflection.rb', line 71 def postgresql_minimum_supported_version? version.to_f >= MINIMUM_POSTGRES_VERSION end |
#primary? ⇒ Boolean
59 60 61 |
# File 'lib/gitlab/database/reflection.rb', line 59 def primary? !recovery? end |
#recovery? ⇒ Boolean
Check whether the server is in recovery mode (recovering from a backup or archive)
53 54 55 56 57 |
# File 'lib/gitlab/database/reflection.rb', line 53 def recovery? recovery = connection.select_value('SELECT pg_is_in_recovery()') Gitlab::Utils.to_boolean(recovery) end |
#system_id ⇒ Object
96 97 98 |
# File 'lib/gitlab/database/reflection.rb', line 96 def system_id connection.select_value('SELECT system_identifier FROM pg_control_system()') end |
#username ⇒ Object
28 29 30 |
# File 'lib/gitlab/database/reflection.rb', line 28 def username config[:username] || ENV['USER'] end |
#version ⇒ Object
63 64 65 |
# File 'lib/gitlab/database/reflection.rb', line 63 def version @version ||= database_version.match(/\A(?:PostgreSQL |)([^\s]+).*\z/)[1] end |