~ moved keys from header to relation
authorEric Prud'hommeaux <eric@w3.org>
Mon, 27 Sep 2010 09:31:57 -0400
changeset 23 40b955a81d55
parent 22 06b795e0c753
child 24 31cf43fcd94b
~ moved keys from header to relation
src/main/scala/Main.scala
src/test/scala/Test.scala
--- a/src/main/scala/Main.scala	Mon Sep 27 08:30:16 2010 -0400
+++ b/src/main/scala/Main.scala	Mon Sep 27 09:31:57 2010 -0400
@@ -5,9 +5,9 @@
 // Relational structure
 object SQL {
 
-  case class Database( m:Map[RelName, Relation] )
-  case class Relation ( header:Header, body:Body )
-  case class Header (types:Map[AttrName, SQLDatatype], keys:List[CandidateKey], pk:CandidateKey, fks:ForeignKeys) {
+  case class Database(m:Map[RelName, Relation])
+  case class Relation (header:Header, body:Body, keys:List[CandidateKey], pk:CandidateKey, fks:ForeignKeys)
+  case class Header (types:Map[AttrName, SQLDatatype]) {
     def keySet () = types.keySet
   }
 
@@ -37,7 +37,7 @@
   type AttrName = String
 
   // Accessor functions:
-  def pk (h:Header) : List[AttrName] = h.pk
+  def pk (r:Relation) : List[AttrName] = r.pk
   def header (r:Relation) : Header = r.header
   def body (r:Relation) : Body = r.body
 
@@ -51,6 +51,12 @@
   type RDFGraph = Set[Triple]
   case class Triple (s:Subject, p:IRI, o:Object)
 
+  sealed abstract class Node // factor out IRIs and BNodes
+  case class NodeIRI(i:IRI) extends Node
+  implicit def iri2nodeiri(i:IRI):Node = NodeIRI(i)
+  case class NodeBNode(b:BNode) extends Node
+  implicit def bnode2nodebnode(b:BNode):Node = NodeBNode(b)
+
   sealed abstract class Subject
   case class SubjectNode(n:Node) extends Subject
   implicit def node2subjectnode(n:Node):Subject = SubjectNode(n)
@@ -68,12 +74,6 @@
   implicit def bnode2objectnode(b:BNode):Object = ObjectNode(b)
   case class ObjectLiteral (n:Literal) extends Object
 
-
-  sealed abstract class Node
-  case class NodeIRI(i:IRI) extends Node
-  implicit def iri2nodeiri(i:IRI):Node = NodeIRI(i)
-  case class NodeBNode(b:BNode) extends Node
-  implicit def bnode2nodebnode(b:BNode):Node = NodeBNode(b)
   case class IRI(iri:String)
   case class BNode(label:String)
 
@@ -104,7 +104,7 @@
 
   // Mapping functions:
   def databasemap (u:StemIRI, db:Database) : RDFGraph = {
-    val idxables:Set[RelName] = db.m.keySet.filter(rn => db.m(rn).header.keys.size > 0)
+    val idxables:Set[RelName] = db.m.keySet.filter(rn => db.m(rn).keys.size > 0)
     val nodes:NodeMap = idxables.map(rn => rn -> relation2subject(u, rn, db.m(rn))).toMap
     db.m.keySet.flatMap(rn => relationmap(u, rn, db.m(rn), nodes)).toSet
   }
@@ -190,9 +190,9 @@
 
   def tuple2subject (u:StemIRI, rn:RelName, t:Tuple, r:Relation) : (List[(CandidateKey, List[CellValue])], Node) = {
     val h = header(r)
-    val vs = pk(h).map(k => lexvalue(h, t, k).asInstanceOf[LexicalValue])
-    val s:Node = if (pk(h).length == 0) freshbnode() else nodemap(u, rn, pk(h), vs) // Assume: no NULLs in primary key
-    (h.keys.map(k => {
+    val vs = pk(r).map(k => lexvalue(h, t, k).asInstanceOf[LexicalValue])
+    val s:Node = if (pk(r).length == 0) freshbnode() else nodemap(u, rn, pk(r), vs) // Assume: no NULLs in primary key
+    (r.keys.map(k => {
       val values:List[CellValue] = k.map(a => t(a))
       (k, values)
     }), s)
@@ -203,11 +203,11 @@
 
   def tuplemap (u:StemIRI, rn:RelName, t:Tuple, r:Relation, nodes:NodeMap) : Set[Triple] = {
     val h = header(r)
-    val vs = pk(h).map(k => lexvalue(h, t, k).asInstanceOf[LexicalValue])
-    val s:Node = if (nodes.get(rn).isDefined) nodes(rn)(pk(h))(vs) else freshbnode()
+    val vs = pk(r).map(k => lexvalue(h, t, k).asInstanceOf[LexicalValue])
+    val s:Node = if (nodes.get(rn).isDefined) nodes(rn)(pk(r))(vs) else freshbnode()
 
     val allAttrs:Set[AttrName] = h.keySet
-    val allFKs:Set[List[AttrName]] = h.fks.keySet
+    val allFKs:Set[List[AttrName]] = r.fks.keySet
     val unaryFKs:Set[AttrName] = allFKs.flatMap(a => {
       if (a.length == 1) a else None
     })
@@ -217,10 +217,10 @@
       if (int.toList.length == 0) None else List(a)
     })
     val scalarlist = allAttrs -- unaryFKs -- nulllist /* -- h.pk */
-    val referencelist = h.fks.keySet -- nullFKs
+    val referencelist = r.fks.keySet -- nullFKs
 
     scalarlist.map(a => scalartriples(u, rn, s, a, h, t)) ++
-    referencelist.map(as => referencetriples(u, rn, s, as, h, t, nodes))
+    referencelist.map(as => referencetriples(u, rn, s, as, r, t, nodes))
 
   }
 
@@ -232,10 +232,10 @@
     val o = literalmap(l, sqlDatatype(h, a))
     Triple(s, p, o)
   }
-  def referencetriples (u:StemIRI, rn:RelName, s:Node, as:List[AttrName], h:Header, t:Tuple, nodes:NodeMap) : Triple = {
+  def referencetriples (u:StemIRI, rn:RelName, s:Node, as:List[AttrName], r:Relation, t:Tuple, nodes:NodeMap) : Triple = {
     val p = predicatemap (u, rn, as)
     val ls:List[LexicalValue] = as.map(a =>t(a).asInstanceOf[LexicalValue])
-    val target = h.fks(as)
+    val target = r.fks(as)
     val o999 = nodemap(u, target.rel, target.attrs, ls)
     val o:Object = nodes(target.rel)(target.attrs)(ls)
     Triple(s, p, o)
--- a/src/test/scala/Test.scala	Mon Sep 27 08:30:16 2010 -0400
+++ b/src/test/scala/Test.scala	Mon Sep 27 09:31:57 2010 -0400
@@ -12,26 +12,26 @@
 
     val addresses = Relation(Header(Map("ID" -> SQLInt(),
 					"city" -> SQLString(),
-					"state" -> SQLString()),
-				    List(List("ID")),
-				    List("ID"),
-				    Map()),
+					"state" -> SQLString())),
 			     Set(Map("ID" -> LexicalValue("18"),
 				     "city" -> LexicalValue("Cambridge"),
-				     "state" -> LexicalValue("MA"))))
+				     "state" -> LexicalValue("MA"))),
+			     List(List("ID")),
+			     List("ID"),
+			     Map())
 
     val people = Relation(Header(Map("ID" -> SQLInt(),
 				     "fname" -> SQLString(),
-				     "addr" -> SQLInt()),
-				 List(List("ID")),
-				 List("ID"),
-				 Map(List("addr") -> Target("Addresses", List("ID")))),
+				     "addr" -> SQLInt())),
 			  Set(Map("ID" -> LexicalValue("7"),
 				  "fname" -> LexicalValue("Bob"),
 				  "addr" -> LexicalValue("18")),
 			      Map("ID" -> LexicalValue("8"),
 				  "fname" -> LexicalValue("Sue"),
-				  "addr" -> ␀())))
+				  "addr" -> ␀())),
+			  List(List("ID")),
+			  List("ID"),
+			  Map(List("addr") -> Target("Addresses", List("ID"))))
 
     val db = Database(Map("Addresses" -> addresses, 
 			  "People" -> people))
@@ -56,23 +56,19 @@
 
     val addresses = Relation(Header(Map("ID" -> SQLInt(),
 					"city" -> SQLString(),
-					"state" -> SQLString()),
-				    List(List("ID")),
-				    List("ID"),
-				    Map()),
+					"state" -> SQLString())),
 			     Set(Map("ID" -> LexicalValue("18"),
 				     "city" -> LexicalValue("Cambridge"),
-				     "state" -> LexicalValue("MA"))))
+				     "state" -> LexicalValue("MA"))),
+			     List(List("ID")),
+			     List("ID"),
+			     Map())
 
     val people = Relation(Header(Map("ID" -> SQLInt(),
 				     "fname" -> SQLString(),
 				     "addr" -> SQLInt(),
 				     "deptName" -> SQLString(),
-				     "deptCity" -> SQLString()),
-				 List(List("ID")),
-				 List("ID"),
-				 Map(List("addr") -> Target("Addresses", List("ID")),
-				     List("deptName", "deptCity") -> Target("Department", List("name", "city")))),
+				     "deptCity" -> SQLString())),
 			  Set(Map("ID" -> LexicalValue("7"),
 				  "fname" -> LexicalValue("Bob"),
 				  "addr" -> LexicalValue("18"),
@@ -82,19 +78,23 @@
 				  "fname" -> LexicalValue("Sue"),
 				  "addr" -> ␀(),
 				  "deptName" -> ␀(),
-				  "deptCity" -> ␀())))
+				  "deptCity" -> ␀())),
+			  List(List("ID")),
+			  List("ID"),
+			  Map(List("addr") -> Target("Addresses", List("ID")),
+			      List("deptName", "deptCity") -> Target("Department", List("name", "city"))))
 
     val department = Relation(Header(Map("ID" -> SQLInt(),
 					"name" -> SQLString(),
 					"city" -> SQLString(),
-					"manager" -> SQLInt()),
-				    List(List("ID"), List("name", "city")),
-				    List("ID"),
-				    Map(List("manager") -> Target("People", List("ID")))),
+					"manager" -> SQLInt())),
 			     Set(Map("ID" -> LexicalValue("23"),
 				     "name" -> LexicalValue("accounting"),
 				     "city" -> LexicalValue("Cambridge"),
-				     "manager" -> LexicalValue("8"))))
+				     "manager" -> LexicalValue("8"))),
+			      List(List("ID"), List("name", "city")),
+			      List("ID"),
+			      Map(List("manager") -> Target("People", List("ID"))))
 
     val db = Database(Map("Addresses" -> addresses, 
 			  "People" -> people, 
@@ -128,17 +128,17 @@
   test("2 Employees") {
     val employees = Relation(Header(Map("ID" -> SQLInt(),
 					"fname" -> SQLString(),
-					"boss" -> SQLInt()),
-				    List(List("ID")),
-				    List("ID"),
-				    Map(List("boss") -> Target("Employees", List("ID")))),
+					"boss" -> SQLInt())),
 			     Set(Map("ID" -> LexicalValue("1"),
 				     "fname" -> LexicalValue("Alice"),
 				     "boss" -> ␀()),
 				 Map("ID" -> LexicalValue("2"),
 				     "fname" -> LexicalValue("Bob"),
 				     "boss" -> LexicalValue("1"))
-			       ))
+			       ),
+			     List(List("ID")),
+			     List("ID"),
+			     Map(List("boss") -> Target("Employees", List("ID"))))
     val db = Database(Map("Employees" -> employees))
     val g = databasemap(StemIRI("http://foo.example/DB"), db)