Module: DataMapper::AggregateFunctions

Included in:
Collection, Model
Defined in:
lib/dm-aggregates/aggregate_functions.rb

Instance Method Summary collapse

Instance Method Details

#aggregate(*args) ⇒ Array, ...

Perform aggregate queries

Examples:

the count of friends

Friend.aggregate(:all.count)

the minimum age, the maximum age and the total age of friends

Friend.aggregate(:age.min, :age.max, :age.sum)

the average age, grouped by gender

Friend.aggregate(:age.avg, :fields => [ :gender ])

Parameters:

  • aggregates (Symbol, ...)

    operators to aggregate with

Returns:

  • (Array, Numeric, DateTime, Date, Time)

    the results of the aggregate query

Raises:

  • (ArgumentError)


150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
# File 'lib/dm-aggregates/aggregate_functions.rb', line 150

def aggregate(*args)
  query = args.last.kind_of?(Hash) ? args.pop : {}

  query[:fields] ||= []
  query[:fields]  |= args
  query[:fields].map! { |f| normalize_field(f) }
  query[:order]  ||= query[:fields].select { |p| p.kind_of?(Property) }

  raise ArgumentError, 'query[:fields] must not be empty' if query[:fields].empty?

  query = scoped_query(query)

  if query.fields.any? { |p| p.kind_of?(Property) }
    # explicitly specify the fields to circumvent a bug in Query#update
    query.repository.aggregate(query.update(:fields => query.fields, :unique => true))
  else
    query.repository.aggregate(query).first  # only return one row
  end
end

#avg(*args) ⇒ Integer

Get the average value of a property

Examples:

the average age of all friends

Friend.avg(:age)

the average age of all female friends

Friend.avg(:age, :conditions => [ 'gender = ?', 'female' ])

Parameters:

  • property (Symbol)

    the property you wish to get the average value of

  • opts (Hash, Symbol)

    the conditions

Returns:

  • (Integer)

    return the average value of a property given the conditions



100
101
102
103
104
105
106
107
# File 'lib/dm-aggregates/aggregate_functions.rb', line 100

def avg(*args)
  query         = args.last.kind_of?(Hash) ? args.pop : {}
  property_name = args.first

  assert_property_type property_name, Integer, Float, BigDecimal

  aggregate(query.merge(:fields => [ property_name.avg ]))
end

#count(*args) ⇒ Integer

Count results (given the conditions)

Examples:

the count of all friends

Friend.count

the count of all friends older then 18

Friend.count(:age.gt => 18)

the count of all your female friends

Friend.count(:conditions => [ 'gender = ?', 'female' ])

the count of all friends with an address (NULL values are not included)

Friend.count(:address)

the count of all friends with an address that are older then 18

Friend.count(:address, :age.gt => 18)

the count of all your female friends with an address

Friend.count(:address, :conditions => [ 'gender = ?', 'female' ])

Parameters:

  • property (Symbol)

    of the property you with to count (optional)

  • opts (Hash, Symbol)

    the conditions

Returns:

  • (Integer)

    return the count given the conditions



29
30
31
32
33
34
35
36
37
38
# File 'lib/dm-aggregates/aggregate_functions.rb', line 29

def count(*args)
  query         = args.last.kind_of?(Hash) ? args.pop : {}
  property_name = args.first

  if property_name
    assert_kind_of 'property', property_by_name(property_name), Property
  end

  aggregate(query.merge(:fields => [ property_name ? property_name.count : :all.count ]))
end

#max(*args) ⇒ Integer

Get the highest value of a property

Examples:

the age of the oldest friend

Friend.max(:age)

the age of the oldest female friend

Friend.max(:age, :conditions => [ 'gender = ?', 'female' ])

Parameters:

  • property (Symbol)

    the property you wish to get the highest value of

  • opts (Hash, Symbol)

    the conditions

Returns:

  • (Integer)

    return the highest value of a property given the conditions



77
78
79
80
81
82
83
84
# File 'lib/dm-aggregates/aggregate_functions.rb', line 77

def max(*args)
  query         = args.last.kind_of?(Hash) ? args.pop : {}
  property_name = args.first

  assert_property_type property_name, Integer, Float, BigDecimal, DateTime, Date, Time

  aggregate(query.merge(:fields => [ property_name.max ]))
end

#min(*args) ⇒ Integer

Get the lowest value of a property

Examples:

the age of the youngest friend

Friend.min(:age)

the age of the youngest female friend

Friend.min(:age, :conditions => [ 'gender = ?', 'female' ])

Parameters:

  • property (Symbol)

    the property you wish to get the lowest value of

  • opts (Hash, Symbol)

    the conditions

Returns:

  • (Integer)

    return the lowest value of a property given the conditions



54
55
56
57
58
59
60
61
# File 'lib/dm-aggregates/aggregate_functions.rb', line 54

def min(*args)
  query         = args.last.kind_of?(Hash) ? args.pop : {}
  property_name = args.first

  assert_property_type property_name, Integer, Float, BigDecimal, DateTime, Date, Time

  aggregate(query.merge(:fields => [ property_name.min ]))
end

#sum(*args) ⇒ Integer

Get the total value of a property

Examples:

the total age of all friends

Friend.sum(:age)

the total age of all female friends

Friend.max(:age, :conditions => [ 'gender = ?', 'female' ])

Parameters:

  • property (Symbol)

    the property you wish to get the total value of

  • opts (Hash, Symbol)

    the conditions

Returns:

  • (Integer)

    return the total value of a property given the conditions



123
124
125
126
127
128
129
130
# File 'lib/dm-aggregates/aggregate_functions.rb', line 123

def sum(*args)
  query         = args.last.kind_of?(Hash) ? args.pop : {}
  property_name = args.first

  assert_property_type property_name, Integer, Float, BigDecimal

  aggregate(query.merge(:fields => [ property_name.sum ]))
end