Commit f38ada1e authored by bow's avatar bow
Browse files

Refactor and streamline BaseRunRecord

parent cd2dd338
......@@ -18,7 +18,7 @@ package nl.lumc.sasc.sentinel.models
import java.util.Date
import com.novus.salat.annotations.{ Key, Salat }
import com.novus.salat.annotations.{ Key, Persist, Salat }
import org.bson.types.ObjectId
/** Representation of an uploaded run summary file. */
......@@ -36,17 +36,23 @@ import org.bson.types.ObjectId
/** Name of the pipeline that produced the run. */
def pipeline: String
/** Number of samples in the run summary file used for statistics. */
def nSamples: Int
/** Sample IDs linked to this run. */
def sampleIds: Seq[ObjectId]
/** Number of libraries in the run summary file used for statistics. */
def nLibs: Int
/** Library IDs linked to this run. */
def libIds: Seq[ObjectId]
/** UTC time when the run record was created. */
def creationTimeUtc: Date
/** UTC time when the run record was deleted. */
def deletionTimeUtc: Option[Date]
/** Number of samples in the run summary file used for statistics. */
@Persist val nSamples: Int = sampleIds.size
/** Number of libraries in the run summary file used for statistics. */
@Persist val nLibs: Int = libIds.size
}
object BaseRunRecord {
......@@ -55,9 +61,8 @@ object BaseRunRecord {
}
/**
* Simple implementation of a run record.
* Simple implementation of a run record with a single reference and multiple annotations.
*
* @param sampleIds Database sample document IDs contained in the sample.
* @param refId Reference record ID contained in the sample.
* @param annotIds Annotation record IDs contained in the sample.
*/
......@@ -65,8 +70,6 @@ case class RunRecord(
@Key("_id") runId: ObjectId,
uploaderId: String,
pipeline: String,
nSamples: Int,
nLibs: Int,
creationTimeUtc: Date,
runName: Option[String] = None,
deletionTimeUtc: Option[Date] = None,
......
......@@ -24,7 +24,7 @@ import com.novus.salat._
import com.novus.salat.global._
import nl.lumc.sasc.sentinel.Pipeline
import nl.lumc.sasc.sentinel.db.MongodbAccessObject
import nl.lumc.sasc.sentinel.models.{ PipelineStats, RunRecord, User }
import nl.lumc.sasc.sentinel.models.{ PipelineStats, BaseRunRecord, User }
import nl.lumc.sasc.sentinel.utils.{ DuplicateFileException, calcMd5, getUtcTimeNow }
import org.scalatra.servlet.FileItem
......@@ -43,7 +43,7 @@ abstract class RunsProcessor(protected val mongo: MongodbAccessObject) extends P
* @param pipeline Enum value representing the pipeline name that generated the run summary file.
* @return A run record of the uploaded run summary file.
*/
def processRun(fi: FileItem, user: User, pipeline: Pipeline.Value): Try[RunRecord] // TODO: use Futures instead
def processRun(fi: FileItem, user: User, pipeline: Pipeline.Value): Try[BaseRunRecord] // TODO: use Futures instead
/** Collection used by this adapter. */
private lazy val coll = mongo.db(collectionNames.Runs)
......@@ -102,9 +102,9 @@ abstract class RunsProcessor(protected val mongo: MongodbAccessObject) extends P
* @param run Run record to store.
* @return Result of the store operation.
*/
def storeRun(run: RunRecord): WriteResult = {
def storeRun(run: BaseRunRecord): WriteResult = {
// TODO: use Futures instead
val dbo = grater[RunRecord].asDBObject(run)
val dbo = grater[BaseRunRecord].asDBObject(run)
coll.insert(dbo)
}
......@@ -118,14 +118,14 @@ abstract class RunsProcessor(protected val mongo: MongodbAccessObject) extends P
* @param user Run uploader.
* @return Run record, if it exists.
*/
def getRunRecord(runId: ObjectId, user: User): Option[RunRecord] = {
def getRunRecord(runId: ObjectId, user: User): Option[BaseRunRecord] = {
// TODO: use Futures instead
val userCheck =
if (user.isAdmin) MongoDBObject.empty
else MongoDBObject("uploaderId" -> user.id)
coll
.findOne(MongoDBObject("_id" -> runId, "deletionTimeUtc" -> MongoDBObject("$exists" -> false)) ++ userCheck)
.collect { case dbo => grater[RunRecord].asObject(dbo) }
.collect { case dbo => grater[BaseRunRecord].asObject(dbo) }
}
/**
......@@ -154,7 +154,7 @@ abstract class RunsProcessor(protected val mongo: MongodbAccessObject) extends P
* @param pipelines Pipeline enums. If non-empty, only run records of the pipelines in the sequence will be retrieved.
* @return Run records.
*/
def getRuns(user: User, pipelines: Seq[Pipeline.Value]): Seq[RunRecord] = {
def getRuns(user: User, pipelines: Seq[Pipeline.Value]): Seq[BaseRunRecord] = {
// TODO: use Futures instead
val query =
if (pipelines.isEmpty) $and("uploaderId" $eq user.id)
......@@ -162,7 +162,7 @@ abstract class RunsProcessor(protected val mongo: MongodbAccessObject) extends P
coll
.find($and(query :: ("deletionTimeUtc" $exists false)))
.sort(MongoDBObject("creationTimeUtc" -> -1))
.map { case dbo => grater[RunRecord].asObject(dbo) }
.map { case dbo => grater[BaseRunRecord].asObject(dbo) }
.toSeq
}
......@@ -189,7 +189,7 @@ abstract class RunsProcessor(protected val mongo: MongodbAccessObject) extends P
* @param user User requesting the delete operation. Only the run uploader him/herself or an admin can delete runs.
* @return Run record with `deletionTimeUtc` attribute and a boolean showing whether the deletion was performed or not.
*/
def deleteRun(runId: ObjectId, user: User): Option[(RunRecord, Boolean)] = {
def deleteRun(runId: ObjectId, user: User): Option[(BaseRunRecord, Boolean)] = {
// TODO: use Futures instead
val userCheck =
if (user.isAdmin) MongoDBObject.empty
......@@ -198,7 +198,7 @@ abstract class RunsProcessor(protected val mongo: MongodbAccessObject) extends P
val docDeleted = coll
.findOne(MongoDBObject("_id" -> runId,
"deletionTimeUtc" -> MongoDBObject("$exists" -> true)) ++ userCheck)
.map { case dbo => (grater[RunRecord].asObject(dbo), false) }
.map { case dbo => (grater[BaseRunRecord].asObject(dbo), false) }
if (docDeleted.isDefined) docDeleted
else {
......@@ -209,7 +209,7 @@ abstract class RunsProcessor(protected val mongo: MongodbAccessObject) extends P
update = MongoDBObject("$set" -> MongoDBObject("deletionTimeUtc" -> getUtcTimeNow)),
returnNew = true,
fields = MongoDBObject.empty, sort = MongoDBObject.empty, remove = false, upsert = false)
.map { case dbo => (grater[RunRecord].asObject(dbo), true) }
.map { case dbo => (grater[BaseRunRecord].asObject(dbo), true) }
docToDelete.foreach {
case (doc, _) =>
val samplesColl = mongo.db(collectionNames.pipelineSamples(doc.pipeline))
......
......@@ -256,9 +256,7 @@ class GentrapV04RunsProcessor(mongo: MongodbAccessObject)
libIds = libs.map(_.id),
creationTimeUtc = getUtcTimeNow,
uploaderId = user.id,
pipeline = pipeline.toString.toLowerCase,
nSamples = samples.size,
nLibs = libs.size)
pipeline = pipeline.toString.toLowerCase)
/** Attribute keys of Gentrap annotations. */
protected val GentrapAnnotationKeys = Set("annotation_bed", "annotation_refflat", "annotation_gtf")
......
......@@ -51,7 +51,7 @@ class PlainRunsProcessor(mongo: MongodbAccessObject) extends RunsProcessor(mongo
(byteContents, unzipped) <- Try(fi.readInputStream())
_ <- Try(parseAndValidate(byteContents))
fileId <- Try(storeFile(byteContents, user, pipeline, fi.getName, unzipped))
run = RunRecord(fileId, user.id, pipeline.toString.toLowerCase, 0, 0, Date.from(Clock.systemUTC().instant))
run = RunRecord(fileId, user.id, pipeline.toString.toLowerCase, Date.from(Clock.systemUTC().instant))
_ <- Try(storeRun(run))
} yield run
}
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment