use of org.eclipse.persistence.sessions.DatabaseRecord in project eclipselink by eclipse-ee4j.
the class JoinedAttributeManager method processDataResults.
/**
* Process the data-results for joined data for a 1-m join.
* This allows incremental processing for a cursor.
*/
public AbstractRecord processDataResults(AbstractRecord row, Cursor cursor, boolean forward) {
if (this.dataResultsByPrimaryKey == null) {
this.dataResultsByPrimaryKey = new HashMap<>();
}
AbstractRecord parentRow = row;
List<AbstractRecord> childRows = new ArrayList<>();
childRows.add(row);
int parentIndex = getParentResultIndex();
// Must adjust for the parent index to ensure the correct pk is extracted.
Vector<DatabaseField> trimedFields = new NonSynchronizedSubVector<>(row.getFields(), parentIndex, row.size());
if (parentIndex > 0) {
Vector trimedValues = new NonSynchronizedSubVector(row.getValues(), parentIndex, row.size());
parentRow = new DatabaseRecord(trimedFields, trimedValues);
}
ObjectBuilder builder = getDescriptor().getObjectBuilder();
AbstractSession session = cursor.getExecutionSession();
// Extract the primary key of the source object, to filter only the joined rows for that object.
Object sourceKey = builder.extractPrimaryKeyFromRow(parentRow, session);
AbstractRecord extraRow = null;
while (true) {
AbstractRecord nextRow = null;
if (forward) {
nextRow = cursor.getAccessor().cursorRetrieveNextRow(cursor.getFields(), cursor.getResultSet(), session);
} else {
nextRow = cursor.getAccessor().cursorRetrievePreviousRow(cursor.getFields(), cursor.getResultSet(), session);
}
if (nextRow == null) {
break;
}
AbstractRecord nextParentRow = nextRow;
if (parentIndex > 0) {
Vector trimedValues = new NonSynchronizedSubVector(nextParentRow.getValues(), parentIndex, nextParentRow.size());
nextParentRow = new DatabaseRecord(trimedFields, trimedValues);
}
// Extract the primary key of the source object, to filter only the joined rows for that object.
Object nextKey = builder.extractPrimaryKeyFromRow(nextParentRow, session);
if ((sourceKey != null) && sourceKey.equals(nextKey)) {
childRows.add(nextRow);
} else {
extraRow = nextRow;
break;
}
}
this.dataResultsByPrimaryKey.put(sourceKey, childRows);
return extraRow;
}
use of org.eclipse.persistence.sessions.DatabaseRecord in project eclipselink by eclipse-ee4j.
the class ObjectRelationalDataTypeDescriptor method buildNestedRowFromFieldValue.
/**
* INTERNAL:
* Build and return the nested database row from the specified field value.
* The field value better be an Struct.
*/
@Override
public AbstractRecord buildNestedRowFromFieldValue(Object fieldValue) throws DatabaseException {
AbstractRecord row = new DatabaseRecord();
Object[] attributes = (Object[]) fieldValue;
for (int index = 0; index < getAllOrderedFields().size(); index++) {
DatabaseField field = (DatabaseField) getAllOrderedFields().get(index);
row.put(field, attributes[index]);
}
return row;
}
use of org.eclipse.persistence.sessions.DatabaseRecord in project eclipselink by eclipse-ee4j.
the class ObjectRelationalDataTypeDescriptor method getRef.
/**
* INTERNAL:
* Get the ref for the object.
* This is required for use by Refs, there might be a better way to do it when objID are supported.
* (i.e. getting it from the object or identity map).
*/
public Ref getRef(Object object, AbstractSession session) {
SQLSelectStatement statement = new SQLSelectStatement();
// Assumed only one for obj-rel descriptors.
statement.addTable(getTables().firstElement());
statement.getFields().addElement(new org.eclipse.persistence.expressions.ExpressionBuilder().ref());
statement.setWhereClause(getObjectBuilder().buildPrimaryKeyExpressionFromObject(object, session));
statement.setRequiresAliases(true);
statement.normalize(session, this);
ValueReadQuery valueQuery = new ValueReadQuery();
valueQuery.setSQLStatement(statement);
valueQuery.checkPrepare(session, new DatabaseRecord(), true);
// Must return unwrapped Ref on WLS.
valueQuery.getCall().setIsNativeConnectionRequired(true);
Ref ref = (Ref) session.executeQuery(valueQuery);
return ref;
}
use of org.eclipse.persistence.sessions.DatabaseRecord in project eclipselink by eclipse-ee4j.
the class ReportQueryResult method processItemFromMapping.
private Object processItemFromMapping(ReportQuery query, AbstractRecord row, DatabaseMapping mapping, ReportItem item, int itemIndex) {
Object value = null;
// Check for non database (EIS) records to use normal get.
if (row instanceof DatabaseRecord) {
value = row.getValues().get(itemIndex);
} else {
value = row.get(mapping.getField());
}
// Bug 421056: JPA 2.1; section 4.8.5
if (item.getAttributeExpression().isFunctionExpression()) {
FunctionExpression exp = (FunctionExpression) item.getAttributeExpression();
int selector = exp.getOperator().getSelector();
// we want to return null, per the spec, here before the mapping gets to alter the value
if (value == null && ((selector == ExpressionOperator.Maximum) || (selector == ExpressionOperator.Minimum))) {
return value;
}
}
// If the mapping was set on the ReportItem, then use the mapping to convert the value
if (mapping.isAbstractColumnMapping()) {
value = ((AbstractColumnMapping) mapping).getObjectValue(value, query.getSession());
} else if (mapping.isDirectCollectionMapping()) {
value = ((DirectCollectionMapping) mapping).getObjectValue(value, query.getSession());
}
return value;
}
use of org.eclipse.persistence.sessions.DatabaseRecord in project eclipselink by eclipse-ee4j.
the class ReportQueryResult method processItem.
/**
* INTERNAL:
* Return a value from an item and database row (converted from raw field values using the mapping).
*/
protected Object processItem(ReportQuery query, AbstractRecord row, Vector toManyData, ReportItem item) {
JoinedAttributeManager joinManager = null;
if (item.hasJoining()) {
joinManager = item.getJoinedAttributeManager();
if (joinManager.isToManyJoin()) {
// PERF: Only reset data-result if unset, must only occur once per item, not per row (n vs n^2).
if (joinManager.getDataResults_() == null) {
joinManager.setDataResults(new ArrayList(toManyData), query.getSession());
}
}
}
Object value = null;
int rowSize = row.size();
int itemIndex = item.getResultIndex();
DatabaseMapping mapping = item.getMapping();
ClassDescriptor descriptor = item.getDescriptor();
if (item.getAttributeExpression() != null) {
if (descriptor == null && mapping != null) {
descriptor = mapping.getReferenceDescriptor();
}
if (mapping != null && (mapping.isAbstractColumnMapping() || mapping.isDirectCollectionMapping())) {
if (itemIndex >= rowSize) {
throw QueryException.reportQueryResultSizeMismatch(itemIndex + 1, rowSize);
}
value = processItemFromMapping(query, row, mapping, item, itemIndex);
// GF_ISSUE_395+
if (this.key != null) {
this.key.append(value);
this.key.append("_");
}
} else if (descriptor != null) {
// Item is for an object result.
int size = descriptor.getAllSelectionFields(query).size();
if (itemIndex + size > rowSize) {
throw QueryException.reportQueryResultSizeMismatch(itemIndex + size, rowSize);
}
AbstractRecord subRow = row;
// Check if at the start of the row, then avoid building a subRow.
if (itemIndex > 0) {
Vector<DatabaseField> trimedFields = new NonSynchronizedSubVector<>(row.getFields(), itemIndex, rowSize);
Vector trimedValues = new NonSynchronizedSubVector(row.getValues(), itemIndex, rowSize);
subRow = new DatabaseRecord(trimedFields, trimedValues);
}
if (mapping != null && mapping.isAggregateObjectMapping()) {
value = ((AggregateObjectMapping) mapping).buildAggregateFromRow(subRow, null, null, joinManager, query, false, query.getSession(), true);
} else {
// TODO : Support prefrechedCacheKeys in report query
value = descriptor.getObjectBuilder().buildObject(query, subRow, joinManager);
}
// a specific mapping. This could happen in a MapContainerPolicy
if (item.getAttributeExpression().isMapEntryExpression() && mapping.isCollectionMapping()) {
Object rowKey = null;
if (mapping.getContainerPolicy().isMapPolicy() && !mapping.getContainerPolicy().isMappedKeyMapPolicy()) {
rowKey = mapping.getContainerPolicy().keyFrom(value, query.getSession());
} else {
rowKey = mapping.getContainerPolicy().buildKey(subRow, query, null, query.getSession(), true);
}
if (((MapEntryExpression) item.getAttributeExpression()).shouldReturnMapEntry()) {
value = new Association(rowKey, value);
} else {
value = rowKey;
}
}
// GF_ISSUE_395
if (this.key != null) {
Object primaryKey = descriptor.getObjectBuilder().extractPrimaryKeyFromRow(subRow, query.getSession());
if (primaryKey != null) {
// GF3233 NPE is caused by processing the null PK being extracted from referenced target with null values in database.
this.key.append(primaryKey);
}
this.key.append("_");
}
} else {
value = row.getValues().get(itemIndex);
// GF_ISSUE_395
if (this.key != null) {
this.key.append(value);
}
}
}
return value;
}
Aggregations