diff --git a/README.md b/README.md index a253ccbb..71079d8d 100644 --- a/README.md +++ b/README.md @@ -72,7 +72,7 @@ docker rm drops > *Notice:* -All server generated output will be written to the `server-output` file. +All server generated output will be written to the command line (logs in the case of a docker image). This is also needed to confirm users since the production server also uses a mock mail server. > @@ -365,6 +365,10 @@ and your service. ChangeLog ========= +## Version 0.36.67 (2021-5-10) +* [[B] #4 - UserDAO does not execute inserts as a transaction](https://github.com/SOTETO/drops/issues/4) +* [[B] #6 - DummyUser creation throws an error on Insert](https://github.com/SOTETO/drops/issues/6) +* [[B] #8 - Database error on inserting Address](https://github.com/SOTETO/drops/issues/8) ## Version 0.36.61 (2019-4-16) diff --git a/app/controllers/Application.scala b/app/controllers/Application.scala index 9d38b3f2..e6ad537f 100644 --- a/app/controllers/Application.scala +++ b/app/controllers/Application.scala @@ -76,6 +76,7 @@ class Application @Inject() ( // save user in database and return a future of the saved user userService.save(crewSupporter) }) + //Future.sequence(users).map((list) => Ok(Json.toJson(list))) Future.sequence(users).map((list) => Ok(Json.toJson(list))) }) ) diff --git a/app/controllers/webapp/Auth.scala b/app/controllers/webapp/Auth.scala index 2673a8ac..75ef2a7d 100644 --- a/app/controllers/webapp/Auth.scala +++ b/app/controllers/webapp/Auth.scala @@ -139,21 +139,34 @@ class Auth @Inject() ( case Some(_) => Future.successful(WebAppResult.Bogus(request, "error.userExists", List(signUpData.email), "AuthProvider.SignUp.UserExists", Json.toJson(Map[String, String]())).getResult) case None => - val profile = Profile(loginInfo, signUpData.email, signUpData.firstName, signUpData.lastName, signUpData.mobilePhone, signUpData.placeOfResidence, signUpData.birthday, signUpData.gender, signUpData.address) + val profile = Profile( + loginInfo, + signUpData.email, + signUpData.firstName, + signUpData.lastName, + signUpData.mobilePhone, + signUpData.placeOfResidence, + signUpData.birthday, + signUpData.gender, + signUpData.address.flatMap(a => a.isEmpty match { + case true => None + case _ => Some(a) + }) + ) for { avatarUrl <- avatarService.retrieveURL(signUpData.email) user <- userService.save(User(id = UUID.randomUUID(), List(profile), updated = System.currentTimeMillis(), created = System.currentTimeMillis())) pw <- authInfoRepository.add(loginInfo, passwordHasher.hash(signUpData.password)) - token <- userTokenService.save(UserToken.create(user.id, signUpData.email, true)) + token <- userTokenService.save(UserToken.create(user.get.id, signUpData.email, true)) } yield { getWebApp match { case Left(message) => WebAppResult.NotFound(request, message._1, Nil, "AuthProvider.SignUp.MissingConfig", Map[String, String]()).getResult case Right(webapp) => { - mailer.welcome(profile, link = webapp.getAbsoluteSignUpTokenEndpoint(token.id.toString)) - WebAppResult.Ok(request, "signup.created", Nil, "AuthProvider.SignUp.Success", Json.toJson(profile)).getResult - } + mailer.welcome(profile, link = webapp.getAbsoluteSignUpTokenEndpoint(token.id.toString)) + WebAppResult.Ok(request, "signup.created", Nil, "AuthProvider.SignUp.Success", Json.toJson(profile)).getResult } } + } } } ) diff --git a/app/daos/ProfileDao.scala b/app/daos/ProfileDao.scala index c799fa4b..18d1767d 100644 --- a/app/daos/ProfileDao.scala +++ b/app/daos/ProfileDao.scala @@ -133,7 +133,7 @@ class MariadbProfileDao @Inject()(val crewDao: MariadbCrewDao) extends ProfileDa s <- supporters.filter(s => s.profileId === p.id) } yield s dbConfig.db.run(action.result).flatMap(result => { - dbConfig.db.run((addresses returning addresses.map(_.id)) += AddressDB(0, Some(UUID.randomUUID()), profile.supporter.address.head, result.head.id)) + dbConfig.db.run((addresses returning addresses.map(_.id)) += AddressDB(0, UUID.randomUUID(), profile.supporter.address.head, result.head.id)) }) } // def getSupporterCrewDB(sc: SupporterCrewDB) : Future[SupporterCrewDB] = dbConfig.db.run( diff --git a/app/daos/UserDao.scala b/app/daos/UserDao.scala index 1325b889..2e026608 100644 --- a/app/daos/UserDao.scala +++ b/app/daos/UserDao.scala @@ -27,11 +27,11 @@ trait UserDao extends ObjectIdResolver with CountResolver{ // def getObjectId(userId: UUID):Future[Option[ObjectIdWrapper]] def find(loginInfo:LoginInfo):Future[Option[User]] def find(userId:UUID):Future[Option[User]] - def save(user:User):Future[User] - def replace(user:User):Future[User] + def save(user:User):Future[Option[User]] + def replace(user:User):Future[Option[User]] def confirm(loginInfo:LoginInfo):Future[User] - def link(user:User, profile:Profile):Future[User] - def update(profile:Profile):Future[User] + def link(user:User, profile:Profile):Future[Option[User]] + def update(profile:Profile):Future[Option[User]] def list : Future[List[User]] def listOfStubs : Future[List[UserStub]] def delete (userId:UUID):Future[Boolean] @@ -60,12 +60,12 @@ class MariadbUserDao @Inject()(val crewDao: MariadbCrewDao) extends UserDao { val oauthTokens = TableQuery[OauthTokenTableDef] val addresses = TableQuery[AddressTableDef] - def uuidFromString(uuid: Option[String]) = { - uuid match { - case Some(id) => Some(UUID.fromString(id)) - case _ => None - } - } +// def uuidFromString(uuid: Option[String]) = { +// uuid match { +// case Some(id) => Some(UUID.fromString(id)) +// case _ => None +// } +// } implicit val getUserResult = GetResult(r => UserDB(r.nextLong, UUID.fromString(r.nextString), r.nextString, r.nextLong, r.nextLong)) implicit val getProfileResult = GetResult(r => ProfileDB(r.nextLong, r.nextBoolean, r.nextString, r.nextLong)) @@ -74,7 +74,19 @@ class MariadbUserDao @Inject()(val crewDao: MariadbCrewDao) extends UserDao { implicit val getSupporterInfoResult = GetResult(r => SupporterDB(r.nextLong, r.nextStringOption, r.nextStringOption, r.nextStringOption, r.nextStringOption, r.nextStringOption, r.nextLongOption, r.nextStringOption, r.nextLong)) implicit val getSupporterCrewInfoResult = GetResult(r => Some(SupporterCrewDB(r.nextLong, r.nextLong, r.nextLong, r.nextStringOption, r.nextStringOption, r.nextLong, r.nextLong, r.nextStringOption, r.nextLongOption))) implicit val getOauth1InfoResult = GetResult(r => Some(OAuth1InfoDB(r.nextLong, r.nextString, r.nextString, r.nextLong))) - implicit val getAddressInfoResult = GetResult(r => Some(AddressDB(r.nextLong, uuidFromString(r.nextStringOption), r.nextString, r.nextStringOption, r.nextString, r.nextString, r.nextString, r.nextLong))) + implicit val getAddressInfoResult = GetResult(r => { + val id = r.nextLong + val uuidOption = r.nextStringOption + val street = r.nextString + val additional = r.nextStringOption + val zip = r.nextString + val city = r.nextString + val country = r.nextString + val supporter_id = r.nextLong + uuidOption.map(uuidString => + AddressDB(id, UUID.fromString(uuidString), street, additional, zip, city, country, supporter_id) + ) + }) @@ -110,17 +122,26 @@ class MariadbUserDao @Inject()(val crewDao: MariadbCrewDao) extends UserDao { * @param user * @return */ - override def save(user: User): Future[User]={ + override def save(user: User): Future[Option[User]]={ val userDBObj = UserDB(user) - dbConfig.db.run((users returning users.map(_.id)) += userDBObj).flatMap(id => { - findDBUserModel(id) - }).flatMap(userObj => { - addProfiles(userObj, user.profiles) - }) + val crewIds : Future[Map[String, Option[Long]]] = Future.sequence(user.profiles.map(profile => + profile.supporter.crew match { + // if supporter has a crew, find the CrewDB.id by UUID crew.id + case Some(crew) => crewDao.findDBCrewModel(crew.id).map(_ match { + case Some(c) => (profile.loginInfo.providerKey, Some(c.id)) + case None => (profile.loginInfo.providerKey, None) + }) + //else None + case _ => Future.successful((profile.loginInfo.providerKey, None)) + } + )).map(_.toMap) + crewIds.flatMap(c_ids => + dbConfig.db.run(insertUser(userDBObj, user.profiles, c_ids)) + ).flatMap(id => find(id)) } - override def replace(updatedUser: User): Future[User] = { + override def replace(updatedUser: User): Future[Option[User]] = { findDBUserModel(updatedUser.id).flatMap(user => { //Delete Profiles val deleteProfile = profiles.filter(_.userId === user.id) @@ -132,9 +153,25 @@ class MariadbUserDao @Inject()(val crewDao: MariadbCrewDao) extends UserDao { dbConfig.db.run( (deletePasswordInfo.delete andThen deleteLoginInfo.delete andThen deleteAddress.delete andThen deleteSupporterCrew.delete andThen deleteSupporter.delete andThen deleteProfile.delete).transactionally - ).flatMap(_ => - addProfiles(user, updatedUser.profiles) - ) + ).flatMap(_ => { + // now insert the new profiles + // start with retrieving the crew IDs of the assigned crews + val crewIds: Future[Map[String, Option[Long]]] = Future.sequence(updatedUser.profiles.map(profile => + profile.supporter.crew match { + // if supporter has a crew, find the CrewDB.id by UUID crew.id + case Some(crew) => crewDao.findDBCrewModel(crew.id).map(_ match { + case Some(c) => (profile.loginInfo.providerKey, Some(c.id)) + case None => (profile.loginInfo.providerKey, None) + }) + //else None + case _ => Future.successful((profile.loginInfo.providerKey, None)) + } + )).map(_.toMap) + crewIds.flatMap(c_ids => + dbConfig.db.run(insertProfiles(user.id, updatedUser.profiles, c_ids)) + ).flatMap(_ => find(user.id)) + //addProfiles(user, updatedUser.profiles) + }) }) } @@ -151,10 +188,25 @@ class MariadbUserDao @Inject()(val crewDao: MariadbCrewDao) extends UserDao { * @param profile * @return */ - override def link(user: User, profile: Profile): Future[User] = { + override def link(user: User, profile: Profile): Future[Option[User]] = { find(profile.loginInfo).flatMap(user => { findDBUserModel(user.get.id).flatMap(userDB => { - addProfiles(userDB, List(profile)) + // now insert the new profiles + // start with retrieving the crew IDs of the assigned crews + val crewIds : Future[Map[String, Option[Long]]] = + profile.supporter.crew match { + // if supporter has a crew, find the CrewDB.id by UUID crew.id + case Some(crew) => crewDao.findDBCrewModel(crew.id).map(_ match { + case Some(c) => Map(profile.loginInfo.providerKey -> Some(c.id)) + case None => Map(profile.loginInfo.providerKey -> None) + }) + //else None + case _ => Future.successful(Map(profile.loginInfo.providerKey -> None)) + } + crewIds.flatMap(c_ids => + dbConfig.db.run(insertProfiles(userDB.id, List(profile), c_ids)) + ).flatMap(_ => find(userDB.id)) + //addProfiles(userDB, List(profile)) }) }) } @@ -166,7 +218,7 @@ class MariadbUserDao @Inject()(val crewDao: MariadbCrewDao) extends UserDao { * @param profile * @return */ - override def update(profile: Profile): Future[User] = { + override def update(profile: Profile): Future[Option[User]] = { find(profile.loginInfo).flatMap(user => { findDBUserModel(user.get.id).flatMap(userDB => { //Delete Profile @@ -179,9 +231,24 @@ class MariadbUserDao @Inject()(val crewDao: MariadbCrewDao) extends UserDao { dbConfig.db.run( (deletePasswordInfo.delete andThen deleteLoginInfo.delete andThen deleteAddress.delete andThen deleteSupporterCrew.delete andThen deleteSupporter.delete andThen deleteProfile.delete).transactionally - ).flatMap(_ => - addProfiles(userDB, List(profile)) - ) + ).flatMap(_ => { + // now insert the new profiles + // start with retrieving the crew IDs of the assigned crews + val crewIds: Future[Map[String, Option[Long]]] = + profile.supporter.crew match { + // if supporter has a crew, find the CrewDB.id by UUID crew.id + case Some(crew) => crewDao.findDBCrewModel(crew.id).map(_ match { + case Some(c) => Map(profile.loginInfo.providerKey -> Some(c.id)) + case None => Map(profile.loginInfo.providerKey -> None) + }) + //else None + case _ => Future.successful(Map(profile.loginInfo.providerKey -> None)) + } + crewIds.flatMap(c_ids => + dbConfig.db.run(insertProfiles(userDB.id, List(profile), c_ids)) + ).flatMap(_ => find(userDB.id)) + //addProfiles(userDB, List(profile)) + }) }) }) } @@ -298,6 +365,78 @@ class MariadbUserDao @Inject()(val crewDao: MariadbCrewDao) extends UserDao { dbConfig.db.run(users.filter(_.id === id).result).map(r => r.head) } + /** + * Creates a [[DBIOAction]] that inserts a complete user as a transaction that inserts into multiple columns. + * + * @author Johann Sell + * @param userDB + * @param userProfiles + * @param crewDBids + * @return + */ + private def insertUser(userDB: UserDB, userProfiles: List[Profile], crewDBids: Map[String, Option[Long]]) : DBIOAction[Long,slick.dbio.NoStream,slick.dbio.Effect.Write with slick.dbio.Effect.Write with slick.dbio.Effect.Write with slick.dbio.Effect.Write with slick.dbio.Effect.Write with slick.dbio.Effect.Write with slick.dbio.Effect.Write with slick.dbio.Effect.Write with slick.dbio.Effect.Transactional with slick.dbio.Effect.Transactional] = { + (for { + u <- (users returning users.map(_.id)) += userDB + _ <- insertProfiles(u, userProfiles, crewDBids) + } yield u).transactionally + } + + /** + * Creates a [[DBIOAction]] that inserts all given profiles as a transaction and assigns them to a given users ID. + * + * @author Johann Sell + * @param userID + * @param userProfiles + * @param crewDBids + * @return + */ + private def insertProfiles(userID: Long, userProfiles: List[Profile], crewDBids: Map[String, Option[Long]]): DBIOAction[List[Long],slick.dbio.NoStream,slick.dbio.Effect.Write with slick.dbio.Effect.Write with slick.dbio.Effect.Write with slick.dbio.Effect.Write with slick.dbio.Effect.Write with slick.dbio.Effect.Write with slick.dbio.Effect.Write with slick.dbio.Effect.Transactional] = { + // Assign a Supporter to an Crew via SupporterCrew. Each SupporterCrew Object contains one Role. + def supporterCrewAssignment(crewDBiD: Option[Long], s: Long, r: Option[Role]) = crewDBiD match { + case Some(crewId) => (supporterCrews returning supporterCrews.map(_.id)) += (SupporterCrewDB(s, crewId, r, None, None, None)) + case _ => DBIO.successful(false) + } + + // Assign Address to Supporter. + def addressAssignment(address: Option[Address], supporterId: Long) = address match { + case Some(a) => (addresses returning addresses.map(_.id)) += AddressDB(a, supporterId) + case _ => DBIO.successful(false) + } + + DBIO.sequence(userProfiles.map(profile => (for { + // insert Profile and return long id as p + p <- (profiles returning profiles.map(_.id)) += ProfileDB(profile, userID) + // insert Supporter with profile_id = p and return long id as s + s <- (supporters returning supporters.map(_.id)) += SupporterDB(0, profile.supporter, p) + //insert Addresses with supporter_id = s. + _ <- profile.supporter.address match { + // if Addresses is a list and not Empty we insert every address in the list and return a DBIO.seq with all id's + case list if list.nonEmpty => list.tail.foldLeft(DBIO.seq(addressAssignment(list.headOption, s)))( + (seq, address) => DBIO.seq(seq, addressAssignment(Some(address), s)) + ) + // else return Database false + case _ => DBIO.successful(false) + } + // same as address for all roles + _ <- profile.supporter.roles match { + case list if list.nonEmpty => list.tail.foldLeft(DBIO.seq(supporterCrewAssignment(crewDBids.getOrElse(profile.loginInfo.providerKey, None), s, list.headOption)))( + (seq, role) => DBIO.seq(seq, supporterCrewAssignment(crewDBids.getOrElse(profile.loginInfo.providerKey, None), s, Some(role))) + ) + case _ => DBIO.seq(supporterCrewAssignment(crewDBids.getOrElse(profile.loginInfo.providerKey, None), s, None)) + } + // insert the LoginInfo PasswordInfo and OAuthInfo Models + _ <- (loginInfos returning loginInfos.map(_.id)) += LoginInfoDB(0, profile.loginInfo, p) + _ <- (profile.passwordInfo match { + case Some(passwordInfo) => (passwordInfos returning passwordInfos.map(_.id)) += PasswordInfoDB(0, passwordInfo, p) + case None => DBIO.successful(false) + }) + _ <- (profile.oauth1Info match { + case Some(oAuth1Info) => (oauth1Infos returning oauth1Infos.map(_.id)) += OAuth1InfoDB(oAuth1Info, p) + case None => DBIO.successful(false) + }) + } yield p).transactionally)) + } + //ToDo: Export Profile DB Operations to ProfileDAO. This has to be protected, becaus it should not used outside the DAO Package /** * internal function to add a list of profiles for one user to the database diff --git a/app/daos/schema/AddressTableDef.scala b/app/daos/schema/AddressTableDef.scala index cd6f4f03..c8fa3a8c 100644 --- a/app/daos/schema/AddressTableDef.scala +++ b/app/daos/schema/AddressTableDef.scala @@ -17,7 +17,7 @@ class AddressTableDef(tag: Tag) extends Table[AddressDB](tag, "Address") { def supporterId = column[Long]("supporter_id") def * = - (id, publicId.?, street, additional.?, zip, city, country, supporterId) <> (AddressDB.tupled, AddressDB.unapply) + (id, publicId, street, additional.?, zip, city, country, supporterId) <> (AddressDB.tupled, AddressDB.unapply) def supporterKey = foreignKey("supporter_id", supporterId, TableQuery[SupporterTableDef])(_.id, onUpdate = ForeignKeyAction.Cascade) diff --git a/app/models/Address.scala b/app/models/Address.scala index 966f9b42..3f0be1be 100644 --- a/app/models/Address.scala +++ b/app/models/Address.scala @@ -28,7 +28,10 @@ case class AddressStub ( country: String ) extends AddressBase { - def toAddress: Address = Address(Some(UUID.randomUUID()), street, additional, zip, city, country) + def toAddress: Address = Address(UUID.randomUUID(), street, additional, zip, city, country) + + def isEmpty: Boolean = + street == "" && additional.map(_ == "").getOrElse(true) && zip == "" && city == "" && country == "" } /** @@ -42,7 +45,7 @@ case class AddressStub ( * @param toAddressStub convert the Address to AddressStub */ case class Address ( - publicId: Option[UUID], + publicId: UUID, override val street: String, override val additional: Option[String], override val zip: String, diff --git a/app/models/DummyUser.scala b/app/models/DummyUser.scala index 1af20650..ca81d501 100644 --- a/app/models/DummyUser.scala +++ b/app/models/DummyUser.scala @@ -39,7 +39,13 @@ object DummyUser { (res, i) => res + pillars.toList(i) ) }, - Set(), + Set(AddressStub( + (json \ "location" \ "street" \ "name").as[String], + None, + (json \ "location" \ "postcode").as[Int].toString, + (json \ "location" \ "city").as[String], + (json \ "location" \ "country").as[String] + ).toAddress), Some("active"), None ) diff --git a/app/models/database/AddressDB.scala b/app/models/database/AddressDB.scala index df581b3e..3cf0e502 100644 --- a/app/models/database/AddressDB.scala +++ b/app/models/database/AddressDB.scala @@ -21,7 +21,7 @@ import models.{Organization, BankAccount} */ case class AddressDB( id: Long, - publicId: Option[UUID], + publicId: UUID, street: String, additional: Option[String], zip: String, @@ -40,14 +40,14 @@ case class AddressDB( ) } - object AddressDB extends ((Long, Option[UUID], String, Option[String], String, String, String, Long) => AddressDB) { + object AddressDB extends ((Long, UUID, String, Option[String], String, String, String, Long) => AddressDB) { - def apply(tuple: (Long, Option[UUID], String, Option[String], String, String, String, Long)): AddressDB = + def apply(tuple: (Long, UUID, String, Option[String], String, String, String, Long)): AddressDB = AddressDB(tuple._1, tuple._2, tuple._3, tuple._4, tuple._5, tuple._6, tuple._7, tuple._8) def apply(id: Long, address: Address, supporterId: Long):AddressDB = AddressDB(id, address.publicId, address.street, address.additional, address.zip, address.city, address.country, supporterId) - def apply(id: Long, uuid: Option[UUID], address: Address, supporterId: Long):AddressDB = AddressDB(id, uuid, address.street, address.additional, address.zip, address.city, address.country, supporterId) + def apply(id: Long, uuid: UUID, address: Address, supporterId: Long):AddressDB = AddressDB(id, uuid, address.street, address.additional, address.zip, address.city, address.country, supporterId) def apply(address: Address, supporterId: Long):AddressDB = AddressDB(0, address.publicId, address.street, address.additional, address.zip, address.city, address.country, supporterId) diff --git a/app/services/UserService.scala b/app/services/UserService.scala index f8b7501b..146af7b9 100644 --- a/app/services/UserService.scala +++ b/app/services/UserService.scala @@ -34,7 +34,10 @@ class UserService @Inject() ( def retrieve(loginInfo:LoginInfo):Future[Option[User]] = userDao.find(loginInfo) def save(user:User) = { userDao.save(user).map(user => { - nats.publishCreate("USER", user.id) + user.map(u => { + nats.publishCreate("USER", u.id) + poolService.save(u) + }) user }) } @@ -42,8 +45,10 @@ class UserService @Inject() ( def update(updatedUser: User) = { userDao.replace(updatedUser).map(user => { - nats.publishUpdate("USER", updatedUser.id) - poolService.update(user) // Todo: Consider result?! + user.map(u => { + nats.publishUpdate("USER", u.id) + poolService.update(u) // Todo: Consider result?! + }) user }) } @@ -100,22 +105,27 @@ class UserService @Inject() ( } def save(socialProfile:CommonSocialProfile) = { - def onSuccess(user: User, create: Boolean) = { - if(create) { - nats.publishCreate("USER", user.id) - poolService.save(user) // Todo: Consider result?! - } else { - nats.publishUpdate("USER", user.id) - poolService.update(user) // Todo: Consider result?! - } + def onCreate(user: Option[User]) = { + user.map(u => { + nats.publishCreate("USER", u.id) + poolService.save(u) + }) + user + } + + def onUpdate(user: Option[User]) = { + user.map(u => { + nats.publishUpdate("USER", u.id) + poolService.update(u) + }) user } val profile = Profile(socialProfile) userDao.find(profile.loginInfo).flatMap { case None => userDao.save(User(UUID.randomUUID(), List(profile), System.currentTimeMillis(), System.currentTimeMillis())) - .map(onSuccess(_, true)) + .map(onCreate(_)) case Some(user) => userDao.update(profile) - .map(onSuccess(_, false)) + .map(onUpdate(_)) } } diff --git a/build.sbt b/build.sbt index cf174a0b..c0d83920 100644 --- a/build.sbt +++ b/build.sbt @@ -1,8 +1,9 @@ import com.typesafe.sbt.packager.docker.Cmd name := """Drops""" +organization := "net.soteto" -version := "0.36.63" +version := "0.36.67" lazy val root = (project in file(".")).enablePlugins(PlayScala).enablePlugins(DockerPlugin) @@ -13,6 +14,7 @@ resolvers ++= Seq( "scalaz-bintray" at "http://dl.bintray.com/scalaz/releases", Resolver.sonatypeRepo("snapshots") ) +resolvers += Resolver.jcenterRepo pipelineStages := Seq(digest,gzip) @@ -59,10 +61,11 @@ excludeFilter in (Assets, LessKeys.less) := "_*.less" // setting a maintainer which is used for all packaging types maintainer in Docker := "Johann Sell" - // exposing the play ports dockerExposedPorts := Seq(9000, 9443) - -dockerRepository := Some("vivaconagua") -version in Docker := "latest" - +dockerRepository := Some("soteto") +//dockerUsername := Some("soteto") +//dockerUpdateLatest := true +routesGenerator := InjectedRoutesGenerator +packageName in Docker := packageName.value +version in Docker := version.value \ No newline at end of file diff --git a/conf/application.conf b/conf/application.conf index 78b15d67..ad8b6232 100644 --- a/conf/application.conf +++ b/conf/application.conf @@ -14,12 +14,13 @@ mongo-async-driver { slick.dbs.default.driver = "slick.driver.MySQLDriver$" slick.dbs.default.db.driver = "com.mysql.jdbc.Driver" -slick.dbs.default.db.url = "jdbc:mysql://172.2.1.2/drops" -#slick.dbs.default.db.user = "root" -#slick.dbs.default.db.password = "admin" -#slick.dbs.default.db.url = "jdbc:mysql://localhost:3306/drops" -slick.dbs.default.db.user = "drops" +#slick.dbs.default.db.url = "jdbc:mysql://172.2.1.2/drops" +slick.dbs.default.db.user = "root" slick.dbs.default.db.password = "drops" +slick.dbs.default.db.url = "jdbc:mysql://172.2.200.1:3306/drops?autoReconnect=true&useUnicode=yes&characterEncoding=UTF-8" +slick.dbs.default.db.connectionTimeout = 30s +#slick.dbs.default.db.user = "drops" +#slick.dbs.default.db.password = "drops" play.evolutions.enabled = true play.evolutions.db.default.autoApply = true diff --git a/conf/evolutions/default/42.sql b/conf/evolutions/default/42.sql new file mode 100644 index 00000000..6ea5cac4 --- /dev/null +++ b/conf/evolutions/default/42.sql @@ -0,0 +1,7 @@ +# --- !Ups +ALTER TABLE Address + MODIFY public_id BINARY(16); + +# --- !Downs +ALTER TABLE Address + MODIFY public_id VARCHAR(36); \ No newline at end of file