--- a/src/main/scala/Main.scala Mon May 31 09:51:11 2010 -0400
+++ b/src/main/scala/Main.scala Tue Jun 01 11:39:49 2010 -0400
@@ -4,17 +4,21 @@
// RDF node types
object RDF {
- type RDFGraph = Set[RDFTriple]
- case class RDFTriple (s:IRI, p:IRI, o:RDFObject)
+ type RDFGraph = Set[Triple]
+ case class Triple (s:IRI, p:IRI, o:RDFObject)
sealed abstract class RDFObject
case class IRIObject (i:IRI) extends RDFObject
- case class LiteralObject (l:RDFLiteral) extends RDFObject
- type IRI = String
- type RDFLiteral = String
+ case class LiteralObject (l:Literal) extends RDFObject
+ case class IRI(iri:String)
+ case class Literal(value:String, datatype:IRI)
+
+ implicit def lit2object(l:Literal):RDFObject = LiteralObject(l)
+ implicit def iri2object(i:IRI):RDFObject = IRIObject(i)
}
// Relational structure
object SQL {
+
case class Relation ( name:RelName, header:Header, body:Body )
type Header = Map[AttrName, (LinkType, SQLDatatype)]
type Body = Set[Tuple]
@@ -52,20 +56,22 @@
import SQL._
// Transformation argument:
- type StemURI = RDF.IRI
+ case class StemIRI(stem:String) {
+ def +(path:String):IRI = IRI(stem + path)
+ }
// Mapping functions:
- def relationmap (u:StemURI, r:Relation) : RDFGraph
+ def relationmap (u:StemIRI, r:Relation) : RDFGraph
= body(r).flatMap(t => tuplemap(u, t, r))
- def tuplemap (u:StemURI, t:Tuple, r:Relation) : Set[RDFTriple] = {
+ def tuplemap (u:StemIRI, 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))
}
- def cellmap (u:StemURI, r:Relation, a:AttrName, s:IRI, t:Tuple) : Option[RDFTriple] = {
+ def cellmap (u:StemIRI, r:Relation, a:AttrName, s:IRI, t:Tuple) : Option[Triple] = {
val h = header(r)
lexvalue(h, t, a) match {
case ☹() => None
@@ -75,22 +81,25 @@
case Fk(r2, a2) => IRIObject(nodemap(u, r2, a2, l))
case _ => LiteralObject(literalmap(l, sqlDatatype(h, a)))
}
- Some(RDFTriple(s, p, o))
+ Some(Triple(s, p, o))
}
}
}
- def nodemap (u:StemURI, r:Relation, a:AttrName, l:LexicalValue) : IRI
- = "<" + u + "/" + relname(r) + "/" + a + "." + l.s + "#foo>"
- def predicatemap (u:StemURI, r:Relation, a:AttrName) : IRI
- = "<" + u + "/" + relname(r) + "#" + a + ">"
+ def nodemap (u:StemIRI, r:Relation, a:AttrName, l:LexicalValue) : IRI =
+ u + ("/" + relname(r) + "/" + a + "." + l.s + "#_")
+
+ def predicatemap (u:StemIRI, r:Relation, a:AttrName) : IRI =
+ u + ("/" + relname(r) + "#" + a)
+
def XSD (d:SQLDatatype) : IRI =
d match {
- case SQLString() => "<http://www.w3.org/2001/XMLSchema#string>"
- case SQLInt() => "<http://www.w3.org/2001/XMLSchema#int>"
+ case SQLString() => IRI("http://www.w3.org/2001/XMLSchema#string")
+ case SQLInt() => IRI("http://www.w3.org/2001/XMLSchema#int")
}
- def literalmap (l:LexicalValue, d:SQLDatatype) : RDFLiteral
- = "\"" + l.s + "\"^^" + XSD(d)
+
+ def literalmap (l:LexicalValue, d:SQLDatatype) : Literal =
+ Literal(l.s, XSD(d))
}
--- a/src/test/scala/Test.scala Mon May 31 09:51:11 2010 -0400
+++ b/src/test/scala/Test.scala Tue Jun 01 11:39:49 2010 -0400
@@ -27,18 +27,18 @@
Map("ID" -> LexicalValue("8"),
"fname" -> LexicalValue("Sue"),
"addr" -> ☹())))
- val u:StemURI = "http://foo.example/DB"
+ val u = StemIRI("http://foo.example/DB")
val expected:RDFGraph =
Set(
- RDFTriple("<http://foo.example/DB/People/ID.7#foo>","<http://foo.example/DB/People#ID>",LiteralObject(""""7"^^<http://www.w3.org/2001/XMLSchema#int>""")),
- RDFTriple("<http://foo.example/DB/People/ID.7#foo>","<http://foo.example/DB/People#fname>",LiteralObject(""""Bob"^^<http://www.w3.org/2001/XMLSchema#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://www.w3.org/2001/XMLSchema#int>""")),
- RDFTriple("<http://foo.example/DB/People/ID.8#foo>","<http://foo.example/DB/People#fname>",LiteralObject("\"Sue\"^^<http://www.w3.org/2001/XMLSchema#string>")),
+ Triple(IRI("http://foo.example/DB/People/ID.7#_"),IRI("http://foo.example/DB/People#ID"),Literal("7",IRI("http://www.w3.org/2001/XMLSchema#int"))),
+ Triple(IRI("http://foo.example/DB/People/ID.7#_"),IRI("http://foo.example/DB/People#fname"),Literal("Bob",IRI("http://www.w3.org/2001/XMLSchema#string"))),
+ Triple(IRI("http://foo.example/DB/People/ID.7#_"),IRI("http://foo.example/DB/People#addr"),IRIObject(IRI("http://foo.example/DB/Addresses/ID.18#_"))),
+ Triple(IRI("http://foo.example/DB/People/ID.8#_"),IRI("http://foo.example/DB/People#ID"),Literal("8",IRI("http://www.w3.org/2001/XMLSchema#int"))),
+ Triple(IRI("http://foo.example/DB/People/ID.8#_"),IRI("http://foo.example/DB/People#fname"),Literal("Sue",IRI("http://www.w3.org/2001/XMLSchema#string"))),
- RDFTriple("<http://foo.example/DB/Addresses/ID.18#foo>","<http://foo.example/DB/Addresses#ID>",LiteralObject(""""18"^^<http://www.w3.org/2001/XMLSchema#int>""")),
- RDFTriple("<http://foo.example/DB/Addresses/ID.18#foo>","<http://foo.example/DB/Addresses#city>",LiteralObject(""""Cambridge"^^<http://www.w3.org/2001/XMLSchema#string>""")),
- RDFTriple("<http://foo.example/DB/Addresses/ID.18#foo>","<http://foo.example/DB/Addresses#state>",LiteralObject(""""MA"^^<http://www.w3.org/2001/XMLSchema#string>""")))
+ Triple(IRI("http://foo.example/DB/Addresses/ID.18#_"),IRI("http://foo.example/DB/Addresses#ID"),Literal("18",IRI("http://www.w3.org/2001/XMLSchema#int"))),
+ 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))
}