}
else
{
// Don't put anything in this position (field has no column in the result set)
}
stmtMappings[fieldNumber] = new StatementMappingIndex(m);
}
if (columnFieldNumberMap.size() == 0)
{
// None of the fields in the class have columns in the datastore table!
throw new NucleusUserException(LOCALISER.msg("059030", candidateClass.getName())).setFatal();
}
// Generate id column field information for later checking the id is present
DatastoreClass table = storeMgr.getDatastoreClass(candidateClass.getName(), clr);
PersistableMapping idMapping = (PersistableMapping)table.getIdMapping();
String[] idColNames = new String[idMapping.getNumberOfDatastoreMappings()];
boolean[] idColMissing = new boolean[idMapping.getNumberOfDatastoreMappings()];
for (int i=0;i<idMapping.getNumberOfDatastoreMappings();i++)
{
DatastoreMapping m = idMapping.getDatastoreMapping(i);
idColNames[i] = m.getDatastoreField().getIdentifier().toString();
idColMissing[i] = true;
}
// Generate discriminator/version information for later checking they are present
String discriminatorColName = table.getDiscriminatorMapping(false) != null ?
table.getDiscriminatorMapping(false).getDatastoreMapping(0).getDatastoreField().getIdentifier().toString() : null;
String versionColName = table.getVersionMapping(false) != null ?
table.getVersionMapping(false).getDatastoreMapping(0).getDatastoreField().getIdentifier().toString() : null;
boolean discrimMissing = (discriminatorColName != null);
boolean versionMissing = true;
if (versionColName == null)
{
versionMissing = false;
}
// Go through the fields of the ResultSet and map to the required fields in the candidate
// Note that we check the existence of the columns again here even though they were checked at compilation
// TODO This could be removed from here since its now done at compile time
ResultSetMetaData rsmd = rs.getMetaData();
HashSet remainingColumnNames = new HashSet(columnFieldNumberMap.size());
int colCount = rsmd.getColumnCount();
int[] datastoreIndex = null;
int[] versionIndex = null;
int[] matchedFieldNumbers = new int[colCount];
int fieldNumberPosition = 0;
for (int colNum=1; colNum<=colCount; ++colNum)
{
String colName = rsmd.getColumnName(colNum);
// Find the field for this column
int fieldNumber = -1;
Integer fieldNum = (Integer)columnFieldNumberMap.get(colName);
if (fieldNum == null)
{
// Try column name in lowercase
fieldNum = (Integer)columnFieldNumberMap.get(colName.toLowerCase());
if (fieldNum == null)
{
// Try column name in UPPERCASE
fieldNum = (Integer)columnFieldNumberMap.get(colName.toUpperCase());
}
}
if (fieldNum != null)
{
fieldNumber = fieldNum.intValue();
}
if (fieldNumber >= 0)
{
int[] exprIndices = null;
if (stmtMappings[fieldNumber].getColumnPositions() != null)
{
exprIndices = new int[stmtMappings[fieldNumber].getColumnPositions().length+1];
for (int i=0;i<stmtMappings[fieldNumber].getColumnPositions().length;i++)
{
exprIndices[i] = stmtMappings[fieldNumber].getColumnPositions()[i];
}
exprIndices[exprIndices.length-1] = colNum;
}
else
{
exprIndices = new int[] {colNum};
}
stmtMappings[fieldNumber].setColumnPositions(exprIndices);
remainingColumnNames.remove(colName);
matchedFieldNumbers[fieldNumberPosition++] = fieldNumber;
}
if (versionColName != null && colName.equals(versionColName))
{
// Identify the location of the version column
versionIndex = new int[1];
versionIndex[0] = colNum;
versionMissing = false;
}
if (candidateCmd.getIdentityType() == IdentityType.DATASTORE)
{
// Check for existence of id column, allowing for any RDBMS using quoted identifiers
if (columnNamesAreTheSame(dba, idColNames[0], colName))
{
datastoreIndex = new int[1];
datastoreIndex[0] = colNum;
idColMissing[0] = false;
}
}
else if (candidateCmd.getIdentityType() == IdentityType.APPLICATION)
{
for (int j=0;j<idColNames.length;j++)
{
// Check for existence of id column, allowing for any RDBMS using quoted identifiers
if (columnNamesAreTheSame(dba, idColNames[j], colName))
{
idColMissing[j] = false;
}
}
}
if (discrimMissing && columnNamesAreTheSame(dba, discriminatorColName, colName))
{
discrimMissing = false;
}
else if (versionMissing && columnNamesAreTheSame(dba, versionColName, colName))
{
versionMissing = false;
}
}
// Set the field numbers found to match what we really have
int[] fieldNumbers = new int[fieldNumberPosition];
for (int i=0;i<fieldNumberPosition;i++)
{
fieldNumbers[i] = matchedFieldNumbers[i];
}
if (discrimMissing)
{
throw new NucleusUserException(LOCALISER_RDBMS.msg("059014",
inputSQL, candidateClass.getName(), discriminatorColName));
}
if (versionMissing)
{
throw new NucleusUserException(LOCALISER_RDBMS.msg("059015",
inputSQL, candidateClass.getName(), versionColName));
}
for (int i=0;i<idColMissing.length;i++)
{
if (idColMissing[i])
{
throw new NucleusUserException(LOCALISER_RDBMS.msg("059013",
inputSQL, candidateClass.getName(), idColNames[i]));
}
}
StatementClassMapping mappingDefinition = new StatementClassMapping();
for (int i=0;i<fieldNumbers.length;i++)
{
mappingDefinition.addMappingForMember(fieldNumbers[i], stmtMappings[fieldNumbers[i]]);
}
if (datastoreIndex != null)
{
StatementMappingIndex datastoreMappingIdx = new StatementMappingIndex(table.getDatastoreObjectIdMapping());
datastoreMappingIdx.setColumnPositions(datastoreIndex);
mappingDefinition.addMappingForMember(StatementClassMapping.MEMBER_DATASTORE_ID, datastoreMappingIdx);
}
if (versionIndex != null)
{
StatementMappingIndex versionMappingIdx = new StatementMappingIndex(table.getVersionMapping(true));
versionMappingIdx.setColumnPositions(versionIndex);
mappingDefinition.addMappingForMember(StatementClassMapping.MEMBER_VERSION, versionMappingIdx);
}
return storeMgr.newResultObjectFactory(candidateCmd, mappingDefinition,
ignoreCache, getFetchPlan(), getCandidateClass());