ruport 0.4.17 → 0.4.19
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/CHANGELOG +22 -2
- data/Rakefile +4 -1
- data/lib/ruport.rb +17 -7
- data/lib/ruport/config.rb +39 -44
- data/lib/ruport/data/record.rb +7 -8
- data/lib/ruport/data/table.rb +39 -5
- data/lib/ruport/data_set.rb +13 -14
- data/lib/ruport/format.rb +10 -10
- data/lib/ruport/format/engine.rb +19 -16
- data/lib/ruport/format/open_node.rb +4 -4
- data/lib/ruport/format/plugin.rb +20 -17
- data/lib/ruport/meta_tools.rb +27 -4
- data/lib/ruport/query.rb +5 -5
- data/lib/ruport/rails/reportable.rb +7 -0
- data/lib/ruport/report.rb +16 -4
- data/test/tc_config.rb +0 -13
- data/test/tc_data_set.rb +3 -0
- data/test/tc_format.rb +1 -0
- data/test/tc_format_engine.rb +1 -0
- data/test/tc_plugin.rb +9 -0
- data/test/tc_ruport.rb +1 -1
- data/test/tc_table.rb +52 -0
- data/test/unit.log +1331 -0
- metadata +2 -2
data/lib/ruport/format/engine.rb
CHANGED
@@ -1,29 +1,30 @@
|
|
1
1
|
module Ruport
|
2
2
|
class Format::Engine
|
3
3
|
require "forwardable"
|
4
|
+
require "enumerator"
|
4
5
|
class << self
|
5
6
|
|
6
7
|
include Enumerable
|
7
8
|
include MetaTools
|
8
9
|
extend Forwardable
|
9
10
|
|
10
|
-
attr_accessor :
|
11
|
+
attr_accessor :engine_classes
|
11
12
|
attr_reader :plugin
|
12
13
|
attr_reader :data
|
13
|
-
attr_accessor :
|
14
|
+
attr_accessor :class_binding
|
14
15
|
attr_reader :options
|
15
16
|
|
16
17
|
def_delegator :@data, :each
|
17
|
-
private :attribute, :attributes, :
|
18
|
+
private :attribute, :attributes, :singleton_class, :action
|
18
19
|
|
19
20
|
def renderer(&block)
|
20
21
|
block = lambda { data } unless block_given?
|
21
|
-
|
22
|
+
singleton_class.send(:define_method, :render,&block)
|
22
23
|
end
|
23
24
|
|
24
25
|
def alias_engine(klass,name)
|
25
|
-
Format::Engine.
|
26
|
-
Format::Engine.
|
26
|
+
Format::Engine.engine_classes ||= {}
|
27
|
+
Format::Engine.engine_classes[name] = klass
|
27
28
|
end
|
28
29
|
|
29
30
|
def data=(data)
|
@@ -49,7 +50,7 @@ module Ruport
|
|
49
50
|
|
50
51
|
def apply_erb
|
51
52
|
active_plugin.data =
|
52
|
-
ERB.new(active_plugin.data).result(
|
53
|
+
ERB.new(active_plugin.data).result(class_binding || binding)
|
53
54
|
end
|
54
55
|
|
55
56
|
def render
|
@@ -57,7 +58,7 @@ module Ruport
|
|
57
58
|
raise "No data provided" unless data
|
58
59
|
active_plugin.data = data.dup
|
59
60
|
if active_plugin.respond_to? :init_plugin_helper
|
60
|
-
|
61
|
+
active_plugin.init_plugin_helper(self)
|
61
62
|
end
|
62
63
|
end
|
63
64
|
|
@@ -66,7 +67,7 @@ module Ruport
|
|
66
67
|
end
|
67
68
|
|
68
69
|
def accept_format_plugin(klass)
|
69
|
-
format_plugins[klass.
|
70
|
+
format_plugins[klass.plugin_name] = klass
|
70
71
|
end
|
71
72
|
|
72
73
|
private
|
@@ -83,12 +84,14 @@ module Ruport
|
|
83
84
|
format_plugins.values
|
84
85
|
end
|
85
86
|
|
86
|
-
def method_missing(id)
|
87
|
+
def method_missing(id,*args)
|
87
88
|
super unless active_plugin.respond_to?("#{id}_helper")
|
88
89
|
return active_plugin.send("#{id}_helper",self)
|
89
90
|
end
|
90
91
|
|
91
92
|
end
|
93
|
+
|
94
|
+
private_class_method :new
|
92
95
|
end
|
93
96
|
|
94
97
|
class Format::Engine::Table < Format::Engine
|
@@ -99,7 +102,7 @@ module Ruport
|
|
99
102
|
build_field_names if (data.respond_to?(:column_names) &&
|
100
103
|
data.column_names && show_field_names)
|
101
104
|
a = active_plugin.render_table
|
102
|
-
|
105
|
+
end
|
103
106
|
|
104
107
|
class << self
|
105
108
|
|
@@ -112,12 +115,12 @@ module Ruport
|
|
112
115
|
end
|
113
116
|
|
114
117
|
def prune(limit=data[0].length)
|
115
|
-
|
118
|
+
limit.times do |field|
|
116
119
|
last = ""
|
117
|
-
data.
|
118
|
-
next if
|
119
|
-
last =
|
120
|
-
|
120
|
+
data.each_cons(2) { |l,e|
|
121
|
+
next if field.nonzero? && e[field-1]
|
122
|
+
last = l[field] if l[field]
|
123
|
+
e[field] = nil if e[field] == last
|
121
124
|
}
|
122
125
|
end
|
123
126
|
end
|
@@ -11,12 +11,12 @@ module Ruport
|
|
11
11
|
@my_name = my_name
|
12
12
|
super(options)
|
13
13
|
self.name = name
|
14
|
-
|
15
|
-
|
14
|
+
send(@my_children_name) ||
|
15
|
+
send("#{@my_children_name}=".to_sym,{})
|
16
16
|
end
|
17
17
|
|
18
|
-
|
19
|
-
|
18
|
+
def each(&p)
|
19
|
+
send(@my_children_name).values.each(&p)
|
20
20
|
end
|
21
21
|
|
22
22
|
def add_child(klass,name,options={})
|
data/lib/ruport/format/plugin.rb
CHANGED
@@ -9,33 +9,33 @@ module Ruport
|
|
9
9
|
include MetaTools
|
10
10
|
|
11
11
|
def helper(name,&block)
|
12
|
-
|
12
|
+
singleton_class.send( :define_method, "#{name}_helper", &block )
|
13
13
|
end
|
14
14
|
|
15
|
-
private :
|
15
|
+
private :singleton_class, :attribute, :attributes, :action
|
16
16
|
|
17
17
|
def plugin_name(name=nil); @name ||= name; end
|
18
18
|
|
19
|
-
def format_name
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
end
|
19
|
+
#def format_name
|
20
|
+
# pattern = /Ruport::Format|Plugin/
|
21
|
+
# @name ||=
|
22
|
+
# self.name.gsub(pattern,"").downcase.delete(":").to_sym
|
23
|
+
#end
|
24
24
|
|
25
25
|
def renderer(render_type,&block)
|
26
26
|
m = "render_#{render_type}".to_sym
|
27
|
-
block
|
28
|
-
|
27
|
+
block ||= lambda { data }
|
28
|
+
singleton_class.send(:define_method, m, &block)
|
29
29
|
end
|
30
30
|
|
31
31
|
def format_field_names(&block)
|
32
|
-
|
32
|
+
singleton_class.send( :define_method, :build_field_names, &block)
|
33
33
|
end
|
34
34
|
|
35
35
|
def register_on(klass)
|
36
36
|
|
37
37
|
if klass.kind_of? Symbol
|
38
|
-
klass = Format::Engine.
|
38
|
+
klass = Format::Engine.engine_classes[klass]
|
39
39
|
end
|
40
40
|
|
41
41
|
klass.accept_format_plugin(self)
|
@@ -65,7 +65,8 @@ module Ruport
|
|
65
65
|
rendered_field_names +
|
66
66
|
FasterCSV.generate { |csv| data.each { |r| csv << r } }
|
67
67
|
end
|
68
|
-
|
68
|
+
|
69
|
+
plugin_name :csv
|
69
70
|
register_on :table_engine
|
70
71
|
end
|
71
72
|
|
@@ -91,9 +92,9 @@ module Ruport
|
|
91
92
|
|
92
93
|
width = self.right_margin || SystemExtensions.terminal_width
|
93
94
|
|
94
|
-
a.
|
95
|
-
r.gsub!(/\A.{#{width},}/) { |m| m[0,width-2]
|
96
|
-
}.join
|
95
|
+
a.to_a.each { |r|
|
96
|
+
r.gsub!(/\A.{#{width+1},}/) { |m| m[0,width-2] + ">>" }
|
97
|
+
}.join
|
97
98
|
end
|
98
99
|
|
99
100
|
format_field_names do
|
@@ -129,7 +130,7 @@ module Ruport
|
|
129
130
|
end
|
130
131
|
|
131
132
|
attribute :right_margin
|
132
|
-
|
133
|
+
plugin_name :text
|
133
134
|
register_on :table_engine
|
134
135
|
register_on :document_engine
|
135
136
|
end
|
@@ -154,7 +155,8 @@ module Ruport
|
|
154
155
|
end
|
155
156
|
|
156
157
|
format_field_names { data.column_names }
|
157
|
-
|
158
|
+
|
159
|
+
plugin_name :pdf
|
158
160
|
register_on :table_engine
|
159
161
|
end
|
160
162
|
|
@@ -176,6 +178,7 @@ module Ruport
|
|
176
178
|
s = "|_." + data.column_names.join(" |_.") + "|\n"
|
177
179
|
end
|
178
180
|
|
181
|
+
plugin_name :html
|
179
182
|
register_on :table_engine
|
180
183
|
register_on :document_engine
|
181
184
|
|
data/lib/ruport/meta_tools.rb
CHANGED
@@ -1,19 +1,42 @@
|
|
1
1
|
module Ruport
|
2
|
+
# This module provides a few tools for doing some manipulations of the
|
3
|
+
# eigenclass on an object. These are used in the implementation of Ruport's
|
4
|
+
# formatting system, and might be helpful for other things.
|
5
|
+
#
|
2
6
|
module MetaTools
|
3
|
-
|
4
|
-
|
7
|
+
# allows you to define an attribute accessor on the singleton_class.
|
8
|
+
#
|
9
|
+
# Example:
|
10
|
+
#
|
11
|
+
# class A
|
12
|
+
# class << self; include MetaTools; end
|
13
|
+
#
|
14
|
+
# attribute :foo
|
15
|
+
# end
|
16
|
+
#
|
17
|
+
# A.foo #=> nil
|
18
|
+
# A.foo = 7 #=> 7
|
5
19
|
def attribute(sym,value = nil)
|
6
|
-
|
20
|
+
singleton_class.send(:attr_accessor, sym )
|
7
21
|
self.send("#{sym}=",value)
|
8
22
|
end
|
9
23
|
|
24
|
+
# same as accessor, but takes an array of attributes
|
25
|
+
#
|
26
|
+
# e.g. attributes [:foo,:bar,:baz]
|
10
27
|
def attributes(syms)
|
11
28
|
syms.each { |s| attribute s }
|
12
29
|
end
|
13
30
|
|
14
31
|
def action(name,&block)
|
15
|
-
|
32
|
+
singleton_class.send(:define_method, name, &block)
|
16
33
|
end
|
17
34
|
end
|
18
35
|
end
|
19
36
|
|
37
|
+
class Module
|
38
|
+
|
39
|
+
# provides the singleton_class object
|
40
|
+
def singleton_class; (class << self; self; end); end
|
41
|
+
|
42
|
+
end
|
data/lib/ruport/query.rb
CHANGED
@@ -99,7 +99,7 @@ module Ruport
|
|
99
99
|
|
100
100
|
# Standard each iterator, iterates through result set row by row.
|
101
101
|
def each(&action)
|
102
|
-
Ruport
|
102
|
+
Ruport.log(
|
103
103
|
"no block given!", :status => :fatal,
|
104
104
|
:level => :log_only, :exception => LocalJumpError
|
105
105
|
) unless action
|
@@ -115,7 +115,7 @@ module Ruport
|
|
115
115
|
|
116
116
|
# clears the contents of the cache
|
117
117
|
def clear_cache
|
118
|
-
@
|
118
|
+
@cached_data = nil
|
119
119
|
end
|
120
120
|
|
121
121
|
# clears the contents of the cache and then runs the query, filling the
|
@@ -179,19 +179,19 @@ module Ruport
|
|
179
179
|
|
180
180
|
def load_file( query_file )
|
181
181
|
begin; File.read( query_file ).strip ; rescue
|
182
|
-
Ruport
|
182
|
+
Ruport.log "Could not open #{query_file}",
|
183
183
|
:status => :fatal, :exception => LoadError
|
184
184
|
end
|
185
185
|
end
|
186
186
|
|
187
|
-
def fetch
|
187
|
+
def fetch
|
188
188
|
data = nil
|
189
189
|
if @cache_enabled and @cached_data
|
190
190
|
data = @cached_data
|
191
191
|
else
|
192
192
|
@statements.each { |query_text| data = query_data( query_text ) }
|
193
193
|
end
|
194
|
-
data.each { |r|
|
194
|
+
data.each { |r| yield(r) } if block_given? ; data
|
195
195
|
@cached_data = data if @cache_enabled
|
196
196
|
return data
|
197
197
|
end
|
@@ -1,17 +1,23 @@
|
|
1
1
|
module Ruport
|
2
|
+
|
2
3
|
module Reportable
|
4
|
+
|
3
5
|
def formatted_table(type,options={})
|
4
6
|
to_ds(:find => options[:find],:columns => options[:columns]).as(type){ |e|
|
5
7
|
yield(e) if block_given?
|
6
8
|
}
|
7
9
|
end
|
10
|
+
|
8
11
|
def to_ds(options={})
|
9
12
|
options[:columns] ||= column_names
|
10
13
|
find(:all,options[:find]).
|
11
14
|
to_ds(column_names).select_columns(*options[:columns])
|
12
15
|
end
|
16
|
+
|
13
17
|
end
|
18
|
+
|
14
19
|
class DataSet
|
20
|
+
|
15
21
|
alias_method :old_append, :<<
|
16
22
|
def <<( stuff, filler=@default )
|
17
23
|
if stuff.kind_of?(ActiveRecord::Base)
|
@@ -20,6 +26,7 @@ module Ruport
|
|
20
26
|
old_append(stuff,filler)
|
21
27
|
end
|
22
28
|
end
|
29
|
+
|
23
30
|
end
|
24
31
|
end
|
25
32
|
|
data/lib/ruport/report.rb
CHANGED
@@ -83,7 +83,8 @@ module Ruport
|
|
83
83
|
def initialize( source_name=:default, mailer_name=:default )
|
84
84
|
use_source source_name
|
85
85
|
use_mailer mailer_name
|
86
|
-
@report_name =
|
86
|
+
@report_name = ""
|
87
|
+
@results = ""
|
87
88
|
@file = nil
|
88
89
|
end
|
89
90
|
|
@@ -100,7 +101,6 @@ module Ruport
|
|
100
101
|
# Preserved for backwards compabilitity, please do not use this.
|
101
102
|
alias_method :report=, :results=
|
102
103
|
|
103
|
-
|
104
104
|
# Simplified interface to Ruport::Query
|
105
105
|
#
|
106
106
|
# === Can read SQL statements from file or string
|
@@ -157,7 +157,7 @@ module Ruport
|
|
157
157
|
# This code will be evaluated in the context of the instance on which it is
|
158
158
|
# called.
|
159
159
|
def eval_template( code, filename=nil )
|
160
|
-
filename =~ /\.rb/ ? eval(code) : ERB.new(code, 0, "%").
|
160
|
+
filename =~ /\.rb/ ? eval(code) : ERB.new(code, 0, "%").result(binding)
|
161
161
|
end
|
162
162
|
|
163
163
|
# sets the active source to the Ruport::Config source requested by label.
|
@@ -261,6 +261,19 @@ module Ruport
|
|
261
261
|
def run(&block)
|
262
262
|
self.class.run(self,&block)
|
263
263
|
end
|
264
|
+
|
265
|
+
def load_csv(file,options={})
|
266
|
+
case options[:as]
|
267
|
+
when :table
|
268
|
+
Data::Table.load(file)
|
269
|
+
when :array
|
270
|
+
a = []
|
271
|
+
Data::Table.load(file) { |s,r| a << r }
|
272
|
+
return a
|
273
|
+
else
|
274
|
+
DataSet.load(file)
|
275
|
+
end
|
276
|
+
end
|
264
277
|
|
265
278
|
# Preserved for backwards compatibility, please do not use this.
|
266
279
|
alias_method :generate_report, :run
|
@@ -271,7 +284,6 @@ module Ruport
|
|
271
284
|
# Creates a new Mailer and sets the <tt>to</tt> attribute to the addresses
|
272
285
|
# specified. Yields a Mailer object, which can be modified before delivery.
|
273
286
|
#
|
274
|
-
# By default, this will
|
275
287
|
def send_to(adds)
|
276
288
|
m = Mailer.new
|
277
289
|
m.to = adds
|
data/test/tc_config.rb
CHANGED
@@ -4,7 +4,6 @@ require "ruport"
|
|
4
4
|
class TestConfiguration < Test::Unit::TestCase
|
5
5
|
|
6
6
|
def setup
|
7
|
-
Ruport::Config.init!
|
8
7
|
Ruport::Config.log_file = "test/unit.log"
|
9
8
|
end
|
10
9
|
|
@@ -16,14 +15,6 @@ class TestConfiguration < Test::Unit::TestCase
|
|
16
15
|
assert_equal(nil, Ruport::Config.default_mailer)
|
17
16
|
end
|
18
17
|
|
19
|
-
def test_init
|
20
|
-
Ruport::Config.init!
|
21
|
-
assert_equal({}, Ruport::Config.sources)
|
22
|
-
assert_equal({}, Ruport::Config.mailers)
|
23
|
-
assert_equal(nil,Ruport::Config.logger)
|
24
|
-
assert_equal(false,Ruport::Config.paranoid?)
|
25
|
-
end
|
26
|
-
|
27
18
|
def test_missing_dsn
|
28
19
|
assert_raise(ArgumentError) {
|
29
20
|
Ruport::Config.source :foo, :user => "root", :password => "fff"
|
@@ -68,10 +59,6 @@ class TestConfiguration < Test::Unit::TestCase
|
|
68
59
|
# We have a logger running now, dont we?
|
69
60
|
assert(Ruport::Config.logger.kind_of?(Logger))
|
70
61
|
|
71
|
-
# If we could go back in time and never define one...
|
72
|
-
Ruport::Config.init!
|
73
|
-
assert Ruport::Config.logger.nil?
|
74
|
-
|
75
62
|
# And then we change are mind again. Back logging?
|
76
63
|
Ruport::Config.log_file = "test/unit.log"
|
77
64
|
assert(Ruport::Config.logger.kind_of?(Logger))
|
data/test/tc_data_set.rb
CHANGED
data/test/tc_format.rb
CHANGED