mongoid-rails2 1.9.3

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/associations/belongs_to_related.rb +58 -0
  4. data/lib/mongoid/associations/embedded_in.rb +72 -0
  5. data/lib/mongoid/associations/embeds_many.rb +254 -0
  6. data/lib/mongoid/associations/embeds_one.rb +96 -0
  7. data/lib/mongoid/associations/has_many_related.rb +181 -0
  8. data/lib/mongoid/associations/has_one_related.rb +85 -0
  9. data/lib/mongoid/associations/meta_data.rb +29 -0
  10. data/lib/mongoid/associations/options.rb +57 -0
  11. data/lib/mongoid/associations/proxy.rb +24 -0
  12. data/lib/mongoid/associations.rb +300 -0
  13. data/lib/mongoid/attributes.rb +204 -0
  14. data/lib/mongoid/callbacks.rb +23 -0
  15. data/lib/mongoid/collection.rb +120 -0
  16. data/lib/mongoid/collections/cyclic_iterator.rb +34 -0
  17. data/lib/mongoid/collections/master.rb +29 -0
  18. data/lib/mongoid/collections/operations.rb +41 -0
  19. data/lib/mongoid/collections/slaves.rb +45 -0
  20. data/lib/mongoid/collections.rb +41 -0
  21. data/lib/mongoid/components.rb +27 -0
  22. data/lib/mongoid/concern.rb +31 -0
  23. data/lib/mongoid/config.rb +191 -0
  24. data/lib/mongoid/contexts/enumerable.rb +151 -0
  25. data/lib/mongoid/contexts/ids.rb +25 -0
  26. data/lib/mongoid/contexts/mongo.rb +285 -0
  27. data/lib/mongoid/contexts/paging.rb +50 -0
  28. data/lib/mongoid/contexts.rb +25 -0
  29. data/lib/mongoid/criteria.rb +249 -0
  30. data/lib/mongoid/criterion/complex.rb +21 -0
  31. data/lib/mongoid/criterion/exclusion.rb +65 -0
  32. data/lib/mongoid/criterion/inclusion.rb +110 -0
  33. data/lib/mongoid/criterion/optional.rb +136 -0
  34. data/lib/mongoid/cursor.rb +81 -0
  35. data/lib/mongoid/deprecation.rb +22 -0
  36. data/lib/mongoid/dirty.rb +253 -0
  37. data/lib/mongoid/document.rb +311 -0
  38. data/lib/mongoid/errors.rb +108 -0
  39. data/lib/mongoid/extensions/array/accessors.rb +17 -0
  40. data/lib/mongoid/extensions/array/aliasing.rb +4 -0
  41. data/lib/mongoid/extensions/array/assimilation.rb +26 -0
  42. data/lib/mongoid/extensions/array/conversions.rb +29 -0
  43. data/lib/mongoid/extensions/array/parentization.rb +13 -0
  44. data/lib/mongoid/extensions/big_decimal/conversions.rb +19 -0
  45. data/lib/mongoid/extensions/binary/conversions.rb +17 -0
  46. data/lib/mongoid/extensions/boolean/conversions.rb +22 -0
  47. data/lib/mongoid/extensions/date/conversions.rb +24 -0
  48. data/lib/mongoid/extensions/datetime/conversions.rb +12 -0
  49. data/lib/mongoid/extensions/float/conversions.rb +20 -0
  50. data/lib/mongoid/extensions/hash/accessors.rb +38 -0
  51. data/lib/mongoid/extensions/hash/assimilation.rb +39 -0
  52. data/lib/mongoid/extensions/hash/conversions.rb +45 -0
  53. data/lib/mongoid/extensions/hash/criteria_helpers.rb +21 -0
  54. data/lib/mongoid/extensions/hash/scoping.rb +12 -0
  55. data/lib/mongoid/extensions/integer/conversions.rb +20 -0
  56. data/lib/mongoid/extensions/nil/assimilation.rb +17 -0
  57. data/lib/mongoid/extensions/object/conversions.rb +33 -0
  58. data/lib/mongoid/extensions/objectid/conversions.rb +15 -0
  59. data/lib/mongoid/extensions/proc/scoping.rb +12 -0
  60. data/lib/mongoid/extensions/string/conversions.rb +15 -0
  61. data/lib/mongoid/extensions/string/inflections.rb +97 -0
  62. data/lib/mongoid/extensions/symbol/inflections.rb +36 -0
  63. data/lib/mongoid/extensions/time_conversions.rb +35 -0
  64. data/lib/mongoid/extensions.rb +101 -0
  65. data/lib/mongoid/extras.rb +61 -0
  66. data/lib/mongoid/factory.rb +20 -0
  67. data/lib/mongoid/field.rb +59 -0
  68. data/lib/mongoid/fields.rb +65 -0
  69. data/lib/mongoid/finders.rb +144 -0
  70. data/lib/mongoid/identity.rb +39 -0
  71. data/lib/mongoid/indexes.rb +30 -0
  72. data/lib/mongoid/javascript/functions.yml +37 -0
  73. data/lib/mongoid/javascript.rb +21 -0
  74. data/lib/mongoid/matchers/all.rb +11 -0
  75. data/lib/mongoid/matchers/default.rb +26 -0
  76. data/lib/mongoid/matchers/exists.rb +13 -0
  77. data/lib/mongoid/matchers/gt.rb +11 -0
  78. data/lib/mongoid/matchers/gte.rb +11 -0
  79. data/lib/mongoid/matchers/in.rb +11 -0
  80. data/lib/mongoid/matchers/lt.rb +11 -0
  81. data/lib/mongoid/matchers/lte.rb +11 -0
  82. data/lib/mongoid/matchers/ne.rb +11 -0
  83. data/lib/mongoid/matchers/nin.rb +11 -0
  84. data/lib/mongoid/matchers/size.rb +11 -0
  85. data/lib/mongoid/matchers.rb +36 -0
  86. data/lib/mongoid/memoization.rb +33 -0
  87. data/lib/mongoid/named_scope.rb +37 -0
  88. data/lib/mongoid/observable.rb +30 -0
  89. data/lib/mongoid/paths.rb +62 -0
  90. data/lib/mongoid/persistence/command.rb +39 -0
  91. data/lib/mongoid/persistence/insert.rb +50 -0
  92. data/lib/mongoid/persistence/insert_embedded.rb +38 -0
  93. data/lib/mongoid/persistence/remove.rb +39 -0
  94. data/lib/mongoid/persistence/remove_all.rb +37 -0
  95. data/lib/mongoid/persistence/remove_embedded.rb +50 -0
  96. data/lib/mongoid/persistence/update.rb +63 -0
  97. data/lib/mongoid/persistence.rb +222 -0
  98. data/lib/mongoid/scope.rb +75 -0
  99. data/lib/mongoid/state.rb +39 -0
  100. data/lib/mongoid/timestamps.rb +27 -0
  101. data/lib/mongoid/version.rb +4 -0
  102. data/lib/mongoid/versioning.rb +27 -0
  103. data/lib/mongoid.rb +122 -0
  104. metadata +298 -0
@@ -0,0 +1,101 @@
1
+ # encoding: utf-8
2
+ require "mongoid/extensions/time_conversions"
3
+ require "mongoid/extensions/array/accessors"
4
+ require "mongoid/extensions/array/aliasing"
5
+ require "mongoid/extensions/array/assimilation"
6
+ require "mongoid/extensions/array/conversions"
7
+ require "mongoid/extensions/array/parentization"
8
+ require "mongoid/extensions/big_decimal/conversions"
9
+ require "mongoid/extensions/binary/conversions"
10
+ require "mongoid/extensions/boolean/conversions"
11
+ require "mongoid/extensions/date/conversions"
12
+ require "mongoid/extensions/datetime/conversions"
13
+ require "mongoid/extensions/float/conversions"
14
+ require "mongoid/extensions/hash/accessors"
15
+ require "mongoid/extensions/hash/assimilation"
16
+ require "mongoid/extensions/hash/conversions"
17
+ require "mongoid/extensions/hash/criteria_helpers"
18
+ require "mongoid/extensions/hash/scoping"
19
+ require "mongoid/extensions/integer/conversions"
20
+ require "mongoid/extensions/nil/assimilation"
21
+ require "mongoid/extensions/object/conversions"
22
+ require "mongoid/extensions/proc/scoping"
23
+ require "mongoid/extensions/string/conversions"
24
+ require "mongoid/extensions/string/inflections"
25
+ require "mongoid/extensions/symbol/inflections"
26
+ require "mongoid/extensions/objectid/conversions"
27
+
28
+ class Array #:nodoc
29
+ include Mongoid::Extensions::Array::Accessors
30
+ include Mongoid::Extensions::Array::Assimilation
31
+ include Mongoid::Extensions::Array::Conversions
32
+ include Mongoid::Extensions::Array::Parentization
33
+ end
34
+
35
+ class BigDecimal #:nodoc
36
+ extend Mongoid::Extensions::BigDecimal::Conversions
37
+ end
38
+
39
+ class Binary #:nodoc
40
+ extend Mongoid::Extensions::Binary::Conversions
41
+ end
42
+
43
+ class Boolean #:nodoc
44
+ extend Mongoid::Extensions::Boolean::Conversions
45
+ end
46
+
47
+ class DateTime #:nodoc
48
+ extend Mongoid::Extensions::TimeConversions
49
+ extend Mongoid::Extensions::DateTime::Conversions
50
+ end
51
+
52
+ class Date #:nodoc
53
+ extend Mongoid::Extensions::TimeConversions
54
+ extend Mongoid::Extensions::Date::Conversions
55
+ end
56
+
57
+ class Float #:nodoc
58
+ extend Mongoid::Extensions::Float::Conversions
59
+ end
60
+
61
+ class Hash #:nodoc
62
+ include Mongoid::Extensions::Hash::Accessors
63
+ include Mongoid::Extensions::Hash::Assimilation
64
+ include Mongoid::Extensions::Hash::CriteriaHelpers
65
+ include Mongoid::Extensions::Hash::Scoping
66
+ include Mongoid::Extensions::Hash::Conversions
67
+ end
68
+
69
+ class Integer #:nodoc
70
+ extend Mongoid::Extensions::Integer::Conversions
71
+ end
72
+
73
+ class NilClass #:nodoc
74
+ include Mongoid::Extensions::Nil::Assimilation
75
+ end
76
+
77
+ class Object #:nodoc:
78
+ include Mongoid::Extensions::Object::Conversions
79
+ end
80
+
81
+ class Proc #:nodoc:
82
+ include Mongoid::Extensions::Proc::Scoping
83
+ end
84
+
85
+ class String #:nodoc
86
+ include Mongoid::Extensions::String::Inflections
87
+ extend Mongoid::Extensions::String::Conversions
88
+ end
89
+
90
+ class Symbol #:nodoc
91
+ remove_method :size if instance_methods.include? :size # temporal fix for ruby 1.9
92
+ include Mongoid::Extensions::Symbol::Inflections
93
+ end
94
+
95
+ class Time #:nodoc
96
+ extend Mongoid::Extensions::TimeConversions
97
+ end
98
+
99
+ class BSON::ObjectId #:nodoc
100
+ extend Mongoid::Extensions::ObjectId::Conversions
101
+ end
@@ -0,0 +1,61 @@
1
+ # encoding: utf-8
2
+ module Mongoid #:nodoc:
3
+ module Extras #:nodoc:
4
+ extend ActiveSupport::Concern
5
+ included do
6
+ class_inheritable_accessor :cached, :enslaved
7
+ self.cached = false
8
+ self.enslaved = false
9
+ delegate :cached?, :enslaved?, :to => "self.class"
10
+ end
11
+
12
+ module ClassMethods #:nodoc
13
+ # Sets caching on for this class. This class level configuration will
14
+ # default all queries to cache the results of the first iteration over
15
+ # the cursor into an internal array. This should only be used for queries
16
+ # that return a small number of results or have small documents, as after
17
+ # the first iteration the entire results will be stored in memory.
18
+ #
19
+ # Example:
20
+ #
21
+ # class Person
22
+ # include Mongoid::Document
23
+ # cache
24
+ # end
25
+ def cache
26
+ self.cached = true
27
+ end
28
+
29
+ # Determines if the class is cached or not.
30
+ #
31
+ # Returns:
32
+ #
33
+ # True if cached, false if not.
34
+ def cached?
35
+ !!self.cached
36
+ end
37
+
38
+ # Set whether or not this documents read operations should delegate to
39
+ # the slave database by default.
40
+ #
41
+ # Example:
42
+ #
43
+ # class Person
44
+ # include Mongoid::Document
45
+ # enslave
46
+ # end
47
+ def enslave
48
+ self.enslaved = true
49
+ end
50
+
51
+ # Determines if the class is enslaved or not.
52
+ #
53
+ # Returns:
54
+ #
55
+ # True if enslaved, false if not.
56
+ def enslaved?
57
+ !!self.enslaved
58
+ end
59
+ end
60
+ end
61
+ end
@@ -0,0 +1,20 @@
1
+ # encoding: utf-8
2
+ module Mongoid #:nodoc:
3
+ class Factory #:nodoc:
4
+ # Builds a new +Document+ from the supplied attributes.
5
+ #
6
+ # Example:
7
+ #
8
+ # <tt>Mongoid::Factory.build(Person, {})</tt>
9
+ #
10
+ # Options:
11
+ #
12
+ # klass: The class to instantiate from if _type is not present.
13
+ # attributes: The +Document+ attributes.
14
+ def self.build(klass, attributes)
15
+ attrs = {}.merge(attributes)
16
+ type = attrs["_type"]
17
+ type ? type.constantize.instantiate(attrs) : klass.instantiate(attrs)
18
+ end
19
+ end
20
+ end
@@ -0,0 +1,59 @@
1
+ # encoding: utf-8
2
+ module Mongoid #:nodoc:
3
+ class Field
4
+ attr_reader :name, :type
5
+
6
+ # Determine if the field is able to be accessible via a mass update.
7
+ #
8
+ # Returns:
9
+ #
10
+ # true if accessible, false if not.
11
+ def accessible?
12
+ !!@accessible
13
+ end
14
+
15
+ # Get the default value for the field.
16
+ #
17
+ # Returns:
18
+ #
19
+ # The primitive value or a copy of the default.
20
+ def default
21
+ copy
22
+ end
23
+
24
+ # Create the new field with a name and optional additional options. Valid
25
+ # options are :default
26
+ #
27
+ # Options:
28
+ #
29
+ # name: The name of the field as a +Symbol+.
30
+ # options: A +Hash+ of options for the field.
31
+ #
32
+ # Example:
33
+ #
34
+ # <tt>Field.new(:score, :default => 0)</tt>
35
+ def initialize(name, options = {})
36
+ @name, @default = name, options[:default]
37
+ @copyable = (@default.is_a?(Array) || @default.is_a?(Hash))
38
+ @type = options[:type] || String
39
+ @accessible = options.has_key?(:accessible) ? options[:accessible] : true
40
+ end
41
+
42
+ # Used for setting an object in the attributes hash. If nil is provided the
43
+ # default will get returned if it exists.
44
+ def set(object)
45
+ type.set(object)
46
+ end
47
+
48
+ # Used for retrieving the object out of the attributes hash.
49
+ def get(object)
50
+ type.get(object)
51
+ end
52
+
53
+ protected
54
+ # Slightly faster default check.
55
+ def copy
56
+ @copyable ? @default.dup : @default
57
+ end
58
+ end
59
+ end
@@ -0,0 +1,65 @@
1
+ # encoding: utf-8
2
+ module Mongoid #:nodoc
3
+ module Fields #:nodoc
4
+ def self.included(base)
5
+ base.class_eval do
6
+ extend ClassMethods
7
+ # Set up the class attributes that must be available to all subclasses.
8
+ # These include defaults, fields
9
+ class_inheritable_accessor :fields
10
+
11
+ self.fields = {}
12
+
13
+ delegate :defaults, :fields, :to => "self.class"
14
+ end
15
+ end
16
+
17
+ module ClassMethods #:nodoc
18
+ # Defines all the fields that are accessable on the Document
19
+ # For each field that is defined, a getter and setter will be
20
+ # added as an instance method to the Document.
21
+ #
22
+ # Options:
23
+ #
24
+ # name: The name of the field, as a +Symbol+.
25
+ # options: A +Hash+ of options to supply to the +Field+.
26
+ #
27
+ # Example:
28
+ #
29
+ # <tt>field :score, :default => 0</tt>
30
+ def field(name, options = {})
31
+ access = name.to_s
32
+ set_field(access, options)
33
+ end
34
+
35
+ # Returns the default values for the fields on the document
36
+ def defaults
37
+ fields.inject({}) do |defs,(field_name,field)|
38
+ next(defs) if field.default.nil?
39
+ defs[field_name.to_s] = field.default
40
+ defs
41
+ end
42
+ end
43
+
44
+ protected
45
+ # Define a field attribute for the +Document+.
46
+ def set_field(name, options = {})
47
+ meth = options.delete(:as) || name
48
+ fields[name] = Field.new(name, options)
49
+ create_accessors(name, meth, options)
50
+ add_dirty_methods(name)
51
+ end
52
+
53
+ # Create the field accessors.
54
+ def create_accessors(name, meth, options = {})
55
+ define_method(meth) { read_attribute(name) }
56
+ define_method("#{meth}=") { |value| write_attribute(name, value) }
57
+ define_method("#{meth}?") do
58
+ attr = read_attribute(name)
59
+ (options[:type] == Boolean) ? attr == true : attr.present?
60
+ end
61
+ end
62
+
63
+ end
64
+ end
65
+ end
@@ -0,0 +1,144 @@
1
+ # encoding: utf-8
2
+ module Mongoid #:nodoc:
3
+ module Finders #:nodoc:
4
+
5
+ # Delegate to the criteria methods that are natural for creating a new
6
+ # criteria.
7
+ [ :all_in, :any_in, :avg, :excludes, :limit, :max, :min,
8
+ :not_in, :only, :order_by, :skip, :sum, :where ].each do |name|
9
+ define_method(name) do |*args|
10
+ criteria.send(name, *args)
11
+ end
12
+ end
13
+
14
+ # Find +Documents+ given the conditions.
15
+ #
16
+ # Options:
17
+ #
18
+ # args: A +Hash+ with a conditions key and other options
19
+ #
20
+ # <tt>Person.all(:conditions => { :attribute => "value" })</tt>
21
+ def all(*args)
22
+ find(:all, *args)
23
+ end
24
+
25
+ # Returns a count of matching records in the database based on the
26
+ # provided arguments.
27
+ #
28
+ # <tt>Person.count(:first, :conditions => { :attribute => "value" })</tt>
29
+ def count(*args)
30
+ Criteria.translate(self, *args).count
31
+ end
32
+
33
+ # Returns true if there are on document in database based on the
34
+ # provided arguments.
35
+ #
36
+ # <tt>Person.exists?(:conditions => { :attribute => "value" })</tt>
37
+ def exists?(*args)
38
+ Criteria.translate(self, *args).limit(1).count == 1
39
+ end
40
+
41
+ # Helper to initialize a new +Criteria+ object for this class.
42
+ #
43
+ # Example:
44
+ #
45
+ # <tt>Person.criteria</tt>
46
+ def criteria
47
+ Criteria.new(self)
48
+ end
49
+
50
+ # Find a +Document+ in several different ways.
51
+ #
52
+ # If a +String+ is provided, it will be assumed that it is a
53
+ # representation of a Mongo::ObjectId and will attempt to find a single
54
+ # +Document+ based on that id. If a +Symbol+ and +Hash+ is provided then
55
+ # it will attempt to find either a single +Document+ or multiples based
56
+ # on the conditions provided and the first parameter.
57
+ #
58
+ # <tt>Person.find(:first, :conditions => { :attribute => "value" })</tt>
59
+ #
60
+ # <tt>Person.find(:all, :conditions => { :attribute => "value" })</tt>
61
+ #
62
+ # <tt>Person.find(Mongo::ObjectId.new.to_s)</tt>
63
+ def find(*args)
64
+ raise Errors::InvalidOptions.new("Calling Document#find with nil is invalid") if args[0].nil?
65
+ type = args.delete_at(0) if args[0].is_a?(Symbol)
66
+ criteria = Criteria.translate(self, *args)
67
+ case type
68
+ when :first then return criteria.one
69
+ when :last then return criteria.last
70
+ else
71
+ return criteria
72
+ end
73
+ end
74
+
75
+ # Find the first +Document+ given the conditions, or creates a new document
76
+ # with the conditions that were supplied
77
+ #
78
+ # Options:
79
+ #
80
+ # args: A +Hash+ of attributes
81
+ #
82
+ # <tt>Person.find_or_create_by(:attribute => "value")</tt>
83
+ def find_or_create_by(attrs = {})
84
+ find_or(:create, attrs)
85
+ end
86
+
87
+ # Find the first +Document+ given the conditions, or instantiates a new document
88
+ # with the conditions that were supplied
89
+ #
90
+ # Options:
91
+ #
92
+ # args: A +Hash+ of attributes
93
+ #
94
+ # <tt>Person.find_or_initialize_by(:attribute => "value")</tt>
95
+ def find_or_initialize_by(attrs = {})
96
+ find_or(:new, attrs)
97
+ end
98
+
99
+ # Find the first +Document+ given the conditions.
100
+ #
101
+ # Options:
102
+ #
103
+ # args: A +Hash+ with a conditions key and other options
104
+ #
105
+ # <tt>Person.first(:conditions => { :attribute => "value" })</tt>
106
+ def first(*args)
107
+ find(:first, *args)
108
+ end
109
+
110
+ # Find the last +Document+ given the conditions.
111
+ #
112
+ # Options:
113
+ #
114
+ # args: A +Hash+ with a conditions key and other options
115
+ #
116
+ # <tt>Person.last(:conditions => { :attribute => "value" })</tt>
117
+ def last(*args)
118
+ find(:last, *args)
119
+ end
120
+
121
+ # Find all documents in paginated fashion given the supplied arguments.
122
+ # If no parameters are passed just default to offset 0 and limit 20.
123
+ #
124
+ # Options:
125
+ #
126
+ # params: A +Hash+ of params to pass to the Criteria API.
127
+ #
128
+ # Example:
129
+ #
130
+ # <tt>Person.paginate(:conditions => { :field => "Test" }, :page => 1,
131
+ # :per_page => 20)</tt>
132
+ #
133
+ # Returns paginated array of docs.
134
+ def paginate(params = {})
135
+ Criteria.translate(self, params).paginate
136
+ end
137
+
138
+ protected
139
+ # Find the first object or create/initialize it.
140
+ def find_or(method, attrs = {})
141
+ first(:conditions => attrs) || send(method, attrs)
142
+ end
143
+ end
144
+ end
@@ -0,0 +1,39 @@
1
+ # encoding: utf-8
2
+ module Mongoid #:nodoc:
3
+ class Identity #:nodoc:
4
+ class << self
5
+ # Create the identity for the +Document+.
6
+ #
7
+ # The id will be set in either in the form of a Mongo
8
+ # +ObjectId+ or a composite key set up by defining a key on the document.
9
+ #
10
+ # The _type will be set to the document's class name.
11
+ def create(doc)
12
+ identify(doc); type(doc); doc
13
+ end
14
+
15
+ protected
16
+ # Return the proper id for the document.
17
+ def generate_id
18
+ id = BSON::ObjectId.new
19
+ Mongoid.use_object_ids ? id : id.to_s
20
+ end
21
+
22
+ # Set the id for the document.
23
+ def identify(doc)
24
+ doc.id = compose(doc).join(" ").identify if doc.primary_key
25
+ doc.id = generate_id if doc.id.blank?
26
+ end
27
+
28
+ # Set the _type field on the document.
29
+ def type(doc)
30
+ doc._type = doc.class.name if doc.hereditary?
31
+ end
32
+
33
+ # Generates the composite key for a document.
34
+ def compose(doc)
35
+ doc.primary_key.collect { |key| doc.attributes[key] }.reject { |val| val.nil? }
36
+ end
37
+ end
38
+ end
39
+ end
@@ -0,0 +1,30 @@
1
+ # encoding: utf-8
2
+ module Mongoid #:nodoc
3
+ module Indexes #:nodoc
4
+ def self.included(base)
5
+ base.class_eval do
6
+ extend ClassMethods
7
+
8
+ cattr_accessor :indexed
9
+ self.indexed = false
10
+ end
11
+ end
12
+
13
+ module ClassMethods #:nodoc
14
+ # Add the default indexes to the root document if they do not already
15
+ # exist. Currently this is only _type.
16
+ def add_indexes
17
+ if hereditary && !indexed
18
+ self._collection.create_index(:_type, :unique => false, :background => true)
19
+ self.indexed = true
20
+ end
21
+ end
22
+
23
+ # Adds an index on the field specified. Options can be :unique => true or
24
+ # :unique => false. It will default to the latter.
25
+ def index(name, options = { :unique => false })
26
+ collection.create_index(name, options)
27
+ end
28
+ end
29
+ end
30
+ end
@@ -0,0 +1,37 @@
1
+ aggregate:
2
+ "function(obj, prev) {
3
+ prev.count++;
4
+ }"
5
+
6
+ group:
7
+ "function(obj, prev) {
8
+ prev.group.push(obj);
9
+ }"
10
+
11
+ max:
12
+ "function(obj, prev) {
13
+ if (prev.max == 'start') {
14
+ prev.max = obj.[field];
15
+ }
16
+ if (prev.max < obj.[field]) {
17
+ prev.max = obj.[field];
18
+ }
19
+ }"
20
+
21
+ min:
22
+ "function(obj, prev) {
23
+ if (prev.min == 'start') {
24
+ prev.min = obj.[field];
25
+ }
26
+ if (prev.min > obj.[field]) {
27
+ prev.min = obj.[field];
28
+ }
29
+ }"
30
+
31
+ sum:
32
+ "function(obj, prev) {
33
+ if (prev.sum == 'start') {
34
+ prev.sum = 0;
35
+ }
36
+ prev.sum += obj.[field];
37
+ }"
@@ -0,0 +1,21 @@
1
+ # encoding: utf-8
2
+ module Mongoid #:nodoc:
3
+ class Javascript
4
+ # Constant for the file that defines all the js functions.
5
+ FUNCTIONS = File.join(File.dirname(__FILE__), "javascript", "functions.yml")
6
+
7
+ # Load the javascript functions and define a class method for each one,
8
+ # that memoizes the value.
9
+ #
10
+ # Example:
11
+ #
12
+ # <tt>Mongoid::Javascript.aggregate</tt>
13
+ YAML.load(File.read(FUNCTIONS)).each_pair do |key, function|
14
+ (class << self; self; end).class_eval <<-EOT
15
+ def #{key}
16
+ @#{key} ||= "#{function}"
17
+ end
18
+ EOT
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,11 @@
1
+ # encoding: utf-8
2
+ module Mongoid #:nodoc:
3
+ module Matchers #:nodoc:
4
+ class All < Default
5
+ # Return true if the attribute and first value in the hash are equal.
6
+ def matches?(value)
7
+ @attribute == value.values.first
8
+ end
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,26 @@
1
+ # encoding: utf-8
2
+ module Mongoid #:nodoc:
3
+ module Matchers #:nodoc:
4
+ class Default
5
+ # Creating a new matcher only requires the value.
6
+ def initialize(attribute)
7
+ @attribute = attribute
8
+ end
9
+ # Return true if the attribute and value are equal.
10
+ def matches?(value)
11
+ @attribute == value
12
+ end
13
+
14
+ protected
15
+ # Return the first value in the hash.
16
+ def first(value)
17
+ value.values.first
18
+ end
19
+
20
+ # If object exists then compare, else return false
21
+ def determine(value, operator)
22
+ @attribute ? @attribute.send(operator, first(value)) : false
23
+ end
24
+ end
25
+ end
26
+ end
@@ -0,0 +1,13 @@
1
+ # encoding: utf-8
2
+ module Mongoid #:nodoc:
3
+ module Matchers #:nodoc:
4
+ class Exists < Default
5
+ # Return true if the attribute exists and checking for existence or
6
+ # return true if the attribute does not exist and checking for
7
+ # non-existence.
8
+ def matches?(value)
9
+ @attribute.nil? != value.values.first
10
+ end
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,11 @@
1
+ # encoding: utf-8
2
+ module Mongoid #:nodoc:
3
+ module Matchers #:nodoc:
4
+ class Gt < Default
5
+ # Return true if the attribute is greater than the value.
6
+ def matches?(value)
7
+ determine(value, :>)
8
+ end
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,11 @@
1
+ # encoding: utf-8
2
+ module Mongoid #:nodoc:
3
+ module Matchers #:nodoc:
4
+ class Gte < Default
5
+ # Return true if the attribute is greater than or equal to the value.
6
+ def matches?(value)
7
+ determine(value, :>=)
8
+ end
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,11 @@
1
+ # encoding: utf-8
2
+ module Mongoid #:nodoc:
3
+ module Matchers #:nodoc:
4
+ class In < Default
5
+ # Return true if the attribute is in the values.
6
+ def matches?(value)
7
+ value.values.first.include?(@attribute)
8
+ end
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,11 @@
1
+ # encoding: utf-8
2
+ module Mongoid #:nodoc:
3
+ module Matchers #:nodoc:
4
+ class Lt < Default
5
+ # Return true if the attribute is less than the value.
6
+ def matches?(value)
7
+ determine(value, :<)
8
+ end
9
+ end
10
+ end
11
+ end