blazer 2.4.2 → 2.4.6

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.

Potentially problematic release.


This version of blazer might be problematic. Click here for more details.

@@ -71,7 +71,7 @@ module Blazer
71
71
  @sql_errors << error if error
72
72
  end
73
73
 
74
- @query.update!(status: "active") if @query.try(:status) == "archived"
74
+ @query.update!(status: "active") if @query.respond_to?(:status) && @query.status.in?(["archived", nil])
75
75
 
76
76
  Blazer.transform_statement.call(data_source, @statement) if Blazer.transform_statement
77
77
 
@@ -180,6 +180,7 @@ module Blazer
180
180
  @query = Blazer::Query.new
181
181
  @query.creator = blazer_user if @query.respond_to?(:creator)
182
182
  end
183
+ @query.status = "active" if @query.respond_to?(:status)
183
184
  unless @query.editable?(blazer_user)
184
185
  @query.errors.add(:base, "Sorry, permission denied")
185
186
  end
@@ -8,7 +8,7 @@ module Blazer
8
8
 
9
9
  validates :statement, presence: true
10
10
 
11
- scope :active, -> { column_names.include?("status") ? where(status: "active") : all }
11
+ scope :active, -> { column_names.include?("status") ? where(status: ["active", nil]) : all }
12
12
  scope :named, -> { where.not(name: "") }
13
13
 
14
14
  def to_param
@@ -8,19 +8,25 @@ module Blazer
8
8
  rows = []
9
9
  error = nil
10
10
 
11
+ query_options = {
12
+ query_string: statement,
13
+ # use token so we fetch cached results after query is run
14
+ client_request_token: Digest::MD5.hexdigest([statement, data_source.id, settings["workgroup"]].compact.join("/")),
15
+ query_execution_context: {
16
+ database: database,
17
+ }
18
+ }
19
+
20
+ if settings["output_location"]
21
+ query_options[:result_configuration] = {output_location: settings["output_location"]}
22
+ end
23
+
24
+ if settings["workgroup"]
25
+ query_options[:work_group] = settings["workgroup"]
26
+ end
27
+
11
28
  begin
12
- resp =
13
- client.start_query_execution(
14
- query_string: statement,
15
- # use token so we fetch cached results after query is run
16
- client_request_token: Digest::MD5.hexdigest([statement,data_source.id].join("/")),
17
- query_execution_context: {
18
- database: database,
19
- },
20
- result_configuration: {
21
- output_location: settings["output_location"]
22
- }
23
- )
29
+ resp = client.start_query_execution(**query_options)
24
30
  query_execution_id = resp.query_execution_id
25
31
 
26
32
  timeout = data_source.timeout || 300
@@ -60,21 +66,21 @@ module Blazer
60
66
  column_types.each_with_index do |ct, i|
61
67
  # TODO more column_types
62
68
  case ct
63
- when "timestamp"
69
+ when "timestamp", "timestamp with time zone"
64
70
  rows.each do |row|
65
- row[i] = utc.parse(row[i])
71
+ row[i] &&= utc.parse(row[i])
66
72
  end
67
73
  when "date"
68
74
  rows.each do |row|
69
- row[i] = Date.parse(row[i])
75
+ row[i] &&= Date.parse(row[i])
70
76
  end
71
77
  when "bigint"
72
78
  rows.each do |row|
73
- row[i] = row[i].to_i
79
+ row[i] &&= row[i].to_i
74
80
  end
75
81
  when "double"
76
82
  rows.each do |row|
77
- row[i] = row[i].to_f
83
+ row[i] &&= row[i].to_f
78
84
  end
79
85
  end
80
86
  end
@@ -118,11 +124,21 @@ module Blazer
118
124
  end
119
125
 
120
126
  def client
121
- @client ||= Aws::Athena::Client.new
127
+ @client ||= Aws::Athena::Client.new(**client_options)
122
128
  end
123
129
 
124
130
  def glue
125
- @glue ||= Aws::Glue::Client.new
131
+ @glue ||= Aws::Glue::Client.new(**client_options)
132
+ end
133
+
134
+ def client_options
135
+ @client_options ||= begin
136
+ if settings["access_key_id"] || settings["secret_access_key"]
137
+ {credentials: Aws::Credentials.new(settings["access_key_id"], settings["secret_access_key"])}
138
+ else
139
+ {}
140
+ end
141
+ end
126
142
  end
127
143
  end
128
144
  end
@@ -13,7 +13,7 @@ module Blazer
13
13
  # code is for backward compatibility
14
14
  if !results.respond_to?(:complete?) || results.complete?
15
15
  columns = results.first.keys.map(&:to_s) if results.size > 0
16
- rows = results.map(&:values)
16
+ rows = results.all.map(&:values)
17
17
  else
18
18
  error = Blazer::TIMEOUT_MESSAGE
19
19
  end
@@ -144,6 +144,7 @@ module Blazer
144
144
 
145
145
  def adapter_instance
146
146
  @adapter_instance ||= begin
147
+ # TODO add required settings to adapters
147
148
  unless settings["url"] || Rails.env.development? || ["bigquery", "athena", "snowflake", "salesforce"].include?(settings["adapter"])
148
149
  raise Blazer::Error, "Empty url for data source: #{id}"
149
150
  end
@@ -182,11 +183,12 @@ module Blazer
182
183
  Blazer::Result.new(self, columns, rows, error, nil, cache && !cache_data.nil?)
183
184
  end
184
185
 
186
+ # TODO check for adapter with same name, default to sql
185
187
  def detect_adapter
186
- schema = settings["url"].to_s.split("://").first
187
- case schema
188
+ scheme = settings["url"].to_s.split("://").first
189
+ case scheme
188
190
  when "mongodb", "presto", "cassandra", "ignite"
189
- schema
191
+ scheme
190
192
  else
191
193
  "sql"
192
194
  end
data/lib/blazer/result.rb CHANGED
@@ -174,7 +174,19 @@ module Blazer
174
174
  def anomaly?(series)
175
175
  series = series.reject { |v| v[0].nil? }.sort_by { |v| v[0] }
176
176
 
177
- if Blazer.anomaly_checks == "trend"
177
+ case Blazer.anomaly_checks
178
+ when "prophet"
179
+ df = Rover::DataFrame.new(series[0..-2].map { |v| {"ds" => v[0], "y" => v[1]} })
180
+ m = Prophet.new(interval_width: 0.99)
181
+ m.logger.level = ::Logger::FATAL # no logging
182
+ m.fit(df)
183
+ future = Rover::DataFrame.new(series[-1..-1].map { |v| {"ds" => v[0]} })
184
+ forecast = m.predict(future).to_a[0]
185
+ lower = forecast["yhat_lower"]
186
+ upper = forecast["yhat_upper"]
187
+ value = series.last[1]
188
+ value < lower || value > upper
189
+ when "trend"
178
190
  anomalies = Trend.anomalies(Hash[series])
179
191
  anomalies.include?(series.last[0])
180
192
  else
@@ -1,3 +1,3 @@
1
1
  module Blazer
2
- VERSION = "2.4.2"
2
+ VERSION = "2.4.6"
3
3
  end
@@ -63,11 +63,11 @@ check_schedules:
63
63
 
64
64
  # enable anomaly detection
65
65
  # note: with trend, time series are sent to https://trendapi.org
66
- # anomaly_checks: trend / r
66
+ # anomaly_checks: prophet / trend / r
67
67
 
68
68
  # enable forecasting
69
69
  # note: with trend, time series are sent to https://trendapi.org
70
- # forecasting: trend / prophet
70
+ # forecasting: prophet / trend
71
71
 
72
72
  # enable map
73
73
  # mapbox_access_token: <%%= ENV["MAPBOX_ACCESS_TOKEN"] %>
@@ -1,6 +1,6 @@
1
1
  The MIT License (MIT)
2
2
 
3
- Copyright (c) 2011-2016 Twitter, Inc.
3
+ Copyright (c) 2011-2019 Twitter, Inc.
4
4
 
5
5
  Permission is hereby granted, free of charge, to any person obtaining a copy
6
6
  of this software and associated documentation files (the "Software"), to deal
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.4.2
4
+ version: 2.4.6
5
5
  platform: ruby
6
6
  authors:
7
7
  - Andrew Kane
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2021-02-09 00:00:00.000000000 Z
11
+ date: 2021-09-21 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: railties
@@ -225,7 +225,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
225
225
  - !ruby/object:Gem::Version
226
226
  version: '0'
227
227
  requirements: []
228
- rubygems_version: 3.2.3
228
+ rubygems_version: 3.2.22
229
229
  signing_key:
230
230
  specification_version: 4
231
231
  summary: Explore your data with SQL. Easily create charts and dashboards, and share