Skip to content
This repository has been archived by the owner on Sep 2, 2022. It is now read-only.

Commit

Permalink
Merge pull request #1903 from graphcool/backwards-compatible-migratio…
Browse files Browse the repository at this point in the history
…n-steps-for-relations

Backwards compatible parsing of Relation Migration Steps
  • Loading branch information
mavilein authored Feb 15, 2018
2 parents a169c5d + 9a0d336 commit 557b235
Show file tree
Hide file tree
Showing 3 changed files with 153 additions and 5 deletions.
3 changes: 2 additions & 1 deletion server/build.sbt
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,8 @@ lazy val sharedModels = normalProject("shared-models")
.dependsOn(jsonUtils % "compile")
.settings(
libraryDependencies ++= Seq(
cuid
cuid,
scalaTest
) ++ joda
)

Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
package com.prisma.shared.models

import com.prisma.shared.models.OnDelete.OnDelete
import play.api.libs.functional.syntax._
import play.api.libs.json._

import scala.language.implicitConversions

object MigrationStepsJsonFormatter extends DefaultReads {
Expand Down Expand Up @@ -95,9 +96,44 @@ object MigrationStepsJsonFormatter extends DefaultReads {
implicit val deleteEnumFormat = Json.format[DeleteEnum]
implicit val updateEnumFormat = Json.format[UpdateEnum]

implicit val createRelationFormat = Json.format[CreateRelation]
implicit val deleteRelationFormat = Json.format[DeleteRelation]
implicit val updateRelationFormat = Json.format[UpdateRelation]
implicit val createRelationFormat: OFormat[CreateRelation] = {
val reads = (
(JsPath \ "name").read[String] and
readOneOf[String]("leftModelName", "modelAName") and
readOneOf[String]("rightModelName", "modelBName") and
(JsPath \ "modelAOnDelete").readWithDefault(OnDelete.SetNull) and
(JsPath \ "modelBOnDelete").readWithDefault(OnDelete.SetNull)
)(CreateRelation.apply _)

val writes = (
(JsPath \ "name").write[String] and
(JsPath \ "leftModelName").write[String] and
(JsPath \ "rightModelName").write[String] and
(JsPath \ "modelAOnDelete").write[OnDelete.Value] and
(JsPath \ "modelBOnDelete").write[OnDelete.Value]
)(unlift(CreateRelation.unapply))

OFormat(reads, writes)
}

implicit val deleteRelationFormat: OFormat[DeleteRelation] = {
val reads = (JsPath \ "name").read[String].map(DeleteRelation.apply)
val writes = OWrites[DeleteRelation](delete => Json.obj("name" -> delete.name))
OFormat(reads, writes)
}

implicit val updateRelationFormat: OFormat[UpdateRelation] = {
val format: OFormat[UpdateRelation] = (
(JsPath \ "name").format[String] and
(JsPath \ "newName").formatNullable[String] and
(JsPath \ "modelAId").formatNullable[String] and
(JsPath \ "modelBId").formatNullable[String] and
(JsPath \ "modelAOnDelete").formatNullable[OnDelete.Value] and
(JsPath \ "modelBOnDelete").formatNullable[OnDelete.Value]
)(UpdateRelation.apply, unlift(UpdateRelation.unapply))

format
}

implicit val migrationStepFormat: Format[MigrationStep] = new Format[MigrationStep] {
val discriminatorField = "discriminator"
Expand Down Expand Up @@ -152,4 +188,6 @@ object MigrationStepsJsonFormatter extends DefaultReads {
case JsDefined(json) => rds.reads(json).map(v => Some(Some(v)))
}
}

def readOneOf[T](field1: String, field2: String)(implicit reads: Reads[T]) = (JsPath \ field1).read[T].orElse((JsPath \ field2).read[T])
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,109 @@
package com.prisma.shared.models

import org.scalatest.{FlatSpec, Matchers}
import play.api.libs.json.Json

class MigrationStepsJsonFormatterSpec extends FlatSpec with Matchers {

import MigrationStepsJsonFormatter._

"CreateRelation" should "be readable in the format of January 2018" in {
val json = Json.parse("""
|{
| "name": "ListToTodo",
| "leftModelName": "List",
| "rightModelName": "Todo",
| "discriminator": "CreateRelation"
| }
""".stripMargin)

val create = json.as[CreateRelation]
create.name should equal("ListToTodo")
create.modelAName should equal("List")
create.modelBName should equal("Todo")
create.modelAOnDelete should equal(OnDelete.SetNull)
create.modelBOnDelete should equal(OnDelete.SetNull)
}

"CreateRelation" should "be readable in the format of February 2018" in {
val json = Json.parse("""
|{
| "name": "ListToTodo",
| "leftModelName": "List",
| "rightModelName": "Todo",
| "modelAOnDelete": "CASCADE",
| "modelBOnDelete": "SET_NULL",
| "discriminator": "CreateRelation"
| }
""".stripMargin)

val create = json.as[CreateRelation]
create.name should equal("ListToTodo")
create.modelAName should equal("List")
create.modelBName should equal("Todo")
create.modelAOnDelete should equal(OnDelete.Cascade)
create.modelBOnDelete should equal(OnDelete.SetNull)
}

"CreateRelation" should "be readable in the BROKEN format of February 2018" in {
val json = Json.parse("""
|{
| "name": "ListToTodo",
| "modelAName": "List",
| "modelBName": "Todo",
| "modelAOnDelete": "CASCADE",
| "modelBOnDelete": "SET_NULL",
| "discriminator": "CreateRelation"
| }
""".stripMargin)

val create = json.as[CreateRelation]
create.name should equal("ListToTodo")
create.modelAName should equal("List")
create.modelBName should equal("Todo")
create.modelAOnDelete should equal(OnDelete.Cascade)
create.modelBOnDelete should equal(OnDelete.SetNull)
}

"UpdateRelation" should "be readable in the format of January 2018" in {
val json = Json.parse("""
|{
| "name": "ListToTodo",
| "newName": "ListToTodoNew",
| "modelAId": "List",
| "modelBId": "Todo",
| "discriminator": "UpdateRelation"
| }
""".stripMargin)

val create = json.as[UpdateRelation]
create.name should equal("ListToTodo")
create.newName should equal(Some("ListToTodoNew"))
create.modelAId should equal(Some("List"))
create.modelBId should equal(Some("Todo"))
create.modelAOnDelete should equal(None)
create.modelBOnDelete should equal(None)
}

"UpdateRelation" should "be readable in the format of February 2018" in {
val json = Json.parse("""
|{
| "name": "ListToTodo",
| "newName": "ListToTodoNew",
| "modelAId": "List",
| "modelBId": "Todo",
| "modelAOnDelete": "CASCADE",
| "modelBOnDelete": "SET_NULL",
| "discriminator": "UpdateRelation"
| }
""".stripMargin)

val create = json.as[UpdateRelation]
create.name should equal("ListToTodo")
create.newName should equal(Some("ListToTodoNew"))
create.modelAId should equal(Some("List"))
create.modelBId should equal(Some("Todo"))
create.modelAOnDelete should equal(Some(OnDelete.Cascade))
create.modelBOnDelete should equal(Some(OnDelete.SetNull))
}
}

0 comments on commit 557b235

Please sign in to comment.