On Wednesday 28 July 2004 14:57, Ritu Kedia wrote:
> I did try the solution proposed by you i.e. count the bytes copied to
> Oracle Blob, but that did not return the correct length. I basically
> executed the select stmt of the storeContent method of the
> OracleRDBMSStore, after the copy method and then retrieved the blob and
> queried for blob.length().
No I mean count the bytes as they are written to Oracle in the copy(...)
method in CommonRDBMSAdapter, so you don't have to write a tmp file.
I think there's a problem in your patch when you use compression and
contentLength is -1.
ziputil.getContentLength() returns the _compressed_ file size, that is good
for:
statement.setBinaryStream(1, is, (int) contentLength);
but bad for:
revisionDescriptor.setContentLength(contentLength);
I've attached patches for Oracle adapter and StoreContentZip, tell me if they
works to you...
Cheers,
--
Davide Savazzi
/*
* $Header: /home/cvspublic/jakarta-slide/src/stores/org/apache/slide/store/impl/rdbms/CommonRDBMSAdapter.java,v 1.2 2004/07/25 11:33:55 unico Exp $
* $Revision: 1.2 $
* $Date: 2004/07/25 11:33:55 $
*
* ====================================================================
*
* Copyright 2004 The Apache Software Foundation
*
* Licensed 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.slide.store.impl.rdbms;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import org.apache.slide.common.Service;
import org.apache.slide.common.ServiceAccessException;
import org.apache.slide.common.Uri;
import org.apache.slide.content.NodeRevisionDescriptor;
import org.apache.slide.content.NodeRevisionNumber;
import org.apache.slide.lock.LockTokenNotFoundException;
import org.apache.slide.lock.NodeLock;
import org.apache.slide.security.NodePermission;
import org.apache.slide.structure.ObjectNode;
import org.apache.slide.structure.ObjectNotFoundException;
import org.apache.slide.util.logger.Logger;
/**
* This adapter has code that has been ported from OracleRDBMSAdapter so that it can be
* resued by both OracleRDBMSAdapter and DB2RDBMSAdapter.
*
*/
public class CommonRDBMSAdapter extends StandardRDBMSAdapter {
// Constructor
public CommonRDBMSAdapter(Service service, Logger logger) {
super(service, logger);
}
public void removeObject(Connection connection, Uri uri, ObjectNode object)
throws ServiceAccessException, ObjectNotFoundException
{
PreparedStatement statement = null;
try {
clearBinding(connection, uri);
// delete links
try {
statement =
connection.prepareStatement(
"delete from LINKS l where l.URI_ID in (" +
"select u.URI_ID from URI u where u.URI_STRING = ?)");
statement.setString(1, uri.toString());
statement.executeUpdate();
} finally {
close(statement);
}
// delete version history
// FIXME: Is this true??? Should the version history be removed if the object is removed???
try {
statement =
connection.prepareStatement(
"delete from VERSION_HISTORY vh where vh.URI_ID in (" +
"select u.URI_ID from URI u where u.URI_STRING = ?)");
statement.setString(1, uri.toString());
statement.executeUpdate();
} finally {
close(statement);
}
// delete version
try {
statement =
connection.prepareStatement(
"delete from VERSION v where v.URI_ID in (" +
"select u.URI_ID from URI u where u.URI_STRING = ?)");
statement.setString(1, uri.toString());
statement.executeUpdate();
} finally {
close(statement);
}
// delete the object itself
try {
statement =
connection.prepareStatement(
"delete from OBJECT o where o.URI_ID in (" +
"select u.URI_ID from URI u where u.URI_STRING = ?)");
statement.setString(1, uri.toString());
statement.executeUpdate();
} finally {
close(statement);
}
// finally delete the uri
try {
statement = connection.prepareStatement("delete from URI where URI_STRING = ?");
statement.setString(1, uri.toString());
statement.executeUpdate();
} finally {
close(statement);
}
} catch (SQLException e) {
throw createException(e, uri.toString());
}
}
public void removeRevisionContent(Connection connection, Uri uri, NodeRevisionDescriptor revisionDescriptor)
throws ServiceAccessException {
try {
PreparedStatement statement = null;
try {
statement =
connection.prepareStatement(
"delete from VERSION_CONTENT vc where vc.VERSION_ID in (" +
"select vh.VERSION_ID from VERSION_HISTORY vh, URI u where vh.REVISION_NO = ? and vh.URI_ID=u.URI_ID AND u.URI_STRING=?)");
statement.setString(1, revisionDescriptor.getRevisionNumber().toString());
statement.setString(2, uri.toString());
statement.executeUpdate();
} finally {
close(statement);
}
} catch (SQLException e) {
throw createException(e, uri.toString());
}
}
public void removeRevisionDescriptors(Connection connection, Uri uri) throws ServiceAccessException {
PreparedStatement statement = null;
try {
statement =
connection.prepareStatement(
"delete from VERSION_PREDS vp where vp.VERSION_ID in (" +
"select vh.VERSION_ID from VERSION_HISTORY vh, URI u where vh.URI_ID = u.URI_ID and u.URI_STRING = ?)");
statement.setString(1, uri.toString());
statement.executeUpdate();
} catch (SQLException e) {
throw createException(e, uri.toString());
} finally {
close(statement);
}
}
public void removeRevisionDescriptor(Connection connection, Uri uri, NodeRevisionNumber revisionNumber)
throws ServiceAccessException
{
PreparedStatement statement = null;
try {
try {
statement =
connection.prepareStatement(
"delete from VERSION_LABELS vl where vl.VERSION_ID in (" +
"select vh.VERSION_ID from VERSION_HISTORY vh, URI u where vh.REVISION_NO = ? and vh.URI_ID = u.URI_ID AND u.URI_STRING = ?)");
statement.setString(1, revisionNumber.toString());
statement.setString(2, uri.toString());
statement.executeUpdate();
} finally {
close(statement);
}
try {
statement =
connection.prepareStatement(
"delete from PROPERTIES p where p.VERSION_ID in (" +
"select vh.VERSION_ID from VERSION_HISTORY vh, URI u where vh.REVISION_NO = ? and vh.URI_ID = u.URI_ID AND u.URI_STRING = ?)");
statement.setString(1, revisionNumber.toString());
statement.setString(2, uri.toString());
statement.executeUpdate();
} finally {
close(statement);
}
} catch (SQLException e) {
throw createException(e, uri.toString());
}
}
public void removeLock(Connection connection, Uri uri, NodeLock lock)
throws ServiceAccessException, LockTokenNotFoundException {
PreparedStatement statement = null;
try {
// FIXME: What about inheritage?
try {
statement =
connection.prepareStatement(
"delete from LOCKS where LOCKS.LOCK_ID in (select u.URI_ID from URI u where u.URI_STRING=?)");
statement.setString(1, lock.getLockId());
statement.executeUpdate();
} finally {
close(statement);
}
try {
statement =
connection.prepareStatement(
"delete from URI where URI_STRING=?");
statement.setString(1, lock.getLockId());
statement.executeUpdate();
} finally {
close(statement);
}
} catch (SQLException e) {
throw createException(e, uri.toString());
}
}
public void revokePermission(Connection connection, Uri uri, NodePermission permission)
throws ServiceAccessException {
PreparedStatement statement = null;
try {
NodeRevisionNumber revisionNumber = permission.getRevisionNumber();
statement =
connection.prepareStatement(
"delete from PERMISSIONS where PERMISSIONS.OBJECT_ID in (select ou.URI_ID from URI ou, URI su, URI au where ou.URI_STRING = ? and SUBJECT_ID = su.URI_ID and su.URI_STRING = ? and ACTION_ID = au.URI_ID and au.URI_STRING = ? and VERSION_NO"
+ getRevisionNumberAsWhereQueryFragement(revisionNumber) + ")");
statement.setString(1, permission.getObjectUri());
statement.setString(2, permission.getSubjectUri());
statement.setString(3, permission.getActionUri());
statement.executeUpdate();
} catch (SQLException e) {
throw createException(e, uri.toString());
} finally {
close(statement);
}
}
public void revokePermissions(Connection connection, Uri uri) throws ServiceAccessException {
PreparedStatement statement = null;
try {
statement =
connection.prepareStatement(
"delete from PERMISSIONS where PERMISSIONS.OBJECT_ID in (select u.URI_ID from URI u where u.URI_STRING = ?)");
statement.setString(1, uri.toString());
statement.executeUpdate();
} catch (SQLException e) {
throw createException(e, uri.toString());
} finally {
close(statement);
}
}
protected void clearBinding(Connection connection, Uri uri)
throws ServiceAccessException, ObjectNotFoundException, SQLException
{
PreparedStatement statement = null;
try {
statement =
connection.prepareStatement(
"delete from BINDING where BINDING.URI_ID in (select URI_ID from URI where URI.URI_STRING = ?)");
statement.setString(1, uri.toString());
statement.executeUpdate();
} finally {
close(statement);
}
try {
statement =
connection.prepareStatement(
"delete from PARENT_BINDING where PARENT_BINDING.URI_ID in (select URI_ID from URI where URI.URI_STRING = ?)");
statement.setString(1, uri.toString());
statement.executeUpdate();
} finally {
close(statement);
}
}
public void close(ResultSet resultSet) {
try {
if (resultSet != null) {
resultSet.close();
}
} catch (SQLException e) {
getLogger().log(e, LOG_CHANNEL, Logger.WARNING);
}
}
public void close(InputStream in) {
try {
if (in != null) {
in.close();
}
} catch (IOException e) {
getLogger().log(e, LOG_CHANNEL, Logger.WARNING);
}
}
public void close(OutputStream out) {
try {
if (out != null) {
out.close();
}
} catch (IOException e) {
getLogger().log(e, LOG_CHANNEL, Logger.WARNING);
}
}
public static long copy(InputStream in, OutputStream out, int bufferSize)
throws IOException
{
long writtenBytes = 0;
int read = 0;
byte buffer[] = new byte[bufferSize];
while ((read = in.read(buffer, 0, bufferSize)) != -1) {
out.write(buffer, 0, read);
writtenBytes += read;
}
return writtenBytes;
}
protected String convertRevisionNumberToComparable(String revisioNumber) {
return "to_number(substr("+revisioNumber+",1,instr("+revisioNumber+",'.')-1)), to_number(substr("+revisioNumber+",instr("+revisioNumber+",'.')+1))";
}
}
/*
* $Header: /home/cvspublic/jakarta-slide/src/stores/org/apache/slide/store/impl/rdbms/StoreContentZip.java,v 1.5 2004/07/28 09:34:16 ib Exp $
* $Revision: 1.5 $
* $Date: 2004/07/28 09:34:16 $
*
* ====================================================================
*
* Copyright 1999-2003 The Apache Software Foundation
*
* Licensed 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.slide.store.impl.rdbms;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.zip.ZipEntry;
import java.util.zip.ZipException;
import java.util.zip.ZipInputStream;
import java.util.zip.ZipOutputStream;
/**
* Title: StoreContentZip
*
* This util class can generally be used to zip/unzip an inputstream
* Returns the zip/unzip data as both output/input streams. This is used
* in the J2EEContentStore
* @version $Revision: 1.5 $
*/
class StoreContentZip {
protected static final int ZIP_BUFFER = 2048;
private long contentLength = 0;
private long initialContentLength = -1;
private OutputStream theOS = null;
/**
* Constructor for StoreContentZip.
*/
public StoreContentZip() {
super();
contentLength = 0;
}
/**
* This method compress the input stream and returns the outputstream
* @param InputStream inIPS
* @exception IOException,ZipException
* @return the compressed OutputStream
*/
public void Zip(InputStream inIPS)
throws IOException, ZipException{
int byteCount = 0;
contentLength = 0;
initialContentLength = 0;
byte data[] = new byte[ZIP_BUFFER];
ByteArrayOutputStream baos = new ByteArrayOutputStream();
ZipOutputStream zoutp = new ZipOutputStream(baos);
zoutp.putNextEntry(new ZipEntry("zippedfile"));
while((byteCount = inIPS.read(data,0,ZIP_BUFFER)) != -1 ) {
zoutp.write(data,0,byteCount);
initialContentLength += byteCount;
}
zoutp.finish();
zoutp.flush();
zoutp.close();
baos.flush();
baos.close();
contentLength = (long)baos.size();
theOS = baos;
}
/**
* This method decompress the input stream and returns the outputstream
* @param InputStream inIPS
* @exception IOException,ZipException
* @return the decompressed OutputStream
*/
public void UnZip(InputStream inIPS)
throws IOException, ZipException{
int byteCount = 0;
contentLength = 0;
byte indata[] = new byte[ZIP_BUFFER];
ByteArrayOutputStream baos = new ByteArrayOutputStream();
ZipInputStream zinp = new ZipInputStream(inIPS);
while (zinp.getNextEntry() != null) {
while ((byteCount = zinp.read(indata,0,ZIP_BUFFER)) != -1 ) {
baos.write(indata,0,byteCount);
}
}
contentLength = (long)baos.size();
baos.flush();
baos.close();
zinp.close();
theOS = baos;
}
/**
* This method returns the compressed/decompressed stream as InputStream
* @param void
* @exception IOException,ZipException
* @return the processed InputStream
*/
public InputStream getInputStream()
throws IOException, ZipException{
return new ByteArrayInputStream(
((ByteArrayOutputStream)theOS).toByteArray());
}
/**
* This method returns the compressed/decompressed stream as O/PStream
* @param void
* @exception IOException,ZipException
* @return the processed InputStream
*/
public OutputStream getOutputStream()
throws IOException, ZipException{
return theOS;
}
/**
* Gets the length.
* @return return the length of the un/compressed Stream
*/
public long getContentLength() {
return contentLength;
}
public long getInitialContentLength() {
return initialContentLength;
}
}
/*
* $Header: /home/cvspublic/jakarta-slide/src/stores/org/apache/slide/store/impl/rdbms/OracleRDBMSAdapter.java,v 1.7 2004/07/28 09:34:16 ib Exp $
* $Revision: 1.7 $
* $Date: 2004/07/28 09:34:16 $
*
* ====================================================================
*
* Copyright 1999-2003 The Apache Software Foundation
*
* Licensed 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.slide.store.impl.rdbms;
import org.apache.slide.common.*;
import org.apache.slide.content.*;
import org.apache.slide.util.logger.Logger;
import java.io.*;
import java.sql.*;
/**
* Adapter for Oracle 10.
*
* @version $Revision: 1.7 $
*/
public class OracleRDBMSAdapter extends CommonRDBMSAdapter implements SequenceAdapter {
protected static String normalizeSequenceName(String sequenceName) {
return sequenceName.replace('-', '_').toUpperCase() + "_SEQ";
}
// Constructor
public OracleRDBMSAdapter(Service service, Logger logger) {
super(service, logger);
}
// Public Methods
public boolean isSequenceSupported(Connection conn) {
return true;
}
public boolean createSequence(Connection conn, String sequenceName) throws ServiceAccessException {
String query = "CREATE SEQUENCE \"" + normalizeSequenceName(sequenceName) + "\"";
PreparedStatement statement = null;
try {
statement = conn.prepareStatement(query);
statement.executeUpdate();
return true;
} catch (SQLException e) {
throw new ServiceAccessException(service, e);
} finally {
close(statement);
}
}
public long nextSequenceValue(Connection conn, String sequenceName) throws ServiceAccessException {
String selectQuery = "SELECT \"" + normalizeSequenceName(sequenceName)+"\".nextval FROM DUAL";
PreparedStatement selectStatement = null;
ResultSet res = null;
try {
selectStatement = conn.prepareStatement(selectQuery);
res = selectStatement.executeQuery();
if (!res.next()) {
throw new ServiceAccessException(service, "Could not increment sequence " + sequenceName);
}
long value = res.getLong(1);
return value;
} catch (SQLException e) {
throw new ServiceAccessException(service, e);
} finally {
close(selectStatement, res);
}
}
public boolean sequenceExists(Connection conn, String sequenceName) throws ServiceAccessException {
PreparedStatement selectStatement = null;
ResultSet res = null;
try {
selectStatement =
conn.prepareStatement("ALTER SEQUENCE \"" + normalizeSequenceName(sequenceName) + "\" INCREMENT BY 1");
res = selectStatement.executeQuery();
return true;
} catch (SQLException e) {
return false;
} finally {
close(selectStatement, res);
}
}
// Private Methods
protected void storeContent(
Connection connection,
Uri uri,
NodeRevisionDescriptor revisionDescriptor,
NodeRevisionContent revisionContent)
throws IOException, SQLException
{
getLogger().log("storeContent: " + uri, Logger.DEBUG);
assureVersionInfo(connection, uri, revisionDescriptor);
long versionContentId = getVersionContentId(connection, uri, revisionDescriptor);
insertEmptyContent(connection, versionContentId);
PreparedStatement statement = connection.prepareStatement(
"SELECT vc.CONTENT FROM VERSION_CONTENT vc WHERE vc.VERSION_ID = ? FOR UPDATE");
try {
statement.setLong(1, versionContentId);
ResultSet res = statement.executeQuery();
try {
res.next();
Blob blob = res.getBlob(1);
InputStream in = revisionContent.streamContent();
OutputStream out = ((oracle.sql.BLOB) blob).getBinaryOutputStream();
StoreContentZip ziputil = new StoreContentZip();
if (bcompress) {
getLogger().log("Compressing the data", LOG_CHANNEL, 6);
ziputil.Zip(in);
in = ziputil.getInputStream();
}
try {
long writtenBytes = copy(in, out, ((oracle.sql.BLOB) blob).getBufferSize());
// TMP
System.out.println("DEBUG ---------- WRITTEN BYTES: " + writtenBytes);
if (revisionDescriptor.getContentLength() == -1) {
if (bcompress) {
revisionDescriptor.setContentLength(ziputil.getInitialContentLength());
} else {
revisionDescriptor.setContentLength(writtenBytes);
}
// TMP
System.out.println("DEBUG ---------- NEWCONTENTLENGTH: " + revisionDescriptor.getContentLength());
} else {
// TMP
System.out.println("DEBUG ---------- ORIGINALCONTENTLENGTH: " + revisionDescriptor.getContentLength());
}
} finally {
close(out);
}
} finally {
close(res);
}
} finally {
close(statement);
}
}
private long getVersionContentId(Connection connection, Uri uri, NodeRevisionDescriptor revisionDescriptor)
throws SQLException
{
PreparedStatement statement = connection.prepareStatement(
"select vh.VERSION_ID from VERSION_HISTORY vh, URI u " +
"where vh.URI_ID = u.URI_ID and u.URI_STRING = ? and vh.REVISION_NO"
+ getRevisionNumberAsWhereQueryFragement(revisionDescriptor.getRevisionNumber()));
try {
statement.setString(1, uri.toString());
ResultSet res = statement.executeQuery();
try {
res.next();
return res.getLong(1);
} finally {
close(res);
}
} finally {
close(statement);
}
}
private void insertEmptyContent(Connection connection, long versionContentId)
throws SQLException
{
PreparedStatement statement = connection.prepareStatement(
"insert into VERSION_CONTENT (VERSION_ID, CONTENT) values (?, EMPTY_BLOB())");
try {
statement.setLong(1, versionContentId);
statement.executeUpdate();
} finally {
close(statement);
}
}
}
Index: org/apache/slide/store/impl/rdbms/CommonRDBMSAdapter.java
===================================================================
RCS file: /home/cvspublic/jakarta-slide/src/stores/org/apache/slide/store/impl/rdbms/CommonRDBMSAdapter.java,v
retrieving revision 1.2
diff -r1.2 CommonRDBMSAdapter.java
316c316
< public static void copy(InputStream in, OutputStream out, int bufferSize)
---
> public static long copy(InputStream in, OutputStream out, int bufferSize)
318a319,320
> long writtenBytes = 0;
>
322a325
> writtenBytes += read;
323a327,328
>
> return writtenBytes;
Index: org/apache/slide/store/impl/rdbms/OracleRDBMSAdapter.java
===================================================================
RCS file: /home/cvspublic/jakarta-slide/src/stores/org/apache/slide/store/impl/rdbms/OracleRDBMSAdapter.java,v
retrieving revision 1.7
diff -r1.7 OracleRDBMSAdapter.java
138a139
> StoreContentZip ziputil = new StoreContentZip();
141d141
< StoreContentZip ziputil = new StoreContentZip();
147c147,154
< copy(in, out, ((oracle.sql.BLOB) blob).getBufferSize());
---
> long writtenBytes = copy(in, out, ((oracle.sql.BLOB) blob).getBufferSize());
> if (revisionDescriptor.getContentLength() == -1) {
> if (bcompress) {
> revisionDescriptor.setContentLength(ziputil.getInitialContentLength());
> } else {
> revisionDescriptor.setContentLength(writtenBytes);
> }
> }
Index: org/apache/slide/store/impl/rdbms/StoreContentZip.java
===================================================================
RCS file: /home/cvspublic/jakarta-slide/src/stores/org/apache/slide/store/impl/rdbms/StoreContentZip.java,v
retrieving revision 1.5
diff -r1.5 StoreContentZip.java
49c49,50
< private OutputStream theOS = null;
---
> private long initialContentLength = -1;
> private OutputStream theOS = null;
69a71
> initialContentLength = 0;
75a78
> initialContentLength += byteCount;
82c85
< contentLength = (long)baos.size();
---
> contentLength = (long)baos.size();
141a145,148
> public long getInitialContentLength() {
> return initialContentLength;
> }
>
---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]