--- a/src/main/scala/SparqlToSql.scala Fri Jun 11 21:46:40 2010 -0400
+++ b/src/main/scala/SparqlToSql.scala Sat Jun 12 09:27:16 2010 -0400
@@ -266,11 +266,11 @@
* @return a new R2RState incorporating the new binding
* For example, <code>SELECT ?emp WHERE { ?emp emp:lastName ?name }</code> will call varConstraint twice:
*
- * given: alias:=R_emp, optAttr:=lastName, v:=?name, rel:=Employee) ->
+ * given: alias:=R_emp, optAttr:=lastName, v:=?name, rel:=Employee ->
* return: (VarAssignable(?name),StringMapper(FullBinding(R_emp.lastName)))
* which maps "Smith" to "Smith"^^xsd:string
*
- * given: alias:=R_emp, optAttr:=empid, v:=?emp, rel:=Employee) ->
+ * given: alias:=R_emp, optAttr:=empid, v:=?emp, rel:=Employee ->
* return: (VarAssignable(?emp),RDFNoder(Employee,FullBinding(R_emp.empid)))
* which maps 4 to <http://hr.example/our/favorite/DB/Employee/id.4#record>
*/
@@ -993,7 +993,7 @@
* @param concat if true, keys will produce SQL functions to generate a URI, e.g. SELECT CONCAT(stemURI, table, "/", pk, ".", R_who.pk) AS who
* @return an SQL query corresponding to sparquery
*/
- def translate (db:sql.DatabaseDesc, sparquery:sparql.Select, stem:StemURI, enforceForeignKeys:Boolean, concat:Boolean) : (sql.Select, Map[sparql.Assignable, SQL2RDFValueMapper]) = {
+ def apply (db:sql.DatabaseDesc, sparquery:sparql.Select, stem:StemURI, enforceForeignKeys:Boolean, concat:Boolean) : (sql.Select, Map[sparql.Assignable, SQL2RDFValueMapper]) = {
val sparql.Select(attrs, triples) = sparquery
/** Create an object to hold our compilation state. */
@@ -1037,13 +1037,62 @@
case _ => Some(sql.ExprConjunction(r2rState.exprs))
}
)
- (select, r2rState.varmap)
- }
-
- def apply (db:sql.DatabaseDesc, sparquery:sparql.Select, stem:StemURI, enforceForeignKeys:Boolean, concat:Boolean) : sql.Select = {
// println("r2rState.varmap: " + r2rState.varmap)
// println("select.expression: " + select.expression)
- translate(db, sparquery, stem, enforceForeignKeys, concat)._1.makePretty() // eliminate foo.bar=foo.bar and stuff like that.
+ (select.makePretty, r2rState.varmap)
}
}
+/**
+ * Support functions to inject SparqlToSql results into an XML Results Set.
+ * @example:
+ * <pre>
+ * val xmlres:String =
+ * head(List[String]("emp", "name")) +
+ * startresult +
+ * binding("emp", "253", rdfmap, stem) +
+ * binding("name", "Bob", rdfmap, stem) +
+ * endresult +
+ * foot
+ * </pre>
+ *
+ * @see {@link w3c.sw.sparql2sql.SparqlToSql}
+ * @see {@link http://www.w3.org/TR/2008/REC-rdf-sparql-XMLres-20080115/ XML Results Format}
+ */
+object SqlToXMLRes {
+ def head (vars:List[String]) : String = {
+ "<?xml version=\"1.0\"?>\n<sparql xmlns=\"http://www.w3.org/2005/sparql-results#\">\n <head>\n" +
+ vars.map(varname => " <variable name=\"" + varname + "\"/>\n").mkString +
+ " </head>\n\n <results>\n"
+ }
+ def startresult () : String = {
+ " <result> \n"
+ }
+ def binding (name:String, value:String, varmap:Map[sparql.Assignable, SparqlToSql.SQL2RDFValueMapper], stem:StemURI) : String = {
+ def getattr (b:SparqlToSql.FullOrPartialBinding) : sql.Attribute = {
+ b match {
+ case SparqlToSql.FullBinding(sql.RelVarAttr(_, attr)) =>
+ attr
+ case SparqlToSql.PartialBinding(binders) => {
+ val SparqlToSql.BindingConstraint(expr, sql.RelVarAttr(rv, attr)) = binders.toList(0)
+ attr
+ }
+ }
+ }
+ val t:String = varmap(sparql.VarAssignable(sparql.Var(name))) match {
+ case SparqlToSql.RDFNoder(rel, b) => "<uri>" + stem.s + rel + "/" + getattr(b) + "." + value + "#record</uri>"
+ case SparqlToSql.RDFBNoder(rel, b) => "<bnode>bnode_" + rel + "/" + getattr(b) + "." + value + "</bnode>"
+ case SparqlToSql.DateMapper(_) => "<literal datatype=\"http://www.w3.org/2001/XMLSchema#date\">" + value + "</literal>"
+ case SparqlToSql.IntMapper(_) => "<literal datatype=\"http://www.w3.org/2001/XMLSchema#integer\">" + value + "</literal>"
+ case SparqlToSql.StringMapper(_) => "<literal datatype=\"http://www.w3.org/2001/XMLSchema#string\">" + value + "</literal>"
+ }
+ " <binding name=\"" + name + "\">\n " + t + "\n </binding>\n"
+ }
+ def endresult () : String = {
+ " </result>\n"
+ }
+ def foot () : String = {
+ " </results>\n</sparql>\n"
+ }
+}
+
--- a/src/test/scala/SparqlToSqlTest.scala Fri Jun 11 21:46:40 2010 -0400
+++ b/src/test/scala/SparqlToSqlTest.scala Sat Jun 12 09:27:16 2010 -0400
@@ -8,7 +8,7 @@
import java.net.URI
import w3c.sw.sql.{Sql,DatabaseDesc,Relation,RelationDesc,Attribute,Value,Datatype,ForeignKey,Name}
import w3c.sw.sparql.Sparql
-import w3c.sw.sparql2sql.{SparqlToSql,StemURI}
+import w3c.sw.sparql2sql.{SparqlToSql,StemURI,SqlToXMLRes}
/* The SparqlToSqlTest class transforms SPARQL queries to a relational data
* structure and compares them to a structure parsed from SQL.
@@ -167,7 +167,7 @@
INNER JOIN Employee AS R_empid18
WHERE R_empid18.empid=R_emp.manager AND R_empid18.empid=18 AND R_emp.empid IS NOT NULL
""").get
- val generated = SparqlToSql(db, sparqlSelect, StemURI("http://hr.example/DB/"), true, false)
+ val generated = SparqlToSql(db, sparqlSelect, StemURI("http://hr.example/DB/"), true, false)._1
assert(generated === parsed)
val output = """
+-----+
@@ -178,6 +178,53 @@
"""
}
+ /* Re-interpret native format: */
+ test("RDF(?s)") {
+ val sparqlParser = Sparql()
+ val sparqlSelect = sparqlParser.parseAll(sparqlParser.select, """
+PREFIX empP : <http://hr.example/DB/Employee#>
+SELECT ?emp {
+?emp empP:manager <http://hr.example/DB/Employee/empid.18#record>
+}
+""").get
+ val sqlParser = Sql()
+ val parsed = sqlParser.parseAll(sqlParser.select, """
+SELECT R_emp.empid AS emp
+ FROM Employee AS R_emp
+ INNER JOIN Employee AS R_empid18
+ WHERE R_empid18.empid=R_emp.manager AND R_empid18.empid=18 AND R_emp.empid IS NOT NULL
+""").get
+ val xmlres = """<?xml version="1.0"?>
+<sparql xmlns="http://www.w3.org/2005/sparql-results#">
+ <head>
+ <variable name="emp"/>
+ </head>
+
+ <results>
+ <result>
+ <binding name="emp">
+ <uri>http://hr.example/DB/Employee/empid.253#record</uri>
+ </binding>
+ </result>
+ </results>
+</sparql>
+""" //"//
+ val stem = StemURI("http://hr.example/DB/")
+ val (generated, rdfmap) = SparqlToSql(db, sparqlSelect, stem, true, false)
+ val head = SqlToXMLRes.head(List[String]("emp"))
+ val body = SqlToXMLRes.startresult + SqlToXMLRes.binding("emp", "253", rdfmap, stem) + SqlToXMLRes.endresult
+ val foot = SqlToXMLRes.foot
+ assert(generated === parsed)
+ assert(head + body + foot === xmlres)
+ val output = """
++-----+
+| emp |
++-----+
+| 253 |
++-----+
+"""
+ }
+
/* Enable turtle string-izing and test URI generation: */
test("SELECT <x> { ?sf <p> <x>} (in-SQL Nodizer)") {
val sparqlParser = Sparql()
@@ -194,7 +241,7 @@
INNER JOIN Employee AS R_empid18
WHERE R_empid18.empid=R_emp.manager AND R_empid18.empid=18 AND R_emp.empid IS NOT NULL
""").get
- val generated = SparqlToSql(db, sparqlSelect, StemURI("http://hr.example/DB/"), true, true)
+ val generated = SparqlToSql(db, sparqlSelect, StemURI("http://hr.example/DB/"), true, true)._1
assert(generated === parsed)
val output = """
+------------------------------------------------+
@@ -220,7 +267,7 @@
FROM Employee AS R_emp
WHERE R_emp.empid IS NOT NULL AND R_emp.lastName IS NOT NULL
""").get
- val generated = SparqlToSql(db, sparqlSelect, StemURI("http://hr.example/DB/"), true, true)
+ val generated = SparqlToSql(db, sparqlSelect, StemURI("http://hr.example/DB/"), true, true)._1
assert(generated === parsed)
val output = """
+----------------------------------------------------+
@@ -250,7 +297,7 @@
INNER JOIN Employee AS R_manager
WHERE R_manager.empid=R_empid253.manager AND R_empid253.empid=253
""").get
- val generated = SparqlToSql(db, sparqlSelect, StemURI("http://hr.example/DB/"), true, false)
+ val generated = SparqlToSql(db, sparqlSelect, StemURI("http://hr.example/DB/"), true, false)._1
assert(generated === parsed)
val output = """
+---------+
@@ -279,7 +326,7 @@
INNER JOIN Employee AS R_18
WHERE R_18.empid=R_emp.manager AND R_18.empid=18 AND R_emp.empid IS NOT NULL
""").get
- val generated = SparqlToSql(db, sparqlSelect, StemURI("http://hr.example/DB/"), true, false)
+ val generated = SparqlToSql(db, sparqlSelect, StemURI("http://hr.example/DB/"), true, false)._1
assert(generated === parsed)
val output = """
+-----+
@@ -308,7 +355,7 @@
INNER JOIN TaskAssignments AS R_task2 ON R_who.empid=R_task2.employee
WHERE R_task1.id<R_task2.id
""").get
- val generated = SparqlToSql(db, sparqlSelect, StemURI("http://hr.example/DB/"), true, false)
+ val generated = SparqlToSql(db, sparqlSelect, StemURI("http://hr.example/DB/"), true, false)._1
assert(generated === parsed)
val output = """
+-------+-------+
@@ -339,7 +386,7 @@
INNER JOIN Employee AS R_manager ON R_manager.empid=R_emp.manager
WHERE R_emp .lastName IS NOT NULL AND R_manager.lastName IS NOT NULL
""").get
- val generated = SparqlToSql(db, sparqlSelect, StemURI("http://hr.example/DB/"), true, false)
+ val generated = SparqlToSql(db, sparqlSelect, StemURI("http://hr.example/DB/"), true, false)._1
assert(generated === parsed)
val output = """
+---------+------------+
@@ -367,7 +414,7 @@
FROM Employee AS R_emp
WHERE R_emp.manager=18 AND R_emp.lastName IS NOT NULL
""").get
- val generated = SparqlToSql(db, sparqlSelect, StemURI("http://hr.example/DB/"), false, false)
+ val generated = SparqlToSql(db, sparqlSelect, StemURI("http://hr.example/DB/"), false, false)._1
assert(generated === parsed)
val output = """
+---------+
@@ -394,7 +441,7 @@
INNER JOIN Employee AS R_empid18
WHERE R_empid18.empid=R_emp.manager AND R_empid18.empid=18 AND R_emp.lastName IS NOT NULL
""").get
- val generated = SparqlToSql(db, sparqlSelect, StemURI("http://hr.example/DB/"), true, false)
+ val generated = SparqlToSql(db, sparqlSelect, StemURI("http://hr.example/DB/"), true, false)._1
assert(generated === parsed)
val output = """
+---------+
@@ -424,7 +471,7 @@
INNER JOIN Employee AS R_manager
WHERE R_manager.empid=R_emp.manager AND R_manager.lastName="Johnson" AND R_emp.lastName IS NOT NULL
""").get
- val generated = SparqlToSql(db, sparqlSelect, StemURI("http://hr.example/DB/"), true, false)
+ val generated = SparqlToSql(db, sparqlSelect, StemURI("http://hr.example/DB/"), true, false)._1
assert(generated === parsed)
val output = """
+---------+
@@ -470,7 +517,7 @@
WHERE R_taskLead.birthday<R_emp.birthday AND R_grandManager.birthday<R_taskLead.birthday
AND R_emp.lastName IS NOT NULL AND R_grandManager.lastName IS NOT NULL
""").get
- val generated = SparqlToSql(db, sparqlSelect, StemURI("http://hr.example/DB/"), true, false)
+ val generated = SparqlToSql(db, sparqlSelect, StemURI("http://hr.example/DB/"), true, false)._1
assert(generated === parsed)
val output = """
+---------+----------------+
@@ -531,7 +578,7 @@
AND (G_union1._DISJOINT_!=0 OR G_union1.who=R_who.empid)
AND (G_union1._DISJOINT_!=1 OR G_union1.who=R_who.empid)
""").get
- val generated = SparqlToSql(db, sparqlSelect, StemURI("http://hr.example/DB/"), false, false)
+ val generated = SparqlToSql(db, sparqlSelect, StemURI("http://hr.example/DB/"), false, false)._1
assert(generated === parsed)
val output = """
+---------+
@@ -595,7 +642,7 @@
AND (G_union0._DISJOINT_!=1 OR R_who.empid=G_union0.who)
AND R_who.lastName="Smith"
""").get // !!! AND (G_union0.bday IS NOT NULL) AND (G_union0.who IS NOT NULL)
- val generated = SparqlToSql(db, sparqlSelect, StemURI("http://hr.example/DB/"), false, false)
+ val generated = SparqlToSql(db, sparqlSelect, StemURI("http://hr.example/DB/"), false, false)._1
assert(generated === parsed)
val output = """
"""
@@ -650,7 +697,7 @@
AND (G_union1._DISJOINT_!=1 OR G_union1.who=R_who.empid)
AND R_who.birthday IS NOT NULL AND R_who.lastName="Smith"
""").get
- val generated = SparqlToSql(db, sparqlSelect, StemURI("http://hr.example/DB/"), false, false)
+ val generated = SparqlToSql(db, sparqlSelect, StemURI("http://hr.example/DB/"), false, false)._1
assert(generated === parsed)
val output = """
"""
@@ -705,7 +752,7 @@
AND (G_union1._DISJOINT_!=1 OR R_who.birthday=G_union1.bday)
AND R_who.lastName="Smith"
""").get
- val generated = SparqlToSql(db, sparqlSelect, StemURI("http://hr.example/DB/"), false, false)
+ val generated = SparqlToSql(db, sparqlSelect, StemURI("http://hr.example/DB/"), false, false)._1
assert(generated === parsed)
val output = """
"""
@@ -736,7 +783,7 @@
) AS G_opt1 ON G_opt1.emp=R_emp.empid
WHERE R_emp.empid IS NOT NULL AND R_emp.lastName IS NOT NULL
""").get
- val generated = SparqlToSql(db, sparqlSelect, StemURI("http://hr.example/DB/"), false, false)
+ val generated = SparqlToSql(db, sparqlSelect, StemURI("http://hr.example/DB/"), false, false)._1
assert(generated === parsed)
val output = """
"""
@@ -767,7 +814,7 @@
WHERE (G_opt1._DISJOINT_ IS NULL OR R_emp.empid=G_opt1.emp)
AND R_emp.lastName IS NOT NULL
""").get
- val generated = SparqlToSql(db, sparqlSelect, StemURI("http://hr.example/DB/"), false, false)
+ val generated = SparqlToSql(db, sparqlSelect, StemURI("http://hr.example/DB/"), false, false)._1
assert(generated === parsed)
val output = """
"""
@@ -805,7 +852,7 @@
) AS G_opt1 ON G_opt1.emp=R_emp.empid
WHERE R_emp.empid IS NOT NULL AND R_emp.lastName IS NOT NULL
""").get
- val generated = SparqlToSql(db, sparqlSelect, StemURI("http://hr.example/DB/"), false, false)
+ val generated = SparqlToSql(db, sparqlSelect, StemURI("http://hr.example/DB/"), false, false)._1
assert(generated === parsed)
val output = """
"""
@@ -850,7 +897,7 @@
AND R_emp2.empid IS NOT NULL AND R_emp2.lastName<R_emp3.lastName
AND R_emp3.lastName<R_emp4.lastName AND R_emp1.empid IS NOT NULL
""").get
- val generated = SparqlToSql(db, sparqlSelect, StemURI("http://hr.example/DB/"), false, false)
+ val generated = SparqlToSql(db, sparqlSelect, StemURI("http://hr.example/DB/"), false, false)._1
assert(generated === parsed)
val output = """
"""
@@ -936,7 +983,7 @@
AND R_patient.MiddleName IS NOT NULL
AND R_sexEntry.EntryName IS NOT NULL
""").get // AND G_opt6.patient IS NULL
- val generated = SparqlToSql(hosp1, sparqlSelect, StemURI("http://hospital.example/DB/"), false, false)
+ val generated = SparqlToSql(hosp1, sparqlSelect, StemURI("http://hospital.example/DB/"), false, false)._1
assert(generated === parsed)
val output = """
"""
@@ -1013,7 +1060,7 @@
AND R_patient.MiddleName IS NOT NULL
AND R_sexEntry.EntryName IS NOT NULL
""").get
- val generated = SparqlToSql(hosp1, sparqlSelect, StemURI("http://hospital.example/DB/"), false, false)
+ val generated = SparqlToSql(hosp1, sparqlSelect, StemURI("http://hospital.example/DB/"), false, false)._1
assert(generated === parsed)
val output = """
"""