stonegao-mongoid 2.0.0.rc.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 (199) hide show
  1. data/LICENSE +20 -0
  2. data/README.rdoc +50 -0
  3. data/Rakefile +51 -0
  4. data/lib/config/locales/bg.yml +44 -0
  5. data/lib/config/locales/de.yml +44 -0
  6. data/lib/config/locales/en.yml +45 -0
  7. data/lib/config/locales/es.yml +44 -0
  8. data/lib/config/locales/fr.yml +45 -0
  9. data/lib/config/locales/hu.yml +47 -0
  10. data/lib/config/locales/it.yml +42 -0
  11. data/lib/config/locales/kr.yml +68 -0
  12. data/lib/config/locales/nl.yml +42 -0
  13. data/lib/config/locales/pl.yml +42 -0
  14. data/lib/config/locales/pt-br.yml +43 -0
  15. data/lib/config/locales/pt.yml +43 -0
  16. data/lib/config/locales/ro.yml +49 -0
  17. data/lib/config/locales/sv.yml +43 -0
  18. data/lib/config/locales/zh-CN.yml +34 -0
  19. data/lib/mongoid/atomicity.rb +111 -0
  20. data/lib/mongoid/attributes.rb +251 -0
  21. data/lib/mongoid/callbacks.rb +13 -0
  22. data/lib/mongoid/collection.rb +137 -0
  23. data/lib/mongoid/collections/cyclic_iterator.rb +34 -0
  24. data/lib/mongoid/collections/master.rb +29 -0
  25. data/lib/mongoid/collections/operations.rb +42 -0
  26. data/lib/mongoid/collections/slaves.rb +45 -0
  27. data/lib/mongoid/collections.rb +70 -0
  28. data/lib/mongoid/components.rb +45 -0
  29. data/lib/mongoid/config/database.rb +167 -0
  30. data/lib/mongoid/config/replset_database.rb +48 -0
  31. data/lib/mongoid/config.rb +343 -0
  32. data/lib/mongoid/contexts/enumerable/sort.rb +43 -0
  33. data/lib/mongoid/contexts/enumerable.rb +226 -0
  34. data/lib/mongoid/contexts/ids.rb +25 -0
  35. data/lib/mongoid/contexts/mongo.rb +345 -0
  36. data/lib/mongoid/contexts/paging.rb +50 -0
  37. data/lib/mongoid/contexts.rb +21 -0
  38. data/lib/mongoid/copyable.rb +44 -0
  39. data/lib/mongoid/criteria.rb +325 -0
  40. data/lib/mongoid/criterion/complex.rb +34 -0
  41. data/lib/mongoid/criterion/creational.rb +34 -0
  42. data/lib/mongoid/criterion/exclusion.rb +67 -0
  43. data/lib/mongoid/criterion/inclusion.rb +134 -0
  44. data/lib/mongoid/criterion/inspection.rb +20 -0
  45. data/lib/mongoid/criterion/optional.rb +213 -0
  46. data/lib/mongoid/criterion/selector.rb +74 -0
  47. data/lib/mongoid/cursor.rb +81 -0
  48. data/lib/mongoid/default_scope.rb +28 -0
  49. data/lib/mongoid/dirty.rb +251 -0
  50. data/lib/mongoid/document.rb +256 -0
  51. data/lib/mongoid/errors/document_not_found.rb +29 -0
  52. data/lib/mongoid/errors/invalid_collection.rb +19 -0
  53. data/lib/mongoid/errors/invalid_database.rb +20 -0
  54. data/lib/mongoid/errors/invalid_field.rb +19 -0
  55. data/lib/mongoid/errors/invalid_options.rb +16 -0
  56. data/lib/mongoid/errors/invalid_type.rb +26 -0
  57. data/lib/mongoid/errors/mongoid_error.rb +27 -0
  58. data/lib/mongoid/errors/too_many_nested_attribute_records.rb +21 -0
  59. data/lib/mongoid/errors/unsaved_document.rb +23 -0
  60. data/lib/mongoid/errors/unsupported_version.rb +21 -0
  61. data/lib/mongoid/errors/validations.rb +24 -0
  62. data/lib/mongoid/errors.rb +12 -0
  63. data/lib/mongoid/extensions/array/conversions.rb +23 -0
  64. data/lib/mongoid/extensions/array/parentization.rb +13 -0
  65. data/lib/mongoid/extensions/big_decimal/conversions.rb +19 -0
  66. data/lib/mongoid/extensions/binary/conversions.rb +17 -0
  67. data/lib/mongoid/extensions/boolean/conversions.rb +27 -0
  68. data/lib/mongoid/extensions/date/conversions.rb +25 -0
  69. data/lib/mongoid/extensions/datetime/conversions.rb +12 -0
  70. data/lib/mongoid/extensions/false_class/equality.rb +13 -0
  71. data/lib/mongoid/extensions/float/conversions.rb +20 -0
  72. data/lib/mongoid/extensions/hash/conversions.rb +19 -0
  73. data/lib/mongoid/extensions/hash/criteria_helpers.rb +22 -0
  74. data/lib/mongoid/extensions/hash/scoping.rb +12 -0
  75. data/lib/mongoid/extensions/integer/conversions.rb +20 -0
  76. data/lib/mongoid/extensions/nil/collectionization.rb +12 -0
  77. data/lib/mongoid/extensions/object/conversions.rb +25 -0
  78. data/lib/mongoid/extensions/object/reflections.rb +17 -0
  79. data/lib/mongoid/extensions/object/yoda.rb +27 -0
  80. data/lib/mongoid/extensions/object_id/conversions.rb +57 -0
  81. data/lib/mongoid/extensions/proc/scoping.rb +12 -0
  82. data/lib/mongoid/extensions/set/conversions.rb +20 -0
  83. data/lib/mongoid/extensions/string/conversions.rb +34 -0
  84. data/lib/mongoid/extensions/string/inflections.rb +97 -0
  85. data/lib/mongoid/extensions/symbol/conversions.rb +21 -0
  86. data/lib/mongoid/extensions/symbol/inflections.rb +40 -0
  87. data/lib/mongoid/extensions/time_conversions.rb +38 -0
  88. data/lib/mongoid/extensions/true_class/equality.rb +13 -0
  89. data/lib/mongoid/extensions.rb +116 -0
  90. data/lib/mongoid/extras.rb +61 -0
  91. data/lib/mongoid/factory.rb +20 -0
  92. data/lib/mongoid/field.rb +95 -0
  93. data/lib/mongoid/fields.rb +138 -0
  94. data/lib/mongoid/finders.rb +173 -0
  95. data/lib/mongoid/hierarchy.rb +85 -0
  96. data/lib/mongoid/identity.rb +89 -0
  97. data/lib/mongoid/indexes.rb +38 -0
  98. data/lib/mongoid/inspection.rb +58 -0
  99. data/lib/mongoid/javascript/functions.yml +37 -0
  100. data/lib/mongoid/javascript.rb +21 -0
  101. data/lib/mongoid/json.rb +16 -0
  102. data/lib/mongoid/keys.rb +77 -0
  103. data/lib/mongoid/logger.rb +18 -0
  104. data/lib/mongoid/matchers/all.rb +11 -0
  105. data/lib/mongoid/matchers/default.rb +27 -0
  106. data/lib/mongoid/matchers/exists.rb +13 -0
  107. data/lib/mongoid/matchers/gt.rb +11 -0
  108. data/lib/mongoid/matchers/gte.rb +11 -0
  109. data/lib/mongoid/matchers/in.rb +11 -0
  110. data/lib/mongoid/matchers/lt.rb +11 -0
  111. data/lib/mongoid/matchers/lte.rb +11 -0
  112. data/lib/mongoid/matchers/ne.rb +11 -0
  113. data/lib/mongoid/matchers/nin.rb +11 -0
  114. data/lib/mongoid/matchers/size.rb +11 -0
  115. data/lib/mongoid/matchers.rb +55 -0
  116. data/lib/mongoid/modifiers/command.rb +18 -0
  117. data/lib/mongoid/modifiers/inc.rb +24 -0
  118. data/lib/mongoid/modifiers.rb +24 -0
  119. data/lib/mongoid/multi_database.rb +11 -0
  120. data/lib/mongoid/multi_parameter_attributes.rb +80 -0
  121. data/lib/mongoid/named_scope.rb +36 -0
  122. data/lib/mongoid/nested_attributes.rb +43 -0
  123. data/lib/mongoid/paranoia.rb +103 -0
  124. data/lib/mongoid/paths.rb +61 -0
  125. data/lib/mongoid/persistence/command.rb +59 -0
  126. data/lib/mongoid/persistence/insert.rb +53 -0
  127. data/lib/mongoid/persistence/insert_embedded.rb +42 -0
  128. data/lib/mongoid/persistence/remove.rb +44 -0
  129. data/lib/mongoid/persistence/remove_all.rb +40 -0
  130. data/lib/mongoid/persistence/remove_embedded.rb +48 -0
  131. data/lib/mongoid/persistence/update.rb +76 -0
  132. data/lib/mongoid/persistence.rb +237 -0
  133. data/lib/mongoid/railtie.rb +129 -0
  134. data/lib/mongoid/railties/database.rake +171 -0
  135. data/lib/mongoid/railties/document.rb +12 -0
  136. data/lib/mongoid/relations/accessors.rb +157 -0
  137. data/lib/mongoid/relations/auto_save.rb +34 -0
  138. data/lib/mongoid/relations/binding.rb +26 -0
  139. data/lib/mongoid/relations/bindings/embedded/in.rb +82 -0
  140. data/lib/mongoid/relations/bindings/embedded/many.rb +98 -0
  141. data/lib/mongoid/relations/bindings/embedded/one.rb +66 -0
  142. data/lib/mongoid/relations/bindings/referenced/in.rb +74 -0
  143. data/lib/mongoid/relations/bindings/referenced/many.rb +96 -0
  144. data/lib/mongoid/relations/bindings/referenced/many_to_many.rb +99 -0
  145. data/lib/mongoid/relations/bindings/referenced/one.rb +66 -0
  146. data/lib/mongoid/relations/bindings.rb +9 -0
  147. data/lib/mongoid/relations/builder.rb +42 -0
  148. data/lib/mongoid/relations/builders/embedded/in.rb +25 -0
  149. data/lib/mongoid/relations/builders/embedded/many.rb +32 -0
  150. data/lib/mongoid/relations/builders/embedded/one.rb +26 -0
  151. data/lib/mongoid/relations/builders/nested_attributes/many.rb +116 -0
  152. data/lib/mongoid/relations/builders/nested_attributes/one.rb +135 -0
  153. data/lib/mongoid/relations/builders/referenced/in.rb +32 -0
  154. data/lib/mongoid/relations/builders/referenced/many.rb +26 -0
  155. data/lib/mongoid/relations/builders/referenced/many_to_many.rb +29 -0
  156. data/lib/mongoid/relations/builders/referenced/one.rb +30 -0
  157. data/lib/mongoid/relations/builders.rb +79 -0
  158. data/lib/mongoid/relations/cascading/delete.rb +19 -0
  159. data/lib/mongoid/relations/cascading/destroy.rb +19 -0
  160. data/lib/mongoid/relations/cascading/nullify.rb +18 -0
  161. data/lib/mongoid/relations/cascading/strategy.rb +26 -0
  162. data/lib/mongoid/relations/cascading.rb +55 -0
  163. data/lib/mongoid/relations/constraint.rb +45 -0
  164. data/lib/mongoid/relations/cyclic.rb +97 -0
  165. data/lib/mongoid/relations/embedded/in.rb +173 -0
  166. data/lib/mongoid/relations/embedded/many.rb +483 -0
  167. data/lib/mongoid/relations/embedded/one.rb +170 -0
  168. data/lib/mongoid/relations/macros.rb +306 -0
  169. data/lib/mongoid/relations/many.rb +171 -0
  170. data/lib/mongoid/relations/metadata.rb +533 -0
  171. data/lib/mongoid/relations/nested_builder.rb +68 -0
  172. data/lib/mongoid/relations/one.rb +47 -0
  173. data/lib/mongoid/relations/polymorphic.rb +54 -0
  174. data/lib/mongoid/relations/proxy.rb +128 -0
  175. data/lib/mongoid/relations/referenced/in.rb +216 -0
  176. data/lib/mongoid/relations/referenced/many.rb +443 -0
  177. data/lib/mongoid/relations/referenced/many_to_many.rb +344 -0
  178. data/lib/mongoid/relations/referenced/one.rb +206 -0
  179. data/lib/mongoid/relations/reflections.rb +45 -0
  180. data/lib/mongoid/relations.rb +105 -0
  181. data/lib/mongoid/safe.rb +23 -0
  182. data/lib/mongoid/safety.rb +207 -0
  183. data/lib/mongoid/scope.rb +31 -0
  184. data/lib/mongoid/serialization.rb +99 -0
  185. data/lib/mongoid/state.rb +66 -0
  186. data/lib/mongoid/timestamps.rb +38 -0
  187. data/lib/mongoid/validations/associated.rb +42 -0
  188. data/lib/mongoid/validations/uniqueness.rb +85 -0
  189. data/lib/mongoid/validations.rb +117 -0
  190. data/lib/mongoid/version.rb +4 -0
  191. data/lib/mongoid/versioning.rb +51 -0
  192. data/lib/mongoid.rb +139 -0
  193. data/lib/rails/generators/mongoid/config/config_generator.rb +25 -0
  194. data/lib/rails/generators/mongoid/config/templates/mongoid.yml +23 -0
  195. data/lib/rails/generators/mongoid/model/model_generator.rb +24 -0
  196. data/lib/rails/generators/mongoid/model/templates/model.rb +17 -0
  197. data/lib/rails/generators/mongoid_generator.rb +61 -0
  198. data/lib/rails/mongoid.rb +57 -0
  199. metadata +380 -0
@@ -0,0 +1,58 @@
1
+ # encoding: utf-8
2
+ module Mongoid #:nodoc
3
+ module Inspection #:nodoc
4
+
5
+ # Returns the class name plus its attributes. If using dynamic fields will
6
+ # include those as well.
7
+ #
8
+ # Example:
9
+ #
10
+ # <tt>person.inspect</tt>
11
+ #
12
+ # Returns:
13
+ #
14
+ # A nice pretty string to look at.
15
+ def inspect
16
+ inspection = []
17
+ inspection.concat(inspect_fields).concat(inspect_dynamic_fields)
18
+ "#<#{self.class.name} _id: #{id}, #{inspection * ', '}>"
19
+ end
20
+
21
+ private
22
+
23
+ # Get an array of inspected fields for the document.
24
+ #
25
+ # Example:
26
+ #
27
+ # <tt>inspect_fields</tt>
28
+ #
29
+ # Returns:
30
+ #
31
+ # An array of pretty printed field values.
32
+ def inspect_fields
33
+ fields.map do |name, field|
34
+ "#{name}: #{@attributes[name].inspect}"
35
+ end
36
+ end
37
+
38
+ # Get an array of inspected dynamic fields for the document.
39
+ #
40
+ # Example:
41
+ #
42
+ # <tt>inspect_dynamic_fields</tt>
43
+ #
44
+ # Returns:
45
+ #
46
+ # An array of pretty printed dynamic field values.
47
+ def inspect_dynamic_fields
48
+ if Mongoid.allow_dynamic_fields
49
+ keys = @attributes.keys - fields.keys - relations.keys - ["_id", "_type"]
50
+ return keys.map do |name|
51
+ "#{name}: #{@attributes[name].inspect}"
52
+ end
53
+ else
54
+ []
55
+ end
56
+ end
57
+ end
58
+ end
@@ -0,0 +1,37 @@
1
+ aggregate:
2
+ "function(obj, prev) {
3
+ prev.count++;
4
+ }"
5
+
6
+ group:
7
+ "function(obj, prev) {
8
+ prev.group.push(obj);
9
+ }"
10
+
11
+ max:
12
+ "function(obj, prev) {
13
+ if (prev.max == 'start') {
14
+ prev.max = obj.[field];
15
+ }
16
+ if (prev.max < obj.[field]) {
17
+ prev.max = obj.[field];
18
+ }
19
+ }"
20
+
21
+ min:
22
+ "function(obj, prev) {
23
+ if (prev.min == 'start') {
24
+ prev.min = obj.[field];
25
+ }
26
+ if (prev.min > obj.[field]) {
27
+ prev.min = obj.[field];
28
+ }
29
+ }"
30
+
31
+ sum:
32
+ "function(obj, prev) {
33
+ if (prev.sum == 'start') {
34
+ prev.sum = 0;
35
+ }
36
+ prev.sum += obj.[field];
37
+ }"
@@ -0,0 +1,21 @@
1
+ # encoding: utf-8
2
+ module Mongoid #:nodoc:
3
+ class Javascript
4
+ # Constant for the file that defines all the js functions.
5
+ FUNCTIONS = File.join(File.dirname(__FILE__), "javascript", "functions.yml")
6
+
7
+ # Load the javascript functions and define a class method for each one,
8
+ # that memoizes the value.
9
+ #
10
+ # Example:
11
+ #
12
+ # <tt>Mongoid::Javascript.aggregate</tt>
13
+ YAML.load(File.read(FUNCTIONS)).each_pair do |key, function|
14
+ (class << self; self; end).class_eval <<-EOT
15
+ def #{key}
16
+ @#{key} ||= "#{function}"
17
+ end
18
+ EOT
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,16 @@
1
+ # encoding: utf-8
2
+ module Mongoid #:nodoc:
3
+ # This module is for hooking in to +ActiveModel+s serialization to let
4
+ # configuring the ability to include the root in JSON happen from the Mongoid
5
+ # config.
6
+ module JSON
7
+ extend ActiveSupport::Concern
8
+
9
+ # We need to redefine where the JSON configuration is getting defined,
10
+ # similar to +ActiveRecord+.
11
+ included do
12
+ undef_method :include_root_in_json
13
+ delegate :include_root_in_json, :to => ::Mongoid
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,77 @@
1
+ # encoding: utf-8
2
+ module Mongoid #:nodoc:
3
+ module Keys
4
+ extend ActiveSupport::Concern
5
+ included do
6
+ cattr_accessor :primary_key, :_identity
7
+ self._identity = { :type => BSON::ObjectId }
8
+
9
+ delegate \
10
+ :_id_type,
11
+ :primary_key,
12
+ :using_object_ids?, :to => "self.class"
13
+ end
14
+
15
+ module ClassMethods #:nodoc:
16
+
17
+ # Convenience method for returning the type of the id for this class.
18
+ #
19
+ # Example:
20
+ #
21
+ # <tt>Person._id_type</tt>
22
+ #
23
+ # Returns:
24
+ #
25
+ # The type of the id.
26
+ def _id_type
27
+ _identity[:type]
28
+ end
29
+
30
+ # Used for telling Mongoid on a per model basis whether to override the
31
+ # default +BSON::ObjectId+ and use a different type. This will be
32
+ # expanded in the future for requiring a PkFactory if the type is not a
33
+ # +BSON::ObjectId+ or +String+.
34
+ #
35
+ # Example:
36
+ #
37
+ # class Person
38
+ # include Mongoid::Document
39
+ # identity :type => String
40
+ # end
41
+ def identity(options = {})
42
+ self._identity = options
43
+ end
44
+
45
+ # Defines the field that will be used for the id of this +Document+. This
46
+ # set the id of this +Document+ before save to a parameterized version of
47
+ # the field that was supplied. This is good for use for readable URLS in
48
+ # web applications.
49
+ #
50
+ # Example:
51
+ #
52
+ # class Person
53
+ # include Mongoid::Document
54
+ # key :first_name, :last_name
55
+ # end
56
+ def key(*fields)
57
+ self.primary_key = fields
58
+ identity(:type => String)
59
+ set_callback :save, :before, :identify
60
+ end
61
+
62
+ # Convenience method for determining if we are using +BSON::ObjectIds+ as
63
+ # our id.
64
+ #
65
+ # Example:
66
+ #
67
+ # <tt>person.using_object_ids?</tt>
68
+ #
69
+ # Returns:
70
+ #
71
+ # true if we are using BSON::ObjectIds
72
+ def using_object_ids?
73
+ _id_type == BSON::ObjectId
74
+ end
75
+ end
76
+ end
77
+ end
@@ -0,0 +1,18 @@
1
+ module Mongoid
2
+ class Logger
3
+
4
+ delegate :info, :debug, :error, :fatal, :unknown, :to => :logger, :allow_nil => true
5
+
6
+ def warn(message)
7
+ logger.warn(message) if logger && logger.respond_to?(:warn)
8
+ end
9
+
10
+ def logger
11
+ Mongoid.logger
12
+ end
13
+
14
+ def inspect
15
+ "#<Mongoid::Logger:0x#{object_id.to_s(16)} @logger=#{logger.inspect}>"
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,11 @@
1
+ # encoding: utf-8
2
+ module Mongoid #:nodoc:
3
+ module Matchers #:nodoc:
4
+ class All < Default
5
+ # Return true if the attribute and first value in the hash are equal.
6
+ def matches?(value)
7
+ @attribute == value.values.first
8
+ end
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,27 @@
1
+ # encoding: utf-8
2
+ module Mongoid #:nodoc:
3
+ module Matchers #:nodoc:
4
+ class Default
5
+ # Creating a new matcher only requires the value.
6
+ def initialize(attribute)
7
+ @attribute = attribute
8
+ end
9
+ # Return true if the attribute and value are equal.
10
+ def matches?(value)
11
+ @attribute.is_a?(Array) && value.is_a?(String) ?
12
+ @attribute.include?(value) : value === @attribute
13
+ end
14
+
15
+ protected
16
+ # Return the first value in the hash.
17
+ def first(value)
18
+ value.values.first
19
+ end
20
+
21
+ # If object exists then compare, else return false
22
+ def determine(value, operator)
23
+ @attribute ? @attribute.send(operator, first(value)) : false
24
+ end
25
+ end
26
+ end
27
+ end
@@ -0,0 +1,13 @@
1
+ # encoding: utf-8
2
+ module Mongoid #:nodoc:
3
+ module Matchers #:nodoc:
4
+ class Exists < Default
5
+ # Return true if the attribute exists and checking for existence or
6
+ # return true if the attribute does not exist and checking for
7
+ # non-existence.
8
+ def matches?(value)
9
+ @attribute.nil? != value.values.first
10
+ end
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,11 @@
1
+ # encoding: utf-8
2
+ module Mongoid #:nodoc:
3
+ module Matchers #:nodoc:
4
+ class Gt < Default
5
+ # Return true if the attribute is greater 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 Gte < Default
5
+ # Return true if the attribute is greater 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 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
@@ -0,0 +1,55 @@
1
+ # encoding: utf-8
2
+ require "mongoid/matchers/default"
3
+ require "mongoid/matchers/all"
4
+ require "mongoid/matchers/exists"
5
+ require "mongoid/matchers/gt"
6
+ require "mongoid/matchers/gte"
7
+ require "mongoid/matchers/in"
8
+ require "mongoid/matchers/lt"
9
+ require "mongoid/matchers/lte"
10
+ require "mongoid/matchers/ne"
11
+ require "mongoid/matchers/nin"
12
+ require "mongoid/matchers/size"
13
+
14
+ module Mongoid #:nodoc:
15
+
16
+ # This module contains all the behavior for ruby implementations of MongoDB
17
+ # selectors.
18
+ module Matchers
19
+
20
+ # Determines if this document has the attributes to match the supplied
21
+ # MongoDB selector. Used for matching on embedded associations.
22
+ #
23
+ # @example Does the document match?
24
+ # document.matches?(:title => { "$in" => [ "test" ] })
25
+ #
26
+ # @param [ Hash ] selector The MongoDB selector.
27
+ #
28
+ # @return [ true, false ] True if matches, false if not.
29
+ def matches?(selector)
30
+ selector.each_pair do |key, value|
31
+ return false unless matcher(key, value).matches?(value)
32
+ end; true
33
+ end
34
+
35
+ protected
36
+
37
+ # Get the matcher for the supplied key and value. Will determine the class
38
+ # name from the key.
39
+ #
40
+ # @example Get the matcher.
41
+ # document.matcher(:title, { "$in" => [ "test" ] })
42
+ #
43
+ # @param [ Symbol, String ] key The field name.
44
+ # @param [ Object, Hash ] The value or selector.
45
+ #
46
+ # @return [ Matcher ] The matcher.
47
+ def matcher(key, value)
48
+ if value.is_a?(Hash)
49
+ name = "Mongoid::Matchers::#{value.keys.first.gsub("$", "").camelize}"
50
+ return name.constantize.new(attributes[key])
51
+ end
52
+ Default.new(attributes[key])
53
+ end
54
+ end
55
+ end
@@ -0,0 +1,18 @@
1
+ # encoding: utf-8
2
+ module Mongoid #:nodoc:
3
+ module Modifiers #:nodoc:
4
+ class Command #:nodoc:
5
+ include Mongoid::Safe
6
+
7
+ # Instantiate the new $inc modifier.
8
+ #
9
+ # Options:
10
+ #
11
+ # klass: The class to get the collection from.
12
+ # options: The options to get passed through to the driver.
13
+ def initialize(document, options = {})
14
+ @document, @options = document, options
15
+ end
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,24 @@
1
+ # encoding: utf-8
2
+ module Mongoid #:nodoc:
3
+ module Modifiers #:nodoc:
4
+ class Inc < Command #:nodoc:
5
+
6
+ # Execute the persistence operation. This will increment the provided
7
+ # field by the supplied value. If no field exists, it will be created and
8
+ # set to the value provided.
9
+ #
10
+ # Options:
11
+ #
12
+ # field: The field to increment.
13
+ # value: The number to increment by.
14
+ def persist(field, value)
15
+ @document.collection.update(
16
+ @document._selector,
17
+ { "$inc" => { field => value } },
18
+ :safe => safe_mode?(@options),
19
+ :multi => false
20
+ )
21
+ end
22
+ end
23
+ end
24
+ end
@@ -0,0 +1,24 @@
1
+ # encoding: utf-8
2
+ require "mongoid/modifiers/command"
3
+ require "mongoid/modifiers/inc"
4
+
5
+ module Mongoid #:nodoc:
6
+ module Modifiers #:nodoc:
7
+ extend ActiveSupport::Concern
8
+
9
+ # Increment the field by the provided value, else if it doesn't exists set
10
+ # it to that value.
11
+ #
12
+ # Options:
13
+ #
14
+ # field: The field to increment.
15
+ # value: The value to increment by.
16
+ # options: Options to pass through to the driver.
17
+ def inc(field, value, options = {})
18
+ current = send(field)
19
+ write_attribute(field, (current ? (current + value) : value))
20
+ Inc.new(self, options).persist(field, value)
21
+ current + value
22
+ end
23
+ end
24
+ end
@@ -0,0 +1,11 @@
1
+ module Mongoid::MultiDatabase
2
+ extend ActiveSupport::Concern
3
+
4
+ module ClassMethods
5
+
6
+ def database; @database end
7
+ def set_database(name)
8
+ @database = name.to_s
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,80 @@
1
+ # encoding: utf-8
2
+ module Mongoid #:nodoc:
3
+ module MultiParameterAttributes
4
+ module Errors
5
+ # Raised when an error occurred while doing a mass assignment to an attribute through the
6
+ # <tt>attributes=</tt> method. The exception has an +attribute+ property that is the name of the
7
+ # offending attribute.
8
+ class AttributeAssignmentError < Mongoid::Errors::MongoidError
9
+ attr_reader :exception, :attribute
10
+ def initialize(message, exception, attribute)
11
+ @exception = exception
12
+ @attribute = attribute
13
+ @message = message
14
+ end
15
+ end
16
+
17
+ # Raised when there are multiple errors while doing a mass assignment through the +attributes+
18
+ # method. The exception has an +errors+ property that contains an array of AttributeAssignmentError
19
+ # objects, each corresponding to the error while assigning to an attribute.
20
+ class MultiparameterAssignmentErrors < Mongoid::Errors::MongoidError
21
+ attr_reader :errors
22
+ def initialize(errors)
23
+ @errors = errors
24
+ end
25
+ end
26
+ end
27
+
28
+ def process(attrs = nil)
29
+ if attrs
30
+ errors = []
31
+ attributes = {}
32
+ multi_parameter_attributes = {}
33
+
34
+ attrs.each_pair do |key, value|
35
+ if key =~ /^([^\(]+)\((\d+)([if])\)$/
36
+ key, index = $1, $2.to_i
37
+ (multi_parameter_attributes[key] ||= {})[index] = value.empty? ? nil : value.send("to_#{$3}")
38
+ else
39
+ attributes[key] = value
40
+ end
41
+ end
42
+
43
+ multi_parameter_attributes.each_pair do |key, values|
44
+ begin
45
+ values = (values.keys.min..values.keys.max).map { |i| values[i] }
46
+ klass = self.class.fields[key].try(:type)
47
+ attributes[key] = instantiate_object(klass, values)
48
+ rescue => e
49
+ errors << Errors::AttributeAssignmentError.new("error on assignment #{values.inspect} to #{key}", e, key)
50
+ end
51
+ end
52
+
53
+ unless errors.empty?
54
+ raise Errors::MultiparameterAssignmentErrors.new(errors), "#{errors.size} error(s) on assignment of multiparameter attributes"
55
+ end
56
+
57
+ super attributes
58
+ else
59
+ super
60
+ end
61
+ end
62
+
63
+ protected
64
+
65
+ def instantiate_object(klass, values_with_empty_parameters)
66
+ return nil if values_with_empty_parameters.all? { |v| v.nil? }
67
+
68
+ values = values_with_empty_parameters.collect { |v| v.nil? ? 1 : v }
69
+
70
+ if klass == DateTime || klass == Date || klass == Time
71
+ klass.send(:convert_to_time, values)
72
+ elsif klass
73
+ klass.new *values
74
+ else
75
+ values
76
+ end
77
+ end
78
+
79
+ end
80
+ end
@@ -0,0 +1,36 @@
1
+ # encoding: utf-8
2
+ module Mongoid #:nodoc:
3
+ module NamedScope
4
+ # Creates a named_scope for the +Document+, similar to ActiveRecord's
5
+ # named_scopes. +NamedScopes+ are proxied +Criteria+ objects that can be
6
+ # chained.
7
+ #
8
+ # Example:
9
+ #
10
+ # class Person
11
+ # include Mongoid::Document
12
+ # field :active, :type => Boolean
13
+ # field :count, :type => Integer
14
+ #
15
+ # named_scope :active, :where => { :active => true }
16
+ # named_scope :count_gt_one, :where => { :count.gt => 1 }
17
+ # named_scope :at_least_count, lambda { |count| { :where => { :count.gt => count } } }
18
+ # end
19
+ def named_scope(name, conditions = {}, &block)
20
+ name = name.to_sym
21
+ scopes[name] = Scope.new(conditions, &block)
22
+ (class << self; self; end).class_eval <<-EOT
23
+ def #{name}(*args)
24
+ scope = scopes[:#{name}]
25
+ scope.extend(criteria.fuse(scope.conditions.scoped(*args)))
26
+ end
27
+ EOT
28
+ end
29
+ alias :scope :named_scope
30
+
31
+ # Return the scopes or default to an empty +Hash+.
32
+ def scopes
33
+ read_inheritable_attribute(:scopes) || write_inheritable_attribute(:scopes, {})
34
+ end
35
+ end
36
+ end
@@ -0,0 +1,43 @@
1
+ # encoding: utf-8
2
+ module Mongoid #:nodoc:
3
+ module NestedAttributes
4
+ extend ActiveSupport::Concern
5
+
6
+ module ClassMethods
7
+ REJECT_ALL_BLANK_PROC = proc { |attributes| attributes.all? { |_, value| value.blank? } }
8
+
9
+ # Used when needing to update related models from a parent relation. Can
10
+ # be used on embedded or referenced relations.
11
+ #
12
+ # @example Defining nested attributes.
13
+ #
14
+ # class Person
15
+ # include Mongoid::Document
16
+ #
17
+ # embeds_many :addresses
18
+ # embeds_one :game
19
+ # references_many :posts
20
+ #
21
+ # accepts_nested_attributes_for :addresses, :game, :posts
22
+ # end
23
+ #
24
+ # @param [ Array<Symbol>, Hash ] *args A list of relation names, followed
25
+ # by a hash of options.
26
+ #
27
+ # @option *args [ true, false ] :allow_destroy Can deletion occur?
28
+ # @option *args [ Proc ] :reject_if Block to reject documents with.
29
+ # @option *args [ Integer ] :limit The max number to create.
30
+ # @option *args [ true, false ] :update_only Only update existing docs.
31
+ def accepts_nested_attributes_for(*args)
32
+ options = args.extract_options!
33
+ options[:reject_if] = REJECT_ALL_BLANK_PROC if options[:reject_if] == :all_blank
34
+ args.each do |name|
35
+ define_method("#{name}_attributes=") do |attrs|
36
+ relation = relations[name.to_s]
37
+ relation.nested_builder(attrs, options).build(self)
38
+ end
39
+ end
40
+ end
41
+ end
42
+ end
43
+ end