org.apache.jena.sdb.store.SQLBridgeBase Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of jena-sdb Show documentation
Show all versions of jena-sdb Show documentation
SDB is a persistence layer for use with Apache Jena that uses an SQL database to store triples/quads.
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.jena.sdb.store;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.apache.jena.sdb.SDB ;
import org.apache.jena.sdb.compiler.SqlBuilder ;
import org.apache.jena.sdb.core.AliasesSql ;
import org.apache.jena.sdb.core.Annotation1 ;
import org.apache.jena.sdb.core.SDBRequest ;
import org.apache.jena.sdb.core.sqlexpr.SqlColumn ;
import org.apache.jena.sdb.core.sqlnode.ColAlias ;
import org.apache.jena.sdb.core.sqlnode.SqlNode ;
import org.apache.jena.sdb.shared.SDBInternalError ;
import org.apache.jena.sdb.sql.RS ;
import org.apache.jena.sdb.sql.ResultSetJDBC ;
import org.apache.jena.sdb.sql.SDBExceptionSQL ;
import org.apache.jena.sparql.core.Var ;
import org.apache.jena.sparql.engine.ExecutionContext ;
import org.apache.jena.sparql.engine.QueryIterator ;
import org.apache.jena.sparql.engine.binding.Binding ;
import org.apache.jena.sparql.engine.iterator.QueryIter ;
import org.apache.jena.sparql.engine.iterator.QueryIterPlainWrapper ;
/** Convert from whatever results a particular layout returns into
* an ARQ QueryIterator of Bindings. An SQLBridge object
* is allocated for each query execution.
*/
public abstract class SQLBridgeBase implements SQLBridge
{
// Always need to allocate a label for a column
// because can't access by table.column
private MapvarLabels = new HashMap() ;
private Annotation1 annotation = new Annotation1() ;
private Collection projectVars = null ;
private SqlNode sqlNodeOriginal = null ;
private SqlNode sqlNode = null ; // Subclass can mutate
protected final SDBRequest request ;
protected SQLBridgeBase(SDBRequest request, SqlNode sqlNode, Collection projectVars)
{
this.request = request ;
this.sqlNodeOriginal = sqlNode ;
this.projectVars = projectVars ;
this.sqlNode = sqlNode ;
}
@Override
public final
void build()
{
buildValues() ;
buildProject() ;
}
protected abstract void buildValues() ;
protected abstract void buildProject() ;
// Build next row from the JDBC ResultSet
protected abstract Binding assembleBinding(ResultSetJDBC rs, Binding binding) ;
@Override
final
public QueryIterator assembleResults(ResultSetJDBC rs, Binding binding, ExecutionContext execCxt)
{
if ( execCxt == null || execCxt.getContext().isTrueOrUndef(SDB.jdbcStream) )
{
// Stream
return new QueryIterSQL(rs, binding, execCxt) ;
}
// Debugging or problems with unreleasing JDBC ResultSets - read all in now.
QueryIterator qIter = new QueryIterSQL(rs, binding, execCxt) ;
List results = new ArrayList() ;
for ( ; qIter.hasNext() ; )
results.add(qIter.nextBinding()) ;
qIter.close() ;
return new QueryIterPlainWrapper(results.iterator(), execCxt) ;
}
private void setProjectVars(Collection projectVars)
{
if ( this.projectVars != null )
throw new SDBInternalError("SQLBridgeBase: Project vars already set") ;
this.projectVars = projectVars ;
}
protected SqlNode getSqlExprNode() { return sqlNodeOriginal ; }
@Override
public SqlNode getSqlNode() { return sqlNode ; }
protected void setSqlNode(SqlNode sqlNode2) { sqlNode = sqlNode2 ; }
protected Collection getProject() { return projectVars ; }
// ---- value support
// ---- project support
protected void addProject(SqlColumn col, String colOutName)
{
sqlNode = SqlBuilder.project(request,
sqlNode,
new ColAlias(col, new SqlColumn(null, colOutName))) ;
}
protected void addAnnotation(String string)
{
annotation.addAnnotation(string) ;
}
protected void setAnnotation()
{
annotation.setAnnotation(sqlNode) ;
}
// ---- Var allocation
protected String allocSqlName(Var v)
{
String sqlVarName = varLabels.get(v) ;
if ( sqlVarName == null )
{
sqlVarName = request.genId(AliasesSql.VarBase) ;
varLabels.put(v, sqlVarName) ;
}
return sqlVarName ;
}
protected String getSqlName(Var v) { return varLabels.get(v) ; }
private class QueryIterSQL extends QueryIter
{
boolean ready = false ;
boolean hasNext = false ;
private ResultSetJDBC jdbcResultSet ;
private Binding parent ;
QueryIterSQL(ResultSetJDBC rs, Binding binding, ExecutionContext execCxt)
{
super(execCxt) ;
this.jdbcResultSet = rs ;
this.parent = binding ;
}
@Override
protected void closeIterator()
{
RS.close(jdbcResultSet) ;
jdbcResultSet = null ;
}
@Override
protected boolean hasNextBinding()
{
if (!ready)
{
try
{
hasNext = jdbcResultSet.get().next() ;
} catch (SQLException ex)
{
closeIterator() ;
throw new SDBExceptionSQL(ex) ;
}
ready = true ;
}
return hasNext ;
}
@Override
protected Binding moveToNextBinding()
{
// if ( ! hasNextBinding() )
// return null ;
ready = false ; // Must set the state to 'unknown'.
return assembleBinding(jdbcResultSet, parent) ;
}
// Asynchronous request to cancel. ARQ 2.8.8 and later.
@Override
protected void requestCancel()
{}
}
}