mongo_mapper_ign 0.7.7 → 0.7.8

Sign up to get free protection for your applications and to get access to all the features.
Files changed (50) hide show
  1. data/LICENSE +20 -20
  2. data/README.rdoc +34 -34
  3. data/bin/mmconsole +60 -60
  4. data/lib/mongo_mapper.rb +123 -123
  5. data/lib/mongo_mapper/document.rb +292 -292
  6. data/lib/mongo_mapper/embedded_document.rb +71 -71
  7. data/lib/mongo_mapper/plugins.rb +36 -36
  8. data/lib/mongo_mapper/plugins/associations.rb +115 -115
  9. data/lib/mongo_mapper/plugins/associations/base.rb +124 -124
  10. data/lib/mongo_mapper/plugins/associations/belongs_to_polymorphic_proxy.rb +31 -31
  11. data/lib/mongo_mapper/plugins/associations/belongs_to_proxy.rb +26 -26
  12. data/lib/mongo_mapper/plugins/associations/collection.rb +21 -21
  13. data/lib/mongo_mapper/plugins/associations/embedded_collection.rb +39 -39
  14. data/lib/mongo_mapper/plugins/associations/in_array_proxy.rb +160 -144
  15. data/lib/mongo_mapper/plugins/associations/many_documents_as_proxy.rb +29 -29
  16. data/lib/mongo_mapper/plugins/associations/many_documents_proxy.rb +130 -130
  17. data/lib/mongo_mapper/plugins/associations/many_embedded_polymorphic_proxy.rb +32 -32
  18. data/lib/mongo_mapper/plugins/associations/many_embedded_proxy.rb +24 -24
  19. data/lib/mongo_mapper/plugins/associations/many_polymorphic_proxy.rb +14 -14
  20. data/lib/mongo_mapper/plugins/associations/one_embedded_proxy.rb +42 -42
  21. data/lib/mongo_mapper/plugins/associations/one_proxy.rb +70 -70
  22. data/lib/mongo_mapper/plugins/associations/proxy.rb +125 -125
  23. data/lib/mongo_mapper/plugins/callbacks.rb +241 -241
  24. data/lib/mongo_mapper/plugins/clone.rb +13 -13
  25. data/lib/mongo_mapper/plugins/descendants.rb +16 -16
  26. data/lib/mongo_mapper/plugins/dirty.rb +119 -119
  27. data/lib/mongo_mapper/plugins/equality.rb +23 -23
  28. data/lib/mongo_mapper/plugins/identity_map.rb +123 -123
  29. data/lib/mongo_mapper/plugins/inspect.rb +14 -14
  30. data/lib/mongo_mapper/plugins/keys.rb +322 -322
  31. data/lib/mongo_mapper/plugins/keys/key.rb +53 -53
  32. data/lib/mongo_mapper/plugins/logger.rb +17 -17
  33. data/lib/mongo_mapper/plugins/modifiers.rb +111 -111
  34. data/lib/mongo_mapper/plugins/pagination.rb +24 -24
  35. data/lib/mongo_mapper/plugins/pagination/proxy.rb +72 -72
  36. data/lib/mongo_mapper/plugins/persistence.rb +96 -96
  37. data/lib/mongo_mapper/plugins/protected.rb +46 -46
  38. data/lib/mongo_mapper/plugins/rails.rb +57 -57
  39. data/lib/mongo_mapper/plugins/serialization.rb +92 -92
  40. data/lib/mongo_mapper/plugins/serialization/array.rb +56 -56
  41. data/lib/mongo_mapper/plugins/serialization/xml_serializer.rb +239 -239
  42. data/lib/mongo_mapper/plugins/timestamps.rb +21 -21
  43. data/lib/mongo_mapper/plugins/userstamps.rb +14 -14
  44. data/lib/mongo_mapper/plugins/validations.rb +46 -46
  45. data/lib/mongo_mapper/query.rb +28 -28
  46. data/lib/mongo_mapper/support.rb +197 -197
  47. data/lib/mongo_mapper/support/descendant_appends.rb +46 -46
  48. data/lib/mongo_mapper/support/find.rb +77 -77
  49. data/lib/mongo_mapper/version.rb +3 -3
  50. metadata +4 -25
@@ -1,292 +1,292 @@
1
- # encoding: UTF-8
2
- module MongoMapper
3
- module Document
4
- extend Support::DescendantAppends
5
-
6
- def self.included(model)
7
- model.class_eval do
8
- include InstanceMethods
9
- extend Support::Find
10
- extend ClassMethods
11
- extend Plugins
12
-
13
- plugin Plugins::Associations
14
- plugin Plugins::Clone
15
- plugin Plugins::Descendants
16
- plugin Plugins::Equality
17
- plugin Plugins::Inspect
18
- plugin Plugins::Keys
19
- plugin Plugins::Dirty # for now dirty needs to be after keys
20
- plugin Plugins::Logger
21
- plugin Plugins::Modifiers
22
- plugin Plugins::Pagination
23
- plugin Plugins::Persistence
24
- plugin Plugins::Protected
25
- plugin Plugins::Rails
26
- plugin Plugins::Serialization
27
- plugin Plugins::Timestamps
28
- plugin Plugins::Userstamps
29
- plugin Plugins::Validations
30
- plugin Plugins::Callbacks # for now callbacks needs to be after validations
31
-
32
- extend Plugins::Validations::DocumentMacros
33
- end
34
-
35
- super
36
- end
37
-
38
- module ClassMethods
39
- def inherited(subclass)
40
- subclass.set_collection_name(collection_name)
41
- super
42
- end
43
-
44
- def ensure_index(spec, options={})
45
- collection.create_index(spec, options)
46
- end
47
-
48
- def find(*args)
49
- options = args.extract_options!
50
- return nil if args.size == 0
51
-
52
- if args.first.is_a?(Array) || args.size > 1
53
- find_some(args, options)
54
- else
55
- query = query(options).update(:_id => args[0])
56
- find_one(query.to_hash)
57
- end
58
- end
59
-
60
- def find!(*args)
61
- options = args.extract_options!
62
- raise DocumentNotFound, "Couldn't find without an ID" if args.size == 0
63
-
64
- if args.first.is_a?(Array) || args.size > 1
65
- find_some!(args, options)
66
- else
67
- query = query(options).update(:_id => args[0])
68
- find_one(query.to_hash) || raise(DocumentNotFound, "Document match #{options.inspect} does not exist in #{collection.name} collection")
69
- end
70
- end
71
-
72
- def find_each(options={})
73
- query(options).find().each { |doc| yield load(doc) }
74
- end
75
-
76
- def find_by_id(id)
77
- find(id)
78
- end
79
-
80
- def first_or_create(args)
81
- first(args) || create(args.reject { |key, value| !key?(key) })
82
- end
83
-
84
- def first_or_new(args)
85
- first(args) || new(args.reject { |key, value| !key?(key) })
86
- end
87
-
88
- def first(options={})
89
- find_one(options)
90
- end
91
-
92
- def last(options={})
93
- raise ':order option must be provided when using last' if options[:order].blank?
94
- find_one(query(options).reverse.to_hash)
95
- end
96
-
97
- def all(options={})
98
- find_many(options)
99
- end
100
-
101
- def count(options={})
102
- query(options).count
103
- end
104
-
105
- def exists?(options={})
106
- !count(options).zero?
107
- end
108
-
109
- def create(*docs)
110
- initialize_each(*docs) { |doc| doc.save }
111
- end
112
-
113
- def create!(*docs)
114
- initialize_each(*docs) { |doc| doc.save! }
115
- end
116
-
117
- def update(*args)
118
- if args.length == 1
119
- update_multiple(args[0])
120
- else
121
- id, attributes = args
122
- update_single(id, attributes)
123
- end
124
- end
125
-
126
- def delete(*ids)
127
- query(:_id => ids.flatten).remove
128
- end
129
-
130
- def delete_all(options={})
131
- query(options).remove
132
- end
133
-
134
- def destroy(*ids)
135
- find_some!(ids.flatten).each(&:destroy)
136
- end
137
-
138
- def destroy_all(options={})
139
- find_each(options) { |document| document.destroy }
140
- end
141
-
142
- def embeddable?
143
- false
144
- end
145
-
146
- def enslave
147
- @enslave = true
148
- end
149
-
150
- def enslave?
151
- @enslave ||= false
152
- end
153
-
154
- def single_collection_inherited?
155
- keys.key?(:_type) && single_collection_inherited_superclass?
156
- end
157
-
158
- def single_collection_inherited_superclass?
159
- superclass.respond_to?(:keys) && superclass.keys.key?(:_type)
160
- end
161
-
162
- # @api private for now
163
- def query(options={})
164
- Query.new(self, options)
165
- end
166
-
167
- private
168
- def initialize_each(*docs)
169
- instances = []
170
- docs = [{}] if docs.blank?
171
- docs.flatten.each do |attrs|
172
- doc = new(attrs)
173
- yield(doc)
174
- instances << doc
175
- end
176
- instances.size == 1 ? instances[0] : instances
177
- end
178
-
179
- def find_some(ids, options={})
180
- query = query(options).update(:_id => ids.flatten.compact.uniq)
181
- find_many(query.to_hash).compact
182
- end
183
-
184
- def find_some!(ids, options={})
185
- ids = ids.flatten.compact.uniq
186
- documents = find_some(ids, options)
187
-
188
- if ids.size == documents.size
189
- documents
190
- else
191
- raise DocumentNotFound, "Couldn't find all of the ids (#{ids.to_sentence}). Found #{documents.size}, but was expecting #{ids.size}"
192
- end
193
- end
194
-
195
- # All query methods that load documents pass through find_one or find_many
196
- def find_one(options={})
197
- load(query(options).first)
198
- end
199
-
200
- # All query methods that load documents pass through find_one or find_many
201
- def find_many(options)
202
- query(options).all().map { |doc| load(doc) }
203
- end
204
-
205
- def update_single(id, attrs)
206
- if id.blank? || attrs.blank? || !attrs.is_a?(Hash)
207
- raise ArgumentError, "Updating a single document requires an id and a hash of attributes"
208
- end
209
-
210
- find(id).tap do |doc|
211
- doc.update_attributes(attrs)
212
- end
213
- end
214
-
215
- def update_multiple(docs)
216
- unless docs.is_a?(Hash)
217
- raise ArgumentError, "Updating multiple documents takes 1 argument and it must be hash"
218
- end
219
-
220
- instances = []
221
- docs.each_pair { |id, attrs| instances << update(id, attrs) }
222
- instances
223
- end
224
- end
225
-
226
- module InstanceMethods
227
- def save(options={})
228
- options.assert_valid_keys(:validate, :safe)
229
- options.reverse_merge!(:validate => true)
230
- !options[:validate] || valid? ? create_or_update(options) : false
231
- end
232
-
233
- def save!(options={})
234
- options.assert_valid_keys(:safe)
235
- save(options) || raise(DocumentNotValid.new(self))
236
- end
237
-
238
- def destroy
239
- delete
240
- end
241
-
242
- def delete
243
- @_destroyed = true
244
- self.class.delete(id) unless new?
245
- end
246
-
247
- def new?
248
- @new
249
- end
250
-
251
- def destroyed?
252
- @_destroyed == true
253
- end
254
-
255
- def reload
256
- if doc = self.class.query(:_id => id).first
257
- self.class.associations.each { |name, assoc| send(name).reset if respond_to?(name) }
258
- self.attributes = doc
259
- self
260
- else
261
- raise DocumentNotFound, "Document match #{_id.inspect} does not exist in #{collection.name} collection"
262
- end
263
- end
264
-
265
- # Used by embedded docs to find root easily without if/respond_to? stuff.
266
- # Documents are always root documents.
267
- def _root_document
268
- self
269
- end
270
-
271
- private
272
- def create_or_update(options={})
273
- result = new? ? create(options) : update(options)
274
- result != false
275
- end
276
-
277
- def create(options={})
278
- save_to_collection(options)
279
- end
280
-
281
- def update(options={})
282
- save_to_collection(options)
283
- end
284
-
285
- def save_to_collection(options={})
286
- safe = options[:safe] || false
287
- @new = false
288
- collection.save(to_mongo, :safe => safe)
289
- end
290
- end
291
- end # Document
292
- end # MongoMapper
1
+ # encoding: UTF-8
2
+ module MongoMapper
3
+ module Document
4
+ extend Support::DescendantAppends
5
+
6
+ def self.included(model)
7
+ model.class_eval do
8
+ include InstanceMethods
9
+ extend Support::Find
10
+ extend ClassMethods
11
+ extend Plugins
12
+
13
+ plugin Plugins::Associations
14
+ plugin Plugins::Clone
15
+ plugin Plugins::Descendants
16
+ plugin Plugins::Equality
17
+ plugin Plugins::Inspect
18
+ plugin Plugins::Keys
19
+ plugin Plugins::Dirty # for now dirty needs to be after keys
20
+ plugin Plugins::Logger
21
+ plugin Plugins::Modifiers
22
+ plugin Plugins::Pagination
23
+ plugin Plugins::Persistence
24
+ plugin Plugins::Protected
25
+ plugin Plugins::Rails
26
+ plugin Plugins::Serialization
27
+ plugin Plugins::Timestamps
28
+ plugin Plugins::Userstamps
29
+ plugin Plugins::Validations
30
+ plugin Plugins::Callbacks # for now callbacks needs to be after validations
31
+
32
+ extend Plugins::Validations::DocumentMacros
33
+ end
34
+
35
+ super
36
+ end
37
+
38
+ module ClassMethods
39
+ def inherited(subclass)
40
+ subclass.set_collection_name(collection_name)
41
+ super
42
+ end
43
+
44
+ def ensure_index(spec, options={})
45
+ collection.create_index(spec, options)
46
+ end
47
+
48
+ def find(*args)
49
+ options = args.extract_options!
50
+ return nil if args.size == 0
51
+
52
+ if args.first.is_a?(Array) || args.size > 1
53
+ find_some(args, options)
54
+ else
55
+ query = query(options).update(:_id => args[0])
56
+ find_one(query.to_hash)
57
+ end
58
+ end
59
+
60
+ def find!(*args)
61
+ options = args.extract_options!
62
+ raise DocumentNotFound, "Couldn't find without an ID" if args.size == 0
63
+
64
+ if args.first.is_a?(Array) || args.size > 1
65
+ find_some!(args, options)
66
+ else
67
+ query = query(options).update(:_id => args[0])
68
+ find_one(query.to_hash) || raise(DocumentNotFound, "Document match #{options.inspect} does not exist in #{collection.name} collection")
69
+ end
70
+ end
71
+
72
+ def find_each(options={})
73
+ query(options).find().each { |doc| yield load(doc) }
74
+ end
75
+
76
+ def find_by_id(id)
77
+ find(id)
78
+ end
79
+
80
+ def first_or_create(args)
81
+ first(args) || create(args.reject { |key, value| !key?(key) })
82
+ end
83
+
84
+ def first_or_new(args)
85
+ first(args) || new(args.reject { |key, value| !key?(key) })
86
+ end
87
+
88
+ def first(options={})
89
+ find_one(options)
90
+ end
91
+
92
+ def last(options={})
93
+ raise ':order option must be provided when using last' if options[:order].blank?
94
+ find_one(query(options).reverse.to_hash)
95
+ end
96
+
97
+ def all(options={})
98
+ find_many(options)
99
+ end
100
+
101
+ def count(options={})
102
+ query(options).count
103
+ end
104
+
105
+ def exists?(options={})
106
+ !count(options).zero?
107
+ end
108
+
109
+ def create(*docs)
110
+ initialize_each(*docs) { |doc| doc.save }
111
+ end
112
+
113
+ def create!(*docs)
114
+ initialize_each(*docs) { |doc| doc.save! }
115
+ end
116
+
117
+ def update(*args)
118
+ if args.length == 1
119
+ update_multiple(args[0])
120
+ else
121
+ id, attributes = args
122
+ update_single(id, attributes)
123
+ end
124
+ end
125
+
126
+ def delete(*ids)
127
+ query(:_id => ids.flatten).remove
128
+ end
129
+
130
+ def delete_all(options={})
131
+ query(options).remove
132
+ end
133
+
134
+ def destroy(*ids)
135
+ find_some!(ids.flatten).each(&:destroy)
136
+ end
137
+
138
+ def destroy_all(options={})
139
+ find_each(options) { |document| document.destroy }
140
+ end
141
+
142
+ def embeddable?
143
+ false
144
+ end
145
+
146
+ def enslave
147
+ @enslave = true
148
+ end
149
+
150
+ def enslave?
151
+ @enslave ||= false
152
+ end
153
+
154
+ def single_collection_inherited?
155
+ keys.key?(:_type) && single_collection_inherited_superclass?
156
+ end
157
+
158
+ def single_collection_inherited_superclass?
159
+ superclass.respond_to?(:keys) && superclass.keys.key?(:_type)
160
+ end
161
+
162
+ # @api private for now
163
+ def query(options={})
164
+ Query.new(self, options)
165
+ end
166
+
167
+ private
168
+ def initialize_each(*docs)
169
+ instances = []
170
+ docs = [{}] if docs.blank?
171
+ docs.flatten.each do |attrs|
172
+ doc = new(attrs)
173
+ yield(doc)
174
+ instances << doc
175
+ end
176
+ instances.size == 1 ? instances[0] : instances
177
+ end
178
+
179
+ def find_some(ids, options={})
180
+ query = query(options).update(:_id => ids.flatten.compact.uniq)
181
+ find_many(query.to_hash).compact
182
+ end
183
+
184
+ def find_some!(ids, options={})
185
+ ids = ids.flatten.compact.uniq
186
+ documents = find_some(ids, options)
187
+
188
+ if ids.size == documents.size
189
+ documents
190
+ else
191
+ raise DocumentNotFound, "Couldn't find all of the ids (#{ids.to_sentence}). Found #{documents.size}, but was expecting #{ids.size}"
192
+ end
193
+ end
194
+
195
+ # All query methods that load documents pass through find_one or find_many
196
+ def find_one(options={})
197
+ load(query(options).first)
198
+ end
199
+
200
+ # All query methods that load documents pass through find_one or find_many
201
+ def find_many(options)
202
+ query(options).all().map { |doc| load(doc) }
203
+ end
204
+
205
+ def update_single(id, attrs)
206
+ if id.blank? || attrs.blank? || !attrs.is_a?(Hash)
207
+ raise ArgumentError, "Updating a single document requires an id and a hash of attributes"
208
+ end
209
+
210
+ find(id).tap do |doc|
211
+ doc.update_attributes(attrs)
212
+ end
213
+ end
214
+
215
+ def update_multiple(docs)
216
+ unless docs.is_a?(Hash)
217
+ raise ArgumentError, "Updating multiple documents takes 1 argument and it must be hash"
218
+ end
219
+
220
+ instances = []
221
+ docs.each_pair { |id, attrs| instances << update(id, attrs) }
222
+ instances
223
+ end
224
+ end
225
+
226
+ module InstanceMethods
227
+ def save(options={})
228
+ options.assert_valid_keys(:validate, :safe)
229
+ options.reverse_merge!(:validate => true)
230
+ !options[:validate] || valid? ? create_or_update(options) : false
231
+ end
232
+
233
+ def save!(options={})
234
+ options.assert_valid_keys(:safe)
235
+ save(options) || raise(DocumentNotValid.new(self))
236
+ end
237
+
238
+ def destroy
239
+ delete
240
+ end
241
+
242
+ def delete
243
+ @_destroyed = true
244
+ self.class.delete(id) unless new?
245
+ end
246
+
247
+ def new?
248
+ @new
249
+ end
250
+
251
+ def destroyed?
252
+ @_destroyed == true
253
+ end
254
+
255
+ def reload
256
+ if doc = self.class.query(:_id => id).first
257
+ self.class.associations.each { |name, assoc| send(name).reset if respond_to?(name) }
258
+ self.attributes = doc
259
+ self
260
+ else
261
+ raise DocumentNotFound, "Document match #{_id.inspect} does not exist in #{collection.name} collection"
262
+ end
263
+ end
264
+
265
+ # Used by embedded docs to find root easily without if/respond_to? stuff.
266
+ # Documents are always root documents.
267
+ def _root_document
268
+ self
269
+ end
270
+
271
+ private
272
+ def create_or_update(options={})
273
+ result = new? ? create(options) : update(options)
274
+ result != false
275
+ end
276
+
277
+ def create(options={})
278
+ save_to_collection(options)
279
+ end
280
+
281
+ def update(options={})
282
+ save_to_collection(options)
283
+ end
284
+
285
+ def save_to_collection(options={})
286
+ safe = options[:safe] || false
287
+ @new = false
288
+ collection.save(to_mongo, :safe => safe)
289
+ end
290
+ end
291
+ end # Document
292
+ end # MongoMapper