adhoq 0.0.3 → 0.0.4

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: a9fac13cfa25151dce3d5c579c39ba8098f07b6f
4
- data.tar.gz: 23f822e233cc7977a2461dbe681a30d2426fffd5
3
+ metadata.gz: fbc8da6ce746ea5888241cae9f548cd431c84ac6
4
+ data.tar.gz: 8bda628674e5dba8625e09b9be76d728b79f714f
5
5
  SHA512:
6
- metadata.gz: f6d1804945abba5952f20f671f68e5fab9141d474dfdcc70aab8a6317cd3c975296e244b6d480a27a2e19066ec2c56eeaadde874ddd3617281275b23c08de6bb
7
- data.tar.gz: 25dac12d074dff4dead41cb23271447737f237103aa494f4148b509b0a6f8cb30be2c1bd3aff9e63fe83763836c744be5249e48422d78d290afdd26685473904
6
+ metadata.gz: 7d606c2dabc3d3b92952355f688d57d9c5abc402502347654130079b52575d81b5ad00efb72fe5725019129b251c28b271ef044ce48b66c010b03abae939d361
7
+ data.tar.gz: 51b8b0c6c041d6034dbb7f7450c2586225a116755cd64fa644a9928a0be0086efd543982dfd9b132891bb417644e1ab2ad7432e794b6248b72022fd5988a2f4b
@@ -0,0 +1,13 @@
1
+ module Adhoq
2
+ class ExplainsController < ApplicationController
3
+ layout false
4
+
5
+ def create
6
+ begin
7
+ @result = Adhoq::Executor.new(params[:query]).explain
8
+ rescue ActiveRecord::StatementInvalid => @statement_invalid
9
+ render 'statement_invalid', status: :unprocessable_entity
10
+ end
11
+ end
12
+ end
13
+ end
@@ -5,9 +5,7 @@ module Adhoq
5
5
  belongs_to :query
6
6
  has_one :report, dependent: :destroy, inverse_of: :execution
7
7
 
8
- def supported_formats
9
- %w[xlsx]
10
- end
8
+ delegate :supported_formats, to: Adhoq::Reporter
11
9
 
12
10
  def generate_report!
13
11
  build_report.generate!
@@ -23,7 +23,7 @@ ul.list-unstyled.tables
23
23
  tbody
24
24
  - ar_class.columns.each do |column|
25
25
  tr
26
- td.pk.icon= column.primary ? icon_fa('check-circle') : ''
26
+ td.pk.icon= column.name == ar_class.primary_key ? icon_fa('check-circle') : ''
27
27
  td.monospace= column.name
28
28
  td= column.type
29
29
  td.null.icon= column.null ? '' : icon_fa('check')
@@ -0,0 +1,2 @@
1
+ pre
2
+ = @result
@@ -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
+
@@ -29,6 +29,10 @@ ul.nav.nav-tabs[role='tablist']
29
29
  a[role='tab' data-toggle='tab' href='#preview' ]
30
30
  i.fa.fa-eye.fa-pad-r
31
31
  | Preview
32
+ li
33
+ a[role='tab' data-toggle='tab' href='#explain' ]
34
+ i.fa.fa-info.fa-pad-r
35
+ | Explain
32
36
  li
33
37
  a[role='tab' data-toggle='tab' href='#current-tables']
34
38
  i.fa.fa-database.fa-pad-r
@@ -46,12 +50,24 @@ ul.nav.nav-tabs[role='tablist']
46
50
  .js-preview-result
47
51
  .alert.alert-info Preview is shown here
48
52
 
53
+ #explain.tab-pane
54
+ h3
55
+ | Query explain
56
+ small
57
+ = link_to explain_path, class: 'js-explain-button', data: {source: '#query_query', result: '.js-explain-result', remote: true, method: 'POST'} do
58
+ i.fa.fa-refresh.fa-pad-r[data-title='Refresh explain']
59
+ | Reflesh
60
+
61
+ .js-explain-result
62
+ .alert.alert-info Explain result is shown here
63
+
49
64
  #current-tables.tab-pane
50
65
  a.loading[href=current_tables_path]
51
66
 
52
67
  javascript:
53
68
  $(function() {
54
69
  Adhoq.enablePreview($('#preview a.js-preview-button'));
70
+ Adhoq.enablePreview($('#explain a.js-explain-button'));
55
71
 
56
72
  $('a[data-toggle="tab"]').on('show.bs.tab', function(ev) { Adhoq.loadCurrentTableTabOnce($(ev.target)) });
57
73
  });
@@ -6,5 +6,6 @@ Adhoq::Engine.routes.draw do
6
6
  end
7
7
 
8
8
  resource :preview, only: 'create'
9
+ resource :explain, only: 'create'
9
10
  resources :current_tables, only: 'index'
10
11
  end
@@ -7,6 +7,12 @@ module Adhoq
7
7
  end
8
8
  end
9
9
 
10
+ def explain(query)
11
+ with_sandbox do
12
+ current_connection.explain(query)
13
+ end
14
+ end
15
+
10
16
  def current_connection
11
17
  ActiveRecord::Base.connection
12
18
  end
@@ -29,6 +35,10 @@ module Adhoq
29
35
  wrap_result(self.class.select(@query))
30
36
  end
31
37
 
38
+ def explain
39
+ self.class.explain(@query)
40
+ end
41
+
32
42
  private
33
43
 
34
44
  def wrap_result(ar_result)
@@ -1,5 +1,9 @@
1
1
  module Adhoq
2
2
  module Reporter
3
+ class UnsupportedFormat < Adhoq::Error; end
4
+
5
+ autoload 'Csv', 'adhoq/reporter/csv'
6
+ autoload 'Json', 'adhoq/reporter/json'
3
7
  autoload 'Xlsx', 'adhoq/reporter/xlsx'
4
8
 
5
9
  class << self
@@ -11,8 +15,21 @@ module Adhoq
11
15
  end
12
16
 
13
17
  def lookup(format)
14
- @map ||= {'xlsx' => Adhoq::Reporter::Xlsx}
15
- @map[format]
18
+ reporters[format.to_s] || raise(UnsupportedFormat)
19
+ end
20
+
21
+ def supported_formats
22
+ reporters.keys.sort
23
+ end
24
+
25
+ private
26
+
27
+ def reporters
28
+ @reporters ||= {
29
+ 'csv' => Adhoq::Reporter::Csv,
30
+ 'json' => Adhoq::Reporter::Json,
31
+ 'xlsx' => Adhoq::Reporter::Xlsx,
32
+ }
16
33
  end
17
34
  end
18
35
  end
@@ -0,0 +1,26 @@
1
+ require 'csv'
2
+
3
+ module Adhoq
4
+ module Reporter
5
+ class Csv
6
+
7
+ def self.mime_type
8
+ 'text/csv; charset=UTF-8'
9
+ end
10
+
11
+ def initialize(result)
12
+ @result = result
13
+ end
14
+
15
+ def build_report
16
+ file = Tempfile.new(['adhoq-reporter', '.csv'], Dir.tmpdir, encoding: 'UTF-8')
17
+ csv = CSV.new(file)
18
+
19
+ csv << @result.header
20
+ @result.rows.each {|row| csv << row }
21
+
22
+ file.tap(&:rewind)
23
+ end
24
+ end
25
+ end
26
+ end
@@ -0,0 +1,31 @@
1
+ require 'json'
2
+
3
+ module Adhoq
4
+ module Reporter
5
+ class Json
6
+
7
+ def self.mime_type
8
+ 'application/json'
9
+ end
10
+
11
+ def initialize(result)
12
+ @result = result
13
+ end
14
+
15
+ def build_report
16
+ file = Tempfile.new(['adhoq-reporter', '.csv'], Dir.tmpdir, encoding: 'UTF-8')
17
+ write_content!(file)
18
+
19
+ file.tap(&:rewind)
20
+ end
21
+
22
+ private
23
+
24
+ def write_content!(file)
25
+ json_objects = @result.rows.map {|row| Hash[*@result.header.zip(row).flatten] }
26
+
27
+ file.write(JSON.dump(json_objects))
28
+ end
29
+ end
30
+ end
31
+ end
@@ -1,3 +1,3 @@
1
1
  module Adhoq
2
- VERSION = "0.0.3"
2
+ VERSION = "0.0.4"
3
3
  end
@@ -0,0 +1,25 @@
1
+ require 'csv'
2
+
3
+ module Adhoq
4
+ RSpec.describe Reporter::Csv, type: :model do
5
+ describe '.mime_type' do
6
+ specify { expect(Adhoq::Reporter::Csv.mime_type).to eq 'text/csv; charset=UTF-8' }
7
+ end
8
+
9
+ context 'create xlsx report' do
10
+ let(:report_data) do
11
+ ex = Adhoq::AdhocExecution.new('csv', attributes_for(:adhoq_query, :greeting)[:query])
12
+
13
+ Adhoq::Reporter.generate(ex)
14
+ end
15
+
16
+ specify do
17
+ expect(CSV.parse(report_data.read)).to eq [
18
+ %w[name description],
19
+ ['hello', 'English greeting message']
20
+ ]
21
+ end
22
+ end
23
+ end
24
+ end
25
+
@@ -0,0 +1,28 @@
1
+ require 'json'
2
+
3
+ module Adhoq
4
+ RSpec.describe Reporter::Json, type: :model do
5
+ describe '.mime_type' do
6
+ specify { expect(Adhoq::Reporter::Json.mime_type).to eq 'application/json' }
7
+ end
8
+
9
+ context 'create xlsx report' do
10
+ let(:report_data) do
11
+ ex = Adhoq::AdhocExecution.new('json', attributes_for(:adhoq_query, :greeting)[:query])
12
+
13
+ Adhoq::Reporter.generate(ex)
14
+ end
15
+
16
+ specify do
17
+ expect(JSON.parse(report_data.read)).to eq [
18
+ {
19
+ 'name' => 'hello',
20
+ 'description' => 'English greeting message'
21
+ }
22
+ ]
23
+ end
24
+ end
25
+ end
26
+ end
27
+
28
+
@@ -2,9 +2,9 @@ module Adhoq
2
2
  RSpec.describe Reporter::Xlsx, type: :model do
3
3
  context 'create xlsx report' do
4
4
  let(:report_data) do
5
- Adhoq::Reporter.generate(Adhoq::AdhocExecution.new('xlsx', <<-SQL.strip_heredoc))
6
- SELECT "hello" AS name ,"English greeting message" AS description
7
- SQL
5
+ ex = Adhoq::AdhocExecution.new('xlsx', attributes_for(:adhoq_query, :greeting)[:query])
6
+
7
+ Adhoq::Reporter.generate(ex)
8
8
  end
9
9
 
10
10
  specify do
@@ -25,5 +25,11 @@ FactoryGirl.define do
25
25
  use_count DESC, id ASC
26
26
  SQL
27
27
  end
28
+
29
+ trait :greeting do
30
+ name 'greeting'
31
+ description 'Static query for testing data'
32
+ query 'SELECT "hello" AS name ,"English greeting message" AS description'
33
+ end
28
34
  end
29
35
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: adhoq
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.3
4
+ version: 0.0.4
5
5
  platform: ruby
6
6
  authors:
7
7
  - Kyosuke MOROHASHI
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2014-10-16 00:00:00.000000000 Z
11
+ date: 2015-06-08 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rails
@@ -184,14 +184,14 @@ dependencies:
184
184
  requirements:
185
185
  - - "~>"
186
186
  - !ruby/object:Gem::Version
187
- version: 1.5.1
187
+ version: 1.6.0
188
188
  type: :development
189
189
  prerelease: false
190
190
  version_requirements: !ruby/object:Gem::Requirement
191
191
  requirements:
192
192
  - - "~>"
193
193
  - !ruby/object:Gem::Version
194
- version: 1.5.1
194
+ version: 1.6.0
195
195
  - !ruby/object:Gem::Dependency
196
196
  name: pry-byebug
197
197
  requirement: !ruby/object:Gem::Requirement
@@ -369,6 +369,7 @@ files:
369
369
  - app/controllers/adhoq/authorization_methods.rb
370
370
  - app/controllers/adhoq/current_tables_controller.rb
371
371
  - app/controllers/adhoq/executions_controller.rb
372
+ - app/controllers/adhoq/explains_controller.rb
372
373
  - app/controllers/adhoq/previews_controller.rb
373
374
  - app/controllers/adhoq/queries_controller.rb
374
375
  - app/helpers/adhoq/application_helper.rb
@@ -379,6 +380,8 @@ files:
379
380
  - app/views/adhoq/application/_global_nav.html.slim
380
381
  - app/views/adhoq/application/_sidebar_queries_index.html.slim
381
382
  - app/views/adhoq/current_tables/index.html.slim
383
+ - app/views/adhoq/explains/create.html.slim
384
+ - app/views/adhoq/explains/statement_invalid.html.slim
382
385
  - app/views/adhoq/previews/create.html.slim
383
386
  - app/views/adhoq/previews/statement_invalid.html.slim
384
387
  - app/views/adhoq/queries/_form.html.slim
@@ -400,6 +403,8 @@ files:
400
403
  - lib/adhoq/executor.rb
401
404
  - lib/adhoq/global_variable.rb
402
405
  - lib/adhoq/reporter.rb
406
+ - lib/adhoq/reporter/csv.rb
407
+ - lib/adhoq/reporter/json.rb
403
408
  - lib/adhoq/reporter/xlsx.rb
404
409
  - lib/adhoq/result.rb
405
410
  - lib/adhoq/storage.rb
@@ -410,6 +415,8 @@ files:
410
415
  - lib/tasks/adhoq_tasks.rake
411
416
  - spec/adhoq/executor_spec.rb
412
417
  - spec/adhoq/global_variable_spec.rb
418
+ - spec/adhoq/reporter/csv_spec.rb
419
+ - spec/adhoq/reporter/json_spec.rb
413
420
  - spec/adhoq/reporter/xlsx_spec.rb
414
421
  - spec/adhoq/storage_spec.rb
415
422
  - spec/factories/adhoq_queries.rb
@@ -447,6 +454,8 @@ summary: DB management console in the wild.
447
454
  test_files:
448
455
  - spec/adhoq/executor_spec.rb
449
456
  - spec/adhoq/global_variable_spec.rb
457
+ - spec/adhoq/reporter/csv_spec.rb
458
+ - spec/adhoq/reporter/json_spec.rb
450
459
  - spec/adhoq/reporter/xlsx_spec.rb
451
460
  - spec/adhoq/storage_spec.rb
452
461
  - spec/factories/adhoq_queries.rb