mongo_mapper 0.8.0 → 0.8.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/lib/mongo_mapper.rb +2 -16
- data/lib/mongo_mapper/plugins/associations/in_array_proxy.rb +1 -1
- data/lib/mongo_mapper/plugins/associations/many_documents_proxy.rb +13 -31
- data/lib/mongo_mapper/plugins/document.rb +1 -1
- data/lib/mongo_mapper/plugins/dynamic_querying.rb +2 -0
- data/lib/mongo_mapper/plugins/identity_map.rb +24 -17
- data/lib/mongo_mapper/plugins/keys.rb +2 -0
- data/lib/mongo_mapper/plugins/querying.rb +7 -67
- data/lib/mongo_mapper/plugins/querying/decorator.rb +1 -1
- data/lib/mongo_mapper/plugins/querying/plucky_methods.rb +15 -0
- data/lib/mongo_mapper/plugins/validations.rb +2 -2
- data/lib/mongo_mapper/version.rb +1 -1
- data/test/{NOTE_ON_TESTING → _NOTE_ON_TESTING} +0 -0
- data/test/functional/associations/test_many_documents_proxy.rb +39 -0
- data/test/functional/test_identity_map.rb +3 -3
- data/test/models.rb +6 -0
- data/test/{active_model_lint_test.rb → test_active_model_lint.rb} +0 -0
- data/test/test_helper.rb +17 -11
- metadata +13 -12
data/lib/mongo_mapper.rb
CHANGED
@@ -65,22 +65,6 @@ module MongoMapper
|
|
65
65
|
autoload :OneEmbeddedProxy, 'mongo_mapper/plugins/associations/one_embedded_proxy'
|
66
66
|
autoload :InArrayProxy, 'mongo_mapper/plugins/associations/in_array_proxy'
|
67
67
|
end
|
68
|
-
|
69
|
-
module DynamicQuerying
|
70
|
-
autoload :DynamicFinder, 'mongo_mapper/plugins/dynamic_querying/dynamic_finder'
|
71
|
-
end
|
72
|
-
|
73
|
-
module Keys
|
74
|
-
autoload :Key, 'mongo_mapper/plugins/keys/key'
|
75
|
-
end
|
76
|
-
|
77
|
-
module Querying
|
78
|
-
autoload :Decorator, 'mongo_mapper/plugins/querying/decorator'
|
79
|
-
end
|
80
|
-
end
|
81
|
-
|
82
|
-
module Support
|
83
|
-
autoload :DescendantAppends, 'mongo_mapper/support/descendant_appends'
|
84
68
|
end
|
85
69
|
|
86
70
|
extend Connection
|
@@ -90,5 +74,7 @@ Dir[File.join(File.dirname(__FILE__), 'mongo_mapper', 'extensions', '*.rb')].eac
|
|
90
74
|
require extension
|
91
75
|
end
|
92
76
|
|
77
|
+
require 'mongo_mapper/support/descendant_appends'
|
78
|
+
|
93
79
|
# FIXME: autoload with proxy is failing, need to investigate
|
94
80
|
require 'mongo_mapper/plugins/associations/proxy'
|
@@ -3,35 +3,8 @@ module MongoMapper
|
|
3
3
|
module Plugins
|
4
4
|
module Associations
|
5
5
|
class ManyDocumentsProxy < Collection
|
6
|
-
include
|
7
|
-
|
8
|
-
def find(*args)
|
9
|
-
query.find(*args)
|
10
|
-
end
|
11
|
-
|
12
|
-
def find!(*args)
|
13
|
-
query.find!(*args)
|
14
|
-
end
|
15
|
-
|
16
|
-
def paginate(options)
|
17
|
-
query.paginate(options)
|
18
|
-
end
|
19
|
-
|
20
|
-
def all(options={})
|
21
|
-
query(options).all
|
22
|
-
end
|
23
|
-
|
24
|
-
def first(options={})
|
25
|
-
query(options).first
|
26
|
-
end
|
27
|
-
|
28
|
-
def last(options={})
|
29
|
-
query(options).last
|
30
|
-
end
|
31
|
-
|
32
|
-
def count(options={})
|
33
|
-
query(options).count
|
34
|
-
end
|
6
|
+
include DynamicQuerying::ClassMethods
|
7
|
+
include Querying::PluckyMethods
|
35
8
|
|
36
9
|
def replace(docs)
|
37
10
|
load_target
|
@@ -93,8 +66,17 @@ module MongoMapper
|
|
93
66
|
def query(options={})
|
94
67
|
klass.
|
95
68
|
query(association.query_options).
|
96
|
-
update(options).
|
97
|
-
|
69
|
+
update(options).update(criteria)
|
70
|
+
end
|
71
|
+
|
72
|
+
def method_missing(method, *args, &block)
|
73
|
+
if klass.respond_to?(method)
|
74
|
+
result = klass.send(method, *args, &block)
|
75
|
+
result.is_a?(Plucky::Query) ?
|
76
|
+
query.merge(result) : super
|
77
|
+
else
|
78
|
+
super
|
79
|
+
end
|
98
80
|
end
|
99
81
|
|
100
82
|
def criteria
|
@@ -18,7 +18,7 @@ module MongoMapper
|
|
18
18
|
end
|
19
19
|
|
20
20
|
def reload
|
21
|
-
if doc =
|
21
|
+
if doc = collection.find_one(:_id => id)
|
22
22
|
tap do |instance|
|
23
23
|
instance.class.associations.each_key do |association_name|
|
24
24
|
send(association_name).reset if respond_to?(association_name)
|
@@ -30,21 +30,34 @@ module MongoMapper
|
|
30
30
|
@identity_map = v
|
31
31
|
end
|
32
32
|
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
33
|
+
module IdentityMapQueryMethods
|
34
|
+
def all(opts={})
|
35
|
+
query = clone.update(opts)
|
36
|
+
super.tap do |docs|
|
37
|
+
model.remove_documents_from_map(docs) if query.fields?
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
def find_one(opts={})
|
42
|
+
query = clone.update(opts)
|
43
|
+
|
44
|
+
if query.simple? && model.identity_map[query[:_id]]
|
45
|
+
model.identity_map[query[:_id]]
|
46
|
+
else
|
47
|
+
super.tap do |doc|
|
48
|
+
model.remove_documents_from_map(doc) if query.fields?
|
49
|
+
end
|
41
50
|
end
|
42
51
|
end
|
43
52
|
end
|
44
53
|
|
45
|
-
def
|
46
|
-
super.
|
47
|
-
|
54
|
+
def query(opts={})
|
55
|
+
super.extend(IdentityMapQueryMethods)
|
56
|
+
end
|
57
|
+
|
58
|
+
def remove_documents_from_map(*documents)
|
59
|
+
documents.flatten.compact.each do |document|
|
60
|
+
identity_map.delete(document['_id'])
|
48
61
|
end
|
49
62
|
end
|
50
63
|
|
@@ -88,12 +101,6 @@ module MongoMapper
|
|
88
101
|
end
|
89
102
|
|
90
103
|
private
|
91
|
-
def remove_documents_from_map(*documents)
|
92
|
-
documents.flatten.compact.each do |document|
|
93
|
-
identity_map.delete(document._id)
|
94
|
-
end
|
95
|
-
end
|
96
|
-
|
97
104
|
def selecting_fields?(options)
|
98
105
|
!options[:fields].nil?
|
99
106
|
end
|
@@ -1,61 +1,21 @@
|
|
1
1
|
# encoding: UTF-8
|
2
|
+
require 'mongo_mapper/plugins/querying/decorator'
|
3
|
+
require 'mongo_mapper/plugins/querying/plucky_methods'
|
4
|
+
|
2
5
|
module MongoMapper
|
3
6
|
module Plugins
|
4
7
|
module Querying
|
5
8
|
module ClassMethods
|
6
|
-
|
7
|
-
options = args.extract_options!
|
8
|
-
return nil if args.size == 0
|
9
|
-
|
10
|
-
if args.first.is_a?(Array) || args.size > 1
|
11
|
-
find_some(args, options)
|
12
|
-
else
|
13
|
-
find_one(options.merge(:_id => args[0]))
|
14
|
-
end
|
15
|
-
end
|
16
|
-
|
17
|
-
def find!(*args)
|
18
|
-
options = args.extract_options!
|
19
|
-
raise DocumentNotFound, "Couldn't find without an ID" if args.size == 0
|
9
|
+
include PluckyMethods
|
20
10
|
|
21
|
-
|
22
|
-
|
23
|
-
else
|
24
|
-
find_one(options.merge(:_id => args[0])) ||
|
25
|
-
raise(DocumentNotFound, "Document match #{options.inspect} does not exist
|
26
|
-
in #{collection.name} collection")
|
27
|
-
end
|
28
|
-
end
|
29
|
-
|
30
|
-
def find_each(options={})
|
31
|
-
query(options).find_each.each { |doc| yield load(doc) }
|
11
|
+
def find_each(opts={})
|
12
|
+
super(opts).each { |doc| yield load(doc) }
|
32
13
|
end
|
33
14
|
|
34
15
|
def find_by_id(id)
|
35
16
|
find_one(:_id => id)
|
36
17
|
end
|
37
18
|
|
38
|
-
def first(options={})
|
39
|
-
find_one(options)
|
40
|
-
end
|
41
|
-
|
42
|
-
# All bets are off an actual order if you provide none.
|
43
|
-
def last(options={})
|
44
|
-
find_one(query(options).reverse.to_hash)
|
45
|
-
end
|
46
|
-
|
47
|
-
def all(options={})
|
48
|
-
find_many(options)
|
49
|
-
end
|
50
|
-
|
51
|
-
def count(options={})
|
52
|
-
query(options).count
|
53
|
-
end
|
54
|
-
|
55
|
-
def exists?(options={})
|
56
|
-
!count(options).zero?
|
57
|
-
end
|
58
|
-
|
59
19
|
def first_or_create(args)
|
60
20
|
first(args) || create(args.reject { |key, value| !key?(key) })
|
61
21
|
end
|
@@ -97,30 +57,10 @@ module MongoMapper
|
|
97
57
|
find_each(options) { |document| document.destroy }
|
98
58
|
end
|
99
59
|
|
100
|
-
def where(options={})
|
101
|
-
query.where(options)
|
102
|
-
end
|
103
|
-
|
104
|
-
def fields(*args)
|
105
|
-
query.fields(*args)
|
106
|
-
end
|
107
|
-
|
108
|
-
def limit(*args)
|
109
|
-
query.limit(*args)
|
110
|
-
end
|
111
|
-
|
112
|
-
def skip(*args)
|
113
|
-
query.skip(*args)
|
114
|
-
end
|
115
|
-
|
116
|
-
def sort(*args)
|
117
|
-
query.sort(*args)
|
118
|
-
end
|
119
|
-
|
120
60
|
# @api private for now
|
121
61
|
def query(options={})
|
122
62
|
Plucky::Query.new(collection).tap do |query|
|
123
|
-
query.extend(
|
63
|
+
query.extend(Decorator)
|
124
64
|
query.object_ids(object_id_keys)
|
125
65
|
query.update(options)
|
126
66
|
query.model(self)
|
@@ -0,0 +1,15 @@
|
|
1
|
+
# encoding: UTF-8
|
2
|
+
require 'forwardable'
|
3
|
+
|
4
|
+
module MongoMapper
|
5
|
+
module Plugins
|
6
|
+
module Querying
|
7
|
+
module PluckyMethods
|
8
|
+
extend Forwardable
|
9
|
+
def_delegators :query, :where, :fields, :limit, :skip, :sort,
|
10
|
+
:count, :last, :first, :all, :paginate,
|
11
|
+
:find, :find!, :exists?, :exist?, :find_each
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
@@ -5,13 +5,13 @@ module MongoMapper
|
|
5
5
|
def self.configure(model)
|
6
6
|
model.class_eval do
|
7
7
|
include Validatable
|
8
|
-
extend
|
8
|
+
extend Validations::DocumentMacros
|
9
9
|
end
|
10
10
|
end
|
11
11
|
|
12
12
|
module DocumentMacros
|
13
13
|
def validates_uniqueness_of(*args)
|
14
|
-
add_validations(args,
|
14
|
+
add_validations(args, Validations::ValidatesUniquenessOf)
|
15
15
|
end
|
16
16
|
end
|
17
17
|
|
data/lib/mongo_mapper/version.rb
CHANGED
File without changes
|
@@ -345,6 +345,45 @@ class ManyDocumentsProxyTest < Test::Unit::TestCase
|
|
345
345
|
end
|
346
346
|
end
|
347
347
|
|
348
|
+
context "sexy querying" do
|
349
|
+
should "work with where" do
|
350
|
+
@project1.statuses.where(:name => 'New').all.should == [@brand_new]
|
351
|
+
end
|
352
|
+
|
353
|
+
should "work with sort" do
|
354
|
+
@project1.statuses.sort(:name).all.should == [@complete, @brand_new]
|
355
|
+
end
|
356
|
+
|
357
|
+
should "work with limit" do
|
358
|
+
@project1.statuses.sort(:name).limit(1).all.should == [@complete]
|
359
|
+
end
|
360
|
+
|
361
|
+
should "work with skip" do
|
362
|
+
@project1.statuses.sort(:name).skip(1).all.should == [@brand_new]
|
363
|
+
end
|
364
|
+
|
365
|
+
should "work with fields" do
|
366
|
+
@project1.statuses.fields(:position).all.each do |status|
|
367
|
+
status.position.should_not be_nil
|
368
|
+
status.name.should be_nil
|
369
|
+
end
|
370
|
+
end
|
371
|
+
|
372
|
+
should "work with scopes" do
|
373
|
+
@project1.statuses.complete.all.should == [@complete]
|
374
|
+
end
|
375
|
+
|
376
|
+
should "work with methods on class that return query" do
|
377
|
+
@project1.statuses.by_position(1).first.should == @brand_new
|
378
|
+
end
|
379
|
+
|
380
|
+
should "not work with methods on class that do not return query" do
|
381
|
+
Status.class_eval { def self.foo; 'foo' end }
|
382
|
+
lambda { @project1.statuses.foo }.
|
383
|
+
should raise_error(NoMethodError)
|
384
|
+
end
|
385
|
+
end
|
386
|
+
|
348
387
|
context "all" do
|
349
388
|
should "work" do
|
350
389
|
@project1.statuses.all(:order => "position asc").should == [@brand_new, @complete]
|
@@ -327,7 +327,7 @@ class IdentityMapTest < Test::Unit::TestCase
|
|
327
327
|
|
328
328
|
should "return nil for document id not found in collection" do
|
329
329
|
assert_in_map(@person)
|
330
|
-
@person_class.find_by_id(
|
330
|
+
@person_class.find_by_id(BSON::ObjectID.new).should be_nil
|
331
331
|
end
|
332
332
|
end
|
333
333
|
|
@@ -342,13 +342,13 @@ class IdentityMapTest < Test::Unit::TestCase
|
|
342
342
|
@person_class.first(:_id => @person.id, :select => 'name').should == @person
|
343
343
|
@person_class.first(:_id => @person.id, 'fields' => ['name']).should == @person
|
344
344
|
@person_class.last(:_id => @person.id, :select => 'name', :order => 'name').should == @person
|
345
|
-
@person_class.find(@person.id
|
345
|
+
@person_class.fields(:name).find(@person.id).should == @person
|
346
346
|
@person_class.all(:_id => @person.id, :select => 'name').should == [@person]
|
347
347
|
assert_not_in_map(@person)
|
348
348
|
end
|
349
349
|
|
350
350
|
should "return nil if not found" do
|
351
|
-
@person_class.
|
351
|
+
@person_class.fields(:name).find(BSON::ObjectID.new).should be_nil
|
352
352
|
end
|
353
353
|
end
|
354
354
|
|
data/test/models.rb
CHANGED
@@ -143,6 +143,12 @@ end
|
|
143
143
|
class Status
|
144
144
|
include MongoMapper::Document
|
145
145
|
|
146
|
+
scope :complete, where(:name => 'Complete')
|
147
|
+
|
148
|
+
def self.by_position(position)
|
149
|
+
where(:position => position)
|
150
|
+
end
|
151
|
+
|
146
152
|
key :project_id, ObjectId
|
147
153
|
key :target_id, ObjectId
|
148
154
|
key :target_type, String
|
File without changes
|
data/test/test_helper.rb
CHANGED
@@ -1,19 +1,23 @@
|
|
1
|
-
require
|
2
|
-
|
3
|
-
|
4
|
-
gem 'jnunemaker-matchy', '0.4.0'
|
5
|
-
gem 'shoulda', '2.10.2'
|
6
|
-
gem '
|
7
|
-
gem '
|
8
|
-
gem 'mocha', '0.9.8'
|
1
|
+
require 'rubygems'
|
2
|
+
gem 'activesupport', ENV['ACTIVE_SUPPORT_VERSION']
|
3
|
+
gem 'json', '~> 1.2.3'
|
4
|
+
gem 'jnunemaker-matchy', '~> 0.4.0'
|
5
|
+
gem 'shoulda', '~> 2.10.2'
|
6
|
+
gem 'timecop', '~> 0.3.1'
|
7
|
+
gem 'mocha', '~> 0.9.8'
|
9
8
|
|
9
|
+
$:.unshift File.expand_path(File.dirname(__FILE__) + '/../lib')
|
10
|
+
require 'mongo_mapper'
|
11
|
+
require 'fileutils'
|
10
12
|
require 'ostruct'
|
13
|
+
require 'pp'
|
14
|
+
|
15
|
+
require 'active_support/version'
|
16
|
+
require 'json'
|
17
|
+
require 'matchy'
|
11
18
|
require 'shoulda'
|
12
19
|
require 'timecop'
|
13
|
-
require 'matchy'
|
14
20
|
require 'mocha'
|
15
|
-
require 'json'
|
16
|
-
require 'pp'
|
17
21
|
|
18
22
|
class Test::Unit::TestCase
|
19
23
|
def Doc(name=nil, &block)
|
@@ -96,3 +100,5 @@ logger = Logger.new(log_dir + '/test.log')
|
|
96
100
|
MongoMapper.connection = Mongo::Connection.new('127.0.0.1', 27017, :logger => logger)
|
97
101
|
MongoMapper.database = "mm-test-#{RUBY_VERSION.gsub('.', '-')}"
|
98
102
|
MongoMapper.database.collections.each { |c| c.drop_indexes }
|
103
|
+
|
104
|
+
puts "\n--- Active Support Version: #{ActiveSupport::VERSION::STRING} ---\n"
|
metadata
CHANGED
@@ -5,8 +5,8 @@ version: !ruby/object:Gem::Version
|
|
5
5
|
segments:
|
6
6
|
- 0
|
7
7
|
- 8
|
8
|
-
-
|
9
|
-
version: 0.8.
|
8
|
+
- 1
|
9
|
+
version: 0.8.1
|
10
10
|
platform: ruby
|
11
11
|
authors:
|
12
12
|
- John Nunemaker
|
@@ -14,7 +14,7 @@ autorequire:
|
|
14
14
|
bindir: bin
|
15
15
|
cert_chain: []
|
16
16
|
|
17
|
-
date: 2010-06-
|
17
|
+
date: 2010-06-18 00:00:00 -04:00
|
18
18
|
default_executable: mmconsole
|
19
19
|
dependencies:
|
20
20
|
- !ruby/object:Gem::Dependency
|
@@ -55,8 +55,8 @@ dependencies:
|
|
55
55
|
segments:
|
56
56
|
- 0
|
57
57
|
- 3
|
58
|
-
-
|
59
|
-
version: 0.3.
|
58
|
+
- 1
|
59
|
+
version: 0.3.1
|
60
60
|
type: :runtime
|
61
61
|
version_requirements: *id003
|
62
62
|
- !ruby/object:Gem::Dependency
|
@@ -64,7 +64,7 @@ dependencies:
|
|
64
64
|
prerelease: false
|
65
65
|
requirement: &id004 !ruby/object:Gem::Requirement
|
66
66
|
requirements:
|
67
|
-
- -
|
67
|
+
- - ~>
|
68
68
|
- !ruby/object:Gem::Version
|
69
69
|
segments:
|
70
70
|
- 1
|
@@ -78,7 +78,7 @@ dependencies:
|
|
78
78
|
prerelease: false
|
79
79
|
requirement: &id005 !ruby/object:Gem::Requirement
|
80
80
|
requirements:
|
81
|
-
- -
|
81
|
+
- - ~>
|
82
82
|
- !ruby/object:Gem::Version
|
83
83
|
segments:
|
84
84
|
- 0
|
@@ -92,7 +92,7 @@ dependencies:
|
|
92
92
|
prerelease: false
|
93
93
|
requirement: &id006 !ruby/object:Gem::Requirement
|
94
94
|
requirements:
|
95
|
-
- -
|
95
|
+
- - ~>
|
96
96
|
- !ruby/object:Gem::Version
|
97
97
|
segments:
|
98
98
|
- 2
|
@@ -106,7 +106,7 @@ dependencies:
|
|
106
106
|
prerelease: false
|
107
107
|
requirement: &id007 !ruby/object:Gem::Requirement
|
108
108
|
requirements:
|
109
|
-
- -
|
109
|
+
- - ~>
|
110
110
|
- !ruby/object:Gem::Version
|
111
111
|
segments:
|
112
112
|
- 0
|
@@ -120,7 +120,7 @@ dependencies:
|
|
120
120
|
prerelease: false
|
121
121
|
requirement: &id008 !ruby/object:Gem::Requirement
|
122
122
|
requirements:
|
123
|
-
- -
|
123
|
+
- - ~>
|
124
124
|
- !ruby/object:Gem::Version
|
125
125
|
segments:
|
126
126
|
- 0
|
@@ -199,6 +199,7 @@ files:
|
|
199
199
|
- lib/mongo_mapper/plugins/persistence.rb
|
200
200
|
- lib/mongo_mapper/plugins/protected.rb
|
201
201
|
- lib/mongo_mapper/plugins/querying/decorator.rb
|
202
|
+
- lib/mongo_mapper/plugins/querying/plucky_methods.rb
|
202
203
|
- lib/mongo_mapper/plugins/querying.rb
|
203
204
|
- lib/mongo_mapper/plugins/rails.rb
|
204
205
|
- lib/mongo_mapper/plugins/safe.rb
|
@@ -212,7 +213,7 @@ files:
|
|
212
213
|
- lib/mongo_mapper/support/descendant_appends.rb
|
213
214
|
- lib/mongo_mapper/version.rb
|
214
215
|
- lib/mongo_mapper.rb
|
215
|
-
- test/
|
216
|
+
- test/_NOTE_ON_TESTING
|
216
217
|
- test/functional/associations/test_belongs_to_polymorphic_proxy.rb
|
217
218
|
- test/functional/associations/test_belongs_to_proxy.rb
|
218
219
|
- test/functional/associations/test_in_array_proxy.rb
|
@@ -247,7 +248,7 @@ files:
|
|
247
248
|
- test/functional/test_userstamps.rb
|
248
249
|
- test/functional/test_validations.rb
|
249
250
|
- test/models.rb
|
250
|
-
- test/
|
251
|
+
- test/test_active_model_lint.rb
|
251
252
|
- test/test_helper.rb
|
252
253
|
- test/unit/associations/test_base.rb
|
253
254
|
- test/unit/associations/test_proxy.rb
|