~ more documentation no-hierarchy
authorAlexandre Bertails <bertails@gmail.com>
Sun, 13 Feb 2011 00:29:29 -0500
branchno-hierarchy
changeset 339 44e6d81cb429
parent 338 bcff22b5561a
child 340 fd36781876e2
~ more documentation
directmapping/src/main/scala/DirectMapping.scala
rdb/src/main/scala/RDB.scala
--- a/directmapping/src/main/scala/DirectMapping.scala	Sat Feb 12 23:57:45 2011 -0500
+++ b/directmapping/src/main/scala/DirectMapping.scala	Sun Feb 13 00:29:29 2011 -0500
@@ -85,8 +85,8 @@
       val s:Node =
         r.pk match {
           case Some(pk) =>
-            /** Table has a primkary key. */	    
-            NodeIRI(iri(r, pk, t.lexvalues(pk)))
+            /** Table has a primkary key. */
+            NodeIRI(tupleToIRI(r, pk, t.lexvalues(pk)))
           case None =>
             /** Table has no primkary key (but has some candidate keys). */
             NodeBNode(freshbnode())
@@ -140,7 +140,7 @@
      * a foreign key contribute to generating triples
      */
     def referenceSemantics (r:Relation, nodes:NodeMap, t:Tuple, fk:ForeignKey):(Predicate, Object) = {
-      val p = predicateSemantics (r, fk)
+      val p = referencePredicateSemantics(r, fk)
       val cellvalues:List[CellValue] = t.cellvalues(fk)
       val ForeignKey(as, target@Target(_, key)) = fk
       val rel = target.r
@@ -159,7 +159,7 @@
      */
     def lexicalValueSemantics(r:Relation, t:Tuple, a:AttrName):Option[(Predicate, Object)] = {
       // a is implicitly promoted to an AttrList
-      val p = predicateSemantics(r, a)
+      val p = lexicalValuePredicateSemantics(r, a)
       val cellValue = t(a)
       val datatype = r.header(a)
       (cellValue, datatype)  match {
@@ -176,9 +176,31 @@
       
     }
 
-    def predicateSemantics (r:Relation, as:AttrList) : IRI =
+    /**
+     * the generated IRI has to be "parsable" for a reverse mapping
+     */
+    def lexicalValuePredicateSemantics(r:Relation, a:AttrName):IRI =
+      IRI(UE(r) + "#" + a)
+
+    /**
+     * the generated IRI has to be "parsable" for a reverse mapping
+     */
+    def referencePredicateSemantics(r:Relation, as:AttrList):IRI =
       IRI(UE(r) + "#" + as.attrs.mkString("_"))
 
+    /**
+     * the generated IRI has to be "parsable" for a reverse mapping
+     * this function must generate a different IRI for each tuple
+     * we know (not enforced by a type) that
+     * - as is actually a pk
+     * - the lexicalvalues are generated from pk
+     * hence, the zip operation is safe as both list have the same size
+     */
+    def tupleToIRI(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 {
@@ -197,11 +219,6 @@
     def UE(r:Relation):String = UE(r.name.n)
     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 23:57:45 2011 -0500
+++ b/rdb/src/main/scala/RDB.scala	Sun Feb 13 00:29:29 2011 -0500
@@ -84,7 +84,7 @@
      * returns all the lexical values corresponding to the given as
      * the order from the list is preserved
      * we assume the values are restricted to non null cells
-     * in particular, it's safe to call giving a primary key
+     * so it's safe to call only with a primary key
      */
     def lexvalues (as:AttrList /* forall a in as, a is in this Tuple */):List[LexicalValue] =
       as.attrs map {
@@ -94,9 +94,16 @@
         }
       }
 
+    /**
+     * returns all the lexical values corresponding to the given as
+     * the order from the list is preserved
+     */
     def cellvalues (as:AttrList /* forall a in as, a is in this Tuple */):List[CellValue] =
       as.attrs map { m(_) }
 
+    /**
+     * returns all foreign keys that have only not-null values in it
+     */
     def references(r:Relation):Set[ForeignKey] = {
       val nullAttributes:Set[AttrName] =
 	m collect { case (attrName, cellValue) if cellValue == ␀ => attrName } toSet
@@ -104,6 +111,10 @@
       r.fks filter { case ForeignKey(as, _) => nullAttributes & as.toSet isEmpty  }
     }
 
+    /**
+     * returns all the not null attribute names
+     * such that they don't also define a unary foreign key
+     */
     def scalars(r:Relation):Set[AttrName] = {
       val notNullAttributes:Set[AttrName] =
 	m collect { case (attrName, cellValue) if cellValue != ␀ => attrName } toSet
@@ -117,10 +128,17 @@
       Tuple(s map { case (name, cellValue) => (AttrName(name), cellValue) } toMap)
   }
 
+  /**
+   * a cell value has either a lexical value or the NULL value
+   */
   abstract class CellValue
   case class LexicalValue(s:String) extends CellValue
   case object ␀ extends CellValue
 
+  /**
+   * ForeignKeys abstracts a set of foreign keys
+   * the expected operation are available
+   */
   case class ForeignKeys (private val fks:Set[ForeignKey]) {
     def has(as:AttrList) = fks exists { _.attrs == as }
     def getFK(as:AttrList):ForeignKey = fks find { _.attrs == as } get
@@ -135,15 +153,23 @@
       ForeignKeys(fks map { case (keys, target) => ForeignKey(keys map { AttrName(_) }, target)} toSet)
   }
 
+  trait AttrList {
+    val attrs:List[AttrName]
+    /**
+     * by definition, a key is unary if it has only one attribute
+     */
+    def isUnary:Boolean = attrs.length == 1
+  }
+
   case class ForeignKey(attrs:List[AttrName], target:Target) extends AttrList
 
   case class Target(rel: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)
   }
 
-
-
   case class CandidateKey (attrs:List[AttrName]) extends AttrList
 
   object CandidateKey {
@@ -151,16 +177,6 @@
       CandidateKey(l map { AttrName(_) } toList)
   }
 
-  trait AttrList {
-    val attrs:List[AttrName]
-    def isUnary:Boolean = attrs.length == 1
-  }
-
-  object AttrList {
-    // it's always ok to automatically promote a single AttrName to an AttrList
-    implicit def promoteAttrsAsAttrList(a:AttrName) = new AttrList { val attrs = List[AttrName](a) }
-  }
-
   case class AttrName(n:String) {
     override def toString = n
   }
@@ -169,6 +185,7 @@
     override def toString = "/* " + name + " */"
   }
 
+  // TODO: use Enumeration so we can go through the datatypes?
   object Datatype {
     val CHAR = Datatype("Char")
     val VARCHAR = Datatype("Varchar")