blazer 2.2.8 → 2.4.2
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.
- checksums.yaml +4 -4
- data/CHANGELOG.md +25 -0
- data/LICENSE.txt +1 -1
- data/README.md +131 -168
- data/app/assets/stylesheets/blazer/application.css +4 -0
- data/app/controllers/blazer/base_controller.rb +8 -0
- data/app/controllers/blazer/dashboards_controller.rb +2 -0
- data/app/controllers/blazer/queries_controller.rb +119 -3
- data/app/controllers/blazer/uploads_controller.rb +147 -0
- data/app/models/blazer/query.rb +9 -2
- data/app/models/blazer/upload.rb +11 -0
- data/app/models/blazer/uploads_connection.rb +7 -0
- data/app/views/blazer/_nav.html.erb +3 -0
- data/app/views/blazer/checks/_form.html.erb +1 -1
- data/app/views/blazer/checks/index.html.erb +3 -0
- data/app/views/blazer/dashboards/_form.html.erb +1 -1
- data/app/views/blazer/dashboards/show.html.erb +1 -1
- data/app/views/blazer/queries/_caching.html.erb +16 -0
- data/app/views/blazer/queries/_cohorts.html.erb +48 -0
- data/app/views/blazer/queries/docs.html.erb +6 -0
- data/app/views/blazer/queries/home.html.erb +3 -0
- data/app/views/blazer/queries/run.html.erb +15 -17
- data/app/views/blazer/queries/show.html.erb +1 -1
- data/app/views/blazer/uploads/_form.html.erb +27 -0
- data/app/views/blazer/uploads/edit.html.erb +3 -0
- data/app/views/blazer/uploads/index.html.erb +55 -0
- data/app/views/blazer/uploads/new.html.erb +3 -0
- data/config/routes.rb +5 -0
- data/lib/blazer.rb +24 -0
- data/lib/blazer/adapters/base_adapter.rb +8 -0
- data/lib/blazer/adapters/druid_adapter.rb +3 -3
- data/lib/blazer/adapters/hive_adapter.rb +45 -0
- data/lib/blazer/adapters/ignite_adapter.rb +54 -0
- data/lib/blazer/adapters/spark_adapter.rb +9 -0
- data/lib/blazer/adapters/sql_adapter.rb +64 -1
- data/lib/blazer/data_source.rb +2 -2
- data/lib/blazer/version.rb +1 -1
- data/lib/generators/blazer/templates/config.yml.tt +6 -0
- data/lib/generators/blazer/templates/install.rb.tt +1 -0
- data/lib/generators/blazer/templates/uploads.rb.tt +10 -0
- data/lib/generators/blazer/uploads_generator.rb +18 -0
- data/lib/tasks/blazer.rake +9 -0
- metadata +18 -32
|
@@ -27,7 +27,7 @@ module Blazer
|
|
|
27
27
|
result = select_all("#{statement} /*#{comment}*/")
|
|
28
28
|
columns = result.columns
|
|
29
29
|
result.rows.each do |untyped_row|
|
|
30
|
-
rows << (result.column_types.empty? ? untyped_row : columns.each_with_index.map { |c, i| untyped_row[i] ? result.column_types[c].send(:cast_value, untyped_row[i]) : untyped_row[i] })
|
|
30
|
+
rows << (result.column_types.empty? ? untyped_row : columns.each_with_index.map { |c, i| untyped_row[i] && result.column_types[c] ? result.column_types[c].send(:cast_value, untyped_row[i]) : untyped_row[i] })
|
|
31
31
|
end
|
|
32
32
|
end
|
|
33
33
|
rescue => e
|
|
@@ -122,6 +122,67 @@ module Blazer
|
|
|
122
122
|
!%w[CREATE ALTER UPDATE INSERT DELETE].include?(statement.split.first.to_s.upcase)
|
|
123
123
|
end
|
|
124
124
|
|
|
125
|
+
def supports_cohort_analysis?
|
|
126
|
+
postgresql? || mysql?
|
|
127
|
+
end
|
|
128
|
+
|
|
129
|
+
# TODO treat date columns as already in time zone
|
|
130
|
+
def cohort_analysis_statement(statement, period:, days:)
|
|
131
|
+
raise "Cohort analysis not supported" unless supports_cohort_analysis?
|
|
132
|
+
|
|
133
|
+
cohort_column = statement =~ /\bcohort_time\b/ ? "cohort_time" : "conversion_time"
|
|
134
|
+
tzname = Blazer.time_zone.tzinfo.name
|
|
135
|
+
|
|
136
|
+
if mysql?
|
|
137
|
+
time_sql = "CONVERT_TZ(cohorts.cohort_time, '+00:00', ?)"
|
|
138
|
+
case period
|
|
139
|
+
when "day"
|
|
140
|
+
date_sql = "CAST(DATE_FORMAT(#{time_sql}, '%Y-%m-%d') AS DATE)"
|
|
141
|
+
date_params = [tzname]
|
|
142
|
+
when "week"
|
|
143
|
+
date_sql = "CAST(DATE_FORMAT(#{time_sql} - INTERVAL ((5 + DAYOFWEEK(#{time_sql})) % 7) DAY, '%Y-%m-%d') AS DATE)"
|
|
144
|
+
date_params = [tzname, tzname]
|
|
145
|
+
else
|
|
146
|
+
date_sql = "CAST(DATE_FORMAT(#{time_sql}, '%Y-%m-01') AS DATE)"
|
|
147
|
+
date_params = [tzname]
|
|
148
|
+
end
|
|
149
|
+
bucket_sql = "CAST(CEIL(TIMESTAMPDIFF(SECOND, cohorts.cohort_time, query.conversion_time) / ?) AS INTEGER)"
|
|
150
|
+
else
|
|
151
|
+
date_sql = "date_trunc(?, cohorts.cohort_time::timestamptz AT TIME ZONE ?)::date"
|
|
152
|
+
date_params = [period, tzname]
|
|
153
|
+
bucket_sql = "CEIL(EXTRACT(EPOCH FROM query.conversion_time - cohorts.cohort_time) / ?)::int"
|
|
154
|
+
end
|
|
155
|
+
|
|
156
|
+
# WITH not an optimization fence in Postgres 12+
|
|
157
|
+
statement = <<~SQL
|
|
158
|
+
WITH query AS (
|
|
159
|
+
#{statement}
|
|
160
|
+
),
|
|
161
|
+
cohorts AS (
|
|
162
|
+
SELECT user_id, MIN(#{cohort_column}) AS cohort_time FROM query
|
|
163
|
+
WHERE user_id IS NOT NULL AND #{cohort_column} IS NOT NULL
|
|
164
|
+
GROUP BY 1
|
|
165
|
+
)
|
|
166
|
+
SELECT
|
|
167
|
+
#{date_sql} AS period,
|
|
168
|
+
0 AS bucket,
|
|
169
|
+
COUNT(DISTINCT cohorts.user_id)
|
|
170
|
+
FROM cohorts GROUP BY 1
|
|
171
|
+
UNION ALL
|
|
172
|
+
SELECT
|
|
173
|
+
#{date_sql} AS period,
|
|
174
|
+
#{bucket_sql} AS bucket,
|
|
175
|
+
COUNT(DISTINCT query.user_id)
|
|
176
|
+
FROM cohorts INNER JOIN query ON query.user_id = cohorts.user_id
|
|
177
|
+
WHERE query.conversion_time IS NOT NULL
|
|
178
|
+
AND query.conversion_time >= cohorts.cohort_time
|
|
179
|
+
#{cohort_column == "conversion_time" ? "AND query.conversion_time != cohorts.cohort_time" : ""}
|
|
180
|
+
GROUP BY 1, 2
|
|
181
|
+
SQL
|
|
182
|
+
params = [statement] + date_params + date_params + [days.to_i * 86400]
|
|
183
|
+
connection_model.send(:sanitize_sql_array, params)
|
|
184
|
+
end
|
|
185
|
+
|
|
125
186
|
protected
|
|
126
187
|
|
|
127
188
|
def select_all(statement, params = [])
|
|
@@ -165,6 +226,8 @@ module Blazer
|
|
|
165
226
|
"public"
|
|
166
227
|
elsif sqlserver?
|
|
167
228
|
"dbo"
|
|
229
|
+
elsif connection_model.respond_to?(:connection_db_config)
|
|
230
|
+
connection_model.connection_db_config.database
|
|
168
231
|
else
|
|
169
232
|
connection_model.connection_config[:database]
|
|
170
233
|
end
|
data/lib/blazer/data_source.rb
CHANGED
|
@@ -6,7 +6,7 @@ module Blazer
|
|
|
6
6
|
|
|
7
7
|
attr_reader :id, :settings
|
|
8
8
|
|
|
9
|
-
def_delegators :adapter_instance, :schema, :tables, :preview_statement, :reconnect, :cost, :explain, :cancel
|
|
9
|
+
def_delegators :adapter_instance, :schema, :tables, :preview_statement, :reconnect, :cost, :explain, :cancel, :supports_cohort_analysis?, :cohort_analysis_statement
|
|
10
10
|
|
|
11
11
|
def initialize(id, settings)
|
|
12
12
|
@id = id
|
|
@@ -185,7 +185,7 @@ module Blazer
|
|
|
185
185
|
def detect_adapter
|
|
186
186
|
schema = settings["url"].to_s.split("://").first
|
|
187
187
|
case schema
|
|
188
|
-
when "mongodb", "presto", "cassandra"
|
|
188
|
+
when "mongodb", "presto", "cassandra", "ignite"
|
|
189
189
|
schema
|
|
190
190
|
else
|
|
191
191
|
"sql"
|
data/lib/blazer/version.rb
CHANGED
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
require "rails/generators/active_record"
|
|
2
|
+
|
|
3
|
+
module Blazer
|
|
4
|
+
module Generators
|
|
5
|
+
class UploadsGenerator < Rails::Generators::Base
|
|
6
|
+
include ActiveRecord::Generators::Migration
|
|
7
|
+
source_root File.join(__dir__, "templates")
|
|
8
|
+
|
|
9
|
+
def copy_migration
|
|
10
|
+
migration_template "uploads.rb", "db/migrate/create_blazer_uploads.rb", migration_version: migration_version
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
def migration_version
|
|
14
|
+
"[#{ActiveRecord::VERSION::MAJOR}.#{ActiveRecord::VERSION::MINOR}]"
|
|
15
|
+
end
|
|
16
|
+
end
|
|
17
|
+
end
|
|
18
|
+
end
|
data/lib/tasks/blazer.rake
CHANGED
|
@@ -8,4 +8,13 @@ namespace :blazer do
|
|
|
8
8
|
task send_failing_checks: :environment do
|
|
9
9
|
Blazer.send_failing_checks
|
|
10
10
|
end
|
|
11
|
+
|
|
12
|
+
desc "archive queries"
|
|
13
|
+
task archive_queries: :environment do
|
|
14
|
+
abort "Audits must be enabled to archive" unless Blazer.audit
|
|
15
|
+
abort "Missing status column - see https://github.com/ankane/blazer#23" unless Blazer::Query.column_names.include?("status")
|
|
16
|
+
|
|
17
|
+
viewed_query_ids = Blazer::Audit.where("created_at > ?", 90.days.ago).group(:query_id).count.keys.compact
|
|
18
|
+
Blazer::Query.active.where.not(id: viewed_query_ids).update_all(status: "archived")
|
|
19
|
+
end
|
|
11
20
|
end
|
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.2
|
|
4
|
+
version: 2.4.2
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Andrew Kane
|
|
8
8
|
autorequire:
|
|
9
9
|
bindir: bin
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date:
|
|
11
|
+
date: 2021-02-09 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: railties
|
|
@@ -66,36 +66,8 @@ dependencies:
|
|
|
66
66
|
- - ">="
|
|
67
67
|
- !ruby/object:Gem::Version
|
|
68
68
|
version: 0.1.1
|
|
69
|
-
- !ruby/object:Gem::Dependency
|
|
70
|
-
name: bundler
|
|
71
|
-
requirement: !ruby/object:Gem::Requirement
|
|
72
|
-
requirements:
|
|
73
|
-
- - ">="
|
|
74
|
-
- !ruby/object:Gem::Version
|
|
75
|
-
version: '0'
|
|
76
|
-
type: :development
|
|
77
|
-
prerelease: false
|
|
78
|
-
version_requirements: !ruby/object:Gem::Requirement
|
|
79
|
-
requirements:
|
|
80
|
-
- - ">="
|
|
81
|
-
- !ruby/object:Gem::Version
|
|
82
|
-
version: '0'
|
|
83
|
-
- !ruby/object:Gem::Dependency
|
|
84
|
-
name: rake
|
|
85
|
-
requirement: !ruby/object:Gem::Requirement
|
|
86
|
-
requirements:
|
|
87
|
-
- - ">="
|
|
88
|
-
- !ruby/object:Gem::Version
|
|
89
|
-
version: '0'
|
|
90
|
-
type: :development
|
|
91
|
-
prerelease: false
|
|
92
|
-
version_requirements: !ruby/object:Gem::Requirement
|
|
93
|
-
requirements:
|
|
94
|
-
- - ">="
|
|
95
|
-
- !ruby/object:Gem::Version
|
|
96
|
-
version: '0'
|
|
97
69
|
description:
|
|
98
|
-
email: andrew@
|
|
70
|
+
email: andrew@ankane.org
|
|
99
71
|
executables: []
|
|
100
72
|
extensions: []
|
|
101
73
|
extra_rdoc_files: []
|
|
@@ -145,6 +117,7 @@ files:
|
|
|
145
117
|
- app/controllers/blazer/checks_controller.rb
|
|
146
118
|
- app/controllers/blazer/dashboards_controller.rb
|
|
147
119
|
- app/controllers/blazer/queries_controller.rb
|
|
120
|
+
- app/controllers/blazer/uploads_controller.rb
|
|
148
121
|
- app/helpers/blazer/base_helper.rb
|
|
149
122
|
- app/mailers/blazer/check_mailer.rb
|
|
150
123
|
- app/mailers/blazer/slack_notifier.rb
|
|
@@ -155,6 +128,8 @@ files:
|
|
|
155
128
|
- app/models/blazer/dashboard_query.rb
|
|
156
129
|
- app/models/blazer/query.rb
|
|
157
130
|
- app/models/blazer/record.rb
|
|
131
|
+
- app/models/blazer/upload.rb
|
|
132
|
+
- app/models/blazer/uploads_connection.rb
|
|
158
133
|
- app/views/blazer/_nav.html.erb
|
|
159
134
|
- app/views/blazer/_variables.html.erb
|
|
160
135
|
- app/views/blazer/check_mailer/failing_checks.html.erb
|
|
@@ -167,6 +142,8 @@ files:
|
|
|
167
142
|
- app/views/blazer/dashboards/edit.html.erb
|
|
168
143
|
- app/views/blazer/dashboards/new.html.erb
|
|
169
144
|
- app/views/blazer/dashboards/show.html.erb
|
|
145
|
+
- app/views/blazer/queries/_caching.html.erb
|
|
146
|
+
- app/views/blazer/queries/_cohorts.html.erb
|
|
170
147
|
- app/views/blazer/queries/_form.html.erb
|
|
171
148
|
- app/views/blazer/queries/docs.html.erb
|
|
172
149
|
- app/views/blazer/queries/edit.html.erb
|
|
@@ -175,6 +152,10 @@ files:
|
|
|
175
152
|
- app/views/blazer/queries/run.html.erb
|
|
176
153
|
- app/views/blazer/queries/schema.html.erb
|
|
177
154
|
- app/views/blazer/queries/show.html.erb
|
|
155
|
+
- app/views/blazer/uploads/_form.html.erb
|
|
156
|
+
- app/views/blazer/uploads/edit.html.erb
|
|
157
|
+
- app/views/blazer/uploads/index.html.erb
|
|
158
|
+
- app/views/blazer/uploads/new.html.erb
|
|
178
159
|
- app/views/layouts/blazer/application.html.erb
|
|
179
160
|
- config/routes.rb
|
|
180
161
|
- lib/blazer.rb
|
|
@@ -185,6 +166,8 @@ files:
|
|
|
185
166
|
- lib/blazer/adapters/drill_adapter.rb
|
|
186
167
|
- lib/blazer/adapters/druid_adapter.rb
|
|
187
168
|
- lib/blazer/adapters/elasticsearch_adapter.rb
|
|
169
|
+
- lib/blazer/adapters/hive_adapter.rb
|
|
170
|
+
- lib/blazer/adapters/ignite_adapter.rb
|
|
188
171
|
- lib/blazer/adapters/influxdb_adapter.rb
|
|
189
172
|
- lib/blazer/adapters/mongodb_adapter.rb
|
|
190
173
|
- lib/blazer/adapters/neo4j_adapter.rb
|
|
@@ -192,6 +175,7 @@ files:
|
|
|
192
175
|
- lib/blazer/adapters/salesforce_adapter.rb
|
|
193
176
|
- lib/blazer/adapters/snowflake_adapter.rb
|
|
194
177
|
- lib/blazer/adapters/soda_adapter.rb
|
|
178
|
+
- lib/blazer/adapters/spark_adapter.rb
|
|
195
179
|
- lib/blazer/adapters/sql_adapter.rb
|
|
196
180
|
- lib/blazer/data_source.rb
|
|
197
181
|
- lib/blazer/detect_anomalies.R
|
|
@@ -203,6 +187,8 @@ files:
|
|
|
203
187
|
- lib/generators/blazer/install_generator.rb
|
|
204
188
|
- lib/generators/blazer/templates/config.yml.tt
|
|
205
189
|
- lib/generators/blazer/templates/install.rb.tt
|
|
190
|
+
- lib/generators/blazer/templates/uploads.rb.tt
|
|
191
|
+
- lib/generators/blazer/uploads_generator.rb
|
|
206
192
|
- lib/tasks/blazer.rake
|
|
207
193
|
- licenses/LICENSE-ace.txt
|
|
208
194
|
- licenses/LICENSE-bootstrap.txt
|
|
@@ -239,7 +225,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
|
239
225
|
- !ruby/object:Gem::Version
|
|
240
226
|
version: '0'
|
|
241
227
|
requirements: []
|
|
242
|
-
rubygems_version: 3.
|
|
228
|
+
rubygems_version: 3.2.3
|
|
243
229
|
signing_key:
|
|
244
230
|
specification_version: 4
|
|
245
231
|
summary: Explore your data with SQL. Easily create charts and dashboards, and share
|