class Blazer::DataSource

Attributes

id[R]
settings[R]

Public Class Methods

new(id, settings) click to toggle source
# File lib/blazer/data_source.rb, line 11
def initialize(id, settings)
  @id = id
  @settings = settings
end

Public Instance Methods

adapter() click to toggle source
# File lib/blazer/data_source.rb, line 16
def adapter
  settings["adapter"] || detect_adapter
end
cache() click to toggle source
# File lib/blazer/data_source.rb, line 48
def cache
  @cache ||= begin
    if settings["cache"].is_a?(Hash)
      settings["cache"]
    elsif settings["cache"]
      {
        "mode" => "all",
        "expires_in" => settings["cache"]
      }
    else
      {
        "mode" => "off"
      }
    end
  end
end
cache_expires_in() click to toggle source
# File lib/blazer/data_source.rb, line 69
def cache_expires_in
  (cache["expires_in"] || 60).to_f
end
cache_key(key) click to toggle source
# File lib/blazer/data_source.rb, line 135
def cache_key(key)
  (["blazer", "v4"] + key).join("/")
end
cache_mode() click to toggle source
# File lib/blazer/data_source.rb, line 65
def cache_mode
  cache["mode"]
end
cache_slow_threshold() click to toggle source
# File lib/blazer/data_source.rb, line 73
def cache_slow_threshold
  (cache["slow_threshold"] || 15).to_f
end
clear_cache(statement) click to toggle source
# File lib/blazer/data_source.rb, line 131
def clear_cache(statement)
  Blazer.cache.delete(statement_cache_key(statement))
end
delete_results(run_id) click to toggle source
# File lib/blazer/data_source.rb, line 92
def delete_results(run_id)
  Blazer.cache.delete(run_cache_key(run_id))
end
linked_columns() click to toggle source
# File lib/blazer/data_source.rb, line 24
def linked_columns
  settings["linked_columns"] || {}
end
local_time_suffix() click to toggle source
# File lib/blazer/data_source.rb, line 77
def local_time_suffix
  @local_time_suffix ||= Array(settings["local_time_suffix"])
end
name() click to toggle source
# File lib/blazer/data_source.rb, line 20
def name
  settings["name"] || @id
end
read_cache(cache_key) click to toggle source
# File lib/blazer/data_source.rb, line 81
def read_cache(cache_key)
  value = Blazer.cache.read(cache_key)
  if value
    Blazer::Result.new(self, *Marshal.load(value), nil)
  end
end
run_cache_key(run_id) click to toggle source
# File lib/blazer/data_source.rb, line 143
def run_cache_key(run_id)
  cache_key(["run", run_id])
end
run_results(run_id) click to toggle source
# File lib/blazer/data_source.rb, line 88
def run_results(run_id)
  read_cache(run_cache_key(run_id))
end
run_statement(statement, options = {}) click to toggle source
# File lib/blazer/data_source.rb, line 96
def run_statement(statement, options = {})
  async = options[:async]
  result = nil
  if cache_mode != "off"
    if options[:refresh_cache]
      clear_cache(statement) # for checks
    else
      result = read_cache(statement_cache_key(statement))
    end
  end

  unless result
    comment = "blazer"
    if options[:user].respond_to?(:id)
      comment << ",user_id:#{options[:user].id}"
    end
    if options[:user].respond_to?(Blazer.user_name)
      # only include letters, numbers, and spaces to prevent injection
      comment << ",user_name:#{options[:user].send(Blazer.user_name).to_s.gsub(/[^a-zA-Z0-9 ]/, "")}"
    end
    if options[:query].respond_to?(:id)
      comment << ",query_id:#{options[:query].id}"
    end
    if options[:check]
      comment << ",check_id:#{options[:check].id},check_emails:#{options[:check].emails}"
    end
    if options[:run_id]
      comment << ",run_id:#{options[:run_id]}"
    end
    result = run_statement_helper(statement, comment, async ? options[:run_id] : nil)
  end

  result
end
select_all_variables() click to toggle source
# File lib/blazer/data_source.rb, line 40
def select_all_variables
  settings["select_all_variables"] || {}
end
smart_columns() click to toggle source
# File lib/blazer/data_source.rb, line 28
def smart_columns
  settings["smart_columns"] || {}
end
smart_variables() click to toggle source
# File lib/blazer/data_source.rb, line 32
def smart_variables
  settings["smart_variables"] || {}
end
statement_cache_key(statement) click to toggle source
# File lib/blazer/data_source.rb, line 139
def statement_cache_key(statement)
  cache_key(["statement", id, Digest::MD5.hexdigest(statement.to_s.gsub("\r\n", "\n"))])
end
timeout() click to toggle source
# File lib/blazer/data_source.rb, line 44
def timeout
  settings["timeout"]
end
variable_defaults() click to toggle source
# File lib/blazer/data_source.rb, line 36
def variable_defaults
  settings["variable_defaults"] || {}
end

Protected Instance Methods

adapter_instance() click to toggle source
# File lib/blazer/data_source.rb, line 149
def adapter_instance
  @adapter_instance ||= begin
    unless settings["url"] || Rails.env.development? || ["bigquery", "athena", "snowflake"].include?(settings["adapter"])
      raise Blazer::Error, "Empty url for data source: #{id}"
    end

    unless Blazer.adapters[adapter]
      raise Blazer::Error, "Unknown adapter"
    end

    Blazer.adapters[adapter].new(self)
  end
end
detect_adapter() click to toggle source
# File lib/blazer/data_source.rb, line 189
def detect_adapter
  schema = settings["url"].to_s.split("://").first
  case schema
  when "mongodb", "presto", "cassandra"
    schema
  else
    "sql"
  end
end
run_statement_helper(statement, comment, run_id) click to toggle source
# File lib/blazer/data_source.rb, line 163
def run_statement_helper(statement, comment, run_id)
  start_time = Time.now
  columns, rows, error = adapter_instance.run_statement(statement, comment)
  duration = Time.now - start_time

  cache_data = nil
  cache = !error && (cache_mode == "all" || (cache_mode == "slow" && duration >= cache_slow_threshold))
  if cache || run_id
    cache_data = Marshal.dump([columns, rows, error, cache ? Time.now : nil]) rescue nil
  end

  if cache && cache_data && adapter_instance.cachable?(statement)
    Blazer.cache.write(statement_cache_key(statement), cache_data, expires_in: cache_expires_in.to_f * 60)
  end

  if run_id
    unless cache_data
      error = "Error storing the results of this query :("
      cache_data = Marshal.dump([[], [], error, nil])
    end
    Blazer.cache.write(run_cache_key(run_id), cache_data, expires_in: 30.seconds)
  end

  Blazer::Result.new(self, columns, rows, error, nil, cache && !cache_data.nil?)
end