Class: Blazer::DataSource
- Inherits:
-
Object
- Object
- Blazer::DataSource
- Defined in:
- lib/blazer/data_source.rb
Instance Attribute Summary collapse
-
#connection_model ⇒ Object
readonly
Returns the value of attribute connection_model.
-
#id ⇒ Object
readonly
Returns the value of attribute id.
-
#settings ⇒ Object
readonly
Returns the value of attribute settings.
Instance Method Summary collapse
- #cache ⇒ Object
- #cache_expires_in ⇒ Object
- #cache_key(key) ⇒ Object
- #cache_mode ⇒ Object
- #cache_slow_threshold ⇒ Object
- #clear_cache(statement) ⇒ Object
- #cost(statement) ⇒ Object
- #delete_results(run_id) ⇒ Object
- #explain(statement) ⇒ Object
-
#initialize(id, settings) ⇒ DataSource
constructor
A new instance of DataSource.
- #linked_columns ⇒ Object
- #local_time_suffix ⇒ Object
- #mysql? ⇒ Boolean
- #name ⇒ Object
- #postgresql? ⇒ Boolean
- #read_cache(cache_key) ⇒ Object
- #reconnect ⇒ Object
- #redshift? ⇒ Boolean
- #run_cache_key(run_id) ⇒ Object
- #run_main_statement(statement, options = {}) ⇒ Object
- #run_results(run_id) ⇒ Object
- #run_statement(statement, options = {}) ⇒ Object
- #schemas ⇒ Object
- #smart_columns ⇒ Object
- #smart_variables ⇒ Object
- #statement_cache_key(statement) ⇒ Object
- #tables ⇒ Object
- #timeout ⇒ Object
- #use_transaction? ⇒ Boolean
- #variable_defaults ⇒ Object
Constructor Details
#initialize(id, settings) ⇒ DataSource
Returns a new instance of DataSource.
7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 |
# File 'lib/blazer/data_source.rb', line 7 def initialize(id, settings) @id = id @settings = settings unless settings["url"] || Rails.env.development? raise Blazer::Error, "Empty url" end @connection_model = Class.new(Blazer::Connection) do def self.name "Blazer::Connection::#{object_id}" end establish_connection(settings["url"]) if settings["url"] end end |
Instance Attribute Details
#connection_model ⇒ Object (readonly)
Returns the value of attribute connection_model.
5 6 7 |
# File 'lib/blazer/data_source.rb', line 5 def connection_model @connection_model end |
#id ⇒ Object (readonly)
Returns the value of attribute id.
5 6 7 |
# File 'lib/blazer/data_source.rb', line 5 def id @id end |
#settings ⇒ Object (readonly)
Returns the value of attribute settings.
5 6 7 |
# File 'lib/blazer/data_source.rb', line 5 def settings @settings end |
Instance Method Details
#cache ⇒ Object
48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 |
# 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 ⇒ Object
69 70 71 |
# File 'lib/blazer/data_source.rb', line 69 def cache_expires_in (cache["expires_in"] || 60).to_f end |
#cache_key(key) ⇒ Object
183 184 185 |
# File 'lib/blazer/data_source.rb', line 183 def cache_key(key) (["blazer", "v4"] + key).join("/") end |
#cache_mode ⇒ Object
65 66 67 |
# File 'lib/blazer/data_source.rb', line 65 def cache_mode cache["mode"] end |
#cache_slow_threshold ⇒ Object
73 74 75 |
# File 'lib/blazer/data_source.rb', line 73 def cache_slow_threshold (cache["slow_threshold"] || 15).to_f end |
#clear_cache(statement) ⇒ Object
179 180 181 |
# File 'lib/blazer/data_source.rb', line 179 def clear_cache(statement) Blazer.cache.delete(statement_cache_key(statement)) end |
#cost(statement) ⇒ Object
85 86 87 88 89 |
# File 'lib/blazer/data_source.rb', line 85 def cost(statement) result = explain(statement) match = /cost=\d+\.\d+..(\d+\.\d+) /.match(result) match[1] if match end |
#delete_results(run_id) ⇒ Object
147 148 149 |
# File 'lib/blazer/data_source.rb', line 147 def delete_results(run_id) Blazer.cache.delete(run_cache_key(run_id)) end |
#explain(statement) ⇒ Object
91 92 93 94 95 96 97 |
# File 'lib/blazer/data_source.rb', line 91 def explain(statement) if postgresql? || redshift? connection_model.connection.select_all("EXPLAIN #{statement}").rows.first.first end rescue nil end |
#linked_columns ⇒ Object
28 29 30 |
# File 'lib/blazer/data_source.rb', line 28 def linked_columns settings["linked_columns"] || {} end |
#local_time_suffix ⇒ Object
77 78 79 |
# File 'lib/blazer/data_source.rb', line 77 def local_time_suffix @local_time_suffix ||= Array(settings["local_time_suffix"]) end |
#mysql? ⇒ Boolean
213 214 215 |
# File 'lib/blazer/data_source.rb', line 213 def mysql? ["MySQL", "Mysql2", "Mysql2Spatial"].include?(adapter_name) end |
#name ⇒ Object
24 25 26 |
# File 'lib/blazer/data_source.rb', line 24 def name settings["name"] || @id end |
#postgresql? ⇒ Boolean
205 206 207 |
# File 'lib/blazer/data_source.rb', line 205 def postgresql? ["PostgreSQL", "PostGIS"].include?(adapter_name) end |
#read_cache(cache_key) ⇒ Object
136 137 138 139 140 141 |
# File 'lib/blazer/data_source.rb', line 136 def read_cache(cache_key) value = Blazer.cache.read(cache_key) if value Blazer::Result.new(self, *Marshal.load(value), nil) end end |
#reconnect ⇒ Object
217 218 219 |
# File 'lib/blazer/data_source.rb', line 217 def reconnect connection_model.establish_connection(settings["url"]) end |
#redshift? ⇒ Boolean
209 210 211 |
# File 'lib/blazer/data_source.rb', line 209 def redshift? ["Redshift"].include?(adapter_name) end |
#run_cache_key(run_id) ⇒ Object
191 192 193 |
# File 'lib/blazer/data_source.rb', line 191 def run_cache_key(run_id) cache_key(["run", run_id]) end |
#run_main_statement(statement, options = {}) ⇒ Object
99 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 132 133 134 |
# File 'lib/blazer/data_source.rb', line 99 def run_main_statement(statement, = {}) query = [:query] Blazer.transform_statement.call(self, statement) if Blazer.transform_statement # audit if Blazer.audit audit = Blazer::Audit.new(statement: statement) audit.query = query audit.data_source = id audit.user = [:user] audit.save! end start_time = Time.now result = run_statement(statement, ) duration = Time.now - start_time if Blazer.audit audit.duration = duration if audit.respond_to?(:duration=) audit.error = result.error if audit.respond_to?(:error=) audit.timed_out = result.timed_out? if audit.respond_to?(:timed_out=) audit.cached = result.cached? if audit.respond_to?(:cached=) if !result.cached? && duration >= 10 audit.cost = cost(statement) if audit.respond_to?(:cost=) end audit.save! if audit.changed? end if query && !result.timed_out? query.checks.each do |check| check.update_state(result) end end result end |
#run_results(run_id) ⇒ Object
143 144 145 |
# File 'lib/blazer/data_source.rb', line 143 def run_results(run_id) read_cache(run_cache_key(run_id)) end |
#run_statement(statement, options = {}) ⇒ Object
151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 |
# File 'lib/blazer/data_source.rb', line 151 def run_statement(statement, = {}) run_id = [:run_id] result = nil if cache_mode != "off" && ![:refresh_cache] result = read_cache(statement_cache_key(statement)) end unless result comment = "blazer" if [:user].respond_to?(:id) comment << ",user_id:#{options[:user].id}" end if [: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 [:query].respond_to?(:id) comment << ",query_id:#{options[:query].id}" end if [:check] comment << ",check_id:#{options[:check].id},check_emails:#{options[:check].emails}" end result = run_statement_helper(statement, comment, [:run_id]) end result end |
#schemas ⇒ Object
195 196 197 198 |
# File 'lib/blazer/data_source.rb', line 195 def schemas default_schema = (postgresql? || redshift?) ? "public" : connection_model.connection_config[:database] settings["schemas"] || [connection_model.connection_config[:schema] || default_schema] end |
#smart_columns ⇒ Object
32 33 34 |
# File 'lib/blazer/data_source.rb', line 32 def smart_columns settings["smart_columns"] || {} end |
#smart_variables ⇒ Object
36 37 38 |
# File 'lib/blazer/data_source.rb', line 36 def smart_variables settings["smart_variables"] || {} end |
#statement_cache_key(statement) ⇒ Object
187 188 189 |
# File 'lib/blazer/data_source.rb', line 187 def statement_cache_key(statement) cache_key(["statement", id, Digest::MD5.hexdigest(statement)]) end |
#tables ⇒ Object
200 201 202 203 |
# File 'lib/blazer/data_source.rb', line 200 def tables result = run_statement(connection_model.send(:sanitize_sql_array, ["SELECT table_name FROM information_schema.tables WHERE table_schema IN (?) ORDER BY table_name", schemas])) result.rows.map(&:first) end |
#timeout ⇒ Object
44 45 46 |
# File 'lib/blazer/data_source.rb', line 44 def timeout settings["timeout"] end |
#use_transaction? ⇒ Boolean
81 82 83 |
# File 'lib/blazer/data_source.rb', line 81 def use_transaction? settings.key?("use_transaction") ? settings["use_transaction"] : true end |
#variable_defaults ⇒ Object
40 41 42 |
# File 'lib/blazer/data_source.rb', line 40 def variable_defaults settings["variable_defaults"] || {} end |