hotwire 0.1.1 → 0.1.2
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/README.markdown +4 -0
- data/VERSION +1 -1
- data/hotwire.gemspec +2 -2
- data/lib/hotwire/response/base.rb +96 -9
- data/test/response/test_base.rb +67 -5
- metadata +4 -4
data/README.markdown
CHANGED
@@ -59,6 +59,10 @@ The following is a basic example of use.
|
|
59
59
|
end
|
60
60
|
end
|
61
61
|
|
62
|
+
## Alternate Data Structures ##
|
63
|
+
|
64
|
+
The set\_data method on a Hotwire::Response object can be called with several different data structures in order to make getting data into the response as smoothly as possible. See the documentation for Hotwire::Response.set\_data for more details.
|
65
|
+
|
62
66
|
## ActiveRecord ##
|
63
67
|
|
64
68
|
If your project includes ActiveRecord, Hotwire will automatically included an ActiveRecord mixin that allows columns to be added from a model class.
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.1.
|
1
|
+
0.1.2
|
data/hotwire.gemspec
CHANGED
@@ -5,11 +5,11 @@
|
|
5
5
|
|
6
6
|
Gem::Specification.new do |s|
|
7
7
|
s.name = %q{hotwire}
|
8
|
-
s.version = "0.1.
|
8
|
+
s.version = "0.1.2"
|
9
9
|
|
10
10
|
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
11
11
|
s.authors = ["Les Freeman"]
|
12
|
-
s.date = %q{2010-
|
12
|
+
s.date = %q{2010-11-02}
|
13
13
|
s.description = %q{Hotwire is designed to ease the pain of creating Google Wire protocol compatible data source in Ruby.}
|
14
14
|
s.email = %q{les@codebenders.com}
|
15
15
|
s.extra_rdoc_files = [
|
@@ -34,26 +34,113 @@ module Hotwire
|
|
34
34
|
end
|
35
35
|
alias_method :add_col, :add_column
|
36
36
|
|
37
|
-
# Adds
|
38
|
-
#
|
37
|
+
# Adds a colleciton of columns to the visualization
|
38
|
+
# +columns+ can either be an array of column definitions:
|
39
|
+
# add_columns(['string', {:id => 'Column A'}], ['number', {:id => 'Column B'}])
|
40
|
+
#
|
41
|
+
# or a sample row of data, represented as a hash keyed as column_name => value:
|
42
|
+
# add_columns({:column_a => 'a1', :column_b => 'b1})
|
43
|
+
# column_name keys are expected to be symbols(string keys do not maintain order).
|
39
44
|
def add_columns(columns)
|
40
|
-
columns.
|
45
|
+
if columns.first.is_a?(Hash)
|
46
|
+
add_columns_from_data_hash(columns)
|
47
|
+
else
|
48
|
+
add_columns_from_array(columns)
|
49
|
+
end
|
41
50
|
end
|
42
51
|
|
43
|
-
# Sets the data to be exported.
|
44
|
-
#
|
45
|
-
#
|
46
|
-
#
|
47
|
-
#
|
52
|
+
# Sets the data to be exported.
|
53
|
+
# +data+ can be a 2-dimensional array of plain data, an array of hashes that are keyed
|
54
|
+
# column_name => value, or a hash with a :columns key and a :rows key
|
55
|
+
#
|
56
|
+
# If passing a 2-dimensional array, the first index should iterate over rows,
|
57
|
+
# the second over columns. Column ordering must be the same used in +add_col+
|
58
|
+
# invokations. Anything that behaves like a 2-dimensional array and supports +each+ is
|
48
59
|
# a perfectly fine alternative.
|
60
|
+
#
|
61
|
+
# If passing an array of column_name => value hashes and no columns have been added,
|
62
|
+
# a column will automatically be added for each entry in the first row of data.
|
63
|
+
# If columns have already been added then the data will be filtered to those
|
64
|
+
# columns. column_name keys are expected to be symbols(string keys do not maintain order).
|
65
|
+
#
|
66
|
+
# If passing a hash with :columns key and a :rows key,
|
67
|
+
# :columns should be an array of column ids: ['col_a', 'col_b'...'col_N']
|
68
|
+
# :rows should be a 2-dimensional array of data: [['a1', 'b1']...['aN', 'bN']]
|
69
|
+
# Note that each row of data must be in the same order as the column id array.
|
49
70
|
def set_data(data)
|
50
|
-
|
71
|
+
if data.is_a?(Hash)
|
72
|
+
set_data_from_hash(data)
|
73
|
+
elsif data.first.is_a?(Hash)
|
74
|
+
set_data_from_array_of_hashes(data)
|
75
|
+
else
|
76
|
+
set_data_from_array(data)
|
77
|
+
end
|
51
78
|
return self
|
52
79
|
end
|
53
80
|
|
54
81
|
# Placeholder method for the subclasses to overwrite
|
55
82
|
def body
|
56
83
|
end
|
84
|
+
|
85
|
+
protected
|
86
|
+
|
87
|
+
# Adds columns to the response based on a sample row of data in the form of a hash
|
88
|
+
# keyed as column_name => value
|
89
|
+
def add_columns_from_data_hash(data)
|
90
|
+
data.first.each do |key, value|
|
91
|
+
add_column(column_type_for_value(value), :id => key.to_s, :label => key.to_s)
|
92
|
+
end
|
93
|
+
end
|
94
|
+
|
95
|
+
# Determines the appropriate Wire Protocol column type for +value+
|
96
|
+
def column_type_for_value(value)
|
97
|
+
case value.class.name
|
98
|
+
when 'BigDecimal', 'Fixnum', 'Float'
|
99
|
+
'number'
|
100
|
+
when /Time/
|
101
|
+
'datetime'
|
102
|
+
when 'Date'
|
103
|
+
'date'
|
104
|
+
when 'String'
|
105
|
+
'string'
|
106
|
+
else
|
107
|
+
'string'
|
108
|
+
end
|
109
|
+
end
|
110
|
+
|
111
|
+
# Adds multiple columns to the response from an array of column definitions:
|
112
|
+
# add_columns(['string', {:id => 'Column A'}], ['number', {:id => 'Column B'}])
|
113
|
+
def add_columns_from_array(columns)
|
114
|
+
columns.each { |col| add_column(*col)}
|
115
|
+
end
|
116
|
+
|
117
|
+
# Sets up the response based on a hash that has a :columns key and a :rows key.
|
118
|
+
# :columns should be an array of column ids: ['col_a', 'col_b'...'col_N']
|
119
|
+
# :rows should be a 2-dimensional array of data: [['a1', 'b1']...['aN', 'bN']]
|
120
|
+
# This method adds columns based on the first row of data and the provided
|
121
|
+
# array of column ids. Note that each row of data must be in the same
|
122
|
+
# order as the column id array.
|
123
|
+
def set_data_from_hash(data)
|
124
|
+
data[:columns].each_with_index do |column_name, index|
|
125
|
+
sample_value = data[:rows].first[index]
|
126
|
+
add_column(column_type_for_value(sample_value), :id => column_name, :label => column_name)
|
127
|
+
end
|
128
|
+
set_data_from_array(data[:rows])
|
129
|
+
end
|
130
|
+
|
131
|
+
# Sets the response data from an array of row hashes that are keyed column_name => value.
|
132
|
+
# If there are no columns setup, they are added automatically.
|
133
|
+
# Data is filtered on the columns that exist.
|
134
|
+
def set_data_from_array_of_hashes(data)
|
135
|
+
add_columns(data) if columns.empty?
|
136
|
+
set_data(data.map { |row| self.columns.map { |c| row[c[:id].to_sym] } })
|
137
|
+
end
|
138
|
+
|
139
|
+
# Sets the response data from a two dimensional array of innumerables.
|
140
|
+
def set_data_from_array(data)
|
141
|
+
@data = data
|
142
|
+
end
|
143
|
+
|
57
144
|
end
|
58
145
|
|
59
146
|
end
|
data/test/response/test_base.rb
CHANGED
@@ -39,14 +39,76 @@ class TestResponseBase < Test::Unit::TestCase
|
|
39
39
|
end
|
40
40
|
|
41
41
|
context "set_data" do
|
42
|
-
|
43
|
-
|
44
|
-
|
42
|
+
context "from an array of hashes" do
|
43
|
+
context "when columns are not set" do
|
44
|
+
setup do
|
45
|
+
@datetime = Time.utc(2010, 11, 2, 9, 35, 00)
|
46
|
+
@data = [{:string_col => 'a1', :int_col => 2, :decimal_col => 3.3, :datetime_col => @datetime}]
|
47
|
+
@response.set_data(@data)
|
48
|
+
end
|
49
|
+
should "add columns to the response" do
|
50
|
+
expected = [{:id => 'string_col', :label => "string_col", :type => 'string'},
|
51
|
+
{:id => 'int_col', :label => "int_col", :type => 'number'},
|
52
|
+
{:id => 'decimal_col', :label => "decimal_col", :type => 'number'},
|
53
|
+
{:id => 'datetime_col', :label => "datetime_col", :type => 'datetime'}]
|
54
|
+
assert_equal expected, @response.columns
|
55
|
+
end
|
56
|
+
should "set the data for the response" do
|
57
|
+
assert_equal [['a1', 2, 3.3, @datetime]], @response.data
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
context "when columns are already set" do
|
62
|
+
setup do
|
63
|
+
@data = [{:col_a => 'a1', :col_b => 'b1', :col_c => 'c1'}]
|
64
|
+
@response.add_columns([['string', {:id => 'col_c', :label => 'col_c'}],
|
65
|
+
['string', {:id => 'col_a', :label => 'col_a'}]])
|
66
|
+
@response.set_data(@data)
|
67
|
+
end
|
68
|
+
should "add columns to the response" do
|
69
|
+
expected = [{:id => 'col_c', :label => "col_c", :type => 'string'},
|
70
|
+
{:id => 'col_a', :label => "col_a", :type => 'string'}]
|
71
|
+
assert_equal expected, @response.columns
|
72
|
+
end
|
73
|
+
should "set the data for the response" do
|
74
|
+
assert_equal [['c1', 'a1']], @response.data
|
75
|
+
end
|
76
|
+
end
|
45
77
|
end
|
46
78
|
|
47
|
-
|
48
|
-
|
79
|
+
context "from a :rows, :columns hash" do
|
80
|
+
setup do
|
81
|
+
@datetime = Time.utc(2010, 11, 2, 9, 35, 00)
|
82
|
+
@data = {:columns => ["string_col", "int_col", "decimal_col", "datetime_col"],
|
83
|
+
:rows => [['a1', 2, 3.3, @datetime]]}
|
84
|
+
@response.set_data(@data)
|
85
|
+
end
|
86
|
+
|
87
|
+
should "add columns to the response" do
|
88
|
+
expected = [{:id => 'string_col', :label => "string_col", :type => 'string'},
|
89
|
+
{:id => 'int_col', :label => "int_col", :type => 'number'},
|
90
|
+
{:id => 'decimal_col', :label => "decimal_col", :type => 'number'},
|
91
|
+
{:id => 'datetime_col', :label => "datetime_col", :type => 'datetime'}]
|
92
|
+
assert_equal expected, @response.columns
|
93
|
+
end
|
94
|
+
|
95
|
+
should "set the data from the response" do
|
96
|
+
assert_equal [['a1', 2, 3.3, @datetime]], @response.data
|
97
|
+
end
|
98
|
+
end
|
99
|
+
|
100
|
+
context "from an array of arrays" do
|
101
|
+
setup do
|
102
|
+
@data = [['a', 'b']]
|
103
|
+
@response.set_data(@data)
|
104
|
+
end
|
105
|
+
|
106
|
+
should "set the data for the response" do
|
107
|
+
assert_equal @data, @response.data
|
108
|
+
end
|
49
109
|
end
|
110
|
+
|
111
|
+
|
50
112
|
end
|
51
113
|
|
52
114
|
end
|
metadata
CHANGED
@@ -1,13 +1,13 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: hotwire
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
hash:
|
4
|
+
hash: 31
|
5
5
|
prerelease: false
|
6
6
|
segments:
|
7
7
|
- 0
|
8
8
|
- 1
|
9
|
-
-
|
10
|
-
version: 0.1.
|
9
|
+
- 2
|
10
|
+
version: 0.1.2
|
11
11
|
platform: ruby
|
12
12
|
authors:
|
13
13
|
- Les Freeman
|
@@ -15,7 +15,7 @@ autorequire:
|
|
15
15
|
bindir: bin
|
16
16
|
cert_chain: []
|
17
17
|
|
18
|
-
date: 2010-
|
18
|
+
date: 2010-11-02 00:00:00 -07:00
|
19
19
|
default_executable:
|
20
20
|
dependencies:
|
21
21
|
- !ruby/object:Gem::Dependency
|