mongo_doc 0.3.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.
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