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.
- data/MIT_LICENSE +20 -0
- data/README.rdoc +47 -0
- data/lib/mongoid.rb +141 -0
- data/lib/mongoid/associations.rb +306 -0
- data/lib/mongoid/associations/embedded_in.rb +74 -0
- data/lib/mongoid/associations/embeds_many.rb +280 -0
- data/lib/mongoid/associations/embeds_one.rb +97 -0
- data/lib/mongoid/associations/foreign_key.rb +35 -0
- data/lib/mongoid/associations/meta_data.rb +38 -0
- data/lib/mongoid/associations/options.rb +62 -0
- data/lib/mongoid/associations/proxy.rb +33 -0
- data/lib/mongoid/associations/referenced_in.rb +59 -0
- data/lib/mongoid/associations/references_many.rb +245 -0
- data/lib/mongoid/associations/references_many_as_array.rb +78 -0
- data/lib/mongoid/associations/references_one.rb +99 -0
- data/lib/mongoid/atomicity.rb +55 -0
- data/lib/mongoid/attributes.rb +242 -0
- data/lib/mongoid/callbacks.rb +21 -0
- data/lib/mongoid/collection.rb +120 -0
- data/lib/mongoid/collections.rb +71 -0
- data/lib/mongoid/collections/cyclic_iterator.rb +34 -0
- data/lib/mongoid/collections/master.rb +29 -0
- data/lib/mongoid/collections/operations.rb +41 -0
- data/lib/mongoid/collections/slaves.rb +45 -0
- data/lib/mongoid/components.rb +34 -0
- data/lib/mongoid/config.rb +263 -0
- data/lib/mongoid/contexts.rb +24 -0
- data/lib/mongoid/contexts/enumerable.rb +156 -0
- data/lib/mongoid/contexts/ids.rb +25 -0
- data/lib/mongoid/contexts/mongo.rb +285 -0
- data/lib/mongoid/contexts/paging.rb +50 -0
- data/lib/mongoid/criteria.rb +248 -0
- data/lib/mongoid/criterion/complex.rb +21 -0
- data/lib/mongoid/criterion/exclusion.rb +65 -0
- data/lib/mongoid/criterion/inclusion.rb +110 -0
- data/lib/mongoid/criterion/optional.rb +189 -0
- data/lib/mongoid/cursor.rb +81 -0
- data/lib/mongoid/deprecation.rb +21 -0
- data/lib/mongoid/dirty.rb +252 -0
- data/lib/mongoid/document.rb +210 -0
- data/lib/mongoid/errors.rb +131 -0
- data/lib/mongoid/extensions.rb +115 -0
- data/lib/mongoid/extensions/array/accessors.rb +17 -0
- data/lib/mongoid/extensions/array/assimilation.rb +26 -0
- data/lib/mongoid/extensions/array/conversions.rb +23 -0
- data/lib/mongoid/extensions/array/parentization.rb +13 -0
- data/lib/mongoid/extensions/big_decimal/conversions.rb +19 -0
- data/lib/mongoid/extensions/binary/conversions.rb +17 -0
- data/lib/mongoid/extensions/boolean/conversions.rb +27 -0
- data/lib/mongoid/extensions/date/conversions.rb +24 -0
- data/lib/mongoid/extensions/datetime/conversions.rb +12 -0
- data/lib/mongoid/extensions/false_class/equality.rb +13 -0
- data/lib/mongoid/extensions/float/conversions.rb +20 -0
- data/lib/mongoid/extensions/hash/accessors.rb +42 -0
- data/lib/mongoid/extensions/hash/assimilation.rb +40 -0
- data/lib/mongoid/extensions/hash/conversions.rb +42 -0
- data/lib/mongoid/extensions/hash/criteria_helpers.rb +20 -0
- data/lib/mongoid/extensions/hash/scoping.rb +12 -0
- data/lib/mongoid/extensions/integer/conversions.rb +20 -0
- data/lib/mongoid/extensions/nil/assimilation.rb +17 -0
- data/lib/mongoid/extensions/object/conversions.rb +21 -0
- data/lib/mongoid/extensions/objectid/conversions.rb +15 -0
- data/lib/mongoid/extensions/proc/scoping.rb +12 -0
- data/lib/mongoid/extensions/set/conversions.rb +20 -0
- data/lib/mongoid/extensions/string/conversions.rb +15 -0
- data/lib/mongoid/extensions/string/inflections.rb +97 -0
- data/lib/mongoid/extensions/symbol/inflections.rb +40 -0
- data/lib/mongoid/extensions/time_conversions.rb +35 -0
- data/lib/mongoid/extensions/true_class/equality.rb +13 -0
- data/lib/mongoid/extras.rb +61 -0
- data/lib/mongoid/factory.rb +20 -0
- data/lib/mongoid/field.rb +83 -0
- data/lib/mongoid/fields.rb +62 -0
- data/lib/mongoid/finders.rb +145 -0
- data/lib/mongoid/hierarchy.rb +74 -0
- data/lib/mongoid/identity.rb +47 -0
- data/lib/mongoid/indexes.rb +27 -0
- data/lib/mongoid/javascript.rb +21 -0
- data/lib/mongoid/javascript/functions.yml +37 -0
- data/lib/mongoid/logger.rb +19 -0
- data/lib/mongoid/matchers.rb +35 -0
- data/lib/mongoid/matchers/all.rb +11 -0
- data/lib/mongoid/matchers/default.rb +26 -0
- data/lib/mongoid/matchers/exists.rb +13 -0
- data/lib/mongoid/matchers/gt.rb +11 -0
- data/lib/mongoid/matchers/gte.rb +11 -0
- data/lib/mongoid/matchers/in.rb +11 -0
- data/lib/mongoid/matchers/lt.rb +11 -0
- data/lib/mongoid/matchers/lte.rb +11 -0
- data/lib/mongoid/matchers/ne.rb +11 -0
- data/lib/mongoid/matchers/nin.rb +11 -0
- data/lib/mongoid/matchers/size.rb +11 -0
- data/lib/mongoid/memoization.rb +33 -0
- data/lib/mongoid/named_scope.rb +37 -0
- data/lib/mongoid/paranoia.rb +106 -0
- data/lib/mongoid/paths.rb +61 -0
- data/lib/mongoid/persistence.rb +216 -0
- data/lib/mongoid/persistence/command.rb +39 -0
- data/lib/mongoid/persistence/insert.rb +48 -0
- data/lib/mongoid/persistence/insert_embedded.rb +44 -0
- data/lib/mongoid/persistence/remove.rb +39 -0
- data/lib/mongoid/persistence/remove_all.rb +38 -0
- data/lib/mongoid/persistence/remove_embedded.rb +50 -0
- data/lib/mongoid/persistence/update.rb +71 -0
- data/lib/mongoid/railtie.rb +67 -0
- data/lib/mongoid/railties/database.rake +60 -0
- data/lib/mongoid/scope.rb +75 -0
- data/lib/mongoid/state.rb +32 -0
- data/lib/mongoid/timestamps.rb +27 -0
- data/lib/mongoid/validations.rb +51 -0
- data/lib/mongoid/validations/associated.rb +32 -0
- data/lib/mongoid/validations/locale/en.yml +5 -0
- data/lib/mongoid/validations/uniqueness.rb +56 -0
- data/lib/mongoid/version.rb +4 -0
- data/lib/mongoid/versioning.rb +26 -0
- data/lib/rails/generators/mongoid/config/config_generator.rb +25 -0
- data/lib/rails/generators/mongoid/config/templates/mongoid.yml +24 -0
- data/lib/rails/generators/mongoid/model/model_generator.rb +24 -0
- data/lib/rails/generators/mongoid/model/templates/model.rb +15 -0
- data/lib/rails/generators/mongoid_generator.rb +61 -0
- data/spec/integration/mongoid/association_attributes_spec.rb +71 -0
- data/spec/integration/mongoid/associations_spec.rb +768 -0
- data/spec/integration/mongoid/attributes_spec.rb +59 -0
- data/spec/integration/mongoid/callback_spec.rb +33 -0
- data/spec/integration/mongoid/contexts/enumerable_spec.rb +33 -0
- data/spec/integration/mongoid/criteria_spec.rb +281 -0
- data/spec/integration/mongoid/dirty_spec.rb +85 -0
- data/spec/integration/mongoid/document_spec.rb +741 -0
- data/spec/integration/mongoid/extensions_spec.rb +22 -0
- data/spec/integration/mongoid/finders_spec.rb +119 -0
- data/spec/integration/mongoid/inheritance_spec.rb +171 -0
- data/spec/integration/mongoid/named_scope_spec.rb +58 -0
- data/spec/integration/mongoid/paranoia_spec.rb +44 -0
- data/spec/integration/mongoid/persistence/update_spec.rb +46 -0
- data/spec/integration/mongoid/persistence_spec.rb +311 -0
- data/spec/integration/mongoid/validations/uniqueness_spec.rb +206 -0
- data/spec/models/account.rb +5 -0
- data/spec/models/address.rb +40 -0
- data/spec/models/agent.rb +7 -0
- data/spec/models/animal.rb +15 -0
- data/spec/models/answer.rb +4 -0
- data/spec/models/callbacks.rb +47 -0
- data/spec/models/category.rb +13 -0
- data/spec/models/comment.rb +10 -0
- data/spec/models/country_code.rb +6 -0
- data/spec/models/employer.rb +5 -0
- data/spec/models/favorite.rb +8 -0
- data/spec/models/game.rb +9 -0
- data/spec/models/inheritance.rb +72 -0
- data/spec/models/location.rb +5 -0
- data/spec/models/login.rb +6 -0
- data/spec/models/mixed_drink.rb +4 -0
- data/spec/models/name.rb +13 -0
- data/spec/models/namespacing.rb +11 -0
- data/spec/models/paranoid_post.rb +18 -0
- data/spec/models/parents.rb +32 -0
- data/spec/models/patient.rb +15 -0
- data/spec/models/person.rb +106 -0
- data/spec/models/pet.rb +7 -0
- data/spec/models/pet_owner.rb +6 -0
- data/spec/models/phone.rb +7 -0
- data/spec/models/post.rb +25 -0
- data/spec/models/preference.rb +7 -0
- data/spec/models/question.rb +8 -0
- data/spec/models/survey.rb +6 -0
- data/spec/models/translation.rb +5 -0
- data/spec/models/user.rb +6 -0
- data/spec/models/user_accout.rb +5 -0
- data/spec/models/vet_visit.rb +5 -0
- data/spec/models/video.rb +5 -0
- data/spec/spec_helper.rb +33 -0
- data/spec/unit/mongoid/associations/embedded_in_spec.rb +193 -0
- data/spec/unit/mongoid/associations/embeds_many_spec.rb +626 -0
- data/spec/unit/mongoid/associations/embeds_one_spec.rb +287 -0
- data/spec/unit/mongoid/associations/foreign_key_spec.rb +90 -0
- data/spec/unit/mongoid/associations/meta_data_spec.rb +110 -0
- data/spec/unit/mongoid/associations/options_spec.rb +215 -0
- data/spec/unit/mongoid/associations/referenced_in_spec.rb +145 -0
- data/spec/unit/mongoid/associations/references_many_as_array_spec.rb +424 -0
- data/spec/unit/mongoid/associations/references_many_spec.rb +502 -0
- data/spec/unit/mongoid/associations/references_one_spec.rb +204 -0
- data/spec/unit/mongoid/associations_spec.rb +688 -0
- data/spec/unit/mongoid/atomicity_spec.rb +164 -0
- data/spec/unit/mongoid/attributes_spec.rb +646 -0
- data/spec/unit/mongoid/callbacks_spec.rb +85 -0
- data/spec/unit/mongoid/collection_spec.rb +187 -0
- data/spec/unit/mongoid/collections/cyclic_iterator_spec.rb +75 -0
- data/spec/unit/mongoid/collections/master_spec.rb +41 -0
- data/spec/unit/mongoid/collections/slaves_spec.rb +81 -0
- data/spec/unit/mongoid/collections_spec.rb +98 -0
- data/spec/unit/mongoid/config_spec.rb +298 -0
- data/spec/unit/mongoid/contexts/enumerable_spec.rb +447 -0
- data/spec/unit/mongoid/contexts/mongo_spec.rb +703 -0
- data/spec/unit/mongoid/contexts_spec.rb +25 -0
- data/spec/unit/mongoid/criteria_spec.rb +873 -0
- data/spec/unit/mongoid/criterion/complex_spec.rb +17 -0
- data/spec/unit/mongoid/criterion/exclusion_spec.rb +121 -0
- data/spec/unit/mongoid/criterion/inclusion_spec.rb +274 -0
- data/spec/unit/mongoid/criterion/optional_spec.rb +483 -0
- data/spec/unit/mongoid/cursor_spec.rb +80 -0
- data/spec/unit/mongoid/deprecation_spec.rb +24 -0
- data/spec/unit/mongoid/dirty_spec.rb +430 -0
- data/spec/unit/mongoid/document_spec.rb +623 -0
- data/spec/unit/mongoid/errors_spec.rb +154 -0
- data/spec/unit/mongoid/extensions/array/accessors_spec.rb +50 -0
- data/spec/unit/mongoid/extensions/array/assimilation_spec.rb +24 -0
- data/spec/unit/mongoid/extensions/array/conversions_spec.rb +52 -0
- data/spec/unit/mongoid/extensions/array/parentization_spec.rb +20 -0
- data/spec/unit/mongoid/extensions/big_decimal/conversions_spec.rb +36 -0
- data/spec/unit/mongoid/extensions/binary/conversions_spec.rb +22 -0
- data/spec/unit/mongoid/extensions/boolean/conversions_spec.rb +49 -0
- data/spec/unit/mongoid/extensions/date/conversions_spec.rb +145 -0
- data/spec/unit/mongoid/extensions/datetime/conversions_spec.rb +14 -0
- data/spec/unit/mongoid/extensions/false_class/equality_spec.rb +35 -0
- data/spec/unit/mongoid/extensions/float/conversions_spec.rb +61 -0
- data/spec/unit/mongoid/extensions/hash/accessors_spec.rb +184 -0
- data/spec/unit/mongoid/extensions/hash/assimilation_spec.rb +59 -0
- data/spec/unit/mongoid/extensions/hash/conversions_spec.rb +35 -0
- data/spec/unit/mongoid/extensions/hash/criteria_helpers_spec.rb +17 -0
- data/spec/unit/mongoid/extensions/hash/scoping_spec.rb +14 -0
- data/spec/unit/mongoid/extensions/integer/conversions_spec.rb +61 -0
- data/spec/unit/mongoid/extensions/nil/assimilation_spec.rb +29 -0
- data/spec/unit/mongoid/extensions/object/conversions_spec.rb +44 -0
- data/spec/unit/mongoid/extensions/objectid/conversions_spec.rb +22 -0
- data/spec/unit/mongoid/extensions/proc/scoping_spec.rb +34 -0
- data/spec/unit/mongoid/extensions/set/conversions_spec.rb +21 -0
- data/spec/unit/mongoid/extensions/string/conversions_spec.rb +28 -0
- data/spec/unit/mongoid/extensions/string/inflections_spec.rb +208 -0
- data/spec/unit/mongoid/extensions/symbol/inflections_spec.rb +107 -0
- data/spec/unit/mongoid/extensions/time_conversions_spec.rb +186 -0
- data/spec/unit/mongoid/extensions/true_class/equality_spec.rb +35 -0
- data/spec/unit/mongoid/extras_spec.rb +102 -0
- data/spec/unit/mongoid/factory_spec.rb +31 -0
- data/spec/unit/mongoid/field_spec.rb +169 -0
- data/spec/unit/mongoid/fields_spec.rb +181 -0
- data/spec/unit/mongoid/finders_spec.rb +439 -0
- data/spec/unit/mongoid/hierarchy_spec.rb +68 -0
- data/spec/unit/mongoid/identity_spec.rb +109 -0
- data/spec/unit/mongoid/indexes_spec.rb +99 -0
- data/spec/unit/mongoid/javascript_spec.rb +48 -0
- data/spec/unit/mongoid/logger_spec.rb +38 -0
- data/spec/unit/mongoid/matchers/all_spec.rb +27 -0
- data/spec/unit/mongoid/matchers/default_spec.rb +27 -0
- data/spec/unit/mongoid/matchers/exists_spec.rb +56 -0
- data/spec/unit/mongoid/matchers/gt_spec.rb +39 -0
- data/spec/unit/mongoid/matchers/gte_spec.rb +49 -0
- data/spec/unit/mongoid/matchers/in_spec.rb +27 -0
- data/spec/unit/mongoid/matchers/lt_spec.rb +39 -0
- data/spec/unit/mongoid/matchers/lte_spec.rb +49 -0
- data/spec/unit/mongoid/matchers/ne_spec.rb +27 -0
- data/spec/unit/mongoid/matchers/nin_spec.rb +27 -0
- data/spec/unit/mongoid/matchers/size_spec.rb +27 -0
- data/spec/unit/mongoid/matchers_spec.rb +329 -0
- data/spec/unit/mongoid/memoization_spec.rb +75 -0
- data/spec/unit/mongoid/named_scope_spec.rb +123 -0
- data/spec/unit/mongoid/paranoia_spec.rb +108 -0
- data/spec/unit/mongoid/paths_spec.rb +272 -0
- data/spec/unit/mongoid/persistence/insert_embedded_spec.rb +154 -0
- data/spec/unit/mongoid/persistence/insert_spec.rb +144 -0
- data/spec/unit/mongoid/persistence/remove_all_spec.rb +82 -0
- data/spec/unit/mongoid/persistence/remove_embedded_spec.rb +152 -0
- data/spec/unit/mongoid/persistence/remove_spec.rb +89 -0
- data/spec/unit/mongoid/persistence/update_spec.rb +177 -0
- data/spec/unit/mongoid/persistence_spec.rb +452 -0
- data/spec/unit/mongoid/scope_spec.rb +240 -0
- data/spec/unit/mongoid/serialization_spec.rb +43 -0
- data/spec/unit/mongoid/state_spec.rb +94 -0
- data/spec/unit/mongoid/timestamps_spec.rb +30 -0
- data/spec/unit/mongoid/validations/associated_spec.rb +103 -0
- data/spec/unit/mongoid/validations/uniqueness_spec.rb +201 -0
- data/spec/unit/mongoid/validations_spec.rb +43 -0
- data/spec/unit/mongoid/versioning_spec.rb +41 -0
- data/spec/unit/mongoid_spec.rb +46 -0
- 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
|