sqltorial 0.0.4 → 0.0.5

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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: b81ab5d2e41712b52e7b96f1f6332e5a28c2ee01
4
- data.tar.gz: 88ad7165935ab617c70786ddd96546c2545c2e35
3
+ metadata.gz: f3ca9d5ba9e65f3a01f00225e743efd0a4be9060
4
+ data.tar.gz: 4e7f40a198a35b4c14d4a71bb1273b5485680eff
5
5
  SHA512:
6
- metadata.gz: 1cbc570b9ea4c206a0811816e307ab89d05ef6904ea1250dacd4a976d9a9aebfdd59e601c460b3914a2462e76fbd55d4e5d62d4ae8da6cf1ebfdc98a22abec1a
7
- data.tar.gz: dcaf1f0cef469d9ca8fc8b56d15b1b7ff6113368ce1f9c2d3b33a5b8aef26e1c5128166d180d4506df4be0d0483d106edf0e776c3c90ef86ebfedfab04bc8e3a
6
+ metadata.gz: bbee4c513b93704a42818553114c40b82fd28945954bf1aa8122c3e626a77de7837cfff17678e62e1f2116298ba04434a124c7523b36933c78ebb0b2827bdf14
7
+ data.tar.gz: ff37c16257fd820609d68567bb3b80288be467c5551b1b982f8d136a0c2635b8364b7e7c2906cbcc71327ef6fd74aa2c433690b11cc25b98a7a09289cc4c231d
@@ -6,6 +6,47 @@ All notable changes to this project will be documented in this file.
6
6
 
7
7
  ### Added
8
8
 
9
+ - Nothing.
10
+
11
+ ### Deprecated
12
+
13
+ - Nothing.
14
+
15
+ ### Removed
16
+
17
+ - Nothing.
18
+
19
+ ### Fixed
20
+
21
+ - Nothing.
22
+
23
+ ## 0.0.5
24
+
25
+ ### Added
26
+
27
+ - More commas for more types of number columns.
28
+ - Support for several Impala-oriented commands.
29
+ - --ignore-cache option
30
+ - --drop-tables option
31
+
32
+ ### Deprecated
33
+
34
+ - Nothing.
35
+
36
+ ### Removed
37
+
38
+ - Nothing.
39
+
40
+ ### Fixed
41
+
42
+ - ID columns shouldn't end up with commas
43
+ - Markdown lists should render properly
44
+ - Handle NULL values in columns
45
+
46
+ ## 0.0.4
47
+
48
+ ### Added
49
+
9
50
  - Watch mode.
10
51
 
11
52
  ### Deprecated
@@ -11,6 +11,8 @@ Escort::App.create do |app|
11
11
 
12
12
  app.options do |opts|
13
13
  opts.opt :no_results, "Don't Include Results", short: '-n', long: '--no-results', type: :boolean, default: false
14
+ opts.opt :drop_it, "Drop tables before create", short: '-D', long: '--drop-tables', type: :boolean, default: false
15
+ opts.opt :ignore_cache, "Ignore cache", short: '-C', long: '--ignore-cache', type: :boolean, default: false
14
16
  opts.opt :output, "Output File", short: '-o', long: '--output', type: :string, default: 'output.md'
15
17
  opts.opt :preface, "Preface File", short: '-p', long: '--preface', type: :string, default: 'preface.md'
16
18
  opts.opt :watch, "Watch Mode", short: '-w', long: '--watch', type: :boolean, default: false
@@ -2,6 +2,7 @@ require_relative 'sql_to_example'
2
2
  require 'sequelizer'
3
3
  require 'facets/pathname/chdir'
4
4
  require 'listen'
5
+ require "fileutils"
5
6
 
6
7
  module SQLtorial
7
8
  class AssembleCommand < ::Escort::ActionCommand::Base
@@ -11,7 +12,7 @@ module SQLtorial
11
12
  end
12
13
 
13
14
  def watch
14
- listener = Listen.to(path) do |modified, added, removed|
15
+ listener = Listen.to(dir) do |modified, added, removed|
15
16
  process
16
17
  end
17
18
  listener.only(/\.sql$/)
@@ -20,13 +21,14 @@ module SQLtorial
20
21
  end
21
22
 
22
23
  def process
24
+ FileUtils.rm_rf(".sqltorial_cache") if global_options[:ignore_cache]
23
25
  process_dir.chdir do
24
26
  preface = Pathname.new(global_options[:preface]) if global_options[:preface]
25
27
  File.open(global_options[:output], 'w') do |f|
26
28
  f.puts preface.read if preface && preface.exist?
27
29
  examples = files.map.with_index do |file, index|
28
30
  Escort::Logger.output.puts "Examplizing #{file.to_s}"
29
- SqlToExample.new(file, db, index + 1).to_str(!global_options[:no_results])
31
+ SqlToExample.new(file, db, index + 1).to_str(global_options)
30
32
  end
31
33
  f.puts(examples.join("\n\n"))
32
34
  end
@@ -37,6 +39,10 @@ module SQLtorial
37
39
  @process_dir = path.directory? ? path : Pathname.pwd
38
40
  end
39
41
 
42
+ def dir
43
+ @dir ||= path.directory? ? path : path.dirname
44
+ end
45
+
40
46
  def path
41
47
  @path ||= Pathname.new(arguments.first || ".")
42
48
  end
@@ -1,6 +1,13 @@
1
1
  module SQLtorial
2
2
  class ValidColumnDirective
3
- REGEXP = /^ DIRECTIVE:\s*(\S+)\s+(\S+)\s+(.+)/
3
+ REGEXP = /^\s*DIRECTIVE:\s*(\S+)\s+(\S+)\s+(.+)/
4
+
5
+ class << self
6
+ def regexp
7
+ REGEXP
8
+ end
9
+ end
10
+
4
11
  attr :column, :op, :matcher
5
12
  def initialize(line)
6
13
  _, column, op, matcher = REGEXP.match(line).to_a
@@ -18,5 +25,5 @@ module SQLtorial
18
25
  [column, op, matcher].join(" ")
19
26
  end
20
27
  end
21
- Directive.register(AllDirective)
28
+ Directive.register(ValidColumnDirective)
22
29
  end
@@ -1,5 +1,5 @@
1
1
  module SQLtorial
2
- VERSION = "0.0.4"
2
+ VERSION = "0.0.5"
3
3
  SUMMARY = %q{Knitr, but for SQL files, sorta}
4
4
  DESCRIPTION = %q{Ingests a set of commented SQL statements, executes them, and dumps the comments, queries, and results into a markdown file}
5
5
  HOMEPAGE = "http://github.com/outcomesinsights/sqltorial"
@@ -21,7 +21,7 @@ module SQLtorial
21
21
  end
22
22
 
23
23
  def cache_file
24
- @cache_file ||= Pathname.pwd + '.cache' + cache_file_name
24
+ @cache_file ||= Pathname.pwd + '.sqltorial_cache' + cache_file_name
25
25
  end
26
26
 
27
27
  def cache_file_name
@@ -24,9 +24,9 @@ module SQLtorial
24
24
  def get_md
25
25
  return "**No results found.**" if all.empty?
26
26
  output = []
27
- output << "Found #{count} results."
27
+ output << "Found #{commatize(count)} results."
28
28
  if count > row_limit
29
- output.last << " Displaying first #{row_limit}."
29
+ output.last << " Displaying first #{commatize(row_limit)}."
30
30
  end
31
31
  output << ""
32
32
  output << tableize(all.first.keys + additional_headers)
@@ -84,7 +84,7 @@ module SQLtorial
84
84
 
85
85
  def make_processors
86
86
  output_rows.first.map do |name, column|
87
- if name.to_s.end_with?('_id')
87
+ if name.to_s =~ /_?id(_|$)/
88
88
  Proc.new do |column|
89
89
  column.to_s.chomp
90
90
  end
@@ -92,11 +92,11 @@ module SQLtorial
92
92
  case column
93
93
  when Float, BigDecimal
94
94
  Proc.new do |column|
95
- sprintf("%.02f", column)
95
+ column ? commatize(sprintf("%.02f", column)) : nil
96
96
  end
97
97
  when Numeric, Fixnum
98
98
  Proc.new do |column|
99
- commatize(column.to_s)
99
+ column ? commatize(column.to_s) : nil
100
100
  end
101
101
  else
102
102
  Proc.new do |column|
@@ -130,9 +130,13 @@ module SQLtorial
130
130
  widths.map { |width| '-' * width }
131
131
  end
132
132
 
133
- def commatize(str)
134
- return str unless str =~ /^\d+$/
135
- str.reverse.chars.each_slice(3).map(&:join).join(',').reverse
133
+ def commatize(input)
134
+ str = input.to_s
135
+ return str unless str =~ /^[\d.]+$/
136
+ str, dec = str.split('.')
137
+ commaed = str.reverse.chars.each_slice(3).map(&:join).join(',').reverse
138
+ commaed << ".#{dec}" if dec and !dec.empty?
139
+ commaed
136
140
  end
137
141
 
138
142
  def cache
@@ -48,29 +48,29 @@ module SQLtorial
48
48
  lines.shift while lines.first.strip.empty?
49
49
  prose_lines << lines.shift.sub(WHITESPACE_REGEX, ' ').sub(/^\s*$/, "\n\n") while lines.first && (lines.first =~ WHITESPACE_REGEX || lines.first.empty?)
50
50
  directives, prose_lines = prose_lines.partition { |line| Directive.match(line) }
51
- [prose_lines.join(''), process_directives(directives), lines.join]
51
+ [prose_lines.map(&:strip).join("\n"), process_directives(directives), lines.join("\n")]
52
52
  end
53
53
 
54
54
  def number
55
55
  @number ||= file.basename.to_s.to_i
56
56
  end
57
57
 
58
- def to_str(include_results = true)
58
+ def to_str(options = {})
59
+ options = options.merge(include_results: true)
59
60
  hash = {}
60
61
  queries.each_with_index do |query, index|
61
62
  prose, directives, sql = make_prose_directives_and_query(query)
62
63
 
63
64
  begin
64
65
  if is_create(sql)
65
- execute(sql, include_results)
66
- hash[sql] = [prose, create_to_md(include_results, sql, directives)];
66
+ hash[sql] = [prose, create_to_md(options, sql, directives)];
67
67
  next
68
- elsif is_drop(sql)
69
- execute(sql, include_results)
68
+ elsif is_passthru(sql)
69
+ execute(sql, options)
70
70
  hash[sql] = [prose, nil];
71
71
  next
72
72
  end
73
- hash[sql] = [prose, query_to_md(include_results, sql, directives)]
73
+ hash[sql] = [prose, query_to_md(options, sql, directives)]
74
74
  rescue
75
75
  puts sql
76
76
  puts $!.message
@@ -90,7 +90,7 @@ module SQLtorial
90
90
  arr << value.last
91
91
  arr.join("\n\n")
92
92
  end
93
- parts.join("\n") + "\n\n"
93
+ parts.join("\n\n") + "\n\n"
94
94
  end
95
95
 
96
96
  private
@@ -114,18 +114,34 @@ module SQLtorial
114
114
  sql =~ /^\s*drop/i
115
115
  end
116
116
 
117
- def execute(sql, include_results)
118
- db.execute(sql) if include_results
117
+ def is_use(sql)
118
+ sql =~ /^\s*use/i
119
119
  end
120
120
 
121
- def create_to_md(include_results, sql, directives)
122
- return nil unless include_results
123
- table_name = /create\s*(?:temp)?\s*(?:table|view)\s*(\S+)/i.match(sql)[1].gsub('.', '__')
121
+ def is_compute(sql)
122
+ sql =~ /^\s*compute\s*stats/i
123
+ end
124
+
125
+ def is_passthru(sql)
126
+ is_drop(sql) || is_use(sql) || is_compute(sql)
127
+ end
128
+
129
+ def execute(sql, options)
130
+ db.execute(sql) if options[:include_results]
131
+ end
132
+
133
+ def create_to_md(options, sql, directives)
134
+ return nil unless options[:include_results]
135
+ table_name = /create\s*(?:temp)?\s*(?:table|view)(?:\s*if\s*not\s*exists)?\s*(\S+)/i.match(sql)[1]
136
+ execute("DROP TABLE IF EXISTS #{table_name}", options) if options[:drop_it]
137
+ execute(sql, options)
138
+ execute("COMPUTE STATS #{table_name}", options)
139
+ table_name.gsub!('.', '__')
124
140
  QueryToMD.new(db[table_name.to_sym], directives).to_md
125
141
  end
126
142
 
127
- def query_to_md(include_results, sql, directives)
128
- return nil unless include_results
143
+ def query_to_md(options, sql, directives)
144
+ return nil unless options[:include_results]
129
145
  return nil if sql.empty?
130
146
  QueryToMD.new(db[sql.sub(';', '')], directives).to_md
131
147
  end
@@ -33,5 +33,5 @@ Gem::Specification.new do |spec|
33
33
  spec.add_dependency "anbt-sql-formatter", "~> 0.0.3"
34
34
  spec.add_dependency "facets", "~> 3.0"
35
35
  spec.add_dependency "escort", "~> 0.4.0"
36
- spec.add_dependency "listen", "~> 3.0.0"
36
+ spec.add_dependency "listen", "~> 3.0"
37
37
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: sqltorial
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.4
4
+ version: 0.0.5
5
5
  platform: ruby
6
6
  authors:
7
7
  - Ryan Duryea
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2015-09-04 00:00:00.000000000 Z
11
+ date: 2015-10-23 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -100,14 +100,14 @@ dependencies:
100
100
  requirements:
101
101
  - - "~>"
102
102
  - !ruby/object:Gem::Version
103
- version: 3.0.0
103
+ version: '3.0'
104
104
  type: :runtime
105
105
  prerelease: false
106
106
  version_requirements: !ruby/object:Gem::Requirement
107
107
  requirements:
108
108
  - - "~>"
109
109
  - !ruby/object:Gem::Version
110
- version: 3.0.0
110
+ version: '3.0'
111
111
  description: Ingests a set of commented SQL statements, executes them, and dumps the
112
112
  comments, queries, and results into a markdown file
113
113
  email: