--- a/src/main/scala/RDB2RDFMain.scala Sun Dec 13 19:17:29 2009 -0500
+++ b/src/main/scala/RDB2RDFMain.scala Mon Dec 14 02:11:39 2009 -0500
@@ -19,7 +19,7 @@
case class PrimaryKey(attr:Attribute)
sealed abstract class Binding
-case class Node(fqattr:FQAttribute) extends Binding
+case class RDFNode(fqattr:FQAttribute) extends Binding
case class Str(fqattr:FQAttribute) extends Binding
case class Int(fqattr:FQAttribute) extends Binding
case class Enum(fqattr:FQAttribute) extends Binding
@@ -98,27 +98,66 @@
println("equiv|=" + fqattr + "=" + value)
}
- def VarConstraint(v:Var, attr:FQAttribute) = {
- println("?" + v.s + "=> @@Binding(" + toString(attr) + ")")
+ /** varConstraint
+ * called on triple pattern subjects and objects of type variable
+ * passed the relation name (from predicate)
+ * if a subject, then the attribute is the primary key for relation
+ * if an object, then passed the attribute name (from predicate)
+ * passed the alias for this relation (e.g. _emp)
+ * */
+ def varConstraint(v:Var, rel:Relation, alias:Relation, attr:Attribute) = {
+ // Employee _emp id
+ // Employee _emp lastName
+ // Employee _emp manager
+
+ // if schema(rel)(fttr) is a String => (v => SRValueString(alias.attr))
+
+ // schema(Employee.id) => (?emp => NodeTemplate("Employee", _emp.id) stemURI + rel + fk(rel) + value
+ // schema(Employee.lastName) => (?lastName => RValueString(_emp.lastName)
+ // schema(Employee.manater) => (?manager => ForeignKey("Employee", _manager.id)
+
+ // SELECT ?emp WHERE { ?emp emp:manager <http://hr.example/our/favorite/DB/Employee/id.18#record> ; emp:name ?name }
+ // SQL Results SPARQL Results
+ // __emp __name ?emp ?name
+ // 4 "Bob" <http://hr.example/our/favorite/DB/Employee/id.4#record> "Bob"^^xsd:string
+ // 6 "Sue" <http://hr.example/our/favorite/DB/Employee/id.6#record> "Sue"^^xsd:string
+
+// type String -> RDFStringConstructor // adds ^^xsd:string
+// type primary key -> RDFNodeConstructor // prefixes with stemURL + relation + attribute and adds #record
+
+ println("?" + v.s + "=> @@Binding(" + alias.n.s + "." + attr.n.s + ")")
+null
}
def LiteralConstraint(lit:SparqlLiteral, attr:FQAttribute) = {
println("equiv|=" + attr + "=" + lit)
}
+ def insertKeyPair(frel:String, fattr:String, trel:String, tattr:String) = {
+// fks + (Relation(Name(frel)) ->
+// (Attribute(Name(fattr)) ->
+// FQAttribute(Relation(Name(trel)), Attribute(Name(tattr)))))
+ }
+
def getKeyTarget(from:FQAttribute) : Option[FQAttribute] = {
- from match {
- case FQAttribute(Relation(Name("Employee")), Attribute(Name("manager"))) =>
- Some(FQAttribute(Relation(Name("Employee")), Attribute(Name("id"))))
- case FQAttribute(Relation(Name("Employee")), Attribute(Name("lastName"))) => None
+ val fk = Map[Relation,Map[Attribute, FQAttribute]]()
+ try {
+ Some(fk(from.relation)(from.attribute))
+ } catch {
+ case _ => None
}
+// from match {
+// case FQAttribute(Relation(Name("Employee")), Attribute(Name("manager"))) =>
+// Some(FQAttribute(Relation(Name("Employee")), Attribute(Name("id"))))
+// case FQAttribute(Relation(Name("Employee")), Attribute(Name("lastName"))) => None
+// }
}
def toString(fqattr:FQAttribute) : String = {
fqattr.relation.n.s + "." + fqattr.attribute.n.s
}
- def acc(state:R2RState, triple:TriplePattern, pk:PrimaryKey):R2RState = {
+ def acc(db:DatabaseDesc, state:R2RState, triple:TriplePattern, pk:PrimaryKey):R2RState = {
val R2RState(project, joins, exprs, varmap) = state
val TriplePattern(s, p, o) = triple
p match {
@@ -129,38 +168,50 @@
println(rel.n.s + " AS " + alias.n.s)
s match {
case SUri(u) => URIconstraint(u, pk)
- case SVar(v) => VarConstraint(v, FQAttribute(alias, pk.attr))
+ case SVar(v) => varConstraint(v, rel, alias, pk.attr)
null
}
val objattr = FQAttribute(alias, attr)
val oAlias = AliasFromO(o) // None if OLit
- val target = getKeyTarget(FQAttribute(rel, attr))
- target match {
- case None => null
- case Some(fqattr) => {
+ val fks = Map[Relation,Map[Attribute, FQAttribute]]()
+ //fks.insertKeyPair("Employee", "manager", "manager", "id")
+ // fks.insertKeyPair("Employee", "asdf", "fdsa", "id")
+// val target = getKeyTarget(FQAttribute(rel, attr))
+// (target, oAlias) match {
+// case _, _ =>
+// }
+
+ val target = db.relationdescs(rel).attributes(attr) match {
+ case ForeignKey(fkrel, fkattr) => {
+ val fqattr = FQAttribute(fkrel, fkattr)
oAlias match {
case None => error("no oAlias for foreign key " + toString(fqattr))
case Some(a) => {
println(toString(objattr) + "->" + toString(FQAttribute(a, fqattr.attribute)))
- 1 // null ptr error otherwise. what's getting assigned to this?
+ o match {
+ case OUri(u) => URIconstraint(u, pk)
+ case OVar(v) => varConstraint(v, fqattr.relation, a, fqattr.attribute)
+ case OLit(l) => LiteralConstraint(l, objattr)
+ }
}
}
}
+ case Value(dt) => {
+ o match {
+ case OUri(u) => URIconstraint(u, pk)
+ case OVar(v) => varConstraint(v, rel, alias, attr)
+ case OLit(l) => LiteralConstraint(l, objattr)
+ }
+ }
}
- o match {
- case OUri(u) => URIconstraint(u, pk)
- case OVar(v) => VarConstraint(v, objattr)
- case OLit(l) => LiteralConstraint(l, objattr)
- null
- }
- null
+
}
case PVar(v) => error("variable predicates require tedious enumeration; too tedious for me.")
}
state
}
- def apply (sparql:SparqlSelect, stem:StemURI, pk:PrimaryKey) : Select = {
+ def apply (db:DatabaseDesc, sparql:SparqlSelect, stem:StemURI, pk:PrimaryKey) : Select = {
val SparqlSelect(attrs, triples) = sparql
var r2rState = R2RState(
// AttributeList(List()),
@@ -184,7 +235,7 @@
Map[Var, FQAttribute]()
)
- triples.triplepatterns.foreach(s => r2rState = acc(r2rState, s, pk))
+ triples.triplepatterns.foreach(s => r2rState = acc(db, r2rState, s, pk))
Select(
r2rState.project,
--- a/src/main/scala/SQL.scala Sun Dec 13 19:17:29 2009 -0500
+++ b/src/main/scala/SQL.scala Mon Dec 14 02:11:39 2009 -0500
@@ -21,10 +21,27 @@
case class PrimaryExpressionNotNull(l:FQAttribute) extends PrimaryExpression
sealed abstract class RValue
case class RValueAttr(fqattribute:FQAttribute) extends RValue
-case class RValueInt(i:Name) extends RValue
-case class RValueString(i:Name) extends RValue
+case class RValueTyped(datatype:SQLDatatype, i:Name) extends RValue
case class Name(s:String)
+object Name {
+ implicit def fromStringToName(s:String):Name = Name(s)
+}
+
+case class SQLDatatype(name:String)
+
+object SQLDatatype {
+ val STRING = SQLDatatype("String")
+ val INTEGER = SQLDatatype("Int")
+}
+
+sealed abstract class ValueDescription
+case class Value(datatype:SQLDatatype) extends ValueDescription
+case class ForeignKey(rel:Relation, attr:Attribute) extends ValueDescription
+
+case class DatabaseDesc(relationdescs:Map[Relation,RelationDesc])
+case class RelationDesc(primaryKey:Attribute, attributes:Map[Attribute, ValueDescription])
+
case class Sql() extends JavaTokenParsers {
def select:Parser[Select] =
@@ -82,8 +99,8 @@
def rvalue:Parser[RValue] = (
fqattribute ^^ { RValueAttr(_) }
- | """[0-9]+""".r ^^ { x => RValueInt(Name(x)) }
- | "\"[^\"]*\"".r ^^ { x => RValueString(Name(x.substring(1, x.size - 1))) }
+ | """[0-9]+""".r ^^ { x => RValueTyped(SQLDatatype.INTEGER, Name(x)) }
+ | "\"[^\"]*\"".r ^^ { x => RValueTyped(SQLDatatype.STRING, Name(x.substring(1, x.size - 1))) }
)
}
--- a/src/test/scala/RDB2RDFTest.scala Sun Dec 13 19:17:29 2009 -0500
+++ b/src/test/scala/RDB2RDFTest.scala Mon Dec 14 02:11:39 2009 -0500
@@ -5,6 +5,16 @@
class RDB2RDFTest extends FunSuite {
+ val db:DatabaseDesc = DatabaseDesc(
+ Map(Relation("Employee") ->
+ RelationDesc(Attribute("id"),
+ Map(Attribute("id") -> Value(SQLDatatype.INTEGER),
+ Attribute("lastName") -> Value(SQLDatatype.STRING),
+ Attribute("width") -> Value(SQLDatatype.INTEGER),
+ Attribute("manager") -> ForeignKey(Relation("Employee"), Attribute("id")),
+ Attribute("address") -> ForeignKey(Relation("Address"), Attribute("id"))))))
+
+
test("SQLbgp") {
val sparqlParser = Sparql()
val sparqlSelect = sparqlParser.parseAll(sparqlParser.select, """
@@ -22,7 +32,7 @@
INNER JOIN Employee AS manager ON manager.id=emp.manager
WHERE emp.lastName IS NOT NULL AND manager.lastName IS NOT NULL
""").get
- assert(RDB2RDF(sparqlSelect, StemURI("http://hr.example/DB/"), PrimaryKey(Attribute(Name("id")))) === sqlSelect)
+ assert(RDB2RDF(db, sparqlSelect, StemURI("http://hr.example/DB/"), PrimaryKey(Attribute(Name("id")))) === sqlSelect)
}
--- a/src/test/scala/SQLTest.scala Sun Dec 13 19:17:29 2009 -0500
+++ b/src/test/scala/SQLTest.scala Mon Dec 14 02:11:39 2009 -0500
@@ -24,7 +24,7 @@
FROM Employee AS emp
WHERE emp.manager=18 AND emp.lastName IS NOT NULL
"""
- val expected = Select(AttributeList(List(NamedAttribute(FQAttribute(Relation(Name("emp")),Attribute(Name("lastName"))),Attribute(Name("empName"))))),TableList(List(Join(TableAlias(Relation(Name("Employee")),Relation(Name("emp"))),None))),Some(Expression(List(PrimaryExpressionEq(FQAttribute(Relation(Name("emp")),Attribute(Name("manager"))),RValueInt(Name("18"))), PrimaryExpressionNotNull(FQAttribute(Relation(Name("emp")),Attribute(Name("lastName"))))))))
+ val expected = Select(AttributeList(List(NamedAttribute(FQAttribute(Relation(Name("emp")),Attribute(Name("lastName"))),Attribute(Name("empName"))))),TableList(List(Join(TableAlias(Relation(Name("Employee")),Relation(Name("emp"))),None))),Some(Expression(List(PrimaryExpressionEq(FQAttribute(Relation(Name("emp")),Attribute(Name("manager"))),RValueTyped(SQLDatatype.INTEGER,Name("18"))), PrimaryExpressionNotNull(FQAttribute(Relation(Name("emp")),Attribute(Name("lastName"))))))))
assert(expected === (a.parseAll(a.select, e).get))
}
@@ -37,7 +37,7 @@
AND manager.lastName="Johnson"
WHERE emp.lastName IS NOT NULL
"""
- val expected = Select(AttributeList(List(NamedAttribute(FQAttribute(Relation(Name("emp")),Attribute(Name("lastName"))),Attribute(Name("empName"))))),TableList(List(Join(TableAlias(Relation(Name("Employee")),Relation(Name("emp"))),None),Join(TableAlias(Relation(Name("Employee")),Relation(Name("manager"))),Some(Expression(List(PrimaryExpressionEq(FQAttribute(Relation(Name("emp")),Attribute(Name("manager"))),RValueAttr(FQAttribute(Relation(Name("manager")),Attribute(Name("id"))))), PrimaryExpressionEq(FQAttribute(Relation(Name("manager")),Attribute(Name("lastName"))),RValueString(Name("Johnson"))))))))),Some(Expression(List(PrimaryExpressionNotNull(FQAttribute(Relation(Name("emp")),Attribute(Name("lastName"))))))))
+ val expected = Select(AttributeList(List(NamedAttribute(FQAttribute(Relation(Name("emp")),Attribute(Name("lastName"))),Attribute(Name("empName"))))),TableList(List(Join(TableAlias(Relation(Name("Employee")),Relation(Name("emp"))),None),Join(TableAlias(Relation(Name("Employee")),Relation(Name("manager"))),Some(Expression(List(PrimaryExpressionEq(FQAttribute(Relation(Name("emp")),Attribute(Name("manager"))),RValueAttr(FQAttribute(Relation(Name("manager")),Attribute(Name("id"))))), PrimaryExpressionEq(FQAttribute(Relation(Name("manager")),Attribute(Name("lastName"))),RValueTyped(SQLDatatype.STRING,Name("Johnson"))))))))),Some(Expression(List(PrimaryExpressionNotNull(FQAttribute(Relation(Name("emp")),Attribute(Name("lastName"))))))))
assert(expected === (a.parseAll(a.select, e).get))
}