--- a/directmapping/src/main/scala/DirectMapping.scala Sun Feb 13 18:09:52 2011 -0500
+++ b/directmapping/src/main/scala/DirectMapping.scala Sun Feb 13 23:02:26 2011 -0500
@@ -75,7 +75,7 @@
} }
}
val m = Map[CandidateKey, Map[List[CellValue], Node]]()
- val tuples = r.body map { t => tupleToNode(t, r) }
+ val tuples = r.body map { t => tupleToNode(t) }
tuples.foldLeft(m){ case (m, (pairs, node)) => ++(m, pairs, node) }
}
@@ -85,12 +85,13 @@
* * if there is a primary key: the constant IRI based on the actual values from the pk
* * if no primary key: a fresh bnode
*/
- def tupleToNode (t:Tuple, r:Relation) : (List[(CandidateKey, List[CellValue])], Node) = {
+ def tupleToNode (t:Tuple) : (List[(CandidateKey, List[CellValue])], Node) = {
+ val r:Relation = t.r
val s:Node =
r.pk match {
case Some(pk) =>
/** Table has a primkary key. */
- NodeIRI(tupleToIRI(r, pk, t.lexvalues(pk)))
+ NodeIRI(tupleToIRI(t, pk))
case None =>
/** Table has no primkary key (but has some candidate keys). */
NodeBNode(freshbnode())
@@ -112,9 +113,10 @@
* We know this because relations with candidate keys are mapped to unique
* subjects, and potentially redundant rows get unique blank node subjects.
*/
- Graph(r.body flatMap { t => tupleSemantics(nodemap, r, t) })
+ Graph(r.body flatMap { t => tupleSemantics(nodemap, t) })
- def tupleSemantics (nodemap:NodeMap, r:Relation, t:Tuple):Set[Triple] = {
+ def tupleSemantics (nodemap:NodeMap, t:Tuple):Set[Triple] = {
+ val r:Relation = t.r
val s:SubjectNode =
// look for the first candidate key if available
r.candidates.headOption match {
@@ -131,8 +133,8 @@
SubjectNode(freshnode)
}
}
- val fromFKs = t.references(r) map { fk => referenceSemantics(r, nodemap, t, fk) }
- val fromLexicalValues = t.scalars(r) flatMap { a => lexicalValueSemantics(r, t, a) }
+ val fromFKs = t.references(r) map { fk => referenceSemantics(nodemap, t, fk) }
+ val fromLexicalValues = t.scalars(r) flatMap { a => lexicalValueSemantics(t, a) }
// the relation provenance is mapped to an RDF type information, computed from the relation itself
val fromRelation = (PredicateIRI(IRI("http://www.w3.org/1999/02/22-rdf-syntax-ns#type")),
ObjectNode(NodeIRI(IRI(UE(r)))))
@@ -142,7 +144,8 @@
/**
* a foreign key contribute to generating triples
*/
- def referenceSemantics (r:Relation, nodes:NodeMap, t:Tuple, fk:ForeignKey):(Predicate, Object) = {
+ def referenceSemantics (nodes:NodeMap, t:Tuple, fk:ForeignKey):(Predicate, Object) = {
+ val r:Relation = t.r
val p = referencePredicateSemantics(r, fk)
val cellvalues:List[CellValue] = t.cellvalues(fk)
val ForeignKey(as, target@Target(_, key)) = fk
@@ -160,7 +163,8 @@
/**
* a lexical value contribute to generating triples (only if it is not null)
*/
- def lexicalValueSemantics(r:Relation, t:Tuple, a:AttrName):Option[(Predicate, Object)] = {
+ def lexicalValueSemantics(t:Tuple, a:AttrName):Option[(Predicate, Object)] = {
+ val r:Relation = t.r
// a is implicitly promoted to an AttrList
val p = lexicalValuePredicateSemantics(r, a)
val cellValue = t(a)
@@ -199,9 +203,11 @@
* - the lexicalvalues are generated from pk
* hence, the zip operation is safe as both list have the same size
*/
- def tupleToIRI(rn:Relation, as:AttrList, ls:List[LexicalValue]):IRI = {
- val pairs:List[String] = as.attrs zip ls map { case (attrName, lexicalValue) => UE(attrName) + "." + UE(lexicalValue.s) }
- IRI(UE(rn) + "/" + pairs.mkString("_") + "#_")
+ def tupleToIRI(t:Tuple, pk:AttrList):IRI = {
+ val r:Relation = t.r
+ val ls:List[LexicalValue] = t.lexvalues(pk)
+ val pairs:List[String] = pk.attrs zip ls map { case (attrName, lexicalValue) => UE(attrName) + "." + UE(lexicalValue.s) }
+ IRI(UE(r) + "/" + pairs.mkString("_") + "#_")
}
// TODO: aren't they already part of the RDF model?
--- a/rdb/src/main/scala/RDB.scala Sun Feb 13 18:09:52 2011 -0500
+++ b/rdb/src/main/scala/RDB.scala Sun Feb 13 23:02:26 2011 -0500
@@ -43,6 +43,12 @@
pk:Option[CandidateKey],
fks:ForeignKeys) {
+ for {
+ t <- body
+ } {
+ t.relation = Some(this)
+ }
+
/** adds a tuple in the body of the relation */
def +(t:Tuple):Relation = this.copy(body = body :+ t)
/** a relation is indexable if it has at least one candidate key */
@@ -74,6 +80,11 @@
* especially, the order of the attribute names is not known within the tuple
*/
case class Tuple (private val m:Map[AttrName, CellValue]) extends PartialFunction[AttrName, CellValue] {
+
+ // hack for the tuple to know the relation it belongs to
+ var relation:Option[Relation] = None
+ lazy val r:Relation = relation.get
+
def apply (a:AttrName) = m(a)
def isDefinedAt(a:AttrName) = m isDefinedAt a