~ the servlet can execute the query against the dataset and return some results
authorAlexandre Bertails <bertails@w3.org>
Fri, 11 Jun 2010 21:45:18 -0400
changeset 202 3e73146b970d
parent 199 f0b45bdd59f7
child 203 d684b9cd3b0c
~ the servlet can execute the query against the dataset and return some results
project/build/RDB2RDF.scala
src/main/scala/Servlet.scala
--- a/project/build/RDB2RDF.scala	Fri Jun 11 18:57:29 2010 -0400
+++ b/project/build/RDB2RDF.scala	Fri Jun 11 21:45:18 2010 -0400
@@ -11,4 +11,6 @@
   val jetty6 = "org.mortbay.jetty" % "jetty" % "6.1.14" % "test"
   val servlet = "javax.servlet" % "servlet-api" % "2.5" % "provided" 
 
+  val mysql = "mysql" % "mysql-connector-java" % "5.1.12"
+
 }
--- a/src/main/scala/Servlet.scala	Fri Jun 11 18:57:29 2010 -0400
+++ b/src/main/scala/Servlet.scala	Fri Jun 11 21:45:18 2010 -0400
@@ -3,9 +3,12 @@
 import javax.servlet.http.{HttpServlet, HttpServletRequest, HttpServletResponse} 
 import scala.xml.XML
 
+import java.sql.{DriverManager, Connection, Statement, ResultSet}
+
 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.sql
 import w3c.sw.sparql2sql.{SparqlToSql,StemURI}
 
 object Config {
@@ -37,7 +40,51 @@
 """
   val db:DatabaseDesc = DDLParser.parseAll(DDLParser.ddl, dbDdl).get
 
+  val defaultSparqlQuery = """PREFIX empP : <http://hr.example/DB/Employee#>
+PREFIX xsd : <http://www.w3.org/2001/XMLSchema#>
+SELECT ?emp {
+?emp  empP:manager    "18"^^xsd:integer
 }
+"""
+
+  val defaultStemURI = "http://hr.example/DB/"
+
+}
+
+object Control {
+
+  private def using[Closeable <: {def close(): Unit}, B](closeable: Closeable)(getB: Closeable => B): B =
+    try {
+      getB(closeable)
+    } finally {
+      closeable.close()
+    }
+
+  private def bmap[T](test: => Boolean)(block: => T): List[T] = {
+    val ret = new scala.collection.mutable.ListBuffer[T]
+    while(test) ret += block
+    ret.toList
+  }
+
+  /** Executes the SQL and processes the result set using the specified function. */
+  private def query[B](connection: Connection, sql: String)(process: ResultSet => B): B =
+    using (connection) { connection =>
+      using (connection.createStatement) { statement =>
+        using (statement.executeQuery(sql)) { results =>
+          process(results)
+        }
+      }
+    }
+
+  /** Executes the SQL and uses the process function to convert each row into a T. */
+  def queryEach[T](connection: Connection, sql: String)(process: ResultSet => T): List[T] =
+    query(connection, sql) { results =>
+      bmap(results.next) {
+        process(results)
+      }
+    }
+}
+
 
 class SparqlEndpoint extends HttpServlet {
 
@@ -45,11 +92,7 @@
 
   override def doGet(request:HttpServletRequest, response:HttpServletResponse) {
 
-    val r = request.getParameter("query")
-
-    println(r)
-
-    r match {
+    request.getParameter("query") match {
       case null | "" => processIndex(request, response)
       case query     => processSparql(request, response, query)
     }
@@ -58,11 +101,39 @@
 
   def processSparql(request:HttpServletRequest, response:HttpServletResponse, query:String) {
 
-    val DDLParser = Sql()
+    val stemURI:StemURI = StemURI(Some(request.getParameter("stemuri")) getOrElse Config.defaultStemURI)
 
+    val sparqlParser = Sparql()
+
+    val sparqlSelect = sparqlParser.parseAll(sparqlParser.select, query).get
+
+    val generated:sql.Select = SparqlToSql(Config.db, sparqlSelect, stemURI, true, false)
+
+    Class.forName("com.mysql.jdbc.Driver").newInstance
+    val connection:Connection = DriverManager.getConnection("jdbc:mysql://localhost/rdb2rdf", "root", "")
+    if (! connection.isClosed) println("Successfully connected")
+
+    import java.sql.{Types => T}
+
+    def f(rs:ResultSet):List[String] = {
+      val metadata = rs.getMetaData
+      val l = for(i <- 1 to metadata.getColumnCount) yield {
+	val t = metadata.getColumnType(i)
+	t match {
+	  case T.VARCHAR => "<VARCHAR:" + rs.getString(i) + ">"
+	  case T.INTEGER => "<INTEGER:" + rs.getInt(i) + ">"
+	  case T.DATE    => "<DATE:" + rs.getDate(i) + ">"
+	  case _         => "<NONMAPPED>"
+	}
+      }
+      l.toList
+    }
+
+    val rows = Control.queryEach(connection, generated.toString) { rs => f(rs) mkString " " }
+    
     response.setContentType("text/plain; charset='" + encoding + "'")
 
-    response.getWriter.write("yo")
+    response.getWriter.write(rows mkString "\n")
 
   }
 
@@ -74,8 +145,11 @@
 	<body>
 	  <h1>RDB2RDF Sparql endpoint</h1>
 	  <form action="sparql">
-            <p><textarea rows="10" cols="80" name="query" id="query">your query here</textarea>
-	    <input type="submit" /></p>
+            <p>
+              StemURI: <input cols="80" name="stemuri" id="stemuri" value={ Config.defaultStemURI } /><br />
+              <textarea rows="10" cols="80" name="query" id="query">{ Config.defaultSparqlQuery }</textarea>
+	      <input type="submit" />
+            </p>
 	  </form>
 	  <hr />
 	  <address>