dbplot 0.0.3 → 0.0.4
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.
- data/VERSION +1 -1
- data/bin/dbplot +2 -4
- data/dbplot.gemspec +6 -4
- data/lib/dbplot/runner.rb +5 -0
- data/lib/dbplot/template.r.erb +11 -0
- data/lib/dbplot.rb +92 -65
- metadata +3 -2
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.0.
|
1
|
+
0.0.4
|
data/bin/dbplot
CHANGED
@@ -1,8 +1,6 @@
|
|
1
1
|
#!/usr/bin/env ruby
|
2
2
|
|
3
|
-
|
4
|
-
|
5
|
-
require 'dbplot'
|
6
|
-
require 'dbplot/runner'
|
3
|
+
require File.expand_path('lib/dbplot')
|
4
|
+
require File.expand_path('lib/dbplot/runner')
|
7
5
|
|
8
6
|
DbPlot::Runner.start
|
data/dbplot.gemspec
CHANGED
@@ -1,15 +1,15 @@
|
|
1
1
|
# Generated by jeweler
|
2
|
-
# DO NOT EDIT THIS FILE
|
3
|
-
# Instead, edit Jeweler::Tasks in Rakefile, and run
|
2
|
+
# DO NOT EDIT THIS FILE DIRECTLY
|
3
|
+
# Instead, edit Jeweler::Tasks in Rakefile, and run the gemspec command
|
4
4
|
# -*- encoding: utf-8 -*-
|
5
5
|
|
6
6
|
Gem::Specification.new do |s|
|
7
7
|
s.name = %q{dbplot}
|
8
|
-
s.version = "0.0.
|
8
|
+
s.version = "0.0.4"
|
9
9
|
|
10
10
|
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
11
11
|
s.authors = ["Jacob Rothstein"]
|
12
|
-
s.date = %q{
|
12
|
+
s.date = %q{2010-02-17}
|
13
13
|
s.default_executable = %q{dbplot}
|
14
14
|
s.description = %q{ruby glue between sql and r (ggplot2)}
|
15
15
|
s.email = %q{github@jacobrothstein.com}
|
@@ -29,6 +29,7 @@ Gem::Specification.new do |s|
|
|
29
29
|
"dbplot.gemspec",
|
30
30
|
"lib/dbplot.rb",
|
31
31
|
"lib/dbplot/runner.rb",
|
32
|
+
"lib/dbplot/template.r.erb",
|
32
33
|
"test/dbplot_test.rb",
|
33
34
|
"test/test_helper.rb"
|
34
35
|
]
|
@@ -55,3 +56,4 @@ Gem::Specification.new do |s|
|
|
55
56
|
s.add_dependency(%q<enumerable-proxy>, [">= 0"])
|
56
57
|
end
|
57
58
|
end
|
59
|
+
|
data/lib/dbplot/runner.rb
CHANGED
@@ -14,6 +14,11 @@ class DbPlot
|
|
14
14
|
on("-p", "--password PASSWORD", "MySQL Password") {|p| d.settings[:password] = p }
|
15
15
|
on("-d", "--database DATABASE", "MySQL Database") {|db| d.settings[:database] = db }
|
16
16
|
on("-q", "--query QUERY", "dbplot query") {|q| d.string = q.gsub(/;?$/, ";") }
|
17
|
+
on("--width WIDTH", "pdf width") {|w| d.settings[:width] = w}
|
18
|
+
on("--height HEIGHT", "pdf height") {|w| d.settings[:height] = h}
|
19
|
+
on("--template TEMPLATE_FILE", "use alternate template") do |t|
|
20
|
+
d.settings[:template_file] = t
|
21
|
+
end
|
17
22
|
on("--version", "Print version info and exit") {puts DbPlot.version;exit}
|
18
23
|
on "--dry-run", "Print but do not execute. Implies -v." do |dry|
|
19
24
|
d.debug = d.settings[:dry_run] = true
|
@@ -0,0 +1,11 @@
|
|
1
|
+
require(ggplot2);
|
2
|
+
require(RMySQL);
|
3
|
+
|
4
|
+
con <- dbConnect(MySQL(), user="<%=@settings[:username]%>",
|
5
|
+
password="<%=@settings[:password]%>", dbname="<%=@settings[:database]%>",
|
6
|
+
host="<%=@settings[:host]%>");
|
7
|
+
|
8
|
+
pdf('<%=@file%>', width = <%=@settings[:width]%>, height = <%=@settings[:height]%>);
|
9
|
+
qplot(<%=@qplot.join(", ")%>, data=dbGetQuery(con, "<%=@query%>"));
|
10
|
+
dev.off()
|
11
|
+
|
data/lib/dbplot.rb
CHANGED
@@ -2,99 +2,63 @@ require 'rubygems'
|
|
2
2
|
require 'mysql'
|
3
3
|
require 'enumerable_proxy'
|
4
4
|
require 'readline'
|
5
|
+
require 'erb'
|
5
6
|
|
6
7
|
class DbPlot
|
7
8
|
attr_accessor :settings, :debug, :data, :string
|
8
9
|
|
9
10
|
def self.version
|
10
|
-
"DbPlot v" +
|
11
|
+
"DbPlot v" + version_string
|
11
12
|
end
|
12
|
-
|
13
|
-
def
|
14
|
-
@settings
|
13
|
+
|
14
|
+
def settings
|
15
|
+
@settings ||= {
|
15
16
|
:host => 'localhost',
|
16
17
|
:username => 'root',
|
17
18
|
:password => 'password',
|
18
|
-
:database => ''
|
19
|
+
:database => '',
|
20
|
+
:width => 5,
|
21
|
+
:height => 5
|
19
22
|
}
|
20
|
-
|
21
|
-
|
23
|
+
end
|
24
|
+
|
25
|
+
def initialize(options = {})
|
26
|
+
%w(host database username password).proxy(:map).to_sym.each do |setting|
|
22
27
|
settings[setting] = options[setting] if options[setting]
|
23
28
|
end
|
24
29
|
end
|
25
30
|
|
31
|
+
def template_file
|
32
|
+
settings[:template_file] || File.instance_eval {expand_path(join(dirname(__FILE__), 'dbplot', 'template.r.erb'))}
|
33
|
+
end
|
34
|
+
|
26
35
|
def execute
|
27
36
|
return unless complete?
|
28
37
|
|
29
|
-
|
30
|
-
"#{col}#{" AS #{col_alias}" if col_alias}"
|
31
|
-
end.join(", ")
|
38
|
+
@query = %{SELECT #{select_string} FROM #{@table}}
|
32
39
|
|
33
|
-
|
40
|
+
template = ERB.new(File.read(template_file)).result(binding)
|
34
41
|
|
35
|
-
template = %{
|
36
|
-
require(ggplot2);
|
37
|
-
require(RMySQL);
|
38
|
-
|
39
|
-
con <- dbConnect(MySQL(), user="#{settings[:username]}",
|
40
|
-
password="#{settings[:password]}", dbname="#{settings[:database]}",
|
41
|
-
host="#{settings[:host]}");
|
42
|
-
|
43
|
-
data <- dbGetQuery(con, "#{@query}")
|
44
|
-
|
45
|
-
pdf('#{@file}', width = 11, height = 8.5);
|
46
|
-
|
47
|
-
qplot(#{@qplot.join(", ")}, data=data);
|
48
|
-
|
49
|
-
dev.off()
|
50
|
-
}
|
51
42
|
puts template if debug
|
43
|
+
|
52
44
|
unless settings[:dry_run]
|
53
45
|
`echo \"#{template.gsub('"', '\\"')}\" | r --no-save #{"2>&1 > /dev/null" unless debug}`
|
54
46
|
end
|
55
47
|
@string = nil
|
56
48
|
end
|
57
|
-
|
58
|
-
def parse
|
59
|
-
name_regex = /[a-z_]+/
|
60
|
-
|
61
|
-
if string =~ /plot (#{name_regex})(?: as (#{name_regex}))? vs (#{name_regex})(?: as (#{name_regex}))? from (#{name_regex})/i
|
62
|
-
@ordinate, @ordinate_alias, @abscissa, @abscissa_alias, @table = $1, $2, $3, $4, $5
|
63
49
|
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
@ordinate_alias || @ordinate
|
71
|
-
]
|
72
|
-
|
73
|
-
if string =~ /into ([a-z._]+.pdf)/
|
74
|
-
@file = $1
|
75
|
-
end
|
76
|
-
|
77
|
-
if string =~ /color by (#{name_regex})(?: as (#{name_regex}))?/i
|
78
|
-
@needed_columns[$1] = $2
|
79
|
-
@qplot << "colour = #{$2 || $1}"
|
80
|
-
end
|
81
|
-
|
82
|
-
if string =~ /facet by (#{name_regex})(?: as (#{name_regex}))?(?: vs (#{name_regex})(?: as (#{name_regex}))?)?/i
|
83
|
-
@needed_columns[$1] = $2
|
84
|
-
if $3
|
85
|
-
@needed_columns[$3] = $4
|
86
|
-
@qplot << "facets = #{$2 || $1}~#{$4 || $3}"
|
87
|
-
else
|
88
|
-
@qplot << "facets = ~#{$2 || $1}"
|
89
|
-
end
|
90
|
-
end
|
91
|
-
|
50
|
+
def parse
|
51
|
+
if legal_expression?
|
52
|
+
set_defaults
|
53
|
+
set_file
|
54
|
+
set_color_by
|
55
|
+
set_facet_by
|
92
56
|
else
|
93
57
|
puts "\ncould not parse: \"#{string}\"\n\n"
|
94
58
|
@string = nil
|
95
59
|
end
|
96
60
|
|
97
|
-
|
61
|
+
self
|
98
62
|
end
|
99
63
|
|
100
64
|
def parse_line(string)
|
@@ -106,14 +70,77 @@ class DbPlot
|
|
106
70
|
end
|
107
71
|
|
108
72
|
def complete?
|
109
|
-
@string =~
|
73
|
+
@string =~ /;\s*$/
|
74
|
+
end
|
75
|
+
|
76
|
+
|
77
|
+
def prompt
|
78
|
+
@string.nil? ? 'dbplot> ' : ' -> '
|
79
|
+
end
|
80
|
+
|
81
|
+
|
82
|
+
private
|
83
|
+
|
84
|
+
def select_string
|
85
|
+
@needed_columns.map do |col, col_alias|
|
86
|
+
"#{col}#{" AS #{col_alias}" if col_alias}"
|
87
|
+
end.join(", ")
|
88
|
+
end
|
89
|
+
|
90
|
+
def legal_expression?
|
91
|
+
name_regex = /[a-z_]+/
|
92
|
+
|
93
|
+
if string =~ /plot (#{name_regex})(?: as (#{name_regex}))? vs (#{name_regex})(?: as (#{name_regex}))? from (#{name_regex})/i
|
94
|
+
@ordinate, @ordinate_alias, @abscissa, @abscissa_alias, @table = $1, $2, $3, $4, $5
|
95
|
+
true
|
96
|
+
end
|
97
|
+
end
|
98
|
+
|
99
|
+
def set_file
|
100
|
+
if string =~ /into ([a-z._]+.pdf)/
|
101
|
+
@file = $1
|
102
|
+
else
|
103
|
+
@file = "out.pdf"
|
104
|
+
end
|
105
|
+
end
|
106
|
+
|
107
|
+
def set_defaults
|
108
|
+
@needed_columns = {@ordinate => @ordinate_alias, @abscissa => @abscissa_alias}
|
109
|
+
|
110
|
+
@qplot = [
|
111
|
+
@abscissa_alias || @abscissa,
|
112
|
+
@ordinate_alias || @ordinate
|
113
|
+
]
|
114
|
+
end
|
115
|
+
|
116
|
+
def set_color_by
|
117
|
+
name_regex = /[a-z_]+/
|
118
|
+
|
119
|
+
if string =~ /color by (#{name_regex})(?: as (#{name_regex}))?/i
|
120
|
+
@needed_columns[$1] = $2
|
121
|
+
@qplot << "colour = #{$2 || $1}"
|
122
|
+
end
|
123
|
+
end
|
124
|
+
|
125
|
+
def set_facet_by
|
126
|
+
name_regex = /[a-z_]+/
|
127
|
+
|
128
|
+
if string =~ /facet by (#{name_regex})(?: as (#{name_regex}))?(?: vs (#{name_regex})(?: as (#{name_regex}))?)?/i
|
129
|
+
@needed_columns[$1] = $2
|
130
|
+
if $3
|
131
|
+
@needed_columns[$3] = $4
|
132
|
+
@qplot << "facets = #{$2 || $1}~#{$4 || $3}"
|
133
|
+
else
|
134
|
+
@qplot << "facets = ~#{$2 || $1}"
|
135
|
+
end
|
136
|
+
end
|
110
137
|
end
|
111
138
|
|
112
139
|
def strip_comments
|
113
140
|
@string.gsub /#.+$/, ''
|
114
141
|
end
|
115
142
|
|
116
|
-
def
|
117
|
-
|
143
|
+
def self.version_string
|
144
|
+
File.instance_eval { read(expand_path(join(dirname(__FILE__), '..', "VERSION"))) }
|
118
145
|
end
|
119
146
|
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: dbplot
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.4
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Jacob Rothstein
|
@@ -9,7 +9,7 @@ autorequire:
|
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
11
|
|
12
|
-
date:
|
12
|
+
date: 2010-02-17 00:00:00 -08:00
|
13
13
|
default_executable: dbplot
|
14
14
|
dependencies:
|
15
15
|
- !ruby/object:Gem::Dependency
|
@@ -42,6 +42,7 @@ files:
|
|
42
42
|
- dbplot.gemspec
|
43
43
|
- lib/dbplot.rb
|
44
44
|
- lib/dbplot/runner.rb
|
45
|
+
- lib/dbplot/template.r.erb
|
45
46
|
- test/dbplot_test.rb
|
46
47
|
- test/test_helper.rb
|
47
48
|
has_rdoc: true
|