com.ibm.as400.access.SQLBlob Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of jt400 Show documentation
Show all versions of jt400 Show documentation
The Open Source version of the IBM Toolbox for Java
The newest version!
///////////////////////////////////////////////////////////////////////////////
//
// JTOpen (IBM Toolbox for Java - OSS version)
//
// Filename: SQLBlob.java
//
// The source code contained herein is licensed under the IBM Public License
// Version 1.0, which has been approved by the Open Source Initiative.
// Copyright (C) 1997-2006 International Business Machines Corporation and
// others. All rights reserved.
//
///////////////////////////////////////////////////////////////////////////////
package com.ibm.as400.access;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.InputStream;
import java.io.IOException;
import java.io.Reader;
import java.math.BigDecimal;
import java.sql.Blob;
import java.sql.Clob;
import java.sql.Date;
/* ifdef JDBC40 */
import java.sql.NClob;
import java.sql.RowId;
/* endif */
import java.sql.SQLException;
/* ifdef JDBC40 */
import java.sql.SQLXML;
/* endif */
import java.sql.Time;
import java.sql.Timestamp;
import java.util.Calendar;
final class SQLBlob extends SQLDataBase
{
static final String copyright = "Copyright (C) 1997-2010 International Business Machines Corporation and others.";
private static final byte[] default_ = new byte[0];
private int maxLength_;
private byte[] value_ = default_;
private Object savedObject_; // This is our byte[] or InputStream or whatever that we save to convert to bytes until we really need to.
private int scale_ = -1; // This is our length.
SQLBlob(int maxLength, SQLConversionSettings settings)
{
super(settings);
maxLength_ = maxLength;
}
public Object clone()
{
return new SQLBlob(maxLength_, null);
}
public void convertFromRawBytes(byte[] rawBytes, int offset, ConvTable ccsidConverter, boolean ignoreConversionErrors)
throws SQLException
{
int length = BinaryConverter.byteArrayToInt(rawBytes, offset);
value_ = new byte[length];
System.arraycopy(rawBytes, offset+4, value_, 0, value_.length);
savedObject_ = null;
}
public void convertToRawBytes(byte[] rawBytes, int offset, ConvTable ccsidConverter)
throws SQLException
{
if(savedObject_ != null) doConversion();
BinaryConverter.intToByteArray(value_.length, rawBytes, offset);
System.arraycopy(value_, 0, rawBytes, offset+4, value_.length);
}
public void set(Object object, Calendar calendar, int scale) throws SQLException
{
// If it's a byte[] we check for data truncation.
if(object instanceof byte[])
{
byte[] bytes = (byte[])object;
truncated_ = (bytes.length > maxLength_ ? bytes.length-maxLength_ : 0);
outOfBounds_ = false;
}
else if(object instanceof String)
{
byte[] bytes = null;
try
{
bytes = BinaryConverter.stringToBytes((String)object);
}
catch(NumberFormatException nfe)
{
// the String contains non-hex characters
JDError.throwSQLException(this, JDError.EXC_DATA_TYPE_MISMATCH, nfe);
// Dummy throw to prevent warning about npe on bytes
throw new SQLException();
}
object = bytes;
outOfBounds_ = false;
truncated_ = (bytes.length > maxLength_ ? bytes.length-maxLength_ : 0);
}
else if (object instanceof Clob) {
byte[] bytes = null;
try {
bytes = BinaryConverter.stringToBytes(((Clob)object).getSubString(1, (int)((Clob)object).length()));
} catch(NumberFormatException nfe) {
// the String contains non-hex characters
JDError.throwSQLException(this, JDError.EXC_DATA_TYPE_MISMATCH, nfe);
// Dummy throw to prevent warning about npe on bytes
throw new SQLException();
}
object = bytes;
outOfBounds_ = false;
truncated_ = (bytes.length > maxLength_ ? bytes.length-maxLength_ : 0);
}
else if(object instanceof Reader)
{
int length = scale; // hack to get the length into the set method
byte[] bytes = null;
if(length >= 0)
{
try
{
int blockSize = length < AS400JDBCPreparedStatement.LOB_BLOCK_SIZE ? length : AS400JDBCPreparedStatement.LOB_BLOCK_SIZE;
ByteArrayOutputStream baos = new ByteArrayOutputStream();
HexReaderInputStream stream = new HexReaderInputStream((Reader)object);
byte[] byteBuffer = new byte[blockSize];
int totalBytesRead = 0;
int bytesRead = stream.read(byteBuffer, 0, blockSize);
while(bytesRead > -1 && totalBytesRead < length)
{
baos.write(byteBuffer, 0, bytesRead);
totalBytesRead += bytesRead;
int bytesRemaining = length - totalBytesRead;
if(bytesRemaining < blockSize)
{
blockSize = bytesRemaining;
}
bytesRead = stream.read(byteBuffer, 0, blockSize);
}
bytes = baos.toByteArray();
if(bytes.length < length)
{
// a length longer than the stream was specified
JDError.throwSQLException(this, JDError.EXC_DATA_TYPE_MISMATCH);
}
int objectLength = bytes.length;
if(bytes.length > maxLength_)
{
byte[] newValue = new byte[maxLength_];
System.arraycopy(bytes, 0, newValue, 0, maxLength_);
bytes = newValue;
}
stream.close(); //@scan1
object = bytes;
truncated_ = objectLength - bytes.length;
}
catch(ExtendedIOException eie)
{
// the Reader contains non-hex characters
JDError.throwSQLException(this, JDError.EXC_DATA_TYPE_MISMATCH, eie);
}
catch(IOException ie)
{
JDError.throwSQLException(JDError.EXC_INTERNAL, ie);
}
}
else if(length == -2 || length == -1 ) //@readerlen new else-if block (read all data)
{
try
{
int blockSize = AS400JDBCPreparedStatement.LOB_BLOCK_SIZE;
ByteArrayOutputStream baos = new ByteArrayOutputStream();
HexReaderInputStream stream = new HexReaderInputStream((Reader)object);
byte[] byteBuffer = new byte[blockSize];
int totalBytesRead = 0;
int bytesRead = stream.read(byteBuffer, 0, blockSize);
while(bytesRead > -1 )
{
baos.write(byteBuffer, 0, bytesRead);
totalBytesRead += bytesRead;
bytesRead = stream.read(byteBuffer, 0, blockSize);
}
bytes = baos.toByteArray();
int objectLength = bytes.length;
if(bytes.length > maxLength_)
{
byte[] newValue = new byte[maxLength_];
System.arraycopy(bytes, 0, newValue, 0, maxLength_);
bytes = newValue;
}
stream.close(); //@scan1
object = bytes;
truncated_ = objectLength - bytes.length;
}
catch(ExtendedIOException eie)
{
// the Reader contains non-hex characters
JDError.throwSQLException(this, JDError.EXC_DATA_TYPE_MISMATCH, eie);
}
catch(IOException ie)
{
JDError.throwSQLException(JDError.EXC_INTERNAL, ie);
}
}
else
{
JDError.throwSQLException(JDError.EXC_DATA_TYPE_MISMATCH);
}
}
else if(( !(object instanceof Blob)) &&
!(object instanceof InputStream))
{
if (JDTrace.isTraceOn()) {
if (object == null) {
JDTrace.logInformation(this, "Unable to assign null object");
} else {
JDTrace.logInformation(this, "Unable to assign object("+object+") of class("+object.getClass().toString()+")");
}
}
JDError.throwSQLException(this, JDError.EXC_DATA_TYPE_MISMATCH);
}
savedObject_ = object;
if(scale != -1) scale_ = scale;
// If we truncated, do the conversion so that the truncated value is set
if (truncated_ > 0) {
doConversion();
}
}
private void doConversion()
throws SQLException
{
try
{
Object object = savedObject_;
if(object instanceof byte[])
{
value_ = (byte[]) object;
int objectLength = value_.length;
if(value_.length > maxLength_)
{
byte[] newValue = new byte[maxLength_];
System.arraycopy(value_, 0, newValue, 0, maxLength_);
value_ = newValue;
}
truncated_ = objectLength - value_.length;
}
else if(object instanceof Blob)
{
Blob blob = (Blob) object;
int blobLength = (int)blob.length();
int lengthToUse = blobLength < 0 ? 0x7FFFFFFF : blobLength;
if(lengthToUse > maxLength_) lengthToUse = maxLength_;
value_ = blob.getBytes(1, lengthToUse);
truncated_ = blobLength - lengthToUse;
}
else if(object instanceof InputStream)
{
int length = scale_; // hack to get the length into the set method
if(length >= 0)
{
InputStream stream = (InputStream)object;
ByteArrayOutputStream baos = new ByteArrayOutputStream();
int blockSize = length < AS400JDBCPreparedStatement.LOB_BLOCK_SIZE ? length : AS400JDBCPreparedStatement.LOB_BLOCK_SIZE;
byte[] byteBuffer = new byte[blockSize];
try
{
int totalBytesRead = 0;
int bytesRead = stream.read(byteBuffer, 0, blockSize);
while(bytesRead > -1 && totalBytesRead < length)
{
baos.write(byteBuffer, 0, bytesRead);
totalBytesRead += bytesRead;
int bytesRemaining = length - totalBytesRead;
if(bytesRemaining < blockSize)
{
blockSize = bytesRemaining;
}
bytesRead = stream.read(byteBuffer, 0, blockSize);
}
}
catch(IOException ie)
{
JDError.throwSQLException(JDError.EXC_INTERNAL, ie);
}
value_ = baos.toByteArray();
if(value_.length < length)
{
// a length longer than the stream was specified
JDError.throwSQLException(this, JDError.EXC_DATA_TYPE_MISMATCH);
}
int objectLength = value_.length;
if(value_.length > maxLength_)
{
byte[] newValue = new byte[maxLength_];
System.arraycopy(value_, 0, newValue, 0, maxLength_);
value_ = newValue;
}
truncated_ = objectLength - value_.length;
}
else if(length == -2) //@readerlen new else-if block (read all data)
{
InputStream stream = (InputStream)object;
ByteArrayOutputStream baos = new ByteArrayOutputStream();
int blockSize = AS400JDBCPreparedStatement.LOB_BLOCK_SIZE;
byte[] byteBuffer = new byte[blockSize];
try
{
int totalBytesRead = 0;
int bytesRead = stream.read(byteBuffer, 0, blockSize);
while(bytesRead > -1)
{
baos.write(byteBuffer, 0, bytesRead);
totalBytesRead += bytesRead;
bytesRead = stream.read(byteBuffer, 0, blockSize);
}
}
catch(IOException ie)
{
JDError.throwSQLException(JDError.EXC_INTERNAL, ie);
}
value_ = baos.toByteArray();
int objectLength = value_.length;
if(value_.length > maxLength_)
{
byte[] newValue = new byte[maxLength_];
System.arraycopy(value_, 0, newValue, 0, maxLength_);
value_ = newValue;
}
truncated_ = objectLength - value_.length;
}
else
{
JDError.throwSQLException(JDError.EXC_DATA_TYPE_MISMATCH);
}
}
else
{
JDError.throwSQLException(JDError.EXC_DATA_TYPE_MISMATCH);
}
}
finally
{
savedObject_ = null;
}
}
//---------------------------------------------------------//
// //
// DESCRIPTION OF SQL TYPE //
// //
//---------------------------------------------------------//
public int getSQLType()
{
return SQLData.BLOB;
}
public String getCreateParameters()
{
return AS400JDBCDriver.getResource("MAXLENGTH",null);
}
public int getDisplaySize()
{
return maxLength_;
}
public String getJavaClassName()
{
return "com.ibm.as400.access.AS400JDBCBlob";
}
public String getLiteralPrefix()
{
return null;
}
public String getLiteralSuffix()
{
return null;
}
public String getLocalName()
{
return "BLOB";
}
public int getMaximumPrecision()
{
return AS400JDBCDatabaseMetaData.MAX_LOB_LENGTH; //@xml3 // the DB2 SQL reference says this should be 2147483647 but we return 1 less to allow for NOT NULL columns
}
public int getMaximumScale()
{
return 0;
}
public int getMinimumScale()
{
return 0;
}
public int getNativeType()
{
return 404;
}
public int getPrecision()
{
return maxLength_;
}
public int getRadix()
{
return 0;
}
public int getScale()
{
return 0;
}
public int getType()
{
return java.sql.Types.BLOB;
}
public String getTypeName()
{
return "BLOB";
}
public boolean isSigned()
{
return false;
}
public boolean isText()
{
return true; //@CRS - Why is this true?
}
public int getActualSize()
{
return value_.length;
}
public int getTruncated()
{
return truncated_;
}
public boolean getOutOfBounds() {
return outOfBounds_;
}
//---------------------------------------------------------//
// //
// CONVERSIONS TO JAVA TYPES //
// //
//---------------------------------------------------------//
public BigDecimal getBigDecimal(int scale) //@CRS - Could use a Converter here to make this work.
throws SQLException
{
JDError.throwSQLException(this, JDError.EXC_DATA_TYPE_MISMATCH);
return null;
}
public InputStream getBinaryStream()
throws SQLException
{
if(savedObject_ != null) doConversion();
truncated_ = 0; outOfBounds_ = false;
return new ByteArrayInputStream(value_);
}
public Blob getBlob()
throws SQLException
{
if(savedObject_ != null) doConversion();
truncated_ = 0; outOfBounds_ = false;
return new AS400JDBCBlob(value_, maxLength_);
}
public boolean getBoolean()
throws SQLException
{
JDError.throwSQLException(this, JDError.EXC_DATA_TYPE_MISMATCH);
return false;
}
public byte getByte()
throws SQLException
{
JDError.throwSQLException(this, JDError.EXC_DATA_TYPE_MISMATCH);
return -1;
}
public byte[] getBytes()
throws SQLException
{
if(savedObject_ != null) doConversion();
truncated_ = 0; outOfBounds_ = false;
return value_;
}
public Date getDate(Calendar calendar) //@CRS - Could use toLong() to make this work.
throws SQLException
{
JDError.throwSQLException(this, JDError.EXC_DATA_TYPE_MISMATCH);
return null;
}
public double getDouble() //@CRS - Could use a Converter here to make this work.
throws SQLException
{
JDError.throwSQLException(this, JDError.EXC_DATA_TYPE_MISMATCH);
return -1;
}
public float getFloat() //@CRS - Could use a Converter here to make this work.
throws SQLException
{
JDError.throwSQLException(this, JDError.EXC_DATA_TYPE_MISMATCH);
return -1;
}
public int getInt() //@CRS - Could use a Converter here to make this work.
throws SQLException
{
JDError.throwSQLException(this, JDError.EXC_DATA_TYPE_MISMATCH);
return -1;
}
public long getLong() //@CRS - Could use a Converter here to make this work.
throws SQLException
{
JDError.throwSQLException(this, JDError.EXC_DATA_TYPE_MISMATCH);
return -1;
}
public Object getObject()
throws SQLException
{
if(savedObject_ != null) doConversion();
truncated_ = 0; outOfBounds_ = false;
return new AS400JDBCBlob(value_, maxLength_);
}
public short getShort() //@CRS - Could use a Converter here to make this work.
throws SQLException
{
JDError.throwSQLException(this, JDError.EXC_DATA_TYPE_MISMATCH);
return -1;
}
public String getString()
throws SQLException
{
if(savedObject_ != null) doConversion();
truncated_ = 0; outOfBounds_ = false;
return BinaryConverter.bytesToHexString(value_);
}
public Time getTime(Calendar calendar) //@CRS - Could use toLong() to make this work.
throws SQLException
{
JDError.throwSQLException(this, JDError.EXC_DATA_TYPE_MISMATCH);
return null;
}
public Timestamp getTimestamp(Calendar calendar) //@CRS - Could use toLong() to make this work.
throws SQLException
{
JDError.throwSQLException(this, JDError.EXC_DATA_TYPE_MISMATCH);
return null;
}
/* ifdef JDBC40 */
//@PDA jdbc40
public RowId getRowId() throws SQLException
{
JDError.throwSQLException(this, JDError.EXC_DATA_TYPE_MISMATCH);
return null;
}
//@PDA jdbc40
public SQLXML getSQLXML() throws SQLException
{
if(savedObject_ != null) doConversion();
truncated_ = 0; outOfBounds_ = false;
//String string = BinaryConverter.bytesToHexString(value_); //@xml2
return new AS400JDBCSQLXML(value_, maxLength_); //@xml2
//return new AS400JDBCSQLXML(string, string.length()); //@xml2
}
/* endif */
// @array
public void saveValue() throws SQLException {
if(savedObject_ != null) doConversion();
savedValue_ = value_;
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy