adhoq 0.0.2
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/LICENSE.txt +22 -0
- data/README.md +80 -0
- data/Rakefile +28 -0
- data/app/assets/javascripts/adhoq/application.js +19 -0
- data/app/assets/javascripts/adhoq/bootstrap-sprockets.js +12 -0
- data/app/assets/javascripts/adhoq/bootstrap.js +2107 -0
- data/app/assets/javascripts/adhoq/bootstrap/affix.js +142 -0
- data/app/assets/javascripts/adhoq/bootstrap/alert.js +92 -0
- data/app/assets/javascripts/adhoq/bootstrap/button.js +110 -0
- data/app/assets/javascripts/adhoq/bootstrap/carousel.js +223 -0
- data/app/assets/javascripts/adhoq/bootstrap/collapse.js +170 -0
- data/app/assets/javascripts/adhoq/bootstrap/dropdown.js +151 -0
- data/app/assets/javascripts/adhoq/bootstrap/modal.js +280 -0
- data/app/assets/javascripts/adhoq/bootstrap/popover.js +113 -0
- data/app/assets/javascripts/adhoq/bootstrap/scrollspy.js +170 -0
- data/app/assets/javascripts/adhoq/bootstrap/tab.js +128 -0
- data/app/assets/javascripts/adhoq/bootstrap/tooltip.js +457 -0
- data/app/assets/javascripts/adhoq/bootstrap/transition.js +59 -0
- data/app/assets/javascripts/adhoq/previewer.js.coffee +25 -0
- data/app/assets/stylesheets/adhoq/_bootstrap-compass.scss +7 -0
- data/app/assets/stylesheets/adhoq/_bootstrap-mincer.scss +17 -0
- data/app/assets/stylesheets/adhoq/_bootstrap-sprockets.scss +7 -0
- data/app/assets/stylesheets/adhoq/adhoq.css.sass +57 -0
- data/app/assets/stylesheets/adhoq/application.css +16 -0
- data/app/assets/stylesheets/adhoq/bootstrap.scss +50 -0
- data/app/assets/stylesheets/adhoq/bootstrap/_alerts.scss +68 -0
- data/app/assets/stylesheets/adhoq/bootstrap/_badges.scss +57 -0
- data/app/assets/stylesheets/adhoq/bootstrap/_breadcrumbs.scss +26 -0
- data/app/assets/stylesheets/adhoq/bootstrap/_button-groups.scss +240 -0
- data/app/assets/stylesheets/adhoq/bootstrap/_buttons.scss +157 -0
- data/app/assets/stylesheets/adhoq/bootstrap/_carousel.scss +243 -0
- data/app/assets/stylesheets/adhoq/bootstrap/_close.scss +35 -0
- data/app/assets/stylesheets/adhoq/bootstrap/_code.scss +68 -0
- data/app/assets/stylesheets/adhoq/bootstrap/_component-animations.scss +35 -0
- data/app/assets/stylesheets/adhoq/bootstrap/_dropdowns.scss +215 -0
- data/app/assets/stylesheets/adhoq/bootstrap/_forms.scss +538 -0
- data/app/assets/stylesheets/adhoq/bootstrap/_glyphicons.scss +237 -0
- data/app/assets/stylesheets/adhoq/bootstrap/_grid.scss +84 -0
- data/app/assets/stylesheets/adhoq/bootstrap/_input-groups.scss +166 -0
- data/app/assets/stylesheets/adhoq/bootstrap/_jumbotron.scss +48 -0
- data/app/assets/stylesheets/adhoq/bootstrap/_labels.scss +66 -0
- data/app/assets/stylesheets/adhoq/bootstrap/_list-group.scss +131 -0
- data/app/assets/stylesheets/adhoq/bootstrap/_media.scss +56 -0
- data/app/assets/stylesheets/adhoq/bootstrap/_mixins.scss +39 -0
- data/app/assets/stylesheets/adhoq/bootstrap/_modals.scss +150 -0
- data/app/assets/stylesheets/adhoq/bootstrap/_navbar.scss +659 -0
- data/app/assets/stylesheets/adhoq/bootstrap/_navs.scss +242 -0
- data/app/assets/stylesheets/adhoq/bootstrap/_normalize.scss +425 -0
- data/app/assets/stylesheets/adhoq/bootstrap/_pager.scss +55 -0
- data/app/assets/stylesheets/adhoq/bootstrap/_pagination.scss +88 -0
- data/app/assets/stylesheets/adhoq/bootstrap/_panels.scss +243 -0
- data/app/assets/stylesheets/adhoq/bootstrap/_popovers.scss +133 -0
- data/app/assets/stylesheets/adhoq/bootstrap/_print.scss +101 -0
- data/app/assets/stylesheets/adhoq/bootstrap/_progress-bars.scss +105 -0
- data/app/assets/stylesheets/adhoq/bootstrap/_responsive-embed.scss +34 -0
- data/app/assets/stylesheets/adhoq/bootstrap/_responsive-utilities.scss +174 -0
- data/app/assets/stylesheets/adhoq/bootstrap/_scaffolding.scss +150 -0
- data/app/assets/stylesheets/adhoq/bootstrap/_tables.scss +233 -0
- data/app/assets/stylesheets/adhoq/bootstrap/_theme.scss +258 -0
- data/app/assets/stylesheets/adhoq/bootstrap/_thumbnails.scss +38 -0
- data/app/assets/stylesheets/adhoq/bootstrap/_tooltip.scss +95 -0
- data/app/assets/stylesheets/adhoq/bootstrap/_type.scss +304 -0
- data/app/assets/stylesheets/adhoq/bootstrap/_utilities.scss +57 -0
- data/app/assets/stylesheets/adhoq/bootstrap/_variables.scss +850 -0
- data/app/assets/stylesheets/adhoq/bootstrap/_wells.scss +29 -0
- data/app/assets/stylesheets/adhoq/bootstrap/bootstrap.scss +50 -0
- data/app/assets/stylesheets/adhoq/bootstrap/mixins/_alerts.scss +14 -0
- data/app/assets/stylesheets/adhoq/bootstrap/mixins/_background-variant.scss +11 -0
- data/app/assets/stylesheets/adhoq/bootstrap/mixins/_border-radius.scss +18 -0
- data/app/assets/stylesheets/adhoq/bootstrap/mixins/_buttons.scss +50 -0
- data/app/assets/stylesheets/adhoq/bootstrap/mixins/_center-block.scss +7 -0
- data/app/assets/stylesheets/adhoq/bootstrap/mixins/_clearfix.scss +22 -0
- data/app/assets/stylesheets/adhoq/bootstrap/mixins/_forms.scss +84 -0
- data/app/assets/stylesheets/adhoq/bootstrap/mixins/_gradients.scss +58 -0
- data/app/assets/stylesheets/adhoq/bootstrap/mixins/_grid-framework.scss +81 -0
- data/app/assets/stylesheets/adhoq/bootstrap/mixins/_grid.scss +122 -0
- data/app/assets/stylesheets/adhoq/bootstrap/mixins/_hide-text.scss +21 -0
- data/app/assets/stylesheets/adhoq/bootstrap/mixins/_image.scss +34 -0
- data/app/assets/stylesheets/adhoq/bootstrap/mixins/_labels.scss +12 -0
- data/app/assets/stylesheets/adhoq/bootstrap/mixins/_list-group.scss +31 -0
- data/app/assets/stylesheets/adhoq/bootstrap/mixins/_nav-divider.scss +10 -0
- data/app/assets/stylesheets/adhoq/bootstrap/mixins/_nav-vertical-align.scss +9 -0
- data/app/assets/stylesheets/adhoq/bootstrap/mixins/_opacity.scss +8 -0
- data/app/assets/stylesheets/adhoq/bootstrap/mixins/_pagination.scss +23 -0
- data/app/assets/stylesheets/adhoq/bootstrap/mixins/_panels.scss +24 -0
- data/app/assets/stylesheets/adhoq/bootstrap/mixins/_progress-bar.scss +10 -0
- data/app/assets/stylesheets/adhoq/bootstrap/mixins/_reset-filter.scss +8 -0
- data/app/assets/stylesheets/adhoq/bootstrap/mixins/_resize.scss +6 -0
- data/app/assets/stylesheets/adhoq/bootstrap/mixins/_responsive-visibility.scss +21 -0
- data/app/assets/stylesheets/adhoq/bootstrap/mixins/_size.scss +10 -0
- data/app/assets/stylesheets/adhoq/bootstrap/mixins/_tab-focus.scss +9 -0
- data/app/assets/stylesheets/adhoq/bootstrap/mixins/_table-row.scss +28 -0
- data/app/assets/stylesheets/adhoq/bootstrap/mixins/_text-emphasis.scss +11 -0
- data/app/assets/stylesheets/adhoq/bootstrap/mixins/_text-overflow.scss +8 -0
- data/app/assets/stylesheets/adhoq/bootstrap/mixins/_vendor-prefixes.scss +219 -0
- data/app/controllers/adhoq/application_controller.rb +5 -0
- data/app/controllers/adhoq/authorization_methods.rb +36 -0
- data/app/controllers/adhoq/executions_controller.rb +25 -0
- data/app/controllers/adhoq/previews_controller.rb +13 -0
- data/app/controllers/adhoq/queries_controller.rb +38 -0
- data/app/helpers/adhoq/application_helper.rb +11 -0
- data/app/models/adhoq/execution.rb +29 -0
- data/app/models/adhoq/query.rb +14 -0
- data/app/models/adhoq/report.rb +42 -0
- data/app/models/adhoq/time_based_orders.rb +9 -0
- data/app/views/adhoq/application/_global_nav.html.slim +11 -0
- data/app/views/adhoq/application/_sidebar_queries_index.html.slim +10 -0
- data/app/views/adhoq/previews/create.html.slim +12 -0
- data/app/views/adhoq/previews/statement_invalid.html.slim +5 -0
- data/app/views/adhoq/queries/_form.html.slim +38 -0
- data/app/views/adhoq/queries/_query.html.slim +43 -0
- data/app/views/adhoq/queries/edit.html.slim +2 -0
- data/app/views/adhoq/queries/index.html.slim +1 -0
- data/app/views/adhoq/queries/new.html.slim +2 -0
- data/app/views/adhoq/queries/show.html.slim +1 -0
- data/app/views/layouts/adhoq/application.html.slim +18 -0
- data/config/routes.rb +9 -0
- data/db/migrate/20141003095645_create_adhoq_queries.rb +11 -0
- data/db/migrate/20141006014750_create_adhoq_executions.rb +13 -0
- data/db/migrate/20141007052308_create_adhoq_reports.rb +12 -0
- data/lib/adhoq.rb +13 -0
- data/lib/adhoq/configuration.rb +21 -0
- data/lib/adhoq/engine.rb +15 -0
- data/lib/adhoq/error.rb +4 -0
- data/lib/adhoq/executor.rb +27 -0
- data/lib/adhoq/global_variable.rb +34 -0
- data/lib/adhoq/reporter.rb +5 -0
- data/lib/adhoq/reporter/xlsx.rb +32 -0
- data/lib/adhoq/result.rb +18 -0
- data/lib/adhoq/storage.rb +5 -0
- data/lib/adhoq/storage/local_file.rb +45 -0
- data/lib/adhoq/version.rb +3 -0
- data/lib/tasks/adhoq_tasks.rake +4 -0
- data/spec/adhoq/executor_spec.rb +11 -0
- data/spec/adhoq/storage_spec.rb +19 -0
- data/spec/factories/adhoq_queries.rb +29 -0
- data/spec/models/adhoq/execution_spec.rb +4 -0
- data/spec/models/adhoq/query_spec.rb +4 -0
- data/spec/models/adhoq/report_spec.rb +25 -0
- data/spec/spec_helper.rb +36 -0
- data/spec/support/have_values_in_xlsx_sheet_matcher.rb +20 -0
- metadata +375 -0
@@ -0,0 +1,36 @@
|
|
1
|
+
module Adhoq
|
2
|
+
module AuthorizationMethods
|
3
|
+
extend ActiveSupport::Concern
|
4
|
+
|
5
|
+
included do |controller|
|
6
|
+
controller.before_action Authorizer.new
|
7
|
+
|
8
|
+
helper_method :adhoq_current_user
|
9
|
+
hide_action :adhoq_current_user
|
10
|
+
end
|
11
|
+
|
12
|
+
class Authorizer
|
13
|
+
def before(controller)
|
14
|
+
return true if authorization.call(controller)
|
15
|
+
|
16
|
+
if failure = Adhoq.config.authorization_failure_action
|
17
|
+
failure.call(controller)
|
18
|
+
else
|
19
|
+
controller.send(:render, text: 'No such file or directory', status: :not_found)
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
private
|
24
|
+
|
25
|
+
def authorization
|
26
|
+
@authorization ||= Adhoq.config.callablize(:authorization)
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
def adhoq_current_user
|
31
|
+
@_adhoq_current_user_proc ||= Adhoq.config.callablize(:current_user)
|
32
|
+
|
33
|
+
@_adhoq_current_user_proc.call(self)
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
module Adhoq
|
2
|
+
class ExecutionsController < ApplicationController
|
3
|
+
def show
|
4
|
+
@execution = current_query.executions.where(id: params[:id], report_format: params[:format]).first!
|
5
|
+
|
6
|
+
respond_report(@execution.report)
|
7
|
+
end
|
8
|
+
|
9
|
+
def create
|
10
|
+
@execution = current_query.execute!(params[:execution][:report_format])
|
11
|
+
|
12
|
+
redirect_to current_query
|
13
|
+
end
|
14
|
+
|
15
|
+
private
|
16
|
+
|
17
|
+
def current_query
|
18
|
+
@query ||= Adhoq::Query.find(params[:query_id])
|
19
|
+
end
|
20
|
+
|
21
|
+
def respond_report(report)
|
22
|
+
send_data report.data.read, type: report.mime_type, filename: report.name, disposition: 'attachment'
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
@@ -0,0 +1,13 @@
|
|
1
|
+
module Adhoq
|
2
|
+
class PreviewsController < ApplicationController
|
3
|
+
layout false
|
4
|
+
|
5
|
+
def create
|
6
|
+
begin
|
7
|
+
@result = Adhoq::Executor.new(params[:query]).execute
|
8
|
+
rescue ActiveRecord::StatementInvalid => @statement_invalid
|
9
|
+
render 'statement_invalid', status: :unprocessable_entity
|
10
|
+
end
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
@@ -0,0 +1,38 @@
|
|
1
|
+
module Adhoq
|
2
|
+
class QueriesController < ApplicationController
|
3
|
+
def index
|
4
|
+
@queries = Adhoq::Query.recent_first
|
5
|
+
end
|
6
|
+
|
7
|
+
def show
|
8
|
+
@query = Adhoq::Query.find(params[:id])
|
9
|
+
end
|
10
|
+
|
11
|
+
def new
|
12
|
+
@query = Adhoq::Query.new
|
13
|
+
end
|
14
|
+
|
15
|
+
def create
|
16
|
+
@query = Adhoq::Query.create!(query_attributes)
|
17
|
+
|
18
|
+
redirect_to @query
|
19
|
+
end
|
20
|
+
|
21
|
+
def edit
|
22
|
+
@query = Adhoq::Query.find(params[:id])
|
23
|
+
end
|
24
|
+
|
25
|
+
def update
|
26
|
+
@query = Adhoq::Query.find(params[:id])
|
27
|
+
@query.update_attributes!(query_attributes)
|
28
|
+
|
29
|
+
redirect_to @query
|
30
|
+
end
|
31
|
+
|
32
|
+
private
|
33
|
+
|
34
|
+
def query_attributes
|
35
|
+
params.require(:query).permit(:name, :description, :query)
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
@@ -0,0 +1,29 @@
|
|
1
|
+
module Adhoq
|
2
|
+
class Execution < ActiveRecord::Base
|
3
|
+
include Adhoq::TimeBasedOrders
|
4
|
+
|
5
|
+
belongs_to :query
|
6
|
+
has_one :report, dependent: :destroy, inverse_of: :execution
|
7
|
+
|
8
|
+
def supported_formats
|
9
|
+
%w[xlsx]
|
10
|
+
end
|
11
|
+
|
12
|
+
def generate_report!
|
13
|
+
build_report.generate!
|
14
|
+
end
|
15
|
+
|
16
|
+
def name
|
17
|
+
[query.name, created_at.strftime('%Y%m%d-%H%M%S'), report_format].join('.')
|
18
|
+
end
|
19
|
+
|
20
|
+
def success?
|
21
|
+
report.try(:success?)
|
22
|
+
end
|
23
|
+
|
24
|
+
# TODO go decorator or view model or so
|
25
|
+
def status_label
|
26
|
+
success? ? :success : :failure
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
@@ -0,0 +1,14 @@
|
|
1
|
+
module Adhoq
|
2
|
+
class Query < ActiveRecord::Base
|
3
|
+
include Adhoq::TimeBasedOrders
|
4
|
+
|
5
|
+
has_many :executions, dependent: :destroy, inverse_of: :query
|
6
|
+
|
7
|
+
def execute!(report_format)
|
8
|
+
executions.create! {|exe|
|
9
|
+
exe.report_format = report_format
|
10
|
+
exe.raw_sql = query
|
11
|
+
}.tap(&:generate_report!)
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
@@ -0,0 +1,42 @@
|
|
1
|
+
module Adhoq
|
2
|
+
class Report < ActiveRecord::Base
|
3
|
+
BUFSIZE = 10.kilobytes.to_i
|
4
|
+
|
5
|
+
belongs_to :execution
|
6
|
+
|
7
|
+
delegate :name, to: 'execution'
|
8
|
+
delegate :mime_type, to: :reporter
|
9
|
+
|
10
|
+
def generate!(storage = Adhoq.current_storage)
|
11
|
+
self.identifier = generate_and_persist_report!(storage)
|
12
|
+
self.generated_at = Time.now
|
13
|
+
self.storage = storage.identifier
|
14
|
+
|
15
|
+
save!
|
16
|
+
end
|
17
|
+
|
18
|
+
def success?
|
19
|
+
data.present?
|
20
|
+
end
|
21
|
+
|
22
|
+
def data(storage = Adhoq.current_storage)
|
23
|
+
storage.get(identifier)
|
24
|
+
end
|
25
|
+
|
26
|
+
private
|
27
|
+
|
28
|
+
def reporter
|
29
|
+
{'xlsx' => Adhoq::Reporter::Xlsx}[execution.report_format]
|
30
|
+
end
|
31
|
+
|
32
|
+
def generate_and_persist_report!(storage)
|
33
|
+
storage.store(".#{execution.report_format}") do |file, *|
|
34
|
+
executor = Executor.new(execution.raw_sql)
|
35
|
+
|
36
|
+
reporter.new(executor.execute).build_report.each(BUFSIZE) do |chunk|
|
37
|
+
file.write chunk
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
@@ -0,0 +1,11 @@
|
|
1
|
+
nav#global-nav.navbar.navbar-default(role='navigation')
|
2
|
+
.container-fluid
|
3
|
+
.navbar-header
|
4
|
+
= link_to 'Adhoq', root_path, class: 'navbar-brand'
|
5
|
+
.navbar-collapse.collapse
|
6
|
+
ul.nav.navbar-nav.navbar-right
|
7
|
+
- if main_app.respond_to?(:root_path)
|
8
|
+
li
|
9
|
+
= link_to main_app.root_path do
|
10
|
+
i.fa.fa-arrow-circle-right.fa-pad-r
|
11
|
+
| Main app
|
@@ -0,0 +1,10 @@
|
|
1
|
+
h2
|
2
|
+
| Queries
|
3
|
+
= link_to 'Create new', :root, class: 'btn btn-primary new-query'
|
4
|
+
ul.queries.list-unstyled
|
5
|
+
- Adhoq::Query.recent_first.each do |query|
|
6
|
+
li.panel.panel-default[query]
|
7
|
+
.panel-heading
|
8
|
+
h2= link_to query.name, query_path(query)
|
9
|
+
p.panel-body.description= query.description
|
10
|
+
|
@@ -0,0 +1,38 @@
|
|
1
|
+
= form_for query, html: {class: 'form form-horizontal query-form', role: 'form'} do |f|
|
2
|
+
.page-header
|
3
|
+
h1
|
4
|
+
= title
|
5
|
+
.actions.btn-in-header
|
6
|
+
button.btn.btn-primary
|
7
|
+
i.fa.fa-floppy-o.fa-pad-r
|
8
|
+
| Save
|
9
|
+
- if f.object.persisted?
|
10
|
+
= link_to 'Cancel', f.object, class: 'btn btn-default'
|
11
|
+
|
12
|
+
.form-group
|
13
|
+
= f.label :name, class: 'col-sm-2 control-label'
|
14
|
+
.col-sm-8
|
15
|
+
= f.text_field :name, class: 'form-control', required: true
|
16
|
+
|
17
|
+
.form-group
|
18
|
+
= f.label :description, class: 'col-sm-2 control-label'
|
19
|
+
.col-sm-8
|
20
|
+
= f.text_area :description, class: 'form-control', required: true
|
21
|
+
|
22
|
+
.form-group
|
23
|
+
= f.label :query, class: 'col-sm-2 control-label'
|
24
|
+
.col-sm-8
|
25
|
+
= f.text_area :query, class: 'form-control', rows: 10, required: true
|
26
|
+
|
27
|
+
.preview
|
28
|
+
h2
|
29
|
+
| Preview
|
30
|
+
.btn-in-header
|
31
|
+
= link_to preview_path, class: 'btn btn-default btn-sm js-preview-button', data: {source: '#query_query', result: '.js-preview-result', remote: true, method: 'POST'} do
|
32
|
+
i.fa.fa-refresh[data-title='Refresh preview']
|
33
|
+
|
34
|
+
.js-preview-result
|
35
|
+
.alert Preview is shown here
|
36
|
+
|
37
|
+
javascript:
|
38
|
+
$(function() { Adhoq.enablePreview($('.preview a.js-preview-button')) })
|
@@ -0,0 +1,43 @@
|
|
1
|
+
section.query
|
2
|
+
.page-header
|
3
|
+
h1
|
4
|
+
= query.name
|
5
|
+
small= "Updated at #{l(query.updated_at, format: :short)}"
|
6
|
+
= link_to [:edit, query], class: 'btn btn-default' do
|
7
|
+
i.fa.fa-pencil.fa-pad-r
|
8
|
+
| Edit
|
9
|
+
p.description= query.description
|
10
|
+
|
11
|
+
pre.query= query.query
|
12
|
+
|
13
|
+
section.new-execution
|
14
|
+
h2 Create report
|
15
|
+
= form_for [query, query.executions.build], html: {class: 'form-inline', role: 'form'} do |f|
|
16
|
+
.form-group.report_format
|
17
|
+
= f.label :report_format
|
18
|
+
= f.select :report_format, f.object.supported_formats, {}, class: 'form-control'
|
19
|
+
.form-group
|
20
|
+
= f.submit 'Create report', class: 'btn btn-default'
|
21
|
+
|
22
|
+
section.past-executions
|
23
|
+
h2 Reports
|
24
|
+
.col-md-10
|
25
|
+
table.executions.table.table-striped.table-hover
|
26
|
+
thead
|
27
|
+
tr
|
28
|
+
th.wip
|
29
|
+
th.created_at= human(Adhoq::Execution, :created_at)
|
30
|
+
th.status= human(Adhoq::Execution, :status)
|
31
|
+
th.report
|
32
|
+
tbody
|
33
|
+
- query.executions.recent_first.each do |exec|
|
34
|
+
tr[exec]
|
35
|
+
td.wip
|
36
|
+
td.created_at= exec.created_at.localtime.iso8601
|
37
|
+
td.status
|
38
|
+
span.label[class=(exec.success? ? 'label-success' : 'label-danger')]= exec.status_label
|
39
|
+
td.report
|
40
|
+
- if exec.success?
|
41
|
+
= link_to([query, exec, format: exec.report_format], class: 'btn btn-sm btn-default') do
|
42
|
+
i.fa.fa-download.fa-pad-r
|
43
|
+
= exec.report_format
|
@@ -0,0 +1 @@
|
|
1
|
+
= render 'query', query: @queries.first
|
@@ -0,0 +1 @@
|
|
1
|
+
= render 'query', query: @query
|
@@ -0,0 +1,18 @@
|
|
1
|
+
doctype html
|
2
|
+
html
|
3
|
+
head
|
4
|
+
title Adhoq
|
5
|
+
= stylesheet_link_tag 'adhoq/application', media: 'all'
|
6
|
+
= javascript_include_tag 'adhoq/application'
|
7
|
+
= csrf_meta_tags
|
8
|
+
|
9
|
+
body
|
10
|
+
.container
|
11
|
+
= render 'global_nav'
|
12
|
+
|
13
|
+
#contents.row
|
14
|
+
#sidebar.col-md-3
|
15
|
+
= render 'sidebar_queries_index'
|
16
|
+
|
17
|
+
#main.col-md-9= yield
|
18
|
+
|
data/config/routes.rb
ADDED
@@ -0,0 +1,13 @@
|
|
1
|
+
class CreateAdhoqExecutions < ActiveRecord::Migration
|
2
|
+
def change
|
3
|
+
create_table :adhoq_executions do |t|
|
4
|
+
t.belongs_to :query, null: false
|
5
|
+
t.text :raw_sql, null: false
|
6
|
+
t.string :report_format, null: false
|
7
|
+
t.string :status, null: false, default: 'requested'
|
8
|
+
t.text :log
|
9
|
+
|
10
|
+
t.timestamps
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
@@ -0,0 +1,12 @@
|
|
1
|
+
class CreateAdhoqReports < ActiveRecord::Migration
|
2
|
+
def change
|
3
|
+
create_table :adhoq_reports do |t|
|
4
|
+
t.belongs_to :execution, null: false, index: true
|
5
|
+
t.string :identifier, null: false
|
6
|
+
t.time :generated_at, null: false
|
7
|
+
t.string :storage, null: false
|
8
|
+
|
9
|
+
t.timestamps
|
10
|
+
end
|
11
|
+
end
|
12
|
+
end
|