blazer 2.1.0 → 2.2.0
Sign up to get free protection for your applications and to get access to all the features.
Potentially problematic release.
This version of blazer might be problematic. Click here for more details.
- checksums.yaml +4 -4
- data/CHANGELOG.md +7 -1
- data/app/controllers/blazer/base_controller.rb +3 -7
- data/app/models/blazer/audit.rb +2 -2
- data/app/models/blazer/check.rb +3 -3
- data/app/models/blazer/dashboard.rb +1 -1
- data/app/models/blazer/query.rb +1 -1
- data/app/views/blazer/queries/_form.html.erb +6 -1
- data/app/views/blazer/queries/schema.html.erb +1 -4
- data/lib/blazer.rb +0 -2
- data/lib/blazer/adapters/sql_adapter.rb +46 -20
- data/lib/blazer/version.rb +1 -1
- data/lib/generators/blazer/install_generator.rb +3 -20
- metadata +8 -8
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: dac159313b83f05cfa2b39da88d889b08e0089a75047a6aff43c24d735b86eb2
|
4
|
+
data.tar.gz: e1d3594c4e957f04ffa575ce1aac36abf29586c275a2c402c2da5b9401356c57
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 05a6d614fd96a40526f0ef7bb34cf6207a48e7bcdb6495f7ea925bec919c116918ad721d388e856c388d6746033fd184eadf25ca93a4afb9c541a8ab8758f8e1
|
7
|
+
data.tar.gz: 79e9087b9e4015cd866fe2b382f0bb015c104af05f9c8b1c209ce2aa06713a46436e2aa307a9901bf0d31fec861463f1224b0cc610d76e2dd5c9c12aa40a8807
|
data/CHANGELOG.md
CHANGED
@@ -1,6 +1,12 @@
|
|
1
|
+
## 2.2.0
|
2
|
+
|
3
|
+
- Added schema to table preview for Postgres and Redshift
|
4
|
+
- Fixed bug with Slack notifications not sending
|
5
|
+
- Dropped support for Rails 4.2
|
6
|
+
|
1
7
|
## 2.1.0
|
2
8
|
|
3
|
-
-
|
9
|
+
- Require latest Chartkick to prevent possible XSS - see [#245](https://github.com/ankane/blazer/issues/245)
|
4
10
|
|
5
11
|
## 2.0.2
|
6
12
|
|
@@ -2,13 +2,9 @@ module Blazer
|
|
2
2
|
class BaseController < ApplicationController
|
3
3
|
# skip filters
|
4
4
|
filters = _process_action_callbacks.map(&:filter) - [:activate_authlogic]
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
skip_around_action(*filters, raise: false)
|
9
|
-
else
|
10
|
-
skip_action_callback(*filters)
|
11
|
-
end
|
5
|
+
skip_before_action(*filters, raise: false)
|
6
|
+
skip_after_action(*filters, raise: false)
|
7
|
+
skip_around_action(*filters, raise: false)
|
12
8
|
|
13
9
|
protect_from_forgery with: :exception
|
14
10
|
|
data/app/models/blazer/audit.rb
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
module Blazer
|
2
2
|
class Audit < Record
|
3
|
-
belongs_to :user,
|
4
|
-
belongs_to :query,
|
3
|
+
belongs_to :user, optional: true, class_name: Blazer.user_class.to_s
|
4
|
+
belongs_to :query, optional: true
|
5
5
|
end
|
6
6
|
end
|
data/app/models/blazer/check.rb
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
module Blazer
|
2
2
|
class Check < Record
|
3
|
-
belongs_to :creator,
|
3
|
+
belongs_to :creator, optional: true, class_name: Blazer.user_class.to_s if Blazer.user_class
|
4
4
|
belongs_to :query
|
5
5
|
|
6
6
|
validates :query_id, presence: true
|
@@ -67,8 +67,8 @@ module Blazer
|
|
67
67
|
end
|
68
68
|
|
69
69
|
# do not notify on creation, except when not passing
|
70
|
-
if (state_was != "new" || state != "passing") && state != state_was
|
71
|
-
Blazer::CheckMailer.state_change(self, state, state_was, result.rows.size, message, result.columns, result.rows.first(10).as_json, result.column_types, check_type).deliver_now
|
70
|
+
if (state_was != "new" || state != "passing") && state != state_was
|
71
|
+
Blazer::CheckMailer.state_change(self, state, state_was, result.rows.size, message, result.columns, result.rows.first(10).as_json, result.column_types, check_type).deliver_now if emails.present?
|
72
72
|
Blazer::SlackNotifier.state_change(self, state, state_was, result.rows.size, message, check_type)
|
73
73
|
end
|
74
74
|
save! if changed?
|
@@ -1,6 +1,6 @@
|
|
1
1
|
module Blazer
|
2
2
|
class Dashboard < Record
|
3
|
-
belongs_to :creator,
|
3
|
+
belongs_to :creator, optional: true, class_name: Blazer.user_class.to_s if Blazer.user_class
|
4
4
|
has_many :dashboard_queries, dependent: :destroy
|
5
5
|
has_many :queries, through: :dashboard_queries
|
6
6
|
|
data/app/models/blazer/query.rb
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
module Blazer
|
2
2
|
class Query < Record
|
3
|
-
belongs_to :creator,
|
3
|
+
belongs_to :creator, optional: true, class_name: Blazer.user_class.to_s if Blazer.user_class
|
4
4
|
has_many :checks, dependent: :destroy
|
5
5
|
has_many :dashboard_queries, dependent: :destroy
|
6
6
|
has_many :dashboards, through: :dashboard_queries
|
@@ -132,7 +132,12 @@
|
|
132
132
|
this.tablesXhr = $.getJSON(Routes.tables_queries_path({data_source: this.dataSource}), function(data) {
|
133
133
|
var newOptions = []
|
134
134
|
for (var i = 0; i < data.length; i++) {
|
135
|
-
|
135
|
+
var table = data[i]
|
136
|
+
if (typeof table === "object") {
|
137
|
+
newOptions.push({text: table.table, value: table.value})
|
138
|
+
} else {
|
139
|
+
newOptions.push({text: table, value: table})
|
140
|
+
}
|
136
141
|
}
|
137
142
|
selectize.clearOptions()
|
138
143
|
selectize.addOption(newOptions)
|
@@ -13,10 +13,7 @@
|
|
13
13
|
<thead>
|
14
14
|
<tr>
|
15
15
|
<th colspan="2">
|
16
|
-
|
17
|
-
<% if table[:schema] != "public" %>
|
18
|
-
<span class="text-muted" style="font-weight: normal;"><%= table[:schema] %></span>
|
19
|
-
<% end %>
|
16
|
+
<% if table[:schema] != "public" %><%= table[:schema] %>.<% end %><%= table[:table] %>
|
20
17
|
</th>
|
21
18
|
</tr>
|
22
19
|
</thead>
|
data/lib/blazer.rb
CHANGED
@@ -72,8 +72,6 @@ module Blazer
|
|
72
72
|
"system requested abort", # redshift
|
73
73
|
"maximum statement execution time exceeded" # mysql
|
74
74
|
]
|
75
|
-
BELONGS_TO_OPTIONAL = {}
|
76
|
-
BELONGS_TO_OPTIONAL[:optional] = true if Rails::VERSION::MAJOR >= 5
|
77
75
|
|
78
76
|
def self.time_zone=(time_zone)
|
79
77
|
@time_zone = time_zone.is_a?(ActiveSupport::TimeZone) ? time_zone : ActiveSupport::TimeZone[time_zone.to_s]
|
@@ -26,9 +26,8 @@ module Blazer
|
|
26
26
|
|
27
27
|
result = select_all("#{statement} /*#{comment}*/")
|
28
28
|
columns = result.columns
|
29
|
-
cast_method = Rails::VERSION::MAJOR < 5 ? :type_cast : :cast_value
|
30
29
|
result.rows.each do |untyped_row|
|
31
|
-
rows << (result.column_types.empty? ? untyped_row : columns.each_with_index.map { |c, i| untyped_row[i] ? result.column_types[c].send(
|
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] })
|
32
31
|
end
|
33
32
|
end
|
34
33
|
rescue => e
|
@@ -41,19 +40,35 @@ module Blazer
|
|
41
40
|
end
|
42
41
|
|
43
42
|
def tables
|
44
|
-
|
45
|
-
result.
|
43
|
+
sql = add_schemas("SELECT table_schema, table_name FROM information_schema.tables")
|
44
|
+
result = data_source.run_statement(sql, refresh_cache: true)
|
45
|
+
if postgresql? || redshift?
|
46
|
+
result.rows.sort_by { |r| [r[0] == default_schema ? "" : r[0], r[1]] }.map do |row|
|
47
|
+
table =
|
48
|
+
if row[0] == default_schema
|
49
|
+
row[1]
|
50
|
+
else
|
51
|
+
"#{row[0]}.#{row[1]}"
|
52
|
+
end
|
53
|
+
|
54
|
+
{
|
55
|
+
table: table,
|
56
|
+
value: connection_model.connection.quote_table_name(table)
|
57
|
+
}
|
58
|
+
end
|
59
|
+
else
|
60
|
+
result.rows.map(&:second).sort
|
61
|
+
end
|
46
62
|
end
|
47
63
|
|
48
64
|
def schema
|
49
|
-
|
50
|
-
result
|
65
|
+
sql = add_schemas("SELECT table_schema, table_name, column_name, data_type, ordinal_position FROM information_schema.columns")
|
66
|
+
result = data_source.run_statement(sql)
|
67
|
+
result.rows.group_by { |r| [r[0], r[1]] }.map { |k, vs| {schema: k[0], table: k[1], columns: vs.sort_by { |v| v[2] }.map { |v| {name: v[2], data_type: v[3]} }} }.sort_by { |t| [t[:schema] == default_schema ? "" : t[:schema], t[:table]] }
|
51
68
|
end
|
52
69
|
|
53
70
|
def preview_statement
|
54
|
-
if
|
55
|
-
"SELECT * FROM \"{table}\" LIMIT 10"
|
56
|
-
elsif sqlserver?
|
71
|
+
if sqlserver?
|
57
72
|
"SELECT TOP (10) * FROM {table}"
|
58
73
|
else
|
59
74
|
"SELECT * FROM {table} LIMIT 10"
|
@@ -92,9 +107,9 @@ module Blazer
|
|
92
107
|
|
93
108
|
def cancel(run_id)
|
94
109
|
if postgresql?
|
95
|
-
select_all("SELECT pg_cancel_backend(pid) FROM pg_stat_activity WHERE pid <> pg_backend_pid() AND query LIKE
|
110
|
+
select_all("SELECT pg_cancel_backend(pid) FROM pg_stat_activity WHERE pid <> pg_backend_pid() AND query LIKE ?", ["%,run_id:#{run_id}%"])
|
96
111
|
elsif redshift?
|
97
|
-
first_row = select_all("SELECT pid FROM stv_recents WHERE status = 'Running' AND query LIKE
|
112
|
+
first_row = select_all("SELECT pid FROM stv_recents WHERE status = 'Running' AND query LIKE ?", ["%,run_id:#{run_id}%"]).first
|
98
113
|
if first_row
|
99
114
|
select_all("CANCEL #{first_row["pid"].to_i}")
|
100
115
|
end
|
@@ -107,7 +122,8 @@ module Blazer
|
|
107
122
|
|
108
123
|
protected
|
109
124
|
|
110
|
-
def select_all(statement)
|
125
|
+
def select_all(statement, params = [])
|
126
|
+
statement = connection_model.send(:sanitize_sql_array, [statement] + params) if params.any?
|
111
127
|
connection_model.connection.select_all(statement)
|
112
128
|
end
|
113
129
|
|
@@ -137,18 +153,28 @@ module Blazer
|
|
137
153
|
connection_model.connection.adapter_name rescue nil
|
138
154
|
end
|
139
155
|
|
140
|
-
def
|
141
|
-
|
156
|
+
def default_schema
|
157
|
+
@default_schema ||= begin
|
158
|
+
if postgresql? || redshift?
|
159
|
+
"public"
|
160
|
+
elsif sqlserver?
|
161
|
+
"dbo"
|
162
|
+
else
|
163
|
+
connection_model.connection_config[:database]
|
164
|
+
end
|
165
|
+
end
|
142
166
|
end
|
143
167
|
|
144
|
-
def
|
145
|
-
if
|
146
|
-
"
|
147
|
-
|
148
|
-
"dbo"
|
168
|
+
def add_schemas(query)
|
169
|
+
if settings["schemas"]
|
170
|
+
where = "table_schema IN (?)"
|
171
|
+
schemas = settings["schemas"]
|
149
172
|
else
|
150
|
-
|
173
|
+
where = "table_schema NOT IN (?)"
|
174
|
+
schemas = ["information_schema"]
|
175
|
+
schemas << "pg_catalog" if postgresql? || redshift?
|
151
176
|
end
|
177
|
+
connection_model.send(:sanitize_sql_array, ["#{query} WHERE #{where}", schemas])
|
152
178
|
end
|
153
179
|
|
154
180
|
def set_timeout(timeout)
|
data/lib/blazer/version.rb
CHANGED
@@ -1,25 +1,10 @@
|
|
1
|
-
# taken from https://github.com/collectiveidea/audited/blob/master/lib/generators/audited/install_generator.rb
|
2
|
-
require "rails/generators"
|
3
|
-
require "rails/generators/migration"
|
4
|
-
require "active_record"
|
5
1
|
require "rails/generators/active_record"
|
6
2
|
|
7
3
|
module Blazer
|
8
4
|
module Generators
|
9
5
|
class InstallGenerator < Rails::Generators::Base
|
10
|
-
include
|
11
|
-
|
12
|
-
source_root File.expand_path("../templates", __FILE__)
|
13
|
-
|
14
|
-
# Implement the required interface for Rails::Generators::Migration.
|
15
|
-
def self.next_migration_number(dirname) #:nodoc:
|
16
|
-
next_migration_number = current_migration_number(dirname) + 1
|
17
|
-
if ActiveRecord::Base.timestamped_migrations
|
18
|
-
[Time.now.utc.strftime("%Y%m%d%H%M%S"), "%.14d" % next_migration_number].max
|
19
|
-
else
|
20
|
-
"%.3d" % next_migration_number
|
21
|
-
end
|
22
|
-
end
|
6
|
+
include ActiveRecord::Generators::Migration
|
7
|
+
source_root File.join(__dir__, "templates")
|
23
8
|
|
24
9
|
def copy_migration
|
25
10
|
migration_template "install.rb", "db/migrate/install_blazer.rb", migration_version: migration_version
|
@@ -30,9 +15,7 @@ module Blazer
|
|
30
15
|
end
|
31
16
|
|
32
17
|
def migration_version
|
33
|
-
|
34
|
-
"[#{ActiveRecord::VERSION::MAJOR}.#{ActiveRecord::VERSION::MINOR}]"
|
35
|
-
end
|
18
|
+
"[#{ActiveRecord::VERSION::MAJOR}.#{ActiveRecord::VERSION::MINOR}]"
|
36
19
|
end
|
37
20
|
end
|
38
21
|
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.
|
4
|
+
version: 2.2.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Andrew Kane
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2019-
|
11
|
+
date: 2019-07-12 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: railties
|
@@ -16,28 +16,28 @@ dependencies:
|
|
16
16
|
requirements:
|
17
17
|
- - ">="
|
18
18
|
- !ruby/object:Gem::Version
|
19
|
-
version: '
|
19
|
+
version: '5'
|
20
20
|
type: :runtime
|
21
21
|
prerelease: false
|
22
22
|
version_requirements: !ruby/object:Gem::Requirement
|
23
23
|
requirements:
|
24
24
|
- - ">="
|
25
25
|
- !ruby/object:Gem::Version
|
26
|
-
version: '
|
26
|
+
version: '5'
|
27
27
|
- !ruby/object:Gem::Dependency
|
28
28
|
name: activerecord
|
29
29
|
requirement: !ruby/object:Gem::Requirement
|
30
30
|
requirements:
|
31
31
|
- - ">="
|
32
32
|
- !ruby/object:Gem::Version
|
33
|
-
version: '
|
33
|
+
version: '5'
|
34
34
|
type: :runtime
|
35
35
|
prerelease: false
|
36
36
|
version_requirements: !ruby/object:Gem::Requirement
|
37
37
|
requirements:
|
38
38
|
- - ">="
|
39
39
|
- !ruby/object:Gem::Version
|
40
|
-
version: '
|
40
|
+
version: '5'
|
41
41
|
- !ruby/object:Gem::Dependency
|
42
42
|
name: chartkick
|
43
43
|
requirement: !ruby/object:Gem::Requirement
|
@@ -214,14 +214,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
214
214
|
requirements:
|
215
215
|
- - ">="
|
216
216
|
- !ruby/object:Gem::Version
|
217
|
-
version: '2.
|
217
|
+
version: '2.4'
|
218
218
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
219
219
|
requirements:
|
220
220
|
- - ">="
|
221
221
|
- !ruby/object:Gem::Version
|
222
222
|
version: '0'
|
223
223
|
requirements: []
|
224
|
-
rubygems_version: 3.0.
|
224
|
+
rubygems_version: 3.0.4
|
225
225
|
signing_key:
|
226
226
|
specification_version: 4
|
227
227
|
summary: Explore your data with SQL. Easily create charts and dashboards, and share
|