Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP

Loading…

Resolves #69 - in which or(where, whereOpt(None)) creates a bad query #71

Merged
merged 2 commits into from

2 participants

@ktoso

Hello again,
It's been some time since I found #69, but since it's now Christmas :christmas_tree: I found some time and came back to this and fixed the issue. :-)

Reminding the problem again:

// what was the problem:
Venue.where(_.or(_.where(_.email eqs "   "), _.where(None)(_.neverMind eqs _)))

// we got:
{"$or": [{"email": "   "}, {  } ]}
                 ^ false     ^ always true => we fetch the entire collection

// what we get with this fix:
{"$or": [ {"email": "   "} ]} // as expected

There are tests for both cases attached (Some/None) and a fix.

I have added a method to AndCondition, if that's something you'd rather want to keep without methods please let me know where I should move this isEmpty method (or don't do it as a method?).

Thanks again for the great library,
Looking forward to the 2.0 / 2.10 releases!

Konrad

ktoso added some commits
@ktoso ktoso failing test for "or + where + whereOpt" edge case, issue #69 20eb932
@ktoso ktoso resolves #69, a blank `{}` should not be included in or queries
This solves an edge case when you have an or(_.where, _.whereOpt(None))
which would before leave a blank `{}` in the query string, making misbehave.

I've added `isEmpty` to `AndCondition`, please let me know if you'd
rather keep it method-less, and we can find a better place for this
method (or don't introduce one at all?)
b979c66
@jliszka jliszka merged commit 3b6c91e into from
@jliszka

Thanks! Sorry, I had put the fix in the v2 branch awhile back, forgot to port it back.

@ktoso

No problem :) Glad to hear it's fixed in 2.0 already.

Thanks for merging!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Commits on Dec 25, 2012
  1. @ktoso
  2. @ktoso

    resolves #69, a blank `{}` should not be included in or queries

    ktoso authored
    This solves an edge case when you have an or(_.where, _.whereOpt(None))
    which would before leave a blank `{}` in the query string, making misbehave.
    
    I've added `isEmpty` to `AndCondition`, please let me know if you'd
    rather keep it method-less, and we can find a better place for this
    method (or don't introduce one at all?)
This page is out of date. Refresh to see the latest.
View
4 rogue-core/src/main/scala/com/foursquare/rogue/MongoHelpers.scala
@@ -6,7 +6,9 @@ import com.mongodb.{BasicDBObjectBuilder, DBObject}
import scala.collection.immutable.ListMap
object MongoHelpers extends Rogue {
- case class AndCondition(clauses: List[QueryClause[_]], orCondition: Option[OrCondition])
+ case class AndCondition(clauses: List[QueryClause[_]], orCondition: Option[OrCondition]) {
+ def isEmpty: Boolean = clauses.isEmpty && orCondition.isEmpty
+ }
case class OrCondition(conditions: List[AndCondition])
View
1  rogue-core/src/main/scala/com/foursquare/rogue/QueryHelpers.scala
@@ -145,6 +145,7 @@ object QueryHelpers {
def orConditionFromQueries(subqueries: List[Query[_, _, _]]) = {
MongoHelpers.OrCondition(subqueries.flatMap(subquery => {
subquery match {
+ case q: Query[_, _, _] if q.condition.isEmpty => None
case q: Query[_, _, _] => Some(q.condition)
case _ => None
}
View
11 rogue-lift/src/test/scala/com/foursquare/rogue/QueryTest.scala
@@ -424,6 +424,17 @@ class QueryTest extends SpecsMatchers {
_.where(_.mayor eqs 2))
.modify(_.userid setTo 1).toString() must_== """db.venues.update({ "$or" : [ { "legid" : 1} , { "mayor" : 2}]}, { "$set" : { "userid" : 1}}, false, false)"""
+ // $or with optional where clause
+ Venue.or(
+ _.where(_.legacyid eqs 1),
+ _.whereOpt(None)(_.mayor eqs _))
+ .modify(_.userid setTo 1).toString() must_== """db.venues.update({ "$or" : [ { "legid" : 1}]}, { "$set" : { "userid" : 1}}, false, false)"""
+
+ Venue.or(
+ _.where(_.legacyid eqs 1),
+ _.whereOpt(Some(2))(_.mayor eqs _))
+ .modify(_.userid setTo 1).toString() must_== """db.venues.update({ "$or" : [ { "legid" : 1} , { "mayor" : 2}]}, { "$set" : { "userid" : 1}}, false, false)"""
+
// OrQuery syntax
val q1 = Venue.where(_.legacyid eqs 1)
val q2 = Venue.where(_.legacyid eqs 2)
Something went wrong with that request. Please try again.