package com.weEat.migrations import org.mongodb.scala.MongoDatabase import scala.concurrent.{ExecutionContext,Future} import scala.util.{Success,Failure} import scala.io.Source import com.weEat.models._ trait Migration { def execute(db: MongoDatabase): Future[Any] } object Migration { implicit val ec: ExecutionContext = ExecutionContext.global val migrations = Seq( InitDb, SeedNutrition, RestoreFromFile(Source.fromResource("db-seeds/nutrients.json"), Nutrient) //RestoreFromFile(Source.fromResource("db-seeds/usda-foods.json"), FoodNode), ) def executeAll(db: MongoDatabase) = executeFutures(db, migrations) def updateToLatest(db: MongoDatabase) = { val collection = db.getCollection[Metadata](Metadata.collectionName) collection.find().first().headOption().map({ case Some(Metadata(last)) => executeFutures(db, migrations.slice(last + 1, migrations.size)) case None => executeAll(db) }).flatten } private def executeFutures(db: MongoDatabase, seq: Seq[Migration]): Future[Any] = seq match { case head::tail => head.execute(db).transformWith({ case Success(_) => executeFutures(db, tail) case Failure(e) => db.getCollection[Metadata](Metadata.collectionName) .insertOne(Metadata(migrations.size - seq.size)).head() .transform(_ => Failure(e)) }) case Nil => db.getCollection[Metadata](Metadata.collectionName) .insertOne(Metadata(migrations.size)).head() } }