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(statement) ⇒ Object
- #cache_mode ⇒ Object
- #cache_slow_threshold ⇒ Object
- #clear_cache(statement) ⇒ Object
- #cost(statement) ⇒ 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
- #reconnect ⇒ Object
- #redshift? ⇒ Boolean
- #run_main_statement(statement, options = {}) ⇒ Object
- #run_statement(statement, options = {}) ⇒ Object
- #schemas ⇒ Object
- #smart_columns ⇒ Object
- #smart_variables ⇒ 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(statement) ⇒ Object
172 173 174 |
# File 'lib/blazer/data_source.rb', line 172 def cache_key(statement) ["blazer", "v3", id, Digest::MD5.hexdigest(statement)].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
168 169 170 |
# File 'lib/blazer/data_source.rb', line 168 def clear_cache(statement) Blazer.cache.delete(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 |
#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
194 195 196 |
# File 'lib/blazer/data_source.rb', line 194 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
186 187 188 |
# File 'lib/blazer/data_source.rb', line 186 def postgresql? ["PostgreSQL", "PostGIS"].include?(adapter_name) end |
#reconnect ⇒ Object
198 199 200 |
# File 'lib/blazer/data_source.rb', line 198 def reconnect connection_model.establish_connection(settings["url"]) end |
#redshift? ⇒ Boolean
190 191 192 |
# File 'lib/blazer/data_source.rb', line 190 def redshift? ["Redshift"].include?(adapter_name) 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 columns, rows, error, cached_at, just_cached = run_statement(statement, .merge(with_just_cached: true)) duration = Time.now - start_time if Blazer.audit audit.duration = duration if audit.respond_to?(:duration=) audit.error = error if audit.respond_to?(:error=) audit.timed_out = error == Blazer::TIMEOUT_MESSAGE if audit.respond_to?(:timed_out=) audit.cached = cached_at.present? if audit.respond_to?(:cached=) if !cached_at && duration >= 10 audit.cost = cost(statement) if audit.respond_to?(:cost=) end audit.save! if audit.changed? end if query && error != Blazer::TIMEOUT_MESSAGE query.checks.each do |check| check.update_state(rows, error) end end [columns, rows, error, cached_at, just_cached] end |
#run_statement(statement, options = {}) ⇒ Object
136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 |
# File 'lib/blazer/data_source.rb', line 136 def run_statement(statement, = {}) columns = nil rows = nil error = nil cached_at = nil just_cached = false cache_key = self.cache_key(statement) if cache if cache && ![:refresh_cache] value = Blazer.cache.read(cache_key) columns, rows, cached_at = Marshal.load(value) if value end unless rows 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 columns, rows, error, just_cached = run_statement_helper(statement, comment) end output = [columns, rows, error, cached_at] output << just_cached if [:with_just_cached] output end |
#schemas ⇒ Object
176 177 178 179 |
# File 'lib/blazer/data_source.rb', line 176 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 |
#tables ⇒ Object
181 182 183 184 |
# File 'lib/blazer/data_source.rb', line 181 def tables columns, rows, error, cached_at = run_statement(connection_model.send(:sanitize_sql_array, ["SELECT table_name FROM information_schema.tables WHERE table_schema IN (?) ORDER BY table_name", schemas])) 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 |