dataview 0.1.1 → 0.2.0
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/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
|