@Override public Void call() { Iterator<Entity> iter = preparedQuery.asIterator(fetchOptions); while (iter.hasNext()) { ArrayList<Key> keys = new ArrayList<>(chunkSize); for (int i = 0; i < chunkSize && iter.hasNext(); i++) { keys.add(iter.next().getKey()); } logger.info("Deleting " + keys.size() + " " + kind + "s with rootJobKey=" + rootJobKey); dataStore.delete(null, keys); } return null; } });
public Entity fetchResult(PreparedQuery preparedQuery) { return preparedQuery.asIterator().next(); } });
private void assertIAEWhenAccessingIterator(PreparedQuery preparedQuery) { Iterator<Entity> iterator = preparedQuery.asIterator(); try { iterator.hasNext(); fail("Expected IllegalArgumentException"); } catch (IllegalArgumentException ex) { // pass } }
public static <T extends TempData> T getLastTempData(Class<T> type) { try { DatastoreService ds = DatastoreServiceFactory.getDatastoreService(); String kind = getKind(type); PreparedQuery pq = ds.prepare(new Query(kind).addSort("timestamp", Query.SortDirection.DESCENDING)); Iterator<Entity> iter = pq.asIterator(); if (iter.hasNext()) { Entity entity = iter.next(); return readTempData(type, entity, ds); } else { return null; } } catch (Exception e) { throw new IllegalStateException(e); } }
@Test(expected = NoSuchElementException.class) public void testIteratorThrowsNoSuchElementException() throws Exception { Iterator<Entity> iterator = preparedQuery.asIterator(); iterator.next(); assertFalse(iterator.hasNext()); iterator.next(); }
private static <T extends TempData> List<T> getAllTempData(Class<T> type, boolean unreadOnly) { try { DatastoreService ds = DatastoreServiceFactory.getDatastoreService(); String kind = getKind(type); Query query = new Query(kind); if (unreadOnly) { query.setFilter(new Query.FilterPredicate(TEMP_DATA_READ_PROPERTY, Query.FilterOperator.EQUAL, false)); } else { query.addSort("timestamp", Query.SortDirection.ASCENDING); } PreparedQuery pq = ds.prepare(query); Iterator<Entity> iter = pq.asIterator(); List<T> result = new ArrayList<>(); while (iter.hasNext()) { Entity entity = iter.next(); T data = readTempData(type, entity, ds); result.add(data); } return result; } catch (Exception e) { throw new IllegalStateException(e); } }
@Test public void testMultipleQueriesWithSameAncestorInsideSameTransactionAreAllowed() { Transaction tx = service.beginTransaction(); try { Key ancestor = KeyFactory.createKey("ancestor", "1"); prepareQueryWithAncestor(tx, ancestor).asIterator().hasNext(); prepareQueryWithAncestor(tx, ancestor).asIterator().hasNext(); } finally { tx.rollback(); } }
@Test public void testAsIterator() throws Exception { Iterator<Entity> iterator = preparedQuery.asIterator(); assertNotNull(iterator); assertTrue(iterator.hasNext()); assertEquals(john, iterator.next()); }
@Test public void testAsIteratorWithOptions() throws Exception { Iterator<Entity> iterator = preparedQuery.asIterator(withDefaults()); assertNotNull(iterator); assertTrue(iterator.hasNext()); assertEquals(john, iterator.next()); }
@Test(expected = IllegalArgumentException.class) public void testWrongType() { Query query = new Query(kindName, rootKey); query.addProjection(new PropertyProjection("stringData", Integer.class)); service.prepare(query).asIterator(fetchOption).next(); }
@Test public void testEntity() { for (String ns : namespaceDat) { NamespaceManager.set(ns); Query query = new Query(kindName); Entity readRec = service.prepare(query).asIterator().next(); assertEquals(ns, readRec.getNamespace()); String appId = readRec.getAppId(); appId = appId.substring(appId.indexOf("~") + 1); assertEquals(SystemProperty.applicationId.get(), appId); assertTrue(readRec.hasProperty("jobType")); } }
@Test public void testQueriesWithDifferentAncestorsInsideSameTransactionThrowIllegalArgumentException() { Transaction tx = service.beginTransaction(); try { Key someAncestor = KeyFactory.createKey("ancestor", "1"); prepareQueryWithAncestor(tx, someAncestor).asIterator().hasNext(); Key otherAncestor = KeyFactory.createKey("ancestor", "2"); assertIAEWhenAccessingResult(prepareQueryWithAncestor(tx, otherAncestor)); } finally { tx.rollback(); } }
@Test @InSequence(5) public void testStep5IteratorWithOption() { FetchOptions foIterator = FetchOptions.Builder.withLimit(limit); Query q = new Query(kindName, rootKey); Iterator<Entity> eData = service.prepare(q).asIterator(foIterator); assertEquals(limit, getSize(eData)); foIterator = FetchOptions.Builder.withOffset(offset); eData = service.prepare(q).asIterator(foIterator); assertEquals(bigCount - offset, getSize(eData)); }
Iterator<Entity> it = preparedQuery.asIterator(fetchOptions);
@Test @InSequence(7) public void testStep7IterableWithOption() { FetchOptions foIterable = FetchOptions.Builder.withLimit(limit); Query q = new Query(kindName, rootKey); Iterator<Entity> eData = service.prepare(q).asIterator(fo.limit(limit)); assertEquals(limit, getSize(eData)); foIterable = FetchOptions.Builder.withOffset(offset); eData = service.prepare(q).asIterator(foIterable); assertEquals(bigCount - offset, getSize(eData)); }
@Test public void testQueryOnSomePropertyWithKeyInDifferentNamespace() { NamespaceManager.set("one"); Key keyInNamespaceOne = KeyFactory.createKey("kind", 1); NamespaceManager.set("two"); Query query = new Query("kind").setFilter(new Query.FilterPredicate("someProperty", EQUAL, keyInNamespaceOne)); PreparedQuery preparedQuery = service.prepare(query); preparedQuery.asSingleEntity(); // should not throw IllegalArgumentException as in previous test preparedQuery.asIterator().hasNext(); // should not throw IllegalArgumentException as in previous test preparedQuery.asList(withDefaults()).size(); // should not throw IllegalArgumentException as in previous test } }
@Test @InSequence(4) public void testStep4BigAsIterator() { Query q = new Query(kindName, rootKey); q.setFilter(new FilterPredicate("count", FilterOperator.LESS_THAN, bigCount)); Iterator<Entity> eData = service.prepare(q).asIterator(fo); assertEquals(bigCount, getSize(eData)); }
@Test public void testQueryOnKeyReservedPropertyInDifferentNamespace() { NamespaceManager.set("one"); Key keyInNamespaceOne = KeyFactory.createKey("kind", 1); NamespaceManager.set("two"); Query query = new Query().setFilter(new Query.FilterPredicate(Entity.KEY_RESERVED_PROPERTY, EQUAL, keyInNamespaceOne)); NamespaceManager.set("one"); // to make sure that the query's namespace is used when checking, not the current namespace try { service.prepare(query).asSingleEntity(); fail("Expected IllegalArgumentException"); } catch (IllegalArgumentException ok) { } try { service.prepare(query).asIterator().next(); fail("Expected IllegalArgumentException"); } catch (IllegalArgumentException ok) { } try { service.prepare(query).asList(withDefaults()).size(); fail("Expected IllegalArgumentException"); } catch (IllegalArgumentException ok) { } }
@Test @InSequence(8) public void testStep8FetchOption() { Query q = new Query(kindName, rootKey).addSort("count", Query.SortDirection.DESCENDING); Entity e = service.prepare(q).asIterator().next(); assertEquals(new Integer(bigCount - 1).longValue(), e.getProperty("count")); FetchOptions foTest = FetchOptions.Builder.withDefaults(); int ttl = service.prepare(q).countEntities(foTest.limit(500)); assertEquals(500, ttl); foTest = FetchOptions.Builder.withDefaults(); ttl = service.prepare(q).countEntities(foTest.offset(150)); assertEquals((bigCount - 150), ttl); fo = FetchOptions.Builder.withDefaults(); ttl = service.prepare(q).countEntities(foTest.offset(50).limit(150)); assertEquals(150, ttl); fo = FetchOptions.Builder.withDefaults(); ttl = service.prepare(q).countEntities(foTest.limit(150).offset(offset)); int expect = (150 < (bigCount - offset)) ? 150 : (bigCount - offset); assertEquals(expect, ttl); }
@Test public void testQueriesWithDifferentAncestorsInsideSameTransactionNoUsage() { Transaction tx = service.beginTransaction(); try { Key a1 = KeyFactory.createKey("ancestor", "1"); prepareQueryWithAncestor(tx, a1).asIterator(); Key a2 = KeyFactory.createKey("ancestor", "2"); prepareQueryWithAncestor(tx, a2).asList(FetchOptions.Builder.withDefaults()); Key a3 = KeyFactory.createKey("ancestor", "3"); prepareQueryWithAncestor(tx, a3).asIterable(); Key a4 = KeyFactory.createKey("ancestor", "4"); prepareQueryWithAncestor(tx, a4).asQueryResultIterable(); Key a5 = KeyFactory.createKey("ancestor", "5"); prepareQueryWithAncestor(tx, a5).asQueryResultIterator(); Key a6 = KeyFactory.createKey("ancestor", "6"); prepareQueryWithAncestor(tx, a6).asQueryResultList(FetchOptions.Builder.withDefaults()); } finally { tx.rollback(); } }