Skip to content

Instantly share code, notes, and snippets.

@djspiewak
Forked from bwmcadams/1-issue-description.scala
Created November 6, 2011 22:02
Show Gist options
  • Save djspiewak/1343614 to your computer and use it in GitHub Desktop.
Save djspiewak/1343614 to your computer and use it in GitHub Desktop.
/* I'm trying to refactor $and and $or (which are essentially the same code returning a different outer query).
The problem is that currently only "String, Any" pairs work, and I need to be able to combine both those *AND* "Query Expression Objects".
Here's the $or spec right now
*/
"Casbah's DSL $or Operator" should {
"Accept multiple values" in {
val or = $or("foo" -> "bar", "x" -> "y")
or must haveListEntry("$or", Seq(MongoDBObject("foo" -> "bar"), MongoDBObject("x" -> "y")))
}
"Work with nested operators" in {
val or = $or( "foo" $lt 5 $gt 1, "x" $gte 10 $lte 152 )
or must haveSuperclass[BasicBSONList]
or must beEqualTo(MongoDBObject("$or" -> MongoDBList(MongoDBObject("foo" -> "bar", "x" -> "y"))))
}
}
/**
the second block doesn't compile or work and I need to figure out an idiom that works.
I've fiddled with a few things but Type Classes don't work due to needing a wildcard / <: on the second arg to the tuple pairs.
*/
/**
* Trait to provide the $or method as a bareword operator.
*
* $or ("Foo" -> "bar")
*
* Targets an RValue of (String, Any)* to be converted to a DBObject
*
* TODO - Test that rvalue ends up being an array e.g.:
*
* scala> $or ("foo" -> "bar", "X" -> 5)
* res1: com.mongodb.casbah.commons.Imports.DBObject = { "$or" : [ { "foo" : "bar" , "X" : 5}]}
*
*
* @author Brendan W. McAdams <brendan@10gen.com>
* @since 2.0
* @see http://www.mongodb.org/display/DOCS/Advanced+Queries#AdvancedQueries-%24or
*/
trait OrOp extends BarewordQueryOperator {
def $or(fields: (String, Any)*) = {
val bldr = MongoDBList.newBuilder
for ((k, v) <- fields) bldr += MongoDBObject(k -> v)
MongoDBObject("$or" -> bldr.result)
}
}
/**
* Trait to provide the $or method as a bareword operator.
*
* $or ("Foo" -> "bar")
*
* Targets an RValue of (String, Any)* to be converted to a DBObject
*
* TODO - Test that rvalue ends up being an array e.g.:
*
* scala> $or ("foo" -> "bar", "X" -> 5)
* res1: com.mongodb.casbah.commons.Imports.DBObject = { "$or" : [ { "foo" : "bar" , "X" : 5}]}
*
*
* @author Brendan W. McAdams <brendan@10gen.com>
* @since 2.0
* @see http://www.mongodb.org/display/DOCS/Advanced+Queries#AdvancedQueries-%24or
*/
trait OrOp extends BarewordQueryOperator {
def $or(fields: (String, Any)*) = {
val bldr = MongoDBList.newBuilder
for ((k, v) <- fields) bldr += MongoDBObject(k -> v)
MongoDBObject("$or" -> bldr.result)
}
}
trait OrOp extends BarewordQueryOperator {
def $or(fields: (String, Any)*) = {
val bldr = MongoDBList.newBuilder
for ((k, v) <- fields) bldr += MongoDBObject(k -> v)
MongoDBObject("$or" -> bldr.result)
}
def $or[A : ValidBarewordExpressionArgType](fields: A*) =
MongoDBObject("$or" -> implicitly[ValidBarewordExpressionArgType[A]].listify(fields))
}
trait ValidTypes {
trait KVPair[-A] extends ValidBarewordExpressionArgType[(String, A)] {
def listify(args: Seq[(String, A)]): Seq[DBObject] = {
val bldr = MongoDBList.newBuilder
args.foreach(kv => bldr += MongoDBObject(kv))
bldr.result.asInstanceOf[Seq[DBObject]]
}
}
// Valid Bareword Query Expression entries
trait CoreOperatorResultObj extends ValidBarewordExpressionArgType[DBObject with QueryExpressionObject] {
def listify(args: Seq[DBObject with QueryExpressionObject]): Seq[DBObject] = {
val bldr = MongoDBList.newBuilder
args.foreach(bldr.+=)
bldr.result.asInstanceOf[Seq[DBObject]]
}
}
}
trait ValidBarewordExpressionArgTypeHolder {
import com.mongodb.casbah.query.ValidTypes.{CoreOperatorResultObj, KVPair}
implicit def kvPairOk[A]: KVPair[A] = new KVPair[A] {}
implicit object CoreOperatorResultObjOk extends CoreOperatorResultObj
}
// give it a shot!
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment