+
+ /**
+ * Invalidates any cached entity list
+ */
+ private void invalidateStore() {
+ // invalidating all EntityLists corresponding with entityClass
+ if (StoreUtil.extendsStorableEntity(entityClass)) {
+ StoreContainerType stoc_type =
+ StoreContainerType.valueOf(entityClass, StoreContainerType.STOC_TYPE_ENTITYLIST);
+ o_store.invalidate(stoc_type);
+ }
+ }
+
+ /**
+ * Retrieves a binary value
+ */
+ public InputStream getBinaryField(String aQuery) throws StorageObjectFailure, SQLException {
+ Connection connection=null;
+ Statement statement=null;
+ InputStream inputStream;
+ InputStream imageInputStream = null;
+
+ try {
+ connection = obtainConnection();
+ try {
+ connection.setAutoCommit(false);
+ statement = connection.createStatement();
+ ResultSet resultSet = executeSql(statement, aQuery);
+
+ if(resultSet!=null) {
+ if (resultSet.next()) {
+ if (resultSet.getMetaData().getColumnType(1) == java.sql.Types.BINARY) {
+ byte[] data = resultSet.getBytes(1);
+ imageInputStream = new ByteArrayInputStream(data);
+ }
+ else {
+ inputStream = resultSet.getBlob(1).getBinaryStream();
+ imageInputStream = new BinaryFieldInputStream(inputStream, connection, statement);
+ }
+ }
+ resultSet.close();
+ }
+ }
+ finally {
+ }
+ }
+ catch (Throwable t) {
+ logger.error("EntityImages.getImage failed: " + t.toString());
+ t.printStackTrace(logger.asPrintWriter(LoggerWrapper.DEBUG_MESSAGE));
+
+ try {
+ connection.setAutoCommit(true);
+ }
+ catch (Throwable e) {
+ logger.error("EntityImages.getImage resetting transaction mode failed: " + e.toString());
+ e.printStackTrace(logger.asPrintWriter(LoggerWrapper.DEBUG_MESSAGE));
+ }
+
+ try {
+ freeConnection(connection, statement);
+ }
+ catch (Throwable e) {
+ logger.error("EntityImages.getImage freeing connection failed: " +e.toString());
+ }
+
+ throw new StorageObjectFailure(t);
+ }
+
+ return imageInputStream;
+ }
+
+ /**
+ * Sets a binary value for a particular field in a record specified by its identifier
+ */
+ public void setBinaryField(String aFieldName, String anObjectId, byte aData[]) throws StorageObjectFailure, SQLException {
+ PreparedStatement statement = null;
+ Connection connection = obtainConnection();
+
+ try {
+ connection.setAutoCommit(false);
+ try {
+ // are we using bytea ?
+ if (getFieldType(aFieldName) == java.sql.Types.BINARY) {
+ statement = connection.prepareStatement(
+ "update " + mainTable + " set " + aFieldName + " = ? where " + getIdFieldName() + "=" + Integer.parseInt(anObjectId));
+ statement.setBytes(1, aData);
+ statement.execute();
+ connection.commit();
+ }
+ // or the old oid's
+ else {
+ PGConnection postgresqlConnection = (org.postgresql.PGConnection) ((DelegatingConnection) connection).getDelegate();
+ LargeObjectManager lobManager = postgresqlConnection.getLargeObjectAPI();
+ int oid = lobManager.create(LargeObjectManager.READ | LargeObjectManager.WRITE);
+ LargeObject obj = lobManager.open(oid, LargeObjectManager.WRITE); // Now open the file File file =
+ obj.write(aData);
+ obj.close();
+ statement = connection.prepareStatement(
+ "update " + mainTable + " set " + aFieldName + " = ? where " + getIdFieldName() + "=" + Integer.parseInt(anObjectId));
+ statement.setInt(1, oid);
+ statement.execute();
+ connection.commit();
+ }
+ }
+ finally {
+ connection.setAutoCommit(true);
+ }
+ }
+ finally {
+ freeConnection(connection, statement);
+ }
+ }
+
+ private void logQueryBefore(String aQuery) {
+ logger.debug("about to perform QUERY " + aQuery);
+// (new Throwable()).printStackTrace(logger.asPrintWriter(LoggerWrapper.DEBUG_MESSAGE));
+ }
+
+ private void logQueryAfter(String aQuery, long aTime) {
+ logger.info("QUERY " + aQuery + " took " + aTime + "ms.");
+ }
+
+ private void logQueryError(String aQuery, long aTime, Throwable anException) {
+ logger.error("QUERY " + aQuery + " took " + aTime + "ms, but threw exception " + anException.toString());
+ }
+
+ private int getFieldType(String aFieldName) {
+ if (fieldNameToType == null) {
+ acquireMetaData();
+ }
+
+ return ((Integer) fieldNameToType.get(aFieldName)).intValue();
+ }
+
+
+ /**
+ * a small wrapper class that allows us to store the DB connection resources
+ * that the BlobInputStream is using and free them upon closing of the stream
+ */
+ private class BinaryFieldInputStream extends InputStream {
+ InputStream inputStream;
+ Connection connection;
+ Statement statement;
+
+ public BinaryFieldInputStream(InputStream aBlobInputStream, Connection aConnection, Statement aStatement ) {
+ inputStream = aBlobInputStream;
+ connection = aConnection;
+ statement = aStatement;
+ }
+
+ public void close () throws IOException {
+ inputStream.close();
+ try {
+ connection.setAutoCommit(true);
+ freeConnection(connection, statement);
+ }
+ catch (Exception e) {
+ throw new IOException("close(): "+e.toString());
+ }
+ }
+
+ public int read() throws IOException {
+ return inputStream.read();
+ }
+ }