mordor 0.1.3 → 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/README.md +19 -0
- data/lib/mordor/collection.rb +6 -37
- data/lib/mordor/resource.rb +47 -15
- data/mordor.gemspec +3 -3
- data/spec/mordor/collection_spec.rb +79 -8
- data/spec/mordor/resource_spec.rb +56 -5
- metadata +6 -6
- data/README +0 -13
data/README.md
ADDED
@@ -0,0 +1,19 @@
|
|
1
|
+
## Introduction
|
2
|
+
Small library to add DataMapper style resources for MongoDB.
|
3
|
+
|
4
|
+
```ruby
|
5
|
+
class ExampleResource
|
6
|
+
include Mordor::Resource
|
7
|
+
|
8
|
+
attribute :first, :index => true
|
9
|
+
attribute :second
|
10
|
+
attribute :third, :finder_method => :find_by_third_attribute
|
11
|
+
end
|
12
|
+
```
|
13
|
+
|
14
|
+
This adds attr_accessors to the ExampleResource for each attribute, plus adds finder methods of the form
|
15
|
+
`find_by_{attribute}`. The naming convention can be overridden by using the optional `:finder_method` option,
|
16
|
+
as can be seen with the third attribute.
|
17
|
+
|
18
|
+
When the `:index => true` option is set, indices are ensured before each query on
|
19
|
+
the collection. Indices are descending by default, but this can be changed by also supplying a `:index_type => Mongo::ASCENDING` option.
|
data/lib/mordor/collection.rb
CHANGED
@@ -7,22 +7,6 @@ module Mordor
|
|
7
7
|
@cursor = cursor
|
8
8
|
end
|
9
9
|
|
10
|
-
def to_a
|
11
|
-
array = []
|
12
|
-
unless @cursor.is_a? Array
|
13
|
-
@cursor.each do |element|
|
14
|
-
if element.is_a? @klass
|
15
|
-
array << element
|
16
|
-
else
|
17
|
-
array << @klass.new(element)
|
18
|
-
end
|
19
|
-
end
|
20
|
-
else
|
21
|
-
array = @cursor.dup
|
22
|
-
end
|
23
|
-
array
|
24
|
-
end
|
25
|
-
|
26
10
|
def each
|
27
11
|
@cursor.each do |element|
|
28
12
|
if element.is_a? @klass
|
@@ -31,21 +15,13 @@ module Mordor
|
|
31
15
|
yield @klass.new(element)
|
32
16
|
end
|
33
17
|
end
|
18
|
+
@cursor.rewind! unless @cursor.is_a? Array
|
34
19
|
end
|
35
20
|
|
36
|
-
def
|
37
|
-
|
38
|
-
@cursor.first ? @klass.new(@cursor.first) : nil
|
39
|
-
else
|
40
|
-
result = @cursor.first
|
41
|
-
@cursor.rewind!
|
42
|
-
result ? @klass.new(result) : nil
|
43
|
-
end
|
44
|
-
end
|
45
|
-
|
46
|
-
def size
|
47
|
-
@cursor.count
|
21
|
+
def size(regard_limits_and_offsets = true)
|
22
|
+
@cursor.is_a?(Array) ? @cursor.count : @cursor.count(regard_limits_and_offsets)
|
48
23
|
end
|
24
|
+
alias :count :size
|
49
25
|
|
50
26
|
def method_missing(method, *args, &block)
|
51
27
|
if @cursor.respond_to?(method)
|
@@ -55,15 +31,8 @@ module Mordor
|
|
55
31
|
end
|
56
32
|
end
|
57
33
|
|
58
|
-
def to_json
|
59
|
-
|
60
|
-
res = {
|
61
|
-
collection_name => []
|
62
|
-
}
|
63
|
-
each do |elem|
|
64
|
-
res[collection_name] << elem.to_hash
|
65
|
-
end
|
66
|
-
res.to_json
|
34
|
+
def to_json(*args)
|
35
|
+
to_a.to_json(*args)
|
67
36
|
end
|
68
37
|
|
69
38
|
def merge(other_collection)
|
data/lib/mordor/resource.rb
CHANGED
@@ -28,7 +28,9 @@ module Mordor
|
|
28
28
|
when Hash
|
29
29
|
value = replace_params(value)
|
30
30
|
when Date, DateTime
|
31
|
-
value = value.to_time
|
31
|
+
value = value.to_time.getlocal
|
32
|
+
when Time
|
33
|
+
value = value.getlocal
|
32
34
|
when BigDecimal
|
33
35
|
value = value.to_f
|
34
36
|
when Array
|
@@ -81,6 +83,10 @@ module Mordor
|
|
81
83
|
result
|
82
84
|
end
|
83
85
|
|
86
|
+
def to_json(*args)
|
87
|
+
to_hash.merge(:_id => _id).to_json(*args)
|
88
|
+
end
|
89
|
+
|
84
90
|
module ClassMethods
|
85
91
|
def create(attributes = {})
|
86
92
|
resource = self.new(attributes)
|
@@ -89,7 +95,7 @@ module Mordor
|
|
89
95
|
end
|
90
96
|
|
91
97
|
def all(options = {})
|
92
|
-
Collection.new(self,
|
98
|
+
Collection.new(self, perform_collection_find({}, options))
|
93
99
|
end
|
94
100
|
|
95
101
|
def collection
|
@@ -105,7 +111,7 @@ module Mordor
|
|
105
111
|
if id.is_a?(String)
|
106
112
|
id = BSON::ObjectId.from_string(id)
|
107
113
|
end
|
108
|
-
if attributes =
|
114
|
+
if attributes = perform_collection_find_one(:_id => id)
|
109
115
|
new(attributes)
|
110
116
|
else
|
111
117
|
nil
|
@@ -116,12 +122,13 @@ module Mordor
|
|
116
122
|
@connection ||= Mordor.connection
|
117
123
|
end
|
118
124
|
|
125
|
+
|
119
126
|
def find_by_id(id)
|
120
127
|
get(id)
|
121
128
|
end
|
122
129
|
|
123
130
|
def find(query, options = {})
|
124
|
-
Collection.new(self,
|
131
|
+
Collection.new(self, perform_collection_find(query, options))
|
125
132
|
end
|
126
133
|
|
127
134
|
def find_by_day(day, options = {})
|
@@ -137,17 +144,21 @@ module Mordor
|
|
137
144
|
end_of_day = (day.to_date + 1).to_datetime.to_date.to_time
|
138
145
|
end
|
139
146
|
hash = {:at => {'$gte' => start, '$lt' => end_of_day}}
|
140
|
-
|
141
|
-
cursor = collection.find({:at => {'$gte' => start, '$lt' => end_of_day}}, options).to_a
|
142
|
-
else
|
143
|
-
cursor = collection.find({:at => {'$gte' => start, '$lt' => end_of_day}})
|
144
|
-
end
|
147
|
+
cursor = perform_collection_find({:at => {'$gte' => start, '$lt' => end_of_day}}, options)
|
145
148
|
Collection.new(self, cursor)
|
146
149
|
end
|
147
150
|
|
151
|
+
|
148
152
|
def attribute(name, options = {})
|
149
|
-
@attributes
|
153
|
+
@attributes ||= []
|
154
|
+
@indices ||= []
|
155
|
+
@index_types ||= {}
|
156
|
+
|
150
157
|
@attributes << name unless @attributes.include?(name)
|
158
|
+
if options[:index]
|
159
|
+
@indices << name unless @indices.include?(name)
|
160
|
+
@index_types[name] = options[:index_type] ? options[:index_type] : Mongo::DESCENDING
|
161
|
+
end
|
151
162
|
|
152
163
|
method_name = options.key?(:finder_method) ? options[:finder_method] : "find_by_#{name}"
|
153
164
|
|
@@ -156,15 +167,36 @@ module Mordor
|
|
156
167
|
attr_accessor name
|
157
168
|
|
158
169
|
def self.#{method_name}(value, options = {})
|
159
|
-
|
160
|
-
col = collection.find({:#{name} => value}, options).to_a
|
161
|
-
else
|
162
|
-
col = collection.find(:#{name} => value)
|
163
|
-
end
|
170
|
+
col = perform_collection_find({:#{name} => value}, options)
|
164
171
|
Collection.new(self, col)
|
165
172
|
end
|
166
173
|
EOS
|
167
174
|
end
|
175
|
+
|
176
|
+
private
|
177
|
+
def perform_collection_find(query, options = {})
|
178
|
+
ensure_indices
|
179
|
+
collection.find(query, options)
|
180
|
+
end
|
181
|
+
|
182
|
+
def perform_collection_find_one(query, options = {})
|
183
|
+
ensure_indices
|
184
|
+
collection.find_one(query, options)
|
185
|
+
end
|
186
|
+
|
187
|
+
def ensure_indices
|
188
|
+
indices.each do |index|
|
189
|
+
collection.ensure_index( [ [index.to_s, index_types[index]] ] )
|
190
|
+
end
|
191
|
+
end
|
192
|
+
|
193
|
+
def indices
|
194
|
+
@indices ||= []
|
195
|
+
end
|
196
|
+
|
197
|
+
def index_types
|
198
|
+
@index_types ||= {}
|
199
|
+
end
|
168
200
|
end
|
169
201
|
end
|
170
202
|
end
|
data/mordor.gemspec
CHANGED
@@ -2,8 +2,8 @@ Gem::Specification.new do |s|
|
|
2
2
|
s.name = "mordor"
|
3
3
|
|
4
4
|
# Do not set the version and date field manually, this is done by the release script
|
5
|
-
s.version = "0.
|
6
|
-
s.date = "2011-
|
5
|
+
s.version = "0.2.0"
|
6
|
+
s.date = "2011-12-23"
|
7
7
|
|
8
8
|
s.summary = "mordor"
|
9
9
|
s.description = <<-eos
|
@@ -29,6 +29,6 @@ Gem::Specification.new do |s|
|
|
29
29
|
|
30
30
|
# The files and test_files directives are set automatically by the release script.
|
31
31
|
# Do not change them by hand, but make sure to add the files to the git repository.
|
32
|
-
s.files = %w(.gitignore Gemfile Gemfile.lock README Rakefile lib/mordor.rb lib/mordor/collection.rb lib/mordor/resource.rb lib/mordor/version.rb mordor.gemspec spec/mordor/collection_spec.rb spec/mordor/connection_spec.rb spec/mordor/resource_spec.rb spec/spec.opts spec/spec_helper.rb tasks/github-gem.rake)
|
32
|
+
s.files = %w(.gitignore Gemfile Gemfile.lock README.md Rakefile lib/mordor.rb lib/mordor/collection.rb lib/mordor/resource.rb lib/mordor/version.rb mordor.gemspec spec/mordor/collection_spec.rb spec/mordor/connection_spec.rb spec/mordor/resource_spec.rb spec/spec.opts spec/spec_helper.rb tasks/github-gem.rake)
|
33
33
|
end
|
34
34
|
|
@@ -4,9 +4,9 @@ describe "with respect to collections" do
|
|
4
4
|
class TestResource
|
5
5
|
include Mordor::Resource
|
6
6
|
|
7
|
-
attribute :first
|
8
|
-
attribute :second
|
9
|
-
attribute :third,
|
7
|
+
attribute :first, :index => true
|
8
|
+
attribute :second, :index => true, :index_type => Mongo::ASCENDING
|
9
|
+
attribute :third, :finder_method => :find_by_third_attribute
|
10
10
|
end
|
11
11
|
|
12
12
|
describe "serialization" do
|
@@ -28,11 +28,82 @@ describe "with respect to collections" do
|
|
28
28
|
|
29
29
|
json_collection = JSON.parse(json_collection)
|
30
30
|
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
31
|
+
json_collection.size.should == 5
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
describe "converting to array" do
|
36
|
+
before :all do
|
37
|
+
clean_sheet
|
38
|
+
|
39
|
+
5.times do |index|
|
40
|
+
res = TestResource.new(:first => "#{index}_first", :second => "#{index}_second", :third => "#{index}_third")
|
41
|
+
res.save.should be_true
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
it "should be possible to convert a collection to an array" do
|
46
|
+
collection = TestResource.find_by_first("1_first")
|
47
|
+
collection.to_a.should be_a Array
|
48
|
+
end
|
49
|
+
|
50
|
+
it "should be possible to convert multiple times after iterating using each" do
|
51
|
+
collection = TestResource.find_by_first("1_first")
|
52
|
+
collection.each do |resource|
|
53
|
+
resource.first
|
54
|
+
end
|
55
|
+
array1 = collection.to_a
|
56
|
+
array2 = collection.to_a
|
57
|
+
array1.size.should == array2.size
|
58
|
+
end
|
59
|
+
|
60
|
+
it "should be possible to convert a collection to an array multiple times" do
|
61
|
+
collection = TestResource.find_by_first("1_first")
|
62
|
+
array1 = collection.to_a
|
63
|
+
array2 = collection.to_a
|
64
|
+
array1.size.should == array2.size
|
65
|
+
end
|
66
|
+
|
67
|
+
it "should convert the collection to an array with the same size" do
|
68
|
+
collection = TestResource.find_by_first("1_first")
|
69
|
+
collection_size = collection.size
|
70
|
+
collection.to_a.size.should == collection_size
|
71
|
+
end
|
72
|
+
end
|
73
|
+
|
74
|
+
describe "counting" do
|
75
|
+
|
76
|
+
before :all do
|
77
|
+
clean_sheet
|
78
|
+
|
79
|
+
5.times do |index|
|
80
|
+
res = TestResource.new(:first => "#{index}_first", :second => "#{index}_second", :third => "#{index}_third")
|
81
|
+
res.save.should be_true
|
82
|
+
end
|
83
|
+
end
|
84
|
+
|
85
|
+
it "should default to taking in account limits" do
|
86
|
+
TestResource.find({}, {:limit => 3}).count.should == 3
|
87
|
+
end
|
88
|
+
|
89
|
+
it "should not take in account limits when requested" do
|
90
|
+
TestResource.find({}, {:limit => 3}).count(false).should == 5
|
91
|
+
end
|
92
|
+
|
93
|
+
it "should not take in account skips when requested" do
|
94
|
+
TestResource.find({}, {:skip => 2}).count(false).should == 5
|
95
|
+
end
|
96
|
+
|
97
|
+
it "should not take in account skips and limits when requested" do
|
98
|
+
TestResource.find({}, {:skip => 1, :limit => 3}).count(false).should == 5
|
99
|
+
end
|
100
|
+
|
101
|
+
it "should take in account skips by defaults" do
|
102
|
+
TestResource.find({}, {:skip => 2}).count.should == 3
|
103
|
+
end
|
104
|
+
|
105
|
+
it "should take in account skips and limits by default" do
|
106
|
+
TestResource.find({}, {:skip => 1, :limit => 3}).count.should == 3
|
36
107
|
end
|
37
108
|
end
|
38
109
|
|
@@ -1,12 +1,22 @@
|
|
1
1
|
require File.join(File.dirname(__FILE__), '..', '/spec_helper.rb')
|
2
2
|
|
3
3
|
describe "with respect to resources" do
|
4
|
-
|
5
|
-
|
4
|
+
before :each do
|
5
|
+
class TestResource
|
6
|
+
include Mordor::Resource
|
7
|
+
|
8
|
+
attribute :first, :index => true
|
9
|
+
attribute :second, :index => true, :index_type => Mongo::ASCENDING
|
10
|
+
attribute :third, :finder_method => :find_by_third_attribute
|
11
|
+
|
12
|
+
# Put this in here again to ensure the original method is still here
|
13
|
+
class_eval do
|
14
|
+
def self.ensure_indices
|
15
|
+
collection.ensure_index( indices.map{|index| [index.to_s, Mongo::DESCENDING]} ) if indices.any?
|
16
|
+
end
|
6
17
|
|
7
|
-
|
8
|
-
|
9
|
-
attribute :third, :finder_method => :find_by_third_attribute
|
18
|
+
end
|
19
|
+
end
|
10
20
|
end
|
11
21
|
|
12
22
|
it "should create accessor methods for all attributes" do
|
@@ -23,6 +33,47 @@ describe "with respect to resources" do
|
|
23
33
|
TestResource.methods.should include "find_by_third_attribute"
|
24
34
|
end
|
25
35
|
|
36
|
+
it "should ensure indices when the option :index => true is given" do
|
37
|
+
TestResource.send(:indices).should include :first
|
38
|
+
end
|
39
|
+
|
40
|
+
it "should default to descending indices" do
|
41
|
+
TestResource.send(:index_types).keys.should include :first
|
42
|
+
TestResource.send(:index_types)[:first].should == Mongo::DESCENDING
|
43
|
+
end
|
44
|
+
|
45
|
+
it "should be possible to set index type using the 'index_type' option" do
|
46
|
+
TestResource.send(:index_types).keys.should include :second
|
47
|
+
TestResource.send(:index_types)[:second].should == Mongo::ASCENDING
|
48
|
+
end
|
49
|
+
|
50
|
+
it "should call ensure_index on the collection for each index when a query is performed" do
|
51
|
+
TestResource.class_eval do
|
52
|
+
def self.ensure_count
|
53
|
+
@count ||= 0
|
54
|
+
end
|
55
|
+
|
56
|
+
def self.ensure_count=(val)
|
57
|
+
@count = val
|
58
|
+
end
|
59
|
+
|
60
|
+
private
|
61
|
+
def self.do_ensure_indices
|
62
|
+
indices.each do |index|
|
63
|
+
collection.ensure_index( [ [index.to_s, index_types[index]] ] )
|
64
|
+
end
|
65
|
+
end
|
66
|
+
|
67
|
+
def self.ensure_indices
|
68
|
+
self.ensure_count = self.ensure_count + 1
|
69
|
+
self.do_ensure_indices
|
70
|
+
end
|
71
|
+
end
|
72
|
+
TestResource.create({:first => 'first', :second => 'second', :third => 'third'})
|
73
|
+
TestResource.all()
|
74
|
+
TestResource.ensure_count.should == 1
|
75
|
+
end
|
76
|
+
|
26
77
|
context "with respect to replacing params" do
|
27
78
|
before :each do
|
28
79
|
clean_sheet
|
metadata
CHANGED
@@ -1,13 +1,13 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: mordor
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
hash:
|
4
|
+
hash: 23
|
5
5
|
prerelease: false
|
6
6
|
segments:
|
7
7
|
- 0
|
8
|
-
-
|
9
|
-
-
|
10
|
-
version: 0.
|
8
|
+
- 2
|
9
|
+
- 0
|
10
|
+
version: 0.2.0
|
11
11
|
platform: ruby
|
12
12
|
authors:
|
13
13
|
- Jan-Willem Koelewijn
|
@@ -16,7 +16,7 @@ autorequire:
|
|
16
16
|
bindir: bin
|
17
17
|
cert_chain: []
|
18
18
|
|
19
|
-
date: 2011-
|
19
|
+
date: 2011-12-23 00:00:00 +01:00
|
20
20
|
default_executable:
|
21
21
|
dependencies:
|
22
22
|
- !ruby/object:Gem::Dependency
|
@@ -174,7 +174,7 @@ files:
|
|
174
174
|
- .gitignore
|
175
175
|
- Gemfile
|
176
176
|
- Gemfile.lock
|
177
|
-
- README
|
177
|
+
- README.md
|
178
178
|
- Rakefile
|
179
179
|
- lib/mordor.rb
|
180
180
|
- lib/mordor/collection.rb
|
data/README
DELETED
@@ -1,13 +0,0 @@
|
|
1
|
-
Small library to add DataMapper style resources for MongoDB.
|
2
|
-
|
3
|
-
class ExampleResource
|
4
|
-
include Mordor::Resource
|
5
|
-
|
6
|
-
attribute :first
|
7
|
-
attribute :second
|
8
|
-
attribute :third, :finder_method => :find_by_third_attribute
|
9
|
-
end
|
10
|
-
|
11
|
-
This adds attr_accessors to the ExampleResource for each attribute, plus adds finder methods of the form
|
12
|
-
find_by_{attribute}. The naming convention can be overridden by using the optional :finder_method option,
|
13
|
-
as can be seen with the third attribute.
|