Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

SCALA-13 - Create a 'light' version of the Query DSL which doesn't us…

…e $ operators

* Rough cut of the DSL but it has major problems due to conflicts w/ scala keywords
  • Loading branch information...
commit 691dd3ddf1a0c658bdc138fe964d9e60ab9b43dd 1 parent b9e72af
@bwmcadams bwmcadams authored
View
6 casbah-core/src/main/scala/Implicits.scala
@@ -117,6 +117,12 @@ object Imports extends Imports with commons.Imports with commons.Exports with qu
trait Imports extends BaseImports with TypeImports with Implicits
package core {
+ /**
+ * You can import core to get "just" Casbah core; no commons, query, etc.
+ * This is useful to pick which QueryDSL type you want, etc.
+ */
+ object `package` extends Imports
+
trait Exports {
type MongoCursor = com.mongodb.casbah.MongoCursor
type MongoCollection = com.mongodb.casbah.MongoCollection
View
253 casbah-query/src/main/scala/BarewordOperators.scala
@@ -1,5 +1,5 @@
/**
- * Copyright (c) 2010 10gen, Inc. <http://10gen.com>
+ * Copyright (c) 2010, 2011 10gen, Inc. <http://10gen.com>
* Copyright (c) 2009, 2010 Novus Partners, Inc. <http://novus.com>
*
* Licensed under the Apache License, Version 2.0 (the "License");
@@ -46,7 +46,7 @@ trait BarewordQueryOperator {
/*
* TODO - Implicit filtering of 'valid' (aka convertible) types for [A]
*/
- def apply[A](oper: String)(fields: (String, A)*) = {
+ def apply[A](oper: String)(fields: (String, A)*): DBObject = {
val bldr = MongoDBObject.newBuilder
for ((k, v) <- fields) bldr += k -> v
MongoDBObject(oper -> bldr.result.asDBObject)
@@ -92,18 +92,33 @@ trait FluidQueryBarewordOps extends SetOp
with NorOp
with BitOp
+trait ArrayOps extends PushOp
+ with PushAllOp
+ with AddToSetOp
+ with PopOp
+ with PullOp
+ with PullAllOp
+
+trait SetOpBase extends BarewordQueryOperator {
+ protected def _set = apply[Any]("$set")_
+}
+
/**
* Trait to provide the $set (Set) Set method as a bareword operator.
- *
+ *
* $set ("Foo" -> "bar")
*
- * Targets an RValue of (String, Any)* to be converted to a DBObject
+ * Targets an RValue of (String, Any)* to be converted to a DBObject
*
* @author Brendan W. McAdams <brendan@10gen.com>
* @see http://www.mongodb.org/display/DOCS/Updating#Updating-%24set
*/
-trait SetOp extends BarewordQueryOperator {
- def $set = apply[Any]("$set")_
+trait SetOp extends SetOpBase {
+ def $set = _set
+}
+
+trait UnsetOpBase extends BarewordQueryOperator {
+ protected def _unset(args: String*): DBObject = apply("$unset")(args.map(_ -> 1): _*)
}
/**
@@ -111,41 +126,43 @@ trait SetOp extends BarewordQueryOperator {
*
* $unset ("foo")
*
- * Targets an RValue of String*, where String are field names to be converted to a DBObject
+ * Targets an RValue of String*, where String are field names to be converted to a DBObject
*
* @author Brendan W. McAdams <brendan@10gen.com>
* @see http://www.mongodb.org/display/DOCS/Updating#Updating-%24unset
*/
-trait UnsetOp extends BarewordQueryOperator {
- def $unset(args: String*) = apply("$unset")(args.map(_ -> 1): _*)
+trait UnsetOp extends UnsetOpBase {
+ def $unset = _unset _
}
-/**
+trait IncOpBase extends BarewordQueryOperator {
+ protected def _inc[T: ValidNumericType](args: (String, T)*): DBObject = apply[T]("$inc")(args: _*)
+}
+
+/**
* Trait to provide the $inc (inc) method as a bareword operator..
*
* $inc ("foo" -> 5)
*
- * Targets an RValue of (String, ValidNumericType)* to be converted to a DBObject
+ * Targets an RValue of (String, ValidNumericType)* to be converted to a DBObject
*
* Due to a quirk in the way I implemented type detection this fails if you mix ValidNumericType types. E.g. floats work, but not mixing floats and ints.
* This can be easily circumvented if you want 'ints' with floats by making your ints floats with .0:
- *
+ *
* $inc ("foo" -> 5.0, "bar" -> 1.6)
*
* @author Brendan W. McAdams <brendan@10gen.com>
* @since 1.0
* @see http://www.mongodb.org/display/DOCS/Updating#Updating-%24inc
*/
-trait IncOp extends BarewordQueryOperator {
- def $inc[T: ValidNumericType](args: (String, T)*) = apply[T]("$inc")(args: _*)
+trait IncOp extends IncOpBase {
+ def $inc[T: ValidNumericType](args: (String, T)*): DBObject = _inc(args: _*)
}
-trait ArrayOps extends PushOp
- with PushAllOp
- with AddToSetOp
- with PopOp
- with PullOp
- with PullAllOp
+
+trait PushOpBase extends BarewordQueryOperator {
+ protected def _push = apply[Any]("$push")_
+}
/*
* Trait to provide the $push (push) method as a bareword operator.
@@ -153,28 +170,17 @@ trait ArrayOps extends PushOp
* Targets an RValue of (String, Any)* to be converted to a DBObject
*
* If Field exists but is not an array an error will occur
- *
+ *
* @author Brendan W. McAdams <brendan@10gen.com>
* @see http://www.mongodb.org/display/DOCS/Updating#Updating-%24push
- *
+ *
*/
-trait PushOp extends BarewordQueryOperator {
- def $push = apply[Any]("$push")_
+trait PushOp extends PushOpBase {
+ def $push = _push
}
-/*
- * Trait to provide the $pushAll (pushAll) method as a bareword operator..
- *
- * Targets an RValue of (String, Array[Any])* to be converted to a DBObject
- *
- * RValue MUST Be an array - otherwise use push.
- *
- *
- * @author Brendan W. McAdams <brendan@10gen.com>
- * @see http://www.mongodb.org/display/DOCS/Updating#Updating-%24pushAll
- */
-trait PushAllOp extends BarewordQueryOperator {
- def $pushAll[A <: Any: Manifest](args: (String, A)*): DBObject =
+trait PushAllOpBase extends BarewordQueryOperator {
+ protected def _pushAll[A <: Any: Manifest](args: (String, A)*): DBObject =
if (manifest[A] <:< manifest[Iterable[_]])
apply("$pushAll")(args.map(z => z._1 -> z._2.asInstanceOf[Iterable[_]]): _*)
else if (manifest[A] <:< manifest[Product])
@@ -186,25 +192,27 @@ trait PushAllOp extends BarewordQueryOperator {
}
/*
- * Trait to provide the $addToSet (addToSet) method as a bareword operator..
+ * Trait to provide the $pushAll (pushAll) method as a bareword operator..
*
- * Targets an RValue of (String, Any)* to be converted to a DBObject
+ * Targets an RValue of (String, Array[Any])* to be converted to a DBObject
*
- * Can also combined with the $each operator for adding many values:
+ * RValue MUST Be an array - otherwise use push.
*
- * scala> $addToSet ("foo") $each (5, 10, 15, "20"))
- * res6: com.mongodb.casbah.commons.Imports.DBObject = { "$addToSet" : { "foo" : { "$each" : [ 5 , 10 , 15 , "20"]}}}
*
* @author Brendan W. McAdams <brendan@10gen.com>
- * @see http://www.mongodb.org/display/DOCS/Updating#Updating-%24addToSet
+ * @see http://www.mongodb.org/display/DOCS/Updating#Updating-%24pushAll
*/
-trait AddToSetOp extends BarewordQueryOperator {
+trait PushAllOp extends PushAllOpBase {
+ def $pushAll[A <: Any: Manifest](args: (String, A)*): DBObject = _pushAll(args: _*)
+}
- def $addToSet[T <% DBObject](arg: T) =
+trait AddToSetOpBase extends BarewordQueryOperator {
+ protected def _addToSet[T <% DBObject](arg: T): DBObject =
MongoDBObject("$addToSet" -> arg)
+
/* $each-able */
- def $addToSet(field: String) = {
+ protected def _addToSet(field: String) = {
/**
* Special query operator only available on the right-hand side of an
* $addToSet which takes a list of values.
@@ -231,23 +239,50 @@ trait AddToSetOp extends BarewordQueryOperator {
else op(target(0))
}
}
+ protected def _addToSet = apply[Any]("$addToSet")_
- def $addToSet = apply[Any]("$addToSet")_
}
/*
- * Trait to provide the $pop (pop) method as a bareword operator..
+ * Trait to provide the $addToSet (addToSet) method as a bareword operator..
*
+ * Targets an RValue of (String, Any)* to be converted to a DBObject
+ *
+ * Can also combined with the $each operator for adding many values:
+ *
+ * scala> $addToSet ("foo") $each (5, 10, 15, "20"))
+ * res6: com.mongodb.casbah.commons.Imports.DBObject = { "$addToSet" : { "foo" : { "$each" : [ 5 , 10 , 15 , "20"]}}}
+ *
+ * @author Brendan W. McAdams <brendan@10gen.com>
+ * @see http://www.mongodb.org/display/DOCS/Updating#Updating-%24addToSet
+ */
+trait AddToSetOp extends AddToSetOpBase {
+ def $addToSet[T <% DBObject](arg: T): DBObject = _addToSet(arg)
+ def $addToSet(field: String) = _addToSet(field)
+ def $addToSet = _addToSet
+}
+
+trait PopOpBase extends BarewordQueryOperator {
+ protected def _pop[T: ValidNumericType](args: (String, T)*) = apply[T]("$pop")(args: _*)
+}
+
+/*
+ * Trait to provide the $pop (pop) method as a bareword operator..
*
- * TODO - Restrict to a 'Whole Number' type
- *
* If Field exists but is not an array an error will occurr.
*
* @author Brendan W. McAdams <brendan@10gen.com>
* @see http://www.mongodb.org/display/DOCS/Updating#Updating-%24pop
*/
-trait PopOp extends BarewordQueryOperator {
- def $pop[T: ValidNumericType](args: (String, T)*) = apply[T]("$pop")(args: _*)
+trait PopOp extends PopOpBase {
+ def $pop[T: ValidNumericType](args: (String, T)*) = _pop(args: _*)
+}
+
+trait PullOpBase extends BarewordQueryOperator {
+ protected def _pull = apply[Any]("$pull")_
+ /** ValueTest enabled version */
+ protected def _pull(inner: => DBObject): DBObject = MongoDBObject("$pull" -> inner)
+ protected def _pull(inner: DBObject): DBObject = MongoDBObject("$pull" -> inner)
}
/*
@@ -256,21 +291,29 @@ trait PopOp extends BarewordQueryOperator {
* Targets an RValue of (String, Any)* to be converted to a DBObject
*
* If Field exists but is not an array an error will occurr.
- *
+ *
* Pull is special as defined in the docs and needs to allow operators on fields.
- *
+ *
* @author Brendan W. McAdams <brendan@10gen.com>
* @see http://www.mongodb.org/display/DOCS/Updating#Updating-%24pull
*/
-trait PullOp extends BarewordQueryOperator {
+trait PullOp extends PullOpBase {
def $pull = apply[Any]("$pull")_
+ def $pull(inner: => DBObject): DBObject = _pull(inner)
+ def $pull(inner: DBObject): DBObject = _pull(inner)
+}
- /** ValueTest enabled version */
- def $pull(inner: => DBObject) =
- MongoDBObject("$pull" -> inner)
+trait PullAllOpBase extends BarewordQueryOperator {
+ protected def _pullAll[A <: Any: Manifest](args: (String, A)*): DBObject =
+ if (manifest[A] <:< manifest[Iterable[_]])
+ apply("$pullAll")(args.map(z => z._1 -> z._2.asInstanceOf[Iterable[_]]): _*)
+ else if (manifest[A] <:< manifest[Product])
+ apply("$pullAll")(args.map(z => z._1 -> z._2.asInstanceOf[Product].productIterator.toIterable): _*)
+ else if (manifest[A].erasure.isArray)
+ apply("$pullAll")(args.map(z => z._1 -> z._2.asInstanceOf[Array[_]].toIterable): _*)
+ else
+ throw new IllegalArgumentException("$pullAll may only be invoked with a (String, A) where String is the field name and A is an Iterable or Product/Tuple of values (got %s).".format(manifest[A]))
- def $pull(inner: DBObject) =
- MongoDBObject("$pull" -> inner)
}
@@ -285,16 +328,12 @@ trait PullOp extends BarewordQueryOperator {
* @author Brendan W. McAdams <brendan@10gen.com>
* @see http://www.mongodb.org/display/DOCS/Updating#Updating-%24pullAll
*/
-trait PullAllOp extends BarewordQueryOperator {
- def $pullAll[A <: Any: Manifest](args: (String, A)*): DBObject =
- if (manifest[A] <:< manifest[Iterable[_]])
- apply("$pullAll")(args.map(z => z._1 -> z._2.asInstanceOf[Iterable[_]]): _*)
- else if (manifest[A] <:< manifest[Product])
- apply("$pullAll")(args.map(z => z._1 -> z._2.asInstanceOf[Product].productIterator.toIterable): _*)
- else if (manifest[A].erasure.isArray)
- apply("$pullAll")(args.map(z => z._1 -> z._2.asInstanceOf[Array[_]].toIterable): _*)
- else
- throw new IllegalArgumentException("$pullAll may only be invoked with a (String, A) where String is the field name and A is an Iterable or Product/Tuple of values (got %s).".format(manifest[A]))
+trait PullAllOp extends PullAllOpBase {
+ def $pullAll[A <: Any: Manifest](args: (String, A)*): DBObject = _pullAll(args: _*)
+}
+
+trait AndOpBase {
+ protected def _and = new NestedBarewordListOperator("$and")
}
/**
@@ -304,19 +343,16 @@ trait PullAllOp extends BarewordQueryOperator {
*
* 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 Ben Gamari <bgamari.foss@gmail.com>
- * @since 2.0
+ * @since 3.0
* @see http://www.mongodb.org/display/DOCS/Advanced+Queries#AdvancedQueries-%24and
*/
+trait AndOp extends AndOpBase {
+ def $and = _and
+}
-trait AndOp {
- def $and = new NestedBarewordListOperator("$and")
+trait OrOpBase {
+ protected def _or = new NestedBarewordListOperator("$or")
}
/**
@@ -324,24 +360,21 @@ trait AndOp {
*
* $or ("Foo" -> "bar")
*
- * Targets an RValue of (String, Any)* to be converted to a DBObject
+ * 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 {
- def $or = new NestedBarewordListOperator("$or")
+trait OrOp extends OrOpBase {
+ def $or = _or
}
+trait RenameOpBase extends BarewordQueryOperator {
+ protected def _rename = apply[Any]("$rename")_
+}
+
/**
* Trait to provide the $rename (Rename field) as a bareword operator
*
@@ -354,8 +387,12 @@ trait OrOp {
* @see http://www.mongodb.org/display/DOCS/Updating#Updating-%24rename
*
*/
-trait RenameOp extends BarewordQueryOperator {
- def $rename = apply[Any]("$rename")_
+trait RenameOp extends RenameOpBase {
+ def $rename = _rename
+}
+
+trait NorOpBase {
+ protected def _nor = new NestedBarewordListOperator("$nor")
}
/**
@@ -369,33 +406,35 @@ trait RenameOp extends BarewordQueryOperator {
* @since 2.0
* @see http://www.mongodb.org/display/DOCS/Advanced+Queries#AdvancedQueries-%24nor
*/
-trait NorOp {
- def $nor = new NestedBarewordListOperator("$nor")
+trait NorOp extends NorOpBase {
+ def $nor = _nor
+}
+
+trait BitOpBase extends BarewordQueryOperator {
+ protected def _bit(field: String) = {
+ new {
+ protected def op(oper: String, target: Any) =
+ MongoDBObject("$bit" -> MongoDBObject(field -> MongoDBObject(oper -> target)))
+
+ def and[T: ValidNumericType](target: T) = op("and", target)
+ def or[T: ValidNumericType](target: T) = op("or", target)
+ }
+ }
}
/**
* Trait to provide the $bit (bit) update method as a bareword Operator
- *
+ *
* Bit does a bitwise operation either AND or OR against a given field or set of fields
* with no left anchor.
- *
+ *
* Targets an RValue of {field: {and|or: integer}}.
*
* @author Brendan W. McAdams <brendan@10gen.com>
* @since 2.1.1
* @see http://www.mongodb.org/display/DOCS/Updating#Updating-%24bit
*/
-trait BitOp extends BarewordQueryOperator {
-
- def $bit(field: String) = {
- new {
- protected def op(oper: String, target: Any) =
- MongoDBObject("$bit" -> MongoDBObject(field -> MongoDBObject(oper -> target)))
-
- def and[T: ValidNumericType](target: T) = op("and", target)
- def or[T: ValidNumericType](target: T) = op("or", target)
- }
- }
-
+trait BitOp extends BitOpBase {
+ def $bit(field: String) = _bit(field)
}
// vim: set ts=2 sw=2 sts=2 et:
View
4 casbah-query/src/main/scala/CoreOperators.scala
@@ -1,5 +1,5 @@
/**
- * Copyright (c) 2010 10gen, Inc. <http://10gen.com>
+ * Copyright (c) 2010, 2011 10gen, Inc. <http://10gen.com>
* Copyright (c) 2009, 2010 Novus Partners, Inc. <http://novus.com>
*
* Licensed under the Apache License, Version 2.0 (the "License");
@@ -91,7 +91,7 @@ object QueryExpressionObject {
*
* @author Brendan W. McAdams <brendan@10gen.com>
*/
-sealed trait QueryOperator extends Logging {
+trait QueryOperator extends Logging {
def field: String
protected var dbObj: Option[DBObject] = None
View
2  casbah-query/src/main/scala/Implicits.scala
@@ -26,7 +26,7 @@ package query
import com.mongodb.casbah.query.dsl.QueryExpressionObject
-trait Implicits {// extends FluidQueryBarewordOps {
+trait Implicits {
/**
* Implicit extension methods for String values (e.g. a field name)
View
82 casbah-query/src/main/scala/light/Implicits.scala
@@ -0,0 +1,82 @@
+/**
+ * Copyright (c) 2008 - 2011 10gen, Inc. <http://10gen.com>
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package com.mongodb.casbah
+package query
+package light
+
+trait Implicits {
+
+ /**
+ * Implicit extension methods for String values (e.g. a field name)
+ * to add Mongo's query operators, minimizing the need to write long series'
+ * of nested maps.
+ *
+ * Mixes in the QueryOperators defined in the QueryOperators mixin.
+ * The NestedQuery implicit [Defined below] allows you to call chained operators on the return value of this
+ * method. Chained operators will place the subsequent operators within the same DBObject,
+ * e.g. <code>"fooDate" $lte yesterday $gte tomorrow</code> maps to a Mongo query of:
+ * <code>{"fooDate": {"$lte": <yesterday>, "$gte": <tomorrow>}}</code>
+ *
+ * @param left A string which should be the field name, the left hand of the query
+ * @return Tuple2[String, DBObject] A tuple containing the field name and the mapped operator value, suitable for instantiating a Map
+ */
+ implicit def mongoQueryStatements(left: String) = new {
+ val field = left
+ } with dsl.light.LightFluidQueryOperators
+
+ /**
+ * Implicit extension methods for Tuple2[String, DBObject] values
+ * to add Mongo's query operators, minimizing the need to write long series'
+ * of nested maps.
+ *
+ * Mixes in the QueryOperators defined in the QueryOperators mixin.
+ * The NestedQuery implicits allows you to call chained operators on the return value of the
+ * base String method method. Chained operators will place the subsequent operators within the same DBObject,
+ * e.g. <code>"fooDate" $lte yesterday $gte tomorrow</code> maps to a Mongo query of:
+ * <code>{"fooDate": {"$lte": <yesterday>, "$gte": <tomorrow>}}</code>
+ *
+ * @param left A string which should be the field name, the left hand of the query
+ * @return Tuple2[String, DBObject] A tuple containing the field name and the mapped operator value, suitable for instantiating a Map
+ */
+ implicit def mongoNestedDBObjectQueryStatements(nested: DBObject with dsl.QueryExpressionObject) = {
+ new {
+ val field = nested.field
+ } with dsl.light.LightValueTestFluidQueryOperators {
+ dbObj = nested.getAs[DBObject](nested.field) // TODO - shore the safety of this up
+ }
+ }
+
+ implicit def tupleToGeoCoords[A: ValidNumericType: Manifest, B: ValidNumericType: Manifest](coords: (A, B)) = dsl.GeoCoords(coords._1, coords._2)
+
+}
+
+trait Imports extends dsl.light.LightFluidQueryBarewordOps with query.BaseImports with query.TypeImports with light.Implicits
+ with commons.Imports with commons.Exports with ValidBarewordExpressionArgTypeHolder with ValidDateTypeHolder
+ with ValidNumericTypeHolder with ValidDateOrNumericTypeHolder
+
+object `package` extends Imports
+
+trait BaseImports {
+ val GeoCoords = com.mongodb.casbah.query.dsl.GeoCoords
+}
+
+trait TypeImports {
+ type GeoCoords = com.mongodb.casbah.query.dsl.GeoCoords[_, _]
+}
+
+
View
313 casbah-query/src/main/scala/light/LightBarewordOperators.scala
@@ -0,0 +1,313 @@
+/**
+ * Copyright (c) 2010, 2011 10gen, Inc. <http://10gen.com>
+ * Copyright (c) 2009, 2010 Novus Partners, Inc. <http://novus.com>
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * For questions and comments about this product, please see the project page at:
+ *
+ * http://github.com/mongodb/casbah
+ *
+ */
+
+package com.mongodb.casbah.query.dsl
+package light
+
+import com.mongodb.casbah.util.Logging
+
+import com.mongodb.casbah.query._
+
+import scalaj.collection.Imports._
+
+
+/**
+ * Aggregation object for Bareword Operators.
+ * Bareword operators stand on their own - they lack the requirement for an LValue.
+ * This mixes them in so they can be pulled down in a single import.
+ *
+ * Typically, you want to follow the model Implicits does, and mix this in
+ * if you want to use it but not import Implicits
+ *
+ * @author Brendan W. McAdams <brendan@10gen.com>
+ * @since 1.0
+ * @see com.mongodb.casbah.Implicits
+ */
+trait LightFluidQueryBarewordOps extends LightSetOp
+ with LightUnsetOp
+ with LightIncOp
+ with LightOrOp
+ with LightAndOp
+ with LightRenameOp
+ with LightArrayOps
+ with LightNorOp
+ with LightBitOp
+
+trait LightArrayOps extends LightPushOp
+ with LightPushAllOp
+ with LightAddToSetOp
+ with LightPopOp
+ with LightPullOp
+ with LightPullAllOp
+
+/**
+ * trait to provide the set (Set) Set method as a bareword operator.
+ *
+ * set ("Foo" -> "bar")
+ *
+ * Targets an RValue of (String, Any)* to be converted to a DBObject
+ *
+ * @author Brendan W. McAdams <brendan@10gen.com>
+ * @see http://www.mongodb.org/display/DOCS/Updating#Updating-%24set
+ */
+trait LightSetOp extends SetOpBase {
+ def set = _set
+}
+
+/**
+ * trait to provide the unset (UnSet) UnSet method as a bareword operator..
+ *
+ * unset ("foo")
+ *
+ * Targets an RValue of String*, where String are field names to be converted to a DBObject
+ *
+ * @author Brendan W. McAdams <brendan@10gen.com>
+ * @see http://www.mongodb.org/display/DOCS/Updating#Updating-%24unset
+ */
+trait LightUnsetOp extends UnsetOpBase {
+ def unset = _unset _
+}
+
+/**
+ * trait to provide the inc (inc) method as a bareword operator..
+ *
+ * inc ("foo" -> 5)
+ *
+ * Targets an RValue of (String, ValidNumericType)* to be converted to a DBObject
+ *
+ * Due to a quirk in the way I implemented type detection this fails if you mix ValidNumericType types. E.g. floats work, but not mixing floats and ints.
+ * This can be easily circumvented if you want 'ints' with floats by making your ints floats with .0:
+ *
+ * inc ("foo" -> 5.0, "bar" -> 1.6)
+ *
+ * @author Brendan W. McAdams <brendan@10gen.com>
+ * @since 1.0
+ * @see http://www.mongodb.org/display/DOCS/Updating#Updating-%24inc
+ */
+trait LightIncOp extends IncOpBase {
+ def inc[T: ValidNumericType](args: (String, T)*): DBObject = _inc(args: _*)
+}
+
+
+trait LightPushOpBase extends BarewordQueryOperator {
+ protected def _push = apply[Any]("push")_
+}
+
+/*
+ * trait to provide the push (push) method as a bareword operator.
+ *
+ * Targets an RValue of (String, Any)* to be converted to a DBObject
+ *
+ * If Field exists but is not an array an error will occur
+ *
+ * @author Brendan W. McAdams <brendan@10gen.com>
+ * @see http://www.mongodb.org/display/DOCS/Updating#Updating-%24push
+ *
+ */
+trait LightPushOp extends PushOpBase {
+ def push = _push
+}
+
+/*
+ * trait to provide the pushAll (pushAll) method as a bareword operator..
+ *
+ * Targets an RValue of (String, Array[Any])* to be converted to a DBObject
+ *
+ * RValue MUST Be an array - otherwise use push.
+ *
+ *
+ * @author Brendan W. McAdams <brendan@10gen.com>
+ * @see http://www.mongodb.org/display/DOCS/Updating#Updating-%24pushAll
+ */
+trait LightPushAllOp extends PushAllOpBase {
+ def pushAll[A <: Any: Manifest](args: (String, A)*): DBObject = _pushAll(args: _*)
+}
+
+/*
+ * trait to provide the addToSet (addToSet) method as a bareword operator..
+ *
+ * Targets an RValue of (String, Any)* to be converted to a DBObject
+ *
+ * Can also combined with the each operator for adding many values:
+ *
+ * scala> addToSet ("foo") each (5, 10, 15, "20"))
+ * res6: com.mongodb.casbah.commons.Imports.DBObject = { "addToSet" : { "foo" : { "each" : [ 5 , 10 , 15 , "20"]}}}
+ *
+ * @author Brendan W. McAdams <brendan@10gen.com>
+ * @see http://www.mongodb.org/display/DOCS/Updating#Updating-%24addToSet
+ */
+trait LightAddToSetOp extends AddToSetOpBase {
+ def addToSet[T <% DBObject](arg: T): DBObject = _addToSet(arg)
+ /* $each-able */
+ def addToSet(field: String) = {
+ /**
+ * Special query operator only available on the right-hand side of an
+ * $addToSet which takes a list of values.
+ *
+ * Slightly hacky to prevent it from returning unless completed with a $each
+ *
+ * THIS WILL NOT WORK IN MONGOD ANYWHERE BUT INSIDE AN ADDTOSET
+ *
+ * @author Brendan W. McAdams <brendan@10gen.com>
+ * @since 2.0
+ * @see http://www.mongodb.org/display/DOCS/Updating#Updating-%24addToSet
+ */
+ new {
+ protected def op(target: Any) =
+ MongoDBObject("$addToSet" -> MongoDBObject(field -> MongoDBObject("$each" -> target)))
+
+ def each(target: Array[Any]) = op(target.toList)
+ def each(target: Any*) =
+ if (target.size > 1)
+ op(target.toList)
+ else if (!target(0).isInstanceOf[Iterable[_]] &&
+ !target(0).isInstanceOf[Array[_]])
+ op(List(target(0)))
+ else op(target(0))
+ }
+ }
+ def addToSet = _addToSet
+}
+
+/*
+ * trait to provide the pop (pop) method as a bareword operator..
+ *
+ * If Field exists but is not an array an error will occurr.
+ *
+ * @author Brendan W. McAdams <brendan@10gen.com>
+ * @see http://www.mongodb.org/display/DOCS/Updating#Updating-%24pop
+ */
+trait LightPopOp extends PopOpBase {
+ def pop[T: ValidNumericType](args: (String, T)*) = _pop(args: _*)
+}
+
+/*
+ * trait to provide the pull (pull) method as a bareword operator..
+ *
+ * Targets an RValue of (String, Any)* to be converted to a DBObject
+ *
+ * If Field exists but is not an array an error will occurr.
+ *
+ * Pull is special as defined in the docs and needs to allow operators on fields.
+ *
+ * @author Brendan W. McAdams <brendan@10gen.com>
+ * @see http://www.mongodb.org/display/DOCS/Updating#Updating-%24pull
+ */
+trait LightPullOp extends PullOpBase {
+ def pull = apply[Any]("pull")_
+ def pull(inner: => DBObject): DBObject = _pull(inner)
+ def pull(inner: DBObject): DBObject = _pull(inner)
+}
+
+/*
+ * trait to provide the pullAll (pullAll) method as a bareword operator..
+ *
+ * Targets an RValue of (String, Array[Any])* to be converted to a DBObject
+ *
+ * RValue MUST Be an array - otherwise use pull.
+ *
+ *
+ * @author Brendan W. McAdams <brendan@10gen.com>
+ * @see http://www.mongodb.org/display/DOCS/Updating#Updating-%24pullAll
+ */
+trait LightPullAllOp extends PullAllOpBase {
+ def pullAll[A <: Any: Manifest](args: (String, A)*): DBObject = _pullAll(args: _*)
+}
+
+/**
+ * trait to provide the and method as a bareword operator.
+ *
+ * and ("Foo" -> "bar")
+ *
+ * Targets an RValue of (String, Any)* to be converted to a DBObject
+ *
+ * @author Ben Gamari <bgamari.foss@gmail.com>
+ * @since 3.0
+ * @see http://www.mongodb.org/display/DOCS/Advanced+Queries#AdvancedQueries-%24and
+ */
+trait LightAndOp extends AndOpBase {
+ def and = _and
+}
+
+/**
+ * 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
+ *
+ * @author Brendan W. McAdams <brendan@10gen.com>
+ * @since 2.0
+ * @see http://www.mongodb.org/display/DOCS/Advanced+Queries#AdvancedQueries-%24or
+ */
+trait LightOrOp extends OrOpBase {
+ def or = _or
+}
+
+/**
+ * trait to provide the rename (Rename field) as a bareword operator
+ *
+ * Targets (takes a right-hand value of) a DBObject or a Tuple of (String, String)
+ *
+ * WORKS ONLY IN MONGODB 1.7.2+
+ *
+ * @author Brendan W. McAdams <brendan@10gen.com>
+ * @since 2.0
+ * @see http://www.mongodb.org/display/DOCS/Updating#Updating-%24rename
+ *
+ */
+trait LightRenameOp extends RenameOpBase {
+ def rename = _rename
+}
+
+/**
+ * trait to provide the nor (nor ) method as a bareword operator
+ *
+ * Nor is a combination of not and or with no left anchor
+ *
+ * Targets an RValue of (String, Array[Any])* to be converted to a DBObject
+ *
+ * @author Brendan W. McAdams <brendan@10gen.com>
+ * @since 2.0
+ * @see http://www.mongodb.org/display/DOCS/Advanced+Queries#AdvancedQueries-%24nor
+ */
+trait LightNorOp extends NorOpBase {
+ def nor = _nor
+}
+
+/**
+ * trait to provide the bit (bit) update method as a bareword Operator
+ *
+ * Bit does a bitwise operation either AND or OR against a given field or set of fields
+ * with no left anchor.
+ *
+ * Targets an RValue of {field: {and|or: integer}}.
+ *
+ * @author Brendan W. McAdams <brendan@10gen.com>
+ * @since 2.1.1
+ * @see http://www.mongodb.org/display/DOCS/Updating#Updating-%24bit
+ */
+trait LightBitOp extends BitOpBase {
+ def bit(field: String) = _bit(field)
+}
+
+// vim: set ts=2 sw=2 sts=2 et:
View
714 casbah-query/src/main/scala/light/LightCoreOperators.scala
@@ -0,0 +1,714 @@
+/**
+ * Copyright (c) 2008 - 2011 10gen, Inc. <http://10gen.com>
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package com.mongodb.casbah.query.dsl
+package light
+
+import com.mongodb.casbah.util.Logging
+
+import scalaj.collection.Imports._
+
+import com.mongodb.casbah.query._
+
+import scala.util.matching._
+import scala.collection.Iterable
+
+import org.bson._
+import org.bson.types.BasicBSONList
+
+
+/**
+ * Mixed trait Lightwhich provides all possible
+ * operators. See Implicits for examples of usage.
+ *
+ * @author Brendan W. McAdams <brendan@10gen.com>
+ */
+trait LightFluidQueryOperators extends LightNotEqualsOp
+ with LightLessThanOp
+ with LightLessThanEqualOp
+ with LightGreaterThanOp
+ with LightGreaterThanEqualOp
+/* with LightInOp*/
+ with LightNotInOp
+ with LightModuloOp
+ with LightSizeOp
+ with LightExistsOp
+ with LightAllOp
+ with LightWhereOp
+ with LightNotOp
+/* with LightSliceOp*/
+ with LightTypeOp
+ with LightElemMatchOp
+ with LightGeospatialOps
+
+trait LightValueTestFluidQueryOperators extends LightLessThanOp
+ with LightLessThanEqualOp
+ with LightGreaterThanOp
+ with LightGreaterThanEqualOp
+ with LightModuloOp
+ with LightSizeOp
+ with LightAllOp
+ with LightWhereOp
+ with LightNotEqualsOp
+ with LightTypeOp
+
+/**
+ * trait to provide the $ne (Not Equal To) method on appropriate callers.
+ *
+ * Targets (takes a right-hand value of) String, Numeric,
+ * Array, DBObject (and DBList), Iterable[_] and Tuple1->22.
+ *
+ *
+ * @author Brendan W. McAdams <brendan@10gen.com>
+ * @see http://www.mongodb.org/display/DOCS/Advanced+Queries#AdvancedQueries-%24ne
+ */
+trait LightNotEqualsOp extends QueryOperator {
+ private val oper = "$ne"
+
+ def ne(target: String) = op(oper, target)
+ def ne(target: DBObject) = op(oper, target)
+ def ne(target: DBRef) = op(oper, target)
+ def ne(target: ObjectId) = op(oper, target)
+ def ne(target: Boolean) = op(oper, target)
+ def ne(target: Array[_]) = op(oper, target.toList)
+ def ne(target: Tuple1[_]) = op(oper, target.productIterator.toList)
+ def ne(target: Tuple2[_, _]) = op(oper, target.productIterator.toList)
+ def ne(target: Tuple3[_, _, _]) = op(oper, target.productIterator.toList)
+ def ne(target: Tuple4[_, _, _, _]) = op(oper, target.productIterator.toList)
+ def ne(target: Tuple5[_, _, _, _, _]) = op(oper, target.productIterator.toList)
+ def ne(target: Tuple6[_, _, _, _, _, _]) = op(oper, target.productIterator.toList)
+ def ne(target: Tuple7[_, _, _, _, _, _, _]) = op(oper, target.productIterator.toList)
+ def ne(target: Tuple8[_, _, _, _, _, _, _, _]) = op(oper, target.productIterator.toList)
+ def ne(target: Tuple9[_, _, _, _, _, _, _, _, _]) = op(oper, target.productIterator.toList)
+ def ne(target: Tuple10[_, _, _, _, _, _, _, _, _, _]) = op(oper, target.productIterator.toList)
+ def ne(target: Tuple11[_, _, _, _, _, _, _, _, _, _, _]) = op(oper, target.productIterator.toList)
+ def ne(target: Tuple12[_, _, _, _, _, _, _, _, _, _, _, _]) = op(oper, target.productIterator.toList)
+ def ne(target: Tuple13[_, _, _, _, _, _, _, _, _, _, _, _, _]) = op(oper, target.productIterator.toList)
+ def ne(target: Tuple14[_, _, _, _, _, _, _, _, _, _, _, _, _, _]) = op(oper, target.productIterator.toList)
+ def ne(target: Tuple15[_, _, _, _, _, _, _, _, _, _, _, _, _, _, _]) = op(oper, target.productIterator.toList)
+ def ne(target: Tuple16[_, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _]) = op(oper, target.productIterator.toList)
+ def ne(target: Tuple17[_, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _]) = op(oper, target.productIterator.toList)
+ def ne(target: Tuple18[_, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _]) = op(oper, target.productIterator.toList)
+ def ne(target: Tuple19[_, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _]) = op(oper, target.productIterator.toList)
+ def ne(target: Tuple20[_, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _]) = op(oper, target.productIterator.toList)
+ def ne(target: Tuple21[_, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _]) = op(oper, target.productIterator.toList)
+ def ne(target: Tuple22[_, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _]) = op(oper, target.productIterator.toList)
+ def ne(target: Iterable[_]) = op(oper, target.toList)
+ def ne[T: ValidDateOrNumericType](target: T) = op(oper, target)
+}
+
+/**
+ * trait to provide the $lt (Less Than) method on appropriate callers.
+ *
+ * Targets (takes a right-hand value of) String, Numeric, JDK And Joda Dates,
+ * Array, DBObject (and DBList), Iterable[_] and Tuple1->22.
+ *
+ *
+ * @author Brendan W. McAdams <brendan@10gen.com>
+ * @see http://www.mongodb.org/display/DOCS/Advanced+Queries#AdvancedQueries-%3C%2C%3C%3D%2C%3E%2C%3E%3D
+ */
+trait LightLessThanOp extends QueryOperator {
+ private val oper = "$lt"
+
+ def lt(target: String) = op(oper, target)
+ def lt(target: DBObject) = op(oper, target)
+ def lt(target: Array[_]) = op(oper, target.toList)
+ def lt(target: Tuple1[_]) = op(oper, target.productIterator.toList)
+ def lt(target: Tuple2[_, _]) = op(oper, target.productIterator.toList)
+ def lt(target: Tuple3[_, _, _]) = op(oper, target.productIterator.toList)
+ def lt(target: Tuple4[_, _, _, _]) = op(oper, target.productIterator.toList)
+ def lt(target: Tuple5[_, _, _, _, _]) = op(oper, target.productIterator.toList)
+ def lt(target: Tuple6[_, _, _, _, _, _]) = op(oper, target.productIterator.toList)
+ def lt(target: Tuple7[_, _, _, _, _, _, _]) = op(oper, target.productIterator.toList)
+ def lt(target: Tuple8[_, _, _, _, _, _, _, _]) = op(oper, target.productIterator.toList)
+ def lt(target: Tuple9[_, _, _, _, _, _, _, _, _]) = op(oper, target.productIterator.toList)
+ def lt(target: Tuple10[_, _, _, _, _, _, _, _, _, _]) = op(oper, target.productIterator.toList)
+ def lt(target: Tuple11[_, _, _, _, _, _, _, _, _, _, _]) = op(oper, target.productIterator.toList)
+ def lt(target: Tuple12[_, _, _, _, _, _, _, _, _, _, _, _]) = op(oper, target.productIterator.toList)
+ def lt(target: Tuple13[_, _, _, _, _, _, _, _, _, _, _, _, _]) = op(oper, target.productIterator.toList)
+ def lt(target: Tuple14[_, _, _, _, _, _, _, _, _, _, _, _, _, _]) = op(oper, target.productIterator.toList)
+ def lt(target: Tuple15[_, _, _, _, _, _, _, _, _, _, _, _, _, _, _]) = op(oper, target.productIterator.toList)
+ def lt(target: Tuple16[_, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _]) = op(oper, target.productIterator.toList)
+ def lt(target: Tuple17[_, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _]) = op(oper, target.productIterator.toList)
+ def lt(target: Tuple18[_, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _]) = op(oper, target.productIterator.toList)
+ def lt(target: Tuple19[_, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _]) = op(oper, target.productIterator.toList)
+ def lt(target: Tuple20[_, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _]) = op(oper, target.productIterator.toList)
+ def lt(target: Tuple21[_, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _]) = op(oper, target.productIterator.toList)
+ def lt(target: Tuple22[_, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _]) = op(oper, target.productIterator.toList)
+ def lt(target: Iterable[_]) = op(oper, target.toList)
+ def lt[T: ValidDateOrNumericType](target: T) = op(oper, target)
+}
+
+/**
+ * trait to provide the $lte (Less Than Or Equal To) method on appropriate callers.
+ *
+ * Targets (takes a right-hand value of) String, Numeric, JDK And Joda Dates,
+ * Array, DBObject (and DBList), Iterable[_] and Tuple1->22.*
+ *
+ * @author Brendan W. McAdams <brendan@10gen.com>
+ * @see http://www.mongodb.org/display/DOCS/Advanced+Queries#AdvancedQueries-%3C%2C%3C%3D%2C%3E%2C%3E%3D
+ */
+trait LightLessThanEqualOp extends QueryOperator {
+ private val oper = "$lte"
+
+ def lte(target: String) = op(oper, target)
+ def lte(target: DBObject) = op(oper, target)
+ def lte(target: Array[_]) = op(oper, target.toList)
+ def lte(target: Tuple1[_]) = op(oper, target.productIterator.toList)
+ def lte(target: Tuple2[_, _]) = op(oper, target.productIterator.toList)
+ def lte(target: Tuple3[_, _, _]) = op(oper, target.productIterator.toList)
+ def lte(target: Tuple4[_, _, _, _]) = op(oper, target.productIterator.toList)
+ def lte(target: Tuple5[_, _, _, _, _]) = op(oper, target.productIterator.toList)
+ def lte(target: Tuple6[_, _, _, _, _, _]) = op(oper, target.productIterator.toList)
+ def lte(target: Tuple7[_, _, _, _, _, _, _]) = op(oper, target.productIterator.toList)
+ def lte(target: Tuple8[_, _, _, _, _, _, _, _]) = op(oper, target.productIterator.toList)
+ def lte(target: Tuple9[_, _, _, _, _, _, _, _, _]) = op(oper, target.productIterator.toList)
+ def lte(target: Tuple10[_, _, _, _, _, _, _, _, _, _]) = op(oper, target.productIterator.toList)
+ def lte(target: Tuple11[_, _, _, _, _, _, _, _, _, _, _]) = op(oper, target.productIterator.toList)
+ def lte(target: Tuple12[_, _, _, _, _, _, _, _, _, _, _, _]) = op(oper, target.productIterator.toList)
+ def lte(target: Tuple13[_, _, _, _, _, _, _, _, _, _, _, _, _]) = op(oper, target.productIterator.toList)
+ def lte(target: Tuple14[_, _, _, _, _, _, _, _, _, _, _, _, _, _]) = op(oper, target.productIterator.toList)
+ def lte(target: Tuple15[_, _, _, _, _, _, _, _, _, _, _, _, _, _, _]) = op(oper, target.productIterator.toList)
+ def lte(target: Tuple16[_, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _]) = op(oper, target.productIterator.toList)
+ def lte(target: Tuple17[_, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _]) = op(oper, target.productIterator.toList)
+ def lte(target: Tuple18[_, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _]) = op(oper, target.productIterator.toList)
+ def lte(target: Tuple19[_, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _]) = op(oper, target.productIterator.toList)
+ def lte(target: Tuple20[_, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _]) = op(oper, target.productIterator.toList)
+ def lte(target: Tuple21[_, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _]) = op(oper, target.productIterator.toList)
+ def lte(target: Tuple22[_, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _]) = op(oper, target.productIterator.toList)
+ def lte(target: Iterable[_]) = op(oper, target.toList)
+ def lte[T: ValidDateOrNumericType](target: T) = op(oper, target)
+}
+
+/**
+ * trait to provide the $gt (Greater Than) method on appropriate callers.
+ *
+ * Targets (takes a right-hand value of) String, Numeric, JDK And Joda Dates,
+ * Array, DBObject (and DBList), Iterable[_] and Tuple1->22.*
+ *
+ * @author Brendan W. McAdams <brendan@10gen.com>
+ * @see http://www.mongodb.org/display/DOCS/Advanced+Queries#AdvancedQueries-%3C%2C%3C%3D%2C%3E%2C%3E%3D
+ */
+trait LightGreaterThanOp extends QueryOperator {
+ private val oper = "$gt"
+
+ def gt(target: String) = op(oper, target)
+ def gt(target: DBObject) = op(oper, target)
+ def gt(target: Array[_]) = op(oper, target.toList)
+ def gt(target: Tuple1[_]) = op(oper, target.productIterator.toList)
+ def gt(target: Tuple2[_, _]) = op(oper, target.productIterator.toList)
+ def gt(target: Tuple3[_, _, _]) = op(oper, target.productIterator.toList)
+ def gt(target: Tuple4[_, _, _, _]) = op(oper, target.productIterator.toList)
+ def gt(target: Tuple5[_, _, _, _, _]) = op(oper, target.productIterator.toList)
+ def gt(target: Tuple6[_, _, _, _, _, _]) = op(oper, target.productIterator.toList)
+ def gt(target: Tuple7[_, _, _, _, _, _, _]) = op(oper, target.productIterator.toList)
+ def gt(target: Tuple8[_, _, _, _, _, _, _, _]) = op(oper, target.productIterator.toList)
+ def gt(target: Tuple9[_, _, _, _, _, _, _, _, _]) = op(oper, target.productIterator.toList)
+ def gt(target: Tuple10[_, _, _, _, _, _, _, _, _, _]) = op(oper, target.productIterator.toList)
+ def gt(target: Tuple11[_, _, _, _, _, _, _, _, _, _, _]) = op(oper, target.productIterator.toList)
+ def gt(target: Tuple12[_, _, _, _, _, _, _, _, _, _, _, _]) = op(oper, target.productIterator.toList)
+ def gt(target: Tuple13[_, _, _, _, _, _, _, _, _, _, _, _, _]) = op(oper, target.productIterator.toList)
+ def gt(target: Tuple14[_, _, _, _, _, _, _, _, _, _, _, _, _, _]) = op(oper, target.productIterator.toList)
+ def gt(target: Tuple15[_, _, _, _, _, _, _, _, _, _, _, _, _, _, _]) = op(oper, target.productIterator.toList)
+ def gt(target: Tuple16[_, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _]) = op(oper, target.productIterator.toList)
+ def gt(target: Tuple17[_, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _]) = op(oper, target.productIterator.toList)
+ def gt(target: Tuple18[_, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _]) = op(oper, target.productIterator.toList)
+ def gt(target: Tuple19[_, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _]) = op(oper, target.productIterator.toList)
+ def gt(target: Tuple20[_, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _]) = op(oper, target.productIterator.toList)
+ def gt(target: Tuple21[_, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _]) = op(oper, target.productIterator.toList)
+ def gt(target: Tuple22[_, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _]) = op(oper, target.productIterator.toList)
+ def gt(target: Iterable[_]) = op(oper, target.toList)
+ def gt[T: ValidDateOrNumericType](target: T) = op(oper, target)
+}
+
+/**
+ * trait to provide the $gte (Greater Than Or Equal To) method on appropriate callers.
+ *
+ * Targets (takes a right-hand value of) String, Numeric, JDK And Joda Dates,
+ * Array, DBObject (and DBList), Iterable[_] and Tuple1->22.*
+ *
+ * @author Brendan W. McAdams <brendan@10gen.com>
+ * @see http://www.mongodb.org/display/DOCS/Advanced+Queries#AdvancedQueries-%3C%2C%3C%3D%2C%3E%2C%3E%3D
+ */
+trait LightGreaterThanEqualOp extends QueryOperator {
+ private val oper = "$gte"
+
+ def gte(target: String) = op(oper, target)
+ def gte(target: DBObject) = op(oper, target)
+ def gte(target: Array[_]) = op(oper, target.toList)
+ def gte(target: Tuple1[_]) = op(oper, target.productIterator.toList)
+ def gte(target: Tuple2[_, _]) = op(oper, target.productIterator.toList)
+ def gte(target: Tuple3[_, _, _]) = op(oper, target.productIterator.toList)
+ def gte(target: Tuple4[_, _, _, _]) = op(oper, target.productIterator.toList)
+ def gte(target: Tuple5[_, _, _, _, _]) = op(oper, target.productIterator.toList)
+ def gte(target: Tuple6[_, _, _, _, _, _]) = op(oper, target.productIterator.toList)
+ def gte(target: Tuple7[_, _, _, _, _, _, _]) = op(oper, target.productIterator.toList)
+ def gte(target: Tuple8[_, _, _, _, _, _, _, _]) = op(oper, target.productIterator.toList)
+ def gte(target: Tuple9[_, _, _, _, _, _, _, _, _]) = op(oper, target.productIterator.toList)
+ def gte(target: Tuple10[_, _, _, _, _, _, _, _, _, _]) = op(oper, target.productIterator.toList)
+ def gte(target: Tuple11[_, _, _, _, _, _, _, _, _, _, _]) = op(oper, target.productIterator.toList)
+ def gte(target: Tuple12[_, _, _, _, _, _, _, _, _, _, _, _]) = op(oper, target.productIterator.toList)
+ def gte(target: Tuple13[_, _, _, _, _, _, _, _, _, _, _, _, _]) = op(oper, target.productIterator.toList)
+ def gte(target: Tuple14[_, _, _, _, _, _, _, _, _, _, _, _, _, _]) = op(oper, target.productIterator.toList)
+ def gte(target: Tuple15[_, _, _, _, _, _, _, _, _, _, _, _, _, _, _]) = op(oper, target.productIterator.toList)
+ def gte(target: Tuple16[_, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _]) = op(oper, target.productIterator.toList)
+ def gte(target: Tuple17[_, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _]) = op(oper, target.productIterator.toList)
+ def gte(target: Tuple18[_, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _]) = op(oper, target.productIterator.toList)
+ def gte(target: Tuple19[_, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _]) = op(oper, target.productIterator.toList)
+ def gte(target: Tuple20[_, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _]) = op(oper, target.productIterator.toList)
+ def gte(target: Tuple21[_, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _]) = op(oper, target.productIterator.toList)
+ def gte(target: Tuple22[_, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _]) = op(oper, target.productIterator.toList)
+ def gte(target: Iterable[_]) = op(oper, target.toList)
+ def gte[T: ValidDateOrNumericType](target: T) = op(oper, target)
+}
+
+/**
+ * trait to provide the $in (In Array) method on appropriate callers.
+ *
+ * Targets (takes a right-hand value of) Arrays of [Any] and variable argument lists of Any.
+ *
+ * Note that the magic of Scala DSLey-ness means that you can write a method such as:
+ *
+ * <code>var x = "foo" $in (1, 2, 3, 5, 28)</code>
+ *
+ * As a valid statement - (1...28) is taken as the argument list to $in and converted
+ * to an Array under the covers.
+ *
+ * @author Brendan W. McAdams <brendan@10gen.com>
+ * @see http://www.mongodb.org/display/DOCS/Advanced+Queries#AdvancedQueries-%24in
+ */
+trait LightInOp extends QueryOperator {
+ private val oper = "$in"
+
+ def in(target: Array[_]) = op(oper, target.toList)
+ def in(target: Tuple1[_]) = op(oper, target.productIterator.toList)
+ def in(target: Tuple2[_, _]) = op(oper, target.productIterator.toList)
+ def in(target: Tuple3[_, _, _]) = op(oper, target.productIterator.toList)
+ def in(target: Tuple4[_, _, _, _]) = op(oper, target.productIterator.toList)
+ def in(target: Tuple5[_, _, _, _, _]) = op(oper, target.productIterator.toList)
+ def in(target: Tuple6[_, _, _, _, _, _]) = op(oper, target.productIterator.toList)
+ def in(target: Tuple7[_, _, _, _, _, _, _]) = op(oper, target.productIterator.toList)
+ def in(target: Tuple8[_, _, _, _, _, _, _, _]) = op(oper, target.productIterator.toList)
+ def in(target: Tuple9[_, _, _, _, _, _, _, _, _]) = op(oper, target.productIterator.toList)
+ def in(target: Tuple10[_, _, _, _, _, _, _, _, _, _]) = op(oper, target.productIterator.toList)
+ def in(target: Tuple11[_, _, _, _, _, _, _, _, _, _, _]) = op(oper, target.productIterator.toList)
+ def in(target: Tuple12[_, _, _, _, _, _, _, _, _, _, _, _]) = op(oper, target.productIterator.toList)
+ def in(target: Tuple13[_, _, _, _, _, _, _, _, _, _, _, _, _]) = op(oper, target.productIterator.toList)
+ def in(target: Tuple14[_, _, _, _, _, _, _, _, _, _, _, _, _, _]) = op(oper, target.productIterator.toList)
+ def in(target: Tuple15[_, _, _, _, _, _, _, _, _, _, _, _, _, _, _]) = op(oper, target.productIterator.toList)
+ def in(target: Tuple16[_, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _]) = op(oper, target.productIterator.toList)
+ def in(target: Tuple17[_, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _]) = op(oper, target.productIterator.toList)
+ def in(target: Tuple18[_, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _]) = op(oper, target.productIterator.toList)
+ def in(target: Tuple19[_, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _]) = op(oper, target.productIterator.toList)
+ def in(target: Tuple20[_, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _]) = op(oper, target.productIterator.toList)
+ def in(target: Tuple21[_, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _]) = op(oper, target.productIterator.toList)
+ def in(target: Tuple22[_, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _]) = op(oper, target.productIterator.toList)
+ def in(target: Iterable[_]) = op(oper, target.toList)
+}
+
+/**
+ * trait to provide the $nin (NOT In Array) method on appropriate callers.
+ *
+ * Targets (takes a right-hand value of) Arrays of [Any] and variable argument lists of Any.
+ *
+ * Note that the magic of Scala DSLey-ness means that you can write a method such as:
+ *
+ * <code>var x = "foo" $nin (1, 2, 3, 5, 28)</code>
+ *
+ * As a valid statement - (1...28) is taken as the argument list to $nin and converted
+ * to an Array under the covers.
+ *
+ * @author Brendan W. McAdams <brendan@10gen.com>
+ * @see http://www.mongodb.org/display/DOCS/Advanced+Queries#AdvancedQueries-%24nin
+ */
+trait LightNotInOp extends QueryOperator {
+ private val oper = "$nin"
+
+ def nin(target: Array[_]) = op(oper, target.toList)
+ def nin(target: Tuple1[_]) = op(oper, target.productIterator.toList)
+ def nin(target: Tuple2[_, _]) = op(oper, target.productIterator.toList)
+ def nin(target: Tuple3[_, _, _]) = op(oper, target.productIterator.toList)
+ def nin(target: Tuple4[_, _, _, _]) = op(oper, target.productIterator.toList)
+ def nin(target: Tuple5[_, _, _, _, _]) = op(oper, target.productIterator.toList)
+ def nin(target: Tuple6[_, _, _, _, _, _]) = op(oper, target.productIterator.toList)
+ def nin(target: Tuple7[_, _, _, _, _, _, _]) = op(oper, target.productIterator.toList)
+ def nin(target: Tuple8[_, _, _, _, _, _, _, _]) = op(oper, target.productIterator.toList)
+ def nin(target: Tuple9[_, _, _, _, _, _, _, _, _]) = op(oper, target.productIterator.toList)
+ def nin(target: Tuple10[_, _, _, _, _, _, _, _, _, _]) = op(oper, target.productIterator.toList)
+ def nin(target: Tuple11[_, _, _, _, _, _, _, _, _, _, _]) = op(oper, target.productIterator.toList)
+ def nin(target: Tuple12[_, _, _, _, _, _, _, _, _, _, _, _]) = op(oper, target.productIterator.toList)
+ def nin(target: Tuple13[_, _, _, _, _, _, _, _, _, _, _, _, _]) = op(oper, target.productIterator.toList)
+ def nin(target: Tuple14[_, _, _, _, _, _, _, _, _, _, _, _, _, _]) = op(oper, target.productIterator.toList)
+ def nin(target: Tuple15[_, _, _, _, _, _, _, _, _, _, _, _, _, _, _]) = op(oper, target.productIterator.toList)
+ def nin(target: Tuple16[_, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _]) = op(oper, target.productIterator.toList)
+ def nin(target: Tuple17[_, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _]) = op(oper, target.productIterator.toList)
+ def nin(target: Tuple18[_, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _]) = op(oper, target.productIterator.toList)
+ def nin(target: Tuple19[_, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _]) = op(oper, target.productIterator.toList)
+ def nin(target: Tuple20[_, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _]) = op(oper, target.productIterator.toList)
+ def nin(target: Tuple21[_, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _]) = op(oper, target.productIterator.toList)
+ def nin(target: Tuple22[_, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _]) = op(oper, target.productIterator.toList)
+ def nin(target: Iterable[_]) = op(oper, target.toList)
+}
+
+/**
+ * trait to provide the $all (Match ALL In Array) method on appropriate callers.
+ *
+ * Targets (takes a right-hand value of) Arrays of [Any] and variable argument lists of Any.
+ *
+ * Note that the magic of Scala DSLey-ness means that you can write a method such as:
+ *
+ * <code>var x = "foo" $all (1, 2, 3, 5, 28)</code>
+ *
+ * As a valid statement - (1...28) is taken as the argument list to $all and converted
+ * to an Array under the covers.
+ *
+ * @author Brendan W. McAdams <brendan@10gen.com>
+ * @see http://www.mongodb.org/display/DOCS/Advanced+Queries#AdvancedQueries-%24all
+ */
+trait LightAllOp extends QueryOperator {
+ private val oper = "$all"
+
+ def all(target: Array[_]) = op(oper, target.toList)
+ def all(target: Tuple1[_]) = op(oper, target.productIterator.toList)
+ def all(target: Tuple2[_, _]) = op(oper, target.productIterator.toList)
+ def all(target: Tuple3[_, _, _]) = op(oper, target.productIterator.toList)
+ def all(target: Tuple4[_, _, _, _]) = op(oper, target.productIterator.toList)
+ def all(target: Tuple5[_, _, _, _, _]) = op(oper, target.productIterator.toList)
+ def all(target: Tuple6[_, _, _, _, _, _]) = op(oper, target.productIterator.toList)
+ def all(target: Tuple7[_, _, _, _, _, _, _]) = op(oper, target.productIterator.toList)
+ def all(target: Tuple8[_, _, _, _, _, _, _, _]) = op(oper, target.productIterator.toList)
+ def all(target: Tuple9[_, _, _, _, _, _, _, _, _]) = op(oper, target.productIterator.toList)
+ def all(target: Tuple10[_, _, _, _, _, _, _, _, _, _]) = op(oper, target.productIterator.toList)
+ def all(target: Tuple11[_, _, _, _, _, _, _, _, _, _, _]) = op(oper, target.productIterator.toList)
+ def all(target: Tuple12[_, _, _, _, _, _, _, _, _, _, _, _]) = op(oper, target.productIterator.toList)
+ def all(target: Tuple13[_, _, _, _, _, _, _, _, _, _, _, _, _]) = op(oper, target.productIterator.toList)
+ def all(target: Tuple14[_, _, _, _, _, _, _, _, _, _, _, _, _, _]) = op(oper, target.productIterator.toList)
+ def all(target: Tuple15[_, _, _, _, _, _, _, _, _, _, _, _, _, _, _]) = op(oper, target.productIterator.toList)
+ def all(target: Tuple16[_, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _]) = op(oper, target.productIterator.toList)
+ def all(target: Tuple17[_, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _]) = op(oper, target.productIterator.toList)
+ def all(target: Tuple18[_, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _]) = op(oper, target.productIterator.toList)
+ def all(target: Tuple19[_, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _]) = op(oper, target.productIterator.toList)
+ def all(target: Tuple20[_, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _]) = op(oper, target.productIterator.toList)
+ def all(target: Tuple21[_, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _]) = op(oper, target.productIterator.toList)
+ def all(target: Tuple22[_, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _]) = op(oper, target.productIterator.toList)
+ def all(target: Iterable[_]) = op(oper, target.toList)
+}
+
+/**
+ * trait to provide the $mod (Modulo) method on appropriate callers.
+ *
+ * Targets a left and right value where the formula is (field % left == right)
+ *
+ * Left and Right can be any ValidNumericType and of two differing types (e.g. one int, one float)
+ *
+ *
+ * @author Brendan W. McAdams <brendan@10gen.com>
+ * @see http://www.mongodb.org/display/DOCS/Advanced+Queries#AdvancedQueries-%24mod
+ */
+trait LightModuloOp extends QueryOperator {
+ private val oper = "$mod"
+
+ def mod[A: ValidNumericType, B: ValidNumericType](left: A, right: B) = op(oper, MongoDBList(left, right))
+}
+
+/**
+ * trait to provide the $size (Size) method on appropriate callers.
+ *
+ * Test value must be an Int or BigInt.
+ *
+ * @author Brendan W. McAdams <brendan@10gen.com>
+ * @see http://www.mongodb.org/display/DOCS/Advanced+Queries#AdvancedQueries-%24size
+ */
+trait LightSizeOp extends QueryOperator {
+ private val oper = "$size"
+
+ def size(target: Int) = op(oper, target)
+ def size(target: BigInt) = op(oper, target)
+}
+
+/**
+ * trait to provide the $exists (Exists) method on appropriate callers.
+ *
+ * Targets (takes a right-hand value of) Booleans.
+ *
+ * @author Brendan W. McAdams <brendan@10gen.com>
+ * @see http://www.mongodb.org/display/DOCS/Advanced+Queries#AdvancedQueries-%7B%7B%24exists%7D%7D
+ */
+trait LightExistsOp extends QueryOperator {
+ private val oper = "$exists"
+
+ def exists(target: Boolean) = op(oper, target)
+}
+
+/**
+ * trait to provide the $where (Where) method on appropriate callers.
+ *
+ * Targets (takes a right-hand value of) JSFunction [which is currently just as string containing a javascript function]
+ *
+ * @author Brendan W. McAdams <brendan@10gen.com>
+ * @see http://www.mongodb.org/display/DOCS/Advanced+Queries#AdvancedQueries-JavascriptExpressionsand%7B%7B%24where%7D%7D
+ */
+trait LightWhereOp extends QueryOperator {
+ private val oper = "$where"
+
+ def where(target: JSFunction) = op(oper, target)
+}
+
+/**
+ * trait to provide the $not (Not) negation method on appropriate callers.
+ *
+ * Make sure your anchor it when you have multiple operators e.g.
+ *
+ * "foo".$not $mod(5, 10)
+ *
+ * Targets (takes a right-hand value of) DBObject or a Scala RegEx
+ *
+ * @author Brendan W. McAdams <brendan@10gen.com>
+ * @see http://www.mongodb.org/display/DOCS/Advanced+Queries#AdvancedQueries-Metaoperator%3A%24not
+ */
+trait LightNotOp extends QueryOperator {
+ private val oper = "$not"
+
+ def not(inner: LightFluidQueryOperators => DBObject) = {
+ val dbObj = inner(new LightFluidQueryOperators {
+ val field = oper
+ })
+ MongoDBObject(field -> dbObj)
+ }
+
+ def not(re: scala.util.matching.Regex) = op(oper, re.pattern)
+ def not(re: java.util.regex.Pattern) = op(oper, re)
+}
+
+/**
+ * trait to provide the $slice (Slice of Array) method on appropriate callers.
+ *
+ * Targets (takes a right-hand value of) either an Int of slice indicator or a tuple
+ * of skip and limit.
+ *
+ * &gt; "foo" $slice 5
+ * res0: (String, com.mongodb.DBObject) = (foo,{ "$slice" : 5})
+ *
+ * &gt; "foo" $slice (5, -1)
+ * res1: (String, com.mongodb.DBObject) = (foo,{ "$slice" : [ 5 , -1]})
+ *
+ * @author Brendan W. McAdams <brendan@10gen.com>
+ * @since 2.0
+ * @see http://www.mongodb.org/display/DOCS/Advanced+Queries#AdvancedQueries-%24sliceoperator
+ *
+ */
+trait LightSliceOp extends QueryOperator {
+ private val oper = "$slice"
+
+ def slice(target: Int) = op(oper, target)
+ def slice(slice: Int, limit: Int) = op(oper, MongoDBList(slice, limit))
+}
+
+/**
+ * trait to provide the $elemMatch method on appropriate callers.
+ *
+ * Targets (takes a right-hand value of) a DBObject view context
+ *
+ * @author Brendan W. McAdams <brendan@10gen.com>
+ * @since 2.0
+ * @see http://www.mongodb.org/display/DOCS/Dot+Notation+(Reaching+into+Objects)#DotNotation%28ReachingintoObjects%29-Matchingwith%24elemMatch
+ *
+ */
+trait LightElemMatchOp extends QueryOperator {
+ private val oper = "$elemMatch"
+
+ def elemMatch[A <% DBObject](target: A) = op(oper, target)
+}
+
+abstract class BSONType[A]
+
+object BSONType {
+ implicit object BSONDouble extends BSONType[Double]
+ implicit object BSONString extends BSONType[String]
+ implicit object BSONObject extends BSONType[BSONObject]
+ implicit object DBObject extends BSONType[DBObject]
+ implicit object DBList extends BSONType[BasicDBList]
+ implicit object BSONDBList extends BSONType[BasicBSONList]
+ implicit object BSONBinary extends BSONType[Array[Byte]]
+ implicit object BSONArray extends BSONType[Array[_]]
+ implicit object BSONList extends BSONType[List[_]]
+ implicit object BSONObjectId extends BSONType[ObjectId]
+ implicit object BSONBoolean extends BSONType[Boolean]
+ implicit object BSONJDKDate extends BSONType[java.util.Date]
+ implicit object BSONJodaDateTime extends BSONType[org.joda.time.DateTime]
+ implicit object BSONNull extends BSONType[Option[Nothing]]
+ implicit object BSONRegex extends BSONType[Regex]
+ implicit object BSONSymbol extends BSONType[Symbol]
+ implicit object BSON32BitInt extends BSONType[Int]
+ implicit object BSON64BitInt extends BSONType[Long]
+ implicit object BSONSQLTimestamp extends BSONType[java.sql.Timestamp]
+}
+
+/**
+ * $type operator to query by type.
+ *
+ * Can type a BSON.<enum value> or a Context Bounded check.
+ *
+ * @author Brendan W. McAdams <brendan@10gen.com>
+ * @since 2.0
+ * @see http://www.mongodb.org/display/DOCS/Advanced+Queries#AdvancedQueries-%7B%7B%24type%7D%7D
+ */
+trait LightTypeOp extends QueryOperator {
+ private val oper = "$type"
+
+ /**
+ * For those who want to pass the static byte from org.bson.BSON explicitly
+ * (or with the simple BSON spec indicator)
+ * TODO: Test for a valid byte, right now we accept anything you say.
+ */
+ def `type`(arg: Byte) = op(oper, arg)
+
+ /**
+ * Matches types based on a Context Bound.
+ * Requires anchoring to prevent compiler confusion:
+ *
+ * "foo".`type`[Double]
+ *
+ */
+ def `type`[A: BSONType: Manifest] =
+ if (manifest[A] <:< manifest[Double])
+ op(oper, BSON.NUMBER)
+ else if (manifest[A] <:< manifest[String])
+ op(oper, BSON.STRING)
+ else if (manifest[A] <:< manifest[BasicDBList] ||
+ manifest[A] <:< manifest[BasicBSONList])
+ op(oper, BSON.ARRAY)
+ else if (manifest[A] <:< manifest[BSONObject] ||
+ manifest[A] <:< manifest[DBObject])
+ op(oper, BSON.OBJECT)
+ else if (manifest[A] <:< manifest[ObjectId])
+ op(oper, BSON.OID)
+ else if (manifest[A] <:< manifest[Boolean])
+ op(oper, BSON.BOOLEAN)
+ else if (manifest[A] <:< manifest[java.sql.Timestamp])
+ op(oper, BSON.TIMESTAMP)
+ else if (manifest[A] <:< manifest[java.util.Date] ||
+ manifest[A] <:< manifest[org.joda.time.DateTime])
+ op(oper, BSON.DATE)
+ else if (manifest[A] <:< manifest[Option[Nothing]])
+ op(oper, BSON.NULL)
+ else if (manifest[A] <:< manifest[Regex])
+ op(oper, BSON.REGEX)
+ else if (manifest[A] <:< manifest[Symbol])
+ op(oper, BSON.SYMBOL)
+ else if (manifest[A] <:< manifest[Int])
+ op(oper, BSON.NUMBER_INT)
+ else if (manifest[A] <:< manifest[Long])
+ op(oper, BSON.NUMBER_LONG)
+ else if (manifest[A].erasure.isArray &&
+ manifest[A] <:< manifest[Array[Byte]])
+ op(oper, BSON.BINARY)
+ else
+ throw new IllegalArgumentException("Invalid BSON Type '%s' for matching".format(manifest.erasure))
+}
+
+trait LightGeospatialOps extends LightGeoNearOp
+ with LightGeoNearSphereOp
+ with LightGeoWithinOps
+
+/**
+ *
+ * trait to provide the $near geospatial search method on appropriate callers
+ *
+ * Note that the args aren't TECHNICALLY latitude and longitude as they depend on:
+ * a) the order you specified your actual index in
+ * b) if you're using actual world maps or something else
+ *
+ * @author Brendan W. McAdams <brendan@10gen.com>
+ * @since 2.0
+ * @see http://www.mongodb.org/display/DOCS/Geospatial+Indexing
+ */
+trait LightGeoNearOp extends QueryOperator {
+ private val oper = "$near"
+
+ def near(coords: dsl.GeoCoords[_, _]) = new NearOpWrapper(coords)
+
+ sealed class NearOpWrapper(coords: dsl.GeoCoords[_, _]) extends BasicDBObject {
+ put(field, new BasicDBObject("$near", coords.toList))
+
+ def maxDistance[T: Numeric](radius: T): DBObject = {
+ get(field).asInstanceOf[DBObject].put("$maxDistance", radius)
+ this
+ }
+
+ }
+
+}
+
+/**
+ *
+ * trait to provide the $nearSphere geospatial search method on appropriate callers
+ *
+ *
+ * Note that the args aren't TECHNICALLY latitude and longitude as they depend on:
+ * a) the order you specified your actual index in
+ * b) if you're using actual world maps or something else
+ *
+ *
+ * @author Brendan W. McAdams <brendan@10gen.com>
+ * @since 2.0
+ * @see http://www.mongodb.org/display/DOCS/Geospatial+Indexing
+ */
+trait LightGeoNearSphereOp extends QueryOperator {
+ private val oper = "$nearSphere"
+
+ def nearSphere(coords: dsl.GeoCoords[_, _]) = op(oper, coords.toList)
+}
+
+/**
+ *
+ * trait to provide the $within geospatial search method on appropriate callers
+ *
+ *
+ * Note that the args aren't TECHNICALLY latitude and longitude as they depend on:
+ * a) the order you specified your actual index in
+ * b) if you're using actual world maps or something else
+ *
+ * @author Brendan W. McAdams <brendan@10gen.com>
+ * @since 2.0
+ * @see http://www.mongodb.org/display/DOCS/Geospatial+Indexing
+ */
+trait LightGeoWithinOps extends QueryOperator {
+ self =>
+ private val oper = "$within"
+
+ def within = new QueryOperator {
+ val field = "$within"
+
+ def box(lowerLeft: dsl.GeoCoords[_, _], upperRight: dsl.GeoCoords[_, _]) =
+ MongoDBObject(
+ self.field ->
+ op("$box", MongoDBList(lowerLeft.toList, upperRight.toList)))
+
+ def center[T: Numeric](center: dsl.GeoCoords[_, _], radius: T) =
+ MongoDBObject(
+ self.field ->
+ op("$center", MongoDBList(center.toList, radius)))
+
+ def centerSphere[T: Numeric](center: dsl.GeoCoords[_, _], radius: T) =
+ MongoDBObject(
+ self.field ->
+ op("$centerSphere", MongoDBList(center.toList, radius)))
+ }
+
+}
+
View
2  casbah-query/src/test/scala/BarewordOperatorsSpec.scala
@@ -1,5 +1,5 @@
/**
- * Copyright (c) 2010 10gen, Inc. <http://10gen.com>
+ * Copyright (c) 2010, 2011 10gen, Inc. <http://10gen.com>
* Copyright (c) 2009, 2010 Novus Partners, Inc. <http://novus.com>
*
* Licensed under the Apache License, Version 2.0 (the "License");
View
5 casbah-query/src/test/scala/DSLCoreOperatorsSpec.scala
@@ -31,7 +31,7 @@ import org.scala_tools.time.Imports._
import com.mongodb.casbah.commons.test.CasbahSpecification
@SuppressWarnings(Array("deprecation"))
-class DSLCoreOperatorsSpec extends CasbahSpecification {
+class LightDSLCoreOperatorsSpec extends CasbahSpecification {
def nonDSL(key: String, oper: String, value: Any) = MongoDBObject(key -> MongoDBObject(oper -> value))
@@ -822,7 +822,7 @@ class DSLCoreOperatorsSpec extends CasbahSpecification {
}
}
"None (null)" in {
- // For some reason you can't use NONE
+ // For some reason you can't use NONE
val typeOper = "foo".$type[Option[Nothing]]
typeOper must haveEntry("foo.$type" -> org.bson.BSON.NULL)
}
@@ -996,3 +996,4 @@ class DSLCoreOperatorsSpec extends CasbahSpecification {
}
}
// vim: set ts=2 sw=2 sts=2 et:
+
View
265 casbah-query/src/test/scala/light/LightBarewordOperatorsSpec.scala
@@ -0,0 +1,265 @@
+/**
+ * Copyright (c) 2010, 2011 10gen, Inc. <http://10gen.com>
+ * Copyright (c) 2009, 2010 Novus Partners, Inc. <http://novus.com>
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * For questions and comments about this product, please see the project page at:
+ *
+ * http://github.com/mongodb/casbah
+ *
+ */
+package com.mongodb.casbah.test.query.light
+
+import com.mongodb.casbah.query.light._
+import com.mongodb.casbah.commons.test.CasbahSpecification
+
+// TODO - Operational/Integration testing with this code
+@SuppressWarnings(Array("deprecation"))
+class LightBarewordOperatorsSpec extends CasbahSpecification {
+ "Casbah's DSL set Operator" should {
+ "Accept one or many pairs of values" in {
+ "A single pair" in {
+ val setVal = set("foo" -> "bar")
+ setVal must haveEntry("$set.foo" -> "bar")
+ }
+ "Multiple pairs" in {
+ val setVal = set("foo" -> "bar", "x" -> 5.2, "y" -> 9, "a" -> ("b", "c", "d", "e"))
+ setVal must haveEntry("$set.foo" -> "bar")
+ setVal must haveEntry("$set.x" -> 5.2)
+ setVal must haveEntry("$set.y" -> 9)
+ setVal must haveEntry("$set.a" -> ("b", "c", "d", "e"))
+ }
+ }
+ }
+
+ "Casbah's DSL unset Operator" should {
+ "Accept one or many values" in {
+ "A single item" in {
+ val _unset = unset("foo")
+ _unset must haveEntry("$unset.foo" -> 1)
+ }
+ "Multiple items" in {
+ val _unset = unset("foo", "bar", "x", "y")
+ _unset must haveEntry("$unset.foo" -> 1)
+ _unset must haveEntry("$unset.bar" -> 1)
+ _unset must haveEntry("$unset.x" -> 1)
+ _unset must haveEntry("$unset.y" -> 1)
+ }
+ }
+ }
+
+ "Casbah's DSL inc Operator" should {
+ "Accept one or many sets of values" in {
+ "A single set" in {
+ val _inc = inc("foo" -> 5.0)
+ _inc must haveEntry("$inc.foo" -> 5.0)
+ }
+ "Multiple sets" in {
+ val _inc = inc("foo" -> 5.0, "bar" -> -1.2)
+ _inc must haveEntry("$inc.foo" -> 5.0)
+ _inc must haveEntry("$inc.bar" -> -1.2)
+ }
+ }
+ }
+
+ "Casbah's DSL or Operator" >> {
+ "Accept multiple values" in {
+ val _or = or ( "foo" -> "bar", "x" -> "y" )
+ _or must haveListEntry("$or", Seq(MongoDBObject("foo" -> "bar"), MongoDBObject("x" -> "y")))
+ }
+ "Accept a mix" in {
+ val _or = or { "foo" -> "bar" :: ("foo" gt 5 lt 10) }
+ _or must haveListEntry("$or", Seq(MongoDBObject("foo" -> "bar"), MongoDBObject("foo" -> MongoDBObject("$gt" -> 5, "$lt" -> 10))))
+ }
+ "Work with nested operators" in {
+ "As a simple list (comma separated)" in {
+ val _or = or( "foo" lt 5 gt 1, "x" gte 10 lte 152 )
+ _or must haveListEntry("$or", Seq(MongoDBObject("foo" -> MongoDBObject("$lt" -> 5, "$gt" -> 1)),
+ MongoDBObject("x" -> MongoDBObject("$gte" -> 10, "$lte" -> 152))))
+ }
+ "As a cons (:: constructed) cell" in {
+ val _or = or( ("foo" lt 5 gt 1) :: ("x" gte 10 lte 152) )
+ _or must haveListEntry("$or", Seq(MongoDBObject("foo" -> MongoDBObject("$lt" -> 5, "$gt" -> 1)),
+ MongoDBObject("x" -> MongoDBObject("$gte" -> 10, "$lte" -> 152))))
+ }
+ }
+ }
+
+ "Casbah's DSL and Operatand" >> {
+ "Accept multiple values" in {
+ val _and = and ( "foo" -> "bar", "x" -> "y" )
+ _and must haveListEntry("$and", Seq(MongoDBObject("foo" -> "bar"), MongoDBObject("x" -> "y")))
+ }
+ "Accept a mix" in {
+ val _and = and { "foo" -> "bar" :: ("foo" gt 5 lt 10) }
+ _and must haveListEntry("$and", Seq(MongoDBObject("foo" -> "bar"), MongoDBObject("foo" -> MongoDBObject("$gt" -> 5, "$lt" -> 10))))
+ }
+ "Work with nested operators" in {
+ "As a simple list (comma separated)" in {
+ val _and = and( "foo" lt 5 gt 1, "x" gte 10 lte 152 )
+ _and must haveListEntry("$and", Seq(MongoDBObject("foo" -> MongoDBObject("$lt" -> 5, "$gt" -> 1)),
+ MongoDBObject("x" -> MongoDBObject("$gte" -> 10, "$lte" -> 152))))
+ }
+ "As a cons (:: constructed) cell" in {
+ val _and = and( ("foo" lt 5 gt 1) :: ("x" gte 10 lte 152) )
+ _and must haveListEntry("$and", Seq(MongoDBObject("foo" -> MongoDBObject("$lt" -> 5, "$gt" -> 1)),
+ MongoDBObject("x" -> MongoDBObject("$gte" -> 10, "$lte" -> 152))))
+ }
+ }
+ }
+
+ "Casbah's DSL rename Operator" should {
+ "Accept one or many sets of renames" in {
+ "A single set" in {
+ val _rename = rename("foo" -> "bar")
+ _rename must haveEntry("$rename.foo" -> "bar")
+ }
+ "Multiple sets" in {
+ val _rename = rename("foo" -> "bar", "x" -> "y")
+ _rename must haveEntry("$rename.foo" -> "bar")
+ _rename must haveEntry("$rename.x" -> "y")
+ }
+ }
+ }
+
+ "Casbah's DSL Array operators" should {
+ "push" in {
+ "Accept a single value" in {
+ val _push = push("foo" -> "bar")
+ _push must haveEntry("$push.foo" -> "bar")
+ }
+ "Accept multiple values" in {
+ val _push = push("foo" -> "bar", "x" -> 5.2)
+ _push must haveEntry("$push.foo" -> "bar")
+ _push must haveEntry("$push.x" -> 5.2)
+ }
+ }
+ "pushAll" in {
+ "Accept a single value list" in {
+ val _push = pushAll("foo" -> ("bar", "baz", "x", "y"))
+ _push must haveListEntry("$pushAll.foo", List("bar", "baz", "x", "y"))
+ }
+ "Not allow a non-list value" in {
+ (pushAll("foo" -> "bar")) must throwA[IllegalArgumentException]
+ }
+ "Accept multiple value lists" in {
+ val _push = pushAll("foo" -> ("bar", "baz", "x", "y"), "n" -> (5, 10, 12, 238))
+ _push must haveListEntry("$pushAll.foo", List("bar", "baz", "x", "y"))
+ _push must haveListEntry("$pushAll.n", List(5, 10, 12, 238))
+ }
+ }
+ "addToSet" in {
+ "Accept a single value" in {
+ val _addToSet = addToSet("foo" -> "bar")
+ _addToSet must haveEntry("$addToSet.foo" -> "bar")
+ }
+ "Accept multiple values" in {
+ val _addToSet = addToSet("foo" -> "bar", "x" -> 5.2)
+ _addToSet must haveEntry("$addToSet.foo" -> "bar")
+ _addToSet must haveEntry("$addToSet.x" -> 5.2)
+ }
+ "Function with the each operator for multi-value updates" in {
+ val _addToSet = addToSet("foo") each ("x", "y", "foo", "bar", "baz")
+ _addToSet must haveListEntry("$addToSet.foo.each", Seq("x", "y", "foo", "bar", "baz"))
+ }
+ }
+ "bit" in {
+ "Accept a single value" in {
+ "For 'and'" in {
+ val _bit = bit("foo") and 5
+ _bit must haveEntry("$bit.foo.and" -> 5)
+ }
+ "For 'or'" in {
+ val _bit = bit("foo") or 5
+ _bit must haveEntry("$bit.foo.or" -> 5)
+ }
+ }
+ }
+ "pop" in {
+ "Accept a single value" in {
+ val _pop = pop("foo" -> 1)
+ _pop must haveEntry("$pop.foo" -> 1)
+ }
+ "Accept multiple values" in {
+ val _pop = pop("foo" -> 1, "x" -> -1)
+ _pop must haveEntry("$pop.foo" -> 1)
+ _pop must haveEntry("$pop.x" -> -1)
+ }
+ }
+ "pull" in {
+ "Accept a single value" in {
+ val _pull = pull("foo" -> "bar")
+ _pull must haveEntry("$pull.foo" -> "bar")
+ }
+ "Allow Value Test Operators" in {
+ "A simple gt test" in {
+ // Syntax oddity due to compiler confusion
+ val _pull = pull { "foo" gt 5 }
+ _pull must haveEntry("$pull.foo.gt" -> 5)
+ }
+ "A deeper chain test" in {
+ // Syntax oddity due to compiler confusion
+ val _pull = pull { "foo" gt 5 lte 52 }
+ _pull must haveEntry("$pull.foo.gt" -> 5)
+ _pull must haveEntry("$pull.foo.lte" -> 52)
+ }
+ }
+ "Accept multiple values" in {
+ val _pull = pull("foo" -> "bar", "x" -> 5.2)
+ _pull must haveEntry("$pull.foo" -> "bar")
+ _pull must haveEntry("$pull.x" -> 5.2)
+ }
+ }
+ "pullAll" in {
+ "Accept a single value list" in {
+ val _pull = pullAll("foo" -> ("bar", "baz", "x", "y"))
+ _pull must haveEntry("$pullAll.foo" -> Seq("bar", "baz", "x", "y"))
+ }
+ "Not allow a non-list value" in {
+ (pullAll("foo" -> "bar")) must throwA[IllegalArgumentException]
+ }
+ "Accept multiple value lists" in {
+ val _pull = pullAll("foo" -> ("bar", "baz", "x", "y"), "n" -> (5, 10, 12, 238))
+ _pull must haveEntry("$pullAll.foo" -> Seq("bar", "baz", "x", "y"))
+ _pull must haveEntry("$pullAll.n" -> Seq(5, 10, 12, 238))
+ }
+ }
+
+ }
+
+ "Casbah's DSL nor operator" >> {
+ "Accept multiple values" in {
+ val _nor = nor ( "foo" -> "bar", "x" -> "y" )
+ _nor must haveListEntry("$nor", Seq(MongoDBObject("foo" -> "bar"), MongoDBObject("x" -> "y")))
+ }
+ "Accept a mix" in {
+ val _nor = nor { "foo" -> "bar" :: ("foo" gt 5 lt 10) }
+ _nor must haveListEntry("$nor", Seq(MongoDBObject("foo" -> "bar"), MongoDBObject("foo" -> MongoDBObject("$gt" -> 5, "$lt" -> 10))))
+ }
+ "Work with nested operators" in {
+ "As a simple list (comma separated)" in {
+ val _nor = nor( "foo" lt 5 gt 1, "x" gte 10 lte 152 )
+ _nor must haveListEntry("$nor", Seq(MongoDBObject("foo" -> MongoDBObject("$lt" -> 5, "$gt" -> 1)),
+ MongoDBObject("x" -> MongoDBObject("$gte" -> 10, "$lte" -> 152))))
+ }
+ "As a cons (:: constructed) cell" in {
+ val _nor = nor( ("foo" lt 5 gt 1) :: ("x" gte 10 lte 152) )
+ _nor must haveListEntry("$nor", Seq(MongoDBObject("foo" -> MongoDBObject("$lt" -> 5, "$gt" -> 1)),
+ MongoDBObject("x" -> MongoDBObject("$$gte" -> 10, "$lte" -> 152))))
+ }
+ }
+ }
+}
+
+// vim: set ts=2 sw=2 sts=2 et:
View
997 casbah-query/src/test/scala/light/LightDSLCoreOperatorsSpec.scala
@@ -0,0 +1,997 @@
+/**
+ * Copyright (c) 2010 10gen, Inc. <http://10gen.com>
+ * Copyright (c) 2009, 2010 Novus Partners, Inc. <http://novus.com>
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * For questions and comments about this product, please see the project page at:
+ *
+ * http://github.com/mongodb/casbah
+ *
+ */
+
+ package com.mongodb.casbah.test.query.light
+ import com.mongodb.casbah.commons.conversions.scala._
+ import com.mongodb.casbah.query.light._
+
+
+ import com.mongodb.casbah.commons.test.CasbahSpecification
+
+ @SuppressWarnings(Array("deprecation"))
+ class DSLCoreOperatorsSpec extends CasbahSpecification {
+
+ def nonDSL(key: String, oper: String, value: Any) = MongoDBObject(key -> MongoDBObject(oper -> value))
+
+ "Casbah's DSL ne operator" should {
+ DeregisterJodaTimeConversionHelpers()
+
+ val testDate = new java.util.Date(109, 01, 02, 0, 0, 0)
+
+ "Accept a right hand value of String" in {
+ val neStr = "foo" ne "ISBN-123456789"
+ neStr must haveEntry("foo.$ne" -> "ISBN-123456789")
+ }
+
+ "Accept a right hand value of DBObject" in {
+ "A BasicDBObject created value" in {
+ val neObj = "foo" ne new BasicDBObject("bar", "baz")
+ neObj must haveEntry("foo.$ne" -> new BasicDBObject("bar", "baz"))
+ }
+ "A MongoDBObject created value" in {
+ val neObj = "foo" ne MongoDBObject("bar" -> "baz")
+ neObj must haveEntry("foo.$ne" -> MongoDBObject("bar" -> "baz"))
+ }
+ "A DBList should work also" in {
+ val neLst = "foo" ne MongoDBList("x", "y", "z")
+ neLst must haveEntry("foo.$ne" -> MongoDBList("x", "y", "z"))
+
+ }
+ }
+
+ "Accept List-like values descended from Iterable" in {
+ "An immutable List works" in {
+ import scala.collection.immutable.List
+ val neLst = "foo" ne List("x", "y", 5)
+ neLst must haveEntry("foo.$ne" -> List("x", "y", 5))
+ }
+
+ "An immutable Seq works" in {
+ import scala.collection.immutable.Seq
+ val neSeq = "foo" ne Seq("x", "y", 5)
+ neSeq must haveEntry("foo.$ne" -> Seq("x", "y", 5))
+ }
+
+ "An immutable Set works" in {
+ import scala.collection.immutable.Set
+ val neSet = "foo" ne Set("x", "y", 5)
+ neSet must haveListEntry("foo.$ne", Set("x", "y", 5))
+ }
+
+ "An mutable HashSet works" in {
+ import scala.collection.mutable.HashSet
+ val neHashSet = "foo" ne HashSet("x", "y", 5)
+ neHashSet must haveListEntry("foo.$ne", HashSet("x", "y", 5))
+ }
+
+ "Also, Arrays function" in {
+ val neArray = "foo" ne Array("x", "y", 5)
+ neArray must haveListEntry("foo.$ne", Array("x", "y", 5))
+ }
+ }
+
+ "Accept a right hand value of ValidDateOrNumericType" in {
+ "with Int" in {
+ val neInt = "foo" ne 10
+ neInt must haveEntry("foo.$ne" -> 10)
+ }
+ "with BigDecimal" in {
+ val neBD = "foo" ne BigDecimal("5.8233232")
+ neBD must haveEntry("foo.$ne" -> BigDecimal("5.8233232"))
+ }
+ "with BigInt" in {
+ val neBI = "foo" ne BigInt("1000000000000000000425425245252")
+ neBI must haveEntry("foo.$ne" -> BigInt("1000000000000000000425425245252"))
+ }
+ "with Byte" in {
+ val neByte = "foo" ne java.lang.Byte.parseByte("51")
+ neByte must haveEntry("foo.$ne" -> java.lang.Byte.parseByte("51"))
+ }
+ "with Double" in {
+ val neDouble = "foo" ne 5.232352
+ neDouble must haveEntry("foo.$ne" -> 5.232352)
+ }
+ "with Float" in {
+ val neFloat = "foo" ne java.lang.Float.parseFloat("5.232352")
+ neFloat must haveEntry("foo.$ne" -> java.lang.Float.parseFloat("5.232352"))
+ }
+ "with Long" in {
+ val neLong = "foo" ne 10L
+ neLong must haveEntry("foo.$ne" -> 10L)
+ }
+ "with Short" in {
+ val neShort = "foo" ne java.lang.Short.parseShort("10")
+ neShort must haveEntry("foo.$ne" -> java.lang.Short.parseShort("10"))
+ }
+ "with JDKDate" in {
+ val neJDKDate = "foo" ne testDate
+ neJDKDate must haveEntry("foo.$ne", testDate)
+ }
+ "with JodaDT" in {
+ RegisterJodaTimeConversionHelpers()
+ val neJodaDT = "foo" ne new org.joda.time.DateTime(testDate.getTime)
+ neJodaDT must haveEntry("foo.$ne" -> new org.joda.time.DateTime(testDate.getTime))
+ }
+ }
+ }
+
+ "Casbah's DSL lt operator" should {
+ DeregisterJodaTimeConversionHelpers()
+
+ val testDate = new java.util.Date(109, 01, 02, 0, 0, 0)
+
+ "Accept a right hand value of String" in {
+ val neStr = "foo" lt "ISBN-123456789"
+ neStr must haveEntry("foo.$lt" -> "ISBN-123456789")
+ }
+
+ "Accept a right hand value of DBObject" in {
+ "A BasicDBObject created value" in {
+ val neObj = "foo" lt new BasicDBObject("bar", "baz")
+ neObj must haveEntry("foo.$lt" -> new BasicDBObject("bar", "baz"))
+ }
+ "A MongoDBObject created value" in {
+ val neObj = "foo" lt MongoDBObject("bar" -> "baz")
+ neObj must haveEntry("foo.$lt" -> MongoDBObject("bar" -> "baz"))
+ }
+ "A DBList should work also" in {
+ val neLst = "foo" lt MongoDBList("x", "y", "z")
+ neLst must haveEntry("foo.$lt" -> MongoDBList("x", "y", "z"))
+
+ }
+ }
+
+ "Accept List-like values descended from Iterable" in {
+ "An immutable List works" in {
+ import scala.collection.immutable.List
+ val neLst = "foo" lt List("x", "y", 5)
+ neLst must haveEntry("foo.$lt" -> List("x", "y", 5))
+ }
+
+ "An immutable Seq works" in {
+ import scala.collection.immutable.Seq
+ val neSeq = "foo" lt Seq("x", "y", 5)
+ neSeq must haveEntry("foo.$lt" -> Seq("x", "y", 5))
+ }
+
+ "An immutable Set works" in {
+ import scala.collection.immutable.Set
+ val neSet = "foo" lt Set("x", "y", 5)
+ neSet must haveListEntry("foo.$lt", List("x", "y", 5))
+ }
+
+ "An mutable HashSet works" in {
+ import scala.collection.mutable.HashSet
+ val neHashSet = "foo" lt HashSet("x", "y", 5)
+ neHashSet must haveListEntry("foo.$lt", HashSet("x", "y", 5)) // TODO - This *MUST* Be able to match regardless of inner type!!!!
+ }
+
+ "Also, Arrays function" in {
+ val neArray = "foo" lt Array("x", "y", 5)
+ neArray must haveListEntry("foo.$lt", Array("x", "y", 5))
+ }
+ }
+
+ "Accept a right hand value of ValidDateOrNumericType" in {
+ "with Int" in {
+ val neInt = "foo" lt 10
+ neInt must haveEntry("foo.$lt" -> 10)
+ }
+ "with BigDecimal" in {
+ val neBD = "foo" lt BigDecimal("5.8233232")
+ neBD must haveEntry("foo.$lt" -> BigDecimal("5.8233232"))
+ }
+ "with BigInt" in {
+ val neBI = "foo" lt BigInt("1000000000000000000425425245252")
+ neBI must haveEntry("foo.$lt" -> BigInt("1000000000000000000425425245252"))
+ }
+ "with Byte" in {
+ val neByte = "foo" lt java.lang.Byte.parseByte("51")
+ neByte must haveEntry("foo.$lt" -> java.lang.Byte.parseByte("51"))
+ }
+ "with Double" in {
+ val neDouble = "foo" lt 5.232352
+ neDouble must haveEntry("foo.$lt" -> 5.232352)
+ }
+ "with Float" in {
+ val neFloat = "foo" lt java.lang.Float.parseFloat("5.232352")
+ neFloat must haveEntry("foo.$lt" -> java.lang.Float.parseFloat("5.232352"))
+ }
+ "with Long" in {
+ val neLong = "foo" lt 10L
+ neLong must haveEntry("foo.$lt" -> 10L)
+ }
+ "with Short" in {
+ val neShort = "foo" lt java.lang.Short.parseShort("10")
+ neShort must haveEntry("foo.$lt" -> java.lang.Short.parseShort("10"))
+ }
+ "with JDKDate" in {
+ val neJDKDate = "foo" lt testDate
+ neJDKDate must haveEntry("foo.$lt" -> testDate)
+ }
+ "with JodaDT" in {
+ RegisterJodaTimeConversionHelpers()
+ val neJodaDT = "foo" lt new org.joda.time.DateTime(testDate.getTime)
+ neJodaDT must haveEntry("foo.$lt" -> new org.joda.time.DateTime(testDate.getTime))
+ }
+
+ }
+ }
+
+ "Casbah's DSL lte operator" should {
+ DeregisterJodaTimeConversionHelpers()
+
+ val testDate = new java.util.Date(109, 01, 02, 0, 0, 0)
+
+ "Accept a right hand value of String" in {
+ val neStr = "foo" lte "ISBN-123456789"
+ neStr must haveEntry("foo.$lte" -> "ISBN-123456789")
+ }
+
+ "Accept a right hand value of DBObject" in {
+ "A BasicDBObject created value" in {
+ val neObj = "foo" lte new BasicDBObject("bar", "baz")
+ neObj must haveEntry("foo.$lte" -> new BasicDBObject("bar", "baz"))
+ }
+ "A MongoDBObject created value" in {
+ val neObj = "foo" lte MongoDBObject("bar" -> "baz")
+ neObj must haveEntry("foo.$lte" -> MongoDBObject("bar" -> "baz"))
+ }
+ "A DBList should work also" in {
+ val neLst = "foo" lte MongoDBList("x", "y", "z")
+ neLst must haveEntry("foo.$lte" -> MongoDBList("x", "y", "z"))
+
+ }
+ }
+
+ "Accept List-like values descended from Iterable" in {
+ "An immutable List works" in {
+ import scala.collection.immutable.List
+ val neLst = "foo" lte List("x", "y", 5)
+ neLst must haveEntry("foo.$lte" -> List("x", "y", 5))
+ }
+
+ "An immutable Seq works" in {
+ import scala.collection.immutable.Seq
+ val neSeq = "foo" lte Seq("x", "y", 5)
+ neSeq must haveEntry("foo.$lte" -> Seq("x", "y", 5))
+ }
+
+ "An immutable Set works" in {
+ import scala.collection.immutable.Set
+ val neSet = "foo" lte Set("x", "y", 5)
+ neSet must haveListEntry("foo.$lte", List("x", "y", 5))
+ }
+
+ "An mutable HashSet works" in {
+ import scala.collection.mutable.HashSet
+ val neHashSet = "foo" lte HashSet("x", "y", 5)
+ neHashSet must haveListEntry("foo.$lte", HashSet("x", "y", 5))
+ }
+
+ "Also, Arrays function" in {
+ val neArray = "foo" lte Array("x", "y", 5)
+ neArray must haveListEntry("foo.$lte", Array("x", "y", 5))
+ }
+ }
+
+ "Accept a right hand value of ValidDateOrNumericType" in {
+ "with Int" in {
+ val neInt = "foo" lte 10
+ neInt must haveEntry("foo.$lte" -> 10)
+ }
+ "with BigDecimal" in {
+ val neBD = "foo" lte BigDecimal("5.8233232")
+ neBD must haveEntry("foo.$lte" -> BigDecimal("5.8233232"))
+ }
+ "with BigInt" in {
+ val neBI = "foo" lte BigInt("1000000000000000000425425245252")
+ neBI must haveEntry("foo.$lte" -> BigInt("1000000000000000000425425245252"))
+ }
+ "with Byte" in {
+ val neByte = "foo" lte java.lang.Byte.parseByte("51")
+ neByte must haveEntry("foo.$lte" -> java.lang.Byte.parseByte("51"))
+ }
+ "with Double" in {
+ val neDouble = "foo" lte 5.232352
+ neDouble must haveEntry("foo.$lte" -> 5.232352)
+ }
+ "with Float" in {
+ val neFloat = "foo" lte java.lang.Float.parseFloat("5.232352")
+ neFloat must haveEntry("foo.$lte" -> java.lang.Float.parseFloat("5.232352"))
+ }
+ "with Long" in {
+ val neLong = "foo" lte 10L
+ neLong must haveEntry("foo.$lte" -> 10L)
+ }
+ "with Short" in {
+ val neShort = "foo" lte java.lang.Short.parseShort("10")
+ neShort must haveEntry("foo.$lte" -> java.lang.Short.parseShort("10"))
+ }
+ "with JDKDate" in {
+ val neJDKDate = "foo" lte testDate
+ neJDKDate must haveEntry("foo.$lte" -> testDate)
+ }
+ "with JodaDT" in {
+ RegisterJodaTimeConversionHelpers()
+ val neJodaDT = "foo" lte new org.joda.time.DateTime(testDate.getTime)
+ neJodaDT must haveEntry("foo.$lte" -> new org.joda.time.DateTime(testDate.getTime))
+ }
+
+ }
+ }
+
+ "Casbah's DSL gt operator" should {
+ DeregisterJodaTimeConversionHelpers()
+
+ val testDate = new java.util.Date(109, 01, 02, 0, 0, 0)
+
+ "Accept a right hand value of String" in {
+ val neStr = "foo" gt "ISBN-123456789"
+ neStr must haveEntry("foo.$gt" -> "ISBN-123456789")
+ }
+
+ "Accept a right hand value of DBObject" in {
+ "A BasicDBObject created value" in {
+ val neObj = "foo" gt new BasicDBObject("bar", "baz")
+ neObj must haveEntry("foo.$gt" -> new BasicDBObject("bar", "baz"))
+ }
+ "A MongoDBObject created value" in {
+ val neObj = "foo" gt MongoDBObject("bar" -> "baz")
+ neObj must haveEntry("foo.$gt" -> MongoDBObject("bar" -> "baz"))
+ }
+ "A DBList should work also" in {
+ val neLst = "foo" gt MongoDBList("x", "y", "z")
+ neLst must haveListEntry("foo.$gt", MongoDBList("x", "y", "z"))
+
+ }
+ }
+
+ "Accept List-like values descended from Iterable" in {
+ "An immutable List works" in {
+ import scala.collection.immutable.List
+ val neLst = "foo" gt List("x", "y", 5)
+ neLst must haveListEntry("foo.$gt", List("x", "y", 5))
+ }
+
+ "An immutable Seq works" in {
+ import scala.collection.immutable.Seq
+ val neSeq = "foo" gt Seq("x", "y", 5)
+ neSeq must haveListEntry("foo.$gt", Seq("x", "y", 5))
+ }
+
+ "An immutable Set works" in {
+ import scala.collection.immutable.Set
+ val neSet = "fo