~ migrating to RDB.Relation
authorEric Prud'hommeaux <eric@w3.org>
Fri, 15 Oct 2010 13:44:06 -0400
changeset 235 012a9d4711ac
parent 234 84e78c96a219
child 236 ab7e05cec247
~ migrating to RDB.Relation
+ RDB.ForeignKeys
src/main/scala/SQL.scala
src/test/scala/SQLTest.scala
--- a/src/main/scala/SQL.scala	Fri Oct 15 12:21:49 2010 -0400
+++ b/src/main/scala/SQL.scala	Fri Oct 15 13:44:06 2010 -0400
@@ -265,7 +265,7 @@
     DatabaseDesc(rs.map{r => (r.name -> r)}.toMap)
 }
 // case class Relation (name:RDB.RelName, header:RDB.Header, body:List[RDB.Tuple], candidates:List[RDB.CandidateKey], pk:Option[RDB.CandidateKey], fks:RDB.ForeignKeys)
-case class RelationDesc(name:RDB.RelName, attributes:Map[RDB.AttrName, ValueDescription], body:List[RDB.Tuple], candidates:List[RDB.CandidateKey], pk:Option[RDB.CandidateKey])
+case class RelationDesc(name:RDB.RelName, attributes:Map[RDB.AttrName, ValueDescription], body:List[RDB.Tuple], candidates:List[RDB.CandidateKey], pk:Option[RDB.CandidateKey], fks:RDB.ForeignKeys)
 sealed abstract class FieldDescOrKeyDeclaration
 case class FieldDesc(attr:RDB.AttrName, value:Value, pkness:Boolean) extends FieldDescOrKeyDeclaration
 sealed abstract class KeyDeclaration extends FieldDescOrKeyDeclaration
@@ -297,26 +297,27 @@
       val pk0:Option[RDB.CandidateKey] = None
       val attrs0 = Map[RDB.AttrName, ValueDescription]()
       val candidates0 = List[RDB.CandidateKey]()
-      val fks0 = Map[List[RDB.AttrName], ForeignKey]()
+      val oldfks0 = Map[List[RDB.AttrName], ForeignKey]()
+      val fks0 = Map[List[RDB.AttrName], RDB.Target]()
       /* <pk>: (most recently parsed) PRIMARY KEY
        * <attrs>: map of attribute to type (e.g. INTEGER)
-       * <fks>: map holding FOREIGN KEY relation REFERENCES attr
+       * <oldfks>: map holding FOREIGN KEY relation REFERENCES attr
        */
-      val (pk, attrs, candidates, fks) =
-	reldesc.foldLeft((pk0, attrs0, candidates0, fks0))((p, rd) => {
-	  val (pkopt, attrs, candidates, fks) = p
+      val (pk, attrs, candidates, oldfks, fks) =
+	reldesc.foldLeft((pk0, attrs0, candidates0, oldfks0, fks0))((p, rd) => {
+	  val (pkopt, attrs, candidates, oldfks, fks) = p
 	  rd match {
 	    case FieldDesc(attr, value, pkness) => {
 	      val (pkNew, candNew) =
 		if (pkness) (Some(RDB.CandidateKey(List(attr))), candidates ++ List(RDB.CandidateKey(attr.n)))
 		else (pkopt, candidates)
-	      (pkNew, attrs + (attr -> value), candNew, fks)
+	      (pkNew, attrs + (attr -> value), candNew, oldfks, fks)
 	    }
 	    case PrimaryKeyDeclaration(key) =>
 	      // @@ why doesn't [[ candidates + RDB.CandidateKey(attr.n) ]] work?
-	      (Some(key), attrs, candidates ++ List(RDB.CandidateKey(key map {attr => RDB.AttrName(attr.n)})), fks)
+	      (Some(key), attrs, candidates ++ List(RDB.CandidateKey(key map {attr => RDB.AttrName(attr.n)})), oldfks, fks)
 	    case ForeignKeyDeclaration(fk, rel, pk) =>
-	      (pkopt, attrs, candidates, fks + (fk -> ForeignKey(rel, pk)))
+	      (pkopt, attrs, candidates, oldfks + (fk -> ForeignKey(rel, pk)), fks + (fk -> RDB.Target(rel, pk)))
 	  }
 	})
       /* Change data type of foreign key attributes to ForeignKey.
@@ -325,10 +326,10 @@
       val attrs2 = attrs.map(x => {
 	val (attr:RDB.AttrName, value:Value) = x
 	val asKey = RDB.CandidateKey(List(attr))
-	if (fks.contains(asKey)) (attr -> fks(asKey))
+	if (oldfks.contains(asKey)) (attr -> oldfks(asKey))
 	else (attr -> value)
       })
-      val rd = RelationDesc(relation, attrs2, List(), candidates, pk)
+      val rd = RelationDesc(relation, attrs2, List(), candidates, pk, RDB.ForeignKeys(fks))
       (relation -> rd)
     }
   }
--- a/src/test/scala/SQLTest.scala	Fri Oct 15 12:21:49 2010 -0400
+++ b/src/test/scala/SQLTest.scala	Fri Oct 15 13:44:06 2010 -0400
@@ -7,6 +7,7 @@
 class SQLTest extends FunSuite {
 
   implicit def string2relName (n:String) = RDB.RelName(n)
+  // implicit def string2attrName (n:String) = RDB.AttrName(n)
 
   test("parse ANDexpression") {
     // AliasedResource(Relation(Name("Employee")),RelVar(Name("R_emp")))
@@ -436,7 +437,8 @@
 		   Map(RDB.AttrName("ID") -> Value(Datatype.INTEGER)),
 		   List(),
 		   List(RDB.CandidateKey("ID")),
-		   Option(RDB.CandidateKey("ID"))))
+		   Option(RDB.CandidateKey("ID")),
+		   RDB.ForeignKeys()))
       assert(expected === (a.parseAll(a.ddl, e).get))
   }
 
@@ -452,7 +454,8 @@
 		       RDB.AttrName("EnterpriseEntryID") -> Value(Datatype.INTEGER)),
 		   List(),
 		   List(RDB.CandidateKey("ID")),
-		   Option(RDB.CandidateKey("ID"))))
+		   Option(RDB.CandidateKey("ID")),
+		   RDB.ForeignKeys()))
 
     assert(expected === (a.parseAll(a.ddl, e).get))
   }
@@ -468,7 +471,8 @@
 		       RDB.AttrName("EnterpriseEntryID") -> Value(Datatype.INTEGER)),
 		   List(),
 		   List(RDB.CandidateKey("ID")),
-		   Option(RDB.CandidateKey("ID"))))
+		   Option(RDB.CandidateKey("ID")),
+		   RDB.ForeignKeys()))
 
     assert(expected === (a.parseAll(a.ddl, e).get))
   }
@@ -487,13 +491,15 @@
 		       RDB.AttrName("SexDE") -> ForeignKey(RDB.RelName("Sex_DE"), RDB.CandidateKey("ID"))),
 		   List(),
 		   List(RDB.CandidateKey("ID")),
-		   Option(RDB.CandidateKey("ID"))),
+		   Option(RDB.CandidateKey("ID")),
+		   RDB.ForeignKeys(List("SexDE") -> RDB.Target("Sex_DE", RDB.CandidateKey("ID")))),
       RelationDesc("Sex_DE",
 		   Map(RDB.AttrName("ID") -> Value(Datatype.INTEGER),
 		       RDB.AttrName("EntryName") -> Value(Datatype.STRING)),
 		   List(),
 		   List(RDB.CandidateKey("ID")),
-		   Option(RDB.CandidateKey("ID")))
+		   Option(RDB.CandidateKey("ID")),
+		   RDB.ForeignKeys())
     )
     assert(expected === (a.parseAll(a.ddl, e).get))
   }
@@ -508,50 +514,57 @@
 CREATE TABLE Medication_DE (ID INT PRIMARY KEY, NDC INT);
 CREATE TABLE NDCcodes (ID INT PRIMARY KEY, NDC INT, ingredient INT);
 """
-  val expected:DatabaseDesc = DatabaseDesc(
-    RelationDesc("Person",
-		 Map(RDB.AttrName("ID") -> Value(Datatype.INTEGER),
-		     RDB.AttrName("MiddleName") -> Value(Datatype.STRING),
-		     RDB.AttrName("DateOfBirth") -> Value(Datatype.DATE),
-		     RDB.AttrName("SexDE") -> ForeignKey(RDB.RelName("Sex_DE"), RDB.CandidateKey("ID"))),
-		 List(),
-		 List(RDB.CandidateKey("ID")),
-		 Option(RDB.CandidateKey("ID"))),
-    RelationDesc("Sex_DE",
-		 Map(RDB.AttrName("ID") -> Value(Datatype.INTEGER),
-		     RDB.AttrName("EntryName") -> Value(Datatype.STRING)),
-		 List(),
-		 List(RDB.CandidateKey("ID")),
-		 Option(RDB.CandidateKey("ID"))),
-    RelationDesc("Item_Medication",
-		 Map(RDB.AttrName("ID") -> Value(Datatype.INTEGER),
-		     RDB.AttrName("PatientID") -> ForeignKey(RDB.RelName("Person"), RDB.CandidateKey("ID")),
-		     RDB.AttrName("PerformedDTTM") -> Value(Datatype.DATE),
-		     RDB.AttrName("EntryName") -> Value(Datatype.STRING)),
-		 List(),
-		 List(RDB.CandidateKey("ID")),
-		 Option(RDB.CandidateKey("ID"))),
-    RelationDesc("Medication",
-		 Map(RDB.AttrName("ID") -> Value(Datatype.INTEGER),
-		     RDB.AttrName("ItemID") -> ForeignKey(RDB.RelName("Item_Medication"), RDB.CandidateKey("ID")),
-		     RDB.AttrName("MedDictDE") -> ForeignKey(RDB.RelName("Medication_DE"), RDB.CandidateKey("ID"))),
-		 List(),
-		 List(RDB.CandidateKey("ID")),
-		 Option(RDB.CandidateKey("ID"))),
-    RelationDesc("Medication_DE",
-		 Map(RDB.AttrName("ID") -> Value(Datatype.INTEGER),
-		     RDB.AttrName("NDC") -> Value(Datatype.INTEGER)),
-		 List(),
-		 List(RDB.CandidateKey("ID")),
-		 Option(RDB.CandidateKey("ID"))),
-    RelationDesc("NDCcodes",
-		 Map(RDB.AttrName("ID") -> Value(Datatype.INTEGER),
-		     RDB.AttrName("NDC") -> Value(Datatype.INTEGER),
-		     RDB.AttrName("ingredient") -> Value(Datatype.INTEGER)),
-		 List(),
-		 List(RDB.CandidateKey("ID")),
-		 Option(RDB.CandidateKey("ID")))
-  )
+    val expected:DatabaseDesc = DatabaseDesc(
+      RelationDesc("Person",
+		   Map(RDB.AttrName("ID") -> Value(Datatype.INTEGER),
+		       RDB.AttrName("MiddleName") -> Value(Datatype.STRING),
+		       RDB.AttrName("DateOfBirth") -> Value(Datatype.DATE),
+		       RDB.AttrName("SexDE") -> ForeignKey(RDB.RelName("Sex_DE"), RDB.CandidateKey("ID"))),
+		   List(),
+		   List(RDB.CandidateKey("ID")),
+		   Option(RDB.CandidateKey("ID")),
+		   RDB.ForeignKeys(List("SexDE") -> RDB.Target("Sex_DE", RDB.CandidateKey("ID")))),
+      RelationDesc("Sex_DE",
+		   Map(RDB.AttrName("ID") -> Value(Datatype.INTEGER),
+		       RDB.AttrName("EntryName") -> Value(Datatype.STRING)),
+		   List(),
+		   List(RDB.CandidateKey("ID")),
+		   Option(RDB.CandidateKey("ID")),
+		   RDB.ForeignKeys()),
+      RelationDesc("Item_Medication",
+		   Map(RDB.AttrName("ID") -> Value(Datatype.INTEGER),
+		       RDB.AttrName("PatientID") -> ForeignKey(RDB.RelName("Person"), RDB.CandidateKey("ID")),
+		       RDB.AttrName("PerformedDTTM") -> Value(Datatype.DATE),
+		       RDB.AttrName("EntryName") -> Value(Datatype.STRING)),
+		   List(),
+		   List(RDB.CandidateKey("ID")),
+		   Option(RDB.CandidateKey("ID")),
+		   RDB.ForeignKeys(List("PatientID") -> RDB.Target("Person", RDB.CandidateKey("ID")))),
+      RelationDesc("Medication",
+		   Map(RDB.AttrName("ID") -> Value(Datatype.INTEGER),
+		       RDB.AttrName("ItemID") -> ForeignKey(RDB.RelName("Item_Medication"), RDB.CandidateKey("ID")),
+		       RDB.AttrName("MedDictDE") -> ForeignKey(RDB.RelName("Medication_DE"), RDB.CandidateKey("ID"))),
+		   List(),
+		   List(RDB.CandidateKey("ID")),
+		   Option(RDB.CandidateKey("ID")),
+		   RDB.ForeignKeys(List("ItemID") -> RDB.Target("Item_Medication", RDB.CandidateKey("ID")),
+				   List("MedDictDE") -> RDB.Target("Medication_DE", RDB.CandidateKey("ID")))),
+      RelationDesc("Medication_DE",
+		   Map(RDB.AttrName("ID") -> Value(Datatype.INTEGER),
+		       RDB.AttrName("NDC") -> Value(Datatype.INTEGER)),
+		   List(),
+		   List(RDB.CandidateKey("ID")),
+		   Option(RDB.CandidateKey("ID")),
+		   RDB.ForeignKeys()),
+      RelationDesc("NDCcodes",
+		   Map(RDB.AttrName("ID") -> Value(Datatype.INTEGER),
+		       RDB.AttrName("NDC") -> Value(Datatype.INTEGER),
+		       RDB.AttrName("ingredient") -> Value(Datatype.INTEGER)),
+		   List(),
+		   List(RDB.CandidateKey("ID")),
+		   Option(RDB.CandidateKey("ID")),
+		   RDB.ForeignKeys())
+    )
     assert(expected === (a.parseAll(a.ddl, e).get))
   }