--- a/src/test/scala/Test.scala Sun Mar 21 17:53:03 2010 -0400
+++ b/src/test/scala/Test.scala Thu Apr 01 21:53:01 2010 -0400
@@ -1,10 +1,128 @@
import org.scalatest.FunSuite
+trait stemGraph {
+}
+
+
class Test extends FunSuite {
+ type RelName = String
+ case class Relation ( name:RelName, header:Header, body:Body )
+ sealed abstract class LinkType
+ case class Pk () extends LinkType
+ case class Fk(r:Relation, a:AttrName) extends LinkType
+ case class NotLinked () extends LinkType
+ type Header = Map[AttrName, (LinkType, SQLDatatype)]
+ type AttrName = String
+ sealed abstract class SQLDatatype
+ case class SQLString () extends SQLDatatype
+ case class SQLInt () extends SQLDatatype
+ type Tuple = Map[AttrName, Either[LexicalValue, ☹]]
+ type Body = Set[Tuple]
+ type LexicalValue = String
+ type IRI = String
+ type StemURI = IRI
+ type RDFLiteral = String
+ case class ☹ ()
+
+ // == funcs ==
+ def pk (h:Header) : AttrName
+ = h.filter(x => x._2._1 == Pk()).keysIterator.toList(0)
+ def header (r:Relation) : Header = r.header
+ def body (r:Relation) : Body = r.body
+
+ def lexvalue (h:Header, t:Tuple, a:AttrName) : Either[LexicalValue, ☹]
+ = t(a)
+ def sqlDatatype (h:Header, a:AttrName) : SQLDatatype = h(a)._2
+ def linktype (h:Header, a:AttrName) : LinkType = h(a)._1
+ def name (r:Relation) : RelName = r.name
+ def nodemap (u:StemURI, r:Relation, a:AttrName, l:LexicalValue) : IRI
+ = u + "/" + name(r) + "/" + a + "." + l + "#foo"
+ def predicatemap (u:StemURI, r:Relation, a:AttrName) : IRI
+ = u + "/" + name(r) + "#" + a
+ def XSD (d:SQLDatatype) : IRI =
+ d match {
+ case SQLString() => "<http://...#string>"
+ case SQLInt() => "<http://...#int>"
+ }
+ def literalmap (l:LexicalValue, d:SQLDatatype) : RDFLiteral
+ = "\"" + l + "\"^^" + XSD(d)
+
+ sealed abstract class RDFObject
+ case class IRIObject (i:IRI) extends RDFObject
+ case class LiteralObject (l:RDFLiteral) extends RDFObject
+
+ case class RDFTriple (s:IRI, p:IRI, o:RDFObject)
+ type RDFGraph = Set[RDFTriple]
+
+ def cellmap (u:StemURI, r:Relation, a:AttrName, s:IRI, t:Tuple) : Option[RDFTriple] = {
+ val h = header(r)
+ lexvalue(h, t, a) match {
+ case Right(☹()) => None
+ case Left(l:LexicalValue) => {
+ val p = predicatemap (u, r, a)
+ val o = linktype(h, a) match {
+ case Fk(r2, a2) => IRIObject(nodemap(u, r2, a2, l))
+ case _ => LiteralObject(literalmap(l, sqlDatatype(h, a)))
+ }
+ Some(RDFTriple(s, p, o))
+ }
+ }
+ }
+
+ def toSet[T](list: List[T]) = {
+ def traverse(list: List[T])(set: Set[T]): Set[T] = list match {
+ case hd :: tail => traverse(tail)(set + hd) // create a new Set, adding hd
+ case Nil => set
+ }
+
+ traverse(list)(Set[T]())
+ }
+
+ def tuplemap (u:StemURI, t:Tuple, r:Relation) : Set[RDFTriple] = {
+ val h = header(r)
+ val k = pk(h)
+ val s = nodemap(u, r, k, lexvalue(h, t, k).left.get) // assume no NULLs in primary key
+ h.keysIterator.toList.flatMap(a => cellmap(u, r, a, s, t)).toSet
+ }
+
+ def relationmap (u:StemURI, r:Relation) : RDFGraph
+ = body(r).flatMap(t => tuplemap(u, t, r))
+
test("") {
+ val addresses = Relation("Addresses",
+ Map("ID" -> (Pk(), SQLInt()),
+ "city" -> (NotLinked(), SQLString()),
+ "state" -> (NotLinked(), SQLString())),
+ Set(Map("ID" -> Left("18"),
+ "city" -> Left("Camrbidge"),
+ "state" -> Left("MA"))))
+ val people = Relation("People",
+ Map("ID" -> (Pk(), SQLInt()),
+ "fname" -> (NotLinked(), SQLString()),
+ "addr" -> (Fk(addresses, "ID"), SQLInt())),
+ Set(Map("ID" -> Left("7"),
+ "fname" -> Left("Bob"),
+ "addr" -> Left("18")),
+ Map("ID" -> Left("8"),
+ "fname" -> Left("Sue"),
+ "addr" -> Right(☹()))))
+ val u = "http://foo.example/DB"
+ val expected =
+ Set(
+ RDFTriple("http://foo.example/DB/People/ID.7#foo","http://foo.example/DB/People#ID",LiteralObject("\"7\"^^<http://...#int>")),
+ RDFTriple("http://foo.example/DB/People/ID.7#foo","http://foo.example/DB/People#fname",LiteralObject("\"Bob\"^^<http://...#string>")),
+ RDFTriple("http://foo.example/DB/People/ID.7#foo","http://foo.example/DB/People#addr",IRIObject("http://foo.example/DB/Addresses/ID.18#foo")),
+ RDFTriple("http://foo.example/DB/People/ID.8#foo","http://foo.example/DB/People#ID",LiteralObject("\"8\"^^<http://...#int>")),
+ RDFTriple("http://foo.example/DB/People/ID.8#foo","http://foo.example/DB/People#fname",LiteralObject("\"Sue\"^^<http://...#string>")),
+
+ RDFTriple("http://foo.example/DB/Addresses/ID.18#foo","http://foo.example/DB/Addresses#ID",LiteralObject("\"18\"^^<http://...#int>")),
+ RDFTriple("http://foo.example/DB/Addresses/ID.18#foo","http://foo.example/DB/Addresses#city",LiteralObject("\"Camrbidge\"^^<http://...#string>")),
+ RDFTriple("http://foo.example/DB/Addresses/ID.18#foo","http://foo.example/DB/Addresses#state",LiteralObject("\"MA\"^^<http://...#string>")))
+
+ assert (expected == relationmap(u, people) ++ relationmap(u, addresses))
}
}