sqltorial 0.0.4 → 0.0.5
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +41 -0
- data/exe/sqltorial +2 -0
- data/lib/sqltorial/assemble_command.rb +8 -2
- data/lib/sqltorial/directives/valid_column_directive.rb +9 -2
- data/lib/sqltorial/metadata.rb +1 -1
- data/lib/sqltorial/query_cache.rb +1 -1
- data/lib/sqltorial/query_to_md.rb +12 -8
- data/lib/sqltorial/sql_to_example.rb +31 -15
- data/sqltorial.gemspec +1 -1
- metadata +4 -4
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: f3ca9d5ba9e65f3a01f00225e743efd0a4be9060
|
4
|
+
data.tar.gz: 4e7f40a198a35b4c14d4a71bb1273b5485680eff
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: bbee4c513b93704a42818553114c40b82fd28945954bf1aa8122c3e626a77de7837cfff17678e62e1f2116298ba04434a124c7523b36933c78ebb0b2827bdf14
|
7
|
+
data.tar.gz: ff37c16257fd820609d68567bb3b80288be467c5551b1b982f8d136a0c2635b8364b7e7c2906cbcc71327ef6fd74aa2c433690b11cc25b98a7a09289cc4c231d
|
data/CHANGELOG.md
CHANGED
@@ -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
|
data/exe/sqltorial
CHANGED
@@ -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(
|
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(
|
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 =
|
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(
|
28
|
+
Directive.register(ValidColumnDirective)
|
22
29
|
end
|
data/lib/sqltorial/metadata.rb
CHANGED
@@ -1,5 +1,5 @@
|
|
1
1
|
module SQLtorial
|
2
|
-
VERSION = "0.0.
|
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"
|
@@ -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
|
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(
|
134
|
-
|
135
|
-
str.
|
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(
|
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(
|
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
|
-
|
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
|
69
|
-
execute(sql,
|
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(
|
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
|
118
|
-
|
117
|
+
def is_use(sql)
|
118
|
+
sql =~ /^\s*use/i
|
119
119
|
end
|
120
120
|
|
121
|
-
def
|
122
|
-
|
123
|
-
|
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(
|
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
|
data/sqltorial.gemspec
CHANGED
@@ -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
|
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
|
+
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-
|
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
|
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
|
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:
|