lib/adapters/parse_adapter.rb in dm-parse-0.3.6 vs lib/adapters/parse_adapter.rb in dm-parse-0.3.7
- old
+ new
@@ -161,85 +161,115 @@
def parse_conditions_for(query)
conditions = query.conditions
return nil if conditions.blank?
- case conditions
+ result = {}
+ translate(conditions, result)
+ finalize result
+ end
+
+ def translate(condition, result)
+ case condition
+ when RegexpComparison
+ translate_for(result, condition, Regex)
+ when EqualToComparison
+ translate_for(result, condition, Eql)
+ when GreaterThanComparison
+ translate_for(result, condition, Gt)
+ when GreaterThanOrEqualToComparison
+ translate_for(result, condition, Gte)
+ when LessThanComparison
+ translate_for(result, condition, Lt)
+ when LessThanOrEqualToComparison
+ translate_for(result, condition, Lte)
+ when InclusionComparison
+ translate_for(result, condition, In)
when NotOperation
- parse_query = Parse::Conditions::And.new
- feed_reversely(parse_query, conditions)
+ condition.each { |c| translate_reversely c, result }
when AndOperation
- parse_query = Parse::Conditions::And.new
- feed_directly(parse_query, conditions)
+ condition.each { |c| translate c, result }
when OrOperation
- parse_query = Parse::Conditions::Or.new
- feed_or(parse_query, conditions)
+ result["$or"] ||= []
+ result["$or"] = result["$or"] + condition.map do |c|
+ r = {}
+ translate c, r
+ r
+ end
+ else
+ raise NotImplementedError
end
+ end
- parse_query.build
+ def translate_reversely(condition, result)
+ case condition
+ when EqualToComparison
+ translate_for(result, condition, Ne)
+ when GreaterThanComparison
+ translate_for(result, condition, Lte)
+ when GreaterThanOrEqualToComparison
+ translate_for(result, condition, Lt)
+ when LessThanComparison
+ translate_for(result, condition, Gte)
+ when LessThanOrEqualToComparison
+ translate_for(result, condition, Gt)
+ when InclusionComparison
+ translate_for(result, condition, Nin)
+ when NotOperation
+ condition.each { |c| translate c, result }
+ when AndOperation
+ condition.each { |c| translate_reversely c, result }
+ else
+ raise NotImplementedError
+ end
end
- def feed_for(parse_query, condition, comparison_class)
+ def translate_for(result, condition, comparison_class)
subject = condition.subject
+
case subject
when DataMapper::Property
- comparison = comparison_class.new condition.value
- parse_query.add subject.field, comparison
+ field = subject.field
+ result[field] ||= []
+ result[field] << comparison_class.new(condition.value)
when DataMapper::Associations::OneToMany::Relationship
child_key = condition.subject.child_key.first
- parse_query.add "objectId", comparison_class.new(condition.value.map { |resource| resource.send child_key.name })
+ result["objectId"] ||= []
+ result["objectId"] << comparison_class.new(condition.value.map { |resource| resource.send child_key.name })
when DataMapper::Associations::ManyToOne::Relationship
child_key = subject.child_key.first
- parse_query.add child_key.field, comparison_class.new(condition.foreign_key_mapping.value)
+ field = child_key.field
+ result[field] ||= []
+ result[field] << comparison_class.new(condition.foreign_key_mapping.value)
else
raise NotImplementedError, "Condition: #{condition}"
end
end
- def feed_reversely(parse_query, conditions)
- conditions.each do |condition|
- case condition
- when EqualToComparison then feed_for(parse_query, condition, Ne)
- when GreaterThanComparison then feed_for(parse_query, condition, Lte)
- when GreaterThanOrEqualToComparison then feed_for(parse_query, condition, Lt)
- when LessThanComparison then feed_for(parse_query, condition, Gte)
- when LessThanOrEqualToComparison then feed_for(parse_query, condition, Gt)
- when NotOperation then feed_directly(parse_query, condition)
- when AndOperation then feed_reversely(parse_query, condition)
- when InclusionComparison then feed_for(parse_query, condition, Nin)
+ def finalize(queries)
+ queries.inject({}) do |result, (field, comparisons)|
+ if field == "$or"
+ result.merge! field => comparisons.map { |c| finalize c }
else
- raise NotImplementedError
+ result.merge! field => combine(comparisons)
end
end
end
- def feed_directly(parse_query, conditions)
- conditions.each do |condition|
- feed_with_condition parse_query, condition
- end
- end
+ def combine(comparisons)
+ groups = comparisons.group_by { |comparison| comparison.is_a? Eql }
+ equals = groups[true]
+ others = groups[false]
- def feed_or(queries, conditions)
- conditions.each do |condition|
- parse_query = Parse::Conditions::And.new
- feed_with_condition parse_query, condition
- queries.add parse_query
- end
- end
-
- def feed_with_condition(parse_query, condition)
- case condition
- when RegexpComparison then feed_for(parse_query, condition, Regex)
- when EqualToComparison then feed_for(parse_query, condition, Eql)
- when GreaterThanComparison then feed_for(parse_query, condition, Gt)
- when GreaterThanOrEqualToComparison then feed_for(parse_query, condition, Gte)
- when LessThanComparison then feed_for(parse_query, condition, Lt)
- when LessThanOrEqualToComparison then feed_for(parse_query, condition, Lte)
- when InclusionComparison then feed_for(parse_query, condition, In)
- when NotOperation then feed_reversely(parse_query, condition)
- when AndOperation then feed_directly(parse_query, condition)
- else
- raise NotImplementedError
+ if equals.present? && others.present?
+ raise "Parse Query: cannot combine Eql with others"
+ elsif equals.present?
+ raise "can only use one EqualToComparison for a field" unless equals.size == 1
+ equals.first.as_json
+ elsif others.present?
+ others.inject({}) do |result, comparison|
+ result.merge! comparison.as_json
+ end
end
end
end