/*
* Copyright 2001-2008 Geert Bevin <gbevin[remove] at uwyn dot com>
* Licensed under the Apache License, Version 2.0 (the "License")
* $Id: oracle_jdbc_driver_OracleDriver.java 3918 2008-04-14 17:35:35Z gbevin $
*/
package com.uwyn.rife.cmf.dam.contentstores.rawstoredrivers;
import com.uwyn.rife.cmf.dam.ContentDataUser;
import com.uwyn.rife.cmf.dam.contentstores.exceptions.UseContentDataErrorException;
import com.uwyn.rife.cmf.dam.exceptions.ContentManagerException;
import com.uwyn.rife.config.RifeConfig;
import com.uwyn.rife.database.Datasource;
import com.uwyn.rife.database.DbPreparedStatement;
import com.uwyn.rife.database.DbPreparedStatementHandler;
import com.uwyn.rife.database.DbResultSet;
import com.uwyn.rife.database.DbResultSetHandler;
import com.uwyn.rife.database.exceptions.DatabaseException;
import com.uwyn.rife.database.queries.Insert;
import com.uwyn.rife.database.queries.Select;
import java.io.BufferedInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.sql.SQLException;
import oracle.sql.BLOB;
public class oracle_jdbc_driver_OracleDriver extends generic
{
private final static int BUFFER_SIZE = 65535; // 64kB
private final static int MAX_BLOB_SIZE = 1024*1024*1024*2; // 2GB
public oracle_jdbc_driver_OracleDriver(Datasource datasource)
{
super(datasource);
mStoreContentChunk = new Insert(getDatasource())
.into(RifeConfig.Cmf.getTableContentStoreRawChunk())
.fieldParameter("contentId")
.fieldParameter("ordinal")
.fieldCustom("chunk", "empty_blob()");
}
protected String getContentSizeColumnName()
{
return "contentsize";
}
public <ResultType> ResultType useContentData(final int id, ContentDataUser user)
throws ContentManagerException
{
if (id < 0) throw new IllegalArgumentException("id must be positive");
if (null == user) throw new IllegalArgumentException("user can't be null");
try
{
InputStream data = RawContentStreamOracle.getInstance(this, mRetrieveContentChunks, id);
try
{
return (ResultType)user.useContentData(data);
}
finally
{
if (data != null)
{
try
{
data.close();
}
catch (IOException e)
{
throw new UseContentDataErrorException(id, e);
}
}
}
}
catch (DatabaseException e)
{
throw new UseContentDataErrorException(id, e);
}
}
protected int storeChunks(Insert storeContentChunk, final int id, final InputStream data)
throws IOException
{
class Scope {
int size = 0;
int length = 0;
int ordinal = 0;
byte[] buffer = null;
int blobsize = 0;
}
final Scope s = new Scope();
if (data != null)
{
s.buffer = new byte[BUFFER_SIZE];
while (s.length != -1 &&
(s.length = data.read(s.buffer)) != -1)
{
if (executeUpdate(storeContentChunk, new DbPreparedStatementHandler() {
public void setParameters(DbPreparedStatement statement)
{
statement
.setInt("contentId", id)
.setInt("ordinal", s.ordinal);
}
}) <= 0)
{
return -1;
}
s.blobsize = 0;
executeQuery(new Select(getDatasource())
.from(storeContentChunk.getInto())
.field("chunk")
.where("contentId", "=", id)
.whereAnd("ordinal = "+s.ordinal+" FOR UPDATE"), new DbResultSetHandler() {
public Object concludeResults(DbResultSet resultset) throws SQLException
{
if (!resultset.next())
{
return null;
}
BLOB blob = (BLOB)resultset.getBlob(1);
OutputStream os = blob.getBinaryOutputStream();
try
{
try
{
do
{
os.write(s.buffer, 0, s.length);
s.size += s.length;
s.blobsize += s.length;
}
while (s.blobsize < MAX_BLOB_SIZE &&
(s.length = data.read(s.buffer)) != -1);
}
finally
{
os.close();
}
}
catch (IOException e)
{
throw new DatabaseException(e);
}
return null;
}
});
s.ordinal++;
}
}
return s.size;
}
protected void serveChunks(DbResultSet resultset, OutputStream os, int size)
throws SQLException, IOException
{
do
{
BLOB blob = (BLOB)resultset.getBlob("chunk");
if (null == blob)
{
return;
}
InputStream is = blob.getBinaryStream();
try
{
byte[] buffer = new byte[blob.getBufferSize()];
BufferedInputStream buffered_image_is = new BufferedInputStream(is, buffer.length);
int input_size = 0;
while ((input_size = buffered_image_is.read(buffer)) != -1)
{
os.write(buffer, 0, input_size);
}
}
finally
{
is.close();
}
}
while (resultset.next());
}
}