def run_statement(statement, comment)
require "json"
require "net/http"
require "uri"
columns = []
rows = []
error = nil
statement = statement.gsub(/--.+/, "")
statement = statement.gsub(/\/\*.+\*\//, "")
statement = statement.sub(/;\s*\z/, "")
statement = statement.squish
uri = URI(settings["url"])
uri.query = URI.encode_www_form("$query" => statement)
req = Net::HTTP::Get.new(uri)
req["X-App-Token"] = settings["app_token"] if settings["app_token"]
options = {
use_ssl: uri.scheme == "https",
open_timeout: 3,
read_timeout: 30
}
begin
res = Net::HTTP.start(uri.hostname, uri.port, options) do |http|
http.request(req)
end
if res.is_a?(Net::HTTPSuccess)
body = JSON.parse(res.body)
columns = JSON.parse(res["x-soda2-fields"])
column_types = columns.zip(JSON.parse(res["x-soda2-types"])).to_h
columns.reject! { |f| f.start_with?(":@") }
rows = body.map { |r| columns.map { |c| r[c] } }
columns.each_with_index do |column, i|
case column_types[column]
when "number"
if rows.all? { |r| r[i].to_i == r[i].to_f }
rows.each do |row|
row[i] = row[i].to_i
end
else
rows.each do |row|
row[i] = row[i].to_f
end
end
when "floating_timestamp"
if rows.all? { |r| r[i].end_with?("T00:00:00.000") }
rows.each do |row|
row[i] = Date.parse(row[i])
end
else
utc = ActiveSupport::TimeZone["Etc/UTC"]
rows.each do |row|
row[i] = utc.parse(row[i])
end
end
end
end
else
error = JSON.parse(res.body)["message"] rescue "Bad response: #{res.code}"
end
rescue => e
error = e.message
end
[columns, rows, error]
end