mongoid-with-auth 1.9.4

Sign up to get free protection for your applications and to get access to all the features.
Files changed (104) hide show
  1. data/MIT_LICENSE +20 -0
  2. data/README.rdoc +49 -0
  3. data/lib/mongoid.rb +122 -0
  4. data/lib/mongoid/associations.rb +300 -0
  5. data/lib/mongoid/associations/belongs_to_related.rb +58 -0
  6. data/lib/mongoid/associations/embedded_in.rb +72 -0
  7. data/lib/mongoid/associations/embeds_many.rb +254 -0
  8. data/lib/mongoid/associations/embeds_one.rb +96 -0
  9. data/lib/mongoid/associations/has_many_related.rb +181 -0
  10. data/lib/mongoid/associations/has_one_related.rb +85 -0
  11. data/lib/mongoid/associations/meta_data.rb +29 -0
  12. data/lib/mongoid/associations/options.rb +57 -0
  13. data/lib/mongoid/associations/proxy.rb +24 -0
  14. data/lib/mongoid/attributes.rb +204 -0
  15. data/lib/mongoid/callbacks.rb +23 -0
  16. data/lib/mongoid/collection.rb +120 -0
  17. data/lib/mongoid/collections.rb +41 -0
  18. data/lib/mongoid/collections/cyclic_iterator.rb +34 -0
  19. data/lib/mongoid/collections/master.rb +29 -0
  20. data/lib/mongoid/collections/operations.rb +41 -0
  21. data/lib/mongoid/collections/slaves.rb +45 -0
  22. data/lib/mongoid/components.rb +27 -0
  23. data/lib/mongoid/concern.rb +31 -0
  24. data/lib/mongoid/config.rb +205 -0
  25. data/lib/mongoid/contexts.rb +25 -0
  26. data/lib/mongoid/contexts/enumerable.rb +151 -0
  27. data/lib/mongoid/contexts/ids.rb +25 -0
  28. data/lib/mongoid/contexts/mongo.rb +285 -0
  29. data/lib/mongoid/contexts/paging.rb +50 -0
  30. data/lib/mongoid/criteria.rb +239 -0
  31. data/lib/mongoid/criterion/complex.rb +21 -0
  32. data/lib/mongoid/criterion/exclusion.rb +65 -0
  33. data/lib/mongoid/criterion/inclusion.rb +110 -0
  34. data/lib/mongoid/criterion/optional.rb +136 -0
  35. data/lib/mongoid/cursor.rb +81 -0
  36. data/lib/mongoid/deprecation.rb +22 -0
  37. data/lib/mongoid/dirty.rb +253 -0
  38. data/lib/mongoid/document.rb +311 -0
  39. data/lib/mongoid/errors.rb +108 -0
  40. data/lib/mongoid/extensions.rb +101 -0
  41. data/lib/mongoid/extensions/array/accessors.rb +17 -0
  42. data/lib/mongoid/extensions/array/aliasing.rb +4 -0
  43. data/lib/mongoid/extensions/array/assimilation.rb +26 -0
  44. data/lib/mongoid/extensions/array/conversions.rb +29 -0
  45. data/lib/mongoid/extensions/array/parentization.rb +13 -0
  46. data/lib/mongoid/extensions/big_decimal/conversions.rb +19 -0
  47. data/lib/mongoid/extensions/binary/conversions.rb +17 -0
  48. data/lib/mongoid/extensions/boolean/conversions.rb +22 -0
  49. data/lib/mongoid/extensions/date/conversions.rb +24 -0
  50. data/lib/mongoid/extensions/datetime/conversions.rb +12 -0
  51. data/lib/mongoid/extensions/float/conversions.rb +20 -0
  52. data/lib/mongoid/extensions/hash/accessors.rb +38 -0
  53. data/lib/mongoid/extensions/hash/assimilation.rb +39 -0
  54. data/lib/mongoid/extensions/hash/conversions.rb +45 -0
  55. data/lib/mongoid/extensions/hash/criteria_helpers.rb +20 -0
  56. data/lib/mongoid/extensions/hash/scoping.rb +12 -0
  57. data/lib/mongoid/extensions/integer/conversions.rb +20 -0
  58. data/lib/mongoid/extensions/nil/assimilation.rb +17 -0
  59. data/lib/mongoid/extensions/object/conversions.rb +33 -0
  60. data/lib/mongoid/extensions/objectid/conversions.rb +15 -0
  61. data/lib/mongoid/extensions/proc/scoping.rb +12 -0
  62. data/lib/mongoid/extensions/string/conversions.rb +15 -0
  63. data/lib/mongoid/extensions/string/inflections.rb +97 -0
  64. data/lib/mongoid/extensions/symbol/inflections.rb +36 -0
  65. data/lib/mongoid/extensions/time_conversions.rb +35 -0
  66. data/lib/mongoid/extras.rb +61 -0
  67. data/lib/mongoid/factory.rb +20 -0
  68. data/lib/mongoid/field.rb +59 -0
  69. data/lib/mongoid/fields.rb +65 -0
  70. data/lib/mongoid/finders.rb +136 -0
  71. data/lib/mongoid/identity.rb +39 -0
  72. data/lib/mongoid/indexes.rb +30 -0
  73. data/lib/mongoid/javascript.rb +21 -0
  74. data/lib/mongoid/javascript/functions.yml +37 -0
  75. data/lib/mongoid/matchers.rb +36 -0
  76. data/lib/mongoid/matchers/all.rb +11 -0
  77. data/lib/mongoid/matchers/default.rb +26 -0
  78. data/lib/mongoid/matchers/exists.rb +13 -0
  79. data/lib/mongoid/matchers/gt.rb +11 -0
  80. data/lib/mongoid/matchers/gte.rb +11 -0
  81. data/lib/mongoid/matchers/in.rb +11 -0
  82. data/lib/mongoid/matchers/lt.rb +11 -0
  83. data/lib/mongoid/matchers/lte.rb +11 -0
  84. data/lib/mongoid/matchers/ne.rb +11 -0
  85. data/lib/mongoid/matchers/nin.rb +11 -0
  86. data/lib/mongoid/matchers/size.rb +11 -0
  87. data/lib/mongoid/memoization.rb +33 -0
  88. data/lib/mongoid/named_scope.rb +37 -0
  89. data/lib/mongoid/observable.rb +30 -0
  90. data/lib/mongoid/paths.rb +62 -0
  91. data/lib/mongoid/persistence.rb +222 -0
  92. data/lib/mongoid/persistence/command.rb +39 -0
  93. data/lib/mongoid/persistence/insert.rb +50 -0
  94. data/lib/mongoid/persistence/insert_embedded.rb +38 -0
  95. data/lib/mongoid/persistence/remove.rb +39 -0
  96. data/lib/mongoid/persistence/remove_all.rb +37 -0
  97. data/lib/mongoid/persistence/remove_embedded.rb +50 -0
  98. data/lib/mongoid/persistence/update.rb +63 -0
  99. data/lib/mongoid/scope.rb +75 -0
  100. data/lib/mongoid/state.rb +39 -0
  101. data/lib/mongoid/timestamps.rb +27 -0
  102. data/lib/mongoid/version.rb +4 -0
  103. data/lib/mongoid/versioning.rb +27 -0
  104. metadata +284 -0
@@ -0,0 +1,136 @@
1
+ # encoding: utf-8
2
+ module Mongoid #:nodoc:
3
+ module Criterion #:nodoc:
4
+ module Optional
5
+ # Tells the criteria that the cursor that gets returned needs to be
6
+ # cached. This is so multiple iterations don't hit the database multiple
7
+ # times, however this is not advisable when working with large data sets
8
+ # as the entire results will get stored in memory.
9
+ #
10
+ # Example:
11
+ #
12
+ # <tt>criteria.cache</tt>
13
+ def cache
14
+ @options.merge!(:cache => true); self
15
+ end
16
+
17
+ # Will return true if the cache option has been set.
18
+ #
19
+ # Example:
20
+ #
21
+ # <tt>criteria.cached?</tt>
22
+ def cached?
23
+ @options[:cache] == true
24
+ end
25
+
26
+ # Flags the criteria to execute against a read-only slave in the pool
27
+ # instead of master.
28
+ #
29
+ # Example:
30
+ #
31
+ # <tt>criteria.enslave</tt>
32
+ def enslave
33
+ @options.merge!(:enslave => true); self
34
+ end
35
+
36
+ # Will return true if the criteria is enslaved.
37
+ #
38
+ # Example:
39
+ #
40
+ # <tt>criteria.enslaved?</tt>
41
+ def enslaved?
42
+ @options[:enslave] == true
43
+ end
44
+
45
+ # Adds a criterion to the +Criteria+ that specifies additional options
46
+ # to be passed to the Ruby driver, in the exact format for the driver.
47
+ #
48
+ # Options:
49
+ #
50
+ # extras: A +Hash+ that gets set to the driver options.
51
+ #
52
+ # Example:
53
+ #
54
+ # <tt>criteria.extras(:limit => 20, :skip => 40)</tt>
55
+ #
56
+ # Returns: <tt>self</tt>
57
+ def extras(extras)
58
+ @options.merge!(extras); filter_options; self
59
+ end
60
+
61
+ # Adds a criterion to the +Criteria+ that specifies an id that must be matched.
62
+ #
63
+ # Options:
64
+ #
65
+ # object_id: A +String+ representation of a <tt>BSON::ObjectId</tt>
66
+ #
67
+ # Example:
68
+ #
69
+ # <tt>criteria.id("4ab2bc4b8ad548971900005c")</tt>
70
+ #
71
+ # Returns: <tt>self</tt>
72
+ def id(*args)
73
+ (args.flatten.size > 1) ? self.in(:_id => args.flatten) : (@selector[:_id] = args.first)
74
+ self
75
+ end
76
+
77
+ # Adds a criterion to the +Criteria+ that specifies the maximum number of
78
+ # results to return. This is mostly used in conjunction with <tt>skip()</tt>
79
+ # to handle paginated results.
80
+ #
81
+ # Options:
82
+ #
83
+ # value: An +Integer+ specifying the max number of results. Defaults to 20.
84
+ #
85
+ # Example:
86
+ #
87
+ # <tt>criteria.limit(100)</tt>
88
+ #
89
+ # Returns: <tt>self</tt>
90
+ def limit(value = 20)
91
+ @options[:limit] = value; self
92
+ end
93
+
94
+ # Returns the offset option. If a per_page option is in the list then it
95
+ # will replace it with a skip parameter and return the same value. Defaults
96
+ # to 20 if nothing was provided.
97
+ def offset(*args)
98
+ args.size > 0 ? skip(args.first) : @options[:skip]
99
+ end
100
+
101
+ # Adds a criterion to the +Criteria+ that specifies the sort order of
102
+ # the returned documents in the database. Similar to a SQL "ORDER BY".
103
+ #
104
+ # Options:
105
+ #
106
+ # params: An +Array+ of [field, direction] sorting pairs.
107
+ #
108
+ # Example:
109
+ #
110
+ # <tt>criteria.order_by([[:field1, :asc], [:field2, :desc]])</tt>
111
+ #
112
+ # Returns: <tt>self</tt>
113
+ def order_by(params = [])
114
+ @options[:sort] = params; self
115
+ end
116
+
117
+ # Adds a criterion to the +Criteria+ that specifies how many results to skip
118
+ # when returning Documents. This is mostly used in conjunction with
119
+ # <tt>limit()</tt> to handle paginated results, and is similar to the
120
+ # traditional "offset" parameter.
121
+ #
122
+ # Options:
123
+ #
124
+ # value: An +Integer+ specifying the number of results to skip. Defaults to 0.
125
+ #
126
+ # Example:
127
+ #
128
+ # <tt>criteria.skip(20)</tt>
129
+ #
130
+ # Returns: <tt>self</tt>
131
+ def skip(value = 0)
132
+ @options[:skip] = value; self
133
+ end
134
+ end
135
+ end
136
+ end
@@ -0,0 +1,81 @@
1
+ # encoding: utf-8
2
+ module Mongoid #:nodoc
3
+ class Cursor
4
+ include Enumerable
5
+ # Operations on the Mongo::Cursor object that will not get overriden by the
6
+ # Mongoid::Cursor are defined here.
7
+ OPERATIONS = [
8
+ :close,
9
+ :closed?,
10
+ :count,
11
+ :explain,
12
+ :fields,
13
+ :full_collection_name,
14
+ :hint,
15
+ :limit,
16
+ :order,
17
+ :query_options_hash,
18
+ :query_opts,
19
+ :selector,
20
+ :skip,
21
+ :snapshot,
22
+ :sort,
23
+ :timeout
24
+ ]
25
+
26
+ attr_reader :collection
27
+
28
+ # The operations above will all delegate to the proxied Mongo::Cursor.
29
+ #
30
+ # Example:
31
+ #
32
+ # <tt>cursor.close</tt>
33
+ OPERATIONS.each do |name|
34
+ define_method(name) { |*args| @cursor.send(name, *args) }
35
+ end
36
+
37
+ # Iterate over each document in the cursor and yield to it.
38
+ #
39
+ # Example:
40
+ #
41
+ # <tt>cursor.each { |doc| p doc.title }</tt>
42
+ def each
43
+ @cursor.each do |document|
44
+ yield Mongoid::Factory.build(@klass, document)
45
+ end
46
+ end
47
+
48
+ # Create the new +Mongoid::Cursor+.
49
+ #
50
+ # Options:
51
+ #
52
+ # collection: The Mongoid::Collection instance.
53
+ # cursor: The Mongo::Cursor to be proxied.
54
+ #
55
+ # Example:
56
+ #
57
+ # <tt>Mongoid::Cursor.new(Person, cursor)</tt>
58
+ def initialize(klass, collection, cursor)
59
+ @klass, @collection, @cursor = klass, collection, cursor
60
+ end
61
+
62
+ # Return the next document in the cursor. Will instantiate a new Mongoid
63
+ # document with the attributes.
64
+ #
65
+ # Example:
66
+ #
67
+ # <tt>cursor.next_document</tt>
68
+ def next_document
69
+ Mongoid::Factory.build(@klass, @cursor.next_document)
70
+ end
71
+
72
+ # Returns an array of all the documents in the cursor.
73
+ #
74
+ # Example:
75
+ #
76
+ # <tt>cursor.to_a</tt>
77
+ def to_a
78
+ @cursor.to_a.collect { |attrs| Mongoid::Factory.build(@klass, attrs) }
79
+ end
80
+ end
81
+ end
@@ -0,0 +1,22 @@
1
+ # encoding: utf-8
2
+ module Mongoid #:nodoc:
3
+ class Deprecation #:nodoc
4
+ include Singleton
5
+
6
+ # Alert of a deprecation. This will delegate to the logger and call warn on
7
+ # it.
8
+ #
9
+ # Example:
10
+ #
11
+ # <tt>deprecation.alert("Method no longer used")</tt>
12
+ def alert(message)
13
+ @logger.warn("Deprecation: #{message}")
14
+ end
15
+
16
+ protected
17
+ # Instantiate a new logger to stdout or a rails logger if available.
18
+ def initialize
19
+ @logger = defined?(Rails) ? Rails.logger : Logger.new($stdout)
20
+ end
21
+ end
22
+ end
@@ -0,0 +1,253 @@
1
+ # encoding: utf-8
2
+ module Mongoid #:nodoc:
3
+ module Dirty #:nodoc:
4
+ extend ActiveSupport::Concern
5
+ module InstanceMethods #:nodoc:
6
+ # Gets the changes for a specific field.
7
+ #
8
+ # Example:
9
+ #
10
+ # person = Person.new(:title => "Sir")
11
+ # person.title = "Madam"
12
+ # person.attribute_change("title") # [ "Sir", "Madam" ]
13
+ #
14
+ # Returns:
15
+ #
16
+ # An +Array+ containing the old and new values.
17
+ def attribute_change(name)
18
+ modifications[name]
19
+ end
20
+
21
+ # Determines if a specific field has chaged.
22
+ #
23
+ # Example:
24
+ #
25
+ # person = Person.new(:title => "Sir")
26
+ # person.title = "Madam"
27
+ # person.attribute_changed?("title") # true
28
+ #
29
+ # Returns:
30
+ #
31
+ # +true+ if changed, +false+ if not.
32
+ def attribute_changed?(name)
33
+ modifications.include?(name)
34
+ end
35
+
36
+ # Gets the old value for a specific field.
37
+ #
38
+ # Example:
39
+ #
40
+ # person = Person.new(:title => "Sir")
41
+ # person.title = "Madam"
42
+ # person.attribute_was("title") # "Sir"
43
+ #
44
+ # Returns:
45
+ #
46
+ # The old field value.
47
+ def attribute_was(name)
48
+ change = modifications[name]
49
+ change ? change[0] : nil
50
+ end
51
+
52
+ # Gets the names of all the fields that have changed in the document.
53
+ #
54
+ # Example:
55
+ #
56
+ # person = Person.new(:title => "Sir")
57
+ # person.title = "Madam"
58
+ # person.changed # returns [ "title" ]
59
+ #
60
+ # Returns:
61
+ #
62
+ # An +Array+ of changed field names.
63
+ def changed
64
+ modifications.keys
65
+ end
66
+
67
+ # Alerts to whether the document has been modified or not.
68
+ #
69
+ # Example:
70
+ #
71
+ # person = Person.new(:title => "Sir")
72
+ # person.title = "Madam"
73
+ # person.changed? # returns true
74
+ #
75
+ # Returns:
76
+ #
77
+ # +true+ if changed, +false+ if not.
78
+ def changed?
79
+ !modifications.empty?
80
+ end
81
+
82
+ # Gets all the modifications that have happened to the object as a +Hash+
83
+ # with the keys being the names of the fields, and the values being an
84
+ # +Array+ with the old value and new value.
85
+ #
86
+ # Example:
87
+ #
88
+ # person = Person.new(:title => "Sir")
89
+ # person.title = "Madam"
90
+ # person.changes # returns { "title" => [ "Sir", "Madam" ] }
91
+ #
92
+ # Returns:
93
+ #
94
+ # A +Hash+ of changes.
95
+ def changes
96
+ modifications
97
+ end
98
+
99
+ # Call this method after save, so the changes can be properly switched.
100
+ #
101
+ # Example:
102
+ #
103
+ # <tt>person.move_changes</tt>
104
+ def move_changes
105
+ @previous_modifications = modifications.dup
106
+ @modifications = {}
107
+ end
108
+
109
+ # Gets all the new values for each of the changed fields, to be passed to
110
+ # a MongoDB $set modifier.
111
+ #
112
+ # Example:
113
+ #
114
+ # person = Person.new(:title => "Sir")
115
+ # person.title = "Madam"
116
+ # person.setters # returns { "title" => "Madam" }
117
+ #
118
+ # Returns:
119
+ #
120
+ # A +Hash+ of new values.
121
+ def setters
122
+ modifications.inject({}) do |sets, (field, changes)|
123
+ key = embedded? ? "#{_position}.#{field}" : field
124
+ sets[key] = changes[1]; sets
125
+ end
126
+ end
127
+
128
+ # Gets all the modifications that have happened to the object before the
129
+ # object was saved.
130
+ #
131
+ # Example:
132
+ #
133
+ # person = Person.new(:title => "Sir")
134
+ # person.title = "Madam"
135
+ # person.save!
136
+ # person.previous_changes # returns { "title" => [ "Sir", "Madam" ] }
137
+ #
138
+ # Returns:
139
+ #
140
+ # A +Hash+ of changes before save.
141
+ def previous_changes
142
+ @previous_modifications
143
+ end
144
+
145
+ # Resets a changed field back to its old value.
146
+ #
147
+ # Example:
148
+ #
149
+ # person = Person.new(:title => "Sir")
150
+ # person.title = "Madam"
151
+ # person.reset_attribute!("title")
152
+ # person.title # "Sir"
153
+ #
154
+ # Returns:
155
+ #
156
+ # The old field value.
157
+ def reset_attribute!(name)
158
+ value = attribute_was(name)
159
+ if value
160
+ @attributes[name] = value
161
+ modifications.delete(name)
162
+ end
163
+ end
164
+
165
+ # Sets up the modifications hash. This occurs just after the document is
166
+ # instantiated.
167
+ #
168
+ # Example:
169
+ #
170
+ # <tt>document.setup_notifications</tt>
171
+ def setup_modifications
172
+ @accessed ||= {}
173
+ @modifications ||= {}
174
+ @previous_modifications ||= {}
175
+ end
176
+
177
+ # Reset all modifications for the document. This will wipe all the marked
178
+ # changes, but not reset the values.
179
+ #
180
+ # Example:
181
+ #
182
+ # <tt>document.reset_modifications</tt>
183
+ def reset_modifications
184
+ @accessed = {}
185
+ @modifications = {}
186
+ end
187
+
188
+ protected
189
+
190
+ # Audit the original value for a field that can be modified in place.
191
+ #
192
+ # Example:
193
+ #
194
+ # <tt>person.accessed("aliases", [ "007" ])</tt>
195
+ def accessed(name, value)
196
+ @accessed ||= {}
197
+ @accessed[name] = value.dup if (value.is_a?(Array) || value.is_a?(Hash)) && !@accessed.has_key?(name)
198
+ value
199
+ end
200
+
201
+ # Get all normal modifications plus in place potential changes.
202
+ #
203
+ # Example:
204
+ #
205
+ # <tt>person.modifications</tt>
206
+ #
207
+ # Returns:
208
+ #
209
+ # All changes to the document.
210
+ def modifications
211
+ @accessed.each_pair do |field, value|
212
+ current = @attributes[field]
213
+ @modifications[field] = [ value, current ] if current != value
214
+ end
215
+ @accessed.clear
216
+ @modifications
217
+ end
218
+
219
+ # Audit the change of a field's value.
220
+ #
221
+ # Example:
222
+ #
223
+ # <tt>person.modify("name", "Jack", "John")</tt>
224
+ def modify(name, old_value, new_value)
225
+ @attributes[name] = new_value
226
+ if @modifications && (old_value != new_value)
227
+ original = @modifications[name].first if @modifications[name]
228
+ @modifications[name] = [ (original || old_value), new_value ]
229
+ end
230
+ end
231
+ end
232
+
233
+ module ClassMethods #:nodoc:
234
+ # Add the dynamic dirty methods. These are custom methods defined on a
235
+ # field by field basis that wrap the dirty attribute methods.
236
+ #
237
+ # Example:
238
+ #
239
+ # person = Person.new(:title => "Sir")
240
+ # person.title = "Madam"
241
+ # person.title_change # [ "Sir", "Madam" ]
242
+ # person.title_changed? # true
243
+ # person.title_was # "Sir"
244
+ # person.reset_title!
245
+ def add_dirty_methods(name)
246
+ define_method("#{name}_change") { attribute_change(name) }
247
+ define_method("#{name}_changed?") { attribute_changed?(name) }
248
+ define_method("#{name}_was") { attribute_was(name) }
249
+ define_method("reset_#{name}!") { reset_attribute!(name) }
250
+ end
251
+ end
252
+ end
253
+ end