You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@jackrabbit.apache.org by ma...@apache.org on 2009/08/08 21:14:49 UTC
svn commit: r802438 - in
/jackrabbit/sandbox/JCR-1456/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/persistence/bundle:
./ util/
Author: martijnh
Date: Sat Aug 8 19:14:49 2009
New Revision: 802438
URL: http://svn.apache.org/viewvc?rev=802438&view=rev
Log:
JCR-1456 Database connection pooling
* Fixed the Oracle, H2 and PostgrSQL PMs (still needs testing)
* Moved DB specific code from Oracle PMs to the OracleConnectionHelper classes
Added:
jackrabbit/sandbox/JCR-1456/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/persistence/bundle/util/Oracle10R1ConnectionHelper.java (with props)
jackrabbit/sandbox/JCR-1456/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/persistence/bundle/util/OracleConnectionHelper.java (with props)
Modified:
jackrabbit/sandbox/JCR-1456/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/persistence/bundle/BundleDbPersistenceManager.java
jackrabbit/sandbox/JCR-1456/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/persistence/bundle/H2PersistenceManager.java
jackrabbit/sandbox/JCR-1456/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/persistence/bundle/Oracle9PersistenceManager.java
jackrabbit/sandbox/JCR-1456/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/persistence/bundle/OraclePersistenceManager.java
jackrabbit/sandbox/JCR-1456/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/persistence/bundle/PostgreSQLPersistenceManager.java
jackrabbit/sandbox/JCR-1456/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/persistence/bundle/util/ConnectionHelper.java
Modified: jackrabbit/sandbox/JCR-1456/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/persistence/bundle/BundleDbPersistenceManager.java
URL: http://svn.apache.org/viewvc/jackrabbit/sandbox/JCR-1456/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/persistence/bundle/BundleDbPersistenceManager.java?rev=802438&r1=802437&r2=802438&view=diff
==============================================================================
--- jackrabbit/sandbox/JCR-1456/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/persistence/bundle/BundleDbPersistenceManager.java (original)
+++ jackrabbit/sandbox/JCR-1456/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/persistence/bundle/BundleDbPersistenceManager.java Sat Aug 8 19:14:49 2009
@@ -435,19 +435,6 @@
}
/**
- * Indicates if the user name should be included when retrieving the tables
- * during {@link #checkTablesExist()}.
- * <p/>
- * Please note that this currently only needs to be changed for oracle based
- * persistence managers.
- *
- * @return <code>false</code>
- */
- public boolean checkTablesWithUser() {
- return false;
- }
-
- /**
* {@inheritDoc}
*
* Basically wraps a JDBC transaction around super.store().
@@ -518,14 +505,26 @@
* {@link ConnectionHelper} instance. Subclasses may override it to return a specialized
* connection helper.
*
- * @param dataSrc the {@link DataSource} of this peristence manager
+ * @param dataSrc the {@link DataSource} of this persistence manager
* @return a {@link ConnectionHelper}
+ * @throws Exception on error
*/
- protected ConnectionHelper createConnectionHelper(DataSource dataSrc) {
+ protected ConnectionHelper createConnectionHelper(DataSource dataSrc) throws Exception {
return new ConnectionHelper(dataSrc);
}
/**
+ * Indicates if the user name should be included when retrieving the tables during
+ * {@link #checkTablesExist()}. <p/> Please note that this currently only needs to be changed for oracle
+ * based persistence managers.
+ *
+ * @return <code>false</code>
+ */
+ public boolean checkTablesWithUser() {
+ return false;
+ }
+
+ /**
* {@inheritDoc}
*/
protected BundleBinding getBinding() {
Modified: jackrabbit/sandbox/JCR-1456/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/persistence/bundle/H2PersistenceManager.java
URL: http://svn.apache.org/viewvc/jackrabbit/sandbox/JCR-1456/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/persistence/bundle/H2PersistenceManager.java?rev=802438&r1=802437&r2=802438&view=diff
==============================================================================
--- jackrabbit/sandbox/JCR-1456/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/persistence/bundle/H2PersistenceManager.java (original)
+++ jackrabbit/sandbox/JCR-1456/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/persistence/bundle/H2PersistenceManager.java Sat Aug 8 19:14:49 2009
@@ -16,14 +16,7 @@
*/
package org.apache.jackrabbit.core.persistence.bundle;
-import java.sql.Connection;
-import java.sql.SQLException;
-import java.sql.Statement;
-
-import javax.jcr.RepositoryException;
-
import org.apache.jackrabbit.core.persistence.PMContext;
-import org.apache.jackrabbit.core.persistence.bundle.util.ConnectionHelper;
/**
* Extends the {@link BundleDbPersistenceManager} by H2 specific code.
@@ -67,12 +60,6 @@
}
/**
- * Creates a new H2 persistence manager.
- */
- public H2PersistenceManager() {
- }
-
- /**
* {@inheritDoc}
*/
public void init(PMContext context) throws Exception {
@@ -91,25 +78,8 @@
}
super.init(context);
- }
-
- /**
- * {@inheritDoc}
- */
- protected void checkSchema() throws SQLException, RepositoryException {
- // FIXME
-// Connection connection = null;
-// Statement stmt = null;
-//
-// try {
-// connection = dataSource.getConnection();
-// stmt = connection.createStatement();
-// stmt.execute("SET LOCK_TIMEOUT " + lockTimeout);
-// } finally {
-// ConnectionHelper.closeSilently(stmt);
-// ConnectionHelper.closeSilently(connection);
-// }
-// super.checkSchema();
+
+ conHelper.exec("SET LOCK_TIMEOUT " + lockTimeout);
}
}
Modified: jackrabbit/sandbox/JCR-1456/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/persistence/bundle/Oracle9PersistenceManager.java
URL: http://svn.apache.org/viewvc/jackrabbit/sandbox/JCR-1456/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/persistence/bundle/Oracle9PersistenceManager.java?rev=802438&r1=802437&r2=802438&view=diff
==============================================================================
--- jackrabbit/sandbox/JCR-1456/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/persistence/bundle/Oracle9PersistenceManager.java (original)
+++ jackrabbit/sandbox/JCR-1456/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/persistence/bundle/Oracle9PersistenceManager.java Sat Aug 8 19:14:49 2009
@@ -16,35 +16,14 @@
*/
package org.apache.jackrabbit.core.persistence.bundle;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.apache.commons.io.IOUtils;
-import org.apache.jackrabbit.core.persistence.PMContext;
-import org.apache.jackrabbit.core.persistence.bundle.util.ConnectionHelper;
-import org.apache.jackrabbit.core.persistence.bundle.util.DbUtility;
-import org.apache.jackrabbit.core.persistence.bundle.util.NodePropBundle;
-import org.apache.jackrabbit.core.persistence.util.Serializer;
-import org.apache.jackrabbit.core.state.ItemStateException;
-import org.apache.jackrabbit.core.state.NodeReferences;
+import javax.sql.DataSource;
-import java.io.ByteArrayInputStream;
-import java.io.ByteArrayOutputStream;
-import java.io.DataOutputStream;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.OutputStream;
-import java.lang.reflect.Method;
-import java.sql.Blob;
-import java.sql.Connection;
-import java.sql.ResultSet;
-import java.sql.SQLException;
-import java.sql.Statement;
+import org.apache.jackrabbit.core.persistence.bundle.util.ConnectionHelper;
+import org.apache.jackrabbit.core.persistence.bundle.util.Oracle10R1ConnectionHelper;
/**
- * <code>OracleLegacyPersistenceManager</code> provides support for Oracle jdbc
- * drivers prior to version 10 which require special handling of BLOB data.
- * <p/>
- * Configuration:<br>
+ * <code>OracleLegacyPersistenceManager</code> provides support for Oracle jdbc drivers prior to version 10
+ * which require special handling of BLOB data. <p/> Configuration:<br>
* <ul>
* <li><param name="{@link #setBundleCacheSize(String) bundleCacheSize}" value="8"/>
* <li><param name="{@link #setConsistencyCheck(String) consistencyCheck}" value="false"/>
@@ -61,216 +40,12 @@
public class Oracle9PersistenceManager extends OraclePersistenceManager {
/**
- * the default logger
- */
- private static Logger log = LoggerFactory.getLogger(Oracle9PersistenceManager.class);
-
- private Class< ? > blobClass;
- private Integer duractionSessionConstant;
- private Integer modeReadWriteConstant;
-
- public Oracle9PersistenceManager() {
- }
-
- //-----------------------------------< OraclePersistenceManager overrides >
- /**
- * {@inheritDoc}
- * <p/>
- * Retrieve the <code>oracle.sql.BLOB</code> class via reflection, and
- * initialize the values for the <code>DURATION_SESSION</code> and
- * <code>MODE_READWRITE</code> constants defined there.
- *
- * @see oracle.sql.BLOB#DURATION_SESSION
- * @see oracle.sql.BLOB#MODE_READWRITE
- */
- public void init(PMContext context) throws Exception {
- super.init(context);
-
- // initialize oracle.sql.BLOB class & constants
-
- // use the Connection object for using the exact same
- // class loader that the Oracle driver was loaded with
-// FIXME
-// Connection connection = null;
-// try {
-// connection = dataSource.getConnection();
-// blobClass = connection.getClass().getClassLoader().loadClass("oracle.sql.BLOB");
-// } finally {
-// ConnectionHelper.closeSilently(connection);
-// }
-
- duractionSessionConstant =
- new Integer(blobClass.getField("DURATION_SESSION").getInt(null));
- modeReadWriteConstant =
- new Integer(blobClass.getField("MODE_READWRITE").getInt(null));
- }
-
- /**
- * @inheritDoc
- */
- protected BundleDbPersistenceManager.CloseableBLOBStore createDBBlobStore(PMContext context) throws Exception {
- return new OracleBLOBStore();
- }
-
- /**
- * {@inheritDoc}
- */
- protected synchronized void storeBundle(NodePropBundle bundle)
- throws ItemStateException {
- Blob blob = null;
- try {
- ByteArrayOutputStream out = new ByteArrayOutputStream(INITIAL_BUFFER_SIZE);
- DataOutputStream dout = new DataOutputStream(out);
- binding.writeBundle(dout, bundle);
- dout.close();
-
- String sql = bundle.isNew() ? bundleInsertSQL : bundleUpdateSQL;
- blob = createTemporaryBlob(new ByteArrayInputStream(out.toByteArray()));
- Object[] params = createParams(bundle.getId(), blob, true);
- conHelper.exec(sql, params);
- } catch (Exception e) {
- String msg = "failed to write bundle: " + bundle.getId();
- log.error(msg, e);
- throw new ItemStateException(msg, e);
- } finally {
- if (blob != null) {
- try {
- freeTemporaryBlob(blob);
- } catch (Exception e1) {
- }
- }
- }
- }
-
- /**
* {@inheritDoc}
*/
@Override
- public synchronized void store(NodeReferences refs)
- throws ItemStateException {
- if (!initialized) {
- throw new IllegalStateException("not initialized");
- }
-
- Blob blob = null;
- try {
- // check if insert or update
- boolean update = existsReferencesTo(refs.getTargetId());
- String sql = (update) ? nodeReferenceUpdateSQL : nodeReferenceInsertSQL;
-
- ByteArrayOutputStream out = new ByteArrayOutputStream(INITIAL_BUFFER_SIZE);
- // serialize references
- Serializer.serialize(refs, out);
-
- // we are synchronized on this instance, therefore we do not
- // not have to additionally synchronize on the preparedStatement
-
- blob = createTemporaryBlob(new ByteArrayInputStream(out.toByteArray()));
- Object[] params = createParams(refs.getTargetId(), blob, true);
- conHelper.exec(sql, params);
-
- // there's no need to close a ByteArrayOutputStream
- //out.close();
- } catch (Exception e) {
- String msg = "failed to write " + refs;
- log.error(msg, e);
- throw new ItemStateException(msg, e);
- } finally {
- if (blob != null) {
- try {
- freeTemporaryBlob(blob);
- } catch (Exception e1) {
- }
- }
- }
- }
-
- //----------------------------------------< oracle-specific blob handling >
- /**
- * Creates a temporary oracle.sql.BLOB instance via reflection and spools
- * the contents of the specified stream.
- */
- protected Blob createTemporaryBlob(InputStream in) throws Exception {
- /*
- BLOB blob = BLOB.createTemporary(con, false, BLOB.DURATION_SESSION);
- blob.open(BLOB.MODE_READWRITE);
- OutputStream out = blob.getBinaryOutputStream();
- ...
- out.flush();
- out.close();
- blob.close();
- return blob;
- */
-// FIXME
-// Method createTemporary = blobClass.getMethod("createTemporary",
-// new Class[]{Connection.class, Boolean.TYPE, Integer.TYPE});
-// Object blob = createTemporary.invoke(null,
-// new Object[]{context.getConnection(), Boolean.FALSE, duractionSessionConstant});
-// Method open = blobClass.getMethod("open", new Class[]{Integer.TYPE});
-// open.invoke(blob, new Object[]{modeReadWriteConstant});
-// Method getBinaryOutputStream = blobClass.getMethod("getBinaryOutputStream", new Class[0]);
-// OutputStream out = (OutputStream) getBinaryOutputStream.invoke(blob);
-// try {
-// IOUtils.copy(in, out);
-// } finally {
-// try {
-// out.flush();
-// } catch (IOException ioe) {
-// }
-// out.close();
-// }
-// Method close = blobClass.getMethod("close", new Class[0]);
-// close.invoke(blob);
-// return (Blob) blob;
- return null;
- }
-
- /**
- * Frees a temporary oracle.sql.BLOB instance via reflection.
- */
- protected void freeTemporaryBlob(Object blob) throws Exception {
- // blob.freeTemporary();
- Method freeTemporary = blobClass.getMethod("freeTemporary", new Class[0]);
- freeTemporary.invoke(blob);
- }
-
- /**
- * A blob store specially for Oracle 9.
- */
- class OracleBLOBStore extends DbBlobStore {
-
- public OracleBLOBStore() throws SQLException {
- }
-
- /**
- * {@inheritDoc}
- */
- public synchronized void put(String blobId, InputStream in, long size)
- throws Exception {
-
- Blob blob = null;
- try {
- boolean exists = false;
- ResultSet rs = null;
- try {
- conHelper.exec(blobSelectExistSQL, new Object[]{blobId}, false, 0);
- // a BLOB exists if the result has at least one entry
- exists = rs.next();
- } finally {
- DbUtility.close(rs);
- }
-
- String sql = (exists) ? blobUpdateSQL : blobInsertSQL;
- blob = createTemporaryBlob(in);
- conHelper.exec(sql, new Object[]{blob, blobId});
- } finally {
- if (blob != null) {
- try {
- freeTemporaryBlob(blob);
- } catch (Exception e) {
- }
- }
- }
- }
+ protected ConnectionHelper createConnectionHelper(DataSource dataSrc) throws Exception {
+ Oracle10R1ConnectionHelper helper = new Oracle10R1ConnectionHelper(dataSrc);
+ helper.init();
+ return helper;
}
}
Modified: jackrabbit/sandbox/JCR-1456/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/persistence/bundle/OraclePersistenceManager.java
URL: http://svn.apache.org/viewvc/jackrabbit/sandbox/JCR-1456/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/persistence/bundle/OraclePersistenceManager.java?rev=802438&r1=802437&r2=802438&view=diff
==============================================================================
--- jackrabbit/sandbox/JCR-1456/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/persistence/bundle/OraclePersistenceManager.java (original)
+++ jackrabbit/sandbox/JCR-1456/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/persistence/bundle/OraclePersistenceManager.java Sat Aug 8 19:14:49 2009
@@ -16,17 +16,16 @@
*/
package org.apache.jackrabbit.core.persistence.bundle;
-import java.sql.Connection;
-import java.sql.DatabaseMetaData;
import java.sql.SQLException;
+import javax.sql.DataSource;
+
import org.apache.jackrabbit.core.persistence.PMContext;
import org.apache.jackrabbit.core.persistence.bundle.util.ConnectionHelper;
import org.apache.jackrabbit.core.persistence.bundle.util.DbNameIndex;
import org.apache.jackrabbit.core.persistence.bundle.util.NGKDbNameIndex;
+import org.apache.jackrabbit.core.persistence.bundle.util.OracleConnectionHelper;
import org.apache.jackrabbit.util.Text;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
/**
* Extends the {@link BundleDbPersistenceManager} by Oracle specific code.
@@ -49,11 +48,6 @@
*/
public class OraclePersistenceManager extends BundleDbPersistenceManager {
- /**
- * the default logger
- */
- private static Logger log = LoggerFactory.getLogger(OraclePersistenceManager.class);
-
/** the variable for the Oracle table space */
public static final String TABLE_SPACE_VARIABLE =
"${tableSpace}";
@@ -104,24 +98,6 @@
setSchemaObjectPrefix(context.getHomeDir().getName() + "_");
}
super.init(context);
-
- // check driver version
- // FIXME
-// Connection connection = dataSource.getConnection();
-// try {
-// DatabaseMetaData metaData = connection.getMetaData();
-// if (metaData.getDriverMajorVersion() < 10) {
-// // Oracle drivers prior to version 10 only support
-// // writing BLOBs up to 32k in size...
-// log.warn("Unsupported driver version detected: "
-// + metaData.getDriverName()
-// + " v" + metaData.getDriverVersion());
-// }
-// } catch (SQLException e) {
-// log.warn("Can not retrieve driver version", e);
-// } finally {
-// ConnectionHelper.closeSilently(connection);
-// }
}
/**
@@ -129,10 +105,9 @@
* @return a new instance of a NGKDbNameIndex.
* @throws SQLException if an SQL error occurs.
*/
-// FIXME
-// protected DbNameIndex createDbNameIndex() throws SQLException {
-// return new NGKDbNameIndex(dataSource, schemaObjectPrefix);
-// }
+ protected DbNameIndex createDbNameIndex() throws SQLException {
+ return new NGKDbNameIndex(conHelper, schemaObjectPrefix);
+ }
/**
* {@inheritDoc}
@@ -160,36 +135,12 @@
}
/**
- * Since Oracle only supports table names up to 30 characters in
- * length illegal characters are simply replaced with "_" rather than
- * escaping them with "_x0000_".
- *
- * @inheritDoc
+ * {@inheritDoc}
*/
-// FIXME
-// protected void prepareSchemaObjectPrefix() throws Exception {
-// String legalChars;
-// Connection connection = null;
-// try {
-// connection = dataSource.getConnection();
-// DatabaseMetaData metaData = connection.getMetaData();
-// legalChars = metaData.getExtraNameCharacters();
-// } finally {
-// ConnectionHelper.closeSilently(connection);
-// }
-//
-// legalChars += "ABCDEFGHIJKLMNOPQRSTUVWXZY0123456789_";
-//
-// String prefix = schemaObjectPrefix.toUpperCase();
-// StringBuffer escaped = new StringBuffer();
-// for (int i = 0; i < prefix.length(); i++) {
-// char c = prefix.charAt(i);
-// if (legalChars.indexOf(c) == -1) {
-// escaped.append('_');
-// } else {
-// escaped.append(c);
-// }
-// }
-// schemaObjectPrefix = escaped.toString();
-// }
+ @Override
+ protected ConnectionHelper createConnectionHelper(DataSource dataSrc) throws Exception {
+ OracleConnectionHelper helper = new OracleConnectionHelper(dataSrc);
+ helper.init();
+ return helper;
+ }
}
Modified: jackrabbit/sandbox/JCR-1456/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/persistence/bundle/PostgreSQLPersistenceManager.java
URL: http://svn.apache.org/viewvc/jackrabbit/sandbox/JCR-1456/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/persistence/bundle/PostgreSQLPersistenceManager.java?rev=802438&r1=802437&r2=802438&view=diff
==============================================================================
--- jackrabbit/sandbox/JCR-1456/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/persistence/bundle/PostgreSQLPersistenceManager.java (original)
+++ jackrabbit/sandbox/JCR-1456/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/persistence/bundle/PostgreSQLPersistenceManager.java Sat Aug 8 19:14:49 2009
@@ -20,11 +20,11 @@
import java.io.InputStream;
import java.sql.ResultSet;
import java.sql.SQLException;
-import java.sql.Statement;
import org.apache.jackrabbit.core.id.NodeId;
import org.apache.jackrabbit.core.persistence.PMContext;
import org.apache.jackrabbit.core.persistence.bundle.util.DbNameIndex;
+import org.apache.jackrabbit.core.persistence.bundle.util.DbUtility;
import org.apache.jackrabbit.core.persistence.bundle.util.NodePropBundle;
import org.apache.jackrabbit.core.persistence.bundle.util.PostgreSQLNameIndex;
import org.apache.jackrabbit.core.persistence.bundle.util.TrackingInputStream;
@@ -76,10 +76,9 @@
* @return a new instance of a DbNameIndex.
* @throws java.sql.SQLException if an SQL error occurs.
*/
-// FIXME
-// protected DbNameIndex createDbNameIndex() throws SQLException {
-// return new PostgreSQLNameIndex(dataSource, schemaObjectPrefix);
-// }
+ protected DbNameIndex createDbNameIndex() throws SQLException {
+ return new PostgreSQLNameIndex(conHelper, schemaObjectPrefix);
+ }
/**
* returns the storage model
@@ -89,39 +88,38 @@
return SM_LONGLONG_KEYS;
}
- // FIXME
-//
-// protected synchronized NodePropBundle loadBundle(NodeId id)
-// throws ItemStateException {
-// BundleDbContext context = createContext();
-// try {
-// Statement stmt = context.getConnectionHelper().executeStmt(bundleSelectSQL, getKey(id));
-// ResultSet rs = stmt.getResultSet();
-// try {
-// if (rs.next()) {
-// InputStream input = rs.getBinaryStream(1);
-// try {
-// TrackingInputStream cin = new TrackingInputStream(input);
-// DataInputStream din = new DataInputStream(cin);
-// NodePropBundle bundle = binding.readBundle(din, id);
-// bundle.setSize(cin.getPosition());
-// return bundle;
-// } finally {
-// input.close();
-// }
-// } else {
-// return null;
-// }
-// } finally {
-// rs.close();
-// }
-// } catch (Exception e) {
-// String msg = "failed to read bundle: " + id + ": " + e;
-// log.error(msg);
-// throw new ItemStateException(msg, e);
-// } finally {
-// context.closeSilently();
-// }
-// }
+ /**
+ * PostgreSQL needs slightly different handling of the binary value that is received:
+ * rs.getBinaryStream vs rs.getBlob in the super class.
+ *
+ * {@inheritDoc}
+ */
+ protected synchronized NodePropBundle loadBundle(NodeId id)
+ throws ItemStateException {
+ ResultSet rs = null;
+ try {
+ rs = conHelper.exec(bundleSelectSQL, getKey(id), false, 0);
+ if (rs.next()) {
+ InputStream input = rs.getBinaryStream(1);
+ try {
+ TrackingInputStream cin = new TrackingInputStream(input);
+ DataInputStream din = new DataInputStream(cin);
+ NodePropBundle bundle = binding.readBundle(din, id);
+ bundle.setSize(cin.getPosition());
+ return bundle;
+ } finally {
+ input.close();
+ }
+ } else {
+ return null;
+ }
+ } catch (Exception e) {
+ String msg = "failed to read bundle: " + id + ": " + e;
+ log.error(msg);
+ throw new ItemStateException(msg, e);
+ } finally {
+ DbUtility.close(rs);
+ }
+ }
}
Modified: jackrabbit/sandbox/JCR-1456/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/persistence/bundle/util/ConnectionHelper.java
URL: http://svn.apache.org/viewvc/jackrabbit/sandbox/JCR-1456/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/persistence/bundle/util/ConnectionHelper.java?rev=802438&r1=802437&r2=802438&view=diff
==============================================================================
--- jackrabbit/sandbox/JCR-1456/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/persistence/bundle/util/ConnectionHelper.java (original)
+++ jackrabbit/sandbox/JCR-1456/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/persistence/bundle/util/ConnectionHelper.java Sat Aug 8 19:14:49 2009
@@ -91,11 +91,7 @@
for (int i = 0; i < id.length(); i++) {
char c = id.charAt(i);
if (legalChars.indexOf(c) == -1) {
- escaped.append("_x");
- String hex = Integer.toHexString(c);
- escaped.append("0000".toCharArray(), 0, 4 - hex.length());
- escaped.append(hex);
- escaped.append("_");
+ replaceCharacter(escaped, c);
} else {
escaped.append(c);
}
@@ -104,13 +100,27 @@
}
/**
- * The default implementation returns the {@code extraNameCharacters} provided by the
- * databases metadata.
+ * Called from {@link #prepareDbIdentifier(String)}. Default implementation replaces the illegal
+ * characters with their hexadecimal encoding.
+ *
+ * @param escaped the escaped db identifier
+ * @param c the character to replace
+ */
+ protected void replaceCharacter(StringBuffer escaped, char c) {
+ escaped.append("_x");
+ String hex = Integer.toHexString(c);
+ escaped.append("0000".toCharArray(), 0, 4 - hex.length());
+ escaped.append(hex);
+ escaped.append("_");
+ }
+
+ /**
+ * The default implementation returns the {@code extraNameCharacters} provided by the databases metadata.
*
* @return the additional characters for identifiers supported by the db
* @throws SQLException on error
*/
- protected String getExtraNameCharacters() throws SQLException {
+ private String getExtraNameCharacters() throws SQLException {
Connection con = dataSource.getConnection();
try {
DatabaseMetaData metaData = con.getMetaData();
@@ -239,7 +249,7 @@
* @param params the parameters for the SQL statement
* @throws SQLException on error
*/
- public final void exec(String sql, Object...params) throws SQLException {
+ public final void exec(String sql, Object... params) throws SQLException {
Connection con = null;
PreparedStatement stmt = null;
try {
@@ -317,9 +327,9 @@
}
/**
- * Gets a connection based on the {@code batchMode} state of this helper. The connection
- * should be closed by a call to {@link #closeResources(Connection, Statement, ResultSet)} which
- * also takes the {@code batchMode} state into account.
+ * Gets a connection based on the {@code batchMode} state of this helper. The connection should be closed
+ * by a call to {@link #closeResources(Connection, Statement, ResultSet)} which also takes the {@code
+ * batchMode} state into account.
*
* @return a {@code Connection} to use, based on the batch mode state
* @throws SQLException on error
@@ -353,12 +363,17 @@
}
/**
- * @param stmt
- * @param params
- * @return
- * @throws SQLException
+ * This method is used by all methods of this class that execute SQL statements. This default
+ * implementation sets all parameters and unwraps {@link StreamWrapper} instances. Subclasses may override
+ * this method to do something special with the parameters. E.g., the {@code Oracle10R1ConnectionHelper}
+ * overrides it in order to add special blob handling.
+ *
+ * @param stmt the {@link PreparedStatement} to execute
+ * @param params the parameters
+ * @return the executed statement
+ * @throws SQLException on error
*/
- private PreparedStatement execute(PreparedStatement stmt, Object[] params) throws SQLException {
+ protected PreparedStatement execute(PreparedStatement stmt, Object[] params) throws SQLException {
for (int i = 0; params != null && i < params.length; i++) {
Object p = params[i];
if (p instanceof StreamWrapper) {
Added: jackrabbit/sandbox/JCR-1456/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/persistence/bundle/util/Oracle10R1ConnectionHelper.java
URL: http://svn.apache.org/viewvc/jackrabbit/sandbox/JCR-1456/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/persistence/bundle/util/Oracle10R1ConnectionHelper.java?rev=802438&view=auto
==============================================================================
--- jackrabbit/sandbox/JCR-1456/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/persistence/bundle/util/Oracle10R1ConnectionHelper.java (added)
+++ jackrabbit/sandbox/JCR-1456/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/persistence/bundle/util/Oracle10R1ConnectionHelper.java Sat Aug 8 19:14:49 2009
@@ -0,0 +1,164 @@
+/*
+ * 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.jackrabbit.core.persistence.bundle.util;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.lang.reflect.Method;
+import java.sql.Blob;
+import java.sql.Connection;
+import java.sql.PreparedStatement;
+import java.sql.SQLException;
+import java.util.ArrayList;
+import java.util.List;
+
+import javax.sql.DataSource;
+
+import org.apache.commons.io.IOUtils;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * The connection helper for Oracle databases of version up to 10.1. It has special blob handling.
+ */
+public final class Oracle10R1ConnectionHelper extends OracleConnectionHelper {
+
+ /**
+ * the default logger
+ */
+ private static Logger log = LoggerFactory.getLogger(Oracle10R1ConnectionHelper.class);
+
+ private Class<?> blobClass;
+
+ private Integer durationSessionConstant;
+
+ private Integer modeReadWriteConstant;
+
+ /**
+ * @param dataSrc
+ */
+ public Oracle10R1ConnectionHelper(DataSource dataSrc) {
+ super(dataSrc);
+ }
+
+ /**
+ * Retrieve the <code>oracle.sql.BLOB</code> class via reflection, and initialize the values for the
+ * <code>DURATION_SESSION</code> and <code>MODE_READWRITE</code> constants defined there.
+ *
+ * @see oracle.sql.BLOB#DURATION_SESSION
+ * @see oracle.sql.BLOB#MODE_READWRITE
+ */
+ public void init() throws Exception {
+ super.init();
+ // initialize oracle.sql.BLOB class & constants
+
+ // use the Connection object for using the exact same
+ // class loader that the Oracle driver was loaded with
+ Connection con = null;
+ try {
+ con = dataSource.getConnection();
+ blobClass = con.getClass().getClassLoader().loadClass("oracle.sql.BLOB");
+ durationSessionConstant = new Integer(blobClass.getField("DURATION_SESSION").getInt(null));
+ modeReadWriteConstant = new Integer(blobClass.getField("MODE_READWRITE").getInt(null));
+ } finally {
+ if (con != null) {
+ DbUtility.close(con, null, null);
+ }
+ }
+ }
+
+ /**
+ * Wraps any input-stream parameters in temporary blobs and frees these again after the statement
+ * has been executed.
+ *
+ * {@inheritDoc}
+ */
+ @Override
+ protected PreparedStatement execute(PreparedStatement stmt, Object[] params) throws SQLException {
+ List<Blob> tmpBlobs = new ArrayList<Blob>();
+ try {
+ for (int i = 0; params != null && i < params.length; i++) {
+ Object p = params[i];
+ if (p instanceof StreamWrapper) {
+ StreamWrapper wrapper = (StreamWrapper) p;
+ Blob tmp = createTemporaryBlob(stmt.getConnection(), wrapper.getStream());
+ tmpBlobs.add(tmp);
+ stmt.setObject(i + 1, tmp);
+ } else if (p instanceof InputStream) {
+ Blob tmp = createTemporaryBlob(stmt.getConnection(), (InputStream) p);
+ tmpBlobs.add(tmp);
+ stmt.setObject(i + 1, tmp);
+ } else {
+ stmt.setObject(i + 1, p);
+ }
+ }
+ stmt.execute();
+ return stmt;
+ } catch (Exception e) {
+ throw new SQLException(e.getMessage());
+ } finally {
+ for (Blob blob : tmpBlobs) {
+ try {
+ freeTemporaryBlob(blob);
+ } catch (Exception e) {
+ log.warn("Could not close temporary blob", e);
+ }
+ }
+ }
+ }
+
+ /**
+ * Creates a temporary oracle.sql.BLOB instance via reflection and spools the contents of the specified
+ * stream.
+ */
+ private Blob createTemporaryBlob(Connection con, InputStream in) throws Exception {
+ /*
+ * BLOB blob = BLOB.createTemporary(con, false, BLOB.DURATION_SESSION);
+ * blob.open(BLOB.MODE_READWRITE); OutputStream out = blob.getBinaryOutputStream(); ... out.flush();
+ * out.close(); blob.close(); return blob;
+ */
+ Method createTemporary =
+ blobClass.getMethod("createTemporary", new Class[]{Connection.class, Boolean.TYPE, Integer.TYPE});
+ Object blob = createTemporary.invoke(null, new Object[]{con, Boolean.FALSE, durationSessionConstant});
+ Method open = blobClass.getMethod("open", new Class[]{Integer.TYPE});
+ open.invoke(blob, new Object[]{modeReadWriteConstant});
+ Method getBinaryOutputStream = blobClass.getMethod("getBinaryOutputStream", new Class[0]);
+ OutputStream out = (OutputStream) getBinaryOutputStream.invoke(blob);
+ try {
+ IOUtils.copy(in, out);
+ } finally {
+ try {
+ out.flush();
+ } catch (IOException ioe) {
+ }
+ out.close();
+ }
+ Method close = blobClass.getMethod("close", new Class[0]);
+ close.invoke(blob);
+ return (Blob) blob;
+ }
+
+ /**
+ * Frees a temporary oracle.sql.BLOB instance via reflection.
+ */
+ private void freeTemporaryBlob(Blob blob) throws Exception {
+ // blob.freeTemporary();
+ Method freeTemporary = blobClass.getMethod("freeTemporary", new Class[0]);
+ freeTemporary.invoke(blob);
+ }
+}
Propchange: jackrabbit/sandbox/JCR-1456/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/persistence/bundle/util/Oracle10R1ConnectionHelper.java
------------------------------------------------------------------------------
svn:eol-style = native
Added: jackrabbit/sandbox/JCR-1456/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/persistence/bundle/util/OracleConnectionHelper.java
URL: http://svn.apache.org/viewvc/jackrabbit/sandbox/JCR-1456/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/persistence/bundle/util/OracleConnectionHelper.java?rev=802438&view=auto
==============================================================================
--- jackrabbit/sandbox/JCR-1456/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/persistence/bundle/util/OracleConnectionHelper.java (added)
+++ jackrabbit/sandbox/JCR-1456/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/persistence/bundle/util/OracleConnectionHelper.java Sat Aug 8 19:14:49 2009
@@ -0,0 +1,75 @@
+/*
+ * 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.jackrabbit.core.persistence.bundle.util;
+
+import java.sql.Connection;
+import java.sql.DatabaseMetaData;
+import java.sql.SQLException;
+
+import javax.sql.DataSource;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * The connection helper for Oracle databases of version 10.2 and later.
+ */
+public class OracleConnectionHelper extends ConnectionHelper {
+
+ /**
+ * the default logger
+ */
+ private static Logger log = LoggerFactory.getLogger(OracleConnectionHelper.class);
+
+ /**
+ * @param dataSrc
+ */
+ public OracleConnectionHelper(DataSource dataSrc) {
+ super(dataSrc);
+ }
+
+ public void init() throws Exception {
+ // check driver version
+ Connection connection = dataSource.getConnection();
+ try {
+ DatabaseMetaData metaData = connection.getMetaData();
+ if (metaData.getDriverMajorVersion() < 10) {
+ // Oracle drivers prior to version 10 only support
+ // writing BLOBs up to 32k in size...
+ log.warn("Unsupported driver version detected: "
+ + metaData.getDriverName()
+ + " v" + metaData.getDriverVersion());
+ }
+ } catch (SQLException e) {
+ log.warn("Can not retrieve driver version", e);
+ } finally {
+ DbUtility.close(connection, null, null);
+ }
+ }
+
+ /**
+ * Since Oracle only supports table names up to 30 characters in
+ * length illegal characters are simply replaced with "_" rather than
+ * escaping them with "_x0000_".
+ *
+ * {@inheritDoc}
+ */
+ @Override
+ protected void replaceCharacter(StringBuffer escaped, char c) {
+ escaped.append("_");
+ }
+}
Propchange: jackrabbit/sandbox/JCR-1456/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/persistence/bundle/util/OracleConnectionHelper.java
------------------------------------------------------------------------------
svn:eol-style = native