adhoq 0.0.2

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 (143) hide show
  1. checksums.yaml +7 -0
  2. data/LICENSE.txt +22 -0
  3. data/README.md +80 -0
  4. data/Rakefile +28 -0
  5. data/app/assets/javascripts/adhoq/application.js +19 -0
  6. data/app/assets/javascripts/adhoq/bootstrap-sprockets.js +12 -0
  7. data/app/assets/javascripts/adhoq/bootstrap.js +2107 -0
  8. data/app/assets/javascripts/adhoq/bootstrap/affix.js +142 -0
  9. data/app/assets/javascripts/adhoq/bootstrap/alert.js +92 -0
  10. data/app/assets/javascripts/adhoq/bootstrap/button.js +110 -0
  11. data/app/assets/javascripts/adhoq/bootstrap/carousel.js +223 -0
  12. data/app/assets/javascripts/adhoq/bootstrap/collapse.js +170 -0
  13. data/app/assets/javascripts/adhoq/bootstrap/dropdown.js +151 -0
  14. data/app/assets/javascripts/adhoq/bootstrap/modal.js +280 -0
  15. data/app/assets/javascripts/adhoq/bootstrap/popover.js +113 -0
  16. data/app/assets/javascripts/adhoq/bootstrap/scrollspy.js +170 -0
  17. data/app/assets/javascripts/adhoq/bootstrap/tab.js +128 -0
  18. data/app/assets/javascripts/adhoq/bootstrap/tooltip.js +457 -0
  19. data/app/assets/javascripts/adhoq/bootstrap/transition.js +59 -0
  20. data/app/assets/javascripts/adhoq/previewer.js.coffee +25 -0
  21. data/app/assets/stylesheets/adhoq/_bootstrap-compass.scss +7 -0
  22. data/app/assets/stylesheets/adhoq/_bootstrap-mincer.scss +17 -0
  23. data/app/assets/stylesheets/adhoq/_bootstrap-sprockets.scss +7 -0
  24. data/app/assets/stylesheets/adhoq/adhoq.css.sass +57 -0
  25. data/app/assets/stylesheets/adhoq/application.css +16 -0
  26. data/app/assets/stylesheets/adhoq/bootstrap.scss +50 -0
  27. data/app/assets/stylesheets/adhoq/bootstrap/_alerts.scss +68 -0
  28. data/app/assets/stylesheets/adhoq/bootstrap/_badges.scss +57 -0
  29. data/app/assets/stylesheets/adhoq/bootstrap/_breadcrumbs.scss +26 -0
  30. data/app/assets/stylesheets/adhoq/bootstrap/_button-groups.scss +240 -0
  31. data/app/assets/stylesheets/adhoq/bootstrap/_buttons.scss +157 -0
  32. data/app/assets/stylesheets/adhoq/bootstrap/_carousel.scss +243 -0
  33. data/app/assets/stylesheets/adhoq/bootstrap/_close.scss +35 -0
  34. data/app/assets/stylesheets/adhoq/bootstrap/_code.scss +68 -0
  35. data/app/assets/stylesheets/adhoq/bootstrap/_component-animations.scss +35 -0
  36. data/app/assets/stylesheets/adhoq/bootstrap/_dropdowns.scss +215 -0
  37. data/app/assets/stylesheets/adhoq/bootstrap/_forms.scss +538 -0
  38. data/app/assets/stylesheets/adhoq/bootstrap/_glyphicons.scss +237 -0
  39. data/app/assets/stylesheets/adhoq/bootstrap/_grid.scss +84 -0
  40. data/app/assets/stylesheets/adhoq/bootstrap/_input-groups.scss +166 -0
  41. data/app/assets/stylesheets/adhoq/bootstrap/_jumbotron.scss +48 -0
  42. data/app/assets/stylesheets/adhoq/bootstrap/_labels.scss +66 -0
  43. data/app/assets/stylesheets/adhoq/bootstrap/_list-group.scss +131 -0
  44. data/app/assets/stylesheets/adhoq/bootstrap/_media.scss +56 -0
  45. data/app/assets/stylesheets/adhoq/bootstrap/_mixins.scss +39 -0
  46. data/app/assets/stylesheets/adhoq/bootstrap/_modals.scss +150 -0
  47. data/app/assets/stylesheets/adhoq/bootstrap/_navbar.scss +659 -0
  48. data/app/assets/stylesheets/adhoq/bootstrap/_navs.scss +242 -0
  49. data/app/assets/stylesheets/adhoq/bootstrap/_normalize.scss +425 -0
  50. data/app/assets/stylesheets/adhoq/bootstrap/_pager.scss +55 -0
  51. data/app/assets/stylesheets/adhoq/bootstrap/_pagination.scss +88 -0
  52. data/app/assets/stylesheets/adhoq/bootstrap/_panels.scss +243 -0
  53. data/app/assets/stylesheets/adhoq/bootstrap/_popovers.scss +133 -0
  54. data/app/assets/stylesheets/adhoq/bootstrap/_print.scss +101 -0
  55. data/app/assets/stylesheets/adhoq/bootstrap/_progress-bars.scss +105 -0
  56. data/app/assets/stylesheets/adhoq/bootstrap/_responsive-embed.scss +34 -0
  57. data/app/assets/stylesheets/adhoq/bootstrap/_responsive-utilities.scss +174 -0
  58. data/app/assets/stylesheets/adhoq/bootstrap/_scaffolding.scss +150 -0
  59. data/app/assets/stylesheets/adhoq/bootstrap/_tables.scss +233 -0
  60. data/app/assets/stylesheets/adhoq/bootstrap/_theme.scss +258 -0
  61. data/app/assets/stylesheets/adhoq/bootstrap/_thumbnails.scss +38 -0
  62. data/app/assets/stylesheets/adhoq/bootstrap/_tooltip.scss +95 -0
  63. data/app/assets/stylesheets/adhoq/bootstrap/_type.scss +304 -0
  64. data/app/assets/stylesheets/adhoq/bootstrap/_utilities.scss +57 -0
  65. data/app/assets/stylesheets/adhoq/bootstrap/_variables.scss +850 -0
  66. data/app/assets/stylesheets/adhoq/bootstrap/_wells.scss +29 -0
  67. data/app/assets/stylesheets/adhoq/bootstrap/bootstrap.scss +50 -0
  68. data/app/assets/stylesheets/adhoq/bootstrap/mixins/_alerts.scss +14 -0
  69. data/app/assets/stylesheets/adhoq/bootstrap/mixins/_background-variant.scss +11 -0
  70. data/app/assets/stylesheets/adhoq/bootstrap/mixins/_border-radius.scss +18 -0
  71. data/app/assets/stylesheets/adhoq/bootstrap/mixins/_buttons.scss +50 -0
  72. data/app/assets/stylesheets/adhoq/bootstrap/mixins/_center-block.scss +7 -0
  73. data/app/assets/stylesheets/adhoq/bootstrap/mixins/_clearfix.scss +22 -0
  74. data/app/assets/stylesheets/adhoq/bootstrap/mixins/_forms.scss +84 -0
  75. data/app/assets/stylesheets/adhoq/bootstrap/mixins/_gradients.scss +58 -0
  76. data/app/assets/stylesheets/adhoq/bootstrap/mixins/_grid-framework.scss +81 -0
  77. data/app/assets/stylesheets/adhoq/bootstrap/mixins/_grid.scss +122 -0
  78. data/app/assets/stylesheets/adhoq/bootstrap/mixins/_hide-text.scss +21 -0
  79. data/app/assets/stylesheets/adhoq/bootstrap/mixins/_image.scss +34 -0
  80. data/app/assets/stylesheets/adhoq/bootstrap/mixins/_labels.scss +12 -0
  81. data/app/assets/stylesheets/adhoq/bootstrap/mixins/_list-group.scss +31 -0
  82. data/app/assets/stylesheets/adhoq/bootstrap/mixins/_nav-divider.scss +10 -0
  83. data/app/assets/stylesheets/adhoq/bootstrap/mixins/_nav-vertical-align.scss +9 -0
  84. data/app/assets/stylesheets/adhoq/bootstrap/mixins/_opacity.scss +8 -0
  85. data/app/assets/stylesheets/adhoq/bootstrap/mixins/_pagination.scss +23 -0
  86. data/app/assets/stylesheets/adhoq/bootstrap/mixins/_panels.scss +24 -0
  87. data/app/assets/stylesheets/adhoq/bootstrap/mixins/_progress-bar.scss +10 -0
  88. data/app/assets/stylesheets/adhoq/bootstrap/mixins/_reset-filter.scss +8 -0
  89. data/app/assets/stylesheets/adhoq/bootstrap/mixins/_resize.scss +6 -0
  90. data/app/assets/stylesheets/adhoq/bootstrap/mixins/_responsive-visibility.scss +21 -0
  91. data/app/assets/stylesheets/adhoq/bootstrap/mixins/_size.scss +10 -0
  92. data/app/assets/stylesheets/adhoq/bootstrap/mixins/_tab-focus.scss +9 -0
  93. data/app/assets/stylesheets/adhoq/bootstrap/mixins/_table-row.scss +28 -0
  94. data/app/assets/stylesheets/adhoq/bootstrap/mixins/_text-emphasis.scss +11 -0
  95. data/app/assets/stylesheets/adhoq/bootstrap/mixins/_text-overflow.scss +8 -0
  96. data/app/assets/stylesheets/adhoq/bootstrap/mixins/_vendor-prefixes.scss +219 -0
  97. data/app/controllers/adhoq/application_controller.rb +5 -0
  98. data/app/controllers/adhoq/authorization_methods.rb +36 -0
  99. data/app/controllers/adhoq/executions_controller.rb +25 -0
  100. data/app/controllers/adhoq/previews_controller.rb +13 -0
  101. data/app/controllers/adhoq/queries_controller.rb +38 -0
  102. data/app/helpers/adhoq/application_helper.rb +11 -0
  103. data/app/models/adhoq/execution.rb +29 -0
  104. data/app/models/adhoq/query.rb +14 -0
  105. data/app/models/adhoq/report.rb +42 -0
  106. data/app/models/adhoq/time_based_orders.rb +9 -0
  107. data/app/views/adhoq/application/_global_nav.html.slim +11 -0
  108. data/app/views/adhoq/application/_sidebar_queries_index.html.slim +10 -0
  109. data/app/views/adhoq/previews/create.html.slim +12 -0
  110. data/app/views/adhoq/previews/statement_invalid.html.slim +5 -0
  111. data/app/views/adhoq/queries/_form.html.slim +38 -0
  112. data/app/views/adhoq/queries/_query.html.slim +43 -0
  113. data/app/views/adhoq/queries/edit.html.slim +2 -0
  114. data/app/views/adhoq/queries/index.html.slim +1 -0
  115. data/app/views/adhoq/queries/new.html.slim +2 -0
  116. data/app/views/adhoq/queries/show.html.slim +1 -0
  117. data/app/views/layouts/adhoq/application.html.slim +18 -0
  118. data/config/routes.rb +9 -0
  119. data/db/migrate/20141003095645_create_adhoq_queries.rb +11 -0
  120. data/db/migrate/20141006014750_create_adhoq_executions.rb +13 -0
  121. data/db/migrate/20141007052308_create_adhoq_reports.rb +12 -0
  122. data/lib/adhoq.rb +13 -0
  123. data/lib/adhoq/configuration.rb +21 -0
  124. data/lib/adhoq/engine.rb +15 -0
  125. data/lib/adhoq/error.rb +4 -0
  126. data/lib/adhoq/executor.rb +27 -0
  127. data/lib/adhoq/global_variable.rb +34 -0
  128. data/lib/adhoq/reporter.rb +5 -0
  129. data/lib/adhoq/reporter/xlsx.rb +32 -0
  130. data/lib/adhoq/result.rb +18 -0
  131. data/lib/adhoq/storage.rb +5 -0
  132. data/lib/adhoq/storage/local_file.rb +45 -0
  133. data/lib/adhoq/version.rb +3 -0
  134. data/lib/tasks/adhoq_tasks.rake +4 -0
  135. data/spec/adhoq/executor_spec.rb +11 -0
  136. data/spec/adhoq/storage_spec.rb +19 -0
  137. data/spec/factories/adhoq_queries.rb +29 -0
  138. data/spec/models/adhoq/execution_spec.rb +4 -0
  139. data/spec/models/adhoq/query_spec.rb +4 -0
  140. data/spec/models/adhoq/report_spec.rb +25 -0
  141. data/spec/spec_helper.rb +36 -0
  142. data/spec/support/have_values_in_xlsx_sheet_matcher.rb +20 -0
  143. metadata +375 -0
@@ -0,0 +1,5 @@
1
+ module Adhoq
2
+ class ApplicationController < ::ApplicationController
3
+ include Adhoq::AuthorizationMethods
4
+ end
5
+ end
@@ -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,11 @@
1
+ module Adhoq
2
+ module ApplicationHelper
3
+ def human(klass, attr = nil)
4
+ if attr
5
+ klass.human_attribute_name(attr)
6
+ else
7
+ klass.model_name.humanize
8
+ end
9
+ end
10
+ end
11
+ 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,9 @@
1
+ module Adhoq
2
+ module TimeBasedOrders
3
+ extend ActiveSupport::Concern
4
+
5
+ included do
6
+ scope :recent_first, -> { order("#{quoted_table_name}.updated_at DESC") }
7
+ end
8
+ end
9
+ 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,12 @@
1
+ p.note #{@result.rows.size} rows
2
+
3
+ table.table.table-striped.table-focus
4
+ thead
5
+ tr
6
+ - @result.header.each do |column|
7
+ th= column
8
+ tbody
9
+ - @result.rows.take(100).each do |row|
10
+ tr
11
+ - row.each do |val|
12
+ td= val
@@ -0,0 +1,5 @@
1
+ p.statement-invalid.alert.alert-danger
2
+ strong= @statement_invalid.original_exception.class
3
+ br
4
+ = @statement_invalid.original_exception.message
5
+
@@ -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 &nbsp;
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,2 @@
1
+ section.edit-query
2
+ = render 'form', query: @query, title: 'Edit query'
@@ -0,0 +1 @@
1
+ = render 'query', query: @queries.first
@@ -0,0 +1,2 @@
1
+ section.new-query
2
+ = render 'form', query: @query, title: 'New query'
@@ -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
+
@@ -0,0 +1,9 @@
1
+ Adhoq::Engine.routes.draw do
2
+ root to: 'queries#new'
3
+
4
+ resources :queries, path: 'q', except: %w(new) do
5
+ resources :executions, only: %w(create show)
6
+ end
7
+
8
+ resource :preview, only: 'create'
9
+ end
@@ -0,0 +1,11 @@
1
+ class CreateAdhoqQueries < ActiveRecord::Migration
2
+ def change
3
+ create_table :adhoq_queries do |t|
4
+ t.string :name
5
+ t.string :description
6
+ t.text :query
7
+
8
+ t.timestamps
9
+ end
10
+ end
11
+ end
@@ -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