package com.weEat.migrations import org.mongodb.scala.MongoDatabase import com.weEat.models.{Authorization,User} import com.weEat.shared.models.FoodNodeId import com.mongodb.client.model._ import org.mongodb.scala.model.Filters._ import org.mongodb.scala.model.Indexes._ import java.util.concurrent.TimeUnit._ import org.bson.BsonType._ import scala.concurrent.{ExecutionContext,Future} object InitDb extends Migration { // Must be multiple of 256 val MAX_SIZE_META_DOCUMENT = 256*4 implicit val ec: ExecutionContext = ExecutionContext.global private def typ = `type` _ def execute(db: MongoDatabase) = Future.sequence(Seq( initMetadataCollection(db), createFoodCollection(db), createUserCollection(db), createTokenCollection(db) )) def initMetadataCollection(db: MongoDatabase) = { db.createCollection(Metadata.collectionName, new CreateCollectionOptions() .capped(true) .maxDocuments(1) .sizeInBytes(MAX_SIZE_META_DOCUMENT) ).head().map(_ => db.getCollection[Metadata](Metadata.collectionName) .insertOne(Metadata()) .head() ).flatten } def createFoodCollection(db: MongoDatabase) = db.createCollection(FoodNodeId.collectionName, new CreateCollectionOptions() ).head() def createUserCollection(db: MongoDatabase) = db.createCollection(User.collectionName, new CreateCollectionOptions().validationOptions( new ValidationOptions().validator( and( typ("email", STRING), typ("password", STRING), typ("created", DATE_TIME) ) ) ) ).head().map(_ => db.getCollection[User](User.collectionName) // TODO: this would be better as hashed // Currently ascending because hashed does not support unique .createIndex(ascending("email"), new IndexOptions().unique(true)).head() ).flatten def createTokenCollection(db: MongoDatabase) = db.createCollection(Authorization.collectionName, new CreateCollectionOptions().validationOptions( new ValidationOptions().validator( and( typ("email", STRING), typ("userId", OBJECT_ID), typ("accessToken", BINARY), typ("refreshToken", BINARY), typ("created", DATE_TIME) ) ) ) ).head().map(_ => db.getCollection[Authorization](Authorization.collectionName) .createIndexes(Seq( // TODO: These two would be better as hashed // Currently ascending because hashed does not support unique new IndexModel(ascending("accessToken"), new IndexOptions() .unique(true)), new IndexModel(ascending("refreshToken"), new IndexOptions() .unique(true)), new IndexModel(ascending("created"),new IndexOptions() .expireAfter(Authorization.refreshFreshTime.getSeconds(), SECONDS) ) )).head() ).flatten }