use of org.apache.cayenne.query.Query in project cayenne by apache.
the class DataContextQueryAction method interceptRefreshQuery.
@Override
protected boolean interceptRefreshQuery() {
if (query instanceof RefreshQuery) {
RefreshQuery refreshQuery = (RefreshQuery) query;
DataContext context = (DataContext) actingContext;
// 1. refresh all
if (refreshQuery.isRefreshAll()) {
synchronized (context.getObjectStore()) {
invalidateLocally(context.getObjectStore(), context.getObjectStore().getObjectIterator());
context.getQueryCache().clear();
}
// cascade
return !DONE;
}
// 2. invalidate object collection
Collection objects = refreshQuery.getObjects();
if (objects != null && !objects.isEmpty()) {
synchronized (context.getObjectStore()) {
invalidateLocally(context.getObjectStore(), objects.iterator());
}
// cascade
return !DONE;
}
// 3. refresh query - have to do it eagerly to refresh the objects involved
Query cachedQuery = refreshQuery.getQuery();
if (cachedQuery != null) {
String cacheKey = cachedQuery.getMetaData(context.getEntityResolver()).getCacheKey();
context.getQueryCache().remove(cacheKey);
this.response = context.performGenericQuery(cachedQuery);
// do not cascade to avoid running query twice
return DONE;
}
// 4. refresh groups...
String[] groups = refreshQuery.getGroupKeys();
if (groups != null && groups.length > 0) {
for (String group : groups) {
context.getQueryCache().removeGroup(group);
}
// cascade group invalidation
return !DONE;
}
// shouldn't ever happen
return DONE;
}
return !DONE;
}
use of org.apache.cayenne.query.Query in project cayenne by apache.
the class DataDomainDeleteBucket method appendQueriesInternal.
@Override
void appendQueriesInternal(Collection<Query> queries) {
DataNodeSyncQualifierDescriptor qualifierBuilder = new DataNodeSyncQualifierDescriptor();
EntitySorter sorter = parent.getDomain().getEntitySorter();
sorter.sortDbEntities(dbEntities, true);
for (DbEntity dbEntity : dbEntities) {
Collection<DbEntityClassDescriptor> descriptors = descriptorsByDbEntity.get(dbEntity);
Map<Object, Query> batches = new LinkedHashMap<>();
for (DbEntityClassDescriptor descriptor : descriptors) {
qualifierBuilder.reset(descriptor);
boolean isRootDbEntity = descriptor.isMaster();
// remove object set for dependent entity, so that it does not show up
// on post processing
List<Persistent> objects = objectsByDescriptor.get(descriptor.getClassDescriptor());
if (objects.isEmpty()) {
continue;
}
checkReadOnly(descriptor.getEntity());
if (isRootDbEntity) {
sorter.sortObjectsForEntity(descriptor.getEntity(), objects, true);
}
for (Persistent o : objects) {
ObjectDiff diff = parent.objectDiff(o.getObjectId());
Map<String, Object> qualifierSnapshot = qualifierBuilder.createQualifierSnapshot(diff);
// organize batches by the nulls in qualifier
Set<String> nullQualifierNames = new HashSet<String>();
for (Map.Entry<String, ?> entry : qualifierSnapshot.entrySet()) {
if (entry.getValue() == null) {
nullQualifierNames.add(entry.getKey());
}
}
Object batchKey = Arrays.asList(nullQualifierNames);
DeleteBatchQuery batch = (DeleteBatchQuery) batches.get(batchKey);
if (batch == null) {
batch = new DeleteBatchQuery(dbEntity, qualifierBuilder.getAttributes(), nullQualifierNames, 27);
batch.setUsingOptimisticLocking(qualifierBuilder.isUsingOptimisticLocking());
batches.put(batchKey, batch);
}
batch.add(qualifierSnapshot);
}
}
queries.addAll(batches.values());
}
}
use of org.apache.cayenne.query.Query in project cayenne by apache.
the class DataNodeQueryAction method runQuery.
public void runQuery(Connection connection, final Query originalQuery) throws SQLException, Exception {
// wrap to ensure that the result is mapped back to the original query, even if
// the underlying SQLAction uses query substitute...
OperationObserver wrapper = new OperationObserver() {
@Override
public void nextBatchCount(Query query, int[] resultCount) {
observer.nextBatchCount(originalQuery, resultCount);
}
@Override
public void nextCount(Query query, int resultCount) {
observer.nextCount(originalQuery, resultCount);
}
@Override
public void nextRows(Query query, List<?> dataRows) {
observer.nextRows(originalQuery, dataRows);
}
@Override
public void nextRows(Query q, ResultIterator it) {
observer.nextRows(originalQuery, it);
}
@Override
public void nextGeneratedRows(Query query, ResultIterator keys, ObjectId idToUpdate) {
observer.nextGeneratedRows(originalQuery, keys, idToUpdate);
}
@Override
public void nextGlobalException(Exception ex) {
observer.nextGlobalException(ex);
}
@Override
public void nextQueryException(Query query, Exception ex) {
observer.nextQueryException(originalQuery, ex);
}
@Override
public boolean isIteratedResult() {
return observer.isIteratedResult();
}
};
SQLAction action = node.getAdapter().getAction(originalQuery, node);
action.performAction(connection, wrapper);
}
use of org.apache.cayenne.query.Query in project cayenne by apache.
the class FlattenedArcKey method buildJoinSnapshotsForDelete.
/**
* Returns pk snapshots for join records for the single-step flattened
* relationship. Multiple joins between the same pair of objects are
* theoretically possible, so the return value is a list.
*/
List buildJoinSnapshotsForDelete(DataNode node) {
Map<String, Object> snapshot = eagerJoinSnapshot();
DbEntity joinEntity = getJoinEntity();
boolean fetchKey = false;
for (DbAttribute dbAttr : joinEntity.getPrimaryKeys()) {
String dbAttrName = dbAttr.getName();
if (!snapshot.containsKey(dbAttrName)) {
fetchKey = true;
break;
}
}
if (!fetchKey) {
return Collections.singletonList(snapshot);
}
// ok, the key is not included in snapshot, must do the fetch...
// TODO: this should be optimized in the future, but now
// DeleteBatchQuery
// expects a PK snapshot, so we must provide it.
QuotingStrategy quoter = node.getAdapter().getQuotingStrategy();
StringBuilder sql = new StringBuilder("SELECT ");
Collection<DbAttribute> pk = joinEntity.getPrimaryKeys();
final List<DbAttribute> pkList = pk instanceof List ? (List<DbAttribute>) pk : new ArrayList<>(pk);
for (int i = 0; i < pkList.size(); i++) {
if (i > 0) {
sql.append(", ");
}
DbAttribute attribute = pkList.get(i);
sql.append("#result('");
sql.append(quoter.quotedName(attribute));
// since the name of the column can potentially be quoted and
// use reserved keywords as name, let's specify generated column
// name parameters to ensure the query doesn't explode
sql.append("' '").append(TypesMapping.getJavaBySqlType(attribute.getType()));
sql.append("' '").append("pk").append(i);
sql.append("')");
}
sql.append(" FROM ").append(quoter.quotedFullyQualifiedName(joinEntity)).append(" WHERE ");
int i = snapshot.size();
for (Object key : snapshot.keySet()) {
sql.append(quoter.quotedIdentifier(joinEntity, String.valueOf(key))).append(" #bindEqual($").append(key).append(")");
if (--i > 0) {
sql.append(" AND ");
}
}
SQLTemplate query = new SQLTemplate(joinEntity.getDataMap(), sql.toString(), true);
query.setParams(snapshot);
final List[] result = new List[1];
node.performQueries(Collections.singleton((Query) query), new DefaultOperationObserver() {
@Override
public void nextRows(Query query, List<?> dataRows) {
if (!dataRows.isEmpty()) {
// decode results...
List<DataRow> fixedRows = new ArrayList<>(dataRows.size());
for (Object o : dataRows) {
DataRow row = (DataRow) o;
DataRow fixedRow = new DataRow(2);
for (int i = 0; i < pkList.size(); i++) {
DbAttribute attribute = pkList.get(i);
fixedRow.put(attribute.getName(), row.get("pk" + i));
}
fixedRows.add(fixedRow);
}
dataRows = fixedRows;
}
result[0] = dataRows;
}
@Override
public void nextQueryException(Query query, Exception ex) {
throw new CayenneRuntimeException("Raising from query exception.", Util.unwindException(ex));
}
@Override
public void nextGlobalException(Exception ex) {
throw new CayenneRuntimeException("Raising from underlyingQueryEngine exception.", Util.unwindException(ex));
}
});
return result[0];
}
use of org.apache.cayenne.query.Query in project cayenne by apache.
the class BaseRemoteServiceTest method testProcessMessageExceptionSerializability.
@Test
public void testProcessMessageExceptionSerializability() throws Throwable {
Map<String, String> map = new HashMap<>();
ObjectContextFactory factory = new ObjectContextFactory() {
public ObjectContext createContext(DataChannel parent) {
return null;
}
public ObjectContext createContext() {
return null;
}
};
BaseRemoteService service = new BaseRemoteService(factory, map) {
@Override
protected ServerSession createServerSession() {
return new ServerSession(new RemoteSession("a"), null);
}
@Override
protected ServerSession createServerSession(String name) {
return createServerSession();
}
@Override
protected ServerSession getServerSession() {
return createServerSession();
}
};
try {
service.processMessage(new QueryMessage(null) {
@Override
public Query getQuery() {
// serializable exception thrown
throw new CayenneRuntimeException();
}
});
fail("Expected to throw");
} catch (Exception ex) {
Util.cloneViaSerialization(ex);
}
try {
service.processMessage(new QueryMessage(null) {
@Override
public Query getQuery() {
// non-serializable exception thrown
throw new MockUnserializableException();
}
});
fail("Expected to throw");
} catch (Exception ex) {
Util.cloneViaSerialization(ex);
}
}
Aggregations