--- a/src/main/scala/SQL.scala Fri Oct 15 10:43:09 2010 -0400
+++ b/src/main/scala/SQL.scala Fri Oct 15 11:23:10 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], primarykey:Option[RDB.AttrName])
+case class RelationDesc(name:RDB.RelName, attributes:Map[RDB.AttrName, ValueDescription], body:List[RDB.Tuple], candidates:List[RDB.CandidateKey], pk:Option[RDB.AttrName])
sealed abstract class FieldDescOrKeyDeclaration
case class FieldDesc(attr:RDB.AttrName, value:Value, pkness:Boolean) extends FieldDescOrKeyDeclaration
sealed abstract class KeyDeclaration extends FieldDescOrKeyDeclaration
@@ -296,25 +296,27 @@
case "CREATE"~"TABLE"~relation~"("~reldesc~")" => {
val pk0:Option[RDB.AttrName] = None
val attrs0 = Map[RDB.AttrName, ValueDescription]()
+ val candidates0 = List[RDB.CandidateKey]()
val fks0 = Map[RDB.AttrName, ForeignKey]()
/* <pk>: (most recently parsed) PRIMARY KEY
* <attrs>: map of attribute to type (e.g. INTEGER)
* <fks>: map holding FOREIGN KEY relation REFERENCES attr
*/
- val (pk, attrs, fks) =
- reldesc.foldLeft((pk0, attrs0, fks0))((p, rd) => {
- val (pkopt, attrs, fks) = p
+ val (pk, attrs, candidates, fks) =
+ reldesc.foldLeft((pk0, attrs0, candidates0, fks0))((p, rd) => {
+ val (pkopt, attrs, candidates, fks) = p
rd match {
case FieldDesc(attr, value, pkness) => {
- val pkNew =
- if (pkness) Some(attr)
- else pkopt
- (pkNew, attrs + (attr -> value), fks)
+ val (pkNew, candNew) =
+ if (pkness) (Some(attr), candidates ++ List(RDB.CandidateKey(attr.n)))
+ else (pkopt, candidates)
+ (pkNew, attrs + (attr -> value), candNew, fks)
}
case PrimaryKeyDeclaration(attr) =>
- (Some(attr), attrs, fks)
+ // @@ why doesn't [[ candidates + RDB.CandidateKey(attr.n) ]] work?
+ (Some(attr), attrs, candidates ++ List(RDB.CandidateKey(attr.n)), fks)
case ForeignKeyDeclaration(fk, rel, pk) =>
- (pkopt, attrs, fks + (fk -> ForeignKey(rel, pk)))
+ (pkopt, attrs, candidates, fks + (fk -> ForeignKey(rel, pk)))
}
})
/* Change data type of foreign key attributes to ForeignKey.
@@ -325,7 +327,7 @@
if (fks.contains(attr)) (attr -> fks(attr))
else (attr -> value)
})
- val rd = RelationDesc(relation, attrs2, List(), List(), pk)
+ val rd = RelationDesc(relation, attrs2, List(), candidates, pk)
(relation -> rd)
}
}
--- a/src/main/scala/SparqlToSql.scala Fri Oct 15 10:43:09 2010 -0400
+++ b/src/main/scala/SparqlToSql.scala Fri Oct 15 11:23:10 2010 -0400
@@ -287,7 +287,7 @@
/**
* Bind optAttr to an SQL generator like RDFNoder(Employee,FullBinding(R_emp.empid))
*/
- val binding = reldesc.primarykey match {
+ val binding = reldesc.pk match {
/** <pre>varConstraint(R_emp, Some(empid), VarAssignable(?emp), Employee) -> RDFNoder(Employee,FullBinding(R_emp.empid))</pre> */
case Some(sql.RDB.AttrName(constrainMe.attribute.n)) => RDFNoder(rel, boundTo)
case _ => {
@@ -390,11 +390,11 @@
val state_postSubj = s match {
case sparql.TermUri(u) =>
/** additional constraint, e.g. R_empid18.empid=18. */
- uriConstraint(stateP, sql.RelVarAttr(relvar, db.relationdescs(rel).primarykey.get), parseObjectURI(u))
+ uriConstraint(stateP, sql.RelVarAttr(relvar, db.relationdescs(rel).pk.get), parseObjectURI(u))
case sparql.TermVar(v) =>
/** assignable binding for novel vars, new constraint for previously bound vars. */
try {
- varConstraint(stateP, relvar, db.relationdescs(rel).primarykey, sparql.VarAssignable(v), db, rel)
+ varConstraint(stateP, relvar, db.relationdescs(rel).pk, sparql.VarAssignable(v), db, rel)
} catch {
case e:java.util.NoSuchElementException =>
/** Tell user that the relation.attribute encoded in the subject was not found in the database description. */
@@ -403,7 +403,7 @@
case sparql.TermBNode(b) =>
/** assignable binding for novel bnodes, new constraint for previously bound bnodes. */
try {
- varConstraint(stateP, relvar, db.relationdescs(rel).primarykey, sparql.BNodeAssignable(b), db, rel)
+ varConstraint(stateP, relvar, db.relationdescs(rel).pk, sparql.BNodeAssignable(b), db, rel)
} catch {
case e:java.util.NoSuchElementException =>
throw new Exception("error processing { " + s + " " + p + " " + o + " } :db.relationdescs(" + rel + ") not found in " + db)
--- a/src/test/scala/SQLTest.scala Fri Oct 15 10:43:09 2010 -0400
+++ b/src/test/scala/SQLTest.scala Fri Oct 15 11:23:10 2010 -0400
@@ -435,7 +435,7 @@
RelationDesc("Sex_DE",
Map(RDB.AttrName("ID") -> Value(Datatype.INTEGER)),
List(),
- List(),
+ List(RDB.CandidateKey("ID")),
Option(RDB.AttrName("ID"))))
assert(expected === (a.parseAll(a.ddl, e).get))
}
@@ -451,7 +451,7 @@
Map(RDB.AttrName("ID") -> Value(Datatype.INTEGER),
RDB.AttrName("EnterpriseEntryID") -> Value(Datatype.INTEGER)),
List(),
- List(),
+ List(RDB.CandidateKey("ID")),
Option(RDB.AttrName("ID"))))
assert(expected === (a.parseAll(a.ddl, e).get))
@@ -467,7 +467,7 @@
Map(RDB.AttrName("ID") -> Value(Datatype.INTEGER),
RDB.AttrName("EnterpriseEntryID") -> Value(Datatype.INTEGER)),
List(),
- List(),
+ List(RDB.CandidateKey("ID")),
Option(RDB.AttrName("ID"))))
assert(expected === (a.parseAll(a.ddl, e).get))
@@ -476,7 +476,7 @@
test("foreign key") {
val a = Sql()
val e = """
- CREATE TABLE Person (ID INT PRIMARY KEY, MiddleName STRING, DateOfBirth DATE, SexDE INT, PRIMARY KEY (ID), FOREIGN KEY (SexDE) REFERENCES Sex_DE(ID));
+ CREATE TABLE Person (ID INT PRIMARY KEY, MiddleName STRING, DateOfBirth DATE, SexDE INT, FOREIGN KEY (SexDE) REFERENCES Sex_DE(ID));
CREATE TABLE Sex_DE (ID INT PRIMARY KEY, EntryName STRING)
"""
val expected:DatabaseDesc = DatabaseDesc(
@@ -486,13 +486,13 @@
RDB.AttrName("DateOfBirth") -> Value(Datatype.DATE),
RDB.AttrName("SexDE") -> ForeignKey(RDB.RelName("Sex_DE"), RDB.AttrName("ID"))),
List(),
- List(),
+ List(RDB.CandidateKey("ID")),
Option(RDB.AttrName("ID"))),
RelationDesc("Sex_DE",
Map(RDB.AttrName("ID") -> Value(Datatype.INTEGER),
RDB.AttrName("EntryName") -> Value(Datatype.STRING)),
List(),
- List(),
+ List(RDB.CandidateKey("ID")),
Option(RDB.AttrName("ID")))
)
assert(expected === (a.parseAll(a.ddl, e).get))
@@ -501,10 +501,10 @@
test("create db") {
val a = Sql()
val e = """
-CREATE TABLE Person (ID INT PRIMARY KEY, MiddleName STRING, DateOfBirth DATE, SexDE INT, PRIMARY KEY (ID), FOREIGN KEY (SexDE) REFERENCES Sex_DE(ID));
+CREATE TABLE Person (ID INT PRIMARY KEY, MiddleName STRING, DateOfBirth DATE, SexDE INT, FOREIGN KEY (SexDE) REFERENCES Sex_DE(ID));
CREATE TABLE Sex_DE (ID INT PRIMARY KEY, EntryName STRING);
-CREATE TABLE Item_Medication (ID INT PRIMARY KEY, PRIMARY KEY (ID), PatientID INT, FOREIGN KEY (PatientID) REFERENCES Person(ID), PerformedDTTM DATE, EntryName STRING);
-CREATE TABLE Medication (ID INT PRIMARY KEY, PRIMARY KEY (ID), ItemID INT, FOREIGN KEY (ItemID) REFERENCES Item_Medication(ID), MedDictDE INT, FOREIGN KEY (MedDictDE) REFERENCES Medication_DE(ID));
+CREATE TABLE Item_Medication (ID INT PRIMARY KEY, PatientID INT, FOREIGN KEY (PatientID) REFERENCES Person(ID), PerformedDTTM DATE, EntryName STRING);
+CREATE TABLE Medication (ID INT PRIMARY KEY, ItemID INT, FOREIGN KEY (ItemID) REFERENCES Item_Medication(ID), MedDictDE INT, FOREIGN KEY (MedDictDE) REFERENCES Medication_DE(ID));
CREATE TABLE Medication_DE (ID INT PRIMARY KEY, NDC INT);
CREATE TABLE NDCcodes (ID INT PRIMARY KEY, NDC INT, ingredient INT);
"""
@@ -515,13 +515,13 @@
RDB.AttrName("DateOfBirth") -> Value(Datatype.DATE),
RDB.AttrName("SexDE") -> ForeignKey(RDB.RelName("Sex_DE"), RDB.AttrName("ID"))),
List(),
- List(), // RDB.CandidateKey("ID")
+ List(RDB.CandidateKey("ID")),
Option(RDB.AttrName("ID"))),
RelationDesc("Sex_DE",
Map(RDB.AttrName("ID") -> Value(Datatype.INTEGER),
RDB.AttrName("EntryName") -> Value(Datatype.STRING)),
List(),
- List(),
+ List(RDB.CandidateKey("ID")),
Option(RDB.AttrName("ID"))),
RelationDesc("Item_Medication",
Map(RDB.AttrName("ID") -> Value(Datatype.INTEGER),
@@ -529,27 +529,27 @@
RDB.AttrName("PerformedDTTM") -> Value(Datatype.DATE),
RDB.AttrName("EntryName") -> Value(Datatype.STRING)),
List(),
- List(),
+ List(RDB.CandidateKey("ID")),
Option(RDB.AttrName("ID"))),
RelationDesc("Medication",
Map(RDB.AttrName("ID") -> Value(Datatype.INTEGER),
RDB.AttrName("ItemID") -> ForeignKey(RDB.RelName("Item_Medication"), RDB.AttrName("ID")),
RDB.AttrName("MedDictDE") -> ForeignKey(RDB.RelName("Medication_DE"), RDB.AttrName("ID"))),
List(),
- List(),
+ List(RDB.CandidateKey("ID")),
Option(RDB.AttrName("ID"))),
RelationDesc("Medication_DE",
Map(RDB.AttrName("ID") -> Value(Datatype.INTEGER),
RDB.AttrName("NDC") -> Value(Datatype.INTEGER)),
List(),
- List(),
+ List(RDB.CandidateKey("ID")),
Option(RDB.AttrName("ID"))),
RelationDesc("NDCcodes",
Map(RDB.AttrName("ID") -> Value(Datatype.INTEGER),
RDB.AttrName("NDC") -> Value(Datatype.INTEGER),
RDB.AttrName("ingredient") -> Value(Datatype.INTEGER)),
List(),
- List(),
+ List(RDB.CandidateKey("ID")),
Option(RDB.AttrName("ID")))
)
assert(expected === (a.parseAll(a.ddl, e).get))