/tests/com/google/appengine/datanucleus/query/JDOQLCursorTest.java

http://datanucleus-appengine.googlecode.com/ · Java · 187 lines · 141 code · 24 blank · 22 comment · 7 complexity · 90ec8a0da9d7516ef977c89cf571c3e0 MD5 · raw file

  1. /*
  2. * Copyright (C) 2010 Google Inc
  3. *
  4. * Licensed under the Apache License, Version 2.0 (the "License");
  5. * you may not use this file except in compliance with the License.
  6. * You may obtain a copy of the License at
  7. *
  8. * http://www.apache.org/licenses/LICENSE-2.0
  9. *
  10. * Unless required by applicable law or agreed to in writing, software
  11. * distributed under the License is distributed on an "AS IS" BASIS,
  12. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  13. * See the License for the specific language governing permissions and
  14. * limitations under the License.
  15. */
  16. package com.google.appengine.datanucleus.query;
  17. import com.google.appengine.api.datastore.Cursor;
  18. import com.google.appengine.api.datastore.Entity;
  19. import com.google.appengine.api.datastore.FetchOptions;
  20. import com.google.appengine.api.datastore.Key;
  21. import com.google.appengine.api.datastore.KeyFactory;
  22. import com.google.appengine.api.datastore.QueryResultIterator;
  23. import com.google.appengine.datanucleus.Utils;
  24. import com.google.appengine.datanucleus.jdo.JDOTestCase;
  25. import com.google.appengine.datanucleus.test.jdo.Flight;
  26. import com.google.appengine.datanucleus.test.jpa.Book;
  27. import java.util.Arrays;
  28. import java.util.Iterator;
  29. import java.util.List;
  30. import java.util.Map;
  31. import javax.jdo.Query;
  32. /**
  33. * @author Max Ross <max.ross@gmail.com>
  34. */
  35. public class JDOQLCursorTest extends JDOTestCase {
  36. public void testGetCursor_List() {
  37. Entity e1 = Flight.newFlightEntity("harold", "bos", "mia", 23, 24);
  38. Entity e2 = Flight.newFlightEntity("harold", "bos", "mia", 23, 24);
  39. Entity e3 = Flight.newFlightEntity("harold", "bos", "mia", 23, 24);
  40. ds.put(Arrays.asList(e1, e2, e3));
  41. Map<String, Object> extensionMap = Utils.newHashMap();
  42. beginTxn();
  43. Query q = pm.newQuery(Flight.class);
  44. q.setRange(0, 1);
  45. List<Flight> flights = (List<Flight>) q.execute();
  46. assertEquals(1, flights.size());
  47. assertEquals(e1.getKey(), KeyFactory.stringToKey(flights.get(0).getId()));
  48. Cursor c = JDOCursorHelper.getCursor(flights);
  49. assertNotNull(c);
  50. extensionMap.put(JDOCursorHelper.CURSOR_EXTENSION, c);
  51. q.setExtensions(extensionMap);
  52. flights = (List<Flight>) q.execute();
  53. assertEquals(1, flights.size());
  54. assertEquals(e2.getKey(), KeyFactory.stringToKey(flights.get(0).getId()));
  55. assertNotNull(JDOCursorHelper.getCursor(flights));
  56. extensionMap.put(JDOCursorHelper.CURSOR_EXTENSION, c.toWebSafeString());
  57. q.setExtensions(extensionMap);
  58. flights = (List<Flight>) q.execute();
  59. assertEquals(1, flights.size());
  60. assertEquals(e2.getKey(), KeyFactory.stringToKey(flights.get(0).getId()));
  61. c = JDOCursorHelper.getCursor(flights);
  62. assertNotNull(c);
  63. extensionMap.put(JDOCursorHelper.CURSOR_EXTENSION, c);
  64. q.setExtensions(extensionMap);
  65. flights = (List<Flight>) q.execute();
  66. assertEquals(1, flights.size());
  67. assertEquals(e3.getKey(), KeyFactory.stringToKey(flights.get(0).getId()));
  68. assertNotNull(JDOCursorHelper.getCursor(flights));
  69. extensionMap.put(JDOCursorHelper.CURSOR_EXTENSION, c.toWebSafeString());
  70. q.setExtensions(extensionMap);
  71. flights = (List<Flight>) q.execute();
  72. assertEquals(1, flights.size());
  73. assertEquals(e3.getKey(), KeyFactory.stringToKey(flights.get(0).getId()));
  74. assertNotNull(JDOCursorHelper.getCursor(flights));
  75. commitTxn();
  76. }
  77. public void testCursorEquality() {
  78. List<Key> keys = Utils.newArrayList();
  79. keys.add(ds.put(Book.newBookEntity("auth", "34", "yar")));
  80. keys.add(ds.put(Book.newBookEntity("auth", "34", "yar")));
  81. keys.add(ds.put(Book.newBookEntity("auth", "34", "yar")));
  82. com.google.appengine.api.datastore.Query query = new com.google.appengine.api.datastore.Query("Book");
  83. QueryResultIterator entityIter = ds.prepare(query).asQueryResultIterator();
  84. List<Cursor> lowLevelCursors = Utils.newArrayList();
  85. lowLevelCursors.add(entityIter.getCursor());
  86. entityIter.next();
  87. lowLevelCursors.add(entityIter.getCursor());
  88. entityIter.next();
  89. lowLevelCursors.add(entityIter.getCursor());
  90. entityIter.next();
  91. lowLevelCursors.add(entityIter.getCursor());
  92. beginTxn();
  93. Query q = pm.newQuery("select from " + Book.class.getName());
  94. Iterator<Book> bookIter = asIterator(q);
  95. List<Cursor> ormCursors = Utils.newArrayList();
  96. ormCursors.add(JDOCursorHelper.getCursor(bookIter));
  97. bookIter.next();
  98. ormCursors.add(JDOCursorHelper.getCursor(bookIter));
  99. bookIter.next();
  100. ormCursors.add(JDOCursorHelper.getCursor(bookIter));
  101. bookIter.next();
  102. ormCursors.add(JDOCursorHelper.getCursor(bookIter));
  103. commitTxn();
  104. assertEquals(lowLevelCursors, ormCursors);
  105. for (int i = 0; i < lowLevelCursors.size(); i++) {
  106. Cursor lowLevelCursor = lowLevelCursors.get(i);
  107. @SuppressWarnings("deprecation")
  108. List<Entity> list = ds.prepare(query).asList(FetchOptions.Builder.withCursor(lowLevelCursor));
  109. assertEquals(3 - i, list.size());
  110. }
  111. }
  112. public void testGetCursor_Iterator() {
  113. List<Key> keys = Utils.newArrayList();
  114. for (int i = 0; i < 10; i++) {
  115. keys.add(ds.put(Book.newBookEntity("auth" + i, "34", "yar")));
  116. }
  117. beginTxn();
  118. Query q = pm.newQuery("select from " + Book.class.getName());
  119. Iterator<Book> bookIter = asIterator(q);
  120. assertCursorResults(JDOCursorHelper.getCursor(bookIter), keys);
  121. int index = 0;
  122. while (bookIter.hasNext()) {
  123. bookIter.next();
  124. assertCursorResults(JDOCursorHelper.getCursor(bookIter), keys.subList(++index, keys.size()));
  125. }
  126. // setting a max result means we call asQueryResultList(), and there are no
  127. // intermediate cursors available from a List.
  128. q.setRange(0, 1);
  129. bookIter = asIterator(q);
  130. assertNull(JDOCursorHelper.getCursor((asIterator(q))));
  131. while (bookIter.hasNext()) {
  132. bookIter.next();
  133. assertNull(JDOCursorHelper.getCursor((asIterator(q))));
  134. }
  135. }
  136. private <T> Iterator<T> asIterator(Query q) {
  137. return ((List) q.execute()).iterator();
  138. }
  139. public void testGetCursor_Iterable() {
  140. List<Key> keys = Utils.newArrayList();
  141. for (int i = 0; i < 10; i++) {
  142. keys.add(ds.put(Book.newBookEntity("auth" + i, "34", "yar")));
  143. }
  144. beginTxn();
  145. Query q = pm.newQuery("select from " + Book.class.getName());
  146. // no limit specified so what we get back doesn't have an end cursor
  147. List<Book> bookList = (List<Book>) q.execute();
  148. assertNull(JDOCursorHelper.getCursor(bookList));
  149. for (@SuppressWarnings("unused") Book b : bookList) {
  150. // no cursor
  151. assertNull(JDOCursorHelper.getCursor(bookList));
  152. }
  153. }
  154. private void assertCursorResults(Cursor cursor, List<Key> expectedKeys) {
  155. Query q = pm.newQuery("select from " + Book.class.getName());
  156. q.addExtension(JDOCursorHelper.QUERY_CURSOR_PROPERTY_NAME, cursor);
  157. List<Key> keys = Utils.newArrayList();
  158. for (Object b : (Iterable) q.execute()) {
  159. keys.add(KeyFactory.stringToKey(((Book) b).getId()));
  160. }
  161. assertEquals(expectedKeys, keys);
  162. }
  163. }