Skip to content

Instantly share code, notes, and snippets.

@etorreborre
Created May 29, 2011 03:03
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save etorreborre/997433 to your computer and use it in GitHub Desktop.
Save etorreborre/997433 to your computer and use it in GitHub Desktop.
Using implicit contexts to remove duplication
/**
* You can compare this Specification with:
* https://github.com/etorreborre/hammersmith/blob/master/mongo-driver/src/test/scala/DirectConnectionSpec.scala
*
* Note that:
* * connectIsMaster returns a function (not a method anymore)
* * distinctValue returns 'ok' (a MatchResult) instead of 'success' (a Result)
*/
class DirectConnectionSpec extends Specification with Logging { def is =
"The MongoDB Direct Connection" ^
"Connect correctly and grab isMaster, then disconnect" ! connectIsMaster^
"Iterate a simple cursor correctly" ! iterateSimpleCursor^
"Iterate a complex (iteratee) cursor correctly" ! iterateComplexCursor^
"Correctly calculate values for 'distinct'" ! distinctValue^
p^
"The write behavior" ^
"Support 'blind' (NoOp) writes" ! noopInsert^
"Support inserts with no (default) write concern" ! insertWithDefaultWriteConcern^
"Support inserts with implicit safe write concern" ! insertWithSafeImplicitWriteConcern^
end
implicit object mongo extends mongoConn
trait mongoConn extends AroundOutside[MongoConnection] {
var conn = MongoConnection()
def around[T <% Result](t: =>T) = {
conn.connected_? must eventually(beTrue)
t
/*conn.close()
conn.connected_? must eventually(beFalse)*/
}
def outside: MongoConnection = { conn = MongoConnection()
conn }
}
def connectIsMaster = (conn: MongoConnection) => {
conn.databaseNames({ dbs: Seq[String] => dbs.foreach(log.trace("DB: %s", _)) })
conn("test").collectionNames({ colls: Seq[String] => colls.foreach(log.trace("Collection: %s", _)) })
conn.connected_? must eventually(beTrue)
}
// todo - this relies heavily on whats on my local workstation; needs to be generic
def iterateSimpleCursor = (conn: MongoConnection) => {
var x = 0
conn("bookstore").find("inventory")(Document.empty, Document.empty)((cursor: Cursor) => {
for (doc <- cursor) {
x += 1
}
})
x must eventually (be_==(336))
}
def iterateComplexCursor = (conn: MongoConnection) => {
var x = 0
conn("bookstore").find("inventory")(Document.empty, Document.empty)((cursor: Cursor) => {
def next(op: Cursor.IterState): Cursor.IterCmd = op match {
case Cursor.Entry(doc) => {
x += 1
if (x < 100) Cursor.Next(next) else Cursor.Done
}
case Cursor.Empty => {
if (x < 100) Cursor.NextBatch(next) else Cursor.Done
}
case Cursor.EOF => {
Cursor.Done
}
}
Cursor.iterate(cursor)(next)
})
x must eventually(5, 5.seconds) (be_==(100))
}
def distinctValue = (conn: MongoConnection) => {
conn("bookstore")("inventory").distinct("author")((values: Seq[Any]) => {
for (item <- values) {
log.trace("Got a value: %s", item.asInstanceOf[String])
}
})
ok
}
def noopInsert = (conn: MongoConnection) => {
val mongo = conn("testHammersmith")("test_insert")
mongo.dropCollection()(success => {
log.info("Dropped collection... Success? " + success)
})
mongo.insert(Document("foo" -> "bar", "bar" -> "baz")){}
// TODO - Implement 'count'
var doc: BSONDocument = null
mongo.findOne(Document("foo" -> "bar"))((_doc: BSONDocument) => {
doc = _doc
})
doc must not (beNull.eventually)
doc must eventually (havePairs("foo" -> "bar", "bar" -> "baz"))
}
def insertWithDefaultWriteConcern = (conn: MongoConnection) => {
val mongo = conn("testHammersmith")("test_insert")
mongo.dropCollection()(success => {
log.info("Dropped collection... Success? " + success)
})
var id: AnyRef = null
mongo.insert(Document("foo" -> "bar", "bar" -> "baz"))((oid: Option[AnyRef], res: WriteResult) => {
id = oid.getOrElse(null)
})
// TODO - Implement 'count'
var doc: BSONDocument = null
mongo.findOne(Document("foo" -> "bar"))((_doc: BSONDocument) => {
doc = _doc
})
doc must not (beNull.eventually)
doc must eventually (havePairs("foo" -> "bar", "bar" -> "baz"))
}
def insertWithSafeImplicitWriteConcern = (conn: MongoConnection) => {
val mongo = conn("testHammersmith")("test_insert")
implicit val safeWrite = WriteConcern.Safe
mongo.dropCollection()(success => {
log.info("Dropped collection... Success? " + success)
})
var id: Option[AnyRef] = null
var ok: Option[Boolean] = None
val handler = RequestFutures.write((result: Either[Throwable, (Option[AnyRef], WriteResult)]) => {
result match {
case Right((oid, wr)) => {
ok = Some(true)
id = oid }
case Left(t) => {
ok = Some(false)
log.error(t, "Command Failed.")
}
}
})
mongo.insert(Document("foo" -> "bar", "bar" -> "baz"))(handler)
ok must eventually { beSome(true) }
id must not (beNull.eventually)
// TODO - Implement 'count'
var doc: BSONDocument = null
mongo.findOne(Document("foo" -> "bar"))((_doc: BSONDocument) => {
doc = _doc
})
doc must not (beNull.eventually)
doc must eventually (havePairs("foo" -> "bar", "bar" -> "baz"))
}
/* "Support findAndModify" in {
val mongo = conn("testHammersmith")("test_findModify")
mongo.insert(Document("x" -> 1), Document("x" -> 2), Document("x" -> 3))
}*/
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment