Module: Rhubarb::FindFreshest

Included in:
PersistingClassMixins
Defined in:
lib/rhubarb/mixins/freshness.rb

Instance Method Summary collapse

Instance Method Details

#find_freshest(args) ⇒ Object

args contains the following keys

* :group_by maps to a list of columns to group by (mandatory)
* :select_by maps to a hash mapping from column symbols to values (optional)
* :version maps to some version to be considered "current" for the purposes of this query; that is, all rows later than the "current" version will be disregarded (optional, defaults to latest version)


19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
# File 'lib/rhubarb/mixins/freshness.rb', line 19

def find_freshest(args)
  args = args.dup

  args[:version] ||= Util::timestamp
  args[:select_by] ||= {}

  query_params = {}
  query_params[:version] = args[:version]

  select_clauses = ["created <= :version"]

  valid_cols = self.colnames.intersection args[:select_by].keys

  valid_cols.map do |col|
    select_clauses << "#{col.to_s} = #{col.inspect}"
    val = args[:select_by][col]
    val = val.row_id if val.respond_to? :row_id
    query_params[col] = val
  end

  group_by_clause = "GROUP BY " + args[:group_by].join(", ")
  where_clause = "WHERE " + select_clauses.join(" AND ")
  projection = self.colnames - [:created]
  join_criteria = projection.map do |column|
    "__fresh.#{column} = __freshest.#{column}"
  end

  projection << "MAX(created) AS __current_version"
  join_criteria << "__fresh.__current_version = __freshest.created"

  join_clause = join_criteria.join(' AND ')
  
  query = "
  SELECT __freshest.* FROM (
SELECT #{projection.to_a.join(', ')} FROM (
  SELECT * from #{quoted_table_name} #{where_clause}
) #{group_by_clause}
  ) as __fresh INNER JOIN #{quoted_table_name} as __freshest ON #{join_clause} ORDER BY row_id"
  self.db.execute(query, query_params).map {|tup| self.new(tup) }
end