pwnash-mongo_mapper 0.7.5 → 0.7.6

Sign up to get free protection for your applications and to get access to all the features.
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