class ExtJs::Mongo

Constants

DEFAULT_LIMIT
DEFAULT_SKIP
MAX_LIMIT

Public Class Methods

allowed_filters() click to toggle source

@return [Array] Array of string values representing keys that are filterable.

# File lib/ruby-ext-js.rb, line 98
def self.allowed_filters
  []
end
filter_opts() click to toggle source

Define options for specific filters. Eg:

{
  "field_1" => { :all_caps => true },
  "field_2" => { :operator => "$all" },
  "field_3" => { :strip => "true" }
}
# File lib/ruby-ext-js.rb, line 108
def self.filter_opts
  {}
end
new( params ) click to toggle source
# File lib/ruby-ext-js.rb, line 74
def initialize( params )
  @params = {}
  params.each do |k, v|
    @params[k.to_s] = v
  end
end

Protected Class Methods

apply_filter_opts( field, values ) click to toggle source
# File lib/ruby-ext-js.rb, line 185
def self.apply_filter_opts( field, values )
  return values if values.size == 0
  
  opts = {
    :strip => true,
    :all_caps => false,
    :operator => nil
  }.merge( filter_opts[field] || {} )
  
  if values.is_a?( String ) || values.is_a?( Array )
    opts[:operator] ||= "$in"
    values = Array( values )
    values.map!{ |value| value.strip } if opts[:strip]
    values.map!{ |value| value.upcase } if opts[:all_caps]
    values = values.size > 1 ? { opts[:operator] => values } : values.first
  elsif values.is_a?( Hash )
    # Values is already a { "$in" => [1, 2] } style hash
    if opts[:operator]
      values = { opts[:operator] => values.values.flatten.uniq }
    end
    if opts[:strip]
      values.each do |k, v|
        if v.is_a?( Array )
          values[k] = v.map{ |value| value.strip }
        elsif v.is_a?( String )
          values[k] = v.strip
        end
      end
    end
    if opts[:all_caps]
      values.each do |k, v|
        if v.is_a?( Array )
          values[k] = v.map{ |value| value.upcase }
        elsif v.is_a?( String )
          values[k] = v.upcase
        end
      end
    end
  end
  
  values
end
comparison_for( str ) click to toggle source
# File lib/ruby-ext-js.rb, line 228
def self.comparison_for( str )
  case str
    when "lt"; "$lte"
    when "gt"; "$gte"
    when "eq"; "=="
    else; "$in"
  end
end
filter_for( hash ) click to toggle source
# File lib/ruby-ext-js.rb, line 153
def self.filter_for( hash )
  hash["data"] ||= {}
  hash["field"] ||= ""
  
  field = hash["field"].gsub(/[^\.\w\d_-]/, "").strip
  values = Array( hash["data"]["value"] )
  comparison = self.comparison_for( hash["data"]["comparison"] )
  
  case hash["data"]["type"]
    when "date"
      offset = Time.now.utc_offset
      values.map!{ |date| date = Date.parse( date ); Time.utc( date.year, date.month, date.day ) }
      if comparison == "=="
        start_time = values[0]
        end_time = Time.utc( start_time.year, start_time.month, start_time.day, 23, 59, 59 )
        values = { comparison_for( "gt" ) => start_time - offset, comparison_for( "lt" ) => end_time - offset }
      else
        values = { comparison => values[0] - offset }
      end
    else
      if values.size == 1
        values = values[0]
      elsif values.size > 1
        values = { comparison => values }
      end
  end
  
  values = self.apply_filter_opts( field, values )
  
  return field, values
end
filter_param( params ) click to toggle source
# File lib/ruby-ext-js.rb, line 133
def self.filter_param( params )
  conds = {}
  
  if params["filter"] && params["filter"].size > 0
    0.upto( params["filter"].size - 1 ).each do |i|
      i = i.to_s
      
      next unless params["filter"][i]
      
      field, values = self.filter_for( params["filter"][i] )
      
      unless field.empty? || !allowed_filters.include?( field ) || values.empty?
        conds.merge! field => values
      end
    end
  end
  
  conds
end
limit_param( params ) click to toggle source
# File lib/ruby-ext-js.rb, line 119
def self.limit_param( params )
  return { :limit => DEFAULT_LIMIT } unless params.key?( "limit" ) && params["limit"].to_i > 0
  { :limit => [params["limit"].to_i, MAX_LIMIT].min }
end
skip_param( params ) click to toggle source
# File lib/ruby-ext-js.rb, line 114
def self.skip_param( params )
  return { :skip => DEFAULT_SKIP } unless params.key?( "start" ) && params.key?( "limit" )
  { :skip => [params["start"].to_i, 0].max }
end
sort_param( params ) click to toggle source
# File lib/ruby-ext-js.rb, line 124
def self.sort_param( params )
  return {} unless params.key?( "sort" )
  
  sort = params["sort"] ? params["sort"].to_sym : :id
  dir = params["dir"] =~ /desc/i ? :desc : :asc
  
  { :sort => [sort, dir] }
end

Public Instance Methods

conditions() click to toggle source

@return [Hash] ‘find()` conditions for `Mongo::Collection.find( conditions, opts )`

# File lib/ruby-ext-js.rb, line 82
def conditions
  self.class.filter_param( @params )
end
options() click to toggle source

@return [Hash] ‘find()` options for `Mongo::Collection.find( conditions, opts )`

# File lib/ruby-ext-js.rb, line 87
def options
  opts = {}
  
  opts.merge! self.class.skip_param( @params )
  opts.merge! self.class.limit_param( @params )
  opts.merge! self.class.sort_param( @params )
  
  opts
end