Module: ViewsSchema
- Defined in:
- lib/views_schema.rb
Overview
Provides the ability to create and manage views through ActiveRecord
Constant Summary collapse
- WARNING =
Warning displayed in the event that the views have been broken
<<~HEREDOC ╔════════════════════════════════════════════════════════════╗ ║ WARNING! ║ ║ The attempt to dump the view schema failed. ║ ║ It is likely that your migrations have broken one or more ║ ║ of the views. It is CRITICAL that this problem is ║ ║ addressed before you commit these migrations. ║ ║ To ensure that reporting is not affected please ensure ║ ║ that the updated view accurately reflects the data. ║ ║ DO NOT change the schema of the view, merely how it ║ ║ retrieves the data. Ensure the changes are thoroughly ║ ║ tested against production like data. ║ ║ ║ ║ Downstream users should be notified of potential ║ ║ disruption. ║ ╚════════════════════════════════════════════════════════════╝ HEREDOC
- ALGORITHMS =
Valid algorithm options, first option is default
%w[UNDEFINED MERGE TEMPTABLE].freeze
- SECURITIES =
Valid security options, first option is default
%w[DEFINER INVOKER].freeze
- VIEW_STATEMENT =
'%{action} ALGORITHM=%<algorithm>s SQL SECURITY %<security>s VIEW `%<name>s` AS %<statement>s'
- REGEXP =
rubocop:todo Layout/LineLength
/\ACREATE ALGORITHM=(?<algorithm>\w*) DEFINER=`[^`]*`@`[^`]*` SQL SECURITY (?<security>\w*) VIEW `[^`]+` AS (?<statement>.*)\z/i
Class Method Summary collapse
-
.all_views ⇒ Object
rubocop:todo Metrics/MethodLength.
-
.create_view(name, statement, algorithm: ALGORITHMS.first, security: SECURITIES.first) ⇒ Void
Creates a new view.
-
.drop_view(name) ⇒ Void
Drops the view.
-
.each_view ⇒ Object
rubocop:enable Layout/LineLength.
-
.execute(args) ⇒ Object
Generates the SQL for view creation/updating.
-
.update_view(name, statement, algorithm: ALGORITHMS.first, security: SECURITIES.first) ⇒ Void
Updates an existing view, or creates a new view if it doesn’t exist already.
Class Method Details
.all_views ⇒ Object
rubocop:todo Metrics/MethodLength
50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 |
# File 'lib/views_schema.rb', line 50 def self.all_views # rubocop:todo Metrics/MethodLength ActiveRecord::Base .connection .execute( " SELECT TABLE_NAME AS name FROM INFORMATION_SCHEMA.VIEWS WHERE TABLE_SCHEMA = '#{ActiveRecord::Base.connection.current_database}';" ) .map do |v| # Behaviour depends on ruby version, so we need to work out what we have v.is_a?(Hash) ? v['name'] : v.first end .flatten end |
.create_view(name, statement, algorithm: ALGORITHMS.first, security: SECURITIES.first) ⇒ Void
Creates a new view. Will fail if the view already exists.
74 75 76 |
# File 'lib/views_schema.rb', line 74 def self.create_view(name, statement, algorithm: ALGORITHMS.first, security: SECURITIES.first) execute(action: 'CREATE', name: name, statement: statement, algorithm: algorithm, security: security) end |
.drop_view(name) ⇒ Void
Drops the view
95 96 97 98 99 |
# File 'lib/views_schema.rb', line 95 def self.drop_view(name) raise "Invalid name: `#{args[:name]}`" unless /^[a-z0-9_]*$/.match?(args[:name]) ActiveRecord::Base.connection.execute("DROP VIEW IF EXISTS `#{name}`;") end |
.each_view ⇒ Object
rubocop:enable Layout/LineLength
39 40 41 42 43 44 45 46 47 48 |
# File 'lib/views_schema.rb', line 39 def self.each_view all_views.each do |name| query = ActiveRecord::Base.connection.exec_query("SHOW CREATE TABLE #{name}").first matched = REGEXP.match(query['Create View']) yield(name, matched[:statement], matched[:algorithm], matched[:security]) end rescue ActiveRecord::StatementInvalid => e puts Rainbow(WARNING).red.inverse raise e end |
.execute(args) ⇒ Object
Use create_view or update_view
Generates the SQL for view creation/updating
110 111 112 113 114 115 |
# File 'lib/views_schema.rb', line 110 def self.execute(args) raise "Invalid name: `#{args[:name]}`" unless /^[a-z0-9_]*$/.match?(args[:name]) args[:statement] = args[:statement].to_sql if args[:statement].respond_to?(:to_sql) ActiveRecord::Base.connection.execute(VIEW_STATEMENT % args) end |
.update_view(name, statement, algorithm: ALGORITHMS.first, security: SECURITIES.first) ⇒ Void
Updates an existing view, or creates a new view if it doesn’t exist already.
86 87 88 |
# File 'lib/views_schema.rb', line 86 def self.update_view(name, statement, algorithm: ALGORITHMS.first, security: SECURITIES.first) execute(action: 'CREATE OR REPLACE', name: name, statement: statement, algorithm: algorithm, security: security) end |