📄 pset_triplestore_rdb.java
字号:
/*
(c) Copyright 2003, 2004, 2005, 2006, 2007 Hewlett-Packard Development Company, LP
[See end of file]
$Id: PSet_TripleStore_RDB.java,v 1.57 2007/01/02 11:50:42 andy_seaborne Exp $
*/
package com.hp.hpl.jena.db.impl;
import java.sql.BatchUpdateException;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.*;
import com.hp.hpl.jena.db.RDFRDBException;
import com.hp.hpl.jena.db.impl.DriverRDB;
import com.hp.hpl.jena.graph.*;
import com.hp.hpl.jena.shared.*;
import com.hp.hpl.jena.util.iterator.ExtendedIterator;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
//=======================================================================
/**
* Handles Physical storage for implementing SpecializedGraphs.
* Different PSet classes are needed for different databases and different
* layout schemes.
* <p>
* This class is a base implemention from which database-specific
* drivers can inherit. It is not generic in the sense that it will work
* on any minimal SQL store and so should be treated as if it were
* an abstract class.
* <p>The SQL statements which implement each of the functions are
* loaded in a separate file etc/[layout]_[database].sql from the classpath.
* See {@link SQLCache SQLCache documentation} for more information on the
* format of this file.
*
* Based on Driver* classes by Dave Reynolds.
*
* @author <a href="mailto:harumi.kuno@hp.com">Harumi Kuno</a>
* @version $Revision: 1.57 $ on $Date: 2007/01/02 11:50:42 $
*/
public class PSet_TripleStore_RDB implements IPSet {
//=======================================================================
// Cutomization variables
/**
* Holds name of AssertedStatement table (defaults to JENA_SYS_AssStatements).
* Every triple store has at least one tables for AssertedStatements.
*/
public String m_tblName = null;
/** The SQL type to use for storing ids (compatible with wrapDBID) */
protected String ID_SQL_TYPE = null;
/** Set to true if the insert operations already check for duplications */
protected boolean SKIP_DUPLICATE_CHECK = false;
/** Set to true to enable cache of pre-prepared statements */
protected boolean CACHE_PREPARED_STATEMENTS = true;
/** The table of sql driver statements */
protected SQLCache m_sql = null;
//=======================================================================
// Internal variables
/** default size for literal and resource caches */
protected final static int DEFAULT_CACHE = 1000;
/** Cache of literals */
protected ICache literalCache = new SimpleCache(DEFAULT_CACHE);
/** Cache of resources */
protected ICache resourceCache = new SimpleCache(DEFAULT_CACHE);
/**
* The IRDBDriver for the database.
*/
protected IRDBDriver m_driver = null;
//=======================================================================
// Constructors and accessors
/**
* Constructor.
*/
public PSet_TripleStore_RDB(){
}
/**
* Link an existing instance of the IPSet to a specific driver
*/
public void setDriver(IRDBDriver driver) throws RDFRDBException {
m_driver = driver;
}
protected static Log logger = LogFactory.getLog(PSet_TripleStore_RDB.class);
public void setSQLType(String value) { ID_SQL_TYPE = value; }
public void setSkipDuplicateCheck(boolean value) { SKIP_DUPLICATE_CHECK = value;}
public void setSQLCache(SQLCache cache ) { m_sql = cache; }
public SQLCache getSQLCache() { return m_sql; }
public void setCachePreparedStatements(boolean value) { CACHE_PREPARED_STATEMENTS = value; }
/**
* Sets m_tblName variable.
* @param tblName the name of the Statement Table
*/
public void setTblName(String tblName){
m_tblName = tblName;
}
/**
* Accessor for m_tblName.
* @return name of the Statement table.
*/
public String getTblName() {
return m_tblName;
}
/**
* Close this PSet
*/
public void close() {
// no need to do anything here for now
}
/**
* @return the database driver.
*/
public IRDBDriver driver() {
return m_driver;
}
/**
* Remove all RDF information about this pset from a database.
*/
public void cleanDB() {
// drop my own table(s)
try {
m_sql.runSQLGroup("dropStatementTable",getTblName());
} catch (SQLException e) {
logger.warn( "Problem dropping table " + getTblName(), e );
throw new RDFRDBException("Failed to drop table ", e);
}
}
/**
* Printable name for the driver configuration
*/
public String toString() {
return this.getClass().getPackage().getName();
}
/**
* Fetch a literal from the cache just knowing its literal rdb-id.
* If it is not in the cache, do not attempt to retrieve it from the database.
*/
public Node_Literal getLiteralFromCache(IDBID id) {
return (Node_Literal) literalCache.get(id);
}
/**
* Convert the raw SQL object used to store a database identifier into a java object
* which meets the IDBID interface.
*/
public IDBID wrapDBID(Object id) throws RDFRDBException {
if (id instanceof Number) {
return new DBIDInt(((Number)id).intValue());
} else if (id == null) {
return null;
} else {
throw new RDFRDBException("Unexpected DB identifier type: " + id);
//return null;
}
}
/**
* Compute the number of rows in a table.
*
* @return int count.
*/
public int rowCount(int gid) {
String tName = getTblName();
int result = 0;
ResultSet rs=null;
try {
String op = "getRowCount";
PreparedStatement ps = m_sql.getPreparedSQLStatement(op,tName);
ps.setInt(1, gid);
rs = ps.executeQuery();
while ( rs.next() ) result = rs.getInt(1);
m_sql.returnPreparedSQLStatement(ps);
} catch (SQLException e) {
logger.debug("tried to count rows in " + tName);
logger.debug("Caught exception: ", e);
throw new JenaException("Exception during database access", e); // Rethrow in case there is a recovery option
} finally {
if (rs != null)
try {
rs.close();
} catch (SQLException e1) {
throw new RDFRDBException("Failed to get last inserted ID: " + e1);
}
}
return result;
}
//=======================================================================
// Patched functions to adapt to oracle jdbc driver expectations
/**
* Convert the current row of a result set from a ResultSet
* to a Triple.
* Expects row to contain:
* S.SubjRes, S.PropRes, S.ObjRes, S.ObjStr, S.ObjLiteral
* @param rs the resultSet to be processed.
*/
public Triple extractTripleFromRowData(
String subj,
String pred,
String obj) {
Node subjNode = subj == null ? null : m_driver.RDBStringToNode(subj);
Node predNode = pred == null ? null : m_driver.RDBStringToNode(pred);
Node objNode = obj == null ? null : m_driver.RDBStringToNode(obj);
return ( Triple.create(subjNode, predNode, objNode) );
}
/**
* Wrap up a boolean flag as a object which the jdbc driver can assert into a boolean/short column.
*/
public Object wrapFlag(boolean flag) {
return flag ? new Short((short)1) : new Short((short)0);
}
/**
*
* Attempt to remove a statement from an Asserted_Statement table,
* if it is present. Return without error if the statement is not
* present.
*
* @param subj_uri is the URI of the subject
* @param pred_uri is the URI of the predicate (property)
* @param obj_node is the URI of the object (can be URI or literal)
* @param graphID is the ID of the graph
* @param complete is true if this handler is capable of adding this triple.
*
**/
public void deleteTriple(Triple t, IDBID graphID) {
deleteTriple(t, graphID, false, null);
}
/**
*
* Attempt to remove a statement from an Asserted_Statement table,
* if it is present. Return without error if the statement is not
* present.
*
* @param subj_uri is the URI of the subject
* @param pred_uri is the URI of the predicate (property)
* @param obj_node is the URI of the object (can be URI or literal)
* @param graphID is the ID of the graph
* @param complete is true if this handler is capable of adding this triple.
*
**/
public void deleteTriple(Triple t, IDBID graphID, boolean isBatch,
Hashtable batchedPreparedStatements) {
deleteTripleAR(t,graphID,null,isBatch,batchedPreparedStatements);
}
/**
*
* Attempt to remove a statement from an Asserted_Statement table,
* if it is present. Return without error if the statement is not
* present.
*
* @param subj_uri is the URI of the subject
* @param pred_uri is the URI of the predicate (property)
* @param obj_node is the URI of the object (can be URI or literal)
* @param stmtURI is the URI of the statement if reified, null for asserted
* @param graphID is the ID of the graph
* @param complete is true if this handler is capable of adding this triple.
*
**/
public void deleteTripleAR(
Triple t,
IDBID graphID,
Node reifNode,
boolean isBatch,
Hashtable batchedPreparedStatements) {
boolean isReif = reifNode != null;
String subj =
t.getSubject().equals(Node.NULL) ? null : m_driver.nodeToRDBString(t.getSubject(),false);
String pred =
t.getPredicate().equals(Node.NULL) ? null : m_driver.nodeToRDBString(t.getPredicate(),false);
String obj =
t.getObject() == Node.ANY ? null : m_driver.nodeToRDBString(t.getObject(),false);
// String gid = graphID.getID().toString();
int gid = ((DBIDInt) graphID).getIntID();
int argc = 1;
String stmtStr;
if ((subj == null) || (pred == null) || (obj == null)) {
// throw new JenaException("Attempt to delete triple with missing values");
// used to think this was an exception. i guess it's not.
return;
}
// get statement string
PreparedStatement ps = null;
stmtStr = isReif ? "deleteReified" : "deleteStatement";
try {
ps =
getPreparedStatement(
stmtStr,
getTblName(),
isBatch,
batchedPreparedStatements);
//ps.clearParameters();
} catch (SQLException e1) {
logger.debug( "SQLException caught " + e1.getErrorCode(), e1);
throw new JenaException("Exception during database access", e1); // Rethrow in case there is a recovery option
}
// now fill in parameters
try {
ps.setString(argc++, subj);
ps.setString(argc++, pred);
ps.setString(argc++, obj);
ps.setInt(argc++, gid);
if (isReif) {
String stmtURI = m_driver.nodeToRDBString(reifNode,false);
ps.setString(argc++, stmtURI);
ps.setString(argc++,"T");
}
} catch (SQLException e1) {
logger.debug("(in delete) SQLException caught ", e1);
throw new JenaException("Exception during database access", e1); // Rethrow in case there is a recovery option
}
try {
if (isBatch) {
ps.addBatch();
} else {
ps.executeUpdate();
m_sql.returnPreparedSQLStatement(ps);
}
} catch (SQLException e1) {
logger.error("Exception executing delete: ", e1);
throw new JenaException("Exception during database access", e1); // Rethrow in case there is a recovery option
}
}
/**
*
* Attempt to store a statement into an Asserted_Statement table.
*
* @param subj_uri is the URI of the subject
* @param pred_uri is the URI of the predicate (property)
* @param obj_node is the URI of the object (can be URI or literal)
* @param graphID is the ID of the graph
* @param complete is true if this handler is capable of adding this triple.
*
**/
public void storeTriple(Triple t, IDBID graphID) {
storeTriple(t,graphID,false, null);
}
/**
* Given an operation name, a table name, whether or not this operation is part of a batched update, and
* a table of batched prepared statements, find or create an appropriate PreparedStatement.
*
* @param op
* @param tableName
* @param isBatch
* @param batchedPreparedStatements
* @return the prepared statement
* @throws SQLException
*/
public PreparedStatement getPreparedStatement(String op,
String tableName,
boolean isBatch,
Hashtable batchedPreparedStatements) throws SQLException {
PreparedStatement ps = null;
String opname = SQLCache.concatOpName(op,tableName);
if (isBatch) {
ps = (PreparedStatement) batchedPreparedStatements.get(opname);
if (ps == null) {
ps = m_sql.getPreparedSQLStatement(op,tableName);
batchedPreparedStatements.put(opname,ps);
}
} else {
ps = m_sql.getPreparedSQLStatement(op,tableName);
}
if (ps == null) {
logger.error("prepared statement not found for " + opname);
}
return ps;
}
/**
*
* Attempt to store a statement into an Asserted_Statement table.
*
* @param subj_uri is the URI of the subject
* @param pred_uri is the URI of the predicate (property)
* @param obj_node is the URI of the object (can be URI or literal)
* @param graphID is the ID of the graph
* @param isBatch is true if this request is part of a batch operation.
*
**/
public void storeTriple(Triple t,
IDBID graphID,
boolean isBatch,
Hashtable batchedPreparedStatements) {
storeTripleAR(t,graphID,null,false,isBatch,batchedPreparedStatements);
}
/**
*
* Attempt to store a statement into an Asserted_Statement table.
*
* @param subj_uri is the URI of the subject
* @param pred_uri is the URI of the predicate (property)
* @param obj_node is the URI of the object (can be URI or literal)
* @param stmtURI is the URI of the statement if reified, null for asserted
* @param hasType is true if the hasType flag should be set for a reified stmt
* @param graphID is the ID of the graph
* @param isBatch is true if this request is part of a batch operation.
*
**/
public void storeTripleAR(
Triple t,
IDBID graphID,
Node reifNode,
boolean hasType,
boolean isBatch,
Hashtable batchedPreparedStatements) {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -