use of org.apache.cayenne.query.EntityResultSegment in project cayenne by apache.
the class ClientChannel method onQuery.
@SuppressWarnings("unchecked")
public QueryResponse onQuery(ObjectContext context, Query query) {
QueryResponse response = send(new QueryMessage(query), QueryResponse.class);
if (context != null) {
EntityResolver resolver = context.getEntityResolver();
QueryMetadata info = query.getMetaData(resolver);
if (!info.isFetchingDataRows()) {
response.reset();
while (response.next()) {
if (response.isList()) {
List objects = response.currentList();
if (!objects.isEmpty()) {
DeepMergeOperation merger = new DeepMergeOperation(context);
List<Object> rsMapping = info.getResultSetMapping();
if (rsMapping == null) {
convertSingleObjects(objects, merger);
} else {
if (rsMapping.size() == 1) {
if (rsMapping.get(0) instanceof EntityResultSegment) {
convertSingleObjects(objects, merger);
}
} else {
processMixedResult(objects, merger, rsMapping);
}
}
}
}
}
}
}
return response;
}
use of org.apache.cayenne.query.EntityResultSegment in project cayenne by apache.
the class MixedResultIncrementalFaultList method createHelper.
@Override
IncrementalListHelper createHelper(QueryMetadata metadata) {
// first compile some meta data about results
indexToEntity = new HashMap<>();
scalarResult = true;
for (Object next : metadata.getResultSetMapping()) {
if (next instanceof EntityResultSegment) {
EntityResultSegment resultSegment = (EntityResultSegment) next;
ObjEntity entity = resultSegment.getClassDescriptor().getEntity();
// store entity's PK position in result
indexToEntity.put(resultSegment.getColumnOffset(), entity);
scalarResult = false;
}
}
// than all data is already there and we don't need to resolve any objects
if (indexToEntity.isEmpty()) {
return new ScalarArrayListHelper();
} else {
return new MixedArrayListHelper();
}
}
use of org.apache.cayenne.query.EntityResultSegment in project cayenne by apache.
the class EJBQLJoinAppender method generateJoinsForFlattenedAttributes.
/**
* Generates Joins statements for those flattened attributes that appear after the
* FROM clause, e.g. in WHERE, ORDER BY, etc clauses. Flattened attributes of the
* entity from the SELECT clause are processed earlier and therefore are omitted.
*
* @param id table to JOIN id
*/
private void generateJoinsForFlattenedAttributes(EJBQLTableId id) {
String entityName = context.getEntityDescriptor(id.getEntityId()).getEntity().getName();
// if the dbPath is not null, all attributes of the entity are processed earlier
boolean isProcessingOmitted = id.getDbPath() != null;
String sourceExpression = context.getCompiledExpression().getSource();
List<Object> resultSetMapping = context.getMetadata().getResultSetMapping();
for (Object mapping : resultSetMapping) {
if (mapping instanceof EntityResultSegment) {
if (entityName.equals(((EntityResultSegment) mapping).getClassDescriptor().getEntity().getName())) {
// if entity is included into SELECT clause, all its attributes are processed earlier
isProcessingOmitted = true;
break;
}
}
}
if (!isProcessingOmitted) {
QuotingStrategy quoter = context.getQuotingStrategy();
Collection<ObjAttribute> attributes = context.getEntityDescriptor(id.getEntityId()).getEntity().getAttributes();
for (ObjAttribute objAttribute : attributes) {
if (objAttribute.isFlattened() && sourceExpression.contains(id.getEntityId() + "." + objAttribute.getName())) {
// joins for attribute are generated if it is flattened and appears in original statement
Iterator<CayenneMapEntry> dbPathIterator = objAttribute.getDbPathIterator();
while (dbPathIterator.hasNext()) {
CayenneMapEntry next = dbPathIterator.next();
if (next instanceof DbRelationship) {
DbRelationship rel = (DbRelationship) next;
context.append(" LEFT OUTER JOIN ");
String targetEntityName = quoter.quotedFullyQualifiedName(rel.getTargetEntity());
String subqueryTargetAlias = context.getTableAlias(id.getEntityId(), targetEntityName);
context.append(targetEntityName).append(' ').append(subqueryTargetAlias);
generateJoiningExpression(rel, context.getTableAlias(id.getEntityId(), quoter.quotedFullyQualifiedName(rel.getSourceEntity())), subqueryTargetAlias);
}
}
}
}
}
}
use of org.apache.cayenne.query.EntityResultSegment in project cayenne by apache.
the class ObjectContextQueryAction method interceptObjectConversion.
/**
* Transfers fetched objects into the target context if it is different from "acting"
* context. Note that when this method is invoked, result objects are already
* registered with acting context by the parent channel.
*/
protected void interceptObjectConversion() {
if (targetContext != null && !metadata.isFetchingDataRows()) {
// rewrite response to contain objects from the query context
GenericResponse childResponse = new GenericResponse();
ShallowMergeOperation merger = null;
for (response.reset(); response.next(); ) {
if (response.isList()) {
List objects = response.currentList();
if (objects.isEmpty()) {
childResponse.addResultList(objects);
} else {
// minor optimization, skip Object[] if there are no persistent objects
boolean haveObjects = metadata.getResultSetMapping() == null;
if (!haveObjects) {
for (Object next : metadata.getResultSetMapping()) {
if (next instanceof EntityResultSegment) {
haveObjects = true;
break;
}
}
}
if (merger == null) {
merger = new ShallowMergeOperation(targetContext);
}
// TODO: Andrus 1/31/2006 - IncrementalFaultList is not properly
// transferred between contexts....
List<Object> childObjects = new ArrayList<>(objects.size());
for (Object object1 : objects) {
if (object1 instanceof Persistent) {
Persistent object = (Persistent) object1;
childObjects.add(merger.merge(object));
} else if (haveObjects && object1 instanceof Object[]) {
// merge objects inside Object[]
Object[] parentData = (Object[]) object1;
Object[] childData = new Object[parentData.length];
System.arraycopy(parentData, 0, childData, 0, parentData.length);
for (int i = 0; i < childData.length; i++) {
if (childData[i] instanceof Persistent) {
childData[i] = merger.merge((Persistent) childData[i]);
}
}
childObjects.add(childData);
} else {
childObjects.add(object1);
}
}
childResponse.addResultList(childObjects);
}
} else {
childResponse.addBatchUpdateCount(response.currentUpdateCount());
}
}
response = childResponse;
}
}
use of org.apache.cayenne.query.EntityResultSegment in project cayenne by apache.
the class DataDomainQueryAction method interceptObjectConversion.
@SuppressWarnings("unchecked")
private void interceptObjectConversion() {
if (context != null) {
// List<DataRow> or List<Object[]>
List mainRows = response.firstList();
if (mainRows != null && !mainRows.isEmpty()) {
ObjectConversionStrategy<?> converter;
if (metadata.isFetchingDataRows()) {
converter = new IdentityConversionStrategy();
} else {
List<Object> rsMapping = metadata.getResultSetMapping();
if (rsMapping == null) {
converter = new SingleObjectConversionStrategy();
} else {
if (metadata.isSingleResultSetMapping()) {
if (rsMapping.get(0) instanceof EntityResultSegment) {
converter = new SingleObjectConversionStrategy();
} else if (rsMapping.get(0) instanceof EmbeddableResultSegment) {
converter = new SingleEmbeddableConversionStrategy();
} else {
converter = new SingleScalarConversionStrategy();
}
} else {
converter = new MixedConversionStrategy();
}
}
}
if (metadata.getResultMapper() != null) {
converter = new MapperConversionStrategy(converter);
}
converter.convert(mainRows);
// rewind response after firstList() call
response.reset();
}
}
}
Aggregations