mongoid-pre 2.0.0.beta1

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 (246) hide show
  1. data/.gitignore +6 -0
  2. data/.watchr +24 -0
  3. data/MIT_LICENSE +20 -0
  4. data/README.rdoc +49 -0
  5. data/Rakefile +52 -0
  6. data/VERSION +1 -0
  7. data/caliper.yml +4 -0
  8. data/lib/mongoid.rb +135 -0
  9. data/lib/mongoid/associations.rb +263 -0
  10. data/lib/mongoid/associations/belongs_to_related.rb +59 -0
  11. data/lib/mongoid/associations/embedded_in.rb +64 -0
  12. data/lib/mongoid/associations/embeds_many.rb +193 -0
  13. data/lib/mongoid/associations/embeds_one.rb +95 -0
  14. data/lib/mongoid/associations/has_many_related.rb +133 -0
  15. data/lib/mongoid/associations/has_one_related.rb +81 -0
  16. data/lib/mongoid/associations/meta_data.rb +28 -0
  17. data/lib/mongoid/associations/options.rb +52 -0
  18. data/lib/mongoid/associations/proxy.rb +31 -0
  19. data/lib/mongoid/attributes.rb +185 -0
  20. data/lib/mongoid/callbacks.rb +18 -0
  21. data/lib/mongoid/collection.rb +119 -0
  22. data/lib/mongoid/collections/cyclic_iterator.rb +34 -0
  23. data/lib/mongoid/collections/master.rb +28 -0
  24. data/lib/mongoid/collections/mimic.rb +46 -0
  25. data/lib/mongoid/collections/operations.rb +41 -0
  26. data/lib/mongoid/collections/slaves.rb +44 -0
  27. data/lib/mongoid/commands.rb +161 -0
  28. data/lib/mongoid/commands/create.rb +19 -0
  29. data/lib/mongoid/commands/delete.rb +16 -0
  30. data/lib/mongoid/commands/delete_all.rb +25 -0
  31. data/lib/mongoid/commands/deletion.rb +18 -0
  32. data/lib/mongoid/commands/destroy.rb +17 -0
  33. data/lib/mongoid/commands/destroy_all.rb +25 -0
  34. data/lib/mongoid/commands/save.rb +30 -0
  35. data/lib/mongoid/components.rb +31 -0
  36. data/lib/mongoid/config.rb +86 -0
  37. data/lib/mongoid/contexts.rb +25 -0
  38. data/lib/mongoid/contexts/enumerable.rb +151 -0
  39. data/lib/mongoid/contexts/ids.rb +25 -0
  40. data/lib/mongoid/contexts/mongo.rb +285 -0
  41. data/lib/mongoid/contexts/paging.rb +42 -0
  42. data/lib/mongoid/criteria.rb +239 -0
  43. data/lib/mongoid/criterion/complex.rb +21 -0
  44. data/lib/mongoid/criterion/exclusion.rb +65 -0
  45. data/lib/mongoid/criterion/inclusion.rb +93 -0
  46. data/lib/mongoid/criterion/optional.rb +136 -0
  47. data/lib/mongoid/cursor.rb +82 -0
  48. data/lib/mongoid/deprecation.rb +22 -0
  49. data/lib/mongoid/dirty.rb +203 -0
  50. data/lib/mongoid/document.rb +306 -0
  51. data/lib/mongoid/errors.rb +77 -0
  52. data/lib/mongoid/extensions.rb +99 -0
  53. data/lib/mongoid/extensions/array/accessors.rb +17 -0
  54. data/lib/mongoid/extensions/array/aliasing.rb +4 -0
  55. data/lib/mongoid/extensions/array/assimilation.rb +26 -0
  56. data/lib/mongoid/extensions/array/conversions.rb +27 -0
  57. data/lib/mongoid/extensions/array/parentization.rb +13 -0
  58. data/lib/mongoid/extensions/big_decimal/conversions.rb +19 -0
  59. data/lib/mongoid/extensions/binary/conversions.rb +17 -0
  60. data/lib/mongoid/extensions/boolean/conversions.rb +16 -0
  61. data/lib/mongoid/extensions/date/conversions.rb +15 -0
  62. data/lib/mongoid/extensions/datetime/conversions.rb +17 -0
  63. data/lib/mongoid/extensions/float/conversions.rb +16 -0
  64. data/lib/mongoid/extensions/hash/accessors.rb +38 -0
  65. data/lib/mongoid/extensions/hash/assimilation.rb +30 -0
  66. data/lib/mongoid/extensions/hash/conversions.rb +15 -0
  67. data/lib/mongoid/extensions/hash/criteria_helpers.rb +20 -0
  68. data/lib/mongoid/extensions/hash/scoping.rb +12 -0
  69. data/lib/mongoid/extensions/integer/conversions.rb +16 -0
  70. data/lib/mongoid/extensions/nil/assimilation.rb +13 -0
  71. data/lib/mongoid/extensions/object/conversions.rb +27 -0
  72. data/lib/mongoid/extensions/objectid/conversions.rb +15 -0
  73. data/lib/mongoid/extensions/proc/scoping.rb +12 -0
  74. data/lib/mongoid/extensions/string/conversions.rb +15 -0
  75. data/lib/mongoid/extensions/string/inflections.rb +97 -0
  76. data/lib/mongoid/extensions/symbol/inflections.rb +36 -0
  77. data/lib/mongoid/extensions/time/conversions.rb +18 -0
  78. data/lib/mongoid/extras.rb +61 -0
  79. data/lib/mongoid/factory.rb +19 -0
  80. data/lib/mongoid/field.rb +52 -0
  81. data/lib/mongoid/fields.rb +62 -0
  82. data/lib/mongoid/finders.rb +136 -0
  83. data/lib/mongoid/identity.rb +39 -0
  84. data/lib/mongoid/indexes.rb +27 -0
  85. data/lib/mongoid/javascript.rb +21 -0
  86. data/lib/mongoid/javascript/functions.yml +37 -0
  87. data/lib/mongoid/matchers.rb +36 -0
  88. data/lib/mongoid/matchers/all.rb +11 -0
  89. data/lib/mongoid/matchers/default.rb +26 -0
  90. data/lib/mongoid/matchers/exists.rb +13 -0
  91. data/lib/mongoid/matchers/gt.rb +11 -0
  92. data/lib/mongoid/matchers/gte.rb +11 -0
  93. data/lib/mongoid/matchers/in.rb +11 -0
  94. data/lib/mongoid/matchers/lt.rb +11 -0
  95. data/lib/mongoid/matchers/lte.rb +11 -0
  96. data/lib/mongoid/matchers/ne.rb +11 -0
  97. data/lib/mongoid/matchers/nin.rb +11 -0
  98. data/lib/mongoid/matchers/size.rb +11 -0
  99. data/lib/mongoid/memoization.rb +27 -0
  100. data/lib/mongoid/named_scope.rb +42 -0
  101. data/lib/mongoid/observable.rb +30 -0
  102. data/lib/mongoid/paths.rb +54 -0
  103. data/lib/mongoid/persistence.rb +27 -0
  104. data/lib/mongoid/persistence/command.rb +20 -0
  105. data/lib/mongoid/persistence/insert.rb +71 -0
  106. data/lib/mongoid/persistence/update.rb +78 -0
  107. data/lib/mongoid/scope.rb +75 -0
  108. data/lib/mongoid/state.rb +32 -0
  109. data/lib/mongoid/timestamps.rb +27 -0
  110. data/lib/mongoid/validations.rb +51 -0
  111. data/lib/mongoid/validations/associated.rb +32 -0
  112. data/lib/mongoid/validations/locale/en.yml +4 -0
  113. data/lib/mongoid/validations/uniqueness.rb +22 -0
  114. data/lib/mongoid/versioning.rb +26 -0
  115. data/mongoid.gemspec +413 -0
  116. data/perf/benchmark.rb +77 -0
  117. data/spec/integration/mongoid/associations_spec.rb +340 -0
  118. data/spec/integration/mongoid/attributes_spec.rb +22 -0
  119. data/spec/integration/mongoid/commands_spec.rb +230 -0
  120. data/spec/integration/mongoid/contexts/enumerable_spec.rb +33 -0
  121. data/spec/integration/mongoid/criteria_spec.rb +272 -0
  122. data/spec/integration/mongoid/dirty_spec.rb +70 -0
  123. data/spec/integration/mongoid/document_spec.rb +650 -0
  124. data/spec/integration/mongoid/extensions_spec.rb +22 -0
  125. data/spec/integration/mongoid/finders_spec.rb +119 -0
  126. data/spec/integration/mongoid/inheritance_spec.rb +137 -0
  127. data/spec/integration/mongoid/named_scope_spec.rb +46 -0
  128. data/spec/integration/mongoid/persistence/update_spec.rb +46 -0
  129. data/spec/models/address.rb +39 -0
  130. data/spec/models/animal.rb +6 -0
  131. data/spec/models/callbacks.rb +18 -0
  132. data/spec/models/comment.rb +8 -0
  133. data/spec/models/country_code.rb +6 -0
  134. data/spec/models/employer.rb +5 -0
  135. data/spec/models/game.rb +7 -0
  136. data/spec/models/inheritance.rb +56 -0
  137. data/spec/models/location.rb +5 -0
  138. data/spec/models/mixed_drink.rb +4 -0
  139. data/spec/models/name.rb +13 -0
  140. data/spec/models/namespacing.rb +11 -0
  141. data/spec/models/patient.rb +6 -0
  142. data/spec/models/person.rb +99 -0
  143. data/spec/models/pet.rb +7 -0
  144. data/spec/models/pet_owner.rb +6 -0
  145. data/spec/models/phone.rb +7 -0
  146. data/spec/models/post.rb +15 -0
  147. data/spec/models/translation.rb +5 -0
  148. data/spec/models/vet_visit.rb +5 -0
  149. data/spec/spec.opts +3 -0
  150. data/spec/spec_helper.rb +31 -0
  151. data/spec/unit/mongoid/associations/belongs_to_related_spec.rb +145 -0
  152. data/spec/unit/mongoid/associations/embedded_in_spec.rb +193 -0
  153. data/spec/unit/mongoid/associations/embeds_many_spec.rb +516 -0
  154. data/spec/unit/mongoid/associations/embeds_one_spec.rb +282 -0
  155. data/spec/unit/mongoid/associations/has_many_related_spec.rb +418 -0
  156. data/spec/unit/mongoid/associations/has_one_related_spec.rb +179 -0
  157. data/spec/unit/mongoid/associations/meta_data_spec.rb +88 -0
  158. data/spec/unit/mongoid/associations/options_spec.rb +192 -0
  159. data/spec/unit/mongoid/associations_spec.rb +595 -0
  160. data/spec/unit/mongoid/attributes_spec.rb +507 -0
  161. data/spec/unit/mongoid/callbacks_spec.rb +55 -0
  162. data/spec/unit/mongoid/collection_spec.rb +187 -0
  163. data/spec/unit/mongoid/collections/cyclic_iterator_spec.rb +75 -0
  164. data/spec/unit/mongoid/collections/master_spec.rb +41 -0
  165. data/spec/unit/mongoid/collections/mimic_spec.rb +43 -0
  166. data/spec/unit/mongoid/collections/slaves_spec.rb +81 -0
  167. data/spec/unit/mongoid/commands/create_spec.rb +31 -0
  168. data/spec/unit/mongoid/commands/delete_all_spec.rb +59 -0
  169. data/spec/unit/mongoid/commands/delete_spec.rb +38 -0
  170. data/spec/unit/mongoid/commands/destroy_all_spec.rb +21 -0
  171. data/spec/unit/mongoid/commands/destroy_spec.rb +51 -0
  172. data/spec/unit/mongoid/commands/save_spec.rb +107 -0
  173. data/spec/unit/mongoid/commands_spec.rb +270 -0
  174. data/spec/unit/mongoid/config_spec.rb +176 -0
  175. data/spec/unit/mongoid/contexts/enumerable_spec.rb +421 -0
  176. data/spec/unit/mongoid/contexts/mongo_spec.rb +682 -0
  177. data/spec/unit/mongoid/contexts_spec.rb +25 -0
  178. data/spec/unit/mongoid/criteria_spec.rb +824 -0
  179. data/spec/unit/mongoid/criterion/complex_spec.rb +19 -0
  180. data/spec/unit/mongoid/criterion/exclusion_spec.rb +91 -0
  181. data/spec/unit/mongoid/criterion/inclusion_spec.rb +219 -0
  182. data/spec/unit/mongoid/criterion/optional_spec.rb +319 -0
  183. data/spec/unit/mongoid/cursor_spec.rb +74 -0
  184. data/spec/unit/mongoid/deprecation_spec.rb +24 -0
  185. data/spec/unit/mongoid/dirty_spec.rb +286 -0
  186. data/spec/unit/mongoid/document_spec.rb +818 -0
  187. data/spec/unit/mongoid/errors_spec.rb +103 -0
  188. data/spec/unit/mongoid/extensions/array/accessors_spec.rb +50 -0
  189. data/spec/unit/mongoid/extensions/array/assimilation_spec.rb +24 -0
  190. data/spec/unit/mongoid/extensions/array/conversions_spec.rb +35 -0
  191. data/spec/unit/mongoid/extensions/array/parentization_spec.rb +20 -0
  192. data/spec/unit/mongoid/extensions/big_decimal/conversions_spec.rb +22 -0
  193. data/spec/unit/mongoid/extensions/binary/conversions_spec.rb +22 -0
  194. data/spec/unit/mongoid/extensions/boolean/conversions_spec.rb +49 -0
  195. data/spec/unit/mongoid/extensions/date/conversions_spec.rb +102 -0
  196. data/spec/unit/mongoid/extensions/datetime/conversions_spec.rb +67 -0
  197. data/spec/unit/mongoid/extensions/float/conversions_spec.rb +61 -0
  198. data/spec/unit/mongoid/extensions/hash/accessors_spec.rb +184 -0
  199. data/spec/unit/mongoid/extensions/hash/assimilation_spec.rb +46 -0
  200. data/spec/unit/mongoid/extensions/hash/conversions_spec.rb +21 -0
  201. data/spec/unit/mongoid/extensions/hash/criteria_helpers_spec.rb +17 -0
  202. data/spec/unit/mongoid/extensions/hash/scoping_spec.rb +14 -0
  203. data/spec/unit/mongoid/extensions/integer/conversions_spec.rb +61 -0
  204. data/spec/unit/mongoid/extensions/nil/assimilation_spec.rb +24 -0
  205. data/spec/unit/mongoid/extensions/object/conversions_spec.rb +57 -0
  206. data/spec/unit/mongoid/extensions/proc/scoping_spec.rb +34 -0
  207. data/spec/unit/mongoid/extensions/string/conversions_spec.rb +17 -0
  208. data/spec/unit/mongoid/extensions/string/inflections_spec.rb +208 -0
  209. data/spec/unit/mongoid/extensions/symbol/inflections_spec.rb +91 -0
  210. data/spec/unit/mongoid/extensions/time/conversions_spec.rb +70 -0
  211. data/spec/unit/mongoid/extras_spec.rb +102 -0
  212. data/spec/unit/mongoid/factory_spec.rb +31 -0
  213. data/spec/unit/mongoid/field_spec.rb +143 -0
  214. data/spec/unit/mongoid/fields_spec.rb +181 -0
  215. data/spec/unit/mongoid/finders_spec.rb +404 -0
  216. data/spec/unit/mongoid/identity_spec.rb +109 -0
  217. data/spec/unit/mongoid/indexes_spec.rb +93 -0
  218. data/spec/unit/mongoid/javascript_spec.rb +48 -0
  219. data/spec/unit/mongoid/matchers/all_spec.rb +27 -0
  220. data/spec/unit/mongoid/matchers/default_spec.rb +27 -0
  221. data/spec/unit/mongoid/matchers/exists_spec.rb +56 -0
  222. data/spec/unit/mongoid/matchers/gt_spec.rb +39 -0
  223. data/spec/unit/mongoid/matchers/gte_spec.rb +49 -0
  224. data/spec/unit/mongoid/matchers/in_spec.rb +27 -0
  225. data/spec/unit/mongoid/matchers/lt_spec.rb +39 -0
  226. data/spec/unit/mongoid/matchers/lte_spec.rb +49 -0
  227. data/spec/unit/mongoid/matchers/ne_spec.rb +27 -0
  228. data/spec/unit/mongoid/matchers/nin_spec.rb +27 -0
  229. data/spec/unit/mongoid/matchers/size_spec.rb +27 -0
  230. data/spec/unit/mongoid/matchers_spec.rb +329 -0
  231. data/spec/unit/mongoid/memoization_spec.rb +75 -0
  232. data/spec/unit/mongoid/named_scope_spec.rb +123 -0
  233. data/spec/unit/mongoid/observable_spec.rb +46 -0
  234. data/spec/unit/mongoid/paths_spec.rb +124 -0
  235. data/spec/unit/mongoid/persistence/insert_spec.rb +175 -0
  236. data/spec/unit/mongoid/persistence/update_spec.rb +148 -0
  237. data/spec/unit/mongoid/persistence_spec.rb +40 -0
  238. data/spec/unit/mongoid/scope_spec.rb +240 -0
  239. data/spec/unit/mongoid/state_spec.rb +83 -0
  240. data/spec/unit/mongoid/timestamps_spec.rb +25 -0
  241. data/spec/unit/mongoid/validations/associated_spec.rb +103 -0
  242. data/spec/unit/mongoid/validations/uniqueness_spec.rb +47 -0
  243. data/spec/unit/mongoid/validations_spec.rb +190 -0
  244. data/spec/unit/mongoid/versioning_spec.rb +41 -0
  245. data/spec/unit/mongoid_spec.rb +46 -0
  246. metadata +476 -0
@@ -0,0 +1,62 @@
1
+ # encoding: utf-8
2
+ module Mongoid #:nodoc
3
+ module Fields #:nodoc
4
+ extend ActiveSupport::Concern
5
+ included do
6
+ # Set up the class attributes that must be available to all subclasses.
7
+ # These include defaults, fields
8
+ class_inheritable_accessor :fields
9
+
10
+ self.fields = {}
11
+ delegate :defaults, :fields, :to => "self.class"
12
+ end
13
+
14
+ module ClassMethods #:nodoc
15
+ # Defines all the fields that are accessable on the Document
16
+ # For each field that is defined, a getter and setter will be
17
+ # added as an instance method to the Document.
18
+ #
19
+ # Options:
20
+ #
21
+ # name: The name of the field, as a +Symbol+.
22
+ # options: A +Hash+ of options to supply to the +Field+.
23
+ #
24
+ # Example:
25
+ #
26
+ # <tt>field :score, :default => 0</tt>
27
+ def field(name, options = {})
28
+ access = name.to_s
29
+ set_field(access, options)
30
+ end
31
+
32
+ # Returns the default values for the fields on the document
33
+ def defaults
34
+ fields.inject({}) do |defs,(field_name,field)|
35
+ next(defs) if field.default.nil?
36
+ defs[field_name.to_s] = field.default
37
+ defs
38
+ end
39
+ end
40
+
41
+ protected
42
+ # Define a field attribute for the +Document+.
43
+ def set_field(name, options = {})
44
+ meth = options.delete(:as) || name
45
+ fields[name] = Field.new(name, options)
46
+ create_accessors(name, meth, options)
47
+ add_dirty_methods(name)
48
+ end
49
+
50
+ # Create the field accessors.
51
+ def create_accessors(name, meth, options = {})
52
+ define_method(meth) { read_attribute(name) }
53
+ define_method("#{meth}=") { |value| write_attribute(name, value) }
54
+ define_method("#{meth}?") do
55
+ attr = read_attribute(name)
56
+ (options[:type] == Boolean) ? attr == true : attr.present?
57
+ end
58
+ end
59
+
60
+ end
61
+ end
62
+ end
@@ -0,0 +1,136 @@
1
+ # encoding: utf-8
2
+ module Mongoid #:nodoc:
3
+ module Finders #:nodoc:
4
+
5
+ # Delegate to the criteria methods that are natural for creating a new
6
+ # criteria.
7
+ [ :all_in, :any_in, :avg, :excludes, :limit, :max, :min,
8
+ :not_in, :only, :order_by, :skip, :sum, :where ].each do |name|
9
+ define_method(name) do |*args|
10
+ criteria.send(name, *args)
11
+ end
12
+ end
13
+
14
+ # Find +Documents+ given the conditions.
15
+ #
16
+ # Options:
17
+ #
18
+ # args: A +Hash+ with a conditions key and other options
19
+ #
20
+ # <tt>Person.all(:conditions => { :attribute => "value" })</tt>
21
+ def all(*args)
22
+ find(:all, *args)
23
+ end
24
+
25
+ # Returns a count of matching records in the database based on the
26
+ # provided arguments.
27
+ #
28
+ # <tt>Person.count(:first, :conditions => { :attribute => "value" })</tt>
29
+ def count(*args)
30
+ Criteria.translate(self, *args).count
31
+ end
32
+
33
+ # Helper to initialize a new +Criteria+ object for this class.
34
+ #
35
+ # Example:
36
+ #
37
+ # <tt>Person.criteria</tt>
38
+ def criteria
39
+ Criteria.new(self)
40
+ end
41
+
42
+ # Find a +Document+ in several different ways.
43
+ #
44
+ # If a +String+ is provided, it will be assumed that it is a
45
+ # representation of a Mongo::ObjectID and will attempt to find a single
46
+ # +Document+ based on that id. If a +Symbol+ and +Hash+ is provided then
47
+ # it will attempt to find either a single +Document+ or multiples based
48
+ # on the conditions provided and the first parameter.
49
+ #
50
+ # <tt>Person.find(:first, :conditions => { :attribute => "value" })</tt>
51
+ #
52
+ # <tt>Person.find(:all, :conditions => { :attribute => "value" })</tt>
53
+ #
54
+ # <tt>Person.find(Mongo::ObjectID.new.to_s)</tt>
55
+ def find(*args)
56
+ raise Errors::InvalidOptions.new("Calling Document#find with nil is invalid") if args[0].nil?
57
+ type = args.delete_at(0) if args[0].is_a?(Symbol)
58
+ criteria = Criteria.translate(self, *args)
59
+ case type
60
+ when :first then return criteria.one
61
+ when :last then return criteria.last
62
+ else
63
+ return criteria
64
+ end
65
+ end
66
+
67
+ # Find the first +Document+ given the conditions, or creates a new document
68
+ # with the conditions that were supplied
69
+ #
70
+ # Options:
71
+ #
72
+ # args: A +Hash+ of attributes
73
+ #
74
+ # <tt>Person.find_or_create_by(:attribute => "value")</tt>
75
+ def find_or_create_by(attrs = {})
76
+ find_or(:create, attrs)
77
+ end
78
+
79
+ # Find the first +Document+ given the conditions, or instantiates a new document
80
+ # with the conditions that were supplied
81
+ #
82
+ # Options:
83
+ #
84
+ # args: A +Hash+ of attributes
85
+ #
86
+ # <tt>Person.find_or_initialize_by(:attribute => "value")</tt>
87
+ def find_or_initialize_by(attrs = {})
88
+ find_or(:new, attrs)
89
+ end
90
+
91
+ # Find the first +Document+ given the conditions.
92
+ #
93
+ # Options:
94
+ #
95
+ # args: A +Hash+ with a conditions key and other options
96
+ #
97
+ # <tt>Person.first(:conditions => { :attribute => "value" })</tt>
98
+ def first(*args)
99
+ find(:first, *args)
100
+ end
101
+
102
+ # Find the last +Document+ given the conditions.
103
+ #
104
+ # Options:
105
+ #
106
+ # args: A +Hash+ with a conditions key and other options
107
+ #
108
+ # <tt>Person.last(:conditions => { :attribute => "value" })</tt>
109
+ def last(*args)
110
+ find(:last, *args)
111
+ end
112
+
113
+ # Find all documents in paginated fashion given the supplied arguments.
114
+ # If no parameters are passed just default to offset 0 and limit 20.
115
+ #
116
+ # Options:
117
+ #
118
+ # params: A +Hash+ of params to pass to the Criteria API.
119
+ #
120
+ # Example:
121
+ #
122
+ # <tt>Person.paginate(:conditions => { :field => "Test" }, :page => 1,
123
+ # :per_page => 20)</tt>
124
+ #
125
+ # Returns paginated array of docs.
126
+ def paginate(params = {})
127
+ Criteria.translate(self, params).paginate
128
+ end
129
+
130
+ protected
131
+ # Find the first object or create/initialize it.
132
+ def find_or(method, attrs = {})
133
+ first(:conditions => attrs) || send(method, attrs)
134
+ end
135
+ end
136
+ end
@@ -0,0 +1,39 @@
1
+ # encoding: utf-8
2
+ module Mongoid #:nodoc:
3
+ class Identity #:nodoc:
4
+ class << self
5
+ # Create the identity for the +Document+.
6
+ #
7
+ # The id will be set in either in the form of a Mongo
8
+ # +ObjectID+ or a composite key set up by defining a key on the document.
9
+ #
10
+ # The _type will be set to the document's class name.
11
+ def create(doc)
12
+ identify(doc); type(doc); doc
13
+ end
14
+
15
+ protected
16
+ # Return the proper id for the document.
17
+ def generate_id
18
+ id = Mongo::ObjectID.new
19
+ Mongoid.use_object_ids ? id : id.to_s
20
+ end
21
+
22
+ # Set the id for the document.
23
+ def identify(doc)
24
+ doc.id = compose(doc).join(" ").identify if doc.primary_key
25
+ doc.id = generate_id unless doc.id
26
+ end
27
+
28
+ # Set the _type field on the document.
29
+ def type(doc)
30
+ doc._type = doc.class.name if Mongoid.persist_types
31
+ end
32
+
33
+ # Generates the composite key for a document.
34
+ def compose(doc)
35
+ doc.primary_key.collect { |key| doc.attributes[key] }.reject { |val| val.nil? }
36
+ end
37
+ end
38
+ end
39
+ end
@@ -0,0 +1,27 @@
1
+ # encoding: utf-8
2
+ module Mongoid #:nodoc
3
+ module Indexes #:nodoc
4
+ extend ActiveSupport::Concern
5
+ included do
6
+ cattr_accessor :indexed
7
+ self.indexed = false
8
+ end
9
+
10
+ module ClassMethods #:nodoc
11
+ # Add the default indexes to the root document if they do not already
12
+ # exist. Currently this is only _type.
13
+ def add_indexes
14
+ unless indexed
15
+ self._collection.create_index(:_type, false)
16
+ self.indexed = true
17
+ end
18
+ end
19
+
20
+ # Adds an index on the field specified. Options can be :unique => true or
21
+ # :unique => false. It will default to the latter.
22
+ def index(name, options = { :unique => false })
23
+ collection.create_index(name, options[:unique])
24
+ end
25
+ end
26
+ end
27
+ end
@@ -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,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,36 @@
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
+ module Matchers
16
+ # Determines if this document has the attributes to match the supplied
17
+ # MongoDB selector. Used for matching on embedded associations.
18
+ def matches?(selector)
19
+ selector.each_pair do |key, value|
20
+ return false unless matcher(key, value).matches?(value)
21
+ end
22
+ true
23
+ end
24
+
25
+ protected
26
+ # Get the matcher for the supplied key and value. Will determine the class
27
+ # name from the key.
28
+ def matcher(key, value)
29
+ if value.is_a?(Hash)
30
+ name = "Mongoid::Matchers::#{value.keys.first.gsub("$", "").camelize}"
31
+ return name.constantize.new(attributes[key])
32
+ end
33
+ Default.new(attributes[key])
34
+ end
35
+ end
36
+ 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,26 @@
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 == value
12
+ end
13
+
14
+ protected
15
+ # Return the first value in the hash.
16
+ def first(value)
17
+ value.values.first
18
+ end
19
+
20
+ # If object exists then compare, else return false
21
+ def determine(value, operator)
22
+ @attribute ? @attribute.send(operator, first(value)) : false
23
+ end
24
+ end
25
+ end
26
+ 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