~ alignment with <a href="http://www.w3.org/2001/sw/rdb2rdf/directGraph/">directGraph document</a>
authorEric Prud'hommeaux <eric@w3.org>
Wed, 29 Sep 2010 11:05:31 -0400
changeset 33 75cf39ef7d74
parent 32 67579e545028
child 34 7e65c7f1f9c8
~ alignment with <a href="http://www.w3.org/2001/sw/rdb2rdf/directGraph/">directGraph document</a>
src/main/scala/Main.scala
--- a/src/main/scala/Main.scala	Wed Sep 29 08:29:26 2010 -0400
+++ b/src/main/scala/Main.scala	Wed Sep 29 11:05:31 2010 -0400
@@ -169,12 +169,44 @@
    * <http://www.w3.org/2001/sw/rdb2rdf/directGraph/>
    */
 
+  def references (t:Tuple, r:Relation):Set[List[AttrName]] = {
+    val allFKs:Set[List[AttrName]] = r.fks.keySet
+    val nulllist:Set[AttrName] = t.nullAttributes(r.header)
+    val nullFKs:Set[List[AttrName]] = allFKs.flatMap(a => {
+      val int:Set[AttrName] = nulllist & a.toSet
+      if (int.toList.length == 0) None else List(a)
+    })
+
+    /** Check to see if r's primary key is a hierarchical key.
+     * http://www.w3.org/2001/sw/rdb2rdf/directGraph/#rule3 */
+    if (r.pk.isDefined && r.fks.contains(r.pk.get))
+      r.fks.keySet -- nullFKs - r.fks(r.pk.get).attrs
+    else
+      r.fks.keySet -- nullFKs
+  }
+
+  def scalars (t:Tuple, r:Relation):Set[AttrName] = {
+    val allAttrs:Set[AttrName] = r.header.keySet
+    val allFKs:Set[List[AttrName]] = r.fks.keySet
+    val unaryFKs:Set[AttrName] = allFKs.flatMap(a => {
+      if (a.length == 1) a else None
+    })
+    val nulllist:Set[AttrName] = t.nullAttributes(r.header)
+
+    /** Check to see if r's primary key is a hierarchical key.
+     * http://www.w3.org/2001/sw/rdb2rdf/directGraph/#rule3 */
+    if (r.pk.isDefined && r.fks.contains(r.pk.get))
+      allAttrs -- unaryFKs -- nulllist ++ r.fks(r.pk.get).attrs
+    else
+      allAttrs -- unaryFKs -- nulllist
+  }
+
   /** The NodeMap-generating functions: */
   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, t, r)
-      m ++ (s._1, s._2)
+      val (pairs, node) = rdfNodeForTuple(u, t, r)
+      m ++ (pairs, node)
     })
   }
 
@@ -204,10 +236,8 @@
     body(r).flatMap(t => directT(u, t, r, nodes, db))
 
   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(r.name).isDefined
+      if (r.candidates.size > 0) {
 	// Known to have at least one key, so take the first one.
 	val k = r.candidates(0)
 	val vs = t.lexvaluesNoNulls(k)
@@ -215,35 +245,12 @@
       } else
 	/** Table has no candidate keys. */
 	freshbnode()
-
-    /** Calculate some handy Sets and Lists of AttrNames. */
-    val allAttrs:Set[AttrName] = h.keySet
-    val allFKs:Set[List[AttrName]] = r.fks.keySet
-    val unaryFKs:Set[AttrName] = allFKs.flatMap(a => {
-      if (a.length == 1) a else None
-    })
-    val nulllist:Set[AttrName] = t.nullAttributes(h)
-    val nullFKs:Set[List[AttrName]] = allFKs.flatMap(a => {
-      val int:Set[AttrName] = nulllist & a.toSet
-      if (int.toList.length == 0) None else List(a)
-    })
+    directS(u, s, t, r, nodes, db)
+  }
 
-    /** Check to see if r's primary key is a hierarchical key.
-     * http://www.w3.org/2001/sw/rdb2rdf/directGraph/ */
-    val hierarchicalKey:CandidateKey =
-      if (r.pk.isDefined && r.fks.contains(r.pk.get))
-	r.fks(r.pk.get).attrs
-      else
-	List()
-
-    val scalarlist = allAttrs -- unaryFKs -- nulllist ++ hierarchicalKey
-    val referencelist = r.fks.keySet -- nullFKs - hierarchicalKey
-
-    /** The graph returned by this tuple includes the scalar triples ... */
-    scalarlist.map(a => scalartriples(u, r.name, s, a, h, t)) ++
-    /** ... and the reference (foreign key) triples. */
-    referencelist.map(as => referencetriples(u, s, as, r, t, nodes))
-
+  def directS (u:StemIRI, s:Node, t:Tuple, r:Relation, nodes:NodeMap, db:Database) : Set[Triple] = {
+    references(t, r).map(as => directN(u, s, as, r, t, nodes)) ++
+    scalars(t, r).map(a => directL(u, r.name, s, a, r.header, t))
   }
 
   var NextBNode = 97
@@ -253,13 +260,13 @@
     BNode(ret.toChar.toString)
   }
 
-  def scalartriples (u:StemIRI, rn:RelName, s:Node, a:AttrName, h:Header, t:Tuple) : Triple = {
+  def directL (u:StemIRI, rn:RelName, s:Node, a:AttrName, h:Header, t:Tuple) : Triple = {
     val p = predicatemap (u, rn, List(a))
     val l = t.lexvalue(a).get
     val o = literalmap(l, h.sqlDatatype(a))
     Triple(s, p, o)
   }
-  def referencetriples (u:StemIRI, s:Node, as:List[AttrName], r:Relation, t:Tuple, nodes:NodeMap) : Triple = {
+  def directN (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)