10000 Added trait to encapsulate common functions used in record objects. · randomcoding/scala-utilities@f8d9d68 · GitHub
[go: up one dir, main page]

Skip to content

Commit f8d9d68

Browse files
committed
Added trait to encapsulate common functions used in record objects.
1 parent a9a182e commit f8d9d68

File tree

1 file changed

+118
-0
lines changed

1 file changed

+118
-0
lines changed
Lines changed: 118 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,118 @@
1+
/**
2+
* Copyright (C) 2012 - RandomCoder <randomcoder@randomcoding.co.uk>
3+
*
4+
* This program is free software: you can redistribute it and/or modify
5+
* it under the terms of the GNU Affero General Public License as
6+
* published by the Free Software Foundation, either version 3 of the
7+
* License, or (at your option) any later version.
8+
*
9+
* This program is distributed in the hope that it will be useful,
10+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
11+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12+
* GNU Affero General Public License for more details.
13+
*
14+
* You should have received a copy of the GNU Affero General Public License
15+
* along with this program. If not, see <http://www.gnu.org/licenses/>.
16+
*
17+
* Contributors:
18+
* RandomCoder <randomcoder@randomcoding.co.uk> - initial API and implementation and/or initial documentation
19+
*/
20+
package uk.co.randomcoding.scala.util.lift.mongodb
21+
22+
import org.bson.types.ObjectId
23+
import net.liftweb.mongodb.record.MongoMetaRecord
24+
import net.liftweb.mongodb.record.MongoRecord
25+
import net.liftweb.mongodb.record.field.ObjectIdPk
26+
import com.foursquare.rogue.Rogue
27+
28+
/**
29+
* Provides common functionality for record companion objects to find matching records and find records by id.
30+
*
31+
* Requires that the type `T extend MongoRecord[T] with ObjectIdPk[T]`
32+
*
33+
* Users of this trait are required to implement the `findById(org.bson.types.ObjectId)` and
34+
* `matchingRecord(T)` methods.
35+
*
36+
* @author RandomCoder <randomcoder@randomcoding.co.uk>
37+
*
38+
* Created On: 29 Jul 2012
39+
*/
40+
trait BaseMongoRecordObject[T <: MongoRecord[T] with ObjectIdPk[T]] {
41+
42+
/**
43+
* Find a record by its object id - typically its `id` or `_id` field.
44+
*
45+
* Should return `Some(record)` if there is a record of ths type with the given object id or `None` if there is not.
46+
*/
47+
def findById(oid: ObjectId): Option[T]
48+
49+
/**
50+
* Find a record that matched the input one, if one is present in the database.
51+
*
52+
* The definition of a match is left up to the implementer, but it is often good to be
53+
* consistent with the companion classes `equals` method.
54+
*
55+
* This method is only required to return a single match, even if there are multiple matches in the database,
56+
* so the exact match strategy and precedence is left up to the implementor.
57+
*
58+
* As this is primarily used (by me) to check that there are no matching records present, then this is sufficient.
59+
*
60+
* @return An optional record if there is a match found, or `None` if there are no records that match.
61+
*/
62+
def matchingRecord(t: T): Option[T]
63+
64+
/**
65+
* Updates the record with the given `ObjectId` with the values from the new record.
66+
*
67+
* If there is no record with the given `ObjectId` then this method '''should not''' add the
68+
* new record, it should return `None`.
69+
*
70+
* If there is a record with the given `ObjectId` then that record should have all its values set to the
71+
* ones in the new record. The updated record should be returned inside an Option.
72+
*/
73+
final def update(oid: ObjectId, newT: T): Option[T] = findById(oid) match {
74+
case Some(record) => newT.id(oid).saveTheRecord
75+
case _ => None
76+
}
77+
78+
/**
79+
* Remove the record with the given `ObjectId` from the collection of this type.
80+
*
81+
* @return The removed record, or if there is no record with the given `ObjectId`,
82+
* or if the remove operation fails `None`
83+
*/
84+
final def remove(oid: ObjectId): Option[T] = findById(oid) match {
85+
case Some(record) => if (record.delete_!) Some(record) else None
86+
case _ => None
87+
}
88+
89+
/**
90+
* Finds a ''matching'' record in the database.
91+
*
92+
* A ''match'' is made if:
93+
*
94+
* - There is another record with the same Object Id
95+
* - A record is returned from the [[uk.co.randomcoding.scala.util.lift.mongodb.BaseMongoRecordObject#matchingRecord(T)]]
96+
*
97+
* @return The optional match, or `None` if there is no match
98+
*/
99+
final def findMatching(t: T): Option[T] = findById(t.id.get) match {
100+
case Some(r) => Some(r)
101+
case _ => matchingRecord(t)
102+
}
103+
104+
/**
105+
* Add a new record to the database unless there is a matching record.
106+
*
107+
* If there is a matching record then '''do not''' add the new one.
108+
*
109+
* A match is determined by calling the `findMatching(T)` method,
110+
* with a return value of Some(t) indicating there is a matching record.
111+
*
112+
* @return The optionally added record, or if there is a match then the matched record.
113+
*/
114+
final def add(t: T): Option[T] = findMatching(t) match {
115+
case Some(t) => Some(t)
116+
case _ => t.saveTheRecord
117+
}
118+
}

0 commit comments

Comments
 (0)
0