module VerifiableView

Public Class Methods

verification_method=(some_proc) click to toggle source
# File lib/verifiable_view.rb, line 15
def self.verification_method=(some_proc)
  @verification_method = some_proc
end

Private Class Methods

verification_method() click to toggle source
# File lib/verifiable_view.rb, line 37
def self.verification_method
  @verification_method || (lambda do |code_def, db_def|
    return true if db_def == code_def
    raise "The view definition in your DB doesn't match with your code" 
  end)
end

Public Instance Methods

definition(&block) click to toggle source
# File lib/verifiable_view.rb, line 11
def definition(&block)
  @definition ||= block or raise "Missing view definition"
end
verify() click to toggle source
# File lib/verifiable_view.rb, line 4
def verify
  VerifiableView.verification_method.call(
    code_view_definition,
    db_view_definition
  )
end

Private Instance Methods

code_view_definition() click to toggle source
# File lib/verifiable_view.rb, line 21
def code_view_definition
  view_name = "view_#{SecureRandom.hex(10)}"
  result = ""
  transaction do
    create_view(view_name)
    result = get_view_sql(view_name)
    raise ActiveRecord::Rollback
  end

  result
end
create_view(name) click to toggle source
# File lib/verifiable_view.rb, line 44
def create_view(name)
  definition_sql = definition.call.to_sql
  connection.execute("create view #{name} as #{definition_sql}")
end
db_view_definition() click to toggle source
# File lib/verifiable_view.rb, line 33
def db_view_definition
  get_view_sql(table_name)
end
get_view_sql(view_name) click to toggle source
# File lib/verifiable_view.rb, line 49
def get_view_sql(view_name)
  connection.
    execute("select view_definition from information_schema.views
            where table_name = '#{view_name}'").
    first&.
    fetch("view_definition")
end