mongo_doc 0.3.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (122) hide show
  1. data/.document +5 -0
  2. data/.gitignore +7 -0
  3. data/LICENSE +20 -0
  4. data/README.textile +174 -0
  5. data/Rakefile +135 -0
  6. data/TODO +31 -0
  7. data/VERSION +1 -0
  8. data/data/.gitignore +2 -0
  9. data/examples/simple_document.rb +35 -0
  10. data/examples/simple_object.rb +30 -0
  11. data/features/finders.feature +76 -0
  12. data/features/mongodb.yml +7 -0
  13. data/features/mongodoc_base.feature +128 -0
  14. data/features/new_record.feature +36 -0
  15. data/features/partial_updates.feature +105 -0
  16. data/features/removing_documents.feature +68 -0
  17. data/features/saving_an_object.feature +15 -0
  18. data/features/scopes.feature +66 -0
  19. data/features/step_definitions/collection_steps.rb +14 -0
  20. data/features/step_definitions/document_steps.rb +149 -0
  21. data/features/step_definitions/documents.rb +30 -0
  22. data/features/step_definitions/finder_steps.rb +15 -0
  23. data/features/step_definitions/json_steps.rb +9 -0
  24. data/features/step_definitions/object_steps.rb +50 -0
  25. data/features/step_definitions/objects.rb +24 -0
  26. data/features/step_definitions/partial_update_steps.rb +32 -0
  27. data/features/step_definitions/query_steps.rb +54 -0
  28. data/features/step_definitions/removing_documents_steps.rb +14 -0
  29. data/features/step_definitions/scope_steps.rb +18 -0
  30. data/features/step_definitions/util_steps.rb +7 -0
  31. data/features/support/support.rb +10 -0
  32. data/features/using_criteria.feature +128 -0
  33. data/lib/mongo_doc/associations/collection_proxy.rb +105 -0
  34. data/lib/mongo_doc/associations/document_proxy.rb +56 -0
  35. data/lib/mongo_doc/associations/hash_proxy.rb +98 -0
  36. data/lib/mongo_doc/associations/proxy_base.rb +53 -0
  37. data/lib/mongo_doc/attributes.rb +140 -0
  38. data/lib/mongo_doc/bson.rb +45 -0
  39. data/lib/mongo_doc/collection.rb +55 -0
  40. data/lib/mongo_doc/connection.rb +88 -0
  41. data/lib/mongo_doc/contexts/enumerable.rb +128 -0
  42. data/lib/mongo_doc/contexts/ids.rb +41 -0
  43. data/lib/mongo_doc/contexts/mongo.rb +232 -0
  44. data/lib/mongo_doc/contexts.rb +25 -0
  45. data/lib/mongo_doc/criteria.rb +38 -0
  46. data/lib/mongo_doc/cursor.rb +32 -0
  47. data/lib/mongo_doc/document.rb +216 -0
  48. data/lib/mongo_doc/ext/array.rb +5 -0
  49. data/lib/mongo_doc/ext/binary.rb +7 -0
  50. data/lib/mongo_doc/ext/boolean_class.rb +11 -0
  51. data/lib/mongo_doc/ext/date.rb +16 -0
  52. data/lib/mongo_doc/ext/date_time.rb +13 -0
  53. data/lib/mongo_doc/ext/dbref.rb +7 -0
  54. data/lib/mongo_doc/ext/hash.rb +7 -0
  55. data/lib/mongo_doc/ext/nil_class.rb +5 -0
  56. data/lib/mongo_doc/ext/numeric.rb +17 -0
  57. data/lib/mongo_doc/ext/object.rb +17 -0
  58. data/lib/mongo_doc/ext/object_id.rb +7 -0
  59. data/lib/mongo_doc/ext/regexp.rb +5 -0
  60. data/lib/mongo_doc/ext/string.rb +5 -0
  61. data/lib/mongo_doc/ext/symbol.rb +5 -0
  62. data/lib/mongo_doc/ext/time.rb +5 -0
  63. data/lib/mongo_doc/finders.rb +49 -0
  64. data/lib/mongo_doc/matchers.rb +35 -0
  65. data/lib/mongo_doc/query.rb +7 -0
  66. data/lib/mongo_doc/scope.rb +64 -0
  67. data/lib/mongo_doc/validations/macros.rb +11 -0
  68. data/lib/mongo_doc/validations/validates_embedded.rb +13 -0
  69. data/lib/mongo_doc.rb +19 -0
  70. data/lib/mongoid/contexts/paging.rb +42 -0
  71. data/lib/mongoid/criteria.rb +247 -0
  72. data/lib/mongoid/criterion/complex.rb +21 -0
  73. data/lib/mongoid/criterion/exclusion.rb +65 -0
  74. data/lib/mongoid/criterion/inclusion.rb +92 -0
  75. data/lib/mongoid/criterion/optional.rb +136 -0
  76. data/lib/mongoid/extensions/hash/criteria_helpers.rb +20 -0
  77. data/lib/mongoid/extensions/symbol/inflections.rb +36 -0
  78. data/lib/mongoid/matchers/all.rb +11 -0
  79. data/lib/mongoid/matchers/default.rb +26 -0
  80. data/lib/mongoid/matchers/exists.rb +13 -0
  81. data/lib/mongoid/matchers/gt.rb +11 -0
  82. data/lib/mongoid/matchers/gte.rb +11 -0
  83. data/lib/mongoid/matchers/in.rb +11 -0
  84. data/lib/mongoid/matchers/lt.rb +11 -0
  85. data/lib/mongoid/matchers/lte.rb +11 -0
  86. data/lib/mongoid/matchers/ne.rb +11 -0
  87. data/lib/mongoid/matchers/nin.rb +11 -0
  88. data/lib/mongoid/matchers/size.rb +11 -0
  89. data/mongo_doc.gemspec +205 -0
  90. data/mongod.example.yml +2 -0
  91. data/mongodb.example.yml +14 -0
  92. data/perf/mongo_doc_runner.rb +90 -0
  93. data/perf/ruby_driver_runner.rb +64 -0
  94. data/script/console +8 -0
  95. data/spec/associations/collection_proxy_spec.rb +200 -0
  96. data/spec/associations/document_proxy_spec.rb +42 -0
  97. data/spec/associations/hash_proxy_spec.rb +163 -0
  98. data/spec/attributes_spec.rb +273 -0
  99. data/spec/bson_matchers.rb +54 -0
  100. data/spec/bson_spec.rb +196 -0
  101. data/spec/collection_spec.rb +161 -0
  102. data/spec/connection_spec.rb +147 -0
  103. data/spec/contexts/enumerable_spec.rb +274 -0
  104. data/spec/contexts/ids_spec.rb +49 -0
  105. data/spec/contexts/mongo_spec.rb +198 -0
  106. data/spec/contexts_spec.rb +28 -0
  107. data/spec/criteria_spec.rb +33 -0
  108. data/spec/cursor_spec.rb +91 -0
  109. data/spec/document_ext.rb +9 -0
  110. data/spec/document_spec.rb +664 -0
  111. data/spec/embedded_save_spec.rb +109 -0
  112. data/spec/finders_spec.rb +73 -0
  113. data/spec/hash_matchers.rb +27 -0
  114. data/spec/matchers_spec.rb +342 -0
  115. data/spec/mongodb.yml +6 -0
  116. data/spec/mongodb_pairs.yml +8 -0
  117. data/spec/new_record_spec.rb +128 -0
  118. data/spec/query_spec.rb +12 -0
  119. data/spec/scope_spec.rb +79 -0
  120. data/spec/spec.opts +2 -0
  121. data/spec/spec_helper.rb +13 -0
  122. metadata +290 -0
@@ -0,0 +1,11 @@
1
+ # encoding: utf-8
2
+ module Mongoid #:nodoc:
3
+ module Matchers #:nodoc:
4
+ class In < Default
5
+ # Return true if the attribute is in the values.
6
+ def matches?(value)
7
+ value.values.first.include?(@attribute)
8
+ end
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,11 @@
1
+ # encoding: utf-8
2
+ module Mongoid #:nodoc:
3
+ module Matchers #:nodoc:
4
+ class Lt < Default
5
+ # Return true if the attribute is less than the value.
6
+ def matches?(value)
7
+ determine(value, :<)
8
+ end
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,11 @@
1
+ # encoding: utf-8
2
+ module Mongoid #:nodoc:
3
+ module Matchers #:nodoc:
4
+ class Lte < Default
5
+ # Return true if the attribute is less than or equal to the value.
6
+ def matches?(value)
7
+ determine(value, :<=)
8
+ end
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,11 @@
1
+ # encoding: utf-8
2
+ module Mongoid #:nodoc:
3
+ module Matchers #:nodoc:
4
+ class Ne < Default
5
+ # Return true if the attribute and first value are not equal.
6
+ def matches?(value)
7
+ @attribute != value.values.first
8
+ end
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,11 @@
1
+ # encoding: utf-8
2
+ module Mongoid #:nodoc:
3
+ module Matchers #:nodoc:
4
+ class Nin < Default
5
+ # Return true if the attribute is not in the value list.
6
+ def matches?(value)
7
+ !value.values.first.include?(@attribute)
8
+ end
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,11 @@
1
+ # encoding: utf-8
2
+ module Mongoid #:nodoc:
3
+ module Matchers #:nodoc:
4
+ class Size < Default
5
+ # Return true if the attribute size is equal to the first value.
6
+ def matches?(value)
7
+ @attribute.size == value.values.first
8
+ end
9
+ end
10
+ end
11
+ end
data/mongo_doc.gemspec ADDED
@@ -0,0 +1,205 @@
1
+ # Generated by jeweler
2
+ # DO NOT EDIT THIS FILE DIRECTLY
3
+ # Instead, edit Jeweler::Tasks in Rakefile, and run the gemspec command
4
+ # -*- encoding: utf-8 -*-
5
+
6
+ Gem::Specification.new do |s|
7
+ s.name = %q{mongo_doc}
8
+ s.version = "0.3.0"
9
+
10
+ s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
+ s.authors = ["Les Hill"]
12
+ s.date = %q{2010-03-02}
13
+ s.description = %q{ODM for MongoDB}
14
+ s.email = %q{leshill@gmail.com}
15
+ s.extra_rdoc_files = [
16
+ "LICENSE",
17
+ "README.textile",
18
+ "TODO"
19
+ ]
20
+ s.files = [
21
+ ".document",
22
+ ".gitignore",
23
+ "LICENSE",
24
+ "README.textile",
25
+ "Rakefile",
26
+ "TODO",
27
+ "VERSION",
28
+ "data/.gitignore",
29
+ "examples/simple_document.rb",
30
+ "examples/simple_object.rb",
31
+ "features/finders.feature",
32
+ "features/mongodb.yml",
33
+ "features/mongodoc_base.feature",
34
+ "features/new_record.feature",
35
+ "features/partial_updates.feature",
36
+ "features/removing_documents.feature",
37
+ "features/saving_an_object.feature",
38
+ "features/scopes.feature",
39
+ "features/step_definitions/collection_steps.rb",
40
+ "features/step_definitions/document_steps.rb",
41
+ "features/step_definitions/documents.rb",
42
+ "features/step_definitions/finder_steps.rb",
43
+ "features/step_definitions/json_steps.rb",
44
+ "features/step_definitions/object_steps.rb",
45
+ "features/step_definitions/objects.rb",
46
+ "features/step_definitions/partial_update_steps.rb",
47
+ "features/step_definitions/query_steps.rb",
48
+ "features/step_definitions/removing_documents_steps.rb",
49
+ "features/step_definitions/scope_steps.rb",
50
+ "features/step_definitions/util_steps.rb",
51
+ "features/support/support.rb",
52
+ "features/using_criteria.feature",
53
+ "lib/mongo_doc.rb",
54
+ "lib/mongo_doc/associations/collection_proxy.rb",
55
+ "lib/mongo_doc/associations/document_proxy.rb",
56
+ "lib/mongo_doc/associations/hash_proxy.rb",
57
+ "lib/mongo_doc/associations/proxy_base.rb",
58
+ "lib/mongo_doc/attributes.rb",
59
+ "lib/mongo_doc/bson.rb",
60
+ "lib/mongo_doc/collection.rb",
61
+ "lib/mongo_doc/connection.rb",
62
+ "lib/mongo_doc/contexts.rb",
63
+ "lib/mongo_doc/contexts/enumerable.rb",
64
+ "lib/mongo_doc/contexts/ids.rb",
65
+ "lib/mongo_doc/contexts/mongo.rb",
66
+ "lib/mongo_doc/criteria.rb",
67
+ "lib/mongo_doc/cursor.rb",
68
+ "lib/mongo_doc/document.rb",
69
+ "lib/mongo_doc/ext/array.rb",
70
+ "lib/mongo_doc/ext/binary.rb",
71
+ "lib/mongo_doc/ext/boolean_class.rb",
72
+ "lib/mongo_doc/ext/date.rb",
73
+ "lib/mongo_doc/ext/date_time.rb",
74
+ "lib/mongo_doc/ext/dbref.rb",
75
+ "lib/mongo_doc/ext/hash.rb",
76
+ "lib/mongo_doc/ext/nil_class.rb",
77
+ "lib/mongo_doc/ext/numeric.rb",
78
+ "lib/mongo_doc/ext/object.rb",
79
+ "lib/mongo_doc/ext/object_id.rb",
80
+ "lib/mongo_doc/ext/regexp.rb",
81
+ "lib/mongo_doc/ext/string.rb",
82
+ "lib/mongo_doc/ext/symbol.rb",
83
+ "lib/mongo_doc/ext/time.rb",
84
+ "lib/mongo_doc/finders.rb",
85
+ "lib/mongo_doc/matchers.rb",
86
+ "lib/mongo_doc/query.rb",
87
+ "lib/mongo_doc/scope.rb",
88
+ "lib/mongo_doc/validations/macros.rb",
89
+ "lib/mongo_doc/validations/validates_embedded.rb",
90
+ "lib/mongoid/contexts/paging.rb",
91
+ "lib/mongoid/criteria.rb",
92
+ "lib/mongoid/criterion/complex.rb",
93
+ "lib/mongoid/criterion/exclusion.rb",
94
+ "lib/mongoid/criterion/inclusion.rb",
95
+ "lib/mongoid/criterion/optional.rb",
96
+ "lib/mongoid/extensions/hash/criteria_helpers.rb",
97
+ "lib/mongoid/extensions/symbol/inflections.rb",
98
+ "lib/mongoid/matchers/all.rb",
99
+ "lib/mongoid/matchers/default.rb",
100
+ "lib/mongoid/matchers/exists.rb",
101
+ "lib/mongoid/matchers/gt.rb",
102
+ "lib/mongoid/matchers/gte.rb",
103
+ "lib/mongoid/matchers/in.rb",
104
+ "lib/mongoid/matchers/lt.rb",
105
+ "lib/mongoid/matchers/lte.rb",
106
+ "lib/mongoid/matchers/ne.rb",
107
+ "lib/mongoid/matchers/nin.rb",
108
+ "lib/mongoid/matchers/size.rb",
109
+ "mongo_doc.gemspec",
110
+ "mongod.example.yml",
111
+ "mongodb.example.yml",
112
+ "perf/mongo_doc_runner.rb",
113
+ "perf/ruby_driver_runner.rb",
114
+ "script/console",
115
+ "spec/associations/collection_proxy_spec.rb",
116
+ "spec/associations/document_proxy_spec.rb",
117
+ "spec/associations/hash_proxy_spec.rb",
118
+ "spec/attributes_spec.rb",
119
+ "spec/bson_matchers.rb",
120
+ "spec/bson_spec.rb",
121
+ "spec/collection_spec.rb",
122
+ "spec/connection_spec.rb",
123
+ "spec/contexts/enumerable_spec.rb",
124
+ "spec/contexts/ids_spec.rb",
125
+ "spec/contexts/mongo_spec.rb",
126
+ "spec/contexts_spec.rb",
127
+ "spec/criteria_spec.rb",
128
+ "spec/cursor_spec.rb",
129
+ "spec/document_ext.rb",
130
+ "spec/document_spec.rb",
131
+ "spec/embedded_save_spec.rb",
132
+ "spec/finders_spec.rb",
133
+ "spec/hash_matchers.rb",
134
+ "spec/matchers_spec.rb",
135
+ "spec/mongodb.yml",
136
+ "spec/mongodb_pairs.yml",
137
+ "spec/new_record_spec.rb",
138
+ "spec/query_spec.rb",
139
+ "spec/scope_spec.rb",
140
+ "spec/spec.opts",
141
+ "spec/spec_helper.rb"
142
+ ]
143
+ s.homepage = %q{http://github.com/leshill/mongodoc}
144
+ s.rdoc_options = ["--charset=UTF-8"]
145
+ s.require_paths = ["lib"]
146
+ s.rubygems_version = %q{1.3.6}
147
+ s.summary = %q{ODM for MongoDB}
148
+ s.test_files = [
149
+ "spec/associations/collection_proxy_spec.rb",
150
+ "spec/associations/document_proxy_spec.rb",
151
+ "spec/associations/hash_proxy_spec.rb",
152
+ "spec/attributes_spec.rb",
153
+ "spec/bson_matchers.rb",
154
+ "spec/bson_spec.rb",
155
+ "spec/collection_spec.rb",
156
+ "spec/connection_spec.rb",
157
+ "spec/contexts/enumerable_spec.rb",
158
+ "spec/contexts/ids_spec.rb",
159
+ "spec/contexts/mongo_spec.rb",
160
+ "spec/contexts_spec.rb",
161
+ "spec/criteria_spec.rb",
162
+ "spec/cursor_spec.rb",
163
+ "spec/document_ext.rb",
164
+ "spec/document_spec.rb",
165
+ "spec/embedded_save_spec.rb",
166
+ "spec/finders_spec.rb",
167
+ "spec/hash_matchers.rb",
168
+ "spec/matchers_spec.rb",
169
+ "spec/new_record_spec.rb",
170
+ "spec/query_spec.rb",
171
+ "spec/scope_spec.rb",
172
+ "spec/spec_helper.rb",
173
+ "examples/simple_document.rb",
174
+ "examples/simple_object.rb"
175
+ ]
176
+
177
+ if s.respond_to? :specification_version then
178
+ current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
179
+ s.specification_version = 3
180
+
181
+ if Gem::Version.new(Gem::RubyGemsVersion) >= Gem::Version.new('1.2.0') then
182
+ s.add_runtime_dependency(%q<mongo>, ["= 0.19"])
183
+ s.add_runtime_dependency(%q<mongo_ext>, ["= 0.19"])
184
+ s.add_runtime_dependency(%q<durran-validatable>, ["= 2.0.1"])
185
+ s.add_runtime_dependency(%q<leshill-will_paginate>, ["= 2.3.11"])
186
+ s.add_development_dependency(%q<rspec>, ["= 1.3.0"])
187
+ s.add_development_dependency(%q<cucumber>, ["= 0.6.2"])
188
+ else
189
+ s.add_dependency(%q<mongo>, ["= 0.19"])
190
+ s.add_dependency(%q<mongo_ext>, ["= 0.19"])
191
+ s.add_dependency(%q<durran-validatable>, ["= 2.0.1"])
192
+ s.add_dependency(%q<leshill-will_paginate>, ["= 2.3.11"])
193
+ s.add_dependency(%q<rspec>, ["= 1.3.0"])
194
+ s.add_dependency(%q<cucumber>, ["= 0.6.2"])
195
+ end
196
+ else
197
+ s.add_dependency(%q<mongo>, ["= 0.19"])
198
+ s.add_dependency(%q<mongo_ext>, ["= 0.19"])
199
+ s.add_dependency(%q<durran-validatable>, ["= 2.0.1"])
200
+ s.add_dependency(%q<leshill-will_paginate>, ["= 2.3.11"])
201
+ s.add_dependency(%q<rspec>, ["= 1.3.0"])
202
+ s.add_dependency(%q<cucumber>, ["= 0.6.2"])
203
+ end
204
+ end
205
+
@@ -0,0 +1,2 @@
1
+ mongod: /usr/local/bin/mongod
2
+ dbpath: /data/db
@@ -0,0 +1,14 @@
1
+ development:
2
+ name: development
3
+ host: localhost
4
+ port: 27017
5
+ options:
6
+ auto_reconnect: true
7
+
8
+ test:
9
+ name: test
10
+ host: localhost
11
+ port: 27017
12
+ options:
13
+ auto_reconnect: true
14
+
@@ -0,0 +1,90 @@
1
+ require "benchmark"
2
+ require "ruby-prof"
3
+ require "mongo_doc"
4
+
5
+ class Person < MongoDoc::Document
6
+ key :birth_date
7
+ has_one :name
8
+ has_one :address
9
+ has_many :phones
10
+ end
11
+
12
+ class Name < MongoDoc::Document
13
+ key :given
14
+ key :family
15
+ key :middle
16
+ end
17
+
18
+ class Address < MongoDoc::Document
19
+ key :street
20
+ key :city
21
+ key :state
22
+ key :post_code
23
+ key :type
24
+ end
25
+
26
+ class Phone < MongoDoc::Document
27
+ key :country_code
28
+ key :number
29
+ key :type
30
+ end
31
+
32
+ class MongoDocRunner
33
+ def self.benchmark
34
+ MongoDoc.connect_to_database('mongo_doc_perf_test')
35
+ MongoDoc.database.collection('people').drop
36
+
37
+ puts "Starting benchmark..."
38
+
39
+ 10.times do |n|
40
+ person = Person.new(:birth_date => Date.new(1970, 1, 1))
41
+ name = Name.new(:given => "James", :family => "Kirk", :middle => "Tiberius")
42
+ address = Address.new(:street => "1 Starfleet Command Way", :city => "San Francisco", :state => "CA", :post_code => "94133", :type => "Work")
43
+ phone = Phone.new(:country_code => 1, :number => "415-555-1212", :type => "Mobile")
44
+ person.name = name
45
+ person.address = address
46
+ person.phones << phone
47
+ person.save
48
+ end
49
+
50
+ Benchmark.bm do |bm|
51
+ bm.report('MongoDoc') do
52
+ 10000.times do |n|
53
+ person = Person.new(:birth_date => Date.new(1970, 1, 1))
54
+ name = Name.new(:given => "James", :family => "Kirk", :middle => "Tiberius")
55
+ address = Address.new(:street => "1 Starfleet Command Way", :city => "San Francisco", :state => "CA", :post_code => "94133", :type => "Work")
56
+ phone = Phone.new(:country_code => 1, :number => "415-555-1212", :type => "Mobile")
57
+ person.name = name
58
+ person.address = address
59
+ person.phones << phone
60
+ person.save
61
+ end
62
+ end
63
+ end
64
+
65
+ end
66
+
67
+ def self.profile
68
+ MongoDoc.connect_to_database('mongo_doc_perf_test')
69
+ MongoDoc.database.collection('people').drop
70
+
71
+ RubyProf.start
72
+
73
+ puts "Starting profiler..."
74
+
75
+ 1000.times do |n|
76
+ person = Person.new(:birth_date => Date.new(1970, 1, 1))
77
+ name = Name.new(:given => "James", :family => "Kirk", :middle => "Tiberius")
78
+ address = Address.new(:street => "1 Starfleet Command Way", :city => "San Francisco", :state => "CA", :post_code => "94133", :type => "Work")
79
+ phone = Phone.new(:country_code => 1, :number => "415-555-1212", :type => "Mobile")
80
+ person.name = name
81
+ person.address = address
82
+ person.phones << phone
83
+ person.save
84
+ end
85
+
86
+ result = RubyProf.stop
87
+ printer = RubyProf::FlatPrinter.new(result)
88
+ printer.print(STDOUT, 0)
89
+ end
90
+ end
@@ -0,0 +1,64 @@
1
+ require "rubygems"
2
+ require "ruby-prof"
3
+ require "mongo_doc"
4
+
5
+ class RubyDriverRunner
6
+ def self.benchmark
7
+ MongoDoc.connect_to_database('mongo_doc_perf_test')
8
+ collection = MongoDoc.database.collection('people')
9
+ collection.drop
10
+
11
+ puts "Starting benchmark..."
12
+
13
+ 10.times do |n|
14
+ person = {:birth_date => Date.new(1970, 1, 1).to_bson, :phones => []}
15
+ name = {:given => "James", :family => "Kirk", :middle => "Tiberius"}
16
+ address = {:street => "1 Starfleet Command Way", :city => "San Francisco", :state => "CA", :post_code => "94133", :type => "Work"}
17
+ phone = {:country_code => 1, :number => "415-555-1212", :type => "Mobile"}
18
+ person[:name] = name
19
+ person[:address] = address
20
+ person[:phones] << phone
21
+ collection.save(person)
22
+ end
23
+
24
+ Benchmark.bm do |bm|
25
+ bm.report('Driver') do
26
+ 10000.times do |n|
27
+ person = {:birth_date => Date.new(1970, 1, 1).to_bson, :phones => []}
28
+ name = {:given => "James", :family => "Kirk", :middle => "Tiberius"}
29
+ address = {:street => "1 Starfleet Command Way", :city => "San Francisco", :state => "CA", :post_code => "94133", :type => "Work"}
30
+ phone = {:country_code => 1, :number => "415-555-1212", :type => "Mobile"}
31
+ person[:name] = name
32
+ person[:address] = address
33
+ person[:phones] << phone
34
+ collection.save(person)
35
+ end
36
+ end
37
+ end
38
+ end
39
+
40
+ def self.profile
41
+ MongoDoc.connect_to_database('mongo_doc_perf_test')
42
+ collection = MongoDoc.database.collection('people')
43
+ collection.drop
44
+
45
+ RubyProf.start
46
+
47
+ puts "Starting profiler..."
48
+
49
+ 1000.times do |n|
50
+ person = {:birth_date => Date.new(1970, 1, 1), :phones => []}
51
+ name = {:given => "James", :family => "Kirk", :middle => "Tiberius"}
52
+ address = { :street => "1 Starfleet Command Way", :city => "San Francisco", :state => "CA", :post_code => "94133", :type => "Work"}
53
+ phone = {:country_code => 1, :number => "415-555-1212", :type => "Mobile"}
54
+ person[:name] = name
55
+ person[:address] = address
56
+ person[:phones] << phone
57
+ collection.insert(person)
58
+ end
59
+
60
+ result = RubyProf.stop
61
+ printer = RubyProf::FlatPrinter.new(result)
62
+ printer.print(STDOUT, 0)
63
+ end
64
+ end
data/script/console ADDED
@@ -0,0 +1,8 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ $LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
4
+
5
+ require 'irb'
6
+ require 'mongo_doc'
7
+
8
+ IRB.start(__FILE__)
@@ -0,0 +1,200 @@
1
+ require File.expand_path(File.join(File.dirname(__FILE__), '..', '/spec_helper'))
2
+
3
+ describe MongoDoc::Associations::CollectionProxy do
4
+ class CollectionProxyTest
5
+ include MongoDoc::Document
6
+
7
+ key :name
8
+ end
9
+
10
+ let(:root) { stub('root', :register_save_observer => nil) }
11
+ let(:proxy) { MongoDoc::Associations::CollectionProxy.new(:assoc_name => 'has_many_name', :assoc_class => CollectionProxyTest, :root => root, :parent => root) }
12
+ let(:item) { CollectionProxyTest.new }
13
+
14
+ context "#<<" do
15
+ it "appends the item to the collection" do
16
+ (proxy << item).should include(item)
17
+ end
18
+
19
+ context "when the item is a Hash" do
20
+ let(:hash) {{:name => 'hash'}}
21
+
22
+ it "does not register a save observer" do
23
+ root.should_not_receive(:register_save_observer)
24
+ proxy << hash
25
+ end
26
+
27
+ it "does not set the root" do
28
+ hash.should_not_receive(:_root=)
29
+ proxy << hash
30
+ end
31
+
32
+ it "adds the hash to the collection" do
33
+ proxy << hash
34
+ proxy.should include(hash)
35
+ end
36
+ end
37
+
38
+ context "when the item is not a MongoDoc::Document" do
39
+ let(:other_item) {'not a doc'}
40
+
41
+ it "does not register a save observer" do
42
+ root.should_not_receive(:register_save_observer)
43
+ proxy << other_item
44
+ end
45
+
46
+ it "does not set the root" do
47
+ other_item.should_not_receive(:_root=)
48
+ proxy << other_item
49
+ end
50
+
51
+ it "adds the item to the collection" do
52
+ proxy << other_item
53
+ proxy.should include(other_item)
54
+ end
55
+ end
56
+
57
+ context "when the item is a MongoDoc::Document" do
58
+ it "registers a save observer" do
59
+ root.should_receive(:register_save_observer)
60
+ proxy << item
61
+ end
62
+
63
+ it "sets the root" do
64
+ proxy << item
65
+ item._root.should == root
66
+ end
67
+ end
68
+
69
+ context "when the item is an array" do
70
+ it "adds the array" do
71
+ array = ['something else']
72
+ proxy << array
73
+ proxy.should include(array)
74
+ end
75
+ end
76
+ end
77
+
78
+ context "#[]=" do
79
+ it "sets the item at the index" do
80
+ proxy[1] = item
81
+ proxy[1].should == item
82
+ end
83
+
84
+ context "when the item is not a MongoDoc::Document" do
85
+ let(:other_item) {'not a doc'}
86
+
87
+ it "does not register a save observer" do
88
+ root.should_not_receive(:register_save_observer)
89
+ proxy[1] = other_item
90
+ end
91
+
92
+ it "does not set the root" do
93
+ other_item.should_not_receive(:_root=)
94
+ proxy[1] = other_item
95
+ end
96
+
97
+ it "adds the item to the collection" do
98
+ proxy[1] = other_item
99
+ proxy.should include(other_item)
100
+ end
101
+ end
102
+
103
+ context "when the item is a MongoDoc::Document" do
104
+ it "registers a save observer" do
105
+ root.should_receive(:register_save_observer)
106
+ proxy[1] = item
107
+ end
108
+
109
+ it "sets the root" do
110
+ proxy[1] = item
111
+ item._root.should == root
112
+ end
113
+ end
114
+ end
115
+
116
+ context "#concat" do
117
+ it "appends the items from the array to self" do
118
+ proxy.concat([item])
119
+ proxy.should include(item)
120
+ end
121
+ end
122
+
123
+ context "#replace" do
124
+ it "clears the existing collection" do
125
+ proxy.should_receive(:clear)
126
+ proxy.replace([item])
127
+ end
128
+
129
+ it "concats the other onto self" do
130
+ other = [item]
131
+ proxy.should_receive(:concat).with(other)
132
+ proxy.replace(other)
133
+ end
134
+ end
135
+
136
+ context "#unshift" do
137
+ let(:proxy_with_item) { proxy << 'other' }
138
+
139
+ it "adds the item to the front of the collection" do
140
+ proxy_with_item.unshift(item)
141
+ proxy_with_item[0].should == item
142
+ end
143
+
144
+ context "when the item is not a MongoDoc::Document" do
145
+ let(:other_item) {'not a doc'}
146
+
147
+ it "does not register a save observer" do
148
+ root.should_not_receive(:register_save_observer)
149
+ proxy_with_item.unshift(other_item)
150
+ end
151
+
152
+ it "does not set the root" do
153
+ other_item.should_not_receive(:_root=)
154
+ proxy_with_item.unshift(other_item)
155
+ end
156
+
157
+ it "adds the item to the front of the collection" do
158
+ proxy_with_item.unshift(other_item)
159
+ proxy_with_item[0].should == other_item
160
+ end
161
+ end
162
+
163
+ context "when the item is a MongoDoc::Document" do
164
+ let(:new_item) { CollectionProxyTest.new }
165
+
166
+ it "registers a save observer" do
167
+ root.should_receive(:register_save_observer)
168
+ proxy_with_item.unshift(new_item)
169
+ end
170
+
171
+ it "sets the root" do
172
+ proxy_with_item.unshift(new_item)
173
+ new_item._root.should == root
174
+ end
175
+
176
+ it "adds the item to the front of the collection" do
177
+ proxy_with_item.unshift(new_item)
178
+ proxy_with_item[0].should == new_item
179
+ end
180
+ end
181
+ end
182
+
183
+ context "#build" do
184
+ let(:name) {'built'}
185
+
186
+ it "adds a built item to the collection" do
187
+ proxy.build({:name => name}).last.name.should == name
188
+ end
189
+
190
+ it "registers a save observer" do
191
+ root.should_receive(:register_save_observer)
192
+ proxy.build({:name => name})
193
+ end
194
+
195
+ it "sets the root" do
196
+ proxy.build({:name => name})
197
+ proxy.last._root.should == root
198
+ end
199
+ end
200
+ end