mongo_doc 0.4.2 → 0.5.5

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.
Files changed (54) hide show
  1. data/.gitignore +1 -0
  2. data/HISTORY.md +8 -1
  3. data/README.textile +12 -24
  4. data/Rakefile +58 -11
  5. data/VERSION +1 -1
  6. data/features/embed_hash.feature +16 -0
  7. data/features/step_definitions/document_steps.rb +1 -1
  8. data/features/step_definitions/documents.rb +2 -0
  9. data/features/step_definitions/embed_hash_steps.rb +6 -0
  10. data/features/step_definitions/string_casting_steps.rb +2 -1
  11. data/features/support/support.rb +1 -0
  12. data/lib/mongo_doc/associations/collection_proxy.rb +29 -13
  13. data/lib/mongo_doc/associations/document_proxy.rb +14 -5
  14. data/lib/mongo_doc/associations/hash_proxy.rb +20 -16
  15. data/lib/mongo_doc/associations/proxy_base.rb +21 -26
  16. data/lib/mongo_doc/associations.rb +15 -6
  17. data/lib/mongo_doc/attributes.rb +2 -20
  18. data/lib/mongo_doc/collection.rb +1 -1
  19. data/lib/mongo_doc/connection.rb +1 -1
  20. data/lib/mongo_doc/contexts/ids.rb +3 -3
  21. data/lib/mongo_doc/contexts/mongo.rb +1 -1
  22. data/lib/mongo_doc/document.rb +30 -13
  23. data/lib/mongo_doc/ext/binary.rb +2 -2
  24. data/lib/mongo_doc/ext/dbref.rb +2 -2
  25. data/lib/mongo_doc/ext/min_max_keys.rb +13 -0
  26. data/lib/mongo_doc/ext/object.rb +4 -2
  27. data/lib/mongo_doc/ext/object_id.rb +2 -2
  28. data/lib/mongo_doc/ext.rb +1 -0
  29. data/lib/mongo_doc/finders.rb +2 -2
  30. data/lib/mongo_doc/root.rb +26 -0
  31. data/lib/mongo_doc/validations.rb +16 -0
  32. data/lib/mongo_doc.rb +2 -1
  33. data/lib/mongoid/criterion/optional.rb +1 -1
  34. data/mongo_doc.gemspec +29 -17
  35. data/perf/mongo_doc_object.rb +78 -0
  36. data/perf/mongo_document.rb +78 -0
  37. data/perf/ruby_driver.rb +43 -0
  38. data/spec/associations/collection_proxy_spec.rb +29 -6
  39. data/spec/associations/document_proxy_spec.rb +22 -19
  40. data/spec/associations/hash_proxy_spec.rb +17 -4
  41. data/spec/associations/proxy_base_spec.rb +92 -0
  42. data/spec/associations_spec.rb +4 -16
  43. data/spec/bson_spec.rb +1 -1
  44. data/spec/connection_spec.rb +2 -2
  45. data/spec/contexts/ids_spec.rb +2 -2
  46. data/spec/document_spec.rb +31 -22
  47. data/spec/ext_spec.rb +8 -0
  48. data/spec/root_spec.rb +41 -0
  49. data/spec/validations_spec.rb +30 -0
  50. metadata +46 -23
  51. data/lib/mongo_doc/query.rb +0 -7
  52. data/perf/mongo_doc_runner.rb +0 -90
  53. data/perf/ruby_driver_runner.rb +0 -64
  54. data/spec/query_spec.rb +0 -12
@@ -219,7 +219,7 @@ module MongoDoc
219
219
  collection.find_one(selector, options)
220
220
  end
221
221
 
222
- alias :first :one
222
+ alias first one
223
223
 
224
224
  SUM_REDUCE = "function(obj, prev) { if (prev.sum == 'start') { prev.sum = 0; } prev.sum += obj.[field]; }"
225
225
  # Sum the context.
@@ -1,12 +1,12 @@
1
1
  require 'mongo_doc/bson'
2
- require 'mongo_doc/query'
3
2
  require 'mongo_doc/attributes'
3
+ require 'mongo_doc/root'
4
4
  require 'mongo_doc/associations'
5
5
  require 'mongo_doc/criteria'
6
6
  require 'mongo_doc/finders'
7
7
  require 'mongo_doc/index'
8
8
  require 'mongo_doc/scope'
9
- require 'mongo_doc/validations/macros'
9
+ require 'mongo_doc/validations'
10
10
 
11
11
  module MongoDoc
12
12
  class UnsupportedOperation < RuntimeError; end
@@ -18,19 +18,23 @@ module MongoDoc
18
18
  def self.included(klass)
19
19
  klass.class_eval do
20
20
  include Attributes
21
+ include Root
21
22
  extend Associations
22
23
  extend ClassMethods
23
24
  extend Criteria
24
25
  extend Finders
25
26
  extend Index
26
27
  extend Scope
27
- include ::Validatable
28
- extend Validations::Macros
28
+ include Validations
29
29
 
30
- alias :id :_id
30
+ alias id _id
31
31
  end
32
32
  end
33
33
 
34
+ def _collection
35
+ _root and _root._collection or self.class.collection
36
+ end
37
+
34
38
  def initialize(attrs = {})
35
39
  self.attributes = attrs
36
40
  end
@@ -96,7 +100,7 @@ module MongoDoc
96
100
 
97
101
  module ClassMethods
98
102
  def bson_create(bson_hash, options = {})
99
- new.tap do |obj|
103
+ allocate.tap do |obj|
100
104
  bson_hash.each do |name, value|
101
105
  obj.send("#{name}=", MongoDoc::BSON.decode(value, options))
102
106
  end
@@ -126,17 +130,13 @@ module MongoDoc
126
130
 
127
131
  protected
128
132
 
129
- def _collection
130
- self.class.collection
131
- end
132
-
133
133
  def _remove
134
134
  _collection.remove({'_id' => _id})
135
135
  end
136
136
 
137
137
  def _update(selector, data, safe)
138
- return _root.send(:_update, _path_to_root(self, {'_id' => _id}, true), _path_to_root(self, data), safe) if _root
139
- _collection.update({'_id' => _id}.merge(selector), MongoDoc::Query.set_modifier(data), :safe => safe)
138
+ return _root.send(:_update, {_selector_path + '._id' => _id}, hash_with_modifier_path_keys(data), safe) if _root
139
+ _collection.update({'_id' => _id}.merge(selector), {'$set' => data}, :safe => safe)
140
140
  end
141
141
 
142
142
  def _save(safe)
@@ -149,8 +149,25 @@ module MongoDoc
149
149
  raise e
150
150
  end
151
151
 
152
+ def hash_with_modifier_path_keys(hash)
153
+ hash.stringify_keys!
154
+ {}.tap do |dup|
155
+ hash.each do |key, value|
156
+ dup[_modifier_path + '.' + key] = value
157
+ end
158
+ end
159
+ end
160
+
161
+ def path(parent_path, child_path)
162
+ if parent_path.blank?
163
+ child_path
164
+ else
165
+ parent_path + '.' + child_path
166
+ end
167
+ end
168
+
152
169
  def before_save_callback(root)
153
- self._id = Mongo::ObjectID.new if new_record?
170
+ self._id = ::BSON::ObjectID.new if new_record?
154
171
  end
155
172
 
156
173
  def save_failed_callback(root)
@@ -1,7 +1,7 @@
1
- module Mongo
1
+ module BSON
2
2
  class Binary
3
3
  def to_bson(*args)
4
4
  self
5
5
  end
6
6
  end
7
- end
7
+ end
@@ -1,7 +1,7 @@
1
- module Mongo
1
+ module BSON
2
2
  class DBRef
3
3
  def to_bson(*args)
4
4
  self
5
5
  end
6
6
  end
7
- end
7
+ end
@@ -0,0 +1,13 @@
1
+ module BSON
2
+ class MaxKey
3
+ def to_bson(*args)
4
+ self
5
+ end
6
+ end
7
+
8
+ class MinKey
9
+ def to_bson(*args)
10
+ self
11
+ end
12
+ end
13
+ end
@@ -1,4 +1,6 @@
1
1
  class Object
2
+ define_method :singleton_class, instance_method(:metaclass) unless respond_to?(:singleton_class)
3
+
2
4
  def to_bson(*args)
3
5
  {MongoDoc::BSON::CLASS_KEY => self.class.name}.tap do |bson_hash|
4
6
  instance_variables.each do |name|
@@ -6,9 +8,9 @@ class Object
6
8
  end
7
9
  end
8
10
  end
9
-
11
+
10
12
  def self.bson_create(bson_hash, options = {})
11
- new.tap do |obj|
13
+ allocate.tap do |obj|
12
14
  bson_hash.each do |name, value|
13
15
  obj.instance_variable_set("@#{name}", MongoDoc::BSON.decode(value, options))
14
16
  end
@@ -1,7 +1,7 @@
1
- module Mongo
1
+ module BSON
2
2
  class ObjectID
3
3
  def to_bson(*args)
4
4
  self
5
5
  end
6
6
  end
7
- end
7
+ end
data/lib/mongo_doc/ext.rb CHANGED
@@ -5,6 +5,7 @@ require 'mongo_doc/ext/date'
5
5
  require 'mongo_doc/ext/date_time'
6
6
  require 'mongo_doc/ext/dbref'
7
7
  require 'mongo_doc/ext/hash'
8
+ require 'mongo_doc/ext/min_max_keys'
8
9
  require 'mongo_doc/ext/nil_class'
9
10
  require 'mongo_doc/ext/numeric'
10
11
  require 'mongo_doc/ext/object'
@@ -6,7 +6,7 @@ module MongoDoc
6
6
  base.extend(Criteria) unless base === Criteria
7
7
  end
8
8
 
9
- # Find a +Document+ based on id (+String+ or +Mongo::ObjectID+)
9
+ # Find a +Document+ based on id (+String+ or +BSON::ObjectID+)
10
10
  #
11
11
  # <tt>Person.find('1')</tt>
12
12
  # <tt>Person.find(obj_id_1, obj_id_2)</tt>
@@ -21,7 +21,7 @@ module MongoDoc
21
21
  criteria
22
22
  end
23
23
 
24
- # Find a +Document+ based on id (+String+ or +Mongo::ObjectID+)
24
+ # Find a +Document+ based on id (+String+ or +BSON::ObjectID+)
25
25
  # or conditions
26
26
  #
27
27
  # <tt>Person.find_one('1')</tt>
@@ -0,0 +1,26 @@
1
+ module MongoDoc
2
+ module Root
3
+
4
+ attr_reader :_root
5
+
6
+ %w(_modifier_path _selector_path).each do |getter|
7
+ module_eval(<<-RUBY, __FILE__, __LINE__)
8
+ def #{getter}
9
+ @#{getter} ||= ''
10
+ end
11
+ RUBY
12
+ end
13
+
14
+ %w(_modifier_path _root _selector_path).each do |setter|
15
+ module_eval(<<-RUBY, __FILE__, __LINE__)
16
+ def #{setter}=(value)
17
+ @#{setter} = value
18
+ _associations.each do|a|
19
+ association = send(a)
20
+ association.#{setter} = value if association
21
+ end
22
+ end
23
+ RUBY
24
+ end
25
+ end
26
+ end
@@ -0,0 +1,16 @@
1
+ module MongoDoc
2
+ module Validations
3
+ def self.included(klass)
4
+ klass.class_eval do
5
+ if MongoDoc.const_defined?('ActiveModel')
6
+ include MongoDoc::ActiveModel::ActiveModelCompliance
7
+ else
8
+ require 'mongo_doc/validations/macros'
9
+
10
+ include ::Validatable
11
+ extend Macros
12
+ end
13
+ end
14
+ end
15
+ end
16
+ end
data/lib/mongo_doc.rb CHANGED
@@ -1,10 +1,11 @@
1
1
  require 'mongo'
2
2
  require 'active_support'
3
+ require 'active_support/core_ext'
3
4
  require 'validatable'
4
5
  require 'will_paginate/collection'
5
6
 
6
7
  module MongoDoc
7
- VERSION = '0.4.2'
8
+ VERSION = '0.5.4'
8
9
  end
9
10
 
10
11
  require 'mongo_doc/connection'
@@ -62,7 +62,7 @@ module Mongoid #:nodoc:
62
62
  #
63
63
  # Options:
64
64
  #
65
- # object_id: A +String+ representation of a <tt>Mongo::ObjectID</tt>
65
+ # object_id: A +String+ representation of a <tt>BSON::ObjectID</tt>
66
66
  #
67
67
  # Example:
68
68
  #
data/mongo_doc.gemspec CHANGED
@@ -5,11 +5,11 @@
5
5
 
6
6
  Gem::Specification.new do |s|
7
7
  s.name = %q{mongo_doc}
8
- s.version = "0.4.2"
8
+ s.version = "0.5.5"
9
9
 
10
10
  s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
11
  s.authors = ["Les Hill"]
12
- s.date = %q{2010-03-23}
12
+ s.date = %q{2010-04-08}
13
13
  s.description = %q{ODM for MongoDB}
14
14
  s.email = %q{leshill@gmail.com}
15
15
  s.extra_rdoc_files = [
@@ -30,6 +30,7 @@ Gem::Specification.new do |s|
30
30
  "examples/simple_document.rb",
31
31
  "examples/simple_object.rb",
32
32
  "features/collections.feature",
33
+ "features/embed_hash.feature",
33
34
  "features/finders.feature",
34
35
  "features/indexes.feature",
35
36
  "features/mongodb.yml",
@@ -42,6 +43,7 @@ Gem::Specification.new do |s|
42
43
  "features/step_definitions/collection_steps.rb",
43
44
  "features/step_definitions/document_steps.rb",
44
45
  "features/step_definitions/documents.rb",
46
+ "features/step_definitions/embed_hash_steps.rb",
45
47
  "features/step_definitions/finder_steps.rb",
46
48
  "features/step_definitions/index_steps.rb",
47
49
  "features/step_definitions/json_steps.rb",
@@ -80,6 +82,7 @@ Gem::Specification.new do |s|
80
82
  "lib/mongo_doc/ext/date_time.rb",
81
83
  "lib/mongo_doc/ext/dbref.rb",
82
84
  "lib/mongo_doc/ext/hash.rb",
85
+ "lib/mongo_doc/ext/min_max_keys.rb",
83
86
  "lib/mongo_doc/ext/nil_class.rb",
84
87
  "lib/mongo_doc/ext/numeric.rb",
85
88
  "lib/mongo_doc/ext/object.rb",
@@ -91,8 +94,9 @@ Gem::Specification.new do |s|
91
94
  "lib/mongo_doc/finders.rb",
92
95
  "lib/mongo_doc/index.rb",
93
96
  "lib/mongo_doc/matchers.rb",
94
- "lib/mongo_doc/query.rb",
97
+ "lib/mongo_doc/root.rb",
95
98
  "lib/mongo_doc/scope.rb",
99
+ "lib/mongo_doc/validations.rb",
96
100
  "lib/mongo_doc/validations/macros.rb",
97
101
  "lib/mongo_doc/validations/validates_embedded.rb",
98
102
  "lib/mongoid/contexts/enumerable.rb",
@@ -118,13 +122,15 @@ Gem::Specification.new do |s|
118
122
  "mongo_doc.gemspec",
119
123
  "mongod.example.yml",
120
124
  "mongodb.example.yml",
121
- "perf/mongo_doc_runner.rb",
122
- "perf/ruby_driver_runner.rb",
125
+ "perf/mongo_doc_object.rb",
126
+ "perf/mongo_document.rb",
127
+ "perf/ruby_driver.rb",
123
128
  "script/console",
124
129
  "spec/array_including_argument_matcher.rb",
125
130
  "spec/associations/collection_proxy_spec.rb",
126
131
  "spec/associations/document_proxy_spec.rb",
127
132
  "spec/associations/hash_proxy_spec.rb",
133
+ "spec/associations/proxy_base_spec.rb",
128
134
  "spec/associations_spec.rb",
129
135
  "spec/attributes_accessor_spec.rb",
130
136
  "spec/attributes_spec.rb",
@@ -148,10 +154,11 @@ Gem::Specification.new do |s|
148
154
  "spec/mongodb.yml",
149
155
  "spec/mongodb_pairs.yml",
150
156
  "spec/new_record_spec.rb",
151
- "spec/query_spec.rb",
157
+ "spec/root_spec.rb",
152
158
  "spec/scope_spec.rb",
153
159
  "spec/spec.opts",
154
- "spec/spec_helper.rb"
160
+ "spec/spec_helper.rb",
161
+ "spec/validations_spec.rb"
155
162
  ]
156
163
  s.homepage = %q{http://github.com/leshill/mongodoc}
157
164
  s.rdoc_options = ["--charset=UTF-8"]
@@ -163,6 +170,7 @@ Gem::Specification.new do |s|
163
170
  "spec/associations/collection_proxy_spec.rb",
164
171
  "spec/associations/document_proxy_spec.rb",
165
172
  "spec/associations/hash_proxy_spec.rb",
173
+ "spec/associations/proxy_base_spec.rb",
166
174
  "spec/associations_spec.rb",
167
175
  "spec/attributes_accessor_spec.rb",
168
176
  "spec/attributes_spec.rb",
@@ -184,9 +192,10 @@ Gem::Specification.new do |s|
184
192
  "spec/index_spec.rb",
185
193
  "spec/matchers_spec.rb",
186
194
  "spec/new_record_spec.rb",
187
- "spec/query_spec.rb",
195
+ "spec/root_spec.rb",
188
196
  "spec/scope_spec.rb",
189
197
  "spec/spec_helper.rb",
198
+ "spec/validations_spec.rb",
190
199
  "examples/simple_document.rb",
191
200
  "examples/simple_object.rb"
192
201
  ]
@@ -197,29 +206,32 @@ Gem::Specification.new do |s|
197
206
 
198
207
  if Gem::Version.new(Gem::RubyGemsVersion) >= Gem::Version.new('1.2.0') then
199
208
  s.add_runtime_dependency(%q<activesupport>, [">= 2.3.4"])
200
- s.add_runtime_dependency(%q<mongo>, ["= 0.19.1"])
201
- s.add_runtime_dependency(%q<mongo_ext>, ["= 0.19.1"])
209
+ s.add_runtime_dependency(%q<mongo>, ["= 0.20.1"])
210
+ s.add_runtime_dependency(%q<bson>, ["= 0.20.1"])
211
+ s.add_runtime_dependency(%q<bson_ext>, ["= 0.20.1"])
202
212
  s.add_runtime_dependency(%q<durran-validatable>, ["= 2.0.1"])
203
213
  s.add_runtime_dependency(%q<leshill-will_paginate>, ["= 2.3.11"])
204
214
  s.add_development_dependency(%q<rspec>, ["= 1.3.0"])
205
- s.add_development_dependency(%q<cucumber>, ["= 0.6.2"])
215
+ s.add_development_dependency(%q<cucumber>, [">= 0.6.2"])
206
216
  else
207
217
  s.add_dependency(%q<activesupport>, [">= 2.3.4"])
208
- s.add_dependency(%q<mongo>, ["= 0.19.1"])
209
- s.add_dependency(%q<mongo_ext>, ["= 0.19.1"])
218
+ s.add_dependency(%q<mongo>, ["= 0.20.1"])
219
+ s.add_dependency(%q<bson>, ["= 0.20.1"])
220
+ s.add_dependency(%q<bson_ext>, ["= 0.20.1"])
210
221
  s.add_dependency(%q<durran-validatable>, ["= 2.0.1"])
211
222
  s.add_dependency(%q<leshill-will_paginate>, ["= 2.3.11"])
212
223
  s.add_dependency(%q<rspec>, ["= 1.3.0"])
213
- s.add_dependency(%q<cucumber>, ["= 0.6.2"])
224
+ s.add_dependency(%q<cucumber>, [">= 0.6.2"])
214
225
  end
215
226
  else
216
227
  s.add_dependency(%q<activesupport>, [">= 2.3.4"])
217
- s.add_dependency(%q<mongo>, ["= 0.19.1"])
218
- s.add_dependency(%q<mongo_ext>, ["= 0.19.1"])
228
+ s.add_dependency(%q<mongo>, ["= 0.20.1"])
229
+ s.add_dependency(%q<bson>, ["= 0.20.1"])
230
+ s.add_dependency(%q<bson_ext>, ["= 0.20.1"])
219
231
  s.add_dependency(%q<durran-validatable>, ["= 2.0.1"])
220
232
  s.add_dependency(%q<leshill-will_paginate>, ["= 2.3.11"])
221
233
  s.add_dependency(%q<rspec>, ["= 1.3.0"])
222
- s.add_dependency(%q<cucumber>, ["= 0.6.2"])
234
+ s.add_dependency(%q<cucumber>, [">= 0.6.2"])
223
235
  end
224
236
  end
225
237
 
@@ -0,0 +1,78 @@
1
+ require "rubygems"
2
+ require "ruby-prof"
3
+ require "mongo_doc"
4
+
5
+ class Person
6
+ attr_accessor :address, :birth_date, :name, :phones
7
+ end
8
+
9
+ class Name
10
+ attr_accessor :family, :given, :middle
11
+ end
12
+
13
+ class Address
14
+ attr_accessor :city, :post_code, :state, :street, :type
15
+ end
16
+
17
+ class Phone
18
+ attr_accessor :country_code, :number, :type
19
+ end
20
+
21
+ class MongoDocObject
22
+ attr_accessor :collection
23
+ attr_accessor :objects
24
+ attr_accessor :ids
25
+
26
+ def initialize
27
+ MongoDoc::Connection.name = 'mongo_doc_object_test'
28
+ self.collection = MongoDoc::Collection.new 'people'
29
+ collection.drop
30
+ end
31
+
32
+ def generate(count)
33
+ self.objects = []
34
+ self.ids = []
35
+ count.times do |i|
36
+ person = Person.new
37
+ person.birth_date = Date.new(1970, 1, 1)
38
+ person.phones = []
39
+
40
+ name = Name.new
41
+ name.given = "James #{i}"
42
+ name.family = "Kirk"
43
+ name.middle = "Tiberius"
44
+
45
+ address = Address.new
46
+ address.street = "1 Starfleet Command Way"
47
+ address.city = "San Francisco"
48
+ address.state = "CA"
49
+ address.post_code = "94133"
50
+ address.type = "Work"
51
+
52
+ phone = Phone.new
53
+ phone.country_code = 1
54
+ phone.number = "415-555-1212"
55
+ phone.type = "Mobile"
56
+
57
+ person.name = name
58
+ person.address = address
59
+ person.phones << phone
60
+
61
+ objects << person
62
+ end
63
+ end
64
+
65
+ def writes(count)
66
+ count.times do |i|
67
+ ids[i] = collection.save(objects[i])
68
+ end
69
+ end
70
+
71
+ def reads(count)
72
+ count.times do |i|
73
+ obj = collection.find_one(ids[i])
74
+ raise 'Not found' unless obj.name.given == objects[i].name.given
75
+ end
76
+ end
77
+
78
+ end
@@ -0,0 +1,78 @@
1
+ require "benchmark"
2
+ require "ruby-prof"
3
+ require "mongo_doc"
4
+
5
+ class Person
6
+ include MongoDoc::Document
7
+
8
+ attr_accessor :birth_date, :type => Date
9
+
10
+ embed :name
11
+ embed :address
12
+ embed_many :phones
13
+ end
14
+
15
+ class Name
16
+ include MongoDoc::Document
17
+
18
+ attr_accessor :given
19
+ attr_accessor :family
20
+ attr_accessor :middle
21
+ end
22
+
23
+ class Address
24
+ include MongoDoc::Document
25
+
26
+ attr_accessor :street
27
+ attr_accessor :city
28
+ attr_accessor :state
29
+ attr_accessor :post_code
30
+ attr_accessor :type
31
+ end
32
+
33
+ class Phone
34
+ include MongoDoc::Document
35
+
36
+ attr_accessor :country_code
37
+ attr_accessor :number
38
+ attr_accessor :type
39
+ end
40
+
41
+ class MongoDocument
42
+ attr_accessor :collection
43
+ attr_accessor :documents
44
+
45
+ def initialize
46
+ MongoDoc::Connection.name = 'mongo_doc_object_test'
47
+ self.collection = MongoDoc::Collection.new 'people'
48
+ collection.drop
49
+ end
50
+
51
+ def generate(count)
52
+ self.documents = []
53
+ count.times do |i|
54
+ person = Person.new(:birth_date => Date.new(1970, 1, 1))
55
+ name = Name.new(:given => "James #{i}", :family => "Kirk", :middle => "Tiberius")
56
+ address = Address.new(:street => "1 Starfleet Command Way", :city => "San Francisco", :state => "CA", :post_code => "94133", :type => "Work")
57
+ phone = Phone.new(:country_code => 1, :number => "415-555-1212", :type => "Mobile")
58
+ person.name = name
59
+ person.address = address
60
+ person.phones << phone
61
+
62
+ documents << person
63
+ end
64
+ end
65
+
66
+ def writes(count)
67
+ count.times do |i|
68
+ documents[i].save
69
+ end
70
+ end
71
+
72
+ def reads(count)
73
+ count.times do |i|
74
+ doc = collection.find_one(documents[i]._id)
75
+ raise 'Not found' unless doc.name.given == documents[i].name.given
76
+ end
77
+ end
78
+ end
@@ -0,0 +1,43 @@
1
+ require "rubygems"
2
+ require "ruby-prof"
3
+ require "mongo_doc"
4
+
5
+ class RubyDriver
6
+ attr_accessor :collection
7
+ attr_accessor :objects
8
+ attr_accessor :ids
9
+
10
+ def initialize
11
+ MongoDoc::Connection.name = 'ruby_driver_test'
12
+ self.collection = MongoDoc::Connection.database.collection 'people'
13
+ collection.drop
14
+ end
15
+
16
+ def generate(count)
17
+ self.objects = []
18
+ self.ids = []
19
+ count.times do |i|
20
+ person = {:birth_date => Date.new(1970, 1, 1).to_bson, :phones => []}
21
+ name = {:given => "James #{i}", :family => "Kirk", :middle => "Tiberius"}
22
+ address = {:street => "1 Starfleet Command Way", :city => "San Francisco", :state => "CA", :post_code => "94133", :type => "Work"}
23
+ phone = {:country_code => 1, :number => "415-555-1212", :type => "Mobile"}
24
+ person[:name] = name
25
+ person[:address] = address
26
+ person[:phones] << phone
27
+ objects << person
28
+ end
29
+ end
30
+
31
+ def writes(count)
32
+ count.times do |i|
33
+ ids[i] = collection.save(objects[i])
34
+ end
35
+ end
36
+
37
+ def reads(count)
38
+ count.times do |i|
39
+ obj = collection.find_one(ids[i])
40
+ raise 'Not found' unless obj and obj['name']['given'] == objects[i][:name][:given]
41
+ end
42
+ end
43
+ end
@@ -7,17 +7,40 @@ describe MongoDoc::Associations::CollectionProxy do
7
7
  attr_accessor :name
8
8
  end
9
9
 
10
+ let(:name) { 'embed_many_name' }
10
11
  let(:root) { CollectionProxyTest.new }
11
- let(:proxy) { MongoDoc::Associations::CollectionProxy.new(:assoc_name => 'embed_many_name', :assoc_class => CollectionProxyTest, :root => root, :parent => root) }
12
+ let(:proxy) { MongoDoc::Associations::CollectionProxy.new(:assoc_name => name, :assoc_class => CollectionProxyTest, :root => root, :parent => root) }
12
13
  let(:item) { CollectionProxyTest.new }
13
14
 
14
- describe "#_path_to_root" do
15
- it "inserts the association name and '$' when not a selector" do
16
- proxy._path_to_root(CollectionProxyTest.new, 'name' => 'value').should == {"embed_many_name.$.name" => 'value'}
15
+ describe "#_modifier_path" do
16
+ it "cascades to child documents with our assoc name and $" do
17
+ document = stub
18
+ proxy.stub(:collection => [document])
19
+ document.should_receive(:_modifier_path=).with("new.path.#{name}.$")
20
+ MongoDoc::Associations::ProxyBase.stub(:is_document?).and_return(true)
21
+ proxy._modifier_path = 'new.path'
22
+ end
23
+ end
24
+
25
+ describe "#_selector_path=" do
26
+ it "cascades to child documents" do
27
+ document = stub
28
+ proxy.stub(:collection => [document])
29
+ document.should_receive("_selector_path=").with("new.path.#{name}")
30
+ MongoDoc::Associations::ProxyBase.stub(:is_document?).and_return(true)
31
+ proxy._selector_path = 'new.path'
32
+ end
33
+ end
34
+
35
+ context "#attach_document" do
36
+ it "sets the Document's modifier path to our modifier path" do
37
+ item.should_receive(:_modifier_path=).with('embed_many_name.$')
38
+ proxy.send(:attach_document, item)
17
39
  end
18
40
 
19
- it "inserts the association name when a selector" do
20
- proxy._path_to_root(CollectionProxyTest.new, {'name' => 'value'}, true).should == {"embed_many_name.name" => 'value'}
41
+ it "sets the Document's selector path to our selector path" do
42
+ item.should_receive(:_selector_path=).with('embed_many_name')
43
+ proxy.send(:attach_document, item)
21
44
  end
22
45
  end
23
46