--- a/directmapping/src/main/scala/DirectMapping.scala Thu Jan 13 16:40:53 2011 -0500
+++ b/directmapping/src/main/scala/DirectMapping.scala Mon Jan 17 15:38:26 2011 -0500
@@ -17,33 +17,33 @@
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))
+ pairs.foldLeft(m) { case (m, (ck, cellValues)) => {
+ m.get(ck) match {
+ case Some(byKey) if byKey.get(cellValues).isDefined =>
+ error("tried to set " + ck + cellValues + " = " + n + "(was " + byKey(cellValues) + ")")
+ case Some(byKey) =>
+ m + (ck -> (byKey + (cellValues -> n)))
+ case None =>
+ m + (ck -> Map(cellValues -> n))
}
- })
+ } }
KeyMap(m2)
}
- def contains(ck:CandidateKey) = m.contains(ck)
+ def contains(ck:CandidateKey) = m contains ck
}
case class NodeMap(m:Map[RelName, KeyMap]) {
def apply(rn:RelName) = m(rn)
def ultimateReferent (rn:RelName, k:CandidateKey, vs:List[LexicalValue], db:Database) : Node = {
// Issue: What if fk is a rearrangement of the pk, per issue fk-pk-order?
- if (db(rn).pk.isDefined && db(rn).fks.contains(db(rn).pk.get.attrs)) {
- /** Table's primary key is a foreign key. */
- val target = db(rn).fks(db(rn).pk.get.attrs)
- ultimateReferent(target.rel, target.key, vs, db)
- } else
- m(rn)(k)(vs)
+ db(rn).pk match {
+ case Some(pk) if db(rn).fks contains (pk.attrs) => {
+ /** Table's primary key is a foreign key. */
+ val target = db(rn).fks(pk.attrs)
+ ultimateReferent(target.rel, target.key, vs, db)
+ }
+ case _ =>
+ m(rn)(k)(vs)
+ }
}
def contains(rn:RelName) = m.contains(rn)
}
@@ -61,65 +61,62 @@
*/
def references (t:Tuple, r:Relation):Set[List[AttrName]] = {
- val allFKs:Set[List[AttrName]] = r.fks.keySet.toSet
+ val allFKs:Set[List[AttrName]] = r.fks.keySet
val nulllist:Set[AttrName] = t.nullAttributes(r.header)
- val nullFKs:Set[List[AttrName]] = allFKs.flatMap(a => {
- val int:Set[AttrName] = nulllist & a.toSet
- if (int.toList.length == 0) None else List(a)
- })
+ val nullFKs:Set[List[AttrName]] = allFKs filter { fk => (nulllist & fk.toSet) nonEmpty }
/** Check to see if r's primary key is a hierarchical key.
* http://www.w3.org/2001/sw/rdb2rdf/directGraph/#rule3 */
- if (r.pk.isDefined && r.fks.contains(r.pk.get.attrs))
- r.fks.keySet.toSet -- nullFKs - r.fks(r.pk.get.attrs).key.attrs
- else
- r.fks.keySet.toSet -- nullFKs
+ r.pk match {
+ case Some(pk) if r.fks contains (pk.attrs) =>
+ r.fks.keySet -- nullFKs - r.fks(pk.attrs).key.attrs
+ case _ =>
+ r.fks.keySet -- nullFKs
+ }
}
def scalars (t:Tuple, r:Relation):Set[AttrName] = {
- val allAttrs:Set[AttrName] = r.header.keySet.toSet
- val allFKs:Set[List[AttrName]] = r.fks.keySet.toSet
- val unaryFKs:Set[AttrName] = allFKs.flatMap(a => {
- if (a.length == 1) a else None
- })
+ val allAttrs:Set[AttrName] = r.header.keySet
+ val allFKs:Set[List[AttrName]] = r.fks.keySet
+ val unaryFKs:Set[AttrName] = allFKs filter { _.length == 1 } flatten
val nulllist:Set[AttrName] = t.nullAttributes(r.header)
/** Check to see if r's primary key is a hierarchical key.
* http://www.w3.org/2001/sw/rdb2rdf/directGraph/#rule3 */
- if (r.pk.isDefined && r.fks.contains(r.pk.get.attrs))
- allAttrs -- unaryFKs -- nulllist ++ r.fks(r.pk.get.attrs).key.attrs
- else
- allAttrs -- unaryFKs -- nulllist
+ r.pk match {
+ case Some(pk) if r.fks contains (pk.attrs) =>
+ allAttrs -- unaryFKs -- nulllist ++ r.fks(pk.attrs).key.attrs
+ case _ =>
+ allAttrs -- unaryFKs -- nulllist
+ }
}
/** The NodeMap-generating functions: */
def relation2KeyMap (r:Relation) : KeyMap = {
val m = KeyMap(Map[CandidateKey, Map[List[CellValue], Node]]())
- r.body.foldLeft(m)((m, t) => {
+ r.body.foldLeft(m) { (m, t) => {
val (pairs, node) = rdfNodeForTuple(t, r)
m ++ (pairs, node)
- })
+ } }
}
def rdfNodeForTuple (t:Tuple, r:Relation) : (List[(CandidateKey, List[CellValue])], Node) = {
val s:Node =
- if (r.pk.isDefined) {
- /** Table has a primkary key. */
- val vs = t.lexvaluesNoNulls(r.pk.get.attrs)
- NodeIRI(nodemap(r.name, r.pk.get.attrs, vs))
- } else
- /** Table has no primkary key (but has some candidate keys). */
- NodeBNode(freshbnode())
- (r.candidates.map(k => {
- val values:List[CellValue] = k.attrs.map(a => t(a))
- (k, values)
- }), s)
+ r.pk match {
+ case Some(pk) =>
+ /** Table has a primkary key. */
+ NodeIRI(nodemap(r.name, pk.attrs, t.lexvaluesNoNulls(pk.attrs)))
+ case None =>
+ /** Table has no primkary key (but has some candidate keys). */
+ NodeBNode(freshbnode())
+ }
+ (r.candidates map { k => (k, k.attrs map { t(_) }) }, s)
}
/** The triples-generating functions start with databasemap: */
def directDB (db:Database) : Graph = {
- val idxables = db.keySet.toSet filter { rn => !db(rn).candidates.isEmpty }
- val nodeMap:NodeMap = idxables map {rn => rn -> relation2KeyMap(db(rn))}
+ val idxables = db.keySet filter { rn => db(rn).candidates nonEmpty }
+ val nodeMap:NodeMap = idxables map { rn => rn -> relation2KeyMap(db(rn)) }
Graph(db.keySet flatMap { (rn:RelName) => directR(db(rn), nodeMap, db) })
}
@@ -132,22 +129,25 @@
def directT (t:Tuple, r:Relation, nodes:NodeMap, db:Database) : Set[Triple] = {
val s:Node =
- if (r.candidates.size > 0) {
+ r.candidates.headOption match {
// Known to have at least one key, so take the first one.
- val k = r.candidates(0)
- val vs = t.lexvaluesNoNulls(k.attrs)
- nodes.ultimateReferent(r.name, k, vs, db)
- } else
+ case Some(firstKey) => {
+ val vs = t.lexvaluesNoNulls(firstKey.attrs)
+ nodes.ultimateReferent(r.name, firstKey, vs, db)
+ }
/** Table has no candidate keys. */
- NodeBNode(freshbnode())
+ case None =>
+ NodeBNode(freshbnode())
+ }
directS(s, t, r, nodes, db)
}
def directS (s:Node, t:Tuple, r:Relation, nodes:NodeMap, db:Database) : Set[Triple] = {
- references(t, r).map(as => directN(s, as, r, t, nodes)) ++
- scalars(t, r).map(a => directL(r.name, s, a, r.header, t))
+ ( references(t, r) map { directN(s, _, r, t, nodes) } ) ++
+ ( scalars(t, r) map { directL(r.name, s, _, r.header, t) } )
}
+ // should be done by BNode
var NextBNode = 97
def freshbnode () : BNode = {
val ret = NextBNode
@@ -157,12 +157,14 @@
def directL (rn:RelName, s:Node, a:AttrName, h:Header, t:Tuple) : Triple = {
val p = predicatemap (rn, List(a))
+ // hrmmmmm
val l = t.lexvalue(a).get
val o = literalmap(l, h.sqlDatatype(a))
Triple(SubjectNode(s),
PredicateIRI(p),
ObjectLiteral(o))
}
+
def directN (s:Node, as:List[AttrName], r:Relation, t:Tuple, nodes:NodeMap) : Triple = {
val p = predicatemap (r.name, as)
val ls:List[LexicalValue] = t.lexvaluesNoNulls(as)
@@ -182,13 +184,14 @@
implicit def attrName2string (rn:AttrName) = rn.n
def nodemap (rn:RelName, as:List[AttrName], ls:List[LexicalValue]) : IRI = {
- val pairs:List[String] = as.zip(ls).map(x => UE(x._1) + "." + UE(x._2.s))
+ val pairs:List[String] = as.zip(ls) map { case (attrName, lexicalValue) => UE(attrName) + "." + UE(lexicalValue.s) }
IRI(UE(rn) + "/" + pairs.mkString("_") + "#_")
}
def predicatemap (rn:RelName, as:List[AttrName]) : IRI =
IRI(UE(rn) + "#" + as.mkString("_"))
-
+
+ // TODO: aren't they already part of the RDF model?
def XSD (d:Datatype) : IRI =
d match {
case Datatype.INTEGER => IRI("http://www.w3.org/2001/XMLSchema#integer")
--- a/rdb/src/main/scala/RDB.scala Thu Jan 13 16:40:53 2011 -0500
+++ b/rdb/src/main/scala/RDB.scala Mon Jan 17 15:38:26 2011 -0500
@@ -7,45 +7,43 @@
case class Database (m:Map[RelName, Relation]) {
def apply (rn:RelName) = m(rn)
- def keySet () = m.keySet
+ def keySet = m.keySet.toSet
}
object Database {
- def apply (l:(Relation)*):Database =
- Database(l.map{r => (r.name -> r)}.toMap)
+ def apply (l:Relation*):Database =
+ Database(l map { r => (r.name -> r) } toMap)
}
case class Relation (name:RelName, header:Header, body:List[Tuple], candidates:List[CandidateKey], pk:Option[CandidateKey], fks:ForeignKeys) {
- def ++ (t:Tuple):Relation = {
- val b2:List[RDB.Tuple] = body ++ List(t)
- Relation(name, header, b2, candidates, pk, fks)
- }
+ // TODO: should be + instead of ++
+ def ++ (t:Tuple):Relation = this.copy(body = body :+ t)
}
case class Header (m:Map[AttrName, Datatype]) {
def apply (a:AttrName) = m(a)
- def keySet () = m.keySet.toSet
+ def keySet = m.keySet.toSet
def sqlDatatype (a:AttrName) : Datatype = m(a)
- def contains (a:AttrName) : Boolean = m.contains(a)
+ def contains (a:AttrName) : Boolean = m contains a
}
object Header {
def apply (s:(String, Datatype)*):Header =
- Header(s.map{p => (AttrName(p._1), p._2)}.toMap)
+ Header(s map { case (name, datatype) => (AttrName(name), datatype) } toMap)
}
case class CandidateKey (attrs:List[AttrName])
object CandidateKey {
- def apply (l:(String)*):CandidateKey =
- CandidateKey(l.map{s => AttrName(s)}.toList)
+ def apply (l:String*):CandidateKey =
+ CandidateKey(l.toList map { AttrName(_) })
}
implicit def cc2list (cc:CandidateKey) = cc.attrs
case class ForeignKeys (m:Map[List[AttrName], Target]) {
def apply (l:List[AttrName]) = m(l)
- def keySet () = m.keySet
- def contains (l:List[AttrName]) = m.contains(l)
+ def keySet = m.keySet.toSet
+ def contains (l:List[AttrName]) = m contains l
}
object ForeignKeys {
def apply (s:(List[String], Target)*):ForeignKeys =
- ForeignKeys(s.map{p => (p._1.map{s => AttrName(s)}, p._2)}.toMap)
+ ForeignKeys(s map { case (keys, target) => (keys map { AttrName(_) }, target)} toMap)
}
case class Target (rel:RelName, key:CandidateKey)
@@ -70,26 +68,20 @@
def apply (a:AttrName) = m(a)
def lexvalue (a:AttrName) : Option[LexicalValue] =
m(a) match {
- case ␀() => None
+ case ␀ => None
case v:LexicalValue => Some(v)
}
- def lexvaluesNoNulls (as:List[AttrName]) = as.map(a => m(a).asInstanceOf[LexicalValue])
- def nullAttributes (h:Header) : Set[(AttrName)] = {
- h.keySet.flatMap(a =>
- lexvalue(a) match {
- case None => Some(a)
- case _ => None
- })
- }
+ def lexvaluesNoNulls (as:List[AttrName]) = as map { m(_).asInstanceOf[LexicalValue] }
+ def nullAttributes (h:Header) : Set[AttrName] = h.keySet filter { lexvalue(_) isEmpty }
}
object Tuple {
def apply (s:(String, CellValue)*):Tuple =
- Tuple(s.map{p => (AttrName(p._1), p._2)}.toMap)
+ Tuple(s map { case (name, cellValue) => (AttrName(name), cellValue) } toMap)
}
abstract class CellValue
case class LexicalValue (s:String) extends CellValue
- case class ␀ () extends CellValue
+ case object ␀ extends CellValue
case class RelName(n:String) {
override def toString = n
--- a/sql/src/main/scala/SQL.scala Thu Jan 13 16:40:53 2011 -0500
+++ b/sql/src/main/scala/SQL.scala Mon Jan 17 15:38:26 2011 -0500
@@ -419,7 +419,7 @@
int ^^ { i => RDB.LexicalValue(i) }
| dquote ^^ { x => RDB.LexicalValue(x.substring(1, x.size - 1)) }
| squote ^^ { x => RDB.LexicalValue(x.substring(1, x.size - 1)) }
- | "NULL" ^^ { case "NULL" => RDB.␀() }
+ | "NULL" ^^ { case "NULL" => RDB.␀ }
)
}
--- a/sql/src/test/scala/SQLTest.scala Thu Jan 13 16:40:53 2011 -0500
+++ b/sql/src/test/scala/SQLTest.scala Mon Jan 17 15:38:26 2011 -0500
@@ -682,7 +682,7 @@
"addr" -> RDB.LexicalValue("18")),
RDB.Tuple("ID" -> RDB.LexicalValue("8"),
"fname" -> RDB.LexicalValue("Sue"),
- "addr" -> RDB.␀())),
+ "addr" -> RDB.␀)),
List(RDB.CandidateKey("ID")),
Some(RDB.CandidateKey("ID")),
RDB.ForeignKeys(List("addr") -> RDB.Target("Addresses", RDB.CandidateKey("ID"))))
@@ -735,9 +735,9 @@
"deptCity" -> RDB.LexicalValue("Cambridge")),
RDB.Tuple("ID" -> RDB.LexicalValue("8"),
"fname" -> RDB.LexicalValue("Sue"),
- "addr" -> RDB.␀(),
- "deptName" -> RDB.␀(),
- "deptCity" -> RDB.␀())),
+ "addr" -> RDB.␀,
+ "deptName" -> RDB.␀,
+ "deptCity" -> RDB.␀)),
List(RDB.CandidateKey("ID")),
Some(RDB.CandidateKey("ID")),
RDB.ForeignKeys(List("addr") -> RDB.Target("Addresses", RDB.CandidateKey("ID")),
@@ -824,9 +824,9 @@
"deptCity" -> RDB.LexicalValue("Cambridge")),
RDB.Tuple("ID" -> RDB.LexicalValue("8"),
"fname" -> RDB.LexicalValue("Sue"),
- "addr" -> RDB.␀(),
- "deptName" -> RDB.␀(),
- "deptCity" -> RDB.␀())),
+ "addr" -> RDB.␀,
+ "deptName" -> RDB.␀,
+ "deptCity" -> RDB.␀)),
List(RDB.CandidateKey("ID")),
Some(RDB.CandidateKey("ID")),
RDB.ForeignKeys(List("addr") -> RDB.Target("Addresses", RDB.CandidateKey("ID")),