~ moved RDB specific functions out of the Direct Mapping no-hierarchy
authorAlexandre Bertails <bertails@gmail.com>
Sat, 12 Feb 2011 17:56:59 -0500
branchno-hierarchy
changeset 335 9a828553ea69
parent 334 f5fd76348339
child 336 8d846f38b2ca
~ moved RDB specific functions out of the Direct Mapping
directmapping/src/main/scala/DirectMapping.scala
rdb/src/main/scala/RDB.scala
--- 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 }
+  }
+
 }