blazer 2.5.0 → 2.6.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (49) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +25 -0
  3. data/README.md +63 -15
  4. data/app/assets/javascripts/blazer/queries.js +12 -1
  5. data/app/assets/stylesheets/blazer/application.css +1 -0
  6. data/app/assets/stylesheets/blazer/bootstrap-propshaft.css +10 -0
  7. data/app/assets/stylesheets/blazer/bootstrap-sprockets.css.erb +10 -0
  8. data/app/assets/stylesheets/blazer/{bootstrap.css.erb → bootstrap.css} +0 -6
  9. data/app/controllers/blazer/base_controller.rb +45 -45
  10. data/app/controllers/blazer/dashboards_controller.rb +4 -11
  11. data/app/controllers/blazer/queries_controller.rb +29 -48
  12. data/app/models/blazer/query.rb +8 -2
  13. data/app/views/blazer/_variables.html.erb +5 -4
  14. data/app/views/blazer/dashboards/_form.html.erb +1 -1
  15. data/app/views/blazer/dashboards/show.html.erb +6 -4
  16. data/app/views/blazer/queries/_caching.html.erb +1 -1
  17. data/app/views/blazer/queries/_form.html.erb +3 -3
  18. data/app/views/blazer/queries/run.html.erb +1 -1
  19. data/app/views/blazer/queries/show.html.erb +12 -7
  20. data/app/views/layouts/blazer/application.html.erb +7 -2
  21. data/lib/blazer/adapters/athena_adapter.rb +55 -18
  22. data/lib/blazer/adapters/base_adapter.rb +16 -1
  23. data/lib/blazer/adapters/bigquery_adapter.rb +13 -2
  24. data/lib/blazer/adapters/cassandra_adapter.rb +15 -4
  25. data/lib/blazer/adapters/drill_adapter.rb +10 -0
  26. data/lib/blazer/adapters/druid_adapter.rb +36 -1
  27. data/lib/blazer/adapters/elasticsearch_adapter.rb +13 -2
  28. data/lib/blazer/adapters/hive_adapter.rb +10 -0
  29. data/lib/blazer/adapters/ignite_adapter.rb +12 -2
  30. data/lib/blazer/adapters/influxdb_adapter.rb +22 -10
  31. data/lib/blazer/adapters/mongodb_adapter.rb +4 -0
  32. data/lib/blazer/adapters/neo4j_adapter.rb +17 -2
  33. data/lib/blazer/adapters/opensearch_adapter.rb +4 -0
  34. data/lib/blazer/adapters/presto_adapter.rb +9 -0
  35. data/lib/blazer/adapters/salesforce_adapter.rb +5 -0
  36. data/lib/blazer/adapters/snowflake_adapter.rb +9 -0
  37. data/lib/blazer/adapters/soda_adapter.rb +9 -0
  38. data/lib/blazer/adapters/spark_adapter.rb +5 -0
  39. data/lib/blazer/adapters/sql_adapter.rb +37 -3
  40. data/lib/blazer/data_source.rb +85 -5
  41. data/lib/blazer/engine.rb +0 -4
  42. data/lib/blazer/result.rb +2 -0
  43. data/lib/blazer/run_statement.rb +7 -3
  44. data/lib/blazer/run_statement_job.rb +4 -2
  45. data/lib/blazer/slack_notifier.rb +5 -2
  46. data/lib/blazer/statement.rb +75 -0
  47. data/lib/blazer/version.rb +1 -1
  48. data/lib/blazer.rb +14 -6
  49. metadata +7 -4
@@ -0,0 +1,75 @@
1
+ module Blazer
2
+ class Statement
3
+ attr_reader :statement, :data_source, :bind_statement, :bind_values
4
+ attr_accessor :values
5
+
6
+ def initialize(statement, data_source = nil)
7
+ @statement = statement
8
+ @data_source = data_source.is_a?(String) ? Blazer.data_sources[data_source] : data_source
9
+ @values = {}
10
+ end
11
+
12
+ def variables
13
+ @variables ||= Blazer.extract_vars(statement)
14
+ end
15
+
16
+ def add_values(var_params)
17
+ variables.each do |var|
18
+ value = var_params[var].presence
19
+ value = nil unless value.is_a?(String) # ignore arrays and hashes
20
+ if value
21
+ if ["start_time", "end_time"].include?(var)
22
+ value = value.to_s.gsub(" ", "+") # fix for Quip bug
23
+ end
24
+
25
+ if var.end_with?("_at")
26
+ begin
27
+ value = Blazer.time_zone.parse(value)
28
+ rescue
29
+ # do nothing
30
+ end
31
+ end
32
+
33
+ unless value.is_a?(ActiveSupport::TimeWithZone)
34
+ if value =~ /\A\d+\z/
35
+ value = value.to_i
36
+ elsif value =~ /\A\d+\.\d+\z/
37
+ value = value.to_f
38
+ end
39
+ end
40
+ end
41
+ value = Blazer.transform_variable.call(var, value) if Blazer.transform_variable
42
+ @values[var] = value
43
+ end
44
+ end
45
+
46
+ def cohort_analysis?
47
+ /\/\*\s*cohort analysis\s*\*\//i.match?(statement)
48
+ end
49
+
50
+ def apply_cohort_analysis(period:, days:)
51
+ @statement = data_source.cohort_analysis_statement(statement, period: period, days: days).sub("{placeholder}") { statement }
52
+ end
53
+
54
+ # should probably transform before cohort analysis
55
+ # but keep previous order for now
56
+ def transformed_statement
57
+ statement = self.statement.dup
58
+ Blazer.transform_statement.call(data_source, statement) if Blazer.transform_statement
59
+ statement
60
+ end
61
+
62
+ def bind
63
+ @bind_statement, @bind_values = data_source.bind_params(transformed_statement, values)
64
+ end
65
+
66
+ def display_statement
67
+ data_source.sub_variables(transformed_statement, values)
68
+ end
69
+
70
+ def clear_cache
71
+ bind if bind_statement.nil?
72
+ data_source.clear_cache(self)
73
+ end
74
+ end
75
+ end
@@ -1,3 +1,3 @@
1
1
  module Blazer
2
- VERSION = "2.5.0"
2
+ VERSION = "2.6.4"
3
3
  end
data/lib/blazer.rb CHANGED
@@ -1,14 +1,18 @@
1
1
  # dependencies
2
- require "csv"
3
- require "yaml"
4
2
  require "chartkick"
5
3
  require "safely/core"
6
4
 
5
+ # stdlib
6
+ require "csv"
7
+ require "json"
8
+ require "yaml"
9
+
7
10
  # modules
8
11
  require "blazer/version"
9
12
  require "blazer/data_source"
10
13
  require "blazer/result"
11
14
  require "blazer/run_statement"
15
+ require "blazer/statement"
12
16
 
13
17
  # adapters
14
18
  require "blazer/adapters/base_adapter"
@@ -43,6 +47,8 @@ module Blazer
43
47
  autoload :CheckMailer, "blazer/check_mailer"
44
48
  # net/http optional
45
49
  autoload :SlackNotifier, "blazer/slack_notifier"
50
+ # activejob optional
51
+ autoload :RunStatementJob, "blazer/run_statement_job"
46
52
 
47
53
  class << self
48
54
  attr_accessor :audit
@@ -76,6 +82,7 @@ module Blazer
76
82
  self.images = false
77
83
  self.override_csp = false
78
84
 
85
+ VARIABLE_MESSAGE = "Variable cannot be used in this position"
79
86
  TIMEOUT_MESSAGE = "Query timed out :("
80
87
  TIMEOUT_ERRORS = [
81
88
  "canceling statement due to statement timeout", # postgres
@@ -128,6 +135,7 @@ module Blazer
128
135
  end
129
136
  end
130
137
 
138
+ # TODO move to Statement and remove in 3.0.0
131
139
  def self.extract_vars(statement)
132
140
  # strip commented out lines
133
141
  # and regex {1} or {1,2}
@@ -148,9 +156,8 @@ module Blazer
148
156
 
149
157
  ActiveSupport::Notifications.instrument("run_check.blazer", check_id: check.id, query_id: check.query.id, state_was: check.state) do |instrument|
150
158
  # try 3 times on timeout errors
151
- data_source = data_sources[check.query.data_source]
152
- statement = check.query.statement
153
- Blazer.transform_statement.call(data_source, statement) if Blazer.transform_statement
159
+ statement = check.query.statement_object
160
+ data_source = statement.data_source
154
161
 
155
162
  while tries <= 3
156
163
  result = data_source.run_statement(statement, refresh_cache: true, check: check, query: check.query)
@@ -178,7 +185,8 @@ module Blazer
178
185
  # TODO use proper logfmt
179
186
  Rails.logger.info "[blazer check] query=#{check.query.name} state=#{check.state} rows=#{result.rows.try(:size)} error=#{result.error}"
180
187
 
181
- instrument[:statement] = statement
188
+ # should be no variables
189
+ instrument[:statement] = statement.bind_statement
182
190
  instrument[:data_source] = data_source
183
191
  instrument[:state] = check.state
184
192
  instrument[:rows] = result.rows.try(:size)
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: blazer
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.5.0
4
+ version: 2.6.4
5
5
  platform: ruby
6
6
  authors:
7
7
  - Andrew Kane
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2022-01-05 00:00:00.000000000 Z
11
+ date: 2022-05-25 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: railties
@@ -109,7 +109,9 @@ files:
109
109
  - app/assets/javascripts/blazer/stupidtable.js
110
110
  - app/assets/javascripts/blazer/vue.js
111
111
  - app/assets/stylesheets/blazer/application.css
112
- - app/assets/stylesheets/blazer/bootstrap.css.erb
112
+ - app/assets/stylesheets/blazer/bootstrap-propshaft.css
113
+ - app/assets/stylesheets/blazer/bootstrap-sprockets.css.erb
114
+ - app/assets/stylesheets/blazer/bootstrap.css
113
115
  - app/assets/stylesheets/blazer/daterangepicker.css
114
116
  - app/assets/stylesheets/blazer/github.css
115
117
  - app/assets/stylesheets/blazer/selectize.css
@@ -184,6 +186,7 @@ files:
184
186
  - lib/blazer/run_statement.rb
185
187
  - lib/blazer/run_statement_job.rb
186
188
  - lib/blazer/slack_notifier.rb
189
+ - lib/blazer/statement.rb
187
190
  - lib/blazer/version.rb
188
191
  - lib/generators/blazer/install_generator.rb
189
192
  - lib/generators/blazer/templates/config.yml.tt
@@ -226,7 +229,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
226
229
  - !ruby/object:Gem::Version
227
230
  version: '0'
228
231
  requirements: []
229
- rubygems_version: 3.2.32
232
+ rubygems_version: 3.3.7
230
233
  signing_key:
231
234
  specification_version: 4
232
235
  summary: Explore your data with SQL. Easily create charts and dashboards, and share