mongoid-locomotive 2.0.0.beta9

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 (274) hide show
  1. data/MIT_LICENSE +20 -0
  2. data/README.rdoc +47 -0
  3. data/lib/mongoid.rb +141 -0
  4. data/lib/mongoid/associations.rb +306 -0
  5. data/lib/mongoid/associations/embedded_in.rb +74 -0
  6. data/lib/mongoid/associations/embeds_many.rb +280 -0
  7. data/lib/mongoid/associations/embeds_one.rb +97 -0
  8. data/lib/mongoid/associations/foreign_key.rb +35 -0
  9. data/lib/mongoid/associations/meta_data.rb +38 -0
  10. data/lib/mongoid/associations/options.rb +62 -0
  11. data/lib/mongoid/associations/proxy.rb +33 -0
  12. data/lib/mongoid/associations/referenced_in.rb +59 -0
  13. data/lib/mongoid/associations/references_many.rb +245 -0
  14. data/lib/mongoid/associations/references_many_as_array.rb +78 -0
  15. data/lib/mongoid/associations/references_one.rb +99 -0
  16. data/lib/mongoid/atomicity.rb +55 -0
  17. data/lib/mongoid/attributes.rb +242 -0
  18. data/lib/mongoid/callbacks.rb +21 -0
  19. data/lib/mongoid/collection.rb +120 -0
  20. data/lib/mongoid/collections.rb +71 -0
  21. data/lib/mongoid/collections/cyclic_iterator.rb +34 -0
  22. data/lib/mongoid/collections/master.rb +29 -0
  23. data/lib/mongoid/collections/operations.rb +41 -0
  24. data/lib/mongoid/collections/slaves.rb +45 -0
  25. data/lib/mongoid/components.rb +34 -0
  26. data/lib/mongoid/config.rb +263 -0
  27. data/lib/mongoid/contexts.rb +24 -0
  28. data/lib/mongoid/contexts/enumerable.rb +156 -0
  29. data/lib/mongoid/contexts/ids.rb +25 -0
  30. data/lib/mongoid/contexts/mongo.rb +285 -0
  31. data/lib/mongoid/contexts/paging.rb +50 -0
  32. data/lib/mongoid/criteria.rb +248 -0
  33. data/lib/mongoid/criterion/complex.rb +21 -0
  34. data/lib/mongoid/criterion/exclusion.rb +65 -0
  35. data/lib/mongoid/criterion/inclusion.rb +110 -0
  36. data/lib/mongoid/criterion/optional.rb +189 -0
  37. data/lib/mongoid/cursor.rb +81 -0
  38. data/lib/mongoid/deprecation.rb +21 -0
  39. data/lib/mongoid/dirty.rb +252 -0
  40. data/lib/mongoid/document.rb +210 -0
  41. data/lib/mongoid/errors.rb +131 -0
  42. data/lib/mongoid/extensions.rb +115 -0
  43. data/lib/mongoid/extensions/array/accessors.rb +17 -0
  44. data/lib/mongoid/extensions/array/assimilation.rb +26 -0
  45. data/lib/mongoid/extensions/array/conversions.rb +23 -0
  46. data/lib/mongoid/extensions/array/parentization.rb +13 -0
  47. data/lib/mongoid/extensions/big_decimal/conversions.rb +19 -0
  48. data/lib/mongoid/extensions/binary/conversions.rb +17 -0
  49. data/lib/mongoid/extensions/boolean/conversions.rb +27 -0
  50. data/lib/mongoid/extensions/date/conversions.rb +24 -0
  51. data/lib/mongoid/extensions/datetime/conversions.rb +12 -0
  52. data/lib/mongoid/extensions/false_class/equality.rb +13 -0
  53. data/lib/mongoid/extensions/float/conversions.rb +20 -0
  54. data/lib/mongoid/extensions/hash/accessors.rb +42 -0
  55. data/lib/mongoid/extensions/hash/assimilation.rb +40 -0
  56. data/lib/mongoid/extensions/hash/conversions.rb +42 -0
  57. data/lib/mongoid/extensions/hash/criteria_helpers.rb +20 -0
  58. data/lib/mongoid/extensions/hash/scoping.rb +12 -0
  59. data/lib/mongoid/extensions/integer/conversions.rb +20 -0
  60. data/lib/mongoid/extensions/nil/assimilation.rb +17 -0
  61. data/lib/mongoid/extensions/object/conversions.rb +21 -0
  62. data/lib/mongoid/extensions/objectid/conversions.rb +15 -0
  63. data/lib/mongoid/extensions/proc/scoping.rb +12 -0
  64. data/lib/mongoid/extensions/set/conversions.rb +20 -0
  65. data/lib/mongoid/extensions/string/conversions.rb +15 -0
  66. data/lib/mongoid/extensions/string/inflections.rb +97 -0
  67. data/lib/mongoid/extensions/symbol/inflections.rb +40 -0
  68. data/lib/mongoid/extensions/time_conversions.rb +35 -0
  69. data/lib/mongoid/extensions/true_class/equality.rb +13 -0
  70. data/lib/mongoid/extras.rb +61 -0
  71. data/lib/mongoid/factory.rb +20 -0
  72. data/lib/mongoid/field.rb +83 -0
  73. data/lib/mongoid/fields.rb +62 -0
  74. data/lib/mongoid/finders.rb +145 -0
  75. data/lib/mongoid/hierarchy.rb +74 -0
  76. data/lib/mongoid/identity.rb +47 -0
  77. data/lib/mongoid/indexes.rb +27 -0
  78. data/lib/mongoid/javascript.rb +21 -0
  79. data/lib/mongoid/javascript/functions.yml +37 -0
  80. data/lib/mongoid/logger.rb +19 -0
  81. data/lib/mongoid/matchers.rb +35 -0
  82. data/lib/mongoid/matchers/all.rb +11 -0
  83. data/lib/mongoid/matchers/default.rb +26 -0
  84. data/lib/mongoid/matchers/exists.rb +13 -0
  85. data/lib/mongoid/matchers/gt.rb +11 -0
  86. data/lib/mongoid/matchers/gte.rb +11 -0
  87. data/lib/mongoid/matchers/in.rb +11 -0
  88. data/lib/mongoid/matchers/lt.rb +11 -0
  89. data/lib/mongoid/matchers/lte.rb +11 -0
  90. data/lib/mongoid/matchers/ne.rb +11 -0
  91. data/lib/mongoid/matchers/nin.rb +11 -0
  92. data/lib/mongoid/matchers/size.rb +11 -0
  93. data/lib/mongoid/memoization.rb +33 -0
  94. data/lib/mongoid/named_scope.rb +37 -0
  95. data/lib/mongoid/paranoia.rb +106 -0
  96. data/lib/mongoid/paths.rb +61 -0
  97. data/lib/mongoid/persistence.rb +216 -0
  98. data/lib/mongoid/persistence/command.rb +39 -0
  99. data/lib/mongoid/persistence/insert.rb +48 -0
  100. data/lib/mongoid/persistence/insert_embedded.rb +44 -0
  101. data/lib/mongoid/persistence/remove.rb +39 -0
  102. data/lib/mongoid/persistence/remove_all.rb +38 -0
  103. data/lib/mongoid/persistence/remove_embedded.rb +50 -0
  104. data/lib/mongoid/persistence/update.rb +71 -0
  105. data/lib/mongoid/railtie.rb +67 -0
  106. data/lib/mongoid/railties/database.rake +60 -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 +5 -0
  113. data/lib/mongoid/validations/uniqueness.rb +56 -0
  114. data/lib/mongoid/version.rb +4 -0
  115. data/lib/mongoid/versioning.rb +26 -0
  116. data/lib/rails/generators/mongoid/config/config_generator.rb +25 -0
  117. data/lib/rails/generators/mongoid/config/templates/mongoid.yml +24 -0
  118. data/lib/rails/generators/mongoid/model/model_generator.rb +24 -0
  119. data/lib/rails/generators/mongoid/model/templates/model.rb +15 -0
  120. data/lib/rails/generators/mongoid_generator.rb +61 -0
  121. data/spec/integration/mongoid/association_attributes_spec.rb +71 -0
  122. data/spec/integration/mongoid/associations_spec.rb +768 -0
  123. data/spec/integration/mongoid/attributes_spec.rb +59 -0
  124. data/spec/integration/mongoid/callback_spec.rb +33 -0
  125. data/spec/integration/mongoid/contexts/enumerable_spec.rb +33 -0
  126. data/spec/integration/mongoid/criteria_spec.rb +281 -0
  127. data/spec/integration/mongoid/dirty_spec.rb +85 -0
  128. data/spec/integration/mongoid/document_spec.rb +741 -0
  129. data/spec/integration/mongoid/extensions_spec.rb +22 -0
  130. data/spec/integration/mongoid/finders_spec.rb +119 -0
  131. data/spec/integration/mongoid/inheritance_spec.rb +171 -0
  132. data/spec/integration/mongoid/named_scope_spec.rb +58 -0
  133. data/spec/integration/mongoid/paranoia_spec.rb +44 -0
  134. data/spec/integration/mongoid/persistence/update_spec.rb +46 -0
  135. data/spec/integration/mongoid/persistence_spec.rb +311 -0
  136. data/spec/integration/mongoid/validations/uniqueness_spec.rb +206 -0
  137. data/spec/models/account.rb +5 -0
  138. data/spec/models/address.rb +40 -0
  139. data/spec/models/agent.rb +7 -0
  140. data/spec/models/animal.rb +15 -0
  141. data/spec/models/answer.rb +4 -0
  142. data/spec/models/callbacks.rb +47 -0
  143. data/spec/models/category.rb +13 -0
  144. data/spec/models/comment.rb +10 -0
  145. data/spec/models/country_code.rb +6 -0
  146. data/spec/models/employer.rb +5 -0
  147. data/spec/models/favorite.rb +8 -0
  148. data/spec/models/game.rb +9 -0
  149. data/spec/models/inheritance.rb +72 -0
  150. data/spec/models/location.rb +5 -0
  151. data/spec/models/login.rb +6 -0
  152. data/spec/models/mixed_drink.rb +4 -0
  153. data/spec/models/name.rb +13 -0
  154. data/spec/models/namespacing.rb +11 -0
  155. data/spec/models/paranoid_post.rb +18 -0
  156. data/spec/models/parents.rb +32 -0
  157. data/spec/models/patient.rb +15 -0
  158. data/spec/models/person.rb +106 -0
  159. data/spec/models/pet.rb +7 -0
  160. data/spec/models/pet_owner.rb +6 -0
  161. data/spec/models/phone.rb +7 -0
  162. data/spec/models/post.rb +25 -0
  163. data/spec/models/preference.rb +7 -0
  164. data/spec/models/question.rb +8 -0
  165. data/spec/models/survey.rb +6 -0
  166. data/spec/models/translation.rb +5 -0
  167. data/spec/models/user.rb +6 -0
  168. data/spec/models/user_accout.rb +5 -0
  169. data/spec/models/vet_visit.rb +5 -0
  170. data/spec/models/video.rb +5 -0
  171. data/spec/spec_helper.rb +33 -0
  172. data/spec/unit/mongoid/associations/embedded_in_spec.rb +193 -0
  173. data/spec/unit/mongoid/associations/embeds_many_spec.rb +626 -0
  174. data/spec/unit/mongoid/associations/embeds_one_spec.rb +287 -0
  175. data/spec/unit/mongoid/associations/foreign_key_spec.rb +90 -0
  176. data/spec/unit/mongoid/associations/meta_data_spec.rb +110 -0
  177. data/spec/unit/mongoid/associations/options_spec.rb +215 -0
  178. data/spec/unit/mongoid/associations/referenced_in_spec.rb +145 -0
  179. data/spec/unit/mongoid/associations/references_many_as_array_spec.rb +424 -0
  180. data/spec/unit/mongoid/associations/references_many_spec.rb +502 -0
  181. data/spec/unit/mongoid/associations/references_one_spec.rb +204 -0
  182. data/spec/unit/mongoid/associations_spec.rb +688 -0
  183. data/spec/unit/mongoid/atomicity_spec.rb +164 -0
  184. data/spec/unit/mongoid/attributes_spec.rb +646 -0
  185. data/spec/unit/mongoid/callbacks_spec.rb +85 -0
  186. data/spec/unit/mongoid/collection_spec.rb +187 -0
  187. data/spec/unit/mongoid/collections/cyclic_iterator_spec.rb +75 -0
  188. data/spec/unit/mongoid/collections/master_spec.rb +41 -0
  189. data/spec/unit/mongoid/collections/slaves_spec.rb +81 -0
  190. data/spec/unit/mongoid/collections_spec.rb +98 -0
  191. data/spec/unit/mongoid/config_spec.rb +298 -0
  192. data/spec/unit/mongoid/contexts/enumerable_spec.rb +447 -0
  193. data/spec/unit/mongoid/contexts/mongo_spec.rb +703 -0
  194. data/spec/unit/mongoid/contexts_spec.rb +25 -0
  195. data/spec/unit/mongoid/criteria_spec.rb +873 -0
  196. data/spec/unit/mongoid/criterion/complex_spec.rb +17 -0
  197. data/spec/unit/mongoid/criterion/exclusion_spec.rb +121 -0
  198. data/spec/unit/mongoid/criterion/inclusion_spec.rb +274 -0
  199. data/spec/unit/mongoid/criterion/optional_spec.rb +483 -0
  200. data/spec/unit/mongoid/cursor_spec.rb +80 -0
  201. data/spec/unit/mongoid/deprecation_spec.rb +24 -0
  202. data/spec/unit/mongoid/dirty_spec.rb +430 -0
  203. data/spec/unit/mongoid/document_spec.rb +623 -0
  204. data/spec/unit/mongoid/errors_spec.rb +154 -0
  205. data/spec/unit/mongoid/extensions/array/accessors_spec.rb +50 -0
  206. data/spec/unit/mongoid/extensions/array/assimilation_spec.rb +24 -0
  207. data/spec/unit/mongoid/extensions/array/conversions_spec.rb +52 -0
  208. data/spec/unit/mongoid/extensions/array/parentization_spec.rb +20 -0
  209. data/spec/unit/mongoid/extensions/big_decimal/conversions_spec.rb +36 -0
  210. data/spec/unit/mongoid/extensions/binary/conversions_spec.rb +22 -0
  211. data/spec/unit/mongoid/extensions/boolean/conversions_spec.rb +49 -0
  212. data/spec/unit/mongoid/extensions/date/conversions_spec.rb +145 -0
  213. data/spec/unit/mongoid/extensions/datetime/conversions_spec.rb +14 -0
  214. data/spec/unit/mongoid/extensions/false_class/equality_spec.rb +35 -0
  215. data/spec/unit/mongoid/extensions/float/conversions_spec.rb +61 -0
  216. data/spec/unit/mongoid/extensions/hash/accessors_spec.rb +184 -0
  217. data/spec/unit/mongoid/extensions/hash/assimilation_spec.rb +59 -0
  218. data/spec/unit/mongoid/extensions/hash/conversions_spec.rb +35 -0
  219. data/spec/unit/mongoid/extensions/hash/criteria_helpers_spec.rb +17 -0
  220. data/spec/unit/mongoid/extensions/hash/scoping_spec.rb +14 -0
  221. data/spec/unit/mongoid/extensions/integer/conversions_spec.rb +61 -0
  222. data/spec/unit/mongoid/extensions/nil/assimilation_spec.rb +29 -0
  223. data/spec/unit/mongoid/extensions/object/conversions_spec.rb +44 -0
  224. data/spec/unit/mongoid/extensions/objectid/conversions_spec.rb +22 -0
  225. data/spec/unit/mongoid/extensions/proc/scoping_spec.rb +34 -0
  226. data/spec/unit/mongoid/extensions/set/conversions_spec.rb +21 -0
  227. data/spec/unit/mongoid/extensions/string/conversions_spec.rb +28 -0
  228. data/spec/unit/mongoid/extensions/string/inflections_spec.rb +208 -0
  229. data/spec/unit/mongoid/extensions/symbol/inflections_spec.rb +107 -0
  230. data/spec/unit/mongoid/extensions/time_conversions_spec.rb +186 -0
  231. data/spec/unit/mongoid/extensions/true_class/equality_spec.rb +35 -0
  232. data/spec/unit/mongoid/extras_spec.rb +102 -0
  233. data/spec/unit/mongoid/factory_spec.rb +31 -0
  234. data/spec/unit/mongoid/field_spec.rb +169 -0
  235. data/spec/unit/mongoid/fields_spec.rb +181 -0
  236. data/spec/unit/mongoid/finders_spec.rb +439 -0
  237. data/spec/unit/mongoid/hierarchy_spec.rb +68 -0
  238. data/spec/unit/mongoid/identity_spec.rb +109 -0
  239. data/spec/unit/mongoid/indexes_spec.rb +99 -0
  240. data/spec/unit/mongoid/javascript_spec.rb +48 -0
  241. data/spec/unit/mongoid/logger_spec.rb +38 -0
  242. data/spec/unit/mongoid/matchers/all_spec.rb +27 -0
  243. data/spec/unit/mongoid/matchers/default_spec.rb +27 -0
  244. data/spec/unit/mongoid/matchers/exists_spec.rb +56 -0
  245. data/spec/unit/mongoid/matchers/gt_spec.rb +39 -0
  246. data/spec/unit/mongoid/matchers/gte_spec.rb +49 -0
  247. data/spec/unit/mongoid/matchers/in_spec.rb +27 -0
  248. data/spec/unit/mongoid/matchers/lt_spec.rb +39 -0
  249. data/spec/unit/mongoid/matchers/lte_spec.rb +49 -0
  250. data/spec/unit/mongoid/matchers/ne_spec.rb +27 -0
  251. data/spec/unit/mongoid/matchers/nin_spec.rb +27 -0
  252. data/spec/unit/mongoid/matchers/size_spec.rb +27 -0
  253. data/spec/unit/mongoid/matchers_spec.rb +329 -0
  254. data/spec/unit/mongoid/memoization_spec.rb +75 -0
  255. data/spec/unit/mongoid/named_scope_spec.rb +123 -0
  256. data/spec/unit/mongoid/paranoia_spec.rb +108 -0
  257. data/spec/unit/mongoid/paths_spec.rb +272 -0
  258. data/spec/unit/mongoid/persistence/insert_embedded_spec.rb +154 -0
  259. data/spec/unit/mongoid/persistence/insert_spec.rb +144 -0
  260. data/spec/unit/mongoid/persistence/remove_all_spec.rb +82 -0
  261. data/spec/unit/mongoid/persistence/remove_embedded_spec.rb +152 -0
  262. data/spec/unit/mongoid/persistence/remove_spec.rb +89 -0
  263. data/spec/unit/mongoid/persistence/update_spec.rb +177 -0
  264. data/spec/unit/mongoid/persistence_spec.rb +452 -0
  265. data/spec/unit/mongoid/scope_spec.rb +240 -0
  266. data/spec/unit/mongoid/serialization_spec.rb +43 -0
  267. data/spec/unit/mongoid/state_spec.rb +94 -0
  268. data/spec/unit/mongoid/timestamps_spec.rb +30 -0
  269. data/spec/unit/mongoid/validations/associated_spec.rb +103 -0
  270. data/spec/unit/mongoid/validations/uniqueness_spec.rb +201 -0
  271. data/spec/unit/mongoid/validations_spec.rb +43 -0
  272. data/spec/unit/mongoid/versioning_spec.rb +41 -0
  273. data/spec/unit/mongoid_spec.rb +46 -0
  274. metadata +433 -0
@@ -0,0 +1,21 @@
1
+ # encoding: utf-8
2
+ module Mongoid #:nodoc:
3
+ module Callbacks
4
+ extend ActiveSupport::Concern
5
+ included do
6
+ extend ActiveModel::Callbacks
7
+
8
+ # Define all the callbacks that are accepted by the document.
9
+ define_model_callbacks \
10
+ :create,
11
+ :destroy,
12
+ :save,
13
+ :update,
14
+ :validation
15
+ end
16
+
17
+ def valid?(*) #nodoc
18
+ _run_validation_callbacks { super }
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,120 @@
1
+ # encoding: utf-8
2
+ require "mongoid/collections/operations"
3
+ require "mongoid/collections/cyclic_iterator"
4
+ require "mongoid/collections/master"
5
+ require "mongoid/collections/slaves"
6
+
7
+ module Mongoid #:nodoc
8
+ # The Mongoid wrapper to the Mongo Ruby driver's collection object.
9
+ class Collection
10
+ attr_reader :counter, :name
11
+
12
+ # All write operations should delegate to the master connection. These
13
+ # operations mimic the methods on a Mongo:Collection.
14
+ #
15
+ # Example:
16
+ #
17
+ # <tt>collection.save({ :name => "Al" })</tt>
18
+ Collections::Operations::PROXIED.each do |name|
19
+ define_method(name) { |*args| master.send(name, *args) }
20
+ end
21
+
22
+ # Determines where to send the next read query. If the slaves are not
23
+ # defined then send to master. If the read counter is under the configured
24
+ # maximum then return the master. In any other case return the slaves.
25
+ #
26
+ # Example:
27
+ #
28
+ # <tt>collection.directed</tt>
29
+ #
30
+ # Return:
31
+ #
32
+ # Either a +Master+ or +Slaves+ collection.
33
+ def directed(options = {})
34
+ options.delete(:cache)
35
+ enslave = options.delete(:enslave) || @klass.enslaved?
36
+ enslave ? master_or_slaves : master
37
+ end
38
+
39
+ # Find documents from the database given a selector and options.
40
+ #
41
+ # Options:
42
+ #
43
+ # selector: A +Hash+ selector that is the query.
44
+ # options: The options to pass to the db.
45
+ #
46
+ # Example:
47
+ #
48
+ # <tt>collection.find({ :test => "value" })</tt>
49
+ def find(selector = {}, options = {})
50
+ cursor = Mongoid::Cursor.new(@klass, self, directed(options).find(selector, options))
51
+ if block_given?
52
+ yield cursor; cursor.close
53
+ else
54
+ cursor
55
+ end
56
+ end
57
+
58
+ # Find the first document from the database given a selector and options.
59
+ #
60
+ # Options:
61
+ #
62
+ # selector: A +Hash+ selector that is the query.
63
+ # options: The options to pass to the db.
64
+ #
65
+ # Example:
66
+ #
67
+ # <tt>collection.find_one({ :test => "value" })</tt>
68
+ def find_one(selector = {}, options = {})
69
+ directed(options).find_one(selector, options)
70
+ end
71
+
72
+ # Initialize a new Mongoid::Collection, setting up the master, slave, and
73
+ # name attributes. Masters will be used for writes, slaves for reads.
74
+ #
75
+ # Example:
76
+ #
77
+ # <tt>Mongoid::Collection.new(masters, slaves, "test")</tt>
78
+ def initialize(klass, name)
79
+ @klass, @name = klass, name
80
+ end
81
+
82
+ # Perform a map/reduce on the documents.
83
+ #
84
+ # Options:
85
+ #
86
+ # map: The map javascript funcdtion.
87
+ # reduce: The reduce javascript function.
88
+ def map_reduce(map, reduce, options = {})
89
+ directed(options).map_reduce(map, reduce, options)
90
+ end
91
+
92
+ alias :mapreduce :map_reduce
93
+
94
+ # Return the object responsible for writes to the database. This will
95
+ # always return a collection associated with the Master DB.
96
+ #
97
+ # Example:
98
+ #
99
+ # <tt>collection.writer</tt>
100
+ def master
101
+ @master ||= Collections::Master.new(Mongoid.master, @name)
102
+ end
103
+
104
+ # Return the object responsible for reading documents from the database.
105
+ # This is usually the slave databases, but in their absence the master will
106
+ # handle the task.
107
+ #
108
+ # Example:
109
+ #
110
+ # <tt>collection.reader</tt>
111
+ def slaves
112
+ @slaves ||= Collections::Slaves.new(Mongoid.slaves, @name)
113
+ end
114
+
115
+ protected
116
+ def master_or_slaves
117
+ slaves.empty? ? master : slaves
118
+ end
119
+ end
120
+ end
@@ -0,0 +1,71 @@
1
+ # encoding: utf-8
2
+ module Mongoid #:nodoc
3
+ # The collections module is used for providing functionality around setting
4
+ # up and updating collections.
5
+ module Collections
6
+ extend ActiveSupport::Concern
7
+ included do
8
+ cattr_accessor :_collection, :collection_name
9
+ self.collection_name = self.name.collectionize
10
+
11
+ delegate :collection, :db, :to => "self.class"
12
+ end
13
+
14
+ module ClassMethods #:nodoc:
15
+ # Returns the collection associated with this +Document+. If the
16
+ # document is embedded, there will be no collection associated
17
+ # with it.
18
+ #
19
+ # Returns: <tt>Mongo::Collection</tt>
20
+ def collection
21
+ raise Errors::InvalidCollection.new(self) if embedded?
22
+ self._collection || set_collection
23
+ add_indexes; self._collection
24
+ end
25
+
26
+ # Return the database associated with this collection.
27
+ #
28
+ # Example:
29
+ #
30
+ # <tt>Person.db</tt>
31
+ def db
32
+ collection.db
33
+ end
34
+
35
+ # Convenience method for getting index information from the collection.
36
+ #
37
+ # Example:
38
+ #
39
+ # <tt>Person.index_information</tt>
40
+ def index_information
41
+ collection.index_information
42
+ end
43
+
44
+ # The MongoDB logger is not exposed through the driver to be changed
45
+ # after initialization of the connection, this is a hacky way around that
46
+ # if logging needs to be changed at runtime.
47
+ #
48
+ # Example:
49
+ #
50
+ # <tt>Person.logger = Logger.new($stdout)</tt>
51
+ def logger=(logger)
52
+ db.connection.instance_variable_set(:@logger, logger)
53
+ end
54
+
55
+ # Macro for setting the collection name to store in.
56
+ #
57
+ # Example:
58
+ #
59
+ # <tt>Person.store_in :populdation</tt>
60
+ def store_in(name)
61
+ self.collection_name = name.to_s
62
+ set_collection
63
+ end
64
+
65
+ protected
66
+ def set_collection
67
+ self._collection = Mongoid::Collection.new(self, self.collection_name)
68
+ end
69
+ end
70
+ end
71
+ end
@@ -0,0 +1,34 @@
1
+ # encoding: utf-8
2
+ module Mongoid #:nodoc:
3
+ module Collections #:nodoc:
4
+ class CyclicIterator
5
+
6
+ attr_reader :counter
7
+
8
+ # Performs iteration over an array, if the array gets to the end then loop
9
+ # back to the first.
10
+ #
11
+ # Example:
12
+ #
13
+ # <tt>CyclicIterator.new([ first, second ])</tt>
14
+ def initialize(array)
15
+ @array, @counter = array, -1
16
+ end
17
+
18
+ # Get the next element in the array. If the element is the last in the
19
+ # array then return the first.
20
+ #
21
+ # Example:
22
+ #
23
+ # <tt>iterator.next</tt>
24
+ #
25
+ # Returns:
26
+ #
27
+ # The next element in the array.
28
+ def next
29
+ (@counter == @array.size - 1) ? @counter = 0 : @counter = @counter + 1
30
+ @array[@counter]
31
+ end
32
+ end
33
+ end
34
+ end
@@ -0,0 +1,29 @@
1
+ # encoding: utf-8
2
+ module Mongoid #:nodoc:
3
+ module Collections #:nodoc:
4
+ class Master
5
+
6
+ attr_reader :collection
7
+
8
+ # All read and write operations should delegate to the master connection.
9
+ # These operations mimic the methods on a Mongo:Collection.
10
+ #
11
+ # Example:
12
+ #
13
+ # <tt>collection.save({ :name => "Al" })</tt>
14
+ Operations::ALL.each do |name|
15
+ define_method(name) { |*args| collection.send(name, *args) }
16
+ end
17
+
18
+ # Create the new database writer. Will create a collection from the
19
+ # master database.
20
+ #
21
+ # Example:
22
+ #
23
+ # <tt>Master.new(master, "mongoid_people")</tt>
24
+ def initialize(master, name)
25
+ @collection = master.collection(name)
26
+ end
27
+ end
28
+ end
29
+ end
@@ -0,0 +1,41 @@
1
+ # encoding: utf-8
2
+ module Mongoid #:nodoc:
3
+ module Collections #:nodoc:
4
+ module Operations #:nodoc:
5
+ # Constant definining all the read operations available for a
6
+ # Mongo:Collection. This is used in delegation.
7
+ READ = [
8
+ :[],
9
+ :db,
10
+ :count,
11
+ :distinct,
12
+ :find,
13
+ :find_one,
14
+ :group,
15
+ :index_information,
16
+ :map_reduce,
17
+ :mapreduce,
18
+ :options
19
+ ]
20
+
21
+ # Constant definining all the write operations available for a
22
+ # Mongo:Collection. This is used in delegation.
23
+ WRITE = [
24
+ :<<,
25
+ :create_index,
26
+ :drop,
27
+ :drop_index,
28
+ :drop_indexes,
29
+ :insert,
30
+ :remove,
31
+ :rename,
32
+ :save,
33
+ :update
34
+ ]
35
+
36
+ # Convenience constant for getting back all collection operations.
37
+ ALL = (READ + WRITE)
38
+ PROXIED = ALL - [ :find, :find_one, :map_reduce, :mapreduce ]
39
+ end
40
+ end
41
+ end
@@ -0,0 +1,45 @@
1
+ # encoding: utf-8
2
+ module Mongoid #:nodoc:
3
+ module Collections #:nodoc:
4
+ class Slaves
5
+
6
+ attr_reader :iterator
7
+
8
+ # All read operations should delegate to the slave connections.
9
+ # These operations mimic the methods on a Mongo:Collection.
10
+ #
11
+ # Example:
12
+ #
13
+ # <tt>collection.save({ :name => "Al" })</tt>
14
+ Operations::READ.each do |name|
15
+ define_method(name) { |*args| collection.send(name, *args) }
16
+ end
17
+
18
+ # Is the collection of slaves empty or not?
19
+ #
20
+ # Return:
21
+ #
22
+ # True is the iterator is not set, false if not.
23
+ def empty?
24
+ @iterator.nil?
25
+ end
26
+
27
+ # Create the new database reader. Will create a collection from the
28
+ # slave databases and cycle through them on each read.
29
+ #
30
+ # Example:
31
+ #
32
+ # <tt>Reader.new(slaves, "mongoid_people")</tt>
33
+ def initialize(slaves, name)
34
+ unless slaves.blank?
35
+ @iterator = CyclicIterator.new(slaves.collect { |db| db.collection(name) })
36
+ end
37
+ end
38
+
39
+ protected
40
+ def collection
41
+ @iterator.next
42
+ end
43
+ end
44
+ end
45
+ end
@@ -0,0 +1,34 @@
1
+ # encoding: utf-8
2
+ module Mongoid #:nodoc
3
+ module Components #:nodoc
4
+ extend ActiveSupport::Concern
5
+ included do
6
+ # All modules that a +Document+ is composed of are defined in this
7
+ # module, to keep the document class from getting too cluttered.
8
+ include ActiveModel::Conversion
9
+ include ActiveModel::Naming
10
+ include ActiveModel::Serialization
11
+ include ActiveModel::Serializers::JSON
12
+ include ActiveModel::Serializers::Xml
13
+ include Mongoid::Associations
14
+ include Mongoid::Atomicity
15
+ include Mongoid::Attributes
16
+ include Mongoid::Collections
17
+ include Mongoid::Dirty
18
+ include Mongoid::Extras
19
+ include Mongoid::Fields
20
+ include Mongoid::Hierarchy
21
+ include Mongoid::Indexes
22
+ include Mongoid::Matchers
23
+ include Mongoid::Memoization
24
+ include Mongoid::Paths
25
+ include Mongoid::Persistence
26
+ include Mongoid::State
27
+ include Mongoid::Validations
28
+ include Mongoid::Callbacks
29
+ extend ActiveModel::Translation
30
+ extend Mongoid::Finders
31
+ extend Mongoid::NamedScope
32
+ end
33
+ end
34
+ end
@@ -0,0 +1,263 @@
1
+ # encoding: utf-8
2
+ require "uri"
3
+
4
+ module Mongoid #:nodoc
5
+ class Config #:nodoc
6
+ include Singleton
7
+
8
+ attr_accessor \
9
+ :allow_dynamic_fields,
10
+ :reconnect_time,
11
+ :parameterize_keys,
12
+ :persist_in_safe_mode,
13
+ :raise_not_found_error,
14
+ :use_object_ids,
15
+ :skip_version_check
16
+
17
+ # Initializes the configuration with default settings.
18
+ def initialize
19
+ reset
20
+ end
21
+
22
+ # Sets whether the times returned from the database are in UTC or local time.
23
+ # If you omit this setting, then times will be returned in
24
+ # the local time zone.
25
+ #
26
+ # Example:
27
+ #
28
+ # <tt>Config.use_utc = true</tt>
29
+ #
30
+ # Returns:
31
+ #
32
+ # A boolean
33
+ def use_utc=(value)
34
+ @use_utc = value || false
35
+ end
36
+
37
+ # Returns whether times are return from the database in UTC. If
38
+ # this setting is false, then times will be returned in the local time zone.
39
+ #
40
+ # Example:
41
+ #
42
+ # <tt>Config.use_utc</tt>
43
+ #
44
+ # Returns:
45
+ #
46
+ # A boolean
47
+ attr_reader :use_utc
48
+ alias_method :use_utc?, :use_utc
49
+
50
+ # Sets the Mongo::DB master database to be used. If the object trying to be
51
+ # set is not a valid +Mongo::DB+, then an error will be raised.
52
+ #
53
+ # Example:
54
+ #
55
+ # <tt>Config.master = Mongo::Connection.db("test")</tt>
56
+ #
57
+ # Returns:
58
+ #
59
+ # The master +Mongo::DB+ instance.
60
+ def master=(db)
61
+ check_database!(db)
62
+ @master = db
63
+ end
64
+
65
+ # Returns the master database, or if none has been set it will raise an
66
+ # error.
67
+ #
68
+ # Example:
69
+ #
70
+ # <tt>Config.master</tt>
71
+ #
72
+ # Returns:
73
+ #
74
+ # The master +Mongo::DB+
75
+ def master
76
+ @master || (raise Errors::InvalidDatabase.new(nil))
77
+ end
78
+
79
+ alias :database :master
80
+ alias :database= :master=
81
+
82
+ # Sets the Mongo::DB slave databases to be used. If the objects provided
83
+ # are not valid +Mongo::DBs+ an error will be raised.
84
+ #
85
+ # Example:
86
+ #
87
+ # <tt>Config.slaves = [ Mongo::Connection.db("test") ]</tt>
88
+ #
89
+ # Returns:
90
+ #
91
+ # The slave DB instances.
92
+ def slaves=(dbs)
93
+ return unless dbs
94
+ dbs.each do |db|
95
+ check_database!(db)
96
+ end
97
+ @slaves = dbs
98
+ end
99
+
100
+ # Returns the slave databases or nil if none have been set.
101
+ #
102
+ # Example:
103
+ #
104
+ # <tt>Config.slaves</tt>
105
+ #
106
+ # Returns:
107
+ #
108
+ # The slave +Mongo::DBs+
109
+ def slaves
110
+ @slaves
111
+ end
112
+
113
+ # Returns the logger, or defaults to Rails logger or stdout logger.
114
+ #
115
+ # Example:
116
+ #
117
+ # <tt>Config.logger</tt>
118
+ def logger
119
+ return @logger if defined?(@logger)
120
+
121
+ @logger = defined?(Rails) ? Rails.logger : ::Logger.new($stdout)
122
+ end
123
+
124
+ # Sets the logger for Mongoid to use.
125
+ #
126
+ # Example:
127
+ #
128
+ # <tt>Config.logger = Logger.new($stdout, :warn)</tt>
129
+ def logger=(logger)
130
+ @logger = logger
131
+ end
132
+
133
+ # Return field names that could cause destructive things to happen if
134
+ # defined in a Mongoid::Document
135
+ #
136
+ # Example:
137
+ #
138
+ # <tt>Config.destructive_fields</tt>
139
+ #
140
+ # Returns:
141
+ #
142
+ # An array of bad field names.
143
+ def destructive_fields
144
+ @destructive_fields ||= lambda {
145
+ klass = Class.new do
146
+ include Mongoid::Document
147
+ end
148
+ klass.instance_methods(true).collect { |method| method.to_s }
149
+ }.call
150
+ end
151
+
152
+ # Configure mongoid from a hash. This is usually called after parsing a
153
+ # yaml config file such as mongoid.yml.
154
+ #
155
+ # Example:
156
+ #
157
+ # <tt>Mongoid::Config.instance.from_hash({})</tt>
158
+ def from_hash(settings)
159
+ _master(settings)
160
+ _slaves(settings)
161
+ settings.except("database").each_pair do |name, value|
162
+ send("#{name}=", value) if respond_to?(name)
163
+ end
164
+ end
165
+
166
+ # Convenience method for connecting to the master database after forking a
167
+ # new process.
168
+ #
169
+ # Example:
170
+ #
171
+ # <tt>Mongoid.reconnect!</tt>
172
+ def reconnect!
173
+ master.connection.connect_to_master
174
+ end
175
+
176
+ # Reset the configuration options to the defaults.
177
+ #
178
+ # Example:
179
+ #
180
+ # <tt>config.reset</tt>
181
+ def reset
182
+ @allow_dynamic_fields = true
183
+ @parameterize_keys = true
184
+ @persist_in_safe_mode = true
185
+ @raise_not_found_error = true
186
+ @reconnect_time = 3
187
+ @use_object_ids = false
188
+ @skip_version_check = false
189
+ @time_zone = nil
190
+ end
191
+
192
+ protected
193
+
194
+ # Check if the database is valid and the correct version.
195
+ #
196
+ # Example:
197
+ #
198
+ # <tt>config.check_database!</tt>
199
+ def check_database!(database)
200
+ raise Errors::InvalidDatabase.new(database) unless database.kind_of?(Mongo::DB)
201
+ unless Mongoid.skip_version_check
202
+ version = database.connection.server_version
203
+ raise Errors::UnsupportedVersion.new(version) if version < Mongoid::MONGODB_VERSION
204
+ end
205
+ end
206
+
207
+ # Get a master database from settings.
208
+ #
209
+ # TODO: Durran: This code's a bit hairy, refactor.
210
+ #
211
+ # Example:
212
+ #
213
+ # <tt>config._master({}, "test")</tt>
214
+ def _master(settings)
215
+ mongo_uri = settings["uri"].present? ? URI.parse(settings["uri"]) : OpenStruct.new
216
+
217
+ name = settings["database"] || mongo_uri.path.to_s.sub("/", "")
218
+ host = settings["host"] || mongo_uri.host || "localhost"
219
+ port = settings["port"] || mongo_uri.port || 27017
220
+ pool_size = settings["pool_size"] || 1
221
+ username = settings["username"] || mongo_uri.user
222
+ password = settings["password"] || mongo_uri.password
223
+
224
+ connection = Mongo::Connection.new(host, port, :logger => Mongoid::Logger.new, :pool_size => pool_size)
225
+ if username || password
226
+ connection.add_auth(name, username, password)
227
+ connection.apply_saved_authentication
228
+ end
229
+ self.master = connection.db(name)
230
+ end
231
+
232
+ # Get a bunch-o-slaves from settings and names.
233
+ #
234
+ # TODO: Durran: This code's a bit hairy, refactor.
235
+ #
236
+ # Example:
237
+ #
238
+ # <tt>config._slaves({}, "test")</tt>
239
+ def _slaves(settings)
240
+ mongo_uri = settings["uri"].present? ? URI.parse(settings["uri"]) : OpenStruct.new
241
+ name = settings["database"] || mongo_uri.path.to_s.sub("/", "")
242
+ self.slaves = []
243
+ slaves = settings["slaves"]
244
+ slaves.to_a.each do |slave|
245
+ slave_uri = slave["uri"].present? ? URI.parse(slave["uri"]) : OpenStruct.new
246
+ slave_username = slave["username"] || slave_uri.user
247
+ slave_password = slave["password"] || slave_uri.password
248
+
249
+ slave_connection = Mongo::Connection.new(
250
+ slave["host"] || slave_uri.host || "localhost",
251
+ slave["port"] || slave_uri.port,
252
+ :slave_ok => true
253
+ )
254
+
255
+ if slave_username || slave_password
256
+ slave_connection.add_auth(name, slave_username, slave_password)
257
+ slave_connection.apply_saved_authentication
258
+ end
259
+ self.slaves << slave_connection.db(name)
260
+ end
261
+ end
262
+ end
263
+ end