mongoid 2.0.0.beta.20 → 2.0.0.rc.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (134) hide show
  1. data/README.rdoc +8 -0
  2. data/Rakefile +51 -0
  3. data/lib/config/locales/nl.yml +39 -0
  4. data/lib/config/locales/ro.yml +1 -1
  5. data/lib/mongoid.rb +17 -17
  6. data/lib/mongoid/atomicity.rb +54 -22
  7. data/lib/mongoid/attributes.rb +145 -125
  8. data/lib/mongoid/callbacks.rb +7 -2
  9. data/lib/mongoid/collection.rb +49 -32
  10. data/lib/mongoid/collections.rb +0 -1
  11. data/lib/mongoid/components.rb +34 -29
  12. data/lib/mongoid/config.rb +207 -193
  13. data/lib/mongoid/config/database.rb +167 -0
  14. data/lib/mongoid/contexts.rb +2 -5
  15. data/lib/mongoid/contexts/enumerable.rb +30 -4
  16. data/lib/mongoid/contexts/ids.rb +2 -2
  17. data/lib/mongoid/contexts/mongo.rb +30 -5
  18. data/lib/mongoid/copyable.rb +44 -0
  19. data/lib/mongoid/criteria.rb +110 -56
  20. data/lib/mongoid/criterion/creational.rb +34 -0
  21. data/lib/mongoid/criterion/destructive.rb +37 -0
  22. data/lib/mongoid/criterion/exclusion.rb +3 -1
  23. data/lib/mongoid/criterion/inclusion.rb +59 -64
  24. data/lib/mongoid/criterion/inspection.rb +22 -0
  25. data/lib/mongoid/criterion/optional.rb +42 -54
  26. data/lib/mongoid/criterion/selector.rb +9 -0
  27. data/lib/mongoid/default_scope.rb +28 -0
  28. data/lib/mongoid/deprecation.rb +5 -5
  29. data/lib/mongoid/dirty.rb +4 -5
  30. data/lib/mongoid/document.rb +161 -114
  31. data/lib/mongoid/extensions.rb +7 -11
  32. data/lib/mongoid/extensions/array/parentization.rb +2 -2
  33. data/lib/mongoid/extensions/date/conversions.rb +1 -1
  34. data/lib/mongoid/extensions/hash/conversions.rb +0 -23
  35. data/lib/mongoid/extensions/nil/collectionization.rb +12 -0
  36. data/lib/mongoid/extensions/object/reflections.rb +17 -0
  37. data/lib/mongoid/extensions/object/yoda.rb +27 -0
  38. data/lib/mongoid/extensions/string/conversions.rb +23 -4
  39. data/lib/mongoid/extensions/time_conversions.rb +4 -4
  40. data/lib/mongoid/field.rb +30 -19
  41. data/lib/mongoid/fields.rb +15 -5
  42. data/lib/mongoid/finders.rb +19 -11
  43. data/lib/mongoid/hierarchy.rb +34 -28
  44. data/lib/mongoid/identity.rb +62 -20
  45. data/lib/mongoid/inspection.rb +58 -0
  46. data/lib/mongoid/matchers.rb +20 -0
  47. data/lib/mongoid/multi_database.rb +11 -0
  48. data/lib/mongoid/nested_attributes.rb +41 -0
  49. data/lib/mongoid/paranoia.rb +3 -4
  50. data/lib/mongoid/paths.rb +1 -1
  51. data/lib/mongoid/persistence.rb +89 -90
  52. data/lib/mongoid/persistence/command.rb +20 -4
  53. data/lib/mongoid/persistence/insert.rb +13 -11
  54. data/lib/mongoid/persistence/insert_embedded.rb +8 -6
  55. data/lib/mongoid/persistence/remove.rb +6 -4
  56. data/lib/mongoid/persistence/remove_all.rb +6 -4
  57. data/lib/mongoid/persistence/remove_embedded.rb +8 -6
  58. data/lib/mongoid/persistence/update.rb +12 -10
  59. data/lib/mongoid/railtie.rb +2 -2
  60. data/lib/mongoid/railties/database.rake +10 -9
  61. data/lib/mongoid/relations.rb +104 -0
  62. data/lib/mongoid/relations/accessors.rb +154 -0
  63. data/lib/mongoid/relations/auto_save.rb +34 -0
  64. data/lib/mongoid/relations/binding.rb +24 -0
  65. data/lib/mongoid/relations/bindings.rb +9 -0
  66. data/lib/mongoid/relations/bindings/embedded/in.rb +77 -0
  67. data/lib/mongoid/relations/bindings/embedded/many.rb +93 -0
  68. data/lib/mongoid/relations/bindings/embedded/one.rb +65 -0
  69. data/lib/mongoid/relations/bindings/referenced/in.rb +78 -0
  70. data/lib/mongoid/relations/bindings/referenced/many.rb +93 -0
  71. data/lib/mongoid/relations/bindings/referenced/many_to_many.rb +94 -0
  72. data/lib/mongoid/relations/bindings/referenced/one.rb +63 -0
  73. data/lib/mongoid/relations/builder.rb +41 -0
  74. data/lib/mongoid/relations/builders.rb +79 -0
  75. data/lib/mongoid/relations/builders/embedded/in.rb +25 -0
  76. data/lib/mongoid/relations/builders/embedded/many.rb +32 -0
  77. data/lib/mongoid/relations/builders/embedded/one.rb +26 -0
  78. data/lib/mongoid/relations/builders/nested_attributes/many.rb +116 -0
  79. data/lib/mongoid/relations/builders/nested_attributes/one.rb +135 -0
  80. data/lib/mongoid/relations/builders/referenced/in.rb +32 -0
  81. data/lib/mongoid/relations/builders/referenced/many.rb +26 -0
  82. data/lib/mongoid/relations/builders/referenced/many_to_many.rb +29 -0
  83. data/lib/mongoid/relations/builders/referenced/one.rb +30 -0
  84. data/lib/mongoid/relations/cascading.rb +55 -0
  85. data/lib/mongoid/relations/cascading/delete.rb +19 -0
  86. data/lib/mongoid/relations/cascading/destroy.rb +19 -0
  87. data/lib/mongoid/relations/cascading/nullify.rb +18 -0
  88. data/lib/mongoid/relations/cascading/strategy.rb +26 -0
  89. data/lib/mongoid/relations/cyclic.rb +97 -0
  90. data/lib/mongoid/relations/embedded/in.rb +172 -0
  91. data/lib/mongoid/relations/embedded/many.rb +450 -0
  92. data/lib/mongoid/relations/embedded/one.rb +169 -0
  93. data/lib/mongoid/relations/macros.rb +302 -0
  94. data/lib/mongoid/relations/many.rb +185 -0
  95. data/lib/mongoid/relations/metadata.rb +529 -0
  96. data/lib/mongoid/relations/nested_builder.rb +52 -0
  97. data/lib/mongoid/relations/one.rb +29 -0
  98. data/lib/mongoid/relations/polymorphic.rb +54 -0
  99. data/lib/mongoid/relations/proxy.rb +122 -0
  100. data/lib/mongoid/relations/referenced/in.rb +214 -0
  101. data/lib/mongoid/relations/referenced/many.rb +358 -0
  102. data/lib/mongoid/relations/referenced/many_to_many.rb +379 -0
  103. data/lib/mongoid/relations/referenced/one.rb +204 -0
  104. data/lib/mongoid/relations/reflections.rb +45 -0
  105. data/lib/mongoid/safe.rb +11 -1
  106. data/lib/mongoid/safety.rb +122 -97
  107. data/lib/mongoid/scope.rb +14 -9
  108. data/lib/mongoid/state.rb +37 -3
  109. data/lib/mongoid/timestamps.rb +11 -0
  110. data/lib/mongoid/validations.rb +42 -3
  111. data/lib/mongoid/validations/associated.rb +8 -5
  112. data/lib/mongoid/validations/uniqueness.rb +23 -2
  113. data/lib/mongoid/version.rb +1 -1
  114. data/lib/mongoid/versioning.rb +25 -16
  115. data/lib/rails/generators/mongoid/model/templates/model.rb +3 -1
  116. metadata +95 -80
  117. data/lib/mongoid/associations.rb +0 -364
  118. data/lib/mongoid/associations/embedded_in.rb +0 -74
  119. data/lib/mongoid/associations/embeds_many.rb +0 -299
  120. data/lib/mongoid/associations/embeds_one.rb +0 -111
  121. data/lib/mongoid/associations/foreign_key.rb +0 -35
  122. data/lib/mongoid/associations/meta_data.rb +0 -38
  123. data/lib/mongoid/associations/options.rb +0 -78
  124. data/lib/mongoid/associations/proxy.rb +0 -60
  125. data/lib/mongoid/associations/referenced_in.rb +0 -70
  126. data/lib/mongoid/associations/references_many.rb +0 -254
  127. data/lib/mongoid/associations/references_many_as_array.rb +0 -128
  128. data/lib/mongoid/associations/references_one.rb +0 -104
  129. data/lib/mongoid/extensions/array/accessors.rb +0 -17
  130. data/lib/mongoid/extensions/array/assimilation.rb +0 -26
  131. data/lib/mongoid/extensions/hash/accessors.rb +0 -42
  132. data/lib/mongoid/extensions/hash/assimilation.rb +0 -40
  133. data/lib/mongoid/extensions/nil/assimilation.rb +0 -17
  134. data/lib/mongoid/memoization.rb +0 -33
@@ -5,7 +5,6 @@ module Mongoid #:nodoc:
5
5
  included do
6
6
  extend ActiveModel::Callbacks
7
7
 
8
- # Define all the callbacks that are accepted by the document.
9
8
  define_model_callbacks \
10
9
  :create,
11
10
  :destroy,
@@ -15,7 +14,13 @@ module Mongoid #:nodoc:
15
14
  :validation
16
15
  end
17
16
 
18
- def valid?(*) #nodoc
17
+ # Determine if the document is valid.
18
+ #
19
+ # @example Is the document valid?
20
+ # person.valid?
21
+ #
22
+ # @return [ true, false ] True if valid, false if not.
23
+ def valid?(*)
19
24
  _run_validation_callbacks { super }
20
25
  end
21
26
  end
@@ -5,16 +5,17 @@ require "mongoid/collections/master"
5
5
  require "mongoid/collections/slaves"
6
6
 
7
7
  module Mongoid #:nodoc
8
- # The Mongoid wrapper to the Mongo Ruby driver's collection object.
8
+
9
+ # This class is the Mongoid wrapper to the Mongo Ruby driver's collection
10
+ # object.
9
11
  class Collection
10
12
  attr_reader :counter, :name
11
13
 
12
14
  # All write operations should delegate to the master connection. These
13
15
  # operations mimic the methods on a Mongo:Collection.
14
16
  #
15
- # Example:
16
- #
17
- # <tt>collection.save({ :name => "Al" })</tt>
17
+ # @example Delegate the operation.
18
+ # collection.save({ :name => "Al" })
18
19
  Collections::Operations::PROXIED.each do |name|
19
20
  define_method(name) { |*args| master.send(name, *args) }
20
21
  end
@@ -23,13 +24,15 @@ module Mongoid #:nodoc
23
24
  # defined then send to master. If the read counter is under the configured
24
25
  # maximum then return the master. In any other case return the slaves.
25
26
  #
26
- # Example:
27
+ # @example Send the operation to the master or slaves.
28
+ # collection.directed
27
29
  #
28
- # <tt>collection.directed</tt>
30
+ # @param [ Hash ] options The operation options.
29
31
  #
30
- # Return:
32
+ # @option options [ true, false ] :cache Should the query cache in memory?
33
+ # @option options [ true, false ] :enslave Send the write to the slave?
31
34
  #
32
- # Either a +Master+ or +Slaves+ collection.
35
+ # @return [ Master, Slaves ] The connection to use.
33
36
  def directed(options = {})
34
37
  options.delete(:cache)
35
38
  enslave = options.delete(:enslave) || @klass.enslaved?
@@ -38,14 +41,13 @@ module Mongoid #:nodoc
38
41
 
39
42
  # Find documents from the database given a selector and options.
40
43
  #
41
- # Options:
42
- #
43
- # selector: A +Hash+ selector that is the query.
44
- # options: The options to pass to the db.
44
+ # @example Find documents in the collection.
45
+ # collection.find({ :test => "value" })
45
46
  #
46
- # Example:
47
+ # @param [ Hash ] selector The query selector.
48
+ # @param [ Hash ] options The options to pass to the db.
47
49
  #
48
- # <tt>collection.find({ :test => "value" })</tt>
50
+ # @return [ Cursor ] The results.
49
51
  def find(selector = {}, options = {})
50
52
  cursor = Mongoid::Cursor.new(@klass, self, directed(options).find(selector, options))
51
53
  if block_given?
@@ -57,14 +59,13 @@ module Mongoid #:nodoc
57
59
 
58
60
  # Find the first document from the database given a selector and options.
59
61
  #
60
- # Options:
62
+ # @example Find one document.
63
+ # collection.find_one({ :test => "value" })
61
64
  #
62
- # selector: A +Hash+ selector that is the query.
63
- # options: The options to pass to the db.
65
+ # @param [ Hash ] selector The query selector.
66
+ # @param [ Hash ] options The options to pass to the db.
64
67
  #
65
- # Example:
66
- #
67
- # <tt>collection.find_one({ :test => "value" })</tt>
68
+ # @return [ Document, nil ] A matching document or nil if none found.
68
69
  def find_one(selector = {}, options = {})
69
70
  directed(options).find_one(selector, options)
70
71
  end
@@ -72,47 +73,63 @@ module Mongoid #:nodoc
72
73
  # Initialize a new Mongoid::Collection, setting up the master, slave, and
73
74
  # name attributes. Masters will be used for writes, slaves for reads.
74
75
  #
75
- # Example:
76
+ # @example Create the new collection.
77
+ # Collection.new(masters, slaves, "test")
76
78
  #
77
- # <tt>Mongoid::Collection.new(masters, slaves, "test")</tt>
79
+ # @param [ Class ] klass The class the collection is for.
80
+ # @param [ String ] name The name of the collection.
78
81
  def initialize(klass, name)
79
82
  @klass, @name = klass, name
80
83
  end
81
84
 
82
85
  # Perform a map/reduce on the documents.
83
86
  #
84
- # Options:
87
+ # @example Perform the map/reduce.
88
+ # collection.map_reduce(map, reduce)
89
+ #
90
+ # @param [ String ] map The map javascript function.
91
+ # @param [ String ] reduce The reduce javascript function.
92
+ # @param [ Hash ] options The options to pass to the db.
85
93
  #
86
- # map: The map javascript function.
87
- # reduce: The reduce javascript function.
94
+ # @return [ Cursor ] The results.
88
95
  def map_reduce(map, reduce, options = {})
89
96
  directed(options).map_reduce(map, reduce, options)
90
97
  end
91
-
92
98
  alias :mapreduce :map_reduce
93
99
 
94
100
  # Return the object responsible for writes to the database. This will
95
101
  # always return a collection associated with the Master DB.
96
102
  #
97
- # Example:
103
+ # @example Get the master connection.
104
+ # collection.master
98
105
  #
99
- # <tt>collection.writer</tt>
106
+ # @return [ Master ] The master connection.
100
107
  def master
101
- @master ||= Collections::Master.new(Mongoid.master, @name)
108
+ db = Mongoid.databases[@klass.database] || Mongoid.master
109
+ @master ||= Collections::Master.new(db, @name)
102
110
  end
103
111
 
104
112
  # Return the object responsible for reading documents from the database.
105
113
  # This is usually the slave databases, but in their absence the master will
106
114
  # handle the task.
107
115
  #
108
- # Example:
116
+ # @example Get the slaves array.
117
+ # collection.slaves
109
118
  #
110
- # <tt>collection.reader</tt>
119
+ # @return [ Slaves ] The pool of slave connections.
111
120
  def slaves
112
- @slaves ||= Collections::Slaves.new(Mongoid.slaves, @name)
121
+ slaves = Mongoid.databases["#{@klass.database}_slaves"] || Mongoid.slaves
122
+ @slaves ||= Collections::Slaves.new(slaves, @name)
113
123
  end
114
124
 
115
125
  protected
126
+
127
+ # Determine if the read is going to the master or the slaves.
128
+ #
129
+ # @example Use the master or slaves?
130
+ # collection.master_or_slaves
131
+ #
132
+ # @return [ Master, Slaves ] Master if not slaves exist, or slaves.
116
133
  def master_or_slaves
117
134
  slaves.empty? ? master : slaves
118
135
  end
@@ -18,7 +18,6 @@ module Mongoid #:nodoc
18
18
  #
19
19
  # Returns: <tt>Mongo::Collection</tt>
20
20
  def collection
21
- raise Errors::InvalidCollection.new(self) if embedded?
22
21
  self._collection || set_collection
23
22
  add_indexes; self._collection
24
23
  end
@@ -2,39 +2,44 @@
2
2
  module Mongoid #:nodoc
3
3
  module Components #:nodoc
4
4
  extend ActiveSupport::Concern
5
+
6
+ # All modules that a +Document+ is composed of are defined in this
7
+ # module, to keep the document class from getting too cluttered.
5
8
  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::MassAssignmentSecurity
12
- include ActiveModel::Serializers::JSON
13
- include ActiveModel::Serializers::Xml
14
- include Mongoid::Associations
15
- include Mongoid::Atomicity
16
- include Mongoid::Attributes
17
- include Mongoid::Collections
18
- include Mongoid::Dirty
19
- include Mongoid::Extras
20
- include Mongoid::Fields
21
- include Mongoid::Hierarchy
22
- include Mongoid::Indexes
23
- include Mongoid::JSON
24
- include Mongoid::Keys
25
- include Mongoid::Matchers
26
- include Mongoid::Memoization
27
- include Mongoid::Modifiers
28
- include Mongoid::MultiParameterAttributes
29
- include Mongoid::Paths
30
- include Mongoid::Persistence
31
- include Mongoid::Safety
32
- include Mongoid::State
33
- include Mongoid::Validations
34
- include Mongoid::Callbacks
35
9
  extend ActiveModel::Translation
10
+ extend Mongoid::DefaultScope
36
11
  extend Mongoid::Finders
37
12
  extend Mongoid::NamedScope
38
13
  end
14
+
15
+ include ActiveModel::Conversion
16
+ include ActiveModel::Naming
17
+ include ActiveModel::Serialization
18
+ include ActiveModel::MassAssignmentSecurity
19
+ include ActiveModel::Serializers::JSON
20
+ include ActiveModel::Serializers::Xml
21
+ include Mongoid::Atomicity
22
+ include Mongoid::Attributes
23
+ include Mongoid::Collections
24
+ include Mongoid::Copyable
25
+ include Mongoid::Dirty
26
+ include Mongoid::Extras
27
+ include Mongoid::Fields
28
+ include Mongoid::Hierarchy
29
+ include Mongoid::Indexes
30
+ include Mongoid::Inspection
31
+ include Mongoid::JSON
32
+ include Mongoid::Keys
33
+ include Mongoid::Matchers
34
+ include Mongoid::MultiParameterAttributes
35
+ include Mongoid::Modifiers
36
+ include Mongoid::NestedAttributes
37
+ include Mongoid::Paths
38
+ include Mongoid::Persistence
39
+ include Mongoid::Relations
40
+ include Mongoid::Safety
41
+ include Mongoid::State
42
+ include Mongoid::Validations
43
+ include Mongoid::Callbacks
39
44
  end
40
45
  end
@@ -1,52 +1,134 @@
1
1
  # encoding: utf-8
2
2
  require "uri"
3
+ require "mongoid/config/database"
3
4
 
4
5
  module Mongoid #:nodoc
5
- class Config #:nodoc
6
- include Singleton
7
6
 
8
- attr_accessor \
9
- :allow_dynamic_fields,
10
- :include_root_in_json,
11
- :reconnect_time,
12
- :parameterize_keys,
13
- :persist_in_safe_mode,
14
- :raise_not_found_error,
15
- :autocreate_indexes,
16
- :skip_version_check
7
+ # This module defines all the configuration options for Mongoid, including the
8
+ # database connections.
9
+ #
10
+ # @todo Durran: This module needs an overhaul, remove singleton, etc.
11
+ module Config
12
+ extend self
17
13
 
18
- # Initializes the configuration with default settings.
19
- def initialize
20
- reset
14
+ attr_accessor :master, :slaves, :settings
15
+ @settings = {}
16
+
17
+ # Define a configuration option with a default.
18
+ #
19
+ # @example Define the option.
20
+ # Config.option(:persist_in_safe_mode, :default => false)
21
+ #
22
+ # @param [ Symbol ] name The name of the configuration option.
23
+ # @param [ Hash ] options Extras for the option.
24
+ #
25
+ # @option options [ Object ] :default The default value.
26
+ #
27
+ # @since 2.0.0.rc.1
28
+ def option(name, options = {})
29
+ define_method(name) do
30
+ settings.has_key?(name) ? settings[name] : options[:default]
31
+ end
32
+ define_method("#{name}=") { |value| settings[name] = value }
33
+ define_method("#{name}?") { send(name) }
21
34
  end
22
35
 
23
- # Sets whether the times returned from the database are in UTC or local time.
24
- # If you omit this setting, then times will be returned in
25
- # the local time zone.
36
+ option :allow_dynamic_fields, :default => true
37
+ option :include_root_in_json, :default => false
38
+ option :parameterize_keys, :default => true
39
+ option :persist_in_safe_mode, :default => false
40
+ option :raise_not_found_error, :default => true
41
+ option :reconnect_time, :default => 3
42
+ option :autocreate_indexes, :default => false
43
+ option :skip_version_check, :default => false
44
+ option :time_zone, :default => nil
45
+
46
+ # Adds a new I18n locale file to the load path.
26
47
  #
27
- # Example:
48
+ # @example Add a portuguese locale.
49
+ # Mongoid::Config.add_language('pt')
28
50
  #
29
- # <tt>Config.use_utc = true</tt>
51
+ # @example Add all available languages.
52
+ # Mongoid::Config.add_language('*')
30
53
  #
31
- # Returns:
54
+ # @param [ String ] language_code The language to add.
55
+ def add_language(language_code = nil)
56
+ Dir[
57
+ File.join(
58
+ File.dirname(__FILE__), "..", "config", "locales", "#{language_code}.yml"
59
+ )
60
+ ].each do |file|
61
+ I18n.load_path << File.expand_path(file)
62
+ end
63
+ end
64
+
65
+ # Get any extra databases that have been configured.
32
66
  #
33
- # A boolean
34
- def use_utc=(value)
35
- @use_utc = value || false
67
+ # @example Get the extras.
68
+ # config.databases
69
+ #
70
+ # @return [ Hash ] A hash of secondary databases.
71
+ def databases
72
+ configure_extras(@settings["databases"]) unless @databases || !@settings
73
+ @databases || {}
36
74
  end
37
75
 
38
- # Returns whether times are return from the database in UTC. If
39
- # this setting is false, then times will be returned in the local time zone.
76
+ # @todo Durran: There were no tests around the databases setter, not sure
77
+ # what the exact expectation was. Set with a hash?
78
+ def databases=(databases)
79
+ end
80
+
81
+ # Return field names that could cause destructive things to happen if
82
+ # defined in a Mongoid::Document.
40
83
  #
41
- # Example:
84
+ # @example Get the destructive fields.
85
+ # config.destructive_fields
42
86
  #
43
- # <tt>Config.use_utc</tt>
87
+ # @return [ Array<String> ] An array of bad field names.
88
+ def destructive_fields
89
+ @destructive_fields ||= lambda {
90
+ klass = Class.new do
91
+ include Mongoid::Document
92
+ end
93
+ klass.instance_methods(true).collect { |method| method.to_s }
94
+ }.call
95
+ end
96
+
97
+ # Configure mongoid from a hash. This is usually called after parsing a
98
+ # yaml config file such as mongoid.yml.
44
99
  #
45
- # Returns:
100
+ # @example Configure Mongoid.
101
+ # config.from_hash({})
46
102
  #
47
- # A boolean
48
- attr_reader :use_utc
49
- alias_method :use_utc?, :use_utc
103
+ # @param [ Hash ] options The settings to use.
104
+ def from_hash(options = {})
105
+ options.except("database", "slaves", "databases").each_pair do |name, value|
106
+ send("#{name}=", value) if respond_to?("#{name}=")
107
+ end
108
+ configure_databases(options)
109
+ configure_extras(options["databases"])
110
+ end
111
+
112
+ # Returns the logger, or defaults to Rails logger or stdout logger.
113
+ #
114
+ # @example Get the logger.
115
+ # config.logger
116
+ #
117
+ # @return [ Logger ] The desired logger.
118
+ def logger
119
+ @logger ||= defined?(Rails) ? Rails.logger : ::Logger.new($stdout)
120
+ end
121
+
122
+ # Sets the logger for Mongoid to use.
123
+ #
124
+ # @example Set the logger.
125
+ # config.logger = Logger.new($stdout, :warn)
126
+ #
127
+ # @return [ Logger ] The newly set logger.
128
+ def logger=(logger)
129
+ @logger = logger
130
+ @master.connection.instance_variable_set(:@logger, logger)
131
+ end
50
132
 
51
133
  # Sets whether the times returned from the database use the ruby or
52
134
  # the ActiveSupport time zone.
@@ -80,31 +162,32 @@ module Mongoid #:nodoc
80
162
  # Sets the Mongo::DB master database to be used. If the object trying to be
81
163
  # set is not a valid +Mongo::DB+, then an error will be raised.
82
164
  #
83
- # Example:
165
+ # @example Set the master database.
166
+ # config.master = Mongo::Connection.db("test")
84
167
  #
85
- # <tt>Config.master = Mongo::Connection.db("test")</tt>
168
+ # @param [ Mongo::DB ] db The master database.
86
169
  #
87
- # Returns:
170
+ # @raise [ Errors::InvalidDatabase ] If the master isnt a valid object.
88
171
  #
89
- # The master +Mongo::DB+ instance.
172
+ # @return [ Mongo::DB ] The master instance.
90
173
  def master=(db)
91
174
  check_database!(db)
92
175
  @master = db
93
176
  end
177
+ alias :database= :master=
94
178
 
95
179
  # Returns the master database, or if none has been set it will raise an
96
180
  # error.
97
181
  #
98
- # Example:
99
- #
100
- # <tt>Config.master</tt>
182
+ # @example Get the master database.
183
+ # config.master
101
184
  #
102
- # Returns:
185
+ # @raise [ Errors::InvalidDatabase ] If the database was not set.
103
186
  #
104
- # The master +Mongo::DB+
187
+ # @return [ Mongo::DB ] The master database.
105
188
  def master
106
189
  unless @master
107
- _master(@settings) if @settings
190
+ configure_databases(@settings) unless @settings.blank?
108
191
  raise Errors::InvalidDatabase.new(nil) unless @master
109
192
  end
110
193
  if @reconnect
@@ -113,20 +196,44 @@ module Mongoid #:nodoc
113
196
  end
114
197
  @master
115
198
  end
116
-
117
199
  alias :database :master
118
- alias :database= :master=
200
+
201
+ # Convenience method for connecting to the master database after forking a
202
+ # new process.
203
+ #
204
+ # @example Reconnect to the master.
205
+ # Mongoid.reconnect!
206
+ #
207
+ # @param [ true, false ] now Perform the reconnection immediately?
208
+ def reconnect!(now = true)
209
+ if now
210
+ master.connection.connect
211
+ else
212
+ # We set a @reconnect flag so that #master knows to reconnect the next
213
+ # time the connection is accessed.
214
+ @reconnect = true
215
+ end
216
+ end
217
+
218
+ # Reset the configuration options to the defaults.
219
+ #
220
+ # @example Reset the configuration options.
221
+ # config.reset
222
+ def reset
223
+ settings.clear
224
+ end
119
225
 
120
226
  # Sets the Mongo::DB slave databases to be used. If the objects provided
121
227
  # are not valid +Mongo::DBs+ an error will be raised.
122
228
  #
123
- # Example:
229
+ # @example Set the slaves.
230
+ # config.slaves = [ Mongo::Connection.db("test") ]
124
231
  #
125
- # <tt>Config.slaves = [ Mongo::Connection.db("test") ]</tt>
232
+ # @param [ Array<Mongo::DB> ] dbs The slave databases.
126
233
  #
127
- # Returns:
234
+ # @raise [ Errors::InvalidDatabase ] If the slaves arent valid objects.
128
235
  #
129
- # The slave DB instances.
236
+ # @return [ Array<Mongo::DB> ] The slave DB instances.
130
237
  def slaves=(dbs)
131
238
  return unless dbs
132
239
  dbs.each do |db|
@@ -137,186 +244,93 @@ module Mongoid #:nodoc
137
244
 
138
245
  # Returns the slave databases or nil if none have been set.
139
246
  #
140
- # Example:
247
+ # @example Get the slaves.
248
+ # config.slaves
141
249
  #
142
- # <tt>Config.slaves</tt>
143
- #
144
- # Returns:
145
- #
146
- # The slave +Mongo::DBs+
250
+ # @return [ Array<Mongo::DB>, nil ] The slave databases.
147
251
  def slaves
148
- _slaves(@settings) unless @slaves || !@settings
149
- @slaves
150
- end
151
-
152
- # Returns the logger, or defaults to Rails logger or stdout logger.
153
- #
154
- # Example:
155
- #
156
- # <tt>Config.logger</tt>
157
- def logger
158
- return @logger if defined?(@logger)
159
-
160
- @logger = defined?(Rails) ? Rails.logger : ::Logger.new($stdout)
161
- end
162
-
163
- # Sets the logger for Mongoid to use.
164
- #
165
- # Example:
166
- #
167
- # <tt>Config.logger = Logger.new($stdout, :warn)</tt>
168
- def logger=(logger)
169
- @logger = logger
170
- end
171
-
172
- # Return field names that could cause destructive things to happen if
173
- # defined in a Mongoid::Document
174
- #
175
- # Example:
176
- #
177
- # <tt>Config.destructive_fields</tt>
178
- #
179
- # Returns:
180
- #
181
- # An array of bad field names.
182
- def destructive_fields
183
- @destructive_fields ||= lambda {
184
- klass = Class.new do
185
- include Mongoid::Document
186
- end
187
- klass.instance_methods(true).collect { |method| method.to_s }
188
- }.call
189
- end
190
-
191
- # Configure mongoid from a hash. This is usually called after parsing a
192
- # yaml config file such as mongoid.yml.
193
- #
194
- # Example:
195
- #
196
- # <tt>Mongoid::Config.instance.from_hash({})</tt>
197
- def from_hash(settings)
198
- settings.except("database", "slaves").each_pair do |name, value|
199
- send("#{name}=", value) if respond_to?("#{name}=")
252
+ unless @slaves
253
+ configure_databases(@settings) if @settings && @settings[:database]
200
254
  end
201
- @settings = settings.dup
255
+ @slaves
202
256
  end
203
257
 
204
- # Adds a new I18n locale file to the load path
205
- #
206
- # Example:
207
- #
208
- # Add portuguese locale
209
- # <tt>Mongoid::config.add_language('pt')</tt>
258
+ # Sets whether the times returned from the database are in UTC or local time.
259
+ # If you omit this setting, then times will be returned in
260
+ # the local time zone.
210
261
  #
211
- # Adds all available languages
212
- # <tt>Mongoid::Config.add_language('*')</tt>
213
- def add_language(language_code = nil)
214
- Dir[File.join(File.dirname(__FILE__), "..", "config", "locales", "#{language_code}.yml")].each do |file|
215
- I18n.load_path << File.expand_path(file)
216
- end
217
- end
218
-
219
- # Convenience method for connecting to the master database after forking a
220
- # new process.
262
+ # @example Set the use of UTC.
263
+ # config.use_utc = true
221
264
  #
222
- # Example:
265
+ # @param [ true, false ] value Whether to use UTC or not.
223
266
  #
224
- # <tt>Mongoid.reconnect!</tt>
225
- def reconnect!(now = true)
226
- if now
227
- master.connection.connect
228
- else
229
- # We set a @reconnect flag so that #master knows to reconnect the next
230
- # time the connection is accessed.
231
- @reconnect = true
232
- end
267
+ # @return [ true, false ] Are we using UTC?
268
+ def use_utc=(value)
269
+ @use_utc = value || false
233
270
  end
234
271
 
235
- # Reset the configuration options to the defaults.
272
+ # Returns whether times are return from the database in UTC. If
273
+ # this setting is false, then times will be returned in the local time zone.
236
274
  #
237
- # Example:
275
+ # @example Are we using UTC?
276
+ # config.use_utc
238
277
  #
239
- # <tt>config.reset</tt>
240
- def reset
241
- @allow_dynamic_fields = true
242
- @include_root_in_json = false
243
- @parameterize_keys = true
244
- @persist_in_safe_mode = false
245
- @raise_not_found_error = true
246
- @reconnect_time = 3
247
- @autocreate_indexes = false
248
- @skip_version_check = false
249
- @time_zone = nil
250
- end
278
+ # @return [ true, false ] True if UTC, false if not.
279
+ attr_reader :use_utc
280
+ alias :use_utc? :use_utc
251
281
 
252
282
  protected
253
283
 
254
284
  # Check if the database is valid and the correct version.
255
285
  #
256
- # Example:
286
+ # @example Check if the database is valid.
287
+ # config.check_database!
257
288
  #
258
- # <tt>config.check_database!</tt>
289
+ # @param [ Mongo::DB ] database The db to check.
290
+ #
291
+ # @raise [ Errors::InvalidDatabase ] If the object is not valid.
292
+ # @raise [ Errors::UnsupportedVersion ] If the db version is too old.
259
293
  def check_database!(database)
260
294
  raise Errors::InvalidDatabase.new(database) unless database.kind_of?(Mongo::DB)
261
- unless Mongoid.skip_version_check
295
+ unless skip_version_check
262
296
  version = database.connection.server_version
263
297
  raise Errors::UnsupportedVersion.new(version) if version < Mongoid::MONGODB_VERSION
264
298
  end
265
299
  end
266
300
 
267
- # Get a master database from settings.
301
+ # Get a database from settings.
268
302
  #
269
- # TODO: Durran: This code's a bit hairy, refactor.
303
+ # @example Configure the master and slave dbs.
304
+ # config.configure_databases("database" => "mongoid")
270
305
  #
271
- # Example:
306
+ # @param [ Hash ] options The options to use.
272
307
  #
273
- # <tt>config._master({}, "test")</tt>
274
- def _master(settings)
275
- mongo_uri = settings["uri"].present? ? URI.parse(settings["uri"]) : OpenStruct.new
276
-
277
- name = settings["database"] || mongo_uri.path.to_s.sub("/", "")
278
- host = settings["host"] || mongo_uri.host || "localhost"
279
- port = settings["port"] || mongo_uri.port || 27017
280
- pool_size = settings["pool_size"] || 1
281
- username = settings["username"] || mongo_uri.user
282
- password = settings["password"] || mongo_uri.password
283
-
284
- connection = Mongo::Connection.new(host, port, :logger => Mongoid::Logger.new, :pool_size => pool_size)
285
- if username || password
286
- connection.add_auth(name, username, password)
287
- connection.apply_saved_authentication
288
- end
289
- self.master = connection.db(name)
308
+ # @option options [ String ] :database The database name.
309
+ # @option options [ String ] :host The database host.
310
+ # @option options [ String ] :password The password for authentication.
311
+ # @option options [ Integer ] :port The port for the database.
312
+ # @option options [ Array<Hash> ] :slaves The slave db options.
313
+ # @option options [ String ] :uri The uri for the database.
314
+ # @option options [ String ] :username The user for authentication.
315
+ #
316
+ # @since 2.0.0.rc.1
317
+ def configure_databases(options)
318
+ @master, @slaves = Database.new(options).configure
290
319
  end
291
320
 
292
- # Get a bunch-o-slaves from settings and names.
321
+ # Get the secondary databases from settings.
293
322
  #
294
- # TODO: Durran: This code's a bit hairy, refactor.
323
+ # @example Configure the master and slave dbs.
324
+ # config.configure_extras("databases" => settings)
295
325
  #
296
- # Example:
326
+ # @param [ Hash ] options The options to use.
297
327
  #
298
- # <tt>config._slaves({}, "test")</tt>
299
- def _slaves(settings)
300
- mongo_uri = settings["uri"].present? ? URI.parse(settings["uri"]) : OpenStruct.new
301
- name = settings["database"] || mongo_uri.path.to_s.sub("/", "")
302
- self.slaves = []
303
- slaves = settings["slaves"]
304
- slaves.to_a.each do |slave|
305
- slave_uri = slave["uri"].present? ? URI.parse(slave["uri"]) : OpenStruct.new
306
- slave_username = slave["username"] || slave_uri.user
307
- slave_password = slave["password"] || slave_uri.password
308
-
309
- slave_connection = Mongo::Connection.new(
310
- slave["host"] || slave_uri.host || "localhost",
311
- slave["port"] || slave_uri.port,
312
- :slave_ok => true
313
- )
314
-
315
- if slave_username || slave_password
316
- slave_connection.add_auth(name, slave_username, slave_password)
317
- slave_connection.apply_saved_authentication
328
+ # @since 2.0.0.rc.1
329
+ def configure_extras(extras)
330
+ @databases = (extras || []).inject({}) do |dbs, (name, options)|
331
+ dbs.tap do |extra|
332
+ dbs[name], dbs["#{name}_slaves"] = Database.new(options).configure
318
333
  end
319
- self.slaves << slave_connection.db(name)
320
334
  end
321
335
  end
322
336
  end