md_data 1.1.0 → 1.1.1
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/Gemfile +1 -0
- data/LICENSE +1 -1
- data/README.md +7 -8
- data/lib/md_data.rb +3 -0
- data/lib/md_data/md_data.rb +45 -23
- data/lib/md_data/version.rb +1 -1
- data/spec/md_data/md_data_spec.rb +98 -13
- metadata +4 -3
data/Gemfile
CHANGED
data/LICENSE
CHANGED
@@ -19,4 +19,4 @@ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
|
19
19
|
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
20
20
|
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
21
21
|
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
22
|
-
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
22
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
CHANGED
@@ -5,15 +5,15 @@ An easy notation for describing multidimensional data.
|
|
5
5
|
For example:
|
6
6
|
|
7
7
|
```
|
8
|
-
1994
|
8
|
+
1994
|
9
9
|
BuenosAires
|
10
10
|
Coal
|
11
11
|
19t
|
12
12
|
Potassium
|
13
13
|
5t
|
14
|
-
1995
|
14
|
+
1995
|
15
15
|
BuenosAires
|
16
|
-
Coal
|
16
|
+
Coal
|
17
17
|
8t
|
18
18
|
Potassium
|
19
19
|
6t
|
@@ -41,7 +41,7 @@ class MaterialConsumption
|
|
41
41
|
end
|
42
42
|
end
|
43
43
|
|
44
|
-
MaterialConsumption.select(:year =>
|
44
|
+
MaterialConsumption.select(:year => :year_1994, :city => :buenos_aires, :material => :coal) #=> '8t'
|
45
45
|
```
|
46
46
|
##Usage
|
47
47
|
By defining dimensions you get helper methods that can be used in 'context' and 'add' conditionals.
|
@@ -50,10 +50,9 @@ By defining dimensions you get helper methods that can be used in 'context' and
|
|
50
50
|
context 'year_1994 && buenos_aires' do
|
51
51
|
add '8t', 'coal'
|
52
52
|
end
|
53
|
-
|
54
53
|
```
|
55
54
|
|
56
|
-
|
55
|
+
Equals
|
57
56
|
|
58
57
|
```
|
59
58
|
context 'year == :year_1994 && city == :buenos_aires' do
|
@@ -65,7 +64,7 @@ Important thing here is that this is still just Ruby in quotes. You can add any
|
|
65
64
|
while you still have basic scenario covered and simplified.
|
66
65
|
|
67
66
|
##Usage
|
68
|
-
For any type of ruled based
|
67
|
+
For any type of ruled based querying, when you want to pull out specific data based on attributes and rules.
|
69
68
|
|
70
69
|
## Installation
|
71
70
|
|
@@ -84,7 +83,7 @@ Or install it yourself as:
|
|
84
83
|
## Limitations
|
85
84
|
|
86
85
|
* No nested context allowed(yet)
|
87
|
-
* Tests for
|
86
|
+
* Tests for mis formed data definition
|
88
87
|
* Support for same dimension instance value and resolving of ambiguity
|
89
88
|
|
90
89
|
## Contributing
|
data/lib/md_data.rb
CHANGED
data/lib/md_data/md_data.rb
CHANGED
@@ -1,20 +1,45 @@
|
|
1
1
|
module MdData
|
2
|
+
#raise this if you cant find appropriate rule
|
3
|
+
class NoRuleFound < StandardError ; end
|
4
|
+
|
2
5
|
def self.included(base)
|
3
6
|
base.extend MdDataClassMethods
|
4
7
|
end
|
5
8
|
|
6
|
-
|
9
|
+
def attributes
|
10
|
+
@attributes
|
11
|
+
end
|
12
|
+
|
13
|
+
def attributes=(value)
|
14
|
+
@attributes = value
|
15
|
+
end
|
16
|
+
|
17
|
+
def define_helpers_methods(dimensions, attributes)
|
18
|
+
dimensions.merge(attributes).each_key { |key| define_helper(key) }
|
19
|
+
end
|
7
20
|
|
21
|
+
def define_helper(key)
|
22
|
+
Kernel.send(:define_method, key) do
|
23
|
+
(instance_variable_get "@attributes")[key]
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
module MdDataClassMethods
|
8
28
|
def table_data(&block)
|
9
29
|
@table_data_block = block
|
10
30
|
end
|
11
31
|
|
12
|
-
def select(attributes)
|
32
|
+
def select(attributes, parent = nil)
|
13
33
|
@rules = []
|
14
34
|
@current_context = nil
|
15
35
|
load_rules
|
16
|
-
|
17
|
-
|
36
|
+
if (parent.nil?)
|
37
|
+
container = self.new
|
38
|
+
else
|
39
|
+
container = self.new(parent)
|
40
|
+
end
|
41
|
+
container.attributes = attributes
|
42
|
+
container.define_helpers_methods(dimensions, attributes)
|
18
43
|
define_dimension_values_methods
|
19
44
|
define_select_from_rules
|
20
45
|
container.select_from_rules(@rules)
|
@@ -27,7 +52,6 @@ module MdData
|
|
27
52
|
def dimensions
|
28
53
|
@dimensions ||= {}
|
29
54
|
end
|
30
|
-
|
31
55
|
|
32
56
|
private
|
33
57
|
def load_rules
|
@@ -35,7 +59,11 @@ module MdData
|
|
35
59
|
end
|
36
60
|
|
37
61
|
def add(value, condition)
|
38
|
-
|
62
|
+
if @current_context.nil?
|
63
|
+
context_condition = ''
|
64
|
+
else
|
65
|
+
context_condition = " && #{@current_context} "
|
66
|
+
end
|
39
67
|
@rules << ( [value , (condition + context_condition)] )
|
40
68
|
end
|
41
69
|
|
@@ -44,39 +72,33 @@ module MdData
|
|
44
72
|
block.call
|
45
73
|
end
|
46
74
|
|
47
|
-
def define_helpers_methods(attributes)
|
48
|
-
attributes.each do |key,value|
|
49
|
-
self.send(:define_method, key) do
|
50
|
-
value
|
51
|
-
end
|
52
|
-
end
|
53
|
-
end
|
54
75
|
|
55
76
|
def define_dimension_values_methods
|
56
77
|
unless @dimensions.nil?
|
57
78
|
@dimensions.each do |name, values|
|
58
|
-
values.each
|
59
|
-
self.send(:define_method, value) do
|
60
|
-
eval "#{name} == :#{value}"
|
61
|
-
end
|
62
|
-
end
|
79
|
+
values.each { |value| equal?(name, value) }
|
63
80
|
end
|
64
81
|
end
|
65
82
|
end
|
66
83
|
|
84
|
+
def equal?(name, value)
|
85
|
+
self.send(:define_method, value) do
|
86
|
+
instance_eval "#{name} == :#{value}"
|
87
|
+
end
|
88
|
+
end
|
89
|
+
|
67
90
|
def define_select_from_rules
|
68
91
|
self.send(:define_method, :select_from_rules) do |rules|
|
69
92
|
result = nil
|
70
93
|
rules.each do |rule|
|
71
|
-
rule_is_satisfied =
|
94
|
+
rule_is_satisfied = instance_eval(rule[1])
|
72
95
|
if rule_is_satisfied
|
73
96
|
result = rule[0]
|
74
97
|
break
|
75
98
|
end
|
76
99
|
end
|
77
|
-
result
|
100
|
+
result.nil? ? raise(NoRuleFound.new('No rule found')) : result
|
78
101
|
end
|
79
102
|
end
|
80
|
-
|
81
|
-
|
82
|
-
end
|
103
|
+
end #MdDataClassMethods
|
104
|
+
end #MdData
|
data/lib/md_data/version.rb
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
require 'md_data'
|
2
2
|
|
3
3
|
describe MdData do
|
4
|
-
|
4
|
+
# use this as an example of extended class
|
5
5
|
class TestClass; include MdData end
|
6
6
|
|
7
7
|
it 'adds table_data class method when included' do
|
@@ -13,10 +13,12 @@ describe MdData do
|
|
13
13
|
end
|
14
14
|
|
15
15
|
it 'should store block for latter usage and allow change' do
|
16
|
+
# use this as an example of extended class
|
16
17
|
class TestClass
|
17
18
|
table_data { "LATER" }
|
18
19
|
end
|
19
20
|
TestClass.send(:load_rules).should == "LATER"
|
21
|
+
# use this as an example of extended class
|
20
22
|
class TestClass
|
21
23
|
table_data { "ALIGATOR" }
|
22
24
|
end
|
@@ -24,6 +26,7 @@ describe MdData do
|
|
24
26
|
end
|
25
27
|
|
26
28
|
it 'rules can be created with add' do
|
29
|
+
# use this as an example of extended class
|
27
30
|
class TestClass
|
28
31
|
table_data { add "8t", "year == 1994" }
|
29
32
|
end
|
@@ -31,9 +34,10 @@ describe MdData do
|
|
31
34
|
end
|
32
35
|
|
33
36
|
it 'multiple rules can be created with add' do
|
37
|
+
# use this as an example of extended class
|
34
38
|
class TestClass
|
35
39
|
table_data do
|
36
|
-
add "8t", "year == 1994"
|
40
|
+
add "8t", "year == 1994"
|
37
41
|
add "9t", "year == 1995"
|
38
42
|
end
|
39
43
|
end
|
@@ -42,6 +46,7 @@ describe MdData do
|
|
42
46
|
end
|
43
47
|
|
44
48
|
it 'should create pull out item based on rules and attributes' do
|
49
|
+
# use this as an example of extended class
|
45
50
|
class TestClass
|
46
51
|
table_data { add "8t" , "year == 1994" }
|
47
52
|
end
|
@@ -49,6 +54,7 @@ describe MdData do
|
|
49
54
|
end
|
50
55
|
|
51
56
|
it 'item can be anythinig' do
|
57
|
+
# use this as an example of extended class
|
52
58
|
class TestClass
|
53
59
|
table_data { add TestClass.new , "year == 1994" }
|
54
60
|
end
|
@@ -56,11 +62,12 @@ describe MdData do
|
|
56
62
|
end
|
57
63
|
|
58
64
|
|
59
|
-
it 'rules can be created with add in
|
65
|
+
it 'rules can be created with add in precondition' do
|
66
|
+
# use this as an example of extended class
|
60
67
|
class TestClass
|
61
68
|
table_data do
|
62
69
|
context "time_of_day == :morning" do
|
63
|
-
add "8t", "year == 1994"
|
70
|
+
add "8t", "year == 1994"
|
64
71
|
end
|
65
72
|
end
|
66
73
|
end
|
@@ -68,11 +75,12 @@ describe MdData do
|
|
68
75
|
end
|
69
76
|
|
70
77
|
it 'rules can be created to comapre with string' do
|
78
|
+
# use this as an example of extended class
|
71
79
|
class TestClass
|
72
80
|
table_data do
|
73
81
|
context "time_of_day == 'morning'" do
|
74
|
-
add "8t", "year == 1995"
|
75
|
-
add "6t", "year == 1994"
|
82
|
+
add "8t", "year == 1995"
|
83
|
+
add "6t", "year == 1994"
|
76
84
|
end
|
77
85
|
end
|
78
86
|
end
|
@@ -80,14 +88,15 @@ describe MdData do
|
|
80
88
|
end
|
81
89
|
|
82
90
|
it 'can have multiple contexts' do
|
91
|
+
# use this as an example of extended class
|
83
92
|
class TestClass
|
84
93
|
table_data do
|
85
94
|
context "time_of_day == :morning" do
|
86
|
-
add "18t", "year == 1995"
|
87
|
-
add "16t", "year == 1994"
|
95
|
+
add "18t", "year == 1995"
|
96
|
+
add "16t", "year == 1994"
|
88
97
|
end
|
89
98
|
context "time_of_day == :evening" do
|
90
|
-
add "8t", "year == 1995"
|
99
|
+
add "8t", "year == 1995"
|
91
100
|
end
|
92
101
|
end
|
93
102
|
end
|
@@ -96,6 +105,7 @@ describe MdData do
|
|
96
105
|
end
|
97
106
|
|
98
107
|
it 'is aware of dimensions' do
|
108
|
+
# use this as an example of extended class
|
99
109
|
class TestClass
|
100
110
|
dimension :year, [:year_1994, :year_1995]
|
101
111
|
dimension :time_of_day, [:morning, :evening]
|
@@ -107,6 +117,7 @@ describe MdData do
|
|
107
117
|
|
108
118
|
|
109
119
|
it 'is creates helper methods for dimensions values' do
|
120
|
+
# use this as an example of extended class
|
110
121
|
class TestClass
|
111
122
|
|
112
123
|
dimension :year, [:year_1994, :year_1995]
|
@@ -114,16 +125,90 @@ describe MdData do
|
|
114
125
|
|
115
126
|
table_data do
|
116
127
|
context "morning" do
|
117
|
-
add "18t", "year_1995"
|
118
|
-
add "16t", "year_1994"
|
128
|
+
add "18t", "year_1995"
|
129
|
+
add "16t", "year_1994"
|
119
130
|
end
|
120
131
|
context "evening" do
|
121
|
-
add "8t", "year_1995"
|
132
|
+
add "8t", "year_1995"
|
133
|
+
end
|
134
|
+
end
|
135
|
+
end
|
136
|
+
TestClass.select(:year => :year_1995, :time_of_day => :morning).should ==
|
137
|
+
"18t"
|
138
|
+
end
|
139
|
+
|
140
|
+
|
141
|
+
it 'is shuld create helper methods for dimensions when atttibute not sent' do
|
142
|
+
# use this as an example of extended class
|
143
|
+
class TestClassIsolated
|
144
|
+
include MdData
|
145
|
+
dimension :year, [:year_1994, :year_1995]
|
146
|
+
dimension :my_time_of_day, [:morning, :evening]
|
147
|
+
|
148
|
+
table_data do
|
149
|
+
context "my_time_of_day == :evening" do
|
150
|
+
add "8t", "year_1995"
|
151
|
+
add "7t", "year_1994"
|
152
|
+
end
|
153
|
+
context "morning" do
|
154
|
+
add "8t", "year_1995"
|
155
|
+
add "6t", "year_1994"
|
156
|
+
end
|
157
|
+
context "true" do
|
158
|
+
add "16t", "year_1995"
|
122
159
|
end
|
123
160
|
end
|
161
|
+
|
124
162
|
end
|
125
|
-
|
163
|
+
|
164
|
+
TestClassIsolated.select({:year => :year_1995}).should == "16t"
|
165
|
+
TestClassIsolated.select({:year => :year_1995}).should == "16t"
|
166
|
+
TestClassIsolated.select({:year => :year_1995,
|
167
|
+
:my_time_of_day => :morning}).should == "8t"
|
168
|
+
TestClassIsolated.select({:year => :year_1994,
|
169
|
+
:my_time_of_day => :evening}).should == "7t"
|
126
170
|
end
|
127
171
|
|
128
172
|
|
173
|
+
it 'is shuld create helper methods for dimensions
|
174
|
+
even if atttibute not sent and using delegator' do
|
175
|
+
# use this as an example of extended class
|
176
|
+
class TestClassIsolated
|
177
|
+
include MdData
|
178
|
+
dimension :year, [:year_1994, :year_1995]
|
179
|
+
dimension :my_2_time_of_day, [:morning, :evening]
|
180
|
+
|
181
|
+
table_data do
|
182
|
+
context "my_2_time_of_day == :evening" do
|
183
|
+
add "8t", "year_1995"
|
184
|
+
add "7t", "year_1994"
|
185
|
+
end
|
186
|
+
context "morning" do
|
187
|
+
add "8t", "year_1995"
|
188
|
+
add "6t", "year_1994"
|
189
|
+
end
|
190
|
+
context "true" do
|
191
|
+
add "16t", "year_1995"
|
192
|
+
end
|
193
|
+
end
|
194
|
+
|
195
|
+
end
|
196
|
+
|
197
|
+
# use this as an example of extended class
|
198
|
+
class Testing
|
199
|
+
attr_reader :table
|
200
|
+
def initialize
|
201
|
+
@table = TestClassIsolated
|
202
|
+
end
|
203
|
+
end
|
204
|
+
|
205
|
+
t = Testing.new
|
206
|
+
t.table.select({:year => :year_1995}).should == "16t"
|
207
|
+
t.table.select({:year => :year_1995}).should == "16t"
|
208
|
+
t.table.select({:year => :year_1995,
|
209
|
+
:my_2_time_of_day => :morning}).should == "8t"
|
210
|
+
t.table.select({:year => :year_1994,
|
211
|
+
:my_2_time_of_day => :evening}).should == "7t"
|
212
|
+
end
|
213
|
+
|
129
214
|
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: md_data
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.1.
|
4
|
+
version: 1.1.1
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2012-
|
12
|
+
date: 2012-04-27 00:00:00.000000000Z
|
13
13
|
dependencies: []
|
14
14
|
description: Describe multidimensional data with simple notation
|
15
15
|
email:
|
@@ -49,9 +49,10 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
49
49
|
version: '0'
|
50
50
|
requirements: []
|
51
51
|
rubyforge_project:
|
52
|
-
rubygems_version: 1.8.
|
52
|
+
rubygems_version: 1.8.10
|
53
53
|
signing_key:
|
54
54
|
specification_version: 3
|
55
55
|
summary: Easy way to descriebe and find values from multidimensional table.
|
56
56
|
test_files:
|
57
57
|
- spec/md_data/md_data_spec.rb
|
58
|
+
has_rdoc:
|