Skip to content

Commit

Permalink
Merge pull request lift#1552 from lift/tcn_issue_1498_2
Browse files Browse the repository at this point in the history
Issue lift#1498 - Mongo -> MongoClient Transition

Deprecates old constructors that interact with Mongo and Lift's abstractions
over it and adds versions that deal with MongoClient.

Also deals with WriteConcern differences in MongoClient vs Mongo, and adds
a couple of new convenience methods to MongoRecord.
  • Loading branch information
Shadowfiend committed May 2, 2014
2 parents dae2255 + d6a9581 commit 5a8f5cf
Show file tree
Hide file tree
Showing 19 changed files with 508 additions and 196 deletions.
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright 2010-2012 WorldWide Conferencing, LLC
* Copyright 2010-2014 WorldWide Conferencing, LLC
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
Expand Down Expand Up @@ -243,6 +243,15 @@ trait MongoMetaRecord[BaseRecord <: MongoRecord[BaseRecord]]
inst.allFields.foreach { _.resetDirty }
}

/**
* Save the instance in the appropriate backing store. Uses the WriteConcern set on the MongoClient instance.
*/
def save(inst: BaseRecord): Boolean = saveOp(inst) {
useColl { coll =>
coll.save(inst.asDBObject)
}
}

/**
* Save the instance in the appropriate backing store
*/
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright 2010-2011 WorldWide Conferencing, LLC
* Copyright 2010-2014 WorldWide Conferencing, LLC
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
Expand All @@ -19,6 +19,7 @@ package mongodb
package record

import net.liftweb.record.{MetaRecord, Record}
import net.liftweb.util.Helpers.tryo

import com.mongodb.{BasicDBObject, DBObject, DBRef, WriteConcern}

Expand Down Expand Up @@ -52,27 +53,37 @@ trait MongoRecord[MyType <: MongoRecord[MyType]] extends BsonRecord[MyType] {
this
}


/**
* Save the instance and return the instance
*/
override def saveTheRecord(): Box[MyType] = {save; Full(this)}
override def saveTheRecord(): Box[MyType] = saveBox()

/**
* Save the instance and return the instance
* @param safe - if true will use WriteConcern SAFE else NORMAL
* @param safe - if true will use WriteConcern ACKNOWLEDGED else UNACKNOWLEDGED
*/
def save(safe: Boolean): MyType = {
save(if (safe) WriteConcern.SAFE else WriteConcern.NORMAL)
def save(safe: Boolean = true): MyType = {
save(if (safe) WriteConcern.ACKNOWLEDGED else WriteConcern.UNACKNOWLEDGED)
}

/**
* Save the instance and return the instance
* WILL NOT RAISE MONGO SERVER ERRORS.
* Use save(Boolean) or save(WriteConcern) to control error behavior
*/
@deprecated("save with no argument list is deprecated and will go away in Lift 3; it defaults to an unsafe WriteConcern. Please call save(false) for this behavior. Calling save() or save(true) will set the WriteConcern to ACKNOWLEDGED, which is in line with default MongoClient behavior.", "2.6")
def save: MyType = save(false)

/**
* Try to save the instance and return the instance in a Box.
*/
def saveBox(): Box[MyType] = tryo {
runSafe {
meta.save(this)
}
this
}

/**
* Update only the dirty fields
*/
Expand All @@ -84,13 +95,32 @@ trait MongoRecord[MyType <: MongoRecord[MyType]] extends BsonRecord[MyType] {
}

/**
* Delete the instance from backing store
*/
* Try to update only the dirty fields
*/
def updateBox: Box[MyType] = tryo {
runSafe {
meta.update(this)
}
this
}

/**
* Delete the instance from backing store
*/
def delete_! : Boolean = {
runSafe {
meta.delete_!(this)
}
}

/**
* Try to delete the instance from backing store
*/
def deleteBox_! : Box[Boolean] = tryo {
runSafe {
meta.delete_!(this)
}
}
}

/**
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright 2010-2013 WorldWide Conferencing, LLC
* Copyright 2010-2014 WorldWide Conferencing, LLC
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
Expand Down Expand Up @@ -174,7 +174,7 @@ object CustomSerializersSpec extends Specification with MongoTestKit {
val mother = Person.createRecord
mother.children(List(jack, jill))
mother.firstBorn(jack)
mother.save
mother.save()

// retrieve it and compare
val mother2 = Person.find(mother.id.get)
Expand Down Expand Up @@ -229,7 +229,7 @@ object CustomSerializersSpec extends Specification with MongoTestKit {
val mother = Person2.createRecord
mother.children(List(jack, jill))
mother.firstBorn(jack)
mother.save
mother.save()

// retrieve it and compare
val mother2 = Person2.find(mother.id.get)
Expand Down Expand Up @@ -276,8 +276,8 @@ object CustomSerializersSpec extends Specification with MongoTestKit {
checkMongoIsRunning

// test data
val rmoss = Player.createRecord.name("Randy Moss").save
val bfavre = Player.createRecord.name("Brett Favre").save
val rmoss = Player.createRecord.name("Randy Moss").save()
val bfavre = Player.createRecord.name("Brett Favre").save()
val vikes = Team(ObjectId.get.toString, "Vikings", bfavre.id.toString)
val jets = Team(ObjectId.get.toString, "Jets", "")
val saints = Team(ObjectId.get.toString, "Saints", "")
Expand All @@ -286,7 +286,7 @@ object CustomSerializersSpec extends Specification with MongoTestKit {
val nfl = League.createRecord
nfl.teams(List(vikes, jets, saints))
nfl.champion(saints)
nfl.save
nfl.save()

// retrieve it and compare
val nfl2 = League.find(nfl.id.get)
Expand Down Expand Up @@ -347,8 +347,8 @@ object CustomSerializersSpec extends Specification with MongoTestKit {
checkMongoIsRunning

// test data
val rmoss = Player.createRecord.name("Randy Moss").save
val bfavre = Player.createRecord.name("Brett Favre").save
val rmoss = Player.createRecord.name("Randy Moss").save()
val bfavre = Player.createRecord.name("Brett Favre").save()
val vikes = Team2(ObjectId.get, "Vikings", bfavre.id.get)
val jets = Team2(ObjectId.get, "Jets", bfavre.id.get)
val saints = Team2(ObjectId.get, "Saints", bfavre.id.get)
Expand All @@ -357,7 +357,7 @@ object CustomSerializersSpec extends Specification with MongoTestKit {
val nfl = League2.createRecord
nfl.teams(List(vikes, jets, saints))
nfl.champion(saints)
nfl.save
nfl.save()

// retrieve it and compare
val nfl2 = League2.find(nfl.id.toString)
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
/*
* Copyright 2014 WorldWide Conferencing, LLC
*
* 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 net.liftweb
package mongodb
package record

import net.liftweb.common._
import net.liftweb.record.field._

import org.specs2.mutable.Specification

import com.mongodb._


package mongoclientsaverecords {

import field._

class SaveDoc private () extends MongoRecord[SaveDoc] with ObjectIdPk[SaveDoc] {
def meta = SaveDoc

object name extends StringField(this, 12)
}
object SaveDoc extends SaveDoc with MongoMetaRecord[SaveDoc] {
import BsonDSL._

ensureIndex(("name" -> 1), true) // unique name
}
}


/**
* Systems under specification for MongoClientSave.
*/
class MongoClientSaveSpec extends Specification with MongoTestKit {
"MongoClientSave Specification".title

import mongoclientsaverecords._

override def mongo = new MongoClient("127.0.0.1", 27017)

"MongoMetaRecord with Mongo save" in {

checkMongoIsRunning

val sd1 = SaveDoc.createRecord.name("MongoSession")
val sd2 = SaveDoc.createRecord.name("MongoSession")
val sd3 = SaveDoc.createRecord.name("MongoDB")

// save to db
sd1.save()
sd2.save(false) // no exception thrown
sd2.save(true) must throwA[MongoException]
sd2.saveBox() must beLike {
case Failure(msg, _, _) => msg must contain("E11000 duplicate key error index") // exception thrown
}
sd3.save()

success
}
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright 2010-2013 WorldWide Conferencing, LLC
* Copyright 2010-2014 WorldWide Conferencing, LLC
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
Expand Down Expand Up @@ -224,7 +224,7 @@ class MongoRecordExamplesSpec extends Specification with MongoTestKit {
tr.person(per)

// save the record in the db
tr.save
tr.save()

// retrieve from db
def fromDb = TstRecord.find("_id", tr.id.value)
Expand Down Expand Up @@ -272,14 +272,14 @@ class MongoRecordExamplesSpec extends Specification with MongoTestKit {
val ref1 = RefDoc.createRecord
val ref2 = RefDoc.createRecord

ref1.save must_== ref1
ref2.save must_== ref2
ref1.save() must_== ref1
ref2.save() must_== ref2

val refUuid1 = RefUuidDoc.createRecord
val refUuid2 = RefUuidDoc.createRecord

refUuid1.save must_== refUuid1
refUuid2.save must_== refUuid2
refUuid1.save() must_== refUuid1
refUuid2.save() must_== refUuid2

val md1 = MainDoc.createRecord
val md2 = MainDoc.createRecord
Expand All @@ -301,10 +301,10 @@ class MongoRecordExamplesSpec extends Specification with MongoTestKit {
md3.refuuid.set(refUuid2.id.get)
md4.refuuid.set(refUuid2.id.get)

md1.save must_== md1
md2.save must_== md2
md3.save must_== md3
md4.save must_== md4
md1.save() must_== md1
md2.save() must_== md2
md3.save() must_== md3
md4.save() must_== md4

MainDoc.count must_== 4
RefDoc.count must_== 2
Expand Down Expand Up @@ -402,8 +402,8 @@ class MongoRecordExamplesSpec extends Specification with MongoTestKit {
val ref1 = RefDoc.createRecord
val ref2 = RefDoc.createRecord

ref1.save must_== ref1
ref2.save must_== ref2
ref1.save() must_== ref1
ref2.save() must_== ref2

val name = "ld1"
val strlist = List("string1", "string2", "string3", "string1")
Expand All @@ -422,7 +422,7 @@ class MongoRecordExamplesSpec extends Specification with MongoTestKit {
ld1.maplist.set(List(Map("name" -> "map1", "type" -> "map"), Map("name" -> "map2", "type" -> "map")))
ld1.binarylist.set(List[Array[Byte]]("foo".getBytes(), "bar".getBytes()))

ld1.save must_== ld1
ld1.save() must_== ld1

val qld1 = ListDoc.find(ld1.id.get)

Expand Down Expand Up @@ -466,7 +466,7 @@ class MongoRecordExamplesSpec extends Specification with MongoTestKit {
val md1 = MapDoc.createRecord
md1.stringmap.set(Map("h" -> "hola"))

md1.save must_== md1
md1.save() must_== md1

md1.delete_!

Expand All @@ -481,7 +481,7 @@ class MongoRecordExamplesSpec extends Specification with MongoTestKit {

val od1 = OptionalDoc.createRecord
od1.stringbox.valueBox must_== Empty
od1.save must_== od1
od1.save() must_== od1

OptionalDoc.find(od1.id.get).foreach {
od1FromDB =>
Expand All @@ -492,7 +492,7 @@ class MongoRecordExamplesSpec extends Specification with MongoTestKit {
val od2 = OptionalDoc.createRecord
od1.stringbox.valueBox must_== Empty
od2.stringbox.set("aloha")
od2.save must_== od2
od2.save() must_== od2

OptionalDoc.find(od2.id.get).foreach {
od2FromDB =>
Expand All @@ -514,7 +514,7 @@ class MongoRecordExamplesSpec extends Specification with MongoTestKit {
sd1.save(true) must_== sd1
sd2.save(true) must throwA[MongoException]

sd1.save
sd1.save()

sd2.name("sd2")
sd2.save(true) must_== sd2
Expand Down
Loading

0 comments on commit 5a8f5cf

Please sign in to comment.