Perform aggregate queries
@example the count of friends
Friend.aggregate(:all.count)
@example the minimum age, the maximum age and the total age of friends
Friend.aggregate(:age.min, :age.max, :age.sum)
@example the average age, grouped by gender
Friend.aggregate(:age.avg, :fields => [ :gender ])
@param aggregates [Symbol, …] operators to aggregate with @param query [Hash] the conditions
@return [Array,Numeric,DateTime,Date,Time] the results of the
aggregate query
@api public
# File lib/dm-aggregates/functions.rb, line 153 153: def aggregate(*args) 154: query = args.last.kind_of?(Hash) ? args.pop : {} 155: 156: query[:fields] ||= [] 157: query[:fields] |= args 158: query[:fields].map! { |f| normalize_field(f) } 159: 160: raise ArgumentError, 'query[:fields] must not be empty' if query[:fields].empty? 161: 162: unless query.key?(:order) 163: # the current collection/model is already sorted by attributes 164: # and since we are projecting away some of the attributes, 165: # and then performing aggregate functions on the remainder, 166: # we need to honor the existing order, as if it were already 167: # materialized, and we are looping over the rows in order. 168: 169: directions = direction_map 170: 171: query[:order] = [] 172: 173: # use the current query order for each property if available 174: query[:fields].each do |property| 175: next unless property.kind_of?(Property) 176: query[:order] << directions.fetch(property, property) 177: end 178: end 179: 180: query = scoped_query(query) 181: 182: if query.fields.any? { |p| p.kind_of?(Property) } 183: query.repository.aggregate(query.update(:unique => true)) 184: else 185: query.repository.aggregate(query).first # only return one row 186: end 187: end
Get the average value of a property
@example the average age of all friends
Friend.avg(:age)
@example the average age of all female friends
Friend.avg(:age, :conditions => [ 'gender = ?', 'female' ])
@param property [Symbol] the property you wish to get the average value of @param opts [Hash, Symbol] the conditions
@return [Integer] return the average value of a property given the conditions
@api public
# File lib/dm-aggregates/functions.rb, line 103 103: def avg(*args) 104: query = args.last.kind_of?(Hash) ? args.pop : {} 105: property_name = args.first 106: 107: assert_property_type property_name, ::Integer, ::Float, ::BigDecimal 108: 109: aggregate(query.merge(:fields => [ property_name.avg ])) 110: end
Count results (given the conditions)
@example the count of all friends
Friend.count
@example the count of all friends older then 18
Friend.count(:age.gt => 18)
@example the count of all your female friends
Friend.count(:conditions => [ 'gender = ?', 'female' ])
@example the count of all friends with an address (NULL values are not included)
Friend.count(:address)
@example the count of all friends with an address that are older then 18
Friend.count(:address, :age.gt => 18)
@example the count of all your female friends with an address
Friend.count(:address, :conditions => [ 'gender = ?', 'female' ])
@param property [Symbol] of the property you with to count (optional) @param opts [Hash, Symbol] the conditions
@return [Integer] return the count given the conditions
@api public
# File lib/dm-aggregates/functions.rb, line 32 32: def count(*args) 33: query = args.last.kind_of?(Hash) ? args.pop : {} 34: property_name = args.first 35: 36: if property_name 37: assert_kind_of 'property', property_by_name(property_name), Property 38: end 39: 40: aggregate(query.merge(:fields => [ property_name ? property_name.count : :all.count ])).to_i 41: end
Get the highest value of a property
@example the age of the oldest friend
Friend.max(:age)
@example the age of the oldest female friend
Friend.max(:age, :conditions => [ 'gender = ?', 'female' ])
@param property [Symbol] the property you wish to get the highest value of @param opts [Hash, Symbol] the conditions
@return [Integer] return the highest value of a property given the conditions
@api public
# File lib/dm-aggregates/functions.rb, line 80 80: def max(*args) 81: query = args.last.kind_of?(Hash) ? args.pop : {} 82: property_name = args.first 83: 84: assert_property_type property_name, ::Integer, ::Float, ::BigDecimal, ::DateTime, ::Date, ::Time 85: 86: aggregate(query.merge(:fields => [ property_name.max ])) 87: end
Get the lowest value of a property
@example the age of the youngest friend
Friend.min(:age)
@example the age of the youngest female friend
Friend.min(:age, :conditions => [ 'gender = ?', 'female' ])
@param property [Symbol] the property you wish to get the lowest value of @param opts [Hash, Symbol] the conditions
@return [Integer] return the lowest value of a property given the conditions
@api public
# File lib/dm-aggregates/functions.rb, line 57 57: def min(*args) 58: query = args.last.kind_of?(Hash) ? args.pop : {} 59: property_name = args.first 60: 61: assert_property_type property_name, ::Integer, ::Float, ::BigDecimal, ::DateTime, ::Date, ::Time 62: 63: aggregate(query.merge(:fields => [ property_name.min ])) 64: end
Get the total value of a property
@example the total age of all friends
Friend.sum(:age)
@example the total age of all female friends
Friend.max(:age, :conditions => [ 'gender = ?', 'female' ])
@param property [Symbol] the property you wish to get the total value of @param opts [Hash, Symbol] the conditions
@return [Integer] return the total value of a property given the conditions
@api public
# File lib/dm-aggregates/functions.rb, line 126 126: def sum(*args) 127: query = args.last.kind_of?(::Hash) ? args.pop : {} 128: property_name = args.first 129: 130: assert_property_type property_name, ::Integer, ::Float, ::BigDecimal 131: 132: aggregate(query.merge(:fields => [ property_name.sum ])) 133: end
# File lib/dm-aggregates/functions.rb, line 191 191: def assert_property_type(name, *types) 192: if name.nil? 193: raise ArgumentError, 'property name must not be nil' 194: end 195: 196: property = property_by_name(name) 197: type = property.primitive 198: 199: unless types.include?(type) 200: raise ArgumentError, "#{name} must be #{types * ' or '}, but was #{type}" 201: end 202: end
# File lib/dm-aggregates/functions.rb, line 223 223: def direction_map 224: direction_map = {} 225: self.query.order.each do |direction| 226: direction_map[direction.target] = direction 227: end 228: direction_map 229: end
# File lib/dm-aggregates/functions.rb, line 204 204: def normalize_field(field) 205: assert_kind_of 'field', field, DataMapper::Query::Operator, Symbol, Property 206: 207: case field 208: when DataMapper::Query::Operator 209: if field.target == :all 210: field 211: else 212: field.class.new(property_by_name(field.target), field.operator) 213: end 214: 215: when Symbol 216: property_by_name(field) 217: 218: when Property 219: field 220: end 221: end
Disabled; run with --debug to generate this.
Generated with the Darkfish Rdoc Generator 1.1.6.