dataview 0.1.1 → 0.2.0
Sign up to get free protection for your applications and to get access to all the features.
- data/lib/data_view.rb +73 -94
- data/test/tc_data_view.rb +44 -44
- metadata +2 -2
data/lib/data_view.rb
CHANGED
@@ -6,78 +6,67 @@ class DataView
|
|
6
6
|
public
|
7
7
|
include Enumerable
|
8
8
|
attr_accessor :data_view
|
9
|
-
def initialize(data_view, values =
|
9
|
+
def initialize(data_view, values = {})
|
10
10
|
@data_view = data_view
|
11
11
|
@values = values
|
12
12
|
end
|
13
13
|
def [](key)
|
14
|
-
|
14
|
+
return @values[get_key(key)]
|
15
15
|
end
|
16
16
|
def []=(key, value)
|
17
|
-
@values[
|
17
|
+
@values[get_key(key)] = value
|
18
18
|
end
|
19
19
|
def each
|
20
|
-
|
21
|
-
yield(
|
20
|
+
data_view.columns.each_with_index do |c, i|
|
21
|
+
yield(c, @values[c])
|
22
22
|
end
|
23
23
|
end
|
24
24
|
def length
|
25
25
|
@values.length
|
26
26
|
end
|
27
27
|
private
|
28
|
-
def
|
29
|
-
return
|
30
|
-
|
31
|
-
return
|
28
|
+
def get_key(key)
|
29
|
+
return key if data_view.columns.include?(key)
|
30
|
+
col = data_view.columns.find {|c| c[:field] == key}
|
31
|
+
return col unless col == nil
|
32
|
+
return data_view.columns[key.to_i] if key.respond_to?(:to_i)
|
33
|
+
raise "The column #{key} does not exist in this row"
|
32
34
|
end
|
33
35
|
end
|
34
36
|
public
|
35
37
|
include Enumerable
|
36
|
-
attr_reader :
|
38
|
+
attr_reader :columns, :rows
|
37
39
|
# Initializes the DataView.
|
38
40
|
# ===Model
|
39
41
|
# The DataView supports a model that contains an array of hashes. The keys in these hashes much be symbols of the field names. This is based off of the ActiveRecord interface.
|
40
|
-
# ===
|
41
|
-
#
|
42
|
-
#
|
43
|
-
#
|
44
|
-
#
|
45
|
-
#
|
46
|
-
#
|
47
|
-
#
|
42
|
+
# ===Columns
|
43
|
+
# An Array of Hashes that contain data about the columns and how the columns will be handled. The column order in the each method is the same as the array order.
|
44
|
+
# Each Hash contains the following keys:
|
45
|
+
# ====:field
|
46
|
+
# (Required) The database field should be a Symbol or String of the field that is called.
|
47
|
+
# ====:title
|
48
|
+
# The title of the column. If one is not given, the field value is used.
|
49
|
+
# ====:value
|
50
|
+
# The value of the particular cell. If a value is not given, the value of the database field in the model is used. If a Symbol or String is given and the model contains a field with that name, then the model value is returned. If the Symbol or string is not a field in the model, the value parameter is returned.
|
51
|
+
# If a Proc is given, the return value of the Proc is used. The Proc must accept a Hash of parameters and return the transformed value. The Hash contains the following keys:
|
48
52
|
# * :sender - The DataView sending the call
|
49
53
|
# * :model - The Model of the DataView
|
50
54
|
# * :row_index - The Index of the current row.
|
51
55
|
# * :column_index - The Index of the current column.
|
52
|
-
# * :
|
56
|
+
# * :column - The column of the current value.
|
53
57
|
# ====:value_transforms
|
54
|
-
#
|
58
|
+
# An Array of Procs that act as event sinks to transform the value into the desired view. The transforms occur in the order of the Array. Each Proc must accept a Hash of parameters and return the transformed value. The Hash contains the following keys:
|
55
59
|
# * :sender - The DataView sending the call
|
56
60
|
# * :row_index - The Index of the current row.
|
57
61
|
# * :column_index - The Index of the current column.
|
58
62
|
# * :value - The current value.
|
59
|
-
# * :
|
60
|
-
def initialize(model,
|
63
|
+
# * :column - The column of the current value.
|
64
|
+
def initialize(model, columns = [])
|
65
|
+
raise 'columns cannot be nil' if columns == nil
|
61
66
|
@model = model.respond_to?(:each_index) ? model : [model]
|
62
67
|
|
63
|
-
# @
|
64
|
-
@
|
65
|
-
@fields = Array.new() if @fields == nil
|
66
|
-
|
67
|
-
# @titles is a hash with the field as the key and the title as the value
|
68
|
-
@titles = get_param_value(params, :titles)
|
69
|
-
@titles = Hash.new() if @titles == nil
|
70
|
-
|
71
|
-
# @values is a hash of Procs that get nondefault values of a field in a particular row. By default, the value is taken by looking at the field in the model.
|
72
|
-
@values = get_param_value(params, :values)
|
73
|
-
@values = Hash.new() if @values == nil
|
74
|
-
|
75
|
-
# @value_transforms is a hash with the field as the key and a Proc or array of procs that transforms the value into the proper format as the value
|
76
|
-
# The Proc that is the value must accept a hash that has the following keys:
|
77
|
-
# :sender, :row_index, :column_index, :value, :field
|
78
|
-
value_transforms = get_param_value(params, :value_transforms)
|
79
|
-
value_transforms = Hash.new() if value_transforms == nil
|
80
|
-
@value_transforms = format_value_transforms(value_transforms)
|
68
|
+
# @columns is an ordered array of the columns that will be shown
|
69
|
+
@columns = columns
|
81
70
|
end
|
82
71
|
# Gets a particular row of the view.
|
83
72
|
def [](index)
|
@@ -93,17 +82,15 @@ class DataView
|
|
93
82
|
yield(get_view_row(row_index))
|
94
83
|
end
|
95
84
|
end
|
96
|
-
# Iterates through each title of the
|
85
|
+
# Iterates through each title of the columns.
|
97
86
|
def each_title
|
98
|
-
@
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
yield(field, nil)
|
103
|
-
end
|
87
|
+
@columns.each do |column|
|
88
|
+
column_title = column[:title]
|
89
|
+
title = (column_title == nil) ? column[:field] : column[:title]
|
90
|
+
yield(column, title)
|
104
91
|
end
|
105
92
|
end
|
106
|
-
# Iterates through each title of the
|
93
|
+
# Iterates through each title of the columns with the index.
|
107
94
|
def each_title_with_index
|
108
95
|
i = 0
|
109
96
|
each_title do |f, t|
|
@@ -114,57 +101,49 @@ class DataView
|
|
114
101
|
private
|
115
102
|
def get_view_row(row_index)
|
116
103
|
model_row = @model[row_index]
|
117
|
-
view_row_values =
|
118
|
-
@
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
:sender => self,
|
123
|
-
:model => @model,
|
124
|
-
:row_index => row_index,
|
125
|
-
:column_index => field_index,
|
126
|
-
:field => field
|
127
|
-
}
|
128
|
-
)
|
129
|
-
else
|
130
|
-
actual_value = model_row[field]
|
131
|
-
end
|
132
|
-
view_value = actual_value
|
133
|
-
|
134
|
-
if @value_transforms.include?(field)
|
135
|
-
transform_value = actual_value
|
136
|
-
|
137
|
-
transforms = @value_transforms[field]
|
138
|
-
transforms = [transforms] unless transforms.respond_to?(:each)
|
139
|
-
transforms.each do |transform|
|
140
|
-
next unless transform
|
141
|
-
transform_params = {
|
142
|
-
:sender => self,
|
143
|
-
:row_index => row_index,
|
144
|
-
:column_index => field_index,
|
145
|
-
:value => transform_value,
|
146
|
-
:field => field
|
147
|
-
}
|
148
|
-
transform_value = transform.call(transform_params)
|
149
|
-
end
|
150
|
-
view_value = transform_value
|
151
|
-
end
|
152
|
-
view_row_values << view_value
|
104
|
+
view_row_values = {}
|
105
|
+
@columns.each_with_index do |column, column_index|
|
106
|
+
value = get_raw_value(model_row, column, row_index, column_index)
|
107
|
+
value = get_transformed_value(value, column, row_index, column_index)
|
108
|
+
view_row_values[column] = value
|
153
109
|
end
|
154
110
|
Row.new(self, view_row_values)
|
155
111
|
end
|
156
|
-
def
|
157
|
-
|
158
|
-
return
|
112
|
+
def get_raw_value(model_row, col, row_index, column_index)
|
113
|
+
value_param = col[:value]
|
114
|
+
return model_row[col[:field]] if value_param == nil
|
115
|
+
|
116
|
+
return @columns[value_param] if @columns.any? {|f| f[:field] == value_param}
|
117
|
+
|
118
|
+
return value_param.call(
|
119
|
+
{
|
120
|
+
:sender => self,
|
121
|
+
:model => @model,
|
122
|
+
:row_index => row_index,
|
123
|
+
:column_index => column_index,
|
124
|
+
:column => col
|
125
|
+
}
|
126
|
+
) if value_param.respond_to?(:call)
|
127
|
+
|
128
|
+
return value_param
|
159
129
|
end
|
160
|
-
def
|
161
|
-
|
162
|
-
|
163
|
-
|
164
|
-
|
165
|
-
|
130
|
+
def get_transformed_value(value, column, row_index, column_index)
|
131
|
+
transforms = column[:value_transforms]
|
132
|
+
return value if transforms == nil
|
133
|
+
|
134
|
+
transforms = [transforms] unless transforms.respond_to?(:each)
|
135
|
+
transforms.each do |transform|
|
136
|
+
next unless transform
|
137
|
+
transform_params = {
|
138
|
+
:sender => self,
|
139
|
+
:row_index => row_index,
|
140
|
+
:column_index => column_index,
|
141
|
+
:value => value,
|
142
|
+
:column => column
|
143
|
+
}
|
144
|
+
value = transform.call(transform_params)
|
166
145
|
end
|
167
|
-
|
146
|
+
value
|
168
147
|
end
|
169
148
|
end
|
170
149
|
|
data/test/tc_data_view.rb
CHANGED
@@ -27,15 +27,17 @@ class DataViewTest < Test::Unit::TestCase
|
|
27
27
|
end
|
28
28
|
def test_value_transforms_accessor
|
29
29
|
data_view = get_data_view(mock_model)
|
30
|
-
data_view.
|
31
|
-
|
30
|
+
col = data_view.columns.find {|col| col[:field] == :field1}
|
31
|
+
col[:value_transforms] = nil
|
32
|
+
field = col[:field]
|
33
|
+
assert_equal(mock_model[0][field], data_view[0][:field1])
|
32
34
|
|
33
35
|
test_transform = lambda { |h|
|
34
36
|
'test ' << h[:value].to_s
|
35
37
|
}
|
36
|
-
|
38
|
+
col[:value_transforms] = test_transform
|
37
39
|
|
38
|
-
expected_transform_value = test_transform.call({:value => mock_model[0][
|
40
|
+
expected_transform_value = test_transform.call({:value => mock_model[0][field]})
|
39
41
|
assert_equal(expected_transform_value, data_view[0][:field1])
|
40
42
|
end
|
41
43
|
private
|
@@ -44,11 +46,12 @@ class DataViewTest < Test::Unit::TestCase
|
|
44
46
|
|
45
47
|
test_model = model.respond_to?(:each_index) ? model : [model]
|
46
48
|
test_model.each_with_index do |r, i|
|
47
|
-
|
49
|
+
columns.each_with_index do |col, j|
|
50
|
+
f = col[:field]
|
48
51
|
if f != :model_value_field
|
49
52
|
v = r[f]
|
50
53
|
else
|
51
|
-
v = get_model_value({:sender => self, :model => model, :row_index => i, :
|
54
|
+
v = get_model_value({:sender => self, :model => model, :row_index => i, :column => col})
|
52
55
|
end
|
53
56
|
assert_equal(expected_altered_value(v), data_view[i][f])
|
54
57
|
end
|
@@ -60,11 +63,12 @@ class DataViewTest < Test::Unit::TestCase
|
|
60
63
|
expected_row = model.respond_to?(:each_index) ? model[i] : model
|
61
64
|
assert_equal(expected_row.length, row.to_a.length)
|
62
65
|
|
63
|
-
expected_row.each do |
|
64
|
-
|
65
|
-
|
66
|
+
expected_row.each do |f, expected_value|
|
67
|
+
col = data_view.columns.find{|col| col[:field] == f}
|
68
|
+
if f == :model_value_field
|
69
|
+
expected_value = get_model_value({:sender => self, :model => model, :row_index => i, :column => col})
|
66
70
|
end
|
67
|
-
assert_equal(expected_altered_value(expected_value), row[
|
71
|
+
assert_equal(expected_altered_value(expected_value), row[f])
|
68
72
|
end
|
69
73
|
end
|
70
74
|
end
|
@@ -72,7 +76,7 @@ class DataViewTest < Test::Unit::TestCase
|
|
72
76
|
data_view = get_data_view(model)
|
73
77
|
i = 0
|
74
78
|
data_view.each_title do |f, t|
|
75
|
-
assert_equal(
|
79
|
+
assert_equal(f[:title], t)
|
76
80
|
i = i + 1
|
77
81
|
end
|
78
82
|
end
|
@@ -80,7 +84,7 @@ class DataViewTest < Test::Unit::TestCase
|
|
80
84
|
data_view = get_data_view(model)
|
81
85
|
ei = 0
|
82
86
|
data_view.each_title_with_index do |f, t, i|
|
83
|
-
assert_equal(
|
87
|
+
assert_equal(f[:title], t)
|
84
88
|
assert_equal(ei, i)
|
85
89
|
ei = ei + 1
|
86
90
|
end
|
@@ -89,13 +93,7 @@ class DataViewTest < Test::Unit::TestCase
|
|
89
93
|
"altered " << v
|
90
94
|
end
|
91
95
|
def get_data_view(model)
|
92
|
-
DataView.new(
|
93
|
-
model,
|
94
|
-
:fields => fields,
|
95
|
-
:titles => titles,
|
96
|
-
:values => values,
|
97
|
-
:value_transforms => value_transforms
|
98
|
-
)
|
96
|
+
DataView.new(model, columns)
|
99
97
|
end
|
100
98
|
def get_model_value_method
|
101
99
|
return @get_model_value_method if defined?(@get_model_value_method)
|
@@ -106,7 +104,7 @@ class DataViewTest < Test::Unit::TestCase
|
|
106
104
|
test_model = params[:model]
|
107
105
|
test_row_index = params[:row_index]
|
108
106
|
test_column_index = params[:column_index]
|
109
|
-
|
107
|
+
test_column = params[:column]
|
110
108
|
|
111
109
|
unless test_sender == self
|
112
110
|
assert_equal(DataView, test_sender.class)
|
@@ -114,23 +112,29 @@ class DataViewTest < Test::Unit::TestCase
|
|
114
112
|
assert_equal(singular_mock_model, test_model[0])
|
115
113
|
end
|
116
114
|
assert((0..2).include?(test_row_index))
|
117
|
-
assert(
|
118
|
-
fi =
|
115
|
+
assert(columns.include?(test_column))
|
116
|
+
fi = columns.index(test_column)
|
119
117
|
assert_equal(fi, test_column_index)
|
120
118
|
end
|
121
|
-
test_row_index.to_s << ' : Custom ' <<
|
119
|
+
test_row_index.to_s << ' : Custom ' << test_column[:field].to_s
|
122
120
|
end
|
123
|
-
def
|
124
|
-
return @
|
125
|
-
|
126
|
-
|
127
|
-
|
128
|
-
|
129
|
-
|
130
|
-
|
131
|
-
|
121
|
+
def columns
|
122
|
+
return @columns if defined?(@columns)
|
123
|
+
|
124
|
+
columns = []
|
125
|
+
[:model_value_field, :field1, :field2, :field3].each do |f|
|
126
|
+
column = Hash.new
|
127
|
+
column[:field] = f
|
128
|
+
column[:title] = get_title(f)
|
129
|
+
column[:value] = get_model_value_method if f == :model_value_field
|
130
|
+
column[:value_transforms] = value_transform
|
131
|
+
columns.push(column)
|
132
132
|
end
|
133
|
-
|
133
|
+
|
134
|
+
@columns = columns
|
135
|
+
end
|
136
|
+
def get_title(field)
|
137
|
+
"#{field.to_s} Title"
|
134
138
|
end
|
135
139
|
def singular_mock_model
|
136
140
|
return @singular_mock_model if defined?(@singular_mock_model)
|
@@ -147,9 +151,9 @@ class DataViewTest < Test::Unit::TestCase
|
|
147
151
|
end
|
148
152
|
def get_mock_model_row(i)
|
149
153
|
row = Hash.new
|
150
|
-
|
151
|
-
|
152
|
-
row[
|
154
|
+
columns.each do |f|
|
155
|
+
field = f[:field]
|
156
|
+
row[field] = i.to_s << ' : ' << field.to_s
|
153
157
|
end
|
154
158
|
row
|
155
159
|
end
|
@@ -159,15 +163,11 @@ class DataViewTest < Test::Unit::TestCase
|
|
159
163
|
v[:model_value_field] = get_model_value_method
|
160
164
|
@values = v
|
161
165
|
end
|
162
|
-
def
|
163
|
-
return @
|
164
|
-
|
165
|
-
|
166
|
-
t[f] = lambda { |h|
|
167
|
-
'altered ' << h[:value].to_s
|
168
|
-
}
|
166
|
+
def value_transform
|
167
|
+
return @value_transform if defined?(@value_transform)
|
168
|
+
@value_transform = lambda do |h|
|
169
|
+
'altered ' << h[:value].to_s
|
169
170
|
end
|
170
|
-
@value_transforms = t
|
171
171
|
end
|
172
172
|
end
|
173
173
|
|
metadata
CHANGED
@@ -3,8 +3,8 @@ rubygems_version: 0.8.11
|
|
3
3
|
specification_version: 1
|
4
4
|
name: dataview
|
5
5
|
version: !ruby/object:Gem::Version
|
6
|
-
version: 0.
|
7
|
-
date: 2005-07-
|
6
|
+
version: 0.2.0
|
7
|
+
date: 2005-07-26 00:00:00 -07:00
|
8
8
|
summary: Data View is a library that creates a view of a data model. The view can transform the data of the data model without changing the data. Supports ActiveRecord models and other data models that have a similar interface.
|
9
9
|
require_paths:
|
10
10
|
- lib
|