app/server.rb in sqlui-0.1.51 vs app/server.rb in sqlui-0.1.52
- old
+ new
@@ -2,12 +2,15 @@
require 'base64'
require 'csv'
require 'erb'
require 'json'
+require 'prometheus/middleware/collector'
+require 'prometheus/middleware/exporter'
require 'sinatra/base'
require 'uri'
+require 'webrick'
require_relative 'database_metadata'
require_relative 'mysql_types'
require_relative 'sql_parser'
require_relative 'sqlui'
@@ -16,10 +19,33 @@
def self.logger
@logger ||= WEBrick::Log.new
end
def self.init_and_run(config, resources_dir)
+ logger.info("Airbrake enabled: #{config.airbrake[:server]&.[](:enabled) || false}")
+ if config.airbrake[:server]&.[](:enabled)
+ require 'airbrake'
+ require 'airbrake/rack'
+
+ Airbrake.configure do |c|
+ c.app_version = File.read('.version').strip
+ c.environment = config.environment
+ c.logger.level = Logger::DEBUG if config.environment != :production?
+ config.airbrake[:server].each do |key, value|
+ c.send("#{key}=".to_sym, value) unless key == :enabled
+ end
+ end
+ Airbrake.add_filter(Airbrake::Rack::RequestBodyFilter.new)
+ Airbrake.add_filter(Airbrake::Rack::HttpParamsFilter.new)
+ Airbrake.add_filter(Airbrake::Rack::HttpHeadersFilter.new)
+ use Airbrake::Rack::Middleware
+ end
+
+ use Rack::Deflater
+ use Prometheus::Middleware::Collector
+ use Prometheus::Middleware::Exporter
+
Mysql2::Client.default_query_options[:as] = :array
Mysql2::Client.default_query_options[:cast_booleans] = true
Mysql2::Client.default_query_options[:database_timezone] = :utc
Mysql2::Client.default_query_options[:cache_rows] = false
@@ -51,21 +77,17 @@
get "#{database.url_path}/?" do
redirect "#{database.url_path}/query", 301
end
get "#{database.url_path}/sqlui.css" do
- @css ||= File.read(File.join(resources_dir, 'sqlui.css'))
- status 200
headers 'Content-Type' => 'text/css; charset=utf-8'
- body @css
+ send_file File.join(resources_dir, 'sqlui.css')
end
get "#{database.url_path}/sqlui.js" do
- @js ||= File.read(File.join(resources_dir, 'sqlui.js'))
- status 200
headers 'Content-Type' => 'text/javascript; charset=utf-8'
- body @js
+ send_file File.join(resources_dir, 'sqlui.js')
end
post "#{database.url_path}/metadata" do
metadata = database.with_client do |client|
{
@@ -97,11 +119,13 @@
headers 'Content-Type' => 'application/json; charset=utf-8'
body metadata.to_json
end
post "#{database.url_path}/query" do
- params.merge!(JSON.parse(request.body.read, symbolize_names: true))
+ data = request.body.read
+ request.body.rewind # since Airbrake will read the body on error
+ params.merge!(JSON.parse(data, symbolize_names: true))
break client_error('missing sql') unless params[:sql]
variables = params[:variables] || {}
sql = find_selected_query(params[:sql], params[:selection])
@@ -109,33 +133,46 @@
headers 'Content-Type' => 'application/json; charset=utf-8'
database.with_client do |client|
query_result = execute_query(client, variables, sql)
stream do |out|
- json = <<~RES.chomp
- {
- "columns": #{query_result.fields.to_json},
- "column_types": #{MysqlTypes.map_to_google_charts_types(query_result.field_types).to_json},
- "total_rows": #{query_result.size.to_json},
- "selection": #{params[:selection].to_json},
- "query": #{params[:sql].to_json},
- "rows": [
- RES
- out << json
- bytes = json.bytesize
- query_result.each_with_index do |row, i|
- json = "#{i.zero? ? '' : ','}\n #{row.to_json}"
- bytes += json.bytesize
- break if i == Sqlui::MAX_ROWS || bytes > Sqlui::MAX_BYTES
-
+ if query_result
+ json = <<~RES.chomp
+ {
+ "columns": #{query_result.fields.to_json},
+ "column_types": #{MysqlTypes.map_to_google_charts_types(query_result.field_types).to_json},
+ "total_rows": #{query_result.size.to_json},
+ "selection": #{params[:selection].to_json},
+ "query": #{params[:sql].to_json},
+ "rows": [
+ RES
out << json
- end
- out << <<~RES
+ bytes = json.bytesize
+ query_result.each_with_index do |row, i|
+ json = "#{i.zero? ? '' : ','}\n #{row.to_json}"
+ bytes += json.bytesize
+ break if i == Sqlui::MAX_ROWS || bytes > Sqlui::MAX_BYTES
- ]
- }
- RES
+ out << json
+ end
+ out << <<~RES
+
+ ]
+ }
+ RES
+ else
+ out << <<~RES
+ {
+ "columns": [],
+ "column_types": [],
+ "total_rows": 0,
+ "selection": #{params[:selection].to_json},
+ "query": #{params[:sql].to_json},
+ "rows": []
+ }
+ RES
+ end
end
end
end
get "#{database.url_path}/download_csv" do
@@ -159,13 +196,17 @@
end
end
end
get(%r{#{Regexp.escape(database.url_path)}/(query|graph|structure|saved)}) do
- @html ||= File.read(File.join(resources_dir, 'sqlui.html'))
status 200
- headers 'Content-Type' => 'text/html; charset=utf-8'
- body @html
+ client_config = config.airbrake[:client] || {}
+ erb :sqlui, locals: {
+ environment: config.environment.to_s,
+ airbrake_enabled: client_config[:enabled] || false,
+ airbrake_project_id: client_config[:project_id] || '',
+ airbrake_project_key: client_config[:project_key] || ''
+ }
end
end
error 400..510 do
exception = env['sinatra.error']