~ cleaned up relational model
authorEric Prud'hommeaux <eric@w3.org>
Fri, 04 Jun 2010 15:04:23 -0400
changeset 13 78cb04cb4b2f
parent 12 c77e2043f54e
child 14 fdc36e0b0a87
~ cleaned up relational model
src/main/scala/Main.scala
--- a/src/main/scala/Main.scala	Fri Jun 04 11:58:11 2010 -0400
+++ b/src/main/scala/Main.scala	Fri Jun 04 15:04:23 2010 -0400
@@ -38,12 +38,12 @@
 
   case class Database( m:Map[RelName, Relation] )
   case class Relation ( header:Header, body:Body, pk:PrimaryKey, fks:ForeignKeys )
-  case class Header (types:Map[AttrName, (LinkType, SQLDatatype)], pk:PrimaryKey, fks:ForeignKeys) {
-    def find (p:((AttrName, (LinkType, SQLDatatype))) ⇒ Boolean) = types.find(p)
+  case class Header (types:Map[AttrName, SQLDatatype], pk:PrimaryKey, fks:ForeignKeys) {
+    def find (p:((AttrName, SQLDatatype)) ⇒ Boolean) = types.find(p)
     def keySet () = types.keySet
     def apply (key:AttrName) = types(key)
   }
-  type Header999 = Map[AttrName, (LinkType, SQLDatatype)]
+  type Header999 = Map[AttrName, SQLDatatype]
   type Body = Set[Tuple]
   type PrimaryKey = List[AttrName]
   type ForeignKeys = Map[AttrName, Target]
@@ -68,14 +68,13 @@
   type AttrName = String
 
   // Accessor functions:
-  def pk (h:Header) : AttrName =  // Assume: one primary key.
-    h.find(x => x._2._1 == Pk()).get._1
+  def pk (h:Header) : AttrName = h.pk(0) // Assume: one primary key.
   def header (r:Relation) : Header = r.header
   def body (r:Relation) : Body = r.body
 
   def lexvalue (h:Header, t:Tuple, a:AttrName) : CellValue = t(a)
-  def sqlDatatype (h:Header, a:AttrName) : SQLDatatype = h(a)._2
-  def linktype (h:Header, a:AttrName) : LinkType = h(a)._1
+  def sqlDatatype (h:Header, a:AttrName) : SQLDatatype = h(a)
+  def linktype (h:Header, a:AttrName) : LinkType = error("not implemented") // h(a)._1
 
 }
 
@@ -101,8 +100,15 @@
     val k = pk(h)
     val s = nodemap(u, rn, k, lexvalue(h, t, k).asInstanceOf[LexicalValue]) // Assume: no NULLs in primary key
 
-    scalartriples(u, rn, s, scalars(h, nonnulls(h, t))) ++
-    referencetriples(u, rn, s, references(h, nonnulls(h, t)))
+    val nulllist = nulls(h, t)
+    val scalarlist = h.keySet -- h.pk -- h.fks.keySet -- nulllist
+    val referencelist = h.fks.keySet -- nulllist
+
+    // scalarlist.map(a => scalartriples2(u, rn, s, a, h, t)) ++
+    // referencelist.map(a => referencetriples2(u, rn, s, a, h, t))
+
+    // scalartriples(u, rn, s, scalars(h, nonnulls(h, t))) ++
+    // referencetriples(u, rn, s, references(h, nonnulls(h, t)))
 
     // scalars(h, nonnulls(h, t)).map{case(a, l, dt) => scalarmap(u, rn, a, l, dt, s)} ++
     // references(h, nonnulls(h, t)).map{case(a, l, fk) => referencemap(u, rn, a, l, fk, s)}
@@ -110,11 +116,57 @@
     // nonnullscalars(h, t).map{case(a, l, dt) => scalarmap(u, rn, a, l, dt, s)} ++
     // nonnullreferences(h, t).map{case(a, l, fk) => referencemap(u, rn, a, l, fk, s)}
 
-    // h.keySet.flatMap(a => cellmap(u, rn, h, a, s, t))
+    h.keySet.flatMap(a => cellmap(u, rn, h, a, s, t))
   }
 
 /* BEGIN different approaches { */
 
+  def scalartriples2 (u:StemIRI, rn:RelName, s:IRI, a:AttrName, h:Header, t:Tuple) : Triple = {
+    val p = predicatemap (u, rn, a)
+    val l = t(a).asInstanceOf[LexicalValue]
+    val o = ObjectLiteral(literalmap(l, sqlDatatype(h, a)))
+    Triple(s, p, o)
+  }
+  def referencetriples2 (u:StemIRI, rn:RelName, s:IRI, a:AttrName, h:Header, t:Tuple) : Triple = {
+    val p = predicatemap (u, rn, a)
+    val l = t(a).asInstanceOf[LexicalValue]
+    val target = h.fks(a)
+    val o = ObjectIRI(nodemap(u, target.rel, target.attr, l))
+    Triple(s, p, o)
+  }
+
+  def nulls (h:Header, t:Tuple) : Set[(AttrName)] = {
+    h.keySet.flatMap(a =>
+      lexvalue(h, t, a) match {
+	case ☹() => Some(a)
+	case _ => None
+      })
+  }
+
+  def nonnulls (h:Header, t:Tuple) : Set[(AttrName, LexicalValue)] = {
+    h.keySet.flatMap(a =>
+      lexvalue(h, t, a) match {
+	case ☹() => None
+	case l:LexicalValue => Some((a, l))
+      })
+  }
+
+  def scalars (h:Header, s:Set[(AttrName, LexicalValue)]) : Set[(AttrName, LexicalValue, SQLDatatype)] = {
+    s.flatMap{case(a, l) =>
+      linktype(h, a) match {
+	case Fk(rn2, a2) => None
+	case _ => Some((a, l, sqlDatatype(h, a)))
+      }}
+  }
+
+  def references (h:Header, s:Set[(AttrName, LexicalValue)]) : Set[(AttrName, LexicalValue, Fk)] = {
+    s.flatMap{case(a, l) =>
+      linktype(h, a) match {
+  	case fk:Fk => Some((a, l, fk))
+	case _ => None
+      }}
+  }
+
   def scalartriples (u:StemIRI, rn:RelName, s:IRI, objs:Set[(AttrName, LexicalValue, SQLDatatype)]) : Set[Triple] = {
     objs.map{
       case(a, l, dt) => {
@@ -147,37 +199,13 @@
     Triple(s, p, o)
   }
 
-  def nonnulls (h:Header, t:Tuple) : Set[(AttrName, LexicalValue)] = {
-    h.keySet.flatMap(a =>
-      lexvalue(h, t, a) match {
-	case ☹() => None
-	case l:LexicalValue => Some((a, l))
-      })
-  }
-
-  def scalars (h:Header, s:Set[(AttrName, LexicalValue)]) : Set[(AttrName, LexicalValue, SQLDatatype)] = {
-    s.flatMap{case(a, l) =>
-      linktype(h, a) match {
-	case Fk(rn2, a2) => None
-	case _ => Some((a, l, sqlDatatype(h, a)))
-      }}
-  }
-
-  def references (h:Header, s:Set[(AttrName, LexicalValue)]) : Set[(AttrName, LexicalValue, Fk)] = {
-    s.flatMap{case(a, l) =>
-      linktype(h, a) match {
-  	case fk:Fk => Some((a, l, fk))
-	case _ => None
-      }}
-  }
-
   def nonnullscalars (h:Header, t:Tuple) : Set[(AttrName, LexicalValue, SQLDatatype)] = {
     h.keySet.flatMap(a =>
       lexvalue(h, t, a) match {
 	case ☹() => None
 	case l:LexicalValue => {
-	  linktype(h, a) match {
-  	    case Fk(rn2, a2) => None
+	  h.fks.get(a) match {
+  	    case Some(_) => None
 	    case _ => Some((a, l, sqlDatatype(h, a)))
 	  }
 	}
@@ -189,24 +217,24 @@
       lexvalue(h, t, a) match {
       case ☹() => None
       case l:LexicalValue => {
-	linktype(h, a) match {
-  	  case fk:Fk => Some((a, l, fk))
+	h.fks.get(a) match {
+  	  case Some(target:Target) => Some((a, l, Fk(target.rel, target.attr)))
 	  case _ => None
 	}
       }
     })
   }
 
-/* } END different approaches */
+// /* } END different approaches */
 
   def cellmap (u:StemIRI, rn:RelName, h:Header, a:AttrName, s:IRI, t:Tuple) : Option[Triple] = {
     lexvalue(h, t, a) match {
       case ☹() => None
       case l:LexicalValue => {
 	val p = predicatemap (u, rn, a)
-	val o = linktype(h, a) match {
-  	  case Fk(rn2, a2) => ObjectIRI(nodemap(u, rn2, a2, l))
-	  case _ => ObjectLiteral(literalmap(l, sqlDatatype(h, a)))
+	val o = h.fks.get(a) match {
+  	  case Some(target:Target) => ObjectIRI(nodemap(u, target.rel, target.attr, l))
+	  case None => ObjectLiteral(literalmap(l, sqlDatatype(h, a)))
 	}
 	Some(Triple(s, p, o))
       }
@@ -230,4 +258,3 @@
   
 }
 
-