--- 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))
}