--- a/directmapping/src/main/scala/DirectMapping.scala Sat Feb 12 17:33:48 2011 -0500
+++ b/directmapping/src/main/scala/DirectMapping.scala Sat Feb 12 17:56:59 2011 -0500
@@ -10,6 +10,20 @@
trait DirectMapping {
+ // should be done by BNode
+ var NextBNode = 97
+ def freshbnode () : BNode = {
+ val ret = NextBNode
+ NextBNode = NextBNode + 1
+ BNode(ret.toChar.toString)
+ }
+
+ // equivalent to RelName -> CandidateKey -> List[CellValue] -> Node
+ type NodeMap = PartialFunction[RelName, KeyMap]
+
+ def dbToNodeMap(db:Database):NodeMap =
+ db.indexables map { rn => rn -> keyMapForRelation(db(rn)) } toMap
+
/**
* A KeyMap associates the candidate key and key values with the
* node for any tuple in a unique relation.
@@ -33,34 +47,16 @@
} }
}
val m = Map[CandidateKey, Map[List[CellValue], Node]]()
- val tuples = r.body map { t => rdfNodeForTuple(t, r) }
+ val tuples = r.body map { t => tupleToNodeIRI(t, r) }
tuples.foldLeft(m){ case (m, (pairs, node)) => ++(m, pairs, node) }
}
-
- type NodeMap = PartialFunction[RelName, KeyMap]
-
- def dbToNodeMap(db:Database):NodeMap = {
- val idxables = db.keySet filter { rn => db(rn).candidates nonEmpty }
- idxables map { rn => rn -> keyMapForRelation(db(rn)) } toMap
- }
/**
* The mapping functions implementing
* <http://www.w3.org/2001/sw/rdb2rdf/directGraph/>
*/
-
- def references (t:Tuple, r:Relation):Set[ForeignKey] = {
- val nulls:Set[AttrName] = t.nullAttributes
- val references = r.fks filter { case ForeignKey(as, _) => nulls & as.toSet isEmpty }
- references
- }
-
- def scalars (t:Tuple, r:Relation):Set[AttrName] = {
- val notNulls:Set[AttrName] = t.notNullAttributes
- notNulls filterNot { attrName => r.fks definesActuallyUnaryFK attrName }
- }
-
- def rdfNodeForTuple (t:Tuple, r:Relation) : (List[(CandidateKey, List[CellValue])], Node) = {
+
+ def tupleToNodeIRI (t:Tuple, r:Relation) : (List[(CandidateKey, List[CellValue])], Node) = {
val s:Node =
r.pk match {
case Some(pk) =>
@@ -105,17 +101,9 @@
ObjectNode(NodeIRI(IRI(UE(r)))))
refs ++ scals + triple
}
-
- // should be done by BNode
- var NextBNode = 97
- def freshbnode () : BNode = {
- val ret = NextBNode
- NextBNode = NextBNode + 1
- BNode(ret.toChar.toString)
- }
-
+
def lexicalValueSemantics (rn:RelName, s:Node, a:AttrName, h:Header, t:Tuple) : Option[Triple] = {
- val p = predicatemap (rn, new AttrList { val attrs = List(a) } )
+ val p = predicateSemantics (rn, new AttrList { val attrs = List(a) } )
val cellValue = t(a)
val datatype = h.datatype(a)
(cellValue, datatype) match {
@@ -132,7 +120,7 @@
}
def referenceSemantics (s:Node, fk:ForeignKey, r:Relation, t:Tuple, nodes:NodeMap) : Triple = {
- val p = predicatemap (r.name, fk)
+ val p = predicateSemantics (r.name, fk)
val ls:List[LexicalValue] = t.notNullLexvalues(fk)
val ForeignKey(as, Target(rel, key)) = fk
if (!(nodes isDefinedAt rel))
@@ -145,20 +133,9 @@
Triple(SubjectNode(s), PredicateIRI(p), o)
}
- // These invariants make nodemap and predicatemap functions prettier.
- def UE(s:String):String = s.replaceAll(" ", "+")
- def UE(rn:RelName):String = UE(rn.n)
- def UE(r:Relation):String = UE(r.name)
- def UE(a:AttrName):String = UE(a.n)
-
- def predicatemap (rn:RelName, as:AttrList) : IRI =
+ def predicateSemantics (rn:RelName, as:AttrList) : IRI =
IRI(UE(rn) + "#" + as.attrs.mkString("_"))
- def iri(rn:Relation, as:AttrList, ls:List[LexicalValue]):IRI = {
- val pairs:List[String] = as.attrs zip ls map { case (attrName, lexicalValue) => UE(attrName) + "." + UE(lexicalValue.s) }
- IRI(UE(rn) + "/" + pairs.mkString("_") + "#_")
- }
-
// TODO: aren't they already part of the RDF model?
def datatypeSemantics (d:Datatype) : IRI =
d match {
@@ -171,8 +148,17 @@
case Datatype.VARCHAR => IRI("http://www.w3.org/2001/XMLSchema#varchar")
case Datatype.STRING => IRI("http://www.w3.org/2001/XMLSchema#string")
}
+
+ // These invariants make nodemap and predicateSemantics functions prettier.
+ def UE(s:String):String = s.replaceAll(" ", "+")
+ def UE(rn:RelName):String = UE(rn.n)
+ def UE(r:Relation):String = UE(r.name)
+ def UE(a:AttrName):String = UE(a.n)
-
+ def iri(rn:Relation, as:AttrList, ls:List[LexicalValue]):IRI = {
+ val pairs:List[String] = as.attrs zip ls map { case (attrName, lexicalValue) => UE(attrName) + "." + UE(lexicalValue.s) }
+ IRI(UE(rn) + "/" + pairs.mkString("_") + "#_")
+ }
}
--- a/rdb/src/main/scala/RDB.scala Sat Feb 12 17:33:48 2011 -0500
+++ b/rdb/src/main/scala/RDB.scala Sat Feb 12 17:56:59 2011 -0500
@@ -8,6 +8,7 @@
case class Database (m:Map[RelName, Relation]) {
def apply (rn:RelName) = m(rn)
def keySet = m.keySet.toSet
+ def indexables = m collect { case (rn, r) if r.isIndexable => rn }
}
object Database {
def apply (l:Relation*):Database =
@@ -17,6 +18,7 @@
case class Relation (name:RelName, header:Header, body:List[Tuple], candidates:List[CandidateKey], pk:Option[CandidateKey], fks:ForeignKeys) {
// TODO: should be + instead of ++
def ++ (t:Tuple):Relation = this.copy(body = body :+ t)
+ def isIndexable:Boolean = candidates.nonEmpty
}
case class Header (m:Map[AttrName, Datatype]) {
@@ -116,4 +118,15 @@
override def toString = n
}
+ def references (t:Tuple, r:Relation):Set[ForeignKey] = {
+ val nulls:Set[AttrName] = t.nullAttributes
+ val references = r.fks filter { case ForeignKey(as, _) => nulls & as.toSet isEmpty }
+ references
+ }
+
+ def scalars (t:Tuple, r:Relation):Set[AttrName] = {
+ val notNulls:Set[AttrName] = t.notNullAttributes
+ notNulls filterNot { attrName => r.fks definesActuallyUnaryFK attrName }
+ }
+
}