~ renaming + function to dereference a fk no-hierarchy
authorAlexandre Bertails <bertails@w3.org>
Mon, 14 Feb 2011 14:38:46 -0500
branchno-hierarchy
changeset 345 57ecde6ce678
parent 344 e4918c0a0e71
child 346 eed565c0c0c2
~ renaming + function to dereference a fk
directmapping/src/main/scala/DirectMapping.scala
rdb/src/main/scala/RDB.scala
--- a/directmapping/src/main/scala/DirectMapping.scala	Mon Feb 14 14:13:53 2011 -0500
+++ b/directmapping/src/main/scala/DirectMapping.scala	Mon Feb 14 14:38:46 2011 -0500
@@ -86,7 +86,7 @@
      * * if no primary key: a fresh bnode
      */
     def tupleToNode (t:Tuple) : (List[(CandidateKey, List[CellValue])], Node) = {
-      val r:Relation = t.r
+      val r:Relation = t.relation
       val s:Node =
         r.pk match {
           case Some(pk) =>
@@ -116,7 +116,7 @@
       Graph(r.body flatMap { t => tupleSemantics(nodemap, t) })
   
     def tupleSemantics (nodemap:NodeMap, t:Tuple):Set[Triple] = {
-      val r:Relation = t.r
+      val r:Relation = t.relation
       val s:SubjectNode =
 	// look for the first candidate key if available
         r.candidates.headOption match {
@@ -145,18 +145,18 @@
      * a foreign key contribute to generating triples
      */
     def referenceSemantics (nodes:NodeMap, t:Tuple, fk:ForeignKey):(Predicate, Object) = {
-      val r:Relation = t.r
+      val r:Relation = t.relation
       val p = referencePredicateSemantics(r, fk)
       val cellvalues:List[CellValue] = t.cellvalues(fk)
       val ForeignKey(as, target@Target(_, key)) = fk
-      val rel = target.r
-      if (!(nodes isDefinedAt rel))
-        error("No referent relation \"" + rel + "\" to match " + r.name + t)
-      if (!(nodes(rel) isDefinedAt key))
-        error("Relation " + rel + " has no attributes (" + key + ") to match " + r.name + t)
-      if (!(nodes(rel)(key) isDefinedAt cellvalues))
-        error("Relation " + rel + "(" + key + ") has no values " + cellvalues + " to match " + r.name + t)
-      val o:Object = ObjectNode(nodes(rel)(key)(cellvalues))
+      val targetRelation = target.relation
+      if (!(nodes isDefinedAt targetRelation))
+        error("No referent relation \"" + targetRelation + "\" to match " + r.name + t)
+      if (!(nodes(targetRelation) isDefinedAt key))
+        error("Relation " + targetRelation + " has no attributes (" + key + ") to match " + r.name + t)
+      if (!(nodes(targetRelation)(key) isDefinedAt cellvalues))
+        error("Relation " + targetRelation + "(" + key + ") has no values " + cellvalues + " to match " + r.name + t)
+      val o:Object = ObjectNode(nodes(targetRelation)(key)(cellvalues))
        (PredicateIRI(p), o)
      }
 
@@ -164,7 +164,7 @@
      * a lexical value contribute to generating triples (only if it is not null)
      */
     def lexicalValueSemantics(t:Tuple, a:AttrName):Option[(Predicate, Object)] = {
-      val r:Relation = t.r
+      val r:Relation = t.relation
       // a is implicitly promoted to an AttrList
       val p = lexicalValuePredicateSemantics(r, a)
       val cellValue = t(a)
@@ -204,7 +204,7 @@
      * hence, the zip operation is safe as both list have the same size
      */
     def tupleToIRI(t:Tuple, pk:AttrList):IRI = {
-      val r:Relation = t.r
+      val r:Relation = t.relation
       val ls:List[LexicalValue] = t.lexvalues(pk)
       val pairs:List[String] = pk.attrs zip ls map { case (attrName, lexicalValue) => UE(attrName) + "." + UE(lexicalValue.s) }
       IRI(UE(r) + "/" + pairs.mkString("_") + "#_")
--- a/rdb/src/main/scala/RDB.scala	Mon Feb 14 14:13:53 2011 -0500
+++ b/rdb/src/main/scala/RDB.scala	Mon Feb 14 14:38:46 2011 -0500
@@ -46,7 +46,7 @@
     for {
       t <- body
     } {
-      t.relation = Some(this)
+      t._relation = Some(this)
     }
 
     /** adds a tuple in the body of the relation */
@@ -82,8 +82,8 @@
   case class Tuple (private val m:Map[AttrName, CellValue]) extends PartialFunction[AttrName, CellValue] {
 
     // hack for the tuple to know the relation it belongs to
-    var relation:Option[Relation] = None
-    lazy val r:Relation = relation.get
+    var _relation:Option[Relation] = None
+    lazy val relation:Relation = _relation.get
 
     def apply (a:AttrName) = m(a)
 
@@ -117,7 +117,7 @@
       val nullAttributes:Set[AttrName] =
 	m collect { case (attrName, cellValue) if cellValue == ␀ => attrName } toSet
 
-      r.fks filter { case ForeignKey(as, _) => nullAttributes & as.toSet isEmpty  }
+      relation.fks filter { case ForeignKey(as, _) => nullAttributes & as.toSet isEmpty  }
     }
 
     /**
@@ -128,8 +128,15 @@
       val notNullAttributes:Set[AttrName] =
 	m collect { case (attrName, cellValue) if cellValue != ␀ => attrName } toSet
 
-      notNullAttributes filterNot { attrName => r.fks definesActuallyUnaryFK attrName }
+      notNullAttributes filterNot { attrName => relation.fks definesActuallyUnaryFK attrName }
     }
+
+    def dereference(fk:ForeignKey):Option[Tuple] = {
+      val values = this.cellvalues(fk)
+      val targetRelation:Relation = fk.target.relation
+      targetRelation.body find { t => values == t.cellvalues(fk) }
+    }
+
   }
 
   object Tuple {
@@ -169,11 +176,11 @@
 
   case class ForeignKey(attrs:List[AttrName], target:Target) extends AttrList
 
-  case class Target(rel:RelName, key:CandidateKey) {
+  case class Target(rn:RelName, key:CandidateKey) {
     // hack: this field will be updated by the Database when it will be created
     // as the target is fully know at that moment
     var db:Option[Database] = None
-    lazy val r:Relation = db.get(rel)
+    lazy val relation:Relation = db.get(rn)
   }
 
   case class CandidateKey (attrs:List[AttrName]) extends AttrList