--- 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))
}
}