class Query

Public Class Methods

new(klass) click to toggle source
# File lib/parse_resource/query.rb, line 3
def initialize(klass)
  @klass = klass
end

Public Instance Methods

all() click to toggle source
# File lib/parse_resource/query.rb, line 134
def all
  execute
end
chunk(count=100) click to toggle source

Divides the query into multiple chunks if you're running into RestClient::BadRequest errors.

# File lib/parse_resource/query.rb, line 50
def chunk(count=100)
  criteria[:chunk] = count
  self
end
chunk_results(params={}) click to toggle source
# File lib/parse_resource/query.rb, line 109
def chunk_results(params={})
  criteria[:limit] ||= 100
  
  start_row = criteria[:skip].to_i
  end_row = [criteria[:limit].to_i - start_row - 1, 1].max
  result = []
  
  # Start at start_row, go to end_row, get results in chunks
  (start_row..end_row).each_slice(criteria[:chunk].to_i) do |slice|
    params[:skip] = slice.first
    params[:limit] = slice.length # Either the chunk size or the end of the limited results

    resp = @klass.resource.get(:params => params)
    results = JSON.parse(resp)['results']
    result = result + results.map {|r| @klass.model_name.constantize.new(r, false)}
    break if results.length < params[:limit] # Got back fewer than we asked for, so exit.
  end
  result
end
count(count=1) click to toggle source
# File lib/parse_resource/query.rb, line 44
def count(count=1)
  criteria[:count] = count
  all
end
criteria() click to toggle source
# File lib/parse_resource/query.rb, line 7
def criteria
  @criteria ||= { :conditions => {} }
end
execute() click to toggle source
# File lib/parse_resource/query.rb, line 87
def execute
  params = {}
  params.merge!({:where => criteria[:conditions].to_json}) if criteria[:conditions]
  params.merge!({:limit => criteria[:limit].to_json}) if criteria[:limit]
  params.merge!({:skip => criteria[:skip].to_json}) if criteria[:skip]
  params.merge!({:count => criteria[:count].to_json}) if criteria[:count]
  params.merge!({:include => criteria[:include]}) if criteria[:include]
  params.merge!({:order => criteria[:order]}) if criteria[:order]

  return chunk_results(params) if criteria[:chunk]

  resp = @klass.resource.get(:params => params)
  
  if criteria[:count] == 1
    results = JSON.parse(resp)['count']
    return results.to_i
  else
    results = JSON.parse(resp)['results']
    return results.map {|r| @klass.model_name.constantize.new(r, false)}
  end
end
first() click to toggle source
# File lib/parse_resource/query.rb, line 129
def first
  limit(1)
  execute.first
end
include_object(parent) click to toggle source
# File lib/parse_resource/query.rb, line 24
def include_object(parent)
  criteria[:include] = parent
  self
end
limit(limit) click to toggle source
# File lib/parse_resource/query.rb, line 16
def limit(limit)
  # If > 1000, set chunking, because large queries over 1000 need it with Parse
  chunk(1000) if limit > 1000

  criteria[:limit] = limit
  self
end
method_missing(meth, *args, &block) click to toggle source
Calls superclass method
# File lib/parse_resource/query.rb, line 138
def method_missing(meth, *args, &block)
  method_name = method_name.to_s
  if method_name.start_with?("find_by_")
    attrib   = method_name.gsub(/^find_by_/,"")
    finder_name = "find_all_by_#{attrib}"

    define_singleton_method(finder_name) do |target_value|
      where({attrib.to_sym => target_value}).first
    end

    send(finder_name, args[0])

  elsif method_name.start_with?("find_all_by_")
    attrib   = method_name.gsub(/^find_all_by_/,"")
    finder_name = "find_all_by_#{attrib}"

    define_singleton_method(finder_name) do |target_value|
      where({attrib.to_sym => target_value}).all
    end

    send(finder_name, args[0])
  end

  if Array.method_defined?(meth)
    all.send(meth, *args, &block)
  else
    super
  end
end
near(klass, geo_point, options) click to toggle source
# File lib/parse_resource/query.rb, line 55
def near(klass, geo_point, options)
  if geo_point.is_a? Array
    geo_point = ParseGeoPoint.new :latitude => geo_point[0], :longitude => geo_point[1]
  end

  query = { "$nearSphere" => geo_point.to_pointer }
  if options[:maxDistanceInMiles]
    query["$maxDistanceInMiles"] = options[:maxDistanceInMiles]
  elsif options[:maxDistanceInRadians]
    query["$maxDistanceInRadians"] = options[:maxDistanceInRadians]
  elsif options[:maxDistanceInKilometers]
    query["$maxDistanceInKilometers"] = options[:maxDistanceInKilometers]
  end

  criteria[:conditions].merge!({ klass => query })
  self
end
order(attr) click to toggle source
# File lib/parse_resource/query.rb, line 29
def order(attr)
  orders = attr.split(" ")
  if orders.count > 1
    criteria[:order] = orders.last.downcase == "desc" ? "-#{orders.first}" : "#{orders.first}"
  else
    criteria[:order] = orders.first
  end
  self
end
respond_to?(meth) click to toggle source
Calls superclass method
# File lib/parse_resource/query.rb, line 168
def respond_to?(meth)
  if Array.method_defined?(meth)
    true
  else
    super
  end
end
skip(skip) click to toggle source
# File lib/parse_resource/query.rb, line 39
def skip(skip)
 criteria[:skip] = skip
 self
end
where(args) click to toggle source
# File lib/parse_resource/query.rb, line 11
def where(args)
  criteria[:conditions].merge!(args)
  self
end
within_box(klass, geo_point_south, geo_point_north) click to toggle source
# File lib/parse_resource/query.rb, line 73
def within_box(klass, geo_point_south, geo_point_north)
  if geo_point_south.is_a? Array
    geo_point_south = ParseGeoPoint.new :latitude => geo_point_south[0], :longitude => geo_point_south[1]
  end

  if geo_point_north.is_a? Array
    geo_point_north = ParseGeoPoint.new :latitude => geo_point_north[0], :longitude => geo_point_north[1]
  end

  query = { "$within" => { "$box" => [geo_point_south.to_pointer, geo_point_north.to_pointer]}}
  criteria[:conditions].merge!({ klass => query })
  self
end