--- a/src/main/scala/Main.scala Tue Sep 28 09:04:23 2010 -0400
+++ b/src/main/scala/Main.scala Tue Sep 28 18:23:51 2010 -0400
@@ -5,12 +5,14 @@
// Relational structure
object SQL {
- case class Database(m:Map[RelName, Relation])
- case class Relation (header:Header, body:Body, keys:List[CandidateKey], pk:Option[CandidateKey], fks:ForeignKeys)
- case class Header (types:Map[AttrName, SQLDatatype]) {
- def keySet () = types.keySet
+ case class Database(m:Map[RelName, Relation]) {
+ def idxables():Set[RelName] = m.keySet filter { rn => !m(rn).candidates.isEmpty }
}
-
+ case class Relation (header:Header, body:Body, candidates:List[CandidateKey], pk:Option[CandidateKey], fks:ForeignKeys)
+ case class Header (m:Map[AttrName, SQLDatatype]) {
+ def keySet () = m.keySet
+ def apply (a:AttrName) = m(a)
+ }
type CandidateKey = List[AttrName]
type ForeignKeys = Map[List[AttrName], Target]
case class Target(rel:RelName, attrs:CandidateKey)
@@ -47,7 +49,7 @@
case v:LexicalValue => Some(v)
}
- def sqlDatatype (h:Header, a:AttrName) : SQLDatatype = h.types(a)
+ def sqlDatatype (h:Header, a:AttrName) : SQLDatatype = h(a)
}
@@ -99,7 +101,27 @@
import RDF._
import SQL._
- type KeyMap = Map[CandidateKey, Map[List[CellValue], Node]]
+ case class KeyMap(m:Map[CandidateKey, Map[List[CellValue], Node]]) {
+ //def KeyMap() : KeyMap = KeyMap(Map[CandidateKey, Map[List[CellValue], Node]]())
+ def apply(i:CandidateKey) : Map[List[CellValue], Node] = m(i)
+ def ++(pairs:List[(CandidateKey, List[CellValue])], n:Node):KeyMap = {
+ val m2:Map[CandidateKey, Map[List[CellValue], Node]] =
+ pairs.foldLeft(m)((m, p) => {
+ if (m.get(p._1).isDefined) {
+ val byKey = m(p._1)
+ if (byKey.get(p._2).isDefined) {
+ error("tried to set " + p._1 + p._2 + " = " + n + "(was " + byKey(p._2) + ")")
+ } else {
+ val im1 = byKey ++ Map[List[CellValue], Node](p._2 -> n)
+ m ++ Map[CandidateKey, Map[List[CellValue], Node]](p._1 -> im1)
+ }
+ } else {
+ m ++ Map[CandidateKey, Map[List[CellValue], Node]](p._1 -> Map(p._2 -> n))
+ }
+ })
+ KeyMap(m2)
+ }
+ }
type NodeMap = Map[RelName, KeyMap]
// Transformation argument:
@@ -109,72 +131,16 @@
// Mapping functions:
def databasemap (u:StemIRI, db:Database) : RDFGraph = {
- 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))
+ val nodes:NodeMap = db.idxables.map(rn => rn -> relation2subject(u, rn, db.m(rn))).toMap
+ db.m.keySet.flatMap(rn => relationmap(u, rn, db.m(rn), nodes, db))
}
def relation2subject (u:StemIRI, rn:RelName, r:Relation) : KeyMap = {
-
- // Here's a built-In test to make sure we don't screw this up:
- val ck1:CandidateKey = List("name", "ssn")
- val ck2:CandidateKey = List("ID")
- val v11:List[CellValue] = List(LexicalValue("bob"), LexicalValue("123"))
- val v21:List[CellValue] = List(LexicalValue("alice"), LexicalValue("8"))
- val v12:List[CellValue] = List(LexicalValue("18"))
- val v22:List[CellValue] = List(LexicalValue("23"))
- val s1:Node = BNode("1")
- val s2:Node = BNode("2")
- val data:Set[(List[(CandidateKey, List[CellValue])], Node)] =
- Set((List((ck1, v11),(ck2, v21)), s1),
- (List((ck1, v12),(ck2, v22)), s2))
- val test = data.foldLeft(Map[CandidateKey, Map[List[CellValue], Node]]())((m, t) => {
- val pairs = t._1
- pairs.foldLeft(m)((m, p) => {
- if (m.get(p._1).isDefined) {
- val byKey = m(p._1)
- if (byKey.get(p._2).isDefined) {
- error("tried to set " + rn + p._1 + p._2 + " = " + t._2 + "(was " + byKey(p._2) + ")")
- } else {
- val im1 = byKey ++ Map[List[CellValue], Node](p._2 -> t._2)
- m ++ Map[CandidateKey, Map[List[CellValue], Node]](p._1 -> im1)
- }
- } else {
- m ++ Map[CandidateKey, Map[List[CellValue], Node]](p._1 -> Map(p._2 -> t._2))
- }
- })
+ val m = KeyMap(Map[CandidateKey, Map[List[CellValue], Node]]())
+ body(r).foldLeft(m)((m, t) => {
+ val s = tuple2subject(u, rn, t, r)
+ m ++ (s._1, s._2)
})
-
- val goal:Map[CandidateKey, Map[List[CellValue], Node]] =
- Map(ck1 -> Map(v11 -> s1,
- v12 -> s2),
- ck2 -> Map(v21 -> s1,
- v22 -> s2))
- assert(goal == test)
-
- // Now the useful invocation:
- val data2:Set[(List[(CandidateKey, List[CellValue])], Node)] = body(r).map(t => {
- // (List(List("name", "ssn"), List("ID")), List(List("bob", 123), List(18)), 1)
- // (List(List("name", "ssn"), List("ID")), List(List("alice", 8), List(23)), 2)
- tuple2subject(u, rn, t, r)
- })
- data2.foldLeft(Map[CandidateKey, Map[List[CellValue], Node]]())((m, t) => {
- val pairs = t._1
- pairs.foldLeft(m)((m, p) => {
- if (m.get(p._1).isDefined) {
- val byKey = m(p._1)
- if (byKey.get(p._2).isDefined) {
- error("tried to set " + rn + p._1 + p._2 + " = " + t._2 + "(was " + byKey(p._2) + ")")
- } else {
- val im1 = byKey ++ Map[List[CellValue], Node](p._2 -> t._2)
- m ++ Map[CandidateKey, Map[List[CellValue], Node]](p._1 -> im1)
- }
- } else {
- m ++ Map[CandidateKey, Map[List[CellValue], Node]](p._1 -> Map(p._2 -> t._2))
- }
- })
- })
-
}
def tuple2subject (u:StemIRI, rn:RelName, t:Tuple, r:Relation) : (List[(CandidateKey, List[CellValue])], Node) = {
@@ -186,21 +152,21 @@
nodemap(u, rn, r.pk.get, vs)
} else
freshbnode()
- (r.keys.map(k => {
+ (r.candidates.map(k => {
val values:List[CellValue] = k.map(a => t(a))
(k, values)
}), s)
}
- def relationmap (u:StemIRI, rn:RelName, r:Relation, nodes:NodeMap) : RDFGraph =
- body(r).flatMap(t => tuplemap(u, rn, t, r, nodes))
+ def relationmap (u:StemIRI, rn:RelName, r:Relation, nodes:NodeMap, db:Database) : RDFGraph =
+ body(r).flatMap(t => tuplemap(u, rn, t, r, nodes, db))
- def tuplemap (u:StemIRI, rn:RelName, t:Tuple, r:Relation, nodes:NodeMap) : Set[Triple] = {
+ def tuplemap (u:StemIRI, rn:RelName, t:Tuple, r:Relation, nodes:NodeMap, db:Database) : Set[Triple] = {
val h = header(r)
val s:Node =
- if (nodes.get(rn).isDefined) {
+ if (r.candidates.size > 0) { // which implies !nodes.get(rn).isDefined
// Known to have at least one key, so take the first one.
- val k = r.keys(0)
+ val k = r.candidates(0)
// Assume: no NULLs in candidate key
val vs = k.map(a => lexvalue(h, t, a).get)
nodes(rn)(k)(vs)
@@ -221,7 +187,7 @@
val referencelist = r.fks.keySet -- nullFKs
scalarlist.map(a => scalartriples(u, rn, s, a, h, t)) ++
- referencelist.map(as => referencetriples(u, rn, s, as, r, t, nodes))
+ referencelist.map(as => referencetriples(u, rn, s, as, r, t, nodes, db))
}
@@ -238,12 +204,15 @@
val o = literalmap(l, sqlDatatype(h, a))
Triple(s, p, o)
}
- def referencetriples (u:StemIRI, rn:RelName, s:Node, as:List[AttrName], r:Relation, t:Tuple, nodes:NodeMap) : Triple = {
+ def referencetriples (u:StemIRI, rn:RelName, s:Node, as:List[AttrName], r:Relation, t:Tuple, nodes:NodeMap, db:Database) : Triple = {
val p = predicatemap (u, rn, as)
val ls:List[LexicalValue] = as.map(a =>t(a).asInstanceOf[LexicalValue])
val target = r.fks(as)
val o999 = nodemap(u, target.rel, target.attrs, ls)
val o:Object = nodes(target.rel)(target.attrs)(ls)
+ // if (db.m(target.rel).fks.contains(target.attrs))
+ // error("need to follow " + target.rel + target.attrs + "->" + db.m(target.rel).fks(target.attrs))
+ // println("need to follow " + target.rel + target.attrs)
Triple(s, p, o)
}