+ databasemap
authorEric Prud'hommeaux <eric@w3.org>
Thu, 03 Jun 2010 19:56:02 -0400
changeset 10 76e6d541cd7d
parent 9 98e06551a3c7
child 11 37a1a69e954f
+ databasemap
- Relation.name
src/main/scala/Main.scala
src/test/scala/Test.scala
--- a/src/main/scala/Main.scala	Thu Jun 03 19:31:14 2010 -0400
+++ b/src/main/scala/Main.scala	Thu Jun 03 19:56:02 2010 -0400
@@ -36,34 +36,38 @@
 // Relational structure
 object SQL {
 
-  case class Relation ( name:RelName, header:Header, body:Body )
+  case class Database( m:Map[RelName, Relation] )
+  case class Relation ( header:Header, body:Body )
   type Header = Map[AttrName, (LinkType, SQLDatatype)]
   type Body = Set[Tuple]
+
   abstract class CellValue
   case class LexicalValue (s:String) extends CellValue
   case class ☹ () extends CellValue
+
   type Tuple = Map[AttrName, CellValue]
+
   sealed abstract class LinkType
   case class Pk () extends LinkType
-  case class Fk(r:Relation, a:AttrName) extends LinkType
+  case class Fk( rn:RelName, a:AttrName ) extends LinkType
   case class NotLinked () extends LinkType
+
   sealed abstract class SQLDatatype
   case class SQLString () extends SQLDatatype
   case class SQLInt () extends SQLDatatype
+
   type RelName = String
   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 =  // Assume: one primary key.
+    h.find(x => x._2._1 == Pk()).get._1
   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 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 relname (r:Relation) : RelName = r.name
 
 }
 
@@ -78,24 +82,26 @@
   }
 
   // Mapping functions:
-  def relationmap (u:StemIRI, r:Relation) : RDFGraph
-  = body(r).flatMap(t => tuplemap(u, t, r))
+  def databasemap (u:StemIRI, db:Database) : RDFGraph =
+    db.m.flatMap(pair => relationmap(u, pair._1, pair._2)).toSet
 
-  def tuplemap (u:StemIRI, t:Tuple, r:Relation) : Set[Triple] = {
+  def relationmap (u:StemIRI, rn:RelName, r:Relation) : RDFGraph =
+    body(r).flatMap(t => tuplemap(u, rn, t, r))
+
+  def tuplemap (u:StemIRI, rn:RelName, t:Tuple, r:Relation) : Set[Triple] = {
     val h = header(r)
     val k = pk(h)
-    val s = nodemap(u, r, k, lexvalue(h, t, k).asInstanceOf[LexicalValue]) // Assume: no NULLs in primary key
-    h.keySet.flatMap(a => cellmap(u, r, a, s, t))
+    val s = nodemap(u, rn, k, lexvalue(h, t, k).asInstanceOf[LexicalValue]) // Assume: no NULLs in primary key
+    h.keySet.flatMap(a => cellmap(u, rn, h, a, s, t))
   }
 
-  def cellmap (u:StemIRI, r:Relation, a:AttrName, s:IRI, t:Tuple) : Option[Triple] = {
-    val h = header(r)
+  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, r, a)
+	val p = predicatemap (u, rn, a)
 	val o = linktype(h, a) match {
-  	  case Fk(r2, a2) => ObjectIRI(nodemap(u, r2, a2, l))
+  	  case Fk(rn2, a2) => ObjectIRI(nodemap(u, rn2, a2, l))
 	  case _ => ObjectLiteral(literalmap(l, sqlDatatype(h, a)))
 	}
 	Some(Triple(s, p, o))
@@ -103,11 +109,11 @@
     }
   }
 
-  def nodemap (u:StemIRI, r:Relation, a:AttrName, l:LexicalValue) : IRI =
-    u + ("/" + relname(r) + "/" + a + "." + l.s + "#_")
+  def nodemap (u:StemIRI, rn:RelName, a:AttrName, l:LexicalValue) : IRI =
+    u + ("/" + rn + "/" + a + "." + l.s + "#_")
 
-  def predicatemap (u:StemIRI, r:Relation, a:AttrName) : IRI =
-    u + ("/" + relname(r) + "#" + a)
+  def predicatemap (u:StemIRI, rn:RelName, a:AttrName) : IRI =
+    u + ("/" + rn + "#" + a)
 
   def XSD (d:SQLDatatype) : IRI =
     d match {
--- a/src/test/scala/Test.scala	Thu Jun 03 19:31:14 2010 -0400
+++ b/src/test/scala/Test.scala	Thu Jun 03 19:56:02 2010 -0400
@@ -9,24 +9,26 @@
 class Test extends FunSuite {
   test("2 People 1 Addresses") {
 
-    val addresses = Relation("Addresses",
-			     Map("ID" -> (Pk(), SQLInt()),
+    val addresses = Relation(Map("ID" -> (Pk(), SQLInt()),
 				 "city" -> (NotLinked(), SQLString()),
 				 "state" -> (NotLinked(), SQLString())),
 			     Set(Map("ID" -> LexicalValue("18"),
 				     "city" -> LexicalValue("Cambridge"),
 				     "state" -> LexicalValue("MA"))))
 
-    val people = Relation("People",
-			     Map("ID" -> (Pk(), SQLInt()),
-				 "fname" -> (NotLinked(), SQLString()),
-				 "addr" -> (Fk(addresses, "ID"), SQLInt())),
-			     Set(Map("ID" -> LexicalValue("7"),
-				     "fname" -> LexicalValue("Bob"),
-				     "addr" -> LexicalValue("18")),
-				 Map("ID" -> LexicalValue("8"),
-				     "fname" -> LexicalValue("Sue"),
-				     "addr" -> ☹())))
+    val people = Relation(Map("ID" -> (Pk(), SQLInt()),
+			      "fname" -> (NotLinked(), SQLString()),
+			      "addr" -> (Fk("Addresses", "ID"), SQLInt())),
+			  Set(Map("ID" -> LexicalValue("7"),
+				  "fname" -> LexicalValue("Bob"),
+				  "addr" -> LexicalValue("18")),
+			      Map("ID" -> LexicalValue("8"),
+				  "fname" -> LexicalValue("Sue"),
+				  "addr" -> ☹())))
+
+    val db = Database(Map("Addresses" -> addresses, 
+			  "People" -> people))
+
     val u = StemIRI("http://foo.example/DB")
     val expected:RDFGraph =
       Set(
@@ -40,7 +42,7 @@
 	Triple(IRI("http://foo.example/DB/Addresses/ID.18#_"),IRI("http://foo.example/DB/Addresses#city"),Literal("Cambridge",IRI("http://www.w3.org/2001/XMLSchema#string"))),
 	Triple(IRI("http://foo.example/DB/Addresses/ID.18#_"),IRI("http://foo.example/DB/Addresses#state"),Literal("MA",IRI("http://www.w3.org/2001/XMLSchema#string"))))
 
-    assert (expected === relationmap(u, people) ++ relationmap(u, addresses))
+    assert (expected === databasemap(u, db))
   }
 
 }