pwnash-mongo_mapper 0.7.5 → 0.7.6

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 (108) hide show
  1. data/lib/mongo_mapper.rb +6 -8
  2. data/lib/mongo_mapper/document.rb +6 -281
  3. data/lib/mongo_mapper/embedded_document.rb +5 -45
  4. data/lib/mongo_mapper/extensions.rb +190 -0
  5. data/lib/mongo_mapper/plugins.rb +27 -18
  6. data/lib/mongo_mapper/plugins/associations.rb +7 -6
  7. data/lib/mongo_mapper/plugins/associations/base.rb +1 -0
  8. data/lib/mongo_mapper/plugins/associations/belongs_to_polymorphic_proxy.rb +1 -0
  9. data/lib/mongo_mapper/plugins/associations/belongs_to_proxy.rb +1 -0
  10. data/lib/mongo_mapper/plugins/associations/collection.rb +1 -0
  11. data/lib/mongo_mapper/plugins/associations/embedded_collection.rb +1 -0
  12. data/lib/mongo_mapper/plugins/associations/in_array_proxy.rb +2 -1
  13. data/lib/mongo_mapper/plugins/associations/many_documents_as_proxy.rb +1 -0
  14. data/lib/mongo_mapper/plugins/associations/many_documents_proxy.rb +4 -4
  15. data/lib/mongo_mapper/plugins/associations/many_embedded_polymorphic_proxy.rb +1 -0
  16. data/lib/mongo_mapper/plugins/associations/many_embedded_proxy.rb +1 -0
  17. data/lib/mongo_mapper/plugins/associations/many_polymorphic_proxy.rb +1 -0
  18. data/lib/mongo_mapper/plugins/associations/one_embedded_proxy.rb +1 -0
  19. data/lib/mongo_mapper/plugins/associations/one_proxy.rb +1 -0
  20. data/lib/mongo_mapper/plugins/associations/proxy.rb +1 -0
  21. data/lib/mongo_mapper/plugins/callbacks.rb +4 -3
  22. data/lib/mongo_mapper/plugins/clone.rb +1 -0
  23. data/lib/mongo_mapper/plugins/descendants.rb +1 -0
  24. data/lib/mongo_mapper/plugins/dirty.rb +1 -0
  25. data/lib/mongo_mapper/plugins/document.rb +40 -0
  26. data/lib/mongo_mapper/plugins/dynamic_querying.rb +42 -0
  27. data/lib/mongo_mapper/{support/find.rb → plugins/dynamic_querying/dynamic_finder.rb} +2 -36
  28. data/lib/mongo_mapper/plugins/embedded_document.rb +48 -0
  29. data/lib/mongo_mapper/plugins/equality.rb +1 -0
  30. data/lib/mongo_mapper/plugins/identity_map.rb +8 -11
  31. data/lib/mongo_mapper/plugins/indexes.rb +11 -0
  32. data/lib/mongo_mapper/plugins/inspect.rb +1 -0
  33. data/lib/mongo_mapper/plugins/keys.rb +7 -9
  34. data/lib/mongo_mapper/plugins/keys/key.rb +12 -2
  35. data/lib/mongo_mapper/plugins/logger.rb +1 -0
  36. data/lib/mongo_mapper/plugins/modifiers.rb +3 -2
  37. data/lib/mongo_mapper/plugins/pagination.rb +1 -0
  38. data/lib/mongo_mapper/plugins/pagination/proxy.rb +1 -0
  39. data/lib/mongo_mapper/plugins/persistence.rb +1 -0
  40. data/lib/mongo_mapper/plugins/protected.rb +1 -0
  41. data/lib/mongo_mapper/plugins/query_logger.rb +5 -10
  42. data/lib/mongo_mapper/plugins/querying.rb +236 -0
  43. data/lib/mongo_mapper/plugins/rails.rb +1 -0
  44. data/lib/mongo_mapper/plugins/sci.rb +31 -0
  45. data/lib/mongo_mapper/plugins/serialization.rb +1 -0
  46. data/lib/mongo_mapper/plugins/timestamps.rb +1 -0
  47. data/lib/mongo_mapper/plugins/userstamps.rb +1 -0
  48. data/lib/mongo_mapper/plugins/validations.rb +5 -1
  49. data/lib/mongo_mapper/query.rb +53 -120
  50. data/lib/mongo_mapper/support.rb +2 -213
  51. data/lib/mongo_mapper/support/descendant_appends.rb +3 -6
  52. data/lib/mongo_mapper/version.rb +2 -1
  53. metadata +156 -190
  54. data/.gitignore +0 -10
  55. data/Rakefile +0 -37
  56. data/mongo_mapper.gemspec +0 -216
  57. data/performance/read_write.rb +0 -52
  58. data/specs.watchr +0 -51
  59. data/test/NOTE_ON_TESTING +0 -1
  60. data/test/active_model_lint_test.rb +0 -13
  61. data/test/functional/associations/test_belongs_to_polymorphic_proxy.rb +0 -63
  62. data/test/functional/associations/test_belongs_to_proxy.rb +0 -101
  63. data/test/functional/associations/test_in_array_proxy.rb +0 -325
  64. data/test/functional/associations/test_many_documents_as_proxy.rb +0 -229
  65. data/test/functional/associations/test_many_documents_proxy.rb +0 -536
  66. data/test/functional/associations/test_many_embedded_polymorphic_proxy.rb +0 -176
  67. data/test/functional/associations/test_many_embedded_proxy.rb +0 -256
  68. data/test/functional/associations/test_many_polymorphic_proxy.rb +0 -302
  69. data/test/functional/associations/test_one_embedded_proxy.rb +0 -68
  70. data/test/functional/associations/test_one_proxy.rb +0 -196
  71. data/test/functional/test_associations.rb +0 -44
  72. data/test/functional/test_binary.rb +0 -27
  73. data/test/functional/test_callbacks.rb +0 -151
  74. data/test/functional/test_dirty.rb +0 -163
  75. data/test/functional/test_document.rb +0 -1219
  76. data/test/functional/test_embedded_document.rb +0 -210
  77. data/test/functional/test_identity_map.rb +0 -507
  78. data/test/functional/test_indexing.rb +0 -44
  79. data/test/functional/test_logger.rb +0 -20
  80. data/test/functional/test_modifiers.rb +0 -416
  81. data/test/functional/test_pagination.rb +0 -93
  82. data/test/functional/test_protected.rb +0 -163
  83. data/test/functional/test_string_id_compatibility.rb +0 -67
  84. data/test/functional/test_timestamps.rb +0 -64
  85. data/test/functional/test_userstamps.rb +0 -28
  86. data/test/functional/test_validations.rb +0 -342
  87. data/test/models.rb +0 -227
  88. data/test/support/custom_matchers.rb +0 -37
  89. data/test/support/timing.rb +0 -16
  90. data/test/test_helper.rb +0 -64
  91. data/test/unit/associations/test_base.rb +0 -212
  92. data/test/unit/associations/test_proxy.rb +0 -105
  93. data/test/unit/serializers/test_json_serializer.rb +0 -202
  94. data/test/unit/test_descendant_appends.rb +0 -71
  95. data/test/unit/test_document.rb +0 -225
  96. data/test/unit/test_dynamic_finder.rb +0 -123
  97. data/test/unit/test_embedded_document.rb +0 -657
  98. data/test/unit/test_keys.rb +0 -216
  99. data/test/unit/test_mongo_mapper.rb +0 -118
  100. data/test/unit/test_pagination.rb +0 -160
  101. data/test/unit/test_plugins.rb +0 -50
  102. data/test/unit/test_query.rb +0 -374
  103. data/test/unit/test_rails.rb +0 -181
  104. data/test/unit/test_rails_compatibility.rb +0 -52
  105. data/test/unit/test_serialization.rb +0 -51
  106. data/test/unit/test_support.rb +0 -390
  107. data/test/unit/test_time_zones.rb +0 -39
  108. data/test/unit/test_validations.rb +0 -544
@@ -0,0 +1,11 @@
1
+ module MongoMapper
2
+ module Plugins
3
+ module Indexes
4
+ module ClassMethods
5
+ def ensure_index(spec, options={})
6
+ collection.create_index(spec, options)
7
+ end
8
+ end
9
+ end
10
+ end
11
+ end
@@ -1,3 +1,4 @@
1
+ # encoding: UTF-8
1
2
  module MongoMapper
2
3
  module Plugins
3
4
  module Inspect
@@ -1,3 +1,4 @@
1
+ # encoding: UTF-8
1
2
  module MongoMapper
2
3
  module Plugins
3
4
  module Keys
@@ -9,7 +10,6 @@ module MongoMapper
9
10
 
10
11
  module ClassMethods
11
12
  def inherited(descendant)
12
- key :_type, String unless keys.keys.include?(:_type)
13
13
  descendant.instance_variable_set(:@keys, keys.dup)
14
14
  super
15
15
  end
@@ -36,9 +36,12 @@ module MongoMapper
36
36
  object_id_key?(:_id)
37
37
  end
38
38
 
39
+ def object_id_keys
40
+ keys.keys.select { |key| keys[key].type == ObjectId }.map(&:to_sym)
41
+ end
42
+
39
43
  def object_id_key?(name)
40
- key = keys[name.to_s]
41
- key && key.type == ObjectId
44
+ object_id_keys.include?(name.to_sym)
42
45
  end
43
46
 
44
47
  def to_mongo(instance)
@@ -53,6 +56,7 @@ module MongoMapper
53
56
 
54
57
  # load is overridden in identity map to ensure same objects are loaded
55
58
  def load(attrs)
59
+ return nil if attrs.nil?
56
60
  begin
57
61
  klass = attrs['_type'].present? ? attrs['_type'].constantize : self
58
62
  klass.new(attrs, true)
@@ -161,8 +165,6 @@ module MongoMapper
161
165
  @new = true
162
166
  assign(attrs)
163
167
  end
164
-
165
- assign_type
166
168
  end
167
169
 
168
170
  def persisted?
@@ -275,10 +277,6 @@ module MongoMapper
275
277
  end
276
278
  end
277
279
 
278
- def assign_type
279
- self._type = self.class.name if respond_to?(:_type=)
280
- end
281
-
282
280
  def ensure_key_exists(name)
283
281
  self.class.key(name) unless respond_to?("#{name}=")
284
282
  end
@@ -1,3 +1,4 @@
1
+ # encoding: UTF-8
1
2
  module MongoMapper
2
3
  module Plugins
3
4
  module Keys
@@ -8,7 +9,7 @@ module MongoMapper
8
9
  options = args.extract_options!
9
10
  @name, @type = args.shift.to_s, args.shift
10
11
  self.options = (options || {}).symbolize_keys
11
- self.default_value = self.options.delete(:default)
12
+ self.default_value = self.options[:default]
12
13
  end
13
14
 
14
15
  def ==(other)
@@ -36,8 +37,17 @@ module MongoMapper
36
37
  end
37
38
 
38
39
  def set(value)
39
- type.to_mongo(value)
40
+ type.to_mongo(value).tap do |values|
41
+ if options[:typecast].present?
42
+ values.map! { |v| typecast_class.to_mongo(v) }
43
+ end
44
+ end
40
45
  end
46
+
47
+ private
48
+ def typecast_class
49
+ options[:typecast].constantize
50
+ end
41
51
  end
42
52
  end
43
53
  end
@@ -1,3 +1,4 @@
1
+ # encoding: UTF-8
1
2
  module MongoMapper
2
3
  module Plugins
3
4
  module Logger
@@ -1,3 +1,4 @@
1
+ # encoding: UTF-8
1
2
  module MongoMapper
2
3
  module Plugins
3
4
  module Modifiers
@@ -29,7 +30,7 @@ module MongoMapper
29
30
  criteria = {:id => ids}
30
31
  end
31
32
 
32
- criteria = to_criteria(criteria)
33
+ criteria = criteria_hash(criteria).to_hash
33
34
  modifiers = keys.inject({}) { |hash, key| hash[key] = 1; hash }
34
35
  collection.update(criteria, {'$unset' => modifiers}, :multi => true)
35
36
  end
@@ -68,7 +69,7 @@ module MongoMapper
68
69
  def criteria_and_keys_from_args(args)
69
70
  keys = args.pop
70
71
  criteria = args[0].is_a?(Hash) ? args[0] : {:id => args}
71
- [to_criteria(criteria), keys]
72
+ [criteria_hash(criteria).to_hash, keys]
72
73
  end
73
74
  end
74
75
 
@@ -1,3 +1,4 @@
1
+ # encoding: UTF-8
1
2
  module MongoMapper
2
3
  module Plugins
3
4
  module Pagination
@@ -1,3 +1,4 @@
1
+ # encoding: UTF-8
1
2
  module MongoMapper
2
3
  module Plugins
3
4
  module Pagination
@@ -1,3 +1,4 @@
1
+ # encoding: UTF-8
1
2
  module MongoMapper
2
3
  module Plugins
3
4
  module Persistence
@@ -1,3 +1,4 @@
1
+ # encoding: UTF-8
1
2
  module MongoMapper
2
3
  module Plugins
3
4
  module Protected
@@ -4,6 +4,7 @@ module MongoMapper
4
4
  module QueryLogger
5
5
 
6
6
  module ClassMethods
7
+
7
8
  def find_one(options={})
8
9
  criteria, query_options = to_query(options)
9
10
  log(query_options.inspect, 'find_one') do
@@ -26,9 +27,9 @@ module MongoMapper
26
27
  end
27
28
 
28
29
  def log_info(query, name, ms)
29
- if self.logger && self.logger.debug?
30
+ if self.logger && self.logger.info?
30
31
  name = '%s (%.1fms)' % [name || 'query', ms]
31
- self.logger.debug(format_log_entry(name, query))
32
+ self.logger.info(format_log_entry(name, query))
32
33
  end
33
34
  end
34
35
 
@@ -45,14 +46,8 @@ module MongoMapper
45
46
  end
46
47
 
47
48
  def format_log_entry(message, dump = nil)
48
- if false # ActiveRecord::Base.colorize_logging
49
- if @@row_even
50
- @@row_even = false
51
- message_color, dump_color = "4;36;1", "0;1"
52
- else
53
- @@row_even = true
54
- message_color, dump_color = "4;35;1", "0"
55
- end
49
+ if ActiveRecord::Base.colorize_logging
50
+ message_color, dump_color = "4;36;1", "0;1"
56
51
 
57
52
  log_entry = " \e[#{message_color}m#{message}\e[0m "
58
53
  log_entry << "\e[#{dump_color}m%#{String === dump ? 's' : 'p'}\e[0m" % dump if dump
@@ -0,0 +1,236 @@
1
+ module MongoMapper
2
+ module Plugins
3
+ module Querying
4
+ module ClassMethods
5
+ def find(*args)
6
+ options = args.extract_options!
7
+ return nil if args.size == 0
8
+
9
+ if args.first.is_a?(Array) || args.size > 1
10
+ find_some(args, options)
11
+ else
12
+ find_one(options.merge(:_id => args[0]))
13
+ end
14
+ end
15
+
16
+ def find!(*args)
17
+ options = args.extract_options!
18
+ raise DocumentNotFound, "Couldn't find without an ID" if args.size == 0
19
+
20
+ if args.first.is_a?(Array) || args.size > 1
21
+ find_some!(args, options)
22
+ else
23
+ find_one(options.merge(:_id => args[0])) ||
24
+ raise(DocumentNotFound, "Document match #{options.inspect} does not exist
25
+ in #{collection.name} collection")
26
+ end
27
+ end
28
+
29
+ def find_each(options={})
30
+ query(options).query.find().each { |doc| yield load(doc) }
31
+ end
32
+
33
+ def find_by_id(id)
34
+ find_one(:_id => id)
35
+ end
36
+
37
+ def first(options={})
38
+ find_one(options)
39
+ end
40
+
41
+ # All bets are off an actual order if you provide none.
42
+ def last(options={})
43
+ find_one(query(options).reverse.to_hash)
44
+ end
45
+
46
+ def all(options={})
47
+ find_many(options)
48
+ end
49
+
50
+ def count(options={})
51
+ query(options).count
52
+ end
53
+
54
+ def exists?(options={})
55
+ !count(options).zero?
56
+ end
57
+
58
+ def first_or_create(args)
59
+ first(args) || create(args.reject { |key, value| !key?(key) })
60
+ end
61
+
62
+ def first_or_new(args)
63
+ first(args) || new(args.reject { |key, value| !key?(key) })
64
+ end
65
+
66
+ def create(*docs)
67
+ initialize_each(*docs) { |doc| doc.save }
68
+ end
69
+
70
+ def create!(*docs)
71
+ initialize_each(*docs) { |doc| doc.save! }
72
+ end
73
+
74
+ def update(*args)
75
+ if args.length == 1
76
+ update_multiple(args[0])
77
+ else
78
+ id, attributes = args
79
+ update_single(id, attributes)
80
+ end
81
+ end
82
+
83
+ def delete(*ids)
84
+ query(:_id => ids.flatten).query.remove
85
+ end
86
+
87
+ def delete_all(options={})
88
+ query(options).query.remove
89
+ end
90
+
91
+ def destroy(*ids)
92
+ find_some!(ids.flatten).each(&:destroy)
93
+ end
94
+
95
+ def destroy_all(options={})
96
+ find_each(options) { |document| document.destroy }
97
+ end
98
+
99
+ def where(options={})
100
+ query.where(options)
101
+ end
102
+
103
+ def fields(*args)
104
+ query.fields(*args)
105
+ end
106
+
107
+ def limit(*args)
108
+ query.limit(*args)
109
+ end
110
+
111
+ def skip(*args)
112
+ query.skip(*args)
113
+ end
114
+
115
+ def sort(*args)
116
+ query.sort(*args)
117
+ end
118
+
119
+ # @api private for now
120
+ def query(options={})
121
+ Query.new(self).update(options)
122
+ end
123
+
124
+ # @api private for now
125
+ def criteria_hash(criteria={})
126
+ Plucky::CriteriaHash.new(criteria, :object_ids => object_id_keys)
127
+ end
128
+
129
+ # @api private for now
130
+ def options_hash(options={})
131
+ Plucky::OptionsHash.new(options)
132
+ end
133
+
134
+ private
135
+ def find_some(ids, options={})
136
+ query = query(options).update(:_id => ids.flatten.compact.uniq)
137
+ find_many(query.to_hash).compact
138
+ end
139
+
140
+ def find_some!(ids, options={})
141
+ ids = ids.flatten.compact.uniq
142
+ docs = find_some(ids, options)
143
+
144
+ if ids.size != docs.size
145
+ raise DocumentNotFound, "Couldn't find all of the ids (#{ids.to_sentence}). Found #{docs.size}, but was expecting #{ids.size}"
146
+ end
147
+
148
+ docs
149
+ end
150
+
151
+ # All query methods that load documents pass through find_one or find_many
152
+ def find_one(options={})
153
+ query(options).first
154
+ end
155
+
156
+ # All query methods that load documents pass through find_one or find_many
157
+ def find_many(options)
158
+ query(options).all
159
+ end
160
+
161
+ def initialize_each(*docs)
162
+ instances = []
163
+ docs = [{}] if docs.blank?
164
+ docs.flatten.each do |attrs|
165
+ doc = new(attrs)
166
+ yield(doc)
167
+ instances << doc
168
+ end
169
+ instances.size == 1 ? instances[0] : instances
170
+ end
171
+
172
+ def update_single(id, attrs)
173
+ if id.blank? || attrs.blank? || !attrs.is_a?(Hash)
174
+ raise ArgumentError, "Updating a single document requires an id and a hash of attributes"
175
+ end
176
+
177
+ find(id).tap do |doc|
178
+ doc.update_attributes(attrs)
179
+ end
180
+ end
181
+
182
+ def update_multiple(docs)
183
+ unless docs.is_a?(Hash)
184
+ raise ArgumentError, "Updating multiple documents takes 1 argument and it must be hash"
185
+ end
186
+
187
+ instances = []
188
+ docs.each_pair { |id, attrs| instances << update(id, attrs) }
189
+ instances
190
+ end
191
+ end
192
+
193
+ module InstanceMethods
194
+ def save(options={})
195
+ options.assert_valid_keys(:validate, :safe)
196
+ options.reverse_merge!(:validate => true)
197
+ !options[:validate] || valid? ? create_or_update(options) : false
198
+ end
199
+
200
+ def save!(options={})
201
+ options.assert_valid_keys(:safe)
202
+ save(options) || raise(DocumentNotValid.new(self))
203
+ end
204
+
205
+ def destroy
206
+ delete
207
+ end
208
+
209
+ def delete
210
+ @_destroyed = true
211
+ self.class.delete(id) unless new?
212
+ end
213
+
214
+ private
215
+ def create_or_update(options={})
216
+ result = new? ? create(options) : update(options)
217
+ result != false
218
+ end
219
+
220
+ def create(options={})
221
+ save_to_collection(options)
222
+ end
223
+
224
+ def update(options={})
225
+ save_to_collection(options)
226
+ end
227
+
228
+ def save_to_collection(options={})
229
+ safe = options[:safe] || false
230
+ @new = false
231
+ collection.save(to_mongo, :safe => safe)
232
+ end
233
+ end
234
+ end
235
+ end
236
+ end
@@ -1,3 +1,4 @@
1
+ # encoding: UTF-8
1
2
  module MongoMapper
2
3
  module Plugins
3
4
  module Rails
@@ -0,0 +1,31 @@
1
+ module MongoMapper
2
+ module Plugins
3
+ module Sci
4
+ module ClassMethods
5
+ def inherited(subclass)
6
+ key :_type, String unless key?(:_type)
7
+ subclass.instance_variable_set("@single_collection_inherited", true)
8
+ subclass.set_collection_name(collection_name) unless subclass.embeddable?
9
+ super
10
+ end
11
+
12
+ def single_collection_inherited?
13
+ @single_collection_inherited == true
14
+ end
15
+
16
+ def query(options={})
17
+ super.tap do |query|
18
+ query[:_type] = name if single_collection_inherited?
19
+ end
20
+ end
21
+ end
22
+
23
+ module InstanceMethods
24
+ def initialize(*args)
25
+ super
26
+ write_key :_type, self.class.name if self.class.key?(:_type)
27
+ end
28
+ end
29
+ end
30
+ end
31
+ end