--- a/src/main/scala/Main.scala Mon Sep 27 08:30:16 2010 -0400
+++ b/src/main/scala/Main.scala Mon Sep 27 09:31:57 2010 -0400
@@ -5,9 +5,9 @@
// Relational structure
object SQL {
- case class Database( m:Map[RelName, Relation] )
- case class Relation ( header:Header, body:Body )
- case class Header (types:Map[AttrName, SQLDatatype], keys:List[CandidateKey], pk:CandidateKey, fks:ForeignKeys) {
+ case class Database(m:Map[RelName, Relation])
+ case class Relation (header:Header, body:Body, keys:List[CandidateKey], pk:CandidateKey, fks:ForeignKeys)
+ case class Header (types:Map[AttrName, SQLDatatype]) {
def keySet () = types.keySet
}
@@ -37,7 +37,7 @@
type AttrName = String
// Accessor functions:
- def pk (h:Header) : List[AttrName] = h.pk
+ def pk (r:Relation) : List[AttrName] = r.pk
def header (r:Relation) : Header = r.header
def body (r:Relation) : Body = r.body
@@ -51,6 +51,12 @@
type RDFGraph = Set[Triple]
case class Triple (s:Subject, p:IRI, o:Object)
+ sealed abstract class Node // factor out IRIs and BNodes
+ case class NodeIRI(i:IRI) extends Node
+ implicit def iri2nodeiri(i:IRI):Node = NodeIRI(i)
+ case class NodeBNode(b:BNode) extends Node
+ implicit def bnode2nodebnode(b:BNode):Node = NodeBNode(b)
+
sealed abstract class Subject
case class SubjectNode(n:Node) extends Subject
implicit def node2subjectnode(n:Node):Subject = SubjectNode(n)
@@ -68,12 +74,6 @@
implicit def bnode2objectnode(b:BNode):Object = ObjectNode(b)
case class ObjectLiteral (n:Literal) extends Object
-
- sealed abstract class Node
- case class NodeIRI(i:IRI) extends Node
- implicit def iri2nodeiri(i:IRI):Node = NodeIRI(i)
- case class NodeBNode(b:BNode) extends Node
- implicit def bnode2nodebnode(b:BNode):Node = NodeBNode(b)
case class IRI(iri:String)
case class BNode(label:String)
@@ -104,7 +104,7 @@
// Mapping functions:
def databasemap (u:StemIRI, db:Database) : RDFGraph = {
- val idxables:Set[RelName] = db.m.keySet.filter(rn => db.m(rn).header.keys.size > 0)
+ val idxables:Set[RelName] = db.m.keySet.filter(rn => db.m(rn).keys.size > 0)
val nodes:NodeMap = idxables.map(rn => rn -> relation2subject(u, rn, db.m(rn))).toMap
db.m.keySet.flatMap(rn => relationmap(u, rn, db.m(rn), nodes)).toSet
}
@@ -190,9 +190,9 @@
def tuple2subject (u:StemIRI, rn:RelName, t:Tuple, r:Relation) : (List[(CandidateKey, List[CellValue])], Node) = {
val h = header(r)
- val vs = pk(h).map(k => lexvalue(h, t, k).asInstanceOf[LexicalValue])
- val s:Node = if (pk(h).length == 0) freshbnode() else nodemap(u, rn, pk(h), vs) // Assume: no NULLs in primary key
- (h.keys.map(k => {
+ val vs = pk(r).map(k => lexvalue(h, t, k).asInstanceOf[LexicalValue])
+ val s:Node = if (pk(r).length == 0) freshbnode() else nodemap(u, rn, pk(r), vs) // Assume: no NULLs in primary key
+ (r.keys.map(k => {
val values:List[CellValue] = k.map(a => t(a))
(k, values)
}), s)
@@ -203,11 +203,11 @@
def tuplemap (u:StemIRI, rn:RelName, t:Tuple, r:Relation, nodes:NodeMap) : Set[Triple] = {
val h = header(r)
- val vs = pk(h).map(k => lexvalue(h, t, k).asInstanceOf[LexicalValue])
- val s:Node = if (nodes.get(rn).isDefined) nodes(rn)(pk(h))(vs) else freshbnode()
+ val vs = pk(r).map(k => lexvalue(h, t, k).asInstanceOf[LexicalValue])
+ val s:Node = if (nodes.get(rn).isDefined) nodes(rn)(pk(r))(vs) else freshbnode()
val allAttrs:Set[AttrName] = h.keySet
- val allFKs:Set[List[AttrName]] = h.fks.keySet
+ val allFKs:Set[List[AttrName]] = r.fks.keySet
val unaryFKs:Set[AttrName] = allFKs.flatMap(a => {
if (a.length == 1) a else None
})
@@ -217,10 +217,10 @@
if (int.toList.length == 0) None else List(a)
})
val scalarlist = allAttrs -- unaryFKs -- nulllist /* -- h.pk */
- val referencelist = h.fks.keySet -- nullFKs
+ val referencelist = r.fks.keySet -- nullFKs
scalarlist.map(a => scalartriples(u, rn, s, a, h, t)) ++
- referencelist.map(as => referencetriples(u, rn, s, as, h, t, nodes))
+ referencelist.map(as => referencetriples(u, rn, s, as, r, t, nodes))
}
@@ -232,10 +232,10 @@
val o = literalmap(l, sqlDatatype(h, a))
Triple(s, p, o)
}
- def referencetriples (u:StemIRI, rn:RelName, s:Node, as:List[AttrName], h:Header, t:Tuple, nodes:NodeMap) : Triple = {
+ def referencetriples (u:StemIRI, rn:RelName, s:Node, as:List[AttrName], r:Relation, t:Tuple, nodes:NodeMap) : Triple = {
val p = predicatemap (u, rn, as)
val ls:List[LexicalValue] = as.map(a =>t(a).asInstanceOf[LexicalValue])
- val target = h.fks(as)
+ val target = r.fks(as)
val o999 = nodemap(u, target.rel, target.attrs, ls)
val o:Object = nodes(target.rel)(target.attrs)(ls)
Triple(s, p, o)
--- a/src/test/scala/Test.scala Mon Sep 27 08:30:16 2010 -0400
+++ b/src/test/scala/Test.scala Mon Sep 27 09:31:57 2010 -0400
@@ -12,26 +12,26 @@
val addresses = Relation(Header(Map("ID" -> SQLInt(),
"city" -> SQLString(),
- "state" -> SQLString()),
- List(List("ID")),
- List("ID"),
- Map()),
+ "state" -> SQLString())),
Set(Map("ID" -> LexicalValue("18"),
"city" -> LexicalValue("Cambridge"),
- "state" -> LexicalValue("MA"))))
+ "state" -> LexicalValue("MA"))),
+ List(List("ID")),
+ List("ID"),
+ Map())
val people = Relation(Header(Map("ID" -> SQLInt(),
"fname" -> SQLString(),
- "addr" -> SQLInt()),
- List(List("ID")),
- List("ID"),
- Map(List("addr") -> Target("Addresses", List("ID")))),
+ "addr" -> SQLInt())),
Set(Map("ID" -> LexicalValue("7"),
"fname" -> LexicalValue("Bob"),
"addr" -> LexicalValue("18")),
Map("ID" -> LexicalValue("8"),
"fname" -> LexicalValue("Sue"),
- "addr" -> ␀())))
+ "addr" -> ␀())),
+ List(List("ID")),
+ List("ID"),
+ Map(List("addr") -> Target("Addresses", List("ID"))))
val db = Database(Map("Addresses" -> addresses,
"People" -> people))
@@ -56,23 +56,19 @@
val addresses = Relation(Header(Map("ID" -> SQLInt(),
"city" -> SQLString(),
- "state" -> SQLString()),
- List(List("ID")),
- List("ID"),
- Map()),
+ "state" -> SQLString())),
Set(Map("ID" -> LexicalValue("18"),
"city" -> LexicalValue("Cambridge"),
- "state" -> LexicalValue("MA"))))
+ "state" -> LexicalValue("MA"))),
+ List(List("ID")),
+ List("ID"),
+ Map())
val people = Relation(Header(Map("ID" -> SQLInt(),
"fname" -> SQLString(),
"addr" -> SQLInt(),
"deptName" -> SQLString(),
- "deptCity" -> SQLString()),
- List(List("ID")),
- List("ID"),
- Map(List("addr") -> Target("Addresses", List("ID")),
- List("deptName", "deptCity") -> Target("Department", List("name", "city")))),
+ "deptCity" -> SQLString())),
Set(Map("ID" -> LexicalValue("7"),
"fname" -> LexicalValue("Bob"),
"addr" -> LexicalValue("18"),
@@ -82,19 +78,23 @@
"fname" -> LexicalValue("Sue"),
"addr" -> ␀(),
"deptName" -> ␀(),
- "deptCity" -> ␀())))
+ "deptCity" -> ␀())),
+ List(List("ID")),
+ List("ID"),
+ Map(List("addr") -> Target("Addresses", List("ID")),
+ List("deptName", "deptCity") -> Target("Department", List("name", "city"))))
val department = Relation(Header(Map("ID" -> SQLInt(),
"name" -> SQLString(),
"city" -> SQLString(),
- "manager" -> SQLInt()),
- List(List("ID"), List("name", "city")),
- List("ID"),
- Map(List("manager") -> Target("People", List("ID")))),
+ "manager" -> SQLInt())),
Set(Map("ID" -> LexicalValue("23"),
"name" -> LexicalValue("accounting"),
"city" -> LexicalValue("Cambridge"),
- "manager" -> LexicalValue("8"))))
+ "manager" -> LexicalValue("8"))),
+ List(List("ID"), List("name", "city")),
+ List("ID"),
+ Map(List("manager") -> Target("People", List("ID"))))
val db = Database(Map("Addresses" -> addresses,
"People" -> people,
@@ -128,17 +128,17 @@
test("2 Employees") {
val employees = Relation(Header(Map("ID" -> SQLInt(),
"fname" -> SQLString(),
- "boss" -> SQLInt()),
- List(List("ID")),
- List("ID"),
- Map(List("boss") -> Target("Employees", List("ID")))),
+ "boss" -> SQLInt())),
Set(Map("ID" -> LexicalValue("1"),
"fname" -> LexicalValue("Alice"),
"boss" -> ␀()),
Map("ID" -> LexicalValue("2"),
"fname" -> LexicalValue("Bob"),
"boss" -> LexicalValue("1"))
- ))
+ ),
+ List(List("ID")),
+ List("ID"),
+ Map(List("boss") -> Target("Employees", List("ID"))))
val db = Database(Map("Employees" -> employees))
val g = databasemap(StemIRI("http://foo.example/DB"), db)