omnis 0.5.0 → 0.6.0
Sign up to get free protection for your applications and to get access to all the features.
- data/README.md +98 -9
- data/lib/omnis/query.rb +5 -0
- data/lib/omnis/version.rb +1 -1
- data/spec/lib/omnis/query_spec.rb +4 -0
- metadata +2 -2
data/README.md
CHANGED
@@ -74,10 +74,95 @@ Mongo::Connection.new['bms']['bookings'].find(mongo.selector, mongo.opts)
|
|
74
74
|
```
|
75
75
|
|
76
76
|
## Transformer
|
77
|
-
Transforms some data into another form of (flattened) data. Extractors can be used to get values from the data source.
|
77
|
+
Transforms some data into another form of (flattened) data. Extractors can be used to get values from the data source.
|
78
78
|
If the first parameter of a property denotes the output field, the second is a string which is passed as argument to the extractor.
|
79
79
|
|
80
|
-
|
80
|
+
There are different ways of getting values from a _source_ document to a _result_ document (or object), described below:
|
81
|
+
|
82
|
+
### Extractors
|
83
|
+
The most basic and simple approach is to use an extractor, one default extractor can be configured in the body of the class.
|
84
|
+
You can build your own extractor if you want, have a look at the built-in.
|
85
|
+
|
86
|
+
The `NestedHashExtractor` extracts data from a nested Hash document by providing a xpath like expression, best shown in an example:
|
87
|
+
|
88
|
+
```ruby
|
89
|
+
hash = {
|
90
|
+
'ref_anixe' => '1234',
|
91
|
+
'service': [
|
92
|
+
{ 'name': 'Hotel Wroclaw'}
|
93
|
+
]
|
94
|
+
}
|
95
|
+
|
96
|
+
xtr = Omnis::NestedHashExtractor.new
|
97
|
+
x_ref_anixe = xtr.extractor('ref_anixe')
|
98
|
+
ref_anixe = x_ref_anixe.(hash) # 1234
|
99
|
+
|
100
|
+
x_hotel_name = xtr.extractor('service.0.name')
|
101
|
+
hotel_name = x_hotel_name.(hash) # Hotel Wroclaw
|
102
|
+
```
|
103
|
+
|
104
|
+
The `MonadicHashExtractor` uses a `Maybe` monad from the [Monadic gem](https://github.com/pzol/monadic#maybe) to safely get values from the _source_.
|
105
|
+
|
106
|
+
The good thing about this is the easy of use in a Transformer
|
107
|
+
|
108
|
+
```ruby
|
109
|
+
class BookingTransformer
|
110
|
+
include Omnis::DataTransformer
|
111
|
+
extractor Omnis::NestedHashExtractor.new
|
112
|
+
|
113
|
+
property :ref_anixe, "ref_anixe"
|
114
|
+
property :hotel_name, "services.0.name"
|
115
|
+
end
|
116
|
+
|
117
|
+
transformer = BookingTransformer.new
|
118
|
+
result = transformer.transform(hash) # {:ref_anixe => '1234', :hotel_name => 'Hotel Wroclaw'}
|
119
|
+
```
|
120
|
+
Easy?
|
121
|
+
|
122
|
+
### Extraction with blocks
|
123
|
+
|
124
|
+
Instead of, or in addition to Extractors you can use blocks for the extraction
|
125
|
+
|
126
|
+
```ruby
|
127
|
+
class BookingTransformer
|
128
|
+
include Omnis::DataTransformer
|
129
|
+
|
130
|
+
property(:ref_anixe) {|src| src['ref_anixe']}
|
131
|
+
property(:hotel_name) {|src| src['services'][0]['name']}
|
132
|
+
end
|
133
|
+
|
134
|
+
# The transformation part remains the same.
|
135
|
+
transformer = BookingTransformer.new
|
136
|
+
result = transformer.transform(hash) # {:ref_anixe => '1234', :hotel_name => 'Hotel Wroclaw'}
|
137
|
+
```
|
138
|
+
This is for some scenarios when you need data validation or additional transformation.
|
139
|
+
|
140
|
+
### Extraction Class Functions
|
141
|
+
The third way to achieve the same is providing a class function. If no expression (or nil) is defined as the second argument to a property and no block hash been provided, the `DataTransformer` will look for a class method to fetch the data.
|
142
|
+
|
143
|
+
```ruby
|
144
|
+
class BookingTransformer
|
145
|
+
include Omnis::DataTransformer
|
146
|
+
extractor Omnis::NestedHashExtractor.new
|
147
|
+
|
148
|
+
property :ref_anixe
|
149
|
+
property :hotel_name
|
150
|
+
|
151
|
+
def self.ref_anixe(src)
|
152
|
+
src['ref_anixe']
|
153
|
+
end
|
154
|
+
|
155
|
+
def self.hotel_name(src)
|
156
|
+
extract(src, 'services.0.name').upcase # use the defined Extractor to get the value and modify it
|
157
|
+
end
|
158
|
+
end
|
159
|
+
|
160
|
+
# The transformation part remains the same, again.
|
161
|
+
transformer = BookingTransformer.new
|
162
|
+
result = transformer.transform(hash) # {:ref_anixe => '1234', :hotel_name => 'Hotel Wroclaw'}
|
163
|
+
```
|
164
|
+
|
165
|
+
### Example
|
81
166
|
```ruby
|
82
167
|
class BookingTransformer
|
83
168
|
include Omnis::DataTransformer
|
@@ -105,7 +190,8 @@ class BookingTransformer
|
|
105
190
|
end
|
106
191
|
```
|
107
192
|
|
108
|
-
Usage
|
193
|
+
### Usage
|
194
|
+
The most basic usage is to provide a document to the transform method
|
109
195
|
```ruby
|
110
196
|
transformer = BookingTransformer.new
|
111
197
|
transformer.transform(doc)
|
@@ -123,7 +209,16 @@ end
|
|
123
209
|
|
124
210
|
If you provide a `#to_object(hash)` method in the Transformer definition, it will be used to convert the output Hash into the object of you desire.
|
125
211
|
|
212
|
+
The way I use it most is to get a proc and pass it directly to the `#find` method of the ruby driver:
|
213
|
+
|
214
|
+
```ruby
|
215
|
+
transformer = BookingTransformer.new.to_proc
|
216
|
+
connection = Mongo::Connection.new
|
217
|
+
connection.db('some_db').collection('some_collection').find({}, :transformer => transformer)
|
218
|
+
```
|
219
|
+
|
126
220
|
## Putting it all together
|
221
|
+
The really good stuff is using the query and the transformer together.
|
127
222
|
|
128
223
|
```ruby
|
129
224
|
query = BookingQuery.new("ref_anixe" => "1abc", "product" => "HOT").to_mongo
|
@@ -131,12 +226,6 @@ transformer = BookingTransformer.new.to_proc
|
|
131
226
|
collection = Mongo::Connection.new['bms']['bookings']
|
132
227
|
|
133
228
|
table = collection.find(query.selector, query.opts.merge(:transformer => transformer))
|
134
|
-
|
135
|
-
table = Omnis::MongoTable.new(connection, params, BookingQuery, BookingTransformer)
|
136
|
-
|
137
|
-
table.call.each do |row|
|
138
|
-
row.
|
139
|
-
end
|
140
229
|
```
|
141
230
|
|
142
231
|
## Installation
|
data/lib/omnis/query.rb
CHANGED
data/lib/omnis/version.rb
CHANGED
@@ -31,6 +31,10 @@ describe Omnis::Query do
|
|
31
31
|
t.fetch(:ref_anixe).should == Omnis::Operators::Matches.new(:ref_anixe, "1abc")
|
32
32
|
end
|
33
33
|
|
34
|
+
it "returns a list of keys that are requested" do
|
35
|
+
t = TestBookingParams.new({"ref_anixe" => "1abc"})
|
36
|
+
t.keys.should == [:ref_anixe]
|
37
|
+
end
|
34
38
|
it "allows to extract all at once" do
|
35
39
|
t = TestBookingParams.new({"ref_anixe" => "1abc"})
|
36
40
|
t.extract.should == [Omnis::Operators::Matches.new(:ref_anixe, "1abc")]
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: omnis
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.6.0
|
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-11-
|
12
|
+
date: 2012-11-25 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: activesupport
|