com.ibm.as400.access.JDServerRow 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: JDServerRow.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-2001 International Business Machines Corporation and
// others. All rights reserved.
//
///////////////////////////////////////////////////////////////////////////////
package com.ibm.as400.access;
import java.sql.ResultSetMetaData;
import java.sql.SQLException;
import java.util.Calendar;
import java.util.Hashtable;
/**
The JDServerRow class implements a row of data that is loaded
directly from a datastream to or from the system.
**/
class JDServerRow
implements JDRow
{
static final String copyright = "Copyright (C) 1997-2001 International Business Machines Corporation and others.";
private int[] parameterTypes_;
// Private data.
private AS400JDBCConnection connection_;
private int[] ccsids_;
// Represents the total length of the data. For arrays
// this is arrayLen * arrayDataLen.
private int[] dataLength_;
private int[] arrayDataLength_;
private int[] dataOffset_;
private String[] fieldNames_;
private int[] lobLocatorHandles_; // @C2A
private int[] precisions_;
private byte[] rawBytes_;
private int rowDataOffset_;
private int rowIndex_;
private int[] scales_;
private DBData serverData_;
private DBDataFormat serverFormat_;
private SQLData[] sqlData_;
private int[] sqlTypes_;
private String[] sqlTypeNames_; /*@L1A*/
private boolean[] translated_;
private boolean wasCompressed = false; // set to true if variable length field compression is used
private Hashtable insensitiveColumnNames_; // @PDA maps strings to column indexes
boolean containsLob_; //@re-prep
boolean containsArray_; //@array
/**
Constructs a JDServerRow object. Use this constructor
when the format information has already been retrieved
from the system.
@param connection The connection to the system.
@param id The id.
@param serverFormat The server format information.
@param settings The conversion settings.
@exception SQLException If an error occurs.
**/
JDServerRow (AS400JDBCConnection connection,
int id,
DBDataFormat serverFormat,
SQLConversionSettings settings)
throws SQLException
{
initialize (connection, id, serverFormat, settings);
}
/**
Constructs a JDServerRow object. Use this constructor when format
information has not yet been retrieved from the system.
@param connection The connection to the system.
@param id The id.
@param settings The conversion settings.
@exception SQLException If an error occurs.
**/
/* @C1D
JDServerRow (AS400JDBCConnection connection,
int id,
SQLConversionSettings settings)
throws SQLException
{
DBDataFormat serverFormat = null;
DBSQLRequestDS request = new DBSQLRequestDS (
DBSQLRequestDS.FUNCTIONID_DESCRIBE,
id, DBSQLRequestDS.ORS_BITMAP_RETURN_DATA
+ DBSQLRequestDS.ORS_BITMAP_DATA_FORMAT, 0);
DBReplyRequestedDS reply = connection.sendAndReceive (request, id);
int errorClass = reply.getErrorClass();
int returnCode = reply.getReturnCode();
if (errorClass != 0)
JDError.throwSQLException (connection, id, errorClass, returnCode);
serverFormat = reply.getDataFormat ();
initialize (connection, id, serverFormat, settings);
}
*/
// @D1A
/**
Returns the raw bytes.
@param index The field index (1-based).
@return A copy of the bytes.
**/
byte[] getRawBytes(int index)
{
int index0 = index - 1;
byte[] copy = new byte[dataLength_[index0]];
System.arraycopy(rawBytes_, rowDataOffset_ + dataOffset_[index0], copy, 0, dataLength_[index0]);
return copy;
}
/**
Initializes the state of the object.
@param connection The connection to the system.
@param id The id.
@param serverFormat The server format information.
@param settings The conversion settings.
@exception SQLException If an error occurs.
**/
private void initialize (AS400JDBCConnection connection,
int id,
DBDataFormat serverFormat,
SQLConversionSettings settings)
throws SQLException
{
// Initialization.
connection_ = connection;
rawBytes_ = null;
rowDataOffset_ = -1;
rowIndex_ = -1;
serverData_ = null;
serverFormat_ = serverFormat;
int dateFormat = -1; // @550A
int timeFormat = -1; // @550A
try
{
int count;
if(serverFormat_ == null)
count = 0;
else
count = serverFormat_.getNumberOfFields ();
ccsids_ = new int[count];
dataLength_ = new int[count];
arrayDataLength_ = new int[count];
dataOffset_ = new int[count];
fieldNames_ = new String[count];
lobLocatorHandles_= new int[count]; // @C2A
precisions_ = new int[count];
scales_ = new int[count];
sqlData_ = new SQLData[count];
sqlTypes_ = new int[count];
sqlTypeNames_ = new String[count]; /*@L1A*/
translated_ = new boolean[count];
insensitiveColumnNames_ = null; //@PDA
containsLob_ = false; //@re-prep
containsArray_ = false; //@array
// Compute the offsets, lengths, and SQL data for
// each field.
if(count > 0)
{
int offset = 0;
boolean translateBinary = connection.getProperties().getBoolean (JDProperties.TRANSLATE_BINARY);
if(connection_.getVRM() >= JDUtilities.vrm610 && serverFormat_.getCSRSData()) // @550A retrieve date/time formats if the data is from a stored procedure result set
{
dateFormat = serverFormat_.getDateFormat();
timeFormat = serverFormat_.getTimeFormat();
}
for(int i = 0; i < count; ++i)
{
ccsids_[i] = serverFormat_.getFieldCCSID (i);
dataOffset_[i] = offset;
dataLength_[i] = serverFormat_.getFieldLength (i);
//@array (if array type) here we do not know the array length, just the element length, but that is okay since the
// elem length is fed into the sqlDataTemplate in SQLArray.
// for reply result, setRowIndex() will later re-populate the dataLength_ and dataOffset_ arrays anyways.)
// @G2C
lobLocatorHandles_[i] = serverFormat_.getFieldLOBLocator (i); // @C2C
offset += dataLength_[i];
scales_[i] = serverFormat_.getFieldScale (i);
precisions_[i] = serverFormat_.getFieldPrecision (i);
sqlTypes_[i] = serverFormat_.getFieldSQLType (i);
int compositeContentType = -1;
if( serverFormat_.getArrayType (i) == 1) //@array
{
compositeContentType = sqlTypes_[i] & 0xFFFE; //@array
sqlTypes_[i] = SQLData.NATIVE_ARRAY; //@array not a hostserver number, since we only get a 1 bit array flag for the type
arrayDataLength_[i] = serverFormat_.getArrayFieldLength(i); /*@G2A*/
} else {
arrayDataLength_[i] = 0; /*@G2A*/
}
//@array comment: we are assuming here that all of the metadata above (except sqlType) is for the array content type
//@re-prep check if lob or locator type here
//hostserver cannot know beforehand if type will be a lob or a locator. This is on a per-connection basis.
int fieldType = sqlTypes_[i] & 0xFFFE; //@re-prep
if(fieldType == 404 || fieldType == 960 || fieldType == 408 || fieldType == 964 || fieldType == 412 || fieldType == 968) //@re-prep
containsLob_ = true; //@re-prep
else if(fieldType == SQLData.NATIVE_ARRAY) //@array
containsArray_ = true; //@array
int maxLobSize = serverFormat_.getFieldLOBMaxSize (i); // @C2C
int xmlCharType = serverFormat_.getXMLCharType(i); //@xml3 sb=0 or db=1
if (fieldType == SQLData.NATIVE_ARRAY) { /*@G2A*/
sqlData_[i] = SQLDataFactory.newData (connection, id,
fieldType, arrayDataLength_[i], precisions_[i],
scales_[i], ccsids_[i], translateBinary, settings,
maxLobSize, (i+1), dateFormat, timeFormat, compositeContentType, xmlCharType); //@F1C // @C2C @550C @array //@xml3
} else {
sqlData_[i] = SQLDataFactory.newData (connection, id,
fieldType, dataLength_[i], precisions_[i],
scales_[i], ccsids_[i], translateBinary, settings,
maxLobSize, (i+1), dateFormat, timeFormat, compositeContentType, xmlCharType); //@F1C // @C2C @550C @array //@xml3
}
// @E2D // SQLDataFactory never returns null.
// @E2D if (sqlData_[i] == null)
// @E2D JDError.throwSQLException (JDError.EXC_INTERNAL);
}
}
}
catch(DBDataStreamException e)
{
JDError.throwSQLException (JDError.EXC_INTERNAL, e);
}
}
// If varying length field compression was used, and it was not used on a subsequent request, we need to set the
// data offsets and data lengths based on the server format
void setOriginalData() throws SQLException{
try{
int count = 0;
if(serverFormat_ != null)
count = serverFormat_.getNumberOfFields ();
if(count>0){
int offset = 0;
for(int i = 0; i < count; ++i)
{
dataOffset_[i] = offset;
dataLength_[i] = serverFormat_.getFieldLength (i);
arrayDataLength_[i] = serverFormat_.getArrayFieldLength(i); /*@G2A*/
offset += dataLength_[i];
}
}
}
catch(DBDataStreamException e){
JDError.throwSQLException(JDError.EXC_INTERNAL, e);
}
}
/**
Sets the server data. Use this when new data has been retrieved
from the system.
@param serverData The server data.
@exception SQLException If an error occurs.
**/
void setServerData (DBData serverData)
throws SQLException
{
serverData_ = serverData;
try
{
rawBytes_ = serverData_.getRawBytes ();
//@array all parsed variable array data from host is inside of DBVariableData (serverData_)
}
catch(DBDataStreamException e)
{
JDError.throwSQLException (JDError.EXC_INTERNAL, e);
}
}
/**
Sets the row index within the server data.
@param rowIndex The row index (0-based).
@exception SQLException If an error occurs.
**/
void setRowIndex (int rowIndex)
throws SQLException
{
rowIndex_ = rowIndex;
try
{
if(serverData_ != null)
{
rowDataOffset_ = serverData_.getRowDataOffset (rowIndex_);
//@array calculate data offsets for arrays (result data from host)
if(this.containsArray_ && rowDataOffset_ != -1) //@array array data not VLC but variable in length
{
//Here if reply is VariableData needed for Arrays. //@array
//@array set input array lengths of data
int offset = 0; //@array
int numOfFields = serverFormat_.getNumberOfFields(); //@array
int[] dataLengths = ((DBVariableData)serverData_).getTotalDataLengthsFromHost(); //@array
int[] arrayDataLengths = ((DBVariableData)serverData_).getArrayDataLengthsFromHost(); /*@G2A*/
int outCount = 0; //@arrayout
for(int j=0; j 0) {
arrayDataLength_[j] = arrayDataLengths[outCount]; /*@G2A*/
}
outCount++; //@arrayout
} //@array
}
} //@array
else if (serverData_.isVariableFieldsCompressed()
&& rowDataOffset_ != -1) // @K54
{ // @K54
wasCompressed = true;
int offset = 0; // @K54
int numOfFields = serverFormat_.getNumberOfFields(); // @K54
for (int j = 0; j < numOfFields; j++) // @K54
{
// Use SQL type to eliminate the string comparisons in the old code @P7A
int sqlType = sqlData_[j].getSQLType();
int length = 0; // @K54
dataOffset_[j] = offset; // @K54
switch (sqlType) {
case SQLData.VARCHAR:
case SQLData.VARCHAR_FOR_BIT_DATA:
case SQLData.LONG_VARCHAR:
case SQLData.LONG_VARCHAR_FOR_BIT_DATA:
case SQLData.VARBINARY:
case SQLData.DATALINK: {
length = BinaryConverter.byteArrayToUnsignedShort(rawBytes_,
rowDataOffset_ + offset); // @K54 //get actual length of data
length += 2; // Add two bytes for length portion on datastream
// //@K54
break;
}
case SQLData.VARGRAPHIC:
case SQLData.LONG_VARGRAPHIC:
case SQLData.LONG_NVARCHAR:
case SQLData.NVARCHAR: {
length = (2 * BinaryConverter.byteArrayToUnsignedShort(rawBytes_, rowDataOffset_ + offset)); //@K54 //get actual length of data
length += 2; //Add two bytes for length portion on datastream //@K54
break;
}
default:
length = serverFormat_.getFieldLength (j); //@K54 //get fixed size of data
} /* switch */
/* ----------------- Old code
String typeName = sqlData_[j].getTypeName(); //@K54
int length = 0; //@K54
dataOffset_[j] = offset; //@K54
//if it is a variable-length field, get actual size of data //@K54
if(typeName.equals("VARCHAR") || //@K54
typeName.equals("VARCHAR () FOR BIT DATA") || //@K54
typeName.equals("LONG VARCHAR") || //@K54
typeName.equals("LONG VARCHAR () FOR BIT DATA") || //@P3C@K54
typeName.equals("VARBINARY") || //@K54
typeName.equals("DATALINK")) //@K54
{ //@K54
length = BinaryConverter.byteArrayToUnsignedShort(rawBytes_, rowDataOffset_ + offset); //@K54 //get actual length of data
length += 2; //Add two bytes for length portion on datastream //@K54
} //@K54
else if(typeName.equals("VARGRAPHIC") || //@K54 graphics are two-byte characters
typeName.equals("LONG VARGRAPHIC") || //@K54
typeName.equals("NVARCHAR")) //@PD61
{ //@K54
length = (2 * BinaryConverter.byteArrayToUnsignedShort(rawBytes_, rowDataOffset_ + offset)); //@K54 //get actual length of data
length += 2; //Add two bytes for length portion on datastream //@K54
}
else
length = serverFormat_.getFieldLength (j); //@K54 //get fixed size of data
------------------------ end old Code */
offset += length; //@K54
dataLength_[j] = length; //@K54
arrayDataLength_[j] = serverFormat_.getArrayFieldLength(j); /*@G2A*/
} //@K54
} //@K54
else if(wasCompressed){ // If varying length field compression was used on one request, and not a subsequent fetch, we need to reset the data lengths and offsets based on the server format
wasCompressed = false;
setOriginalData();
}
}
else
rowDataOffset_ = -1;
}
catch(DBDataStreamException e)
{
JDError.throwSQLException (JDError.EXC_INTERNAL, e);
}
// Reset so that data gets retranslated.
for(int i = 0; i < translated_.length; ++i)
translated_[i] = false;
}
//-------------------------------------------------------------//
// //
// INTERFACE IMPLEMENTATIONS //
// //
//-------------------------------------------------------------//
public int findField (String name)
throws SQLException
{
if(name.startsWith("\"") && name.endsWith("\"")) //@D6a @DELIMc
{
name = JDUtilities.stripOuterDoubleQuotes(name); //@DELIMa
for(int i=1; i<=sqlData_.length; ++i)
if(name.equals(getFieldName(i))) //@D6c (used to be equalsIgnoreCase)
return i;
}
else
{
//@PDA use hashtable to reduce number of toUpper calls
//X.equalsIgnoreCase(Y) converts both X and Y to uppercase.
if(insensitiveColumnNames_ == null)
{
// Create a new hash table to hold all the column name/number mappings.
insensitiveColumnNames_ = new Hashtable(sqlData_.length);
// cache all the column names and numbers.
for (int i = sqlData_.length; i >= 1; i--)//@pdc 776N6J (int i = 1; i <= sqlData_.length; i++)
{
String cName = getFieldName(i);
// Never uppercase the name from the database. If the name is
// supposed to be uppercase, it will already be. If it isn't, it will be
// lowercase and its double quotes will be missing.
insensitiveColumnNames_.put(cName, Integer.valueOf(i));
}
}
// Look up the mapping in our cache. First look up using the user's casing
Integer x = (Integer) insensitiveColumnNames_.get(name);
if (x != null)
return (x.intValue());
else
{
String upperCaseName = name.toUpperCase();
x = (Integer) insensitiveColumnNames_.get(upperCaseName);
if (x != null)
{
// Add the user's casing
insensitiveColumnNames_.put(name, x);
return (x.intValue());
}
}
}
if (JDTrace.isTraceOn()) {
JDTrace.logInformation (this, "Did not find column " + name);
StringBuffer sb = new StringBuffer();
for (int i = 1; i <= sqlData_.length; i++)
{
sb.append("["+i+"]="+getFieldName(i)+" ");
}
JDTrace.logInformation (this, "Columns are " + sb.toString());
}
JDError.throwSQLException (JDError.EXC_COLUMN_NOT_FOUND);
return -1;
}
public int getFieldCount ()
{
return sqlData_.length;
}
public int getFieldLOBLocatorHandle (int index) // @C2A
throws SQLException // @C2A
{ // @C2A
return lobLocatorHandles_[index-1]; // @C2A
} // @C2A
public String getFieldName (int index)
throws SQLException
{
try
{
// We need to trim() the field name before
// returning it, since in some cases (e.g.
// stored procedure written in RPG) the
// field names have spaces at end of the name.
//
// Cache the field names so we only translate them once.
//
int index0 = index-1;
if(fieldNames_[index0] == null) {
String thisFieldName = serverFormat_.getFieldName (index0,
connection_.getConverter (serverFormat_.getFieldNameCCSID (index0)));
// The native JDBC driver behavior is to only trim spaces from
// the end of the string and to preserve leading whitespace.
// Use the same behavior for the toolbox driver. @O7A
if (thisFieldName.length() > 0) {
thisFieldName = JDUtilities.trimTrailingSpace(thisFieldName);
}
fieldNames_[index0] = thisFieldName;
}
//Bidi-HCG - add converion from serverFormat_.getFieldNameCCSID (index0) to "bidi string type" here
//Bidi-HCG start
boolean reorder = connection_.getProperties().getBoolean(JDProperties.BIDI_IMPLICIT_REORDERING);
if(reorder){
String value_ = fieldNames_[index0];
value_ = AS400BidiTransform.convertDataFromHostCCSID(value_, connection_, serverFormat_.getFieldNameCCSID (index0));
return value_;
}
//Bidi-HCG end
return fieldNames_[index0];
}
catch(DBDataStreamException e)
{
JDError.throwSQLException (JDError.EXC_DESCRIPTOR_INDEX_INVALID, e);
return null;
}
}
/*@L1A*/
public String getSQLTypeName (int index)
throws SQLException
{
try
{
// We need to trim() the field name before
// returning it, since in some cases (e.g.
// stored procedure written in RPG) the
// field names have spaces at end of the name.
//
// Cache the field names so we only translate them once.
//
int index0 = index-1;
if(sqlTypeNames_[index0] == null) {
int ccsid = serverFormat_.getUDTNameCCSID (index0);
if (ccsid > -1 ) {
if (ccsid == 0) {
// There is a bug in the host server where the CCSID was not returned
// To keep working, just use CCSID 37
ccsid = 37;
}
sqlTypeNames_[index0] =
serverFormat_.getUDTName (index0,
connection_.getConverter (ccsid)).trim();
}
if (sqlTypeNames_[index0] == null) {
sqlTypeNames_[index0] = sqlData_[index0].getTypeName();
}
}
if (sqlTypeNames_[index0] != null) {
boolean reorder = connection_.getProperties().getBoolean(JDProperties.BIDI_IMPLICIT_REORDERING);
if(reorder){
String value_ = sqlTypeNames_[index0];
value_ = AS400BidiTransform.convertDataFromHostCCSID(value_, connection_, serverFormat_.getFieldNameCCSID (index0));
return value_;
}
}
//Bidi-HCG end
return sqlTypeNames_[index0];
}
catch(DBDataStreamException e)
{
JDError.throwSQLException (JDError.EXC_DESCRIPTOR_INDEX_INVALID, e);
return null;
}
}
/* @C1D
public int getFieldPrecision (int index)
throws SQLException
{
return precisions_[index-1];
}
public int getFieldScale (int index)
throws SQLException
{
return scales_[index-1];
}
*/
public SQLData getSQLData (int index)
throws SQLException
{
try
{
int index0 = index - 1;
// Translate the first time only, and only when there
// is a current row.
// (There is a chance that there are not when
// this gets called, specifically in the case
// where result set meta data methods get called
// before fetching data.)
if((rowIndex_ >= 0) && (translated_[index0] == false))
{
// @E1D // The CCSID returned in the data format is not
// @E1D // necessarily correct (says the database host server
// @E1D // documentation), so we should always use the server
// @E1D // job CCSID or its graphic equivalent.
// @E1D ConverterImplRemote ccsidConverter = null;
// @E1D if (sqlData_[index0].isText ()) {
// @E1D if (sqlData_[index0].isGraphic ()) {
// @E1D // @A0A
// @E1D // Code added here to check for the 13488 Unicode ccsid.
// @E1D // If there's one, set 'ccsidConverter' to null so that
// @E1D // hand conversion is done in SQLChar.set().
// @E1D if (ccsids_[index0] == 13488) // @A0A
// @E1D ccsidConverter = null; // @A0A
// @E1D else // @A0A
// @E1D ccsidConverter = connection_.getGraphicConverter ();
// @E1D }
// @E1D else
// @E1D ccsidConverter = connection_.getConverter ();
// @E1D }
// Use the CCSID returned in the data format. // @E1A
ConvTable ccsidConverter = connection_.getConverter(ccsids_[index0]); // @E1A @P0C
// If there are bytes, then do a translation.
if(rawBytes_ != null)
{
//set array length so convertFromRawBytes knows how many to convert
if(sqlData_[index0].getType() == java.sql.Types.ARRAY) //@array
{ //@array
int outputIndex0 = getVariableOutputIndex(index0); //@arrayout (arrays in DBVariableData only contain output parms here, so need to skip any input parms in other JDServer arrays)
int arrayCount = ((DBVariableData)serverData_).getIndicatorCountsFromHost()[outputIndex0] ; //@arrayout
((SQLArray)sqlData_[index0]).setArrayCount( arrayCount ); //@array indicatorCountsFromHost will be array count if array type
//SQLArray.convertFromRawBytes will create array elements and iterate calling convertFromRayBytes and it knows array length from above call
sqlData_[index0].convertFromRawBytes (rawBytes_,
rowDataOffset_ + dataOffset_[index0],
ccsidConverter); //@array
//We need to set null values into the array elements here since there is not JDBC wasNull method like there is for ResultSet.
//For an array elements, a null value is just a null array element.
for(int i = 0; i < arrayCount; i++) //@array
{ //@array
if((serverData_ != null) && (serverData_.getIndicator(rowIndex_, outputIndex0, i) == -1)) //@array //@arrayout
((SQLArray)sqlData_[index0]).setElementNull(i); //@array //@nullelem
} //@array
} //@array
else
{
try {
sqlData_[index0].convertFromRawBytes (rawBytes_,
rowDataOffset_ + dataOffset_[index0],
ccsidConverter);
} catch (NumberFormatException nfe) {
if (JDTrace.isTraceOn()) {
JDTrace.logInformation (this, "Caught number format exception rowDataOffset_="+rowDataOffset_+" dataOffset_["+index0+"]="+dataOffset_[index0]);
for (int i = 0; i < dataOffset_.length; i++) {
JDTrace.logInformation (this, "....dataOffset_["+i+"]="+dataOffset_[i]);
}
JDTrace.logInformation (this, "....rowIndex_="+rowIndex_);
serverData_.logInformation("...");
}
throw nfe;
}
}
translated_[index0] = true;
}
}
return sqlData_[index0];
}
catch(ArrayIndexOutOfBoundsException e)
{
JDError.throwSQLException (JDError.EXC_DESCRIPTOR_INDEX_INVALID, e);
return null;
}
}
//@arrayout
/**
Calculates the index by skipping any non output parms (inout parms are output)
@param index The field index (0-based).
@return new index into an output-only parm list (-1 if non are output parms)
@exception SQLException If an error occurs.
**/
int getVariableOutputIndex(int index) throws SQLException
{
int newIndex = 0;
for(int x = 0; x <= index; x++) //@index
{
if(isOutput(x+1)) //isOutput is 1 based //@index
newIndex++;
}
return newIndex-1;
}
public SQLData getSQLType (int index)
throws SQLException
{
return sqlData_[index - 1];
}
/**
Is there a data mapping error for the field?
@param index The field index (1-based).
@return true or false
@exception SQLException If an error occurs.
**/
public boolean isDataMappingError(int index)
throws SQLException
{
try
{
int outputIndex = index; //@arrayout
if(serverData_ instanceof DBVariableData) //@arrayout
outputIndex = getVariableOutputIndex(index-1) + 1; //@arrayout (arrays in DBVariableData only contain output parms here, so need to skip any input parms in other JDServer arrays)
if((serverData_ != null) && (serverData_.getIndicator(rowIndex_, outputIndex - 1) == -2)) //@arrayout
return true;
else
return false;
}
catch(DBDataStreamException e)
{
JDError.throwSQLException(JDError.EXC_DESCRIPTOR_INDEX_INVALID, e);
return false;
}
}
/**
Is the field value SQL NULL?
@param index The field index (1-based).
@return true or false
@exception SQLException If an error occurs.
**/
public boolean isNull(int index)
throws SQLException
{
try
{
int outputIndex = index; //@arrayout
if(serverData_ instanceof DBVariableData) //@arrayout
outputIndex = getVariableOutputIndex(index-1) + 1; //@arrayout (arrays in DBVariableData only contain output parms here, so need to skip any input parms in other JDServer arrays)
if((serverData_ != null) && (serverData_.getIndicator(rowIndex_, outputIndex - 1) == -1)) //@arrayout
return true;
else
return false;
}
catch(DBDataStreamException e)
{
JDError.throwSQLException(JDError.EXC_DESCRIPTOR_INDEX_INVALID, e);
return false;
}
}
/**
Can the field contain a SQL NULL value?
@param index The field index (1-based).
@return true if nullable.
@exception SQLException If an error occurs.
**/
public int isNullable (int index)
throws SQLException
{
//@F2 Add try/catch block to this method.
try
{ //@F2A
return(((sqlTypes_[index-1] & 0x0001) != 0)
? ResultSetMetaData.columnNullable
: ResultSetMetaData.columnNoNulls);
}
catch(ArrayIndexOutOfBoundsException e) //@F2A
{
//@F2A
JDError.throwSQLException (JDError.EXC_DESCRIPTOR_INDEX_INVALID, e); //@F2A
return 0; //@F2A
} //@F2A
}
/**
Return the CCSID for a field.
@param index The field index (1-based).
@return The CCSID.
@exception SQLException If an error occurs.
**/
public int getCCSID (int index)
throws SQLException
{
return ccsids_[index-1];
}
/**
Return the length of a field's data within server
data. For an array, this is arrayCount * arrayDataLen.
@param index The field index (1-based).
@return The data length.
@exception SQLException If an error occurs.
**/
public int getLength (int index)
throws SQLException
{
return dataLength_[index-1];
}
/**
* Return the length of element in an array
* @param index index of array element to examine
* @return length of the array data element
*/
/*@G2A*/
public int getArrayDataLength(int index ) {
return arrayDataLength_[index-1];
}
/**
Return the length of the row's data.
@return The row length.
@exception SQLException If an error occurs.
**/
int getRowLength ()
throws SQLException
{
try
{
return serverFormat_.getRecordSize();
}
catch(DBDataStreamException e)
{
JDError.throwSQLException (JDError.EXC_DESCRIPTOR_INDEX_INVALID, e);
return -1;
}
}
//@CRS - performance
private synchronized void initParmTypes()
{
int count = getFieldCount();
parameterTypes_ = new int[count];
for (int i=0; i
© 2015 - 2025 Weber Informatics LLC | Privacy Policy