--- a/src/main/scala/Main.scala Wed Sep 29 00:28:35 2010 -0400
+++ b/src/main/scala/Main.scala Wed Sep 29 00:47:43 2010 -0400
@@ -119,6 +119,8 @@
import RDF._
import SQL._
+ /** A KeyMap associates the candidate key and key values with the
+ * node for any tuple in a unique relation. */
case class KeyMap(m:Map[CandidateKey, Map[List[CellValue], Node]]) {
//def KeyMap() : KeyMap = KeyMap(Map[CandidateKey, Map[List[CellValue], Node]]())
def apply(i:CandidateKey) : Map[List[CellValue], Node] = m(i)
@@ -153,17 +155,17 @@
}
}
- // Transformation argument:
+ /** The direct mapping requires one parameter: the StemIRI */
case class StemIRI(stem:String) {
def +(path:String):IRI = IRI(stem + path)
}
- // Mapping functions:
- def databasemap (u:StemIRI, db:Database) : RDFGraph = {
- val nodes = NodeMap(db.idxables.map(rn => rn -> relation2KeyMap(u, rn, db(rn))).toMap)
- db.keySet.flatMap(rn => relationmap(u, rn, db(rn), nodes, db))
- }
+ /**
+ * The mapping functions implementing
+ * <http://www.w3.org/2001/sw/rdb2rdf/directGraph/>
+ */
+ /** The NodeMap-generating functions: */
def relation2KeyMap (u:StemIRI, rn:RelName, r:Relation) : KeyMap = {
val m = KeyMap(Map[CandidateKey, Map[List[CellValue], Node]]())
body(r).foldLeft(m)((m, t) => {
@@ -173,7 +175,6 @@
}
def rdfNodeForTuple (u:StemIRI, rn:RelName, t:Tuple, r:Relation) : (List[(CandidateKey, List[CellValue])], Node) = {
- val h = header(r)
val s:Node =
if (r.pk.isDefined) {
/** Table has a primkary key. */
@@ -188,42 +189,54 @@
}), s)
}
+ /** The triples-generating functions start with databasemap: */
+ def databasemap (u:StemIRI, db:Database) : RDFGraph = {
+ val nodes = NodeMap(db.idxables.map(rn => rn -> relation2KeyMap(u, rn, db(rn))).toMap)
+ db.keySet.flatMap(rn => relationmap(u, rn, db(rn), nodes, db))
+ }
+
def relationmap (u:StemIRI, rn:RelName, r:Relation, nodes:NodeMap, db:Database) : RDFGraph =
body(r).flatMap(t => tuplemap(u, rn, t, r, nodes, db))
def tuplemap (u:StemIRI, rn:RelName, 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
+ // 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)
+ } 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)
+ })
+
+ /** 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 s:Node =
- if (r.candidates.size > 0) { // which implies !nodes.get(rn).isDefined
- // Known to have at least one key, so take the first one.
- val k = r.candidates(0)
- // Assume: no NULLs in candidate key
- val vs = t.lexvaluesNoNulls(k)
- nodes.ultimateReferent(rn, k, vs, db)
- } else
- /** Table has no candidate keys. */
- freshbnode()
-
- 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 = 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)
- })
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, rn, s, a, h, t)) ++
+ /** ... and the reference (foreign key) triples. */
referencelist.map(as => referencetriples(u, rn, s, as, r, t, nodes))
}