~ simplified prototypes
authorEric Prud'hommeaux <eric@w3.org>
Wed, 29 Sep 2010 08:29:26 -0400
changeset 32 67579e545028
parent 31 fb0c1ef531fa
child 33 75cf39ef7d74
~ simplified prototypes
src/main/scala/Main.scala
src/test/scala/Test.scala
--- a/src/main/scala/Main.scala	Wed Sep 29 08:05:11 2010 -0400
+++ b/src/main/scala/Main.scala	Wed Sep 29 08:29:26 2010 -0400
@@ -9,8 +9,10 @@
     def apply (rn:RelName) = m(rn)
     def keySet () = m.keySet
   }
+  implicit def l2db (rs:List[Relation]):Map[RelName, Relation] =
+    rs.map(r => (r.name -> r)).toMap
 
-  case class Relation (header:Header, body:Body, candidates:List[CandidateKey], pk:Option[CandidateKey], fks:ForeignKeys)
+  case class Relation (name:RelName, header:Header, body:Body, candidates:List[CandidateKey], pk:Option[CandidateKey], fks:ForeignKeys)
   case class Header (m:Map[AttrName, SQLDatatype]) {
     def apply (a:AttrName) = m(a)
     def keySet () = m.keySet
@@ -168,20 +170,20 @@
    */
 
   /** The NodeMap-generating functions: */
-  def relation2KeyMap (u:StemIRI, rn:RelName, r:Relation) : KeyMap = {
+  def relation2KeyMap (u:StemIRI, r:Relation) : KeyMap = {
     val m = KeyMap(Map[CandidateKey, Map[List[CellValue], Node]]())
     body(r).foldLeft(m)((m, t) => {
-      val s = rdfNodeForTuple(u, rn, t, r)
+      val s = rdfNodeForTuple(u, t, r)
       m ++ (s._1, s._2)
     })
   }
 
-  def rdfNodeForTuple (u:StemIRI, rn:RelName, t:Tuple, r:Relation) : (List[(CandidateKey, List[CellValue])], Node) = {
+  def rdfNodeForTuple (u:StemIRI, t:Tuple, r:Relation) : (List[(CandidateKey, List[CellValue])], Node) = {
     val s:Node =
       if (r.pk.isDefined) {
 	/** Table has a primkary key. */
 	val vs = t.lexvaluesNoNulls(r.pk.get)
-	nodemap(u, rn, r.pk.get, vs)
+	nodemap(u, r.name, r.pk.get, vs)
       } else
 	/** Table has no primkary key (but has some candidate keys). */
 	freshbnode()
@@ -194,22 +196,22 @@
   /** The triples-generating functions start with databasemap: */
   def directDB (u:StemIRI, db:Database) : RDFGraph = {
     val idxables = db.keySet filter { rn => !db(rn).candidates.isEmpty }
-    val nodeMap = idxables map {rn => rn -> relation2KeyMap(u, rn, db(rn))}
-    db.keySet.flatMap(rn => directR(u, rn, db(rn), nodeMap, db))
+    val nodeMap = idxables map {rn => rn -> relation2KeyMap(u, db(rn))}
+    db.keySet.flatMap(rn => directR(u, db(rn), nodeMap, db))
   }
 
-  def directR (u:StemIRI, rn:RelName, r:Relation, nodes:NodeMap, db:Database) : RDFGraph =
-    body(r).flatMap(t => tuplemap(u, rn, t, r, nodes, db))
+  def directR (u:StemIRI, r:Relation, nodes:NodeMap, db:Database) : RDFGraph =
+    body(r).flatMap(t => directT(u, t, r, nodes, db))
 
-  def tuplemap (u:StemIRI, rn:RelName, t:Tuple, r:Relation, nodes:NodeMap, db:Database) : Set[Triple] = {
+  def directT (u:StemIRI, t:Tuple, r:Relation, nodes:NodeMap, db:Database) : Set[Triple] = {
     val h = header(r)
 
     val s:Node =
-      if (r.candidates.size > 0) { // or nodes.get(rn).isDefined
+      if (r.candidates.size > 0) { // or nodes.get(r.name).isDefined
 	// Known to have at least one key, so take the first one.
 	val k = r.candidates(0)
 	val vs = t.lexvaluesNoNulls(k)
-	nodes.ultimateReferent(rn, k, vs, db)
+	nodes.ultimateReferent(r.name, k, vs, db)
       } else
 	/** Table has no candidate keys. */
 	freshbnode()
@@ -238,9 +240,9 @@
     val referencelist = r.fks.keySet -- nullFKs - hierarchicalKey
 
     /** The graph returned by this tuple includes the scalar triples ... */
-    scalarlist.map(a => scalartriples(u, rn, s, a, h, t)) ++
+    scalarlist.map(a => scalartriples(u, r.name, s, a, h, t)) ++
     /** ... and the reference (foreign key) triples. */
-    referencelist.map(as => referencetriples(u, rn, s, as, r, t, nodes))
+    referencelist.map(as => referencetriples(u, s, as, r, t, nodes))
 
   }
 
@@ -257,8 +259,8 @@
     val o = literalmap(l, h.sqlDatatype(a))
     Triple(s, p, o)
   }
-  def referencetriples (u:StemIRI, rn:RelName, s:Node, as:List[AttrName], r:Relation, t:Tuple, nodes:NodeMap) : Triple = {
-    val p = predicatemap (u, rn, as)
+  def referencetriples (u:StemIRI, s:Node, as:List[AttrName], r:Relation, t:Tuple, nodes:NodeMap) : Triple = {
+    val p = predicatemap (u, r.name, as)
     val ls:List[LexicalValue] = t.lexvaluesNoNulls(as)
     val target = r.fks(as)
     val o:Object = nodes(target.rel)(target.attrs)(ls)
--- a/src/test/scala/Test.scala	Wed Sep 29 08:05:11 2010 -0400
+++ b/src/test/scala/Test.scala	Wed Sep 29 08:29:26 2010 -0400
@@ -10,17 +10,19 @@
 
   test("2 People 1 Addresses") {
 
-    val addresses = Relation(Header(Map("ID" -> SQLInt(),
-					"city" -> SQLString(),
-					"state" -> SQLString())),
-			     Set(Map("ID" -> LexicalValue("18"),
-				     "city" -> LexicalValue("Cambridge"),
-				     "state" -> LexicalValue("MA"))),
-			     List(List("ID")),
-			     Some(List("ID")),
-			     Map())
+    val addrs = Relation("Addresses",
+			 Header(Map("ID" -> SQLInt(),
+				    "city" -> SQLString(),
+				    "state" -> SQLString())),
+			 Set(Map("ID" -> LexicalValue("18"),
+				 "city" -> LexicalValue("Cambridge"),
+				 "state" -> LexicalValue("MA"))),
+			 List(List("ID")),
+			 Some(List("ID")),
+			 Map())
 
-    val people = Relation(Header(Map("ID" -> SQLInt(),
+    val people = Relation("People",
+			  Header(Map("ID" -> SQLInt(),
 				     "fname" -> SQLString(),
 				     "addr" -> SQLInt())),
 			  Set(Map("ID" -> LexicalValue("7"),
@@ -33,8 +35,7 @@
 			  Some(List("ID")),
 			  Map(List("addr") -> Target("Addresses", List("ID"))))
 
-    val db = Database(Map("Addresses" -> addresses, 
-			  "People" -> people))
+    val db = Database(List(addrs, people))
     val g = directDB(StemIRI("http://foo.example/DB"), db)
 
     val expected:RDFGraph =
@@ -55,17 +56,19 @@
 
   test("2 People 1 Addresses 1 Department") {
 
-    val addresses = Relation(Header(Map("ID" -> SQLInt(),
-					"city" -> SQLString(),
-					"state" -> SQLString())),
-			     Set(Map("ID" -> LexicalValue("18"),
-				     "city" -> LexicalValue("Cambridge"),
-				     "state" -> LexicalValue("MA"))),
-			     List(List("ID")),
-			     Some(List("ID")),
-			     Map())
+    val addrs = Relation("Addresses",
+			 Header(Map("ID" -> SQLInt(),
+				    "city" -> SQLString(),
+				    "state" -> SQLString())),
+			 Set(Map("ID" -> LexicalValue("18"),
+				 "city" -> LexicalValue("Cambridge"),
+				 "state" -> LexicalValue("MA"))),
+			 List(List("ID")),
+			 Some(List("ID")),
+			 Map())
 
-    val people = Relation(Header(Map("ID" -> SQLInt(),
+    val people = Relation("People",
+			  Header(Map("ID" -> SQLInt(),
 				     "fname" -> SQLString(),
 				     "addr" -> SQLInt(),
 				     "deptName" -> SQLString(),
@@ -85,7 +88,8 @@
 			  Map(List("addr") -> Target("Addresses", List("ID")),
 			      List("deptName", "deptCity") -> Target("Department", List("name", "city"))))
 
-    val department = Relation(Header(Map("ID" -> SQLInt(),
+    val department = Relation("Department",
+			      Header(Map("ID" -> SQLInt(),
 					"name" -> SQLString(),
 					"city" -> SQLString(),
 					"manager" -> SQLInt())),
@@ -97,9 +101,7 @@
 			      Some(List("ID")),
 			      Map(List("manager") -> Target("People", List("ID"))))
 
-    val db = Database(Map("Addresses" -> addresses, 
-			  "People" -> people, 
-			  "Department" -> department))
+    val db = Database(List(addrs, people, department))
     val g = directDB(StemIRI("http://foo.example/DB"), db)
 
     val expected:RDFGraph =
@@ -129,17 +131,19 @@
 
   test("2 People 1 Addresses 1 Department 2 Projects 1 Task") {
 
-    val addresses = Relation(Header(Map("ID" -> SQLInt(),
-					"city" -> SQLString(),
-					"state" -> SQLString())),
-			     Set(Map("ID" -> LexicalValue("18"),
-				     "city" -> LexicalValue("Cambridge"),
-				     "state" -> LexicalValue("MA"))),
-			     List(List("ID")),
-			     Some(List("ID")),
-			     Map())
+    val addrs = Relation("Addresses",
+			 Header(Map("ID" -> SQLInt(),
+				    "city" -> SQLString(),
+				    "state" -> SQLString())),
+			 Set(Map("ID" -> LexicalValue("18"),
+				 "city" -> LexicalValue("Cambridge"),
+				 "state" -> LexicalValue("MA"))),
+			 List(List("ID")),
+			 Some(List("ID")),
+			 Map())
 
-    val people = Relation(Header(Map("ID" -> SQLInt(),
+    val people = Relation("People",
+			  Header(Map("ID" -> SQLInt(),
 				     "fname" -> SQLString(),
 				     "addr" -> SQLInt(),
 				     "deptName" -> SQLString(),
@@ -159,19 +163,21 @@
 			  Map(List("addr") -> Target("Addresses", List("ID")),
 			      List("deptName", "deptCity") -> Target("Department", List("name", "city"))))
 
-    val department = Relation(Header(Map("ID" -> SQLInt(),
+    val department = Relation("Department",
+			      Header(Map("ID" -> SQLInt(),
 					 "name" -> SQLString(),
 					 "city" -> SQLString(),
 					 "manager" -> SQLInt())),
 			      Set(Map("ID" -> LexicalValue("23"),
 				     "name" -> LexicalValue("accounting"),
 				     "city" -> LexicalValue("Cambridge"),
-				     "manager" -> LexicalValue("8"))), // no data
+				     "manager" -> LexicalValue("8"))),
 			      List(List("ID"), List("name", "city")),
 			      Some(List("ID")),
 			      Map(List("manager") -> Target("People", List("ID"))))
 
-    val projects = Relation(Header(Map("lead" -> SQLInt(),
+    val projects = Relation("Projects",
+			    Header(Map("lead" -> SQLInt(),
 				       "name" -> SQLString(),
 				       "deptName" -> SQLString(),
 				       "deptCity" -> SQLString())),
@@ -190,7 +196,8 @@
 			    Map(List("lead") -> Target("People", List("ID")),
 				List("deptName", "deptCity") -> Target("Department", List("name", "city"))))
 
-    val tasks = Relation(Header(Map("worker" -> SQLInt(),
+    val tasks = Relation("TaskAssignments",
+			 Header(Map("worker" -> SQLInt(),
 				    "project" -> SQLString(),
 				    "deptName" -> SQLString(),
 				    "deptCity" -> SQLString())),
@@ -204,11 +211,7 @@
 			     List("project", "deptName", "deptCity") -> Target("Projects", List("name", "deptName", "deptCity")),
 			     List("deptName", "deptCity") -> Target("Department", List("name", "city"))))
 
-    val db = Database(Map("Addresses" -> addresses, 
-			  "People" -> people, 
-			  "Department" -> department, 
-			  "Projects" -> projects, 
-			  "TaskAssignments" -> tasks))
+    val db = Database(List(addrs, people, department, projects, tasks))
     val g = directDB(StemIRI("http://foo.example/DB"), db)
 
     val expected:RDFGraph =
@@ -257,17 +260,19 @@
 
   test("1 People 1 Addresses 1 Offices") {
 
-    val addresses = Relation(Header(Map("ID" -> SQLInt(),
-					"city" -> SQLString(),
-					"state" -> SQLString())),
-			     Set(Map("ID" -> LexicalValue("18"),
-				     "city" -> LexicalValue("Cambridge"),
-				     "state" -> LexicalValue("MA"))),
-			     List(List("ID")),
-			     Some(List("ID")),
-			     Map())
+    val addrs = Relation("Addresses",
+			 Header(Map("ID" -> SQLInt(),
+				    "city" -> SQLString(),
+				    "state" -> SQLString())),
+			 Set(Map("ID" -> LexicalValue("18"),
+				 "city" -> LexicalValue("Cambridge"),
+				 "state" -> LexicalValue("MA"))),
+			 List(List("ID")),
+			 Some(List("ID")),
+			 Map())
 
-    val people = Relation(Header(Map("ID" -> SQLInt(),
+    val people = Relation("People",
+			  Header(Map("ID" -> SQLInt(),
 				     "fname" -> SQLString(),
 				     "addr" -> SQLInt())),
 			  Set(Map("ID" -> LexicalValue("7"),
@@ -277,7 +282,8 @@
 			  Some(List("ID")),
 			  Map(List("addr") -> Target("Addresses", List("ID"))))
 
-    val offices = Relation(Header(Map("ID" -> SQLInt(),
+    val offices = Relation("Offices",
+			   Header(Map("ID" -> SQLInt(),
 				      "building" -> SQLInt(),
 				      "ofcNumber" -> SQLString())),
 			     Set(Map("ID" -> LexicalValue("18"),
@@ -287,9 +293,7 @@
 			     Some(List("ID")),
 			     Map(List("ID") -> Target("Addresses", List("ID"))))
 
-    val db = Database(Map("Addresses" -> addresses, 
-			  "People" -> people, 
-			  "Offices" -> offices))
+    val db = Database(List(addrs, people, offices))
     val g = directDB(StemIRI("http://foo.example/DB"), db)
 
     val expected:RDFGraph =
@@ -312,17 +316,19 @@
 
   test("1 People 1 Addresses 1 Offices 1 ExectutiveOffices") {
 
-    val addresses = Relation(Header(Map("ID" -> SQLInt(),
-					"city" -> SQLString(),
-					"state" -> SQLString())),
-			     Set(Map("ID" -> LexicalValue("18"),
-				     "city" -> LexicalValue("Cambridge"),
-				     "state" -> LexicalValue("MA"))),
-			     List(List("ID")),
-			     Some(List("ID")),
-			     Map())
+    val addrs = Relation("Addresses",
+			 Header(Map("ID" -> SQLInt(),
+				    "city" -> SQLString(),
+				    "state" -> SQLString())),
+			 Set(Map("ID" -> LexicalValue("18"),
+				 "city" -> LexicalValue("Cambridge"),
+				 "state" -> LexicalValue("MA"))),
+			 List(List("ID")),
+			 Some(List("ID")),
+			 Map())
 
-    val people = Relation(Header(Map("ID" -> SQLInt(),
+    val people = Relation("People",
+			  Header(Map("ID" -> SQLInt(),
 				     "fname" -> SQLString(),
 				     "addr" -> SQLInt())),
 			  Set(Map("ID" -> LexicalValue("7"),
@@ -332,7 +338,8 @@
 			  Some(List("ID")),
 			  Map(List("addr") -> Target("Addresses", List("ID"))))
 
-    val offices = Relation(Header(Map("ID" -> SQLInt(),
+    val offices = Relation("Offices",
+			   Header(Map("ID" -> SQLInt(),
 				      "building" -> SQLInt(),
 				      "ofcNumber" -> SQLString())),
 			     Set(Map("ID" -> LexicalValue("18"),
@@ -342,7 +349,8 @@
 			     Some(List("ID")),
 			     Map(List("ID") -> Target("Addresses", List("ID"))))
 
-    val execoffices = Relation(Header(Map("ID" -> SQLInt(),
+    val execoffices = Relation("ExecutiveOffices",
+			       Header(Map("ID" -> SQLInt(),
 					  "desk" -> SQLString())),
 			       Set(Map("ID" -> LexicalValue("18"),
 				       "desk" -> LexicalValue("oak"))),
@@ -350,10 +358,7 @@
 			       Some(List("ID")),
 			       Map(List("ID") -> Target("Offices", List("ID"))))
 
-    val db = Database(Map("Addresses" -> addresses, 
-			  "People" -> people, 
-			  "Offices" -> offices, 
-			  "ExecutiveOffices" -> execoffices))
+    val db = Database(List(addrs, people, offices, execoffices))
     val g = directDB(StemIRI("http://foo.example/DB"), db)
 
     val expected:RDFGraph =
@@ -403,7 +408,8 @@
 
 
   test("2 Employees") {
-    val employees = Relation(Header(Map("ID" -> SQLInt(),
+    val employees = Relation("Employees",
+			     Header(Map("ID" -> SQLInt(),
 					"fname" -> SQLString(),
 					"boss" -> SQLInt())),
 			     Set(Map("ID" -> LexicalValue("1"),
@@ -416,7 +422,7 @@
 			     List(List("ID")),
 			     Some(List("ID")),
 			     Map(List("boss") -> Target("Employees", List("ID"))))
-    val db = Database(Map("Employees" -> employees))
+    val db = Database(List(employees))
     val g = directDB(StemIRI("http://foo.example/DB"), db)
 
     val expected:RDFGraph =