blazer_xlsx 3.0.5

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 (148) hide show
  1. checksums.yaml +7 -0
  2. data/CHANGELOG.md +442 -0
  3. data/CONTRIBUTING.md +42 -0
  4. data/LICENSE.txt +22 -0
  5. data/README.md +1093 -0
  6. data/app/assets/fonts/blazer/glyphicons-halflings-regular.eot +0 -0
  7. data/app/assets/fonts/blazer/glyphicons-halflings-regular.svg +288 -0
  8. data/app/assets/fonts/blazer/glyphicons-halflings-regular.ttf +0 -0
  9. data/app/assets/fonts/blazer/glyphicons-halflings-regular.woff +0 -0
  10. data/app/assets/fonts/blazer/glyphicons-halflings-regular.woff2 +0 -0
  11. data/app/assets/images/blazer/favicon.png +0 -0
  12. data/app/assets/javascripts/blazer/Sortable.js +3709 -0
  13. data/app/assets/javascripts/blazer/ace/ace.js +19630 -0
  14. data/app/assets/javascripts/blazer/ace/ext-language_tools.js +1981 -0
  15. data/app/assets/javascripts/blazer/ace/mode-sql.js +215 -0
  16. data/app/assets/javascripts/blazer/ace/snippets/sql.js +16 -0
  17. data/app/assets/javascripts/blazer/ace/snippets/text.js +9 -0
  18. data/app/assets/javascripts/blazer/ace/theme-twilight.js +18 -0
  19. data/app/assets/javascripts/blazer/ace.js +6 -0
  20. data/app/assets/javascripts/blazer/application.js +84 -0
  21. data/app/assets/javascripts/blazer/bootstrap.js +2580 -0
  22. data/app/assets/javascripts/blazer/chart.umd.js +13 -0
  23. data/app/assets/javascripts/blazer/chartjs-adapter-date-fns.bundle.js +6322 -0
  24. data/app/assets/javascripts/blazer/chartkick.js +2570 -0
  25. data/app/assets/javascripts/blazer/daterangepicker.js +1578 -0
  26. data/app/assets/javascripts/blazer/fuzzysearch.js +24 -0
  27. data/app/assets/javascripts/blazer/highlight.min.js +466 -0
  28. data/app/assets/javascripts/blazer/jquery.js +10872 -0
  29. data/app/assets/javascripts/blazer/jquery.stickytableheaders.js +325 -0
  30. data/app/assets/javascripts/blazer/mapkick.bundle.js +1029 -0
  31. data/app/assets/javascripts/blazer/moment-timezone-with-data.js +1548 -0
  32. data/app/assets/javascripts/blazer/moment.js +5685 -0
  33. data/app/assets/javascripts/blazer/queries.js +130 -0
  34. data/app/assets/javascripts/blazer/rails-ujs.js +746 -0
  35. data/app/assets/javascripts/blazer/routes.js +26 -0
  36. data/app/assets/javascripts/blazer/selectize.js +3891 -0
  37. data/app/assets/javascripts/blazer/stupidtable-custom-settings.js +13 -0
  38. data/app/assets/javascripts/blazer/stupidtable.js +281 -0
  39. data/app/assets/javascripts/blazer/vue.global.prod.js +1 -0
  40. data/app/assets/stylesheets/blazer/application.css +243 -0
  41. data/app/assets/stylesheets/blazer/bootstrap-propshaft.css +10 -0
  42. data/app/assets/stylesheets/blazer/bootstrap-sprockets.css.erb +10 -0
  43. data/app/assets/stylesheets/blazer/bootstrap.css +6828 -0
  44. data/app/assets/stylesheets/blazer/daterangepicker.css +410 -0
  45. data/app/assets/stylesheets/blazer/github.css +125 -0
  46. data/app/assets/stylesheets/blazer/selectize.css +403 -0
  47. data/app/controllers/blazer/base_controller.rb +135 -0
  48. data/app/controllers/blazer/checks_controller.rb +56 -0
  49. data/app/controllers/blazer/dashboards_controller.rb +99 -0
  50. data/app/controllers/blazer/queries_controller.rb +472 -0
  51. data/app/controllers/blazer/uploads_controller.rb +147 -0
  52. data/app/helpers/blazer/base_helper.rb +39 -0
  53. data/app/models/blazer/audit.rb +6 -0
  54. data/app/models/blazer/check.rb +104 -0
  55. data/app/models/blazer/connection.rb +5 -0
  56. data/app/models/blazer/dashboard.rb +17 -0
  57. data/app/models/blazer/dashboard_query.rb +9 -0
  58. data/app/models/blazer/query.rb +42 -0
  59. data/app/models/blazer/record.rb +5 -0
  60. data/app/models/blazer/upload.rb +11 -0
  61. data/app/models/blazer/uploads_connection.rb +7 -0
  62. data/app/views/blazer/_nav.html.erb +18 -0
  63. data/app/views/blazer/_variables.html.erb +127 -0
  64. data/app/views/blazer/check_mailer/failing_checks.html.erb +7 -0
  65. data/app/views/blazer/check_mailer/state_change.html.erb +48 -0
  66. data/app/views/blazer/checks/_form.html.erb +79 -0
  67. data/app/views/blazer/checks/edit.html.erb +3 -0
  68. data/app/views/blazer/checks/index.html.erb +72 -0
  69. data/app/views/blazer/checks/new.html.erb +3 -0
  70. data/app/views/blazer/dashboards/_form.html.erb +82 -0
  71. data/app/views/blazer/dashboards/edit.html.erb +3 -0
  72. data/app/views/blazer/dashboards/new.html.erb +3 -0
  73. data/app/views/blazer/dashboards/show.html.erb +53 -0
  74. data/app/views/blazer/queries/_caching.html.erb +16 -0
  75. data/app/views/blazer/queries/_cohorts.html.erb +48 -0
  76. data/app/views/blazer/queries/_form.html.erb +255 -0
  77. data/app/views/blazer/queries/docs.html.erb +147 -0
  78. data/app/views/blazer/queries/edit.html.erb +2 -0
  79. data/app/views/blazer/queries/home.html.erb +169 -0
  80. data/app/views/blazer/queries/new.html.erb +2 -0
  81. data/app/views/blazer/queries/run.html.erb +183 -0
  82. data/app/views/blazer/queries/schema.html.erb +55 -0
  83. data/app/views/blazer/queries/show.html.erb +72 -0
  84. data/app/views/blazer/uploads/_form.html.erb +27 -0
  85. data/app/views/blazer/uploads/edit.html.erb +3 -0
  86. data/app/views/blazer/uploads/index.html.erb +55 -0
  87. data/app/views/blazer/uploads/new.html.erb +3 -0
  88. data/app/views/layouts/blazer/application.html.erb +25 -0
  89. data/config/routes.rb +25 -0
  90. data/lib/blazer/adapters/athena_adapter.rb +182 -0
  91. data/lib/blazer/adapters/base_adapter.rb +76 -0
  92. data/lib/blazer/adapters/bigquery_adapter.rb +79 -0
  93. data/lib/blazer/adapters/cassandra_adapter.rb +70 -0
  94. data/lib/blazer/adapters/drill_adapter.rb +38 -0
  95. data/lib/blazer/adapters/druid_adapter.rb +102 -0
  96. data/lib/blazer/adapters/elasticsearch_adapter.rb +61 -0
  97. data/lib/blazer/adapters/hive_adapter.rb +55 -0
  98. data/lib/blazer/adapters/ignite_adapter.rb +64 -0
  99. data/lib/blazer/adapters/influxdb_adapter.rb +57 -0
  100. data/lib/blazer/adapters/neo4j_adapter.rb +62 -0
  101. data/lib/blazer/adapters/opensearch_adapter.rb +52 -0
  102. data/lib/blazer/adapters/presto_adapter.rb +54 -0
  103. data/lib/blazer/adapters/salesforce_adapter.rb +50 -0
  104. data/lib/blazer/adapters/snowflake_adapter.rb +82 -0
  105. data/lib/blazer/adapters/soda_adapter.rb +105 -0
  106. data/lib/blazer/adapters/spark_adapter.rb +14 -0
  107. data/lib/blazer/adapters/sql_adapter.rb +353 -0
  108. data/lib/blazer/adapters.rb +17 -0
  109. data/lib/blazer/anomaly_detectors.rb +22 -0
  110. data/lib/blazer/check_mailer.rb +27 -0
  111. data/lib/blazer/data_source.rb +266 -0
  112. data/lib/blazer/engine.rb +42 -0
  113. data/lib/blazer/forecasters.rb +7 -0
  114. data/lib/blazer/result.rb +178 -0
  115. data/lib/blazer/result_cache.rb +71 -0
  116. data/lib/blazer/run_statement.rb +45 -0
  117. data/lib/blazer/run_statement_job.rb +20 -0
  118. data/lib/blazer/slack_notifier.rb +94 -0
  119. data/lib/blazer/statement.rb +77 -0
  120. data/lib/blazer/version.rb +3 -0
  121. data/lib/blazer.rb +282 -0
  122. data/lib/generators/blazer/install_generator.rb +22 -0
  123. data/lib/generators/blazer/templates/config.yml.tt +79 -0
  124. data/lib/generators/blazer/templates/install.rb.tt +47 -0
  125. data/lib/generators/blazer/templates/uploads.rb.tt +10 -0
  126. data/lib/generators/blazer/uploads_generator.rb +18 -0
  127. data/lib/tasks/blazer.rake +20 -0
  128. data/licenses/LICENSE-ace.txt +24 -0
  129. data/licenses/LICENSE-bootstrap.txt +21 -0
  130. data/licenses/LICENSE-chart.js.txt +9 -0
  131. data/licenses/LICENSE-chartjs-adapter-date-fns.txt +9 -0
  132. data/licenses/LICENSE-chartkick.js.txt +22 -0
  133. data/licenses/LICENSE-date-fns.txt +21 -0
  134. data/licenses/LICENSE-daterangepicker.txt +21 -0
  135. data/licenses/LICENSE-fuzzysearch.txt +20 -0
  136. data/licenses/LICENSE-highlight.js.txt +29 -0
  137. data/licenses/LICENSE-jquery.txt +20 -0
  138. data/licenses/LICENSE-kurkle-color.txt +9 -0
  139. data/licenses/LICENSE-mapkick-bundle.txt +1029 -0
  140. data/licenses/LICENSE-moment-timezone.txt +20 -0
  141. data/licenses/LICENSE-moment.txt +22 -0
  142. data/licenses/LICENSE-rails-ujs.txt +20 -0
  143. data/licenses/LICENSE-selectize.txt +202 -0
  144. data/licenses/LICENSE-sortable.txt +21 -0
  145. data/licenses/LICENSE-stickytableheaders.txt +20 -0
  146. data/licenses/LICENSE-stupidtable.txt +19 -0
  147. data/licenses/LICENSE-vue.txt +21 -0
  148. metadata +271 -0
data/lib/blazer.rb ADDED
@@ -0,0 +1,282 @@
1
+ # dependencies
2
+ require "chartkick"
3
+ require "safely/core"
4
+
5
+ # stdlib
6
+ require "csv"
7
+ require "digest/sha2"
8
+ require "json"
9
+ require "yaml"
10
+
11
+ # modules
12
+ require_relative "blazer/version"
13
+ require_relative "blazer/data_source"
14
+ require_relative "blazer/result"
15
+ require_relative "blazer/result_cache"
16
+ require_relative "blazer/run_statement"
17
+ require_relative "blazer/statement"
18
+
19
+ # adapters
20
+ require_relative "blazer/adapters/base_adapter"
21
+ require_relative "blazer/adapters/athena_adapter"
22
+ require_relative "blazer/adapters/bigquery_adapter"
23
+ require_relative "blazer/adapters/cassandra_adapter"
24
+ require_relative "blazer/adapters/drill_adapter"
25
+ require_relative "blazer/adapters/druid_adapter"
26
+ require_relative "blazer/adapters/elasticsearch_adapter"
27
+ require_relative "blazer/adapters/hive_adapter"
28
+ require_relative "blazer/adapters/ignite_adapter"
29
+ require_relative "blazer/adapters/influxdb_adapter"
30
+ require_relative "blazer/adapters/neo4j_adapter"
31
+ require_relative "blazer/adapters/opensearch_adapter"
32
+ require_relative "blazer/adapters/presto_adapter"
33
+ require_relative "blazer/adapters/salesforce_adapter"
34
+ require_relative "blazer/adapters/soda_adapter"
35
+ require_relative "blazer/adapters/spark_adapter"
36
+ require_relative "blazer/adapters/sql_adapter"
37
+ require_relative "blazer/adapters/snowflake_adapter"
38
+
39
+ # engine
40
+ require_relative "blazer/engine"
41
+
42
+ module Blazer
43
+ class Error < StandardError; end
44
+ class UploadError < Error; end
45
+ class TimeoutNotSupported < Error; end
46
+
47
+ # actionmailer optional
48
+ autoload :CheckMailer, "blazer/check_mailer"
49
+ # net/http optional
50
+ autoload :SlackNotifier, "blazer/slack_notifier"
51
+ # activejob optional
52
+ autoload :RunStatementJob, "blazer/run_statement_job"
53
+
54
+ class << self
55
+ attr_accessor :audit
56
+ attr_reader :time_zone
57
+ attr_accessor :user_name
58
+ attr_writer :user_class
59
+ attr_writer :user_method
60
+ attr_accessor :before_action
61
+ attr_accessor :from_email
62
+ attr_accessor :cache
63
+ attr_accessor :transform_statement
64
+ attr_accessor :transform_variable
65
+ attr_accessor :check_schedules
66
+ attr_accessor :anomaly_checks
67
+ attr_accessor :forecasting
68
+ attr_accessor :async
69
+ attr_accessor :images
70
+ attr_accessor :override_csp
71
+ attr_accessor :slack_oauth_token
72
+ attr_accessor :slack_webhook_url
73
+ attr_accessor :mapbox_access_token
74
+ end
75
+ self.audit = true
76
+ self.user_name = :name
77
+ self.check_schedules = ["5 minutes", "1 hour", "1 day"]
78
+ self.anomaly_checks = false
79
+ self.forecasting = false
80
+ self.async = false
81
+ self.images = false
82
+ self.override_csp = false
83
+
84
+ VARIABLE_MESSAGE = "Variable cannot be used in this position"
85
+ TIMEOUT_MESSAGE = "Query timed out :("
86
+ TIMEOUT_ERRORS = [
87
+ "canceling statement due to statement timeout", # postgres
88
+ "canceling statement due to conflict with recovery", # postgres
89
+ "cancelled on user's request", # redshift
90
+ "canceled on user's request", # redshift
91
+ "system requested abort", # redshift
92
+ "maximum statement execution time exceeded" # mysql
93
+ ]
94
+
95
+ def self.time_zone=(time_zone)
96
+ @time_zone = time_zone.is_a?(ActiveSupport::TimeZone) ? time_zone : ActiveSupport::TimeZone[time_zone.to_s]
97
+ end
98
+
99
+ def self.user_class
100
+ if !defined?(@user_class)
101
+ @user_class = settings.key?("user_class") ? settings["user_class"] : (User.name rescue nil)
102
+ end
103
+ @user_class
104
+ end
105
+
106
+ def self.user_method
107
+ if !defined?(@user_method)
108
+ @user_method = settings["user_method"]
109
+ if user_class
110
+ @user_method ||= "current_#{user_class.to_s.downcase.singularize}"
111
+ end
112
+ end
113
+ @user_method
114
+ end
115
+
116
+ def self.settings
117
+ @settings ||= begin
118
+ path = Rails.root.join("config", "blazer.yml").to_s
119
+ if File.exist?(path)
120
+ YAML.safe_load(ERB.new(File.read(path)).result, aliases: true)
121
+ else
122
+ {}
123
+ end
124
+ end
125
+ end
126
+
127
+ def self.data_sources
128
+ @data_sources ||= begin
129
+ ds = Hash.new { |hash, key| raise Blazer::Error, "Unknown data source: #{key}" }
130
+ settings["data_sources"].each do |id, s|
131
+ ds[id] = Blazer::DataSource.new(id, s)
132
+ end
133
+ ds
134
+ end
135
+ end
136
+
137
+ def self.run_checks(schedule: nil)
138
+ checks = Blazer::Check.includes(:query)
139
+ checks = checks.where(schedule: schedule) if schedule
140
+ checks.find_each do |check|
141
+ next if check.state == "disabled"
142
+ Safely.safely { run_check(check) }
143
+ end
144
+ end
145
+
146
+ def self.run_check(check)
147
+ tries = 1
148
+
149
+ ActiveSupport::Notifications.instrument("run_check.blazer", check_id: check.id, query_id: check.query.id, state_was: check.state) do |instrument|
150
+ # try 3 times on timeout errors
151
+ statement = check.query.statement_object
152
+ data_source = statement.data_source
153
+
154
+ while tries <= 3
155
+ result = data_source.run_statement(statement, refresh_cache: true, check: check, query: check.query)
156
+ if result.timed_out?
157
+ Rails.logger.info "[blazer timeout] query=#{check.query.name}"
158
+ tries += 1
159
+ sleep(10)
160
+ elsif result.error.to_s.start_with?("PG::ConnectionBad")
161
+ data_source.reconnect
162
+ Rails.logger.info "[blazer reconnect] query=#{check.query.name}"
163
+ tries += 1
164
+ sleep(10)
165
+ else
166
+ break
167
+ end
168
+ end
169
+
170
+ begin
171
+ check.reload # in case state has changed since job started
172
+ check.update_state(result)
173
+ rescue ActiveRecord::RecordNotFound
174
+ # check deleted
175
+ end
176
+
177
+ # TODO use proper logfmt
178
+ Rails.logger.info "[blazer check] query=#{check.query.name} state=#{check.state} rows=#{result.rows.try(:size)} error=#{result.error}"
179
+
180
+ # should be no variables
181
+ instrument[:statement] = statement.bind_statement
182
+ instrument[:data_source] = data_source
183
+ instrument[:state] = check.state
184
+ instrument[:rows] = result.rows.try(:size)
185
+ instrument[:error] = result.error
186
+ instrument[:tries] = tries
187
+ end
188
+ end
189
+
190
+ def self.send_failing_checks
191
+ emails = {}
192
+ slack_channels = {}
193
+
194
+ Blazer::Check.includes(:query).where(state: ["failing", "error", "timed out", "disabled"]).find_each do |check|
195
+ check.split_emails.each do |email|
196
+ (emails[email] ||= []) << check
197
+ end
198
+ check.split_slack_channels.each do |channel|
199
+ (slack_channels[channel] ||= []) << check
200
+ end
201
+ end
202
+
203
+ emails.each do |email, checks|
204
+ Safely.safely do
205
+ Blazer::CheckMailer.failing_checks(email, checks).deliver_now
206
+ end
207
+ end
208
+
209
+ slack_channels.each do |channel, checks|
210
+ Safely.safely do
211
+ Blazer::SlackNotifier.failing_checks(channel, checks)
212
+ end
213
+ end
214
+ end
215
+
216
+ def self.slack?
217
+ slack_oauth_token.present? || slack_webhook_url.present?
218
+ end
219
+
220
+ # TODO show warning on invalid access token
221
+ def self.maps?
222
+ mapbox_access_token.present? && mapbox_access_token.start_with?("pk.")
223
+ end
224
+
225
+ def self.uploads?
226
+ settings.key?("uploads")
227
+ end
228
+
229
+ def self.uploads_connection
230
+ raise "Empty url for uploads" unless settings.dig("uploads", "url")
231
+ Blazer::UploadsConnection.connection
232
+ end
233
+
234
+ def self.uploads_schema
235
+ settings.dig("uploads", "schema") || "uploads"
236
+ end
237
+
238
+ def self.uploads_table_name(name)
239
+ uploads_connection.quote_table_name("#{uploads_schema}.#{name}")
240
+ end
241
+
242
+ def self.adapters
243
+ @adapters ||= {}
244
+ end
245
+
246
+ def self.register_adapter(name, adapter)
247
+ adapters[name] = adapter
248
+ end
249
+
250
+ def self.anomaly_detectors
251
+ @anomaly_detectors ||= {}
252
+ end
253
+
254
+ def self.register_anomaly_detector(name, &anomaly_detector)
255
+ anomaly_detectors[name] = anomaly_detector
256
+ end
257
+
258
+ def self.forecasters
259
+ @forecasters ||= {}
260
+ end
261
+
262
+ def self.register_forecaster(name, &forecaster)
263
+ forecasters[name] = forecaster
264
+ end
265
+
266
+ def self.archive_queries
267
+ raise "Audits must be enabled to archive" unless Blazer.audit
268
+ raise "Missing status column - see https://github.com/ankane/blazer#23" unless Blazer::Query.column_names.include?("status")
269
+
270
+ viewed_query_ids = Blazer::Audit.where("created_at > ?", 90.days.ago).group(:query_id).count.keys.compact
271
+ Blazer::Query.active.where.not(id: viewed_query_ids).update_all(status: "archived")
272
+ end
273
+
274
+ # private
275
+ def self.monotonic_time
276
+ Process.clock_gettime(Process::CLOCK_MONOTONIC)
277
+ end
278
+ end
279
+
280
+ require_relative "blazer/adapters"
281
+ require_relative "blazer/anomaly_detectors"
282
+ require_relative "blazer/forecasters"
@@ -0,0 +1,22 @@
1
+ require "rails/generators/active_record"
2
+
3
+ module Blazer
4
+ module Generators
5
+ class InstallGenerator < Rails::Generators::Base
6
+ include ActiveRecord::Generators::Migration
7
+ source_root File.join(__dir__, "templates")
8
+
9
+ def copy_migration
10
+ migration_template "install.rb", "db/migrate/install_blazer.rb", migration_version: migration_version
11
+ end
12
+
13
+ def copy_config
14
+ template "config.yml", "config/blazer.yml"
15
+ end
16
+
17
+ def migration_version
18
+ "[#{ActiveRecord::VERSION::MAJOR}.#{ActiveRecord::VERSION::MINOR}]"
19
+ end
20
+ end
21
+ end
22
+ end
@@ -0,0 +1,79 @@
1
+ # see https://github.com/ankane/blazer for more info
2
+
3
+ data_sources:
4
+ main:
5
+ url: <%%= ENV["BLAZER_DATABASE_URL"] %>
6
+
7
+ # statement timeout, in seconds
8
+ # none by default
9
+ # timeout: 15
10
+
11
+ # caching settings
12
+ # can greatly improve speed
13
+ # off by default
14
+ # cache:
15
+ # mode: slow # or all
16
+ # expires_in: 60 # min
17
+ # slow_threshold: 15 # sec, only used in slow mode
18
+
19
+ # wrap queries in a transaction for safety
20
+ # not necessary if you use a read-only user
21
+ # true by default
22
+ # use_transaction: false
23
+
24
+ smart_variables:
25
+ # zone_id: "SELECT id, name FROM zones ORDER BY name ASC"
26
+ # period: ["day", "week", "month"]
27
+ # status: {0: "Active", 1: "Archived"}
28
+
29
+ linked_columns:
30
+ # user_id: "/admin/users/{value}"
31
+
32
+ smart_columns:
33
+ # user_id: "SELECT id, name FROM users WHERE id IN {value}"
34
+
35
+ # create audits
36
+ audit: true
37
+
38
+ # change the time zone
39
+ # time_zone: "Pacific Time (US & Canada)"
40
+
41
+ # class name of the user model
42
+ # user_class: User
43
+
44
+ # method name for the current user
45
+ # user_method: current_user
46
+
47
+ # method name for the display name
48
+ # user_name: name
49
+
50
+ # custom before_action to use for auth
51
+ # before_action_method: require_admin
52
+
53
+ # email to send checks from
54
+ # from_email: blazer@example.org
55
+
56
+ # webhook for Slack
57
+ # slack_webhook_url: <%%= ENV["BLAZER_SLACK_WEBHOOK_URL"] %>
58
+
59
+ check_schedules:
60
+ - "1 day"
61
+ - "1 hour"
62
+ - "5 minutes"
63
+
64
+ # enable anomaly detection
65
+ # note: with trend, time series are sent to https://trendapi.org
66
+ # anomaly_checks: prophet / trend / anomaly_detection
67
+
68
+ # enable forecasting
69
+ # note: with trend, time series are sent to https://trendapi.org
70
+ # forecasting: prophet / trend
71
+
72
+ # enable map
73
+ # mapbox_access_token: <%%= ENV["MAPBOX_ACCESS_TOKEN"] %>
74
+
75
+ # enable uploads
76
+ # uploads:
77
+ # url: <%%= ENV["BLAZER_UPLOADS_URL"] %>
78
+ # schema: uploads
79
+ # data_source: main
@@ -0,0 +1,47 @@
1
+ class <%= migration_class_name %> < ActiveRecord::Migration<%= migration_version %>
2
+ def change
3
+ create_table :blazer_queries do |t|
4
+ t.references :creator
5
+ t.string :name
6
+ t.text :description
7
+ t.text :statement
8
+ t.string :data_source
9
+ t.string :status
10
+ t.timestamps null: false
11
+ end
12
+
13
+ create_table :blazer_audits do |t|
14
+ t.references :user
15
+ t.references :query
16
+ t.text :statement
17
+ t.string :data_source
18
+ t.datetime :created_at
19
+ end
20
+
21
+ create_table :blazer_dashboards do |t|
22
+ t.references :creator
23
+ t.string :name
24
+ t.timestamps null: false
25
+ end
26
+
27
+ create_table :blazer_dashboard_queries do |t|
28
+ t.references :dashboard
29
+ t.references :query
30
+ t.integer :position
31
+ t.timestamps null: false
32
+ end
33
+
34
+ create_table :blazer_checks do |t|
35
+ t.references :creator
36
+ t.references :query
37
+ t.string :state
38
+ t.string :schedule
39
+ t.text :emails
40
+ t.text :slack_channels
41
+ t.string :check_type
42
+ t.text :message
43
+ t.datetime :last_run_at
44
+ t.timestamps null: false
45
+ end
46
+ end
47
+ end
@@ -0,0 +1,10 @@
1
+ class <%= migration_class_name %> < ActiveRecord::Migration<%= migration_version %>
2
+ def change
3
+ create_table :blazer_uploads do |t|
4
+ t.references :creator
5
+ t.string :table
6
+ t.text :description
7
+ t.timestamps null: false
8
+ end
9
+ end
10
+ end
@@ -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
@@ -0,0 +1,20 @@
1
+ namespace :blazer do
2
+ desc "run checks"
3
+ task :run_checks, [:schedule] => :environment do |_, args|
4
+ Blazer.run_checks(schedule: args[:schedule] || ENV["SCHEDULE"])
5
+ end
6
+
7
+ desc "send failing checks"
8
+ task send_failing_checks: :environment do
9
+ Blazer.send_failing_checks
10
+ end
11
+
12
+ desc "archive queries"
13
+ task archive_queries: :environment do
14
+ begin
15
+ Blazer.archive_queries
16
+ rescue => e
17
+ abort e.message
18
+ end
19
+ end
20
+ end
@@ -0,0 +1,24 @@
1
+ Copyright (c) 2010, Ajax.org B.V.
2
+ All rights reserved.
3
+
4
+ Redistribution and use in source and binary forms, with or without
5
+ modification, are permitted provided that the following conditions are met:
6
+ * Redistributions of source code must retain the above copyright
7
+ notice, this list of conditions and the following disclaimer.
8
+ * Redistributions in binary form must reproduce the above copyright
9
+ notice, this list of conditions and the following disclaimer in the
10
+ documentation and/or other materials provided with the distribution.
11
+ * Neither the name of Ajax.org B.V. nor the
12
+ names of its contributors may be used to endorse or promote products
13
+ derived from this software without specific prior written permission.
14
+
15
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
16
+ ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
17
+ WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
18
+ DISCLAIMED. IN NO EVENT SHALL AJAX.ORG B.V. BE LIABLE FOR ANY
19
+ DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
20
+ (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
21
+ LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
22
+ ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
23
+ (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
24
+ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
@@ -0,0 +1,21 @@
1
+ The MIT License (MIT)
2
+
3
+ Copyright (c) 2011-2019 Twitter, Inc.
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in
13
+ all copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21
+ THE SOFTWARE.
@@ -0,0 +1,9 @@
1
+ The MIT License (MIT)
2
+
3
+ Copyright (c) 2014-2022 Chart.js Contributors
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
6
+
7
+ The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
8
+
9
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -0,0 +1,9 @@
1
+ The MIT License (MIT)
2
+
3
+ Copyright (c) 2019 Chart.js Contributors
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
6
+
7
+ The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
8
+
9
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2013-2023 Andrew Kane
2
+
3
+ MIT License
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2021 Sasha Koss and Lesha Koss https://kossnocorp.mit-license.org
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1,21 @@
1
+ The MIT License (MIT)
2
+
3
+ Copyright (c) 2012-2020 Dan Grossman
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in
13
+ all copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21
+ THE SOFTWARE.
@@ -0,0 +1,20 @@
1
+ The MIT License (MIT)
2
+
3
+ Copyright © 2015 Nicolas Bevacqua
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy of
6
+ this software and associated documentation files (the "Software"), to deal in
7
+ the Software without restriction, including without limitation the rights to
8
+ use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
9
+ the Software, and to permit persons to whom the Software is furnished to do so,
10
+ subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
17
+ FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
18
+ COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
19
+ IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
20
+ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -0,0 +1,29 @@
1
+ BSD 3-Clause License
2
+
3
+ Copyright (c) 2006, Ivan Sagalaev.
4
+ All rights reserved.
5
+
6
+ Redistribution and use in source and binary forms, with or without
7
+ modification, are permitted provided that the following conditions are met:
8
+
9
+ * Redistributions of source code must retain the above copyright notice, this
10
+ list of conditions and the following disclaimer.
11
+
12
+ * Redistributions in binary form must reproduce the above copyright notice,
13
+ this list of conditions and the following disclaimer in the documentation
14
+ and/or other materials provided with the distribution.
15
+
16
+ * Neither the name of the copyright holder nor the names of its
17
+ contributors may be used to endorse or promote products derived from
18
+ this software without specific prior written permission.
19
+
20
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
21
+ AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22
+ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
23
+ DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
24
+ FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
25
+ DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
26
+ SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
27
+ CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
28
+ OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
29
+ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.