Methods Summary |
---|
public void | addField(com.sun.jdo.spi.persistence.support.sqlstore.model.LocalFieldDesc fieldDesc, com.sun.jdo.spi.persistence.support.sqlstore.sql.generator.ColumnRef columnRef, boolean projection)Create and add a ResultFieldDesc for the given fieldDesc and columnRef.
ResultFieldDesc rfd = new ResultFieldDesc(fieldDesc, columnRef);
// remember the projection
if (projection) {
this.fieldProjection = rfd;
}
fields.add(rfd);
fieldNames.add(fieldDesc.getName());
|
private void | addField(com.sun.jdo.spi.persistence.support.sqlstore.sql.ResultDesc rs)
if (rs != null) {
fields.add(rs);
fieldNames.add(null);
}
|
private void | applyDeferredUpdatesToPrefetchedCollections(java.util.Collection resultCollection)The prefetched collection fields might have deferred updates for
if (prefetching && prefetchedCollectionFields != null && prefetchedCollectionFields.size() > 0) {
for (Iterator resultItr = resultCollection.iterator(); resultItr.hasNext();) {
// resultPC is guranted to be instance of PersistenceCapable
PersistenceCapable resultPC = (PersistenceCapable) resultItr.next();
// resultPC can be null if this is a projection query
if(resultPC != null) {
SQLStateManager sm = (SQLStateManager)resultPC.jdoGetStateManager();
Iterator prefetchedCollectionFieldsIter = prefetchedCollectionFields.iterator();
StateManager resultSM = resultPC.jdoGetStateManager();
while (prefetchedCollectionFieldsIter.hasNext()) {
ForeignFieldDesc prefetchedCollectionField =
(ForeignFieldDesc) prefetchedCollectionFieldsIter.next();
// process deferred updates for all prefetched collection relationship
if(prefetchedCollectionField.cardinalityUPB > 1) {
SCOCollection relationshipValue =
(SCOCollection) prefetchedCollectionField.getValue(sm);
if(relationshipValue.isDeferred()){
relationshipValue.applyDeferredUpdates(null);
}
// Presence mask bit for a prefetched collection field is
// not set in setFields. Set the bit here.
resultSM.setPresenceMaskBit(prefetchedCollectionField.absoluteID);
}
}
}
}
}
|
private static java.lang.Object | createSCO(java.lang.Object value, StateManager sm, com.sun.jdo.spi.persistence.support.sqlstore.model.FieldDesc fieldDesc)Creates a SCO corresponding to value .
Currently used for dates. The actual SCO conversion for dates is done in
{@link com.sun.jdo.spi.persistence.support.sqlstore.model.FieldDesc#createSCO(java.lang.Object, com.sun.jdo.spi.persistence.support.sqlstore.StateManager)}.
Object retVal = null;
if (fieldDesc != null) {
int enumType = fieldDesc.getEnumType();
// Need to convert Date fields into their SCO equivalents
switch(enumType) {
case FieldTypeEnumeration.UTIL_DATE:
case FieldTypeEnumeration.SQL_DATE:
case FieldTypeEnumeration.SQL_TIME:
case FieldTypeEnumeration.SQL_TIMESTAMP:
retVal = fieldDesc.createSCO(value, sm);
break;
default:
}
}
return retVal;
|
public void | doJoin(com.sun.jdo.spi.persistence.support.sqlstore.sql.ResultDesc foreignResult, com.sun.jdo.spi.persistence.support.sqlstore.model.ForeignFieldDesc parentField)Joins foreignResult with this resultDesc
addField(foreignResult);
foreignResult.parentField = parentField;
// if foreign result correponds to a collection relationship being
// prefetched, remember it.
if(parentField.cardinalityUPB > 1) {
if(prefetchedCollectionFields == null) {
prefetchedCollectionFields = new ArrayList();
}
prefetchedCollectionFields.add(parentField);
}
|
private StateManager | findOrCreateStateManager(java.sql.ResultSet resultData, PersistenceManager pm)Returns a StateManager which PC instance to be populated with the values.
If such instance exists in this PersistenceManager cache,
it is returned, otherwise a new instance is created.
try {
Class oidClass = config.getOidClass();
Object oid = oidClass.newInstance();
// Copy key field values
Field keyFields[] = config.getKeyFields();
String keyNames[] = config.getKeyFieldNames();
for (int i = 0; i < keyFields.length; i++) {
Field keyField = keyFields[i];
String keyName = keyNames[i];
FieldDesc fd = config.getField(keyName);
int index = fieldNames.indexOf(keyName);
ResultFieldDesc rfd = (ResultFieldDesc)fields.get(index);
Object v = getConvertedObject(resultData, rfd.getColumnRef(), fd, null);
if (debug) {
logger.finest("sqlstore.resultdesc.marking_key_field",keyName); // NOI18N
}
if (v == null ) {
return null;
}
keyField.set(oid, v);
}
return pm.findOrCreateStateManager(oid, config.getPersistenceCapableClass());
} catch (Exception e) {
// RESOLVE...
throw new JDOFatalInternalException(e.getMessage());
}
|
private java.lang.Object | getAggregateResult(java.sql.ResultSet resultData)Get result for Aggregates. Since resultset containing result for aggregates would not
contain any other columns, it is assumed that the result is available at index == 1.
Object result = null;
if (resultData.next() ) {
//Aggregate results are always at index 1;
result = getValueFromResultSet(resultData, 1, aggregateResultType);
}
return result;
|
private static java.lang.Object | getConvertedObject(java.sql.ResultSet resultData, com.sun.jdo.spi.persistence.support.sqlstore.sql.generator.ColumnRef columnRef, com.sun.jdo.spi.persistence.support.sqlstore.model.FieldDesc fieldDesc, StateManager sm)Get the value to be bound to the field described by fieldDesc
from the result set. The conversion to the correct field type might be done
by the driver. If we can't get the correct type from the driver, the
conversion in done in FieldDesc::convertValue.
Object retVal = null;
try {
retVal = getValueFromResultSet(resultData, columnRef, fieldDesc.getEnumType());
// Create an SCO object in case we want to populate a pc.
if (retVal != null) {
// Create a SCO instance in case we want to populate a pc.
Object scoVal = createSCO(retVal, sm, fieldDesc);
if (scoVal != null) {
retVal = scoVal;
}
}
} catch (SQLException sqlException) {
//The driver is not able to convert for us
//We would use resultData.getObject(index) below
//and let FieldDesc::convertValue() do the conversion
//Nothing to do here
try {
// Get the generic object and let FieldDesc::convertValue() deal with it.
// This will return an SCO as needed.
retVal = fieldDesc.convertValue(resultData.getObject(columnRef.getIndex()), sm);
}
catch (Exception e) {
//Resolve : The original code was returning null and not throwing any
//exception in this case. Should we also do that????
logger.log(Logger.WARNING,"sqlstore.exception.log",e);
}
}
return retVal;
|
private java.lang.Object | getProjectedField(java.sql.ResultSet resultData)Returns the projected field from the result set. This field is
always a local field. Foreign fields are handled in setFields.
We return the database value for projections on local fields.
Unless we flush for queries in optimistic transactions the value
from the database might be different from the value in memory.
//Field projection can never be null if this method gets called.
FieldDesc f = fieldProjection.getFieldDesc();
if (debug) {
logger.finest("sqlstore.resultdesc.returning_field", f.getName()); // NOI18N
}
return getConvertedObject(resultData, fieldProjection.getColumnRef(), f, null);
|
public java.lang.Object | getResult(PersistenceManager pm, java.sql.ResultSet resultData)Materialize data from the result set into objects.
Object result = null;
debug = logger.isLoggable(Logger.FINEST);
if (!isAggregate()) {
Collection resultCollection = new ArrayList();
// Fill in the data from the current row of resultData.
while (resultData.next()) {
Object resultObject = null;
if (fieldProjection != null) {
resultObject = getProjectedField(resultData);
} else {
resultObject = setFields(pm, resultData);
}
// resultCollection might contain resultObject if prefetch
// is enabled. Do not add duplicates. Duplicates are required
// for projection queries
if (!prefetching || !resultCollection.contains(resultObject)) {
resultCollection.add(resultObject);
}
}
//Iterate over the results obtained and handle deferred collection updates.
applyDeferredUpdatesToPrefetchedCollections(resultCollection);
result = resultCollection;
} else {
// Aggregate functions return an object instead of a collection.
result = getAggregateResult(resultData);
}
return result;
|
private static java.lang.Object | getValueFromResultSet(java.sql.ResultSet resultData, com.sun.jdo.spi.persistence.support.sqlstore.sql.generator.ColumnRef columnRef, int resultType)Gets value at index from resultData. resultData is queried for passed resultType.
int index = columnRef.getIndex();
int columnType = columnRef.getColumnType();
return getValueFromResultSet(resultData, index, resultType, columnType);
|
private static java.lang.Object | getValueFromResultSet(java.sql.ResultSet resultData, int index, int resultType)Gets value at index from resultData .resultData
is queried for passed resultType.
// Types.OTHER is passed as a placeholder here.
// It implies don't care for columnType.
return getValueFromResultSet(resultData, index, resultType, Types.OTHER);
|
private static java.lang.Object | getValueFromResultSet(java.sql.ResultSet resultData, int index, int resultType, int columnType)Gets value at index from resultData. resultData is queried for passed resultType.
Object retVal = null;
try {
switch(resultType) {
case FieldTypeEnumeration.BOOLEAN_PRIMITIVE :
case FieldTypeEnumeration.BOOLEAN :
boolean booleanValue = resultData.getBoolean(index);
if(!resultData.wasNull() )
retVal = new Boolean(booleanValue);
break;
case FieldTypeEnumeration.CHARACTER_PRIMITIVE :
case FieldTypeEnumeration.CHARACTER :
String strValue = resultData.getString(index);
if(strValue != null)
retVal = FieldDesc.getCharFromString(strValue);
break;
case FieldTypeEnumeration.BYTE_PRIMITIVE :
case FieldTypeEnumeration.BYTE :
byte byteValue = resultData.getByte(index);
if(!resultData.wasNull() )
retVal = new Byte(byteValue);
break;
case FieldTypeEnumeration.SHORT_PRIMITIVE :
case FieldTypeEnumeration.SHORT :
short shortValue = resultData.getShort(index);
if(!resultData.wasNull() )
retVal = new Short(shortValue);
break;
case FieldTypeEnumeration.INTEGER_PRIMITIVE :
case FieldTypeEnumeration.INTEGER :
int intValue = resultData.getInt(index);
if(!resultData.wasNull() )
retVal = new Integer(intValue);
break;
case FieldTypeEnumeration.LONG_PRIMITIVE :
case FieldTypeEnumeration.LONG :
long longValue = resultData.getLong(index);
if(!resultData.wasNull() )
retVal = new Long(longValue);
break;
case FieldTypeEnumeration.FLOAT_PRIMITIVE :
case FieldTypeEnumeration.FLOAT :
float floatValue = resultData.getFloat(index);
if(!resultData.wasNull() )
retVal = new Float(floatValue);
break;
case FieldTypeEnumeration.DOUBLE_PRIMITIVE :
case FieldTypeEnumeration.DOUBLE :
double doubleValue = resultData.getDouble(index);
if(!resultData.wasNull() )
retVal = new Double(doubleValue);
break;
case FieldTypeEnumeration.BIGDECIMAL :
case FieldTypeEnumeration.BIGINTEGER :
retVal = resultData.getBigDecimal(index);
if ((resultType == FieldTypeEnumeration.BIGINTEGER) && (retVal != null)) {
retVal = ( (java.math.BigDecimal) retVal).toBigInteger();
}
break;
case FieldTypeEnumeration.STRING :
if(LocalFieldDesc.isCharLobType(columnType) ) {
Reader reader = resultData.getCharacterStream(index);
retVal = readCharacterStreamToString(reader);
} else {
retVal = resultData.getString(index);
}
break;
case FieldTypeEnumeration.SQL_DATE :
retVal = resultData.getDate(index);
break;
case FieldTypeEnumeration.SQL_TIME :
retVal = resultData.getTime(index);
break;
case FieldTypeEnumeration.UTIL_DATE :
case FieldTypeEnumeration.SQL_TIMESTAMP :
//Variable ts is introduced to avoid cast
Timestamp ts;
ts = resultData.getTimestamp(index);
if (resultType == FieldTypeEnumeration.UTIL_DATE && ts != null) {
retVal = new Date(ts.getTime());
} else {
retVal = ts;
}
break;
case FieldTypeEnumeration.ARRAY_BYTE_PRIMITIVE :
InputStream is = resultData.getBinaryStream(index);
retVal = readInputStreamToByteArray(is);
break;
case FieldTypeEnumeration.NOT_ENUMERATED :
//RESOLVE:
//We should only get here for getting values for hidden fields.
//hiddenFields does not have their java type initialized. Its sort of difficult
//to initialize java type without major re-org of the code in ClassDesc :(.
//But once it is done, we should throw an exception if we reach here.
//
//For now retrieve value for hidden fields as object as they are any way
//stored as Object in SQLStatemanager.
retVal = resultData.getObject(index);
break;
default :
//If we reach here, a new type has been added to FieldTypeEnumeration.
//Please update this method to handle new type.
throw new JDOFatalInternalException(I18NHelper.getMessage(messages,
"sqlstore.resultdesc.unknownfieldtype",resultType) );
} //switch
} catch (SQLException e) {
if(logger.isLoggable(Logger.WARNING) ) {
Object items[] =
{ new Integer(index), new Integer(resultType), new Integer(columnType), e};
logger.log(Logger.WARNING,"sqlstore.resultdesc.errorgettingvalefromresulset",items);
}
throw e;
}
// RESOLVE: Following is a workaround till we are able to initialize java type for hidden fields.
// When we are able to determine java type of hidden fields, this code should go back
// to case FieldTypeEnumeration.String
if (LocalFieldDesc.isFixedCharType(columnType)
// For Character fields, this method is expected to return
// Character. Do not convert them to String.
&& resultType != FieldTypeEnumeration.CHARACTER_PRIMITIVE
&& resultType != FieldTypeEnumeration.CHARACTER
&& retVal != null) {
// To support char columns, we rtrim fields mapped to fixedchar.
retVal = StringHelper.rtrim(retVal.toString());
}
return retVal;
|
private boolean | isAggregate()Specifies, if this was an aggregate query.
return aggregateResultType != FieldTypeEnumeration.NOT_ENUMERATED;
|
private static java.lang.String | readCharacterStreamToString(java.io.Reader reader)Reads from the character stream reader into a String.
String retVal = null;
if(reader != null) {
BufferedReader buffReader = new BufferedReader(reader);
StringBuffer buff = new StringBuffer();
try {
int charRead;
while( (charRead = buffReader.read() ) != -1) {
buff.append( (char)charRead );
}
} catch (IOException e) {
// log the exception and don't return any value
// Eating the exception here. As the caller also does not
// know how to deal with this exception.
logger.log(Logger.WARNING,"sqlstore.exception.log",e);
}
retVal = buff.toString();
}
return retVal;
|
private static byte[] | readInputStreamToByteArray(java.io.InputStream is)Reads from input stream is into a byte array.
byte[] byteArray = null;
if (is != null) {
ByteArrayOutputStream bos = new ByteArrayOutputStream();
byte[] chunk = new byte[2000];
int read = 0;
try {
while ((read = is.read(chunk)) != -1) {
bos.write(chunk, 0, read);
}
byteArray = bos.toByteArray();
} catch (IOException e) {
// log the exception and don't return any value
// Eating the exception here. As the caller also does not
// know how to deal with this exception.
logger.log(Logger.WARNING,"sqlstore.exception.log",e);
}
}
return byteArray;
|
private static void | setFieldValue(StateManager sm, com.sun.jdo.spi.persistence.support.sqlstore.model.FieldDesc f, java.lang.Object value)Set given value for the given field f for
given statemanager sm .
Also set presence mask bit for the field in given sm .
f.setValue(sm, value);
sm.setPresenceMaskBit(f.absoluteID);
|
private java.lang.Object | setFields(PersistenceManager pm, java.sql.ResultSet resultData)Bind the columns from this ResultSet row to the persistent object described
by this ResultDesc. External queries always return only one type of objects
and don't have nested ResultDescs. Internal queries can have nested ResultDescs.
Run through all the fields of the field list and bind the values in
that order. Nested ResultDescs are processed by recursive calls.
Object pcObj = null;
// Get the Statemanager corresponding to the current row
SQLStateManager sm = (SQLStateManager) findOrCreateStateManager(resultData, pm);
if (sm != null) {
pcObj = sm.getPersistent();
sm.getLock();
try {
// Fields are read in the order in which they were placed in
// the sql select statement. This ordering is important while reading
// from streams corresponding to LONG columns on Oracle.
for (int i = 0; i < fields.size(); i++) {
Object temp = fields.get(i);
if (temp instanceof ResultFieldDesc) {
ResultFieldDesc rfd = (ResultFieldDesc) temp;
LocalFieldDesc f = rfd.getFieldDesc();
if (!sm.getPresenceMaskBit(f.absoluteID)) {
Object value = getConvertedObject(resultData, rfd.getColumnRef(), f, sm);
if (debug) {
logger.finest("sqlstore.resultdesc.marking_field", f.getName()); // NOI18N
}
// Set the field value and presence mask bit.
setFieldValue(sm, f, value);
}
} else {
ResultDesc frd = (ResultDesc) temp;
ForeignFieldDesc parentField = frd.parentField;
// Only try to fetch the field if it is not already present.
// If the field is already present, it should be in
// consistent state w.r.t. this transaction. Overwriting
// it with the value from database might corrupt consistency of data.
if (!sm.getPresenceMaskBit(parentField.absoluteID)) {
Object fobj = frd.setFields(pm, resultData);
if(parentField.cardinalityUPB > 1) { // parentField is a collection.
SCOCollection collection = (SCOCollection) parentField.getValue(sm);
if (collection == null) {
// Getting first member of the collection. Initialize the collection.
// Presence mask bit for a collection field can not set here.
// This is because the collection is not fully present till all the
// elements of the collection are added. If the bit is set here,
// next member of this collection from this resultset will not
// be processed(added) here.
// This bit is set after all the elements of this collection are
// processed. That is in applyDeferredUpdatesToPrefetchedCollections()
sm.replaceCollection(parentField, null);
// Get the newly created SCOCollection back.
collection = (SCOCollection) parentField.getValue(sm);
}
if(fobj != null ) {
collection.addToBaseCollection(fobj);
}
} else { // parentField is an object.
// Set the field value and presence mask bit.
setFieldValue(sm, parentField, fobj);
}
}
if (debug) {
logger.finest("sqlstore.resultdesc.marking_foreign_field", // NOI18N
parentField.getName());
}
}
}
sm.initialize(true);
} finally {
// Always release the lock.
sm.releaseLock();
}
} else {
// sm can be null if we can not find or create a statemanager from the result data.
// This is possible if we are projecting on a foreignfield and there is no
// result returned.
}
return pcObj;
|
public void | setParentField(com.sun.jdo.spi.persistence.support.sqlstore.model.ForeignFieldDesc parentField)Set the field that is the recipient of the result of this ResultDesc.
this.parentField = parentField;
|
public void | setPrefetching()
prefetching = true;
|