blazer 1.0.0 → 1.0.1

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 4f6da26ecc0d5ab8855037e401139fe007d60688
4
- data.tar.gz: 9c1346b367f96b89240ae6c396dae6d9fd0f4f60
3
+ metadata.gz: 135fd38b9d7a75473a1ecf2afd1acf27ff9a6ffb
4
+ data.tar.gz: 83e0ec15e78191d00b6a81275f60c59dfaff17d8
5
5
  SHA512:
6
- metadata.gz: 6d1d3782d208f2c8b00bc5bedb1d4ecbaee6e7d23cb4d90f8a76348f061d4601c9d5d8c0061dc6cc79944d78897177eb95a026b1d5939aa32575d2b2a5bf0ddc
7
- data.tar.gz: d51440f5c1890e0eed340ec6d2d5dc974286c0f1af1781a8294e2726525a9a3b54a0e5d7f03f160ce976d01795007e7adf91a59422cab4844ddeecbaf24a6acd
6
+ metadata.gz: 11fd0afc742cde141f2019cc70de520a95b7222c302dba952807dd91945380db9aeb2334e89eaa7a8f60ebcbfb9ec56faf838a23e12f7a80b9507f1937942aa3
7
+ data.tar.gz: ac2b8e150d3791aa89d63be8562d6413c30cbd488d5b0dad7a60c813e66ece451adec26b6b2962708ad322495a52c02dd612933769bf14b54d4c4a87612b81de
data/CHANGELOG.md CHANGED
@@ -1,3 +1,10 @@
1
+ ## 1.0.1
2
+
3
+ - Added comments to queries
4
+ - Added `cache` option
5
+ - Added `user_method` option
6
+ - Added `use_transaction` option
7
+
1
8
  ## 1.0.0
2
9
 
3
10
  - Added support for multiple data sources
@@ -30,6 +30,7 @@ module Blazer
30
30
  if var.end_with?("_at")
31
31
  value = Blazer.time_zone.parse(value) rescue nil
32
32
  end
33
+ value.gsub!(" ", "+") if ["start_time", "end_time"].include?(var) # fix for Quip bug
33
34
  statement.gsub!("{#{var}}", ActiveRecord::Base.connection.quote(value))
34
35
  end
35
36
  end
@@ -41,8 +42,13 @@ module Blazer
41
42
  helper_method :extract_vars
42
43
 
43
44
  def variable_params
44
- params.except(:controller, :action, :id, :host, :query, :table_names, :authenticity_token, :utf8, :_method, :commit, :statement, :data_source)
45
+ params.except(:controller, :action, :id, :host, :query, :query_id, :table_names, :authenticity_token, :utf8, :_method, :commit, :statement, :data_source)
45
46
  end
46
47
  helper_method :variable_params
48
+
49
+ def blazer_user
50
+ send(Blazer.user_method) if Blazer.user_method && respond_to?(Blazer.user_method)
51
+ end
52
+ helper_method :blazer_user
47
53
  end
48
54
  end
@@ -34,7 +34,7 @@ module Blazer
34
34
  data_sources.each do |data_source|
35
35
  query = data_source.smart_variables[var]
36
36
  if query
37
- rows, error = data_source.run_statement(query)
37
+ rows, error, cached_at = data_source.run_statement(query)
38
38
  (@smart_vars[var] ||= []).concat rows.map { |v| v.values.reverse }
39
39
  @sql_errors << error if error
40
40
  end
@@ -1,12 +1,14 @@
1
1
  module Blazer
2
2
  class QueriesController < BaseController
3
- before_action :set_query, only: [:show, :edit, :update, :destroy]
3
+ before_action :set_queries, only: [:home, :index]
4
+ before_action :set_query, only: [:show, :edit, :update, :destroy, :refresh]
5
+
6
+ def home
7
+ @queries = @queries.limit(1000)
8
+ end
4
9
 
5
10
  def index
6
- @queries = Blazer::Query.order(:name)
7
- @queries = @queries.includes(:creator) if Blazer.user_class
8
- @trending_queries = Blazer::Audit.group(:query_id).where("created_at > ?", 2.days.ago).having("COUNT(DISTINCT user_id) >= 3").uniq.count(:user_id)
9
- @checks = Blazer::Check.group(:query_id).count
11
+ render partial: "index", layout: false
10
12
  end
11
13
 
12
14
  def new
@@ -15,7 +17,7 @@ module Blazer
15
17
 
16
18
  def create
17
19
  @query = Blazer::Query.new(query_params)
18
- @query.creator = current_user if respond_to?(:current_user) && Blazer.user_class
20
+ @query.creator = blazer_user
19
21
 
20
22
  if @query.save
21
23
  redirect_to query_path(@query, variable_params)
@@ -34,7 +36,7 @@ module Blazer
34
36
  @bind_vars.each do |var|
35
37
  query = data_source.smart_variables[var]
36
38
  if query
37
- rows, error = data_source.run_statement(query)
39
+ rows, error, cached_at = data_source.run_statement(query)
38
40
  @smart_vars[var] = rows.map { |v| v.values.reverse }
39
41
  @sql_errors << error if error
40
42
  end
@@ -60,12 +62,12 @@ module Blazer
60
62
  audit = Blazer::Audit.new(statement: @statement)
61
63
  audit.query = @query
62
64
  audit.data_source = data_source
63
- audit.user = current_user if respond_to?(:current_user) && Blazer.user_class
65
+ audit.user = blazer_user
64
66
  audit.save!
65
67
  end
66
68
 
67
69
  @data_source = Blazer.data_sources[data_source]
68
- @rows, @error = @data_source.run_statement(@statement)
70
+ @rows, @error, @cached_at = @data_source.run_statement(@statement, user: blazer_user, query: @query, refresh_cache: params[:check])
69
71
 
70
72
  if @query && !@error.to_s.include?("canceling statement due to statement timeout")
71
73
  @query.checks.each do |check|
@@ -97,7 +99,7 @@ module Blazer
97
99
  query = @data_source.smart_columns[key]
98
100
  if query
99
101
  values = @rows.map { |r| r[key] }.compact.uniq
100
- rows, error = @data_source.run_statement(ActiveRecord::Base.send(:sanitize_sql_array, [query.sub("{value}", "(?)"), values]))
102
+ rows, error, cached_at = @data_source.run_statement(ActiveRecord::Base.send(:sanitize_sql_array, [query.sub("{value}", "(?)"), values]))
101
103
  @boom[key] = Hash[rows.map(&:values)]
102
104
  end
103
105
  end
@@ -115,6 +117,14 @@ module Blazer
115
117
  end
116
118
  end
117
119
 
120
+ def refresh
121
+ data_source = Blazer.data_sources[@query.data_source]
122
+ @statement = @query.statement.dup
123
+ process_vars(@statement)
124
+ data_source.clear_cache(@statement)
125
+ redirect_to query_path(@query, variable_params)
126
+ end
127
+
118
128
  def update
119
129
  if @query.update(query_params)
120
130
  redirect_to query_path(@query, variable_params)
@@ -135,6 +145,13 @@ module Blazer
135
145
 
136
146
  private
137
147
 
148
+ def set_queries
149
+ @queries = Blazer::Query.order(:name)
150
+ @queries = @queries.includes(:creator) if Blazer.user_class
151
+ @trending_queries = Blazer::Audit.group(:query_id).where("created_at > ?", 2.days.ago).having("COUNT(DISTINCT user_id) >= 3").uniq.count(:user_id)
152
+ @checks = Blazer::Check.group(:query_id).count
153
+ end
154
+
138
155
  def set_query
139
156
  @query = Blazer::Query.find(params[:id].to_s.split("-").first)
140
157
  end
@@ -1,7 +1,7 @@
1
1
  <p style="text-muted">Running check...</p>
2
2
 
3
3
  <script>
4
- $.post("<%= run_queries_path %>", <%= json_escape({statement: @query.statement, query_id: @query.id}.to_json).html_safe %>, function (data) {
4
+ $.post("<%= run_queries_path %>", <%= json_escape({statement: @query.statement, query_id: @query.id, check: true}.to_json).html_safe %>, function (data) {
5
5
  setTimeout( function () {
6
6
  window.location.href = "<%= checks_path %>";
7
7
  }, 200);
@@ -34,21 +34,19 @@ li:hover .glyphicon-remove {
34
34
  <div class="form-group">
35
35
  <%= f.label :query_id, "Add Chart" %>
36
36
  <div class="hide">
37
- <%= select_tag :query_id, options_for_select(Blazer::Query.order(:name).map { |q| [q.name, q.id] }, {include_blank: true}) %>
37
+ <%= select_tag :query_id, options_for_select(Blazer::Query.order(:name).map { |q| [q.name, q.id] }), {include_blank: true, placeholder: "Select chart"} %>
38
38
  </div>
39
39
  <script>
40
- $("#query_id").selectize({allowEmptyOption: true}).parents(".hide").removeClass("hide");
40
+ $("#query_id").selectize().parents(".hide").removeClass("hide");
41
41
  $("#query_id").change( function () {
42
42
  var $option = $(this).find("option:selected");
43
43
  if ($option.val() !== "") {
44
- // console.log($option.val());
45
- // console.log($option.text());
46
44
  var $li = $("<li></li>");
47
45
  $li.addClass("list-group-item");
48
46
  $li.text($option.text());
49
47
  $li.prepend('<span class="glyphicon glyphicon-remove" aria-hidden="true" style="float: right; margin-top: 3px;"></span><input type="hidden" name="query_ids[]" id="query_ids_" value="' + $option.val() + '">');
50
48
  $(".list-group").append($li);
51
- $(this).val("");
49
+ $(this)[0].selectize.setValue("");
52
50
  $(".form-group").removeClass("hide");
53
51
  }
54
52
  });
@@ -134,9 +134,17 @@
134
134
  </div>
135
135
  </div>
136
136
  <script>
137
- $.post("<%= run_queries_path %>", <%= json_escape({statement: query.statement, query_id: query.id, only_chart: true}.to_json).html_safe %>, function (data) {
137
+ var request = $.ajax({
138
+ url: "<%= run_queries_path %>",
139
+ method: "POST",
140
+ data: <%= json_escape({statement: query.statement, query_id: query.id, only_chart: true}.to_json).html_safe %>,
141
+ dataType: "html"
142
+ }).done(function(data) {
138
143
  $("#chart-<%= i %>").html(data);
139
144
  $("#chart-<%= i %> table").stupidtable();
145
+ }).fail(function(jqXHR, textStatus, errorThrown) {
146
+ var message = (typeof errorThrown === "string") ? errorThrown : errorThrown.message;
147
+ $("#chart-<%= i %>").css("color", "red").html(message);
140
148
  });
141
149
  </script>
142
150
  <% end %>
@@ -111,7 +111,7 @@
111
111
  if (xhr) {
112
112
  xhr.abort();
113
113
  }
114
- xhr = $.post("<%= run_queries_path %>", $.extend({}, params, {statement: editor.getValue(), data_source: $("#query_data_source").val()}), function (data) {
114
+ xhr = $.post("<%= run_queries_path %>", $.extend({}, params, {statement: editor.getValue().replace(/\n/g, "\r\n"), data_source: $("#query_data_source").val()}), function (data) {
115
115
  $("#results").html(data);
116
116
 
117
117
  error_line = /LINE (\d+)/g.exec($("#results").find('.alert-danger').text());
@@ -0,0 +1,29 @@
1
+ <% @queries.each do |query| %>
2
+ <tr>
3
+ <td class="query">
4
+ <%= link_to query.name, query %>
5
+ <span style="color: #ccc;"><%= extract_vars(query.statement).join(", ") %></span>
6
+ <% if @queries.size < 1000 && query.created_at > 2.days.ago %>
7
+ <small style="font-weight: bold; color: #5cb85c;">NEW</small>
8
+ <% end %>
9
+ <% if @trending_queries[query.id] %>
10
+ <small style="font-weight: bold; color: #f60;">TRENDING</small>
11
+ <% end %>
12
+ <% if @checks[query.id] %>
13
+ <small style="font-weight: bold; color: #f60;">CHECK</small>
14
+ <% end %>
15
+ <div class="hide"><%= query.name.gsub(/\s+/, "") %></div>
16
+ </td>
17
+ <td class="creator text-right text-muted">
18
+ <% if query.respond_to?(:creator) && (creator = query.creator) && creator.respond_to?(Blazer.user_name) %>
19
+ <% name = creator.send(Blazer.user_name) %>
20
+ <% if creator == blazer_user %>
21
+ You
22
+ <div class="hide">me <%= name %></div>
23
+ <% else %>
24
+ <%= name %>
25
+ <% end %>
26
+ <% end %>
27
+ </td>
28
+ </tr>
29
+ <% end %>
@@ -0,0 +1,40 @@
1
+ <div id="queries">
2
+ <div id="header" style="margin-bottom: 20px;">
3
+ <div class="pull-right">
4
+ <%= link_to "New Query", new_query_path, class: "btn btn-info" %>
5
+ <%= link_to "Dashboards", dashboards_path, class: "btn btn-primary" %>
6
+ <%= link_to "Checks", checks_path, class: "btn btn-primary" %>
7
+ </div>
8
+ <input type="text" placeholder="Start typing a query or person" style="width: 300px; display: inline-block;" autofocus=true class="search form-control" />
9
+ </div>
10
+
11
+ <table class="table">
12
+ <thead>
13
+ <tr>
14
+ <th>Query</th>
15
+ <th style="width: 20%; text-align: right;">Mastermind</th>
16
+ </tr>
17
+ </thead>
18
+ <tbody class="list">
19
+ <%= render partial: "index" %>
20
+ </tbody>
21
+ </table>
22
+ </div>
23
+
24
+ <script>
25
+ var options = {
26
+ valueNames: ['query', 'creator']
27
+ };
28
+
29
+ function updateList() {
30
+ var userList = new List('queries', options);
31
+ userList.search($(".search").val());
32
+ }
33
+ updateList();
34
+ </script>
35
+
36
+ <% if @queries.size == 1000 %>
37
+ <script>
38
+ $(".list").load("<%= queries_path %>", updateList);
39
+ </script>
40
+ <% end %>
@@ -8,6 +8,14 @@
8
8
  <% end %>
9
9
  <% else %>
10
10
  <% unless @only_chart %>
11
+ <% if @cached_at %>
12
+ <p class="text-muted" style="float: right;">
13
+ Cached <%= time_ago_in_words(@cached_at, include_seconds: true) %> ago
14
+ <% if @query && !params[:data_source] %>
15
+ <%= link_to "Refresh", refresh_query_path(@query, variable_params), method: :post %>
16
+ <% end %>
17
+ </p>
18
+ <% end %>
11
19
  <p class="text-muted"><%= pluralize(@rows.size, "row") %></p>
12
20
  <% end %>
13
21
  <% if @rows.any? %>
@@ -22,7 +30,11 @@
22
30
  <% elsif values.size == 2 && values.first.is_a?(String) && values.last.is_a?(Numeric) %>
23
31
  <%= pie_chart @rows.map(&:values), library: {sliceVisibilityThreshold: 1 / 40.0}, id: chart_id %>
24
32
  <% elsif @only_chart %>
25
- <% @no_chart = true %>
33
+ <% if @rows.size == 1 && @rows.first.size == 1 %>
34
+ <p style="font-size: 160px;"><%= format_value(@rows.first.keys.first, @rows.first.values.first) %></p>
35
+ <% else %>
36
+ <% @no_chart = true %>
37
+ <% end %>
26
38
  <% end %>
27
39
 
28
40
  <% unless @only_chart && !@no_chart %>
@@ -153,9 +153,17 @@
153
153
  </div>
154
154
 
155
155
  <script>
156
- $.post("<%= run_queries_path %>", <%= json_escape({statement: @statement, query_id: @query.id}.to_json).html_safe %>, function (data) {
156
+ var request = $.ajax({
157
+ url: "<%= run_queries_path %>",
158
+ method: "POST",
159
+ data: <%= json_escape(variable_params.merge(statement: @statement, query_id: @query.id).to_json).html_safe %>,
160
+ dataType: "html"
161
+ }).done(function(data) {
157
162
  $("#results").html(data);
158
163
  $("#results table").stupidtable().stickyTableHeaders({fixedOffset: 60});
164
+ }).fail(function(jqXHR, textStatus, errorThrown) {
165
+ var message = (typeof errorThrown === "string") ? errorThrown : errorThrown.message;
166
+ $("#results").css("color", "red").html(message);
159
167
  });
160
168
  </script>
161
169
  <% end %>
data/config/routes.rb CHANGED
@@ -1,11 +1,12 @@
1
1
  Blazer::Engine.routes.draw do
2
- resources :queries, except: [:index] do
2
+ resources :queries do
3
3
  post :run, on: :collection # err on the side of caution
4
+ post :refresh, on: :member
4
5
  get :tables, on: :collection
5
6
  end
6
7
  resources :checks, except: [:show] do
7
8
  get :run, on: :member
8
9
  end
9
10
  resources :dashboards
10
- root to: "queries#index"
11
+ root to: "queries#home"
11
12
  end
data/lib/blazer.rb CHANGED
@@ -11,7 +11,9 @@ module Blazer
11
11
  attr_reader :time_zone
12
12
  attr_accessor :user_name
13
13
  attr_accessor :user_class
14
+ attr_accessor :user_method
14
15
  attr_accessor :from_email
16
+ attr_accessor :cache
15
17
  end
16
18
  self.audit = true
17
19
  self.user_name = :name
@@ -43,7 +45,7 @@ module Blazer
43
45
  tries = 0
44
46
  # try 3 times on timeout errors
45
47
  begin
46
- rows, error = data_sources[check.query.data_source].run_statement(check.query.statement)
48
+ rows, error, cached_at = data_sources[check.query.data_source].run_statement(check.query.statement, refresh_cache: true)
47
49
  tries += 1
48
50
  end while error && error.include?("canceling statement due to statement timeout") && tries < 3
49
51
  check.update_state(rows, error)
@@ -1,3 +1,5 @@
1
+ require "digest/md5"
2
+
1
3
  module Blazer
2
4
  class DataSource
3
5
  attr_reader :id, :settings, :connection_model
@@ -34,37 +36,94 @@ module Blazer
34
36
  settings["timeout"]
35
37
  end
36
38
 
37
- def run_statement(statement)
38
- rows = []
39
+ def cache
40
+ settings["cache"]
41
+ end
42
+
43
+ def use_transaction?
44
+ settings.key?("use_transaction") ? settings["use_transaction"] : true
45
+ end
46
+
47
+ def run_statement(statement, options = {})
48
+ rows = nil
39
49
  error = nil
40
- begin
41
- connection_model.transaction do
42
- connection_model.connection.execute("SET statement_timeout = #{timeout.to_i * 1000}") if timeout && postgresql?
43
- result = connection_model.connection.select_all(statement)
44
- result.each do |untyped_row|
45
- row = {}
46
- untyped_row.each do |k, v|
47
- row[k] = result.column_types.empty? ? v : result.column_types[k].send(:type_cast, v)
50
+ cached_at = nil
51
+ cache_key = self.cache_key(statement) if cache
52
+ if cache && !options[:refresh_cache]
53
+ value = Blazer.cache.read(cache_key)
54
+ rows, cached_at = Marshal.load(value) if value
55
+ end
56
+
57
+ unless rows
58
+ rows = []
59
+
60
+ comment = "blazer"
61
+ if options[:user].respond_to?(:id)
62
+ comment << ",user_id:#{options[:user].id}"
63
+ end
64
+ if options[:user].respond_to?(Blazer.user_name)
65
+ # only include letters, numbers, and spaces to prevent injection
66
+ comment << ",user_name:#{options[:user].send(Blazer.user_name).to_s.gsub(/[^a-zA-Z0-9 ]/, "")}"
67
+ end
68
+ if options[:query].respond_to?(:id)
69
+ comment << ",query_id:#{options[:query].id}"
70
+ end
71
+
72
+ in_transaction do
73
+ begin
74
+ connection_model.connection.execute("SET statement_timeout = #{timeout.to_i * 1000}") if timeout && postgresql?
75
+ result = connection_model.connection.select_all("#{statement} /*#{comment}*/")
76
+ result.each do |untyped_row|
77
+ row = {}
78
+ untyped_row.each do |k, v|
79
+ row[k] = result.column_types.empty? ? v : result.column_types[k].send(:type_cast, v)
80
+ end
81
+ rows << row
48
82
  end
49
- rows << row
83
+ rescue ActiveRecord::StatementInvalid => e
84
+ error = e.message.sub(/.+ERROR: /, "")
50
85
  end
51
- raise ActiveRecord::Rollback
52
86
  end
53
- rescue ActiveRecord::StatementInvalid => e
54
- error = e.message.sub(/.+ERROR: /, "")
87
+
88
+ Blazer.cache.write(cache_key, Marshal.dump([rows, Time.now]), expires_in: cache.to_f * 60) if !error && cache
55
89
  end
56
- [rows, error]
90
+
91
+ [rows, error, cached_at]
92
+ end
93
+
94
+ def clear_cache(statement)
95
+ Blazer.cache.delete(cache_key(statement))
96
+ end
97
+
98
+ def cache_key(statement)
99
+ ["blazer", "v2", id, Digest::MD5.hexdigest(statement)].join("/")
57
100
  end
58
101
 
59
102
  def tables
60
103
  default_schema = postgresql? ? "public" : connection_model.connection_config[:database]
61
104
  schema = connection_model.connection_config[:schema] || default_schema
62
- rows, error = run_statement(connection_model.send(:sanitize_sql_array, ["SELECT table_name, column_name, ordinal_position, data_type FROM information_schema.columns WHERE table_schema = ?", schema]))
105
+ rows, error, cached_at = run_statement(connection_model.send(:sanitize_sql_array, ["SELECT table_name, column_name, ordinal_position, data_type FROM information_schema.columns WHERE table_schema = ?", schema]))
63
106
  Hash[rows.group_by { |r| r["table_name"] }.map { |t, f| [t, f.sort_by { |f| f["ordinal_position"] }.map { |f| f.slice("column_name", "data_type") }] }.sort_by { |t, _f| t }]
64
107
  end
65
108
 
66
109
  def postgresql?
67
110
  ["PostgreSQL", "Redshift"].include?(connection_model.connection.adapter_name)
68
111
  end
112
+
113
+ protected
114
+
115
+ def in_transaction
116
+ if use_transaction?
117
+ connection_model.transaction do
118
+ begin
119
+ yield
120
+ ensure
121
+ raise ActiveRecord::Rollback
122
+ end
123
+ end
124
+ else
125
+ yield
126
+ end
127
+ end
69
128
  end
70
129
  end
data/lib/blazer/engine.rb CHANGED
@@ -12,7 +12,14 @@ module Blazer
12
12
  Blazer.from_email = Blazer.settings["from_email"] if Blazer.settings["from_email"]
13
13
 
14
14
  Blazer.user_class ||= Blazer.settings["user_class"] || User rescue nil
15
+ Blazer.user_method = Blazer.settings["user_method"]
16
+ if Blazer.user_class
17
+ Blazer.user_method ||= "current_#{Blazer.user_class.to_s.downcase.singularize}"
18
+ end
19
+
15
20
  Blazer::Query.belongs_to :creator, class_name: Blazer.user_class.to_s if Blazer.user_class
21
+
22
+ Blazer.cache ||= Rails.cache
16
23
  end
17
24
  end
18
25
  end
@@ -1,3 +1,3 @@
1
1
  module Blazer
2
- VERSION = "1.0.0"
2
+ VERSION = "1.0.1"
3
3
  end
@@ -4,7 +4,20 @@ data_sources:
4
4
  main:
5
5
  url: <%%= ENV["BLAZER_DATABASE_URL"] %>
6
6
 
7
- # timeout: 15 # applies to PostgreSQL only
7
+ # statement timeout, in seconds
8
+ # applies to PostgreSQL only
9
+ # none by default
10
+ # timeout: 15
11
+
12
+ # time to cache results, in minutes
13
+ # can greatly improve speed
14
+ # none by default
15
+ # cache: 60
16
+
17
+ # wrap queries in a transaction for safety
18
+ # not necessary if you use a read-only user
19
+ # true by default
20
+ # use_transaction: false
8
21
 
9
22
  smart_variables:
10
23
  # zone_id: "SELECT id, name FROM zones ORDER BY name ASC"
@@ -26,3 +39,6 @@ audit: true
26
39
 
27
40
  # method name for the user model
28
41
  # user_name: name
42
+
43
+ # email to send checks from
44
+ # from_email: blazer@example.org
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: 1.0.0
4
+ version: 1.0.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Andrew Kane
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2015-10-04 00:00:00.000000000 Z
11
+ date: 2015-10-08 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rails
@@ -128,9 +128,10 @@ files:
128
128
  - app/views/blazer/dashboards/new.html.erb
129
129
  - app/views/blazer/dashboards/show.html.erb
130
130
  - app/views/blazer/queries/_form.html.erb
131
+ - app/views/blazer/queries/_index.html.erb
131
132
  - app/views/blazer/queries/_tables.html
132
133
  - app/views/blazer/queries/edit.html.erb
133
- - app/views/blazer/queries/index.html.erb
134
+ - app/views/blazer/queries/home.html.erb
134
135
  - app/views/blazer/queries/new.html.erb
135
136
  - app/views/blazer/queries/run.html.erb
136
137
  - app/views/blazer/queries/show.html.erb
@@ -170,4 +171,3 @@ signing_key:
170
171
  specification_version: 4
171
172
  summary: Share data effortlessly with your team
172
173
  test_files: []
173
- has_rdoc:
@@ -1,57 +0,0 @@
1
- <div id="queries">
2
- <div id="header" style="margin-bottom: 20px;">
3
- <div class="pull-right">
4
- <%= link_to "New Query", new_query_path, class: "btn btn-info" %>
5
- <%= link_to "Dashboards", dashboards_path, class: "btn btn-primary" %>
6
- <%= link_to "Checks", checks_path, class: "btn btn-primary" %>
7
- </div>
8
- <input type="text" placeholder="Start typing a query or person" style="width: 300px; display: inline-block;" autofocus=true class="search form-control" />
9
- </div>
10
-
11
- <table class="table">
12
- <thead>
13
- <tr>
14
- <th>Query</th>
15
- <th style="width: 20%; text-align: right;">Mastermind</th>
16
- </tr>
17
- </thead>
18
- <tbody class="list">
19
- <% @queries.each do |query| %>
20
- <tr>
21
- <td class="query">
22
- <%= link_to query.name, query %>
23
- <span style="color: #ccc;"><%= extract_vars(query.statement).join(", ") %></span>
24
- <% if query.created_at > 2.days.ago %>
25
- <small style="font-weight: bold; color: #5cb85c;">NEW</small>
26
- <% end %>
27
- <% if @trending_queries[query.id] %>
28
- <small style="font-weight: bold; color: #f60;">TRENDING</small>
29
- <% end %>
30
- <% if @checks[query.id] %>
31
- <small style="font-weight: bold; color: #f60;">CHECK</small>
32
- <% end %>
33
- <div class="hide"><%= query.name.gsub(/\s+/, "") %></div>
34
- </td>
35
- <td class="creator text-right text-muted">
36
- <% if query.respond_to?(:creator) && (creator = query.creator) && creator.respond_to?(Blazer.user_name) %>
37
- <% name = creator.send(Blazer.user_name) %>
38
- <% if respond_to?(:current_user) and creator == current_user %>
39
- You
40
- <div class="hide">me <%= name %></div>
41
- <% else %>
42
- <%= name %>
43
- <% end %>
44
- <% end %>
45
- </td>
46
- </tr>
47
- <% end %>
48
- </tbody>
49
- </table>
50
- </div>
51
-
52
- <script>
53
- var options = {
54
- valueNames: ['query', 'creator']
55
- };
56
- var userList = new List('queries', options);
57
- </script>