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

http://datanucleus-appengine.googlecode.com/ · Java · 182 lines · 131 code · 24 blank · 27 comment · 7 complexity · b4decbc25078577443eb443565ea6468 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.jpa.JPATestCase;
  25. import com.google.appengine.datanucleus.test.jpa.Book;
  26. import java.util.Arrays;
  27. import java.util.Iterator;
  28. import java.util.List;
  29. import javax.persistence.FlushModeType;
  30. import javax.persistence.Query;
  31. /**
  32. * @author Max Ross <max.ross@gmail.com>
  33. */
  34. public class JPQLCursorTest extends JPATestCase {
  35. public void testGetCursor_List() {
  36. Entity e1 = Book.newBookEntity("auth", "34", "yar");
  37. Entity e2 = Book.newBookEntity("auth", "34", "yar");
  38. Entity e3 = Book.newBookEntity("auth", "34", "yar");
  39. ds.put(Arrays.asList(e1, e2, e3));
  40. beginTxn();
  41. Query q = em.createQuery("select from " + Book.class.getName() + " b");
  42. q.setMaxResults(1);
  43. List<Book> books = (List<Book>) q.getResultList();
  44. assertEquals(1, books.size());
  45. assertEquals(e1.getKey(), KeyFactory.stringToKey(books.get(0).getId()));
  46. Cursor c = JPACursorHelper.getCursor(books);
  47. assertNotNull(c);
  48. q.setHint(JPACursorHelper.CURSOR_HINT, c);
  49. books = (List<Book>) q.getResultList();
  50. assertEquals(1, books.size());
  51. assertEquals(e2.getKey(), KeyFactory.stringToKey(books.get(0).getId()));
  52. assertNotNull(JPACursorHelper.getCursor(books));
  53. q.setHint(JPACursorHelper.CURSOR_HINT, c.toWebSafeString());
  54. books = (List<Book>) q.getResultList();
  55. assertEquals(1, books.size());
  56. assertEquals(e2.getKey(), KeyFactory.stringToKey(books.get(0).getId()));
  57. c = JPACursorHelper.getCursor(books);
  58. assertNotNull(c);
  59. q.setHint(JPACursorHelper.CURSOR_HINT, c);
  60. books = (List<Book>) q.getResultList();
  61. assertEquals(1, books.size());
  62. assertEquals(e3.getKey(), KeyFactory.stringToKey(books.get(0).getId()));
  63. assertNotNull(JPACursorHelper.getCursor(books));
  64. q.setHint(JPACursorHelper.CURSOR_HINT, c.toWebSafeString());
  65. books = (List<Book>) q.getResultList();
  66. assertEquals(1, books.size());
  67. assertEquals(e3.getKey(), KeyFactory.stringToKey(books.get(0).getId()));
  68. assertNotNull(JPACursorHelper.getCursor(books));
  69. commitTxn();
  70. }
  71. public void testCursorEquality() {
  72. List<Key> keys = Utils.newArrayList();
  73. keys.add(ds.put(Book.newBookEntity("auth", "34", "yar")));
  74. keys.add(ds.put(Book.newBookEntity("auth", "34", "yar")));
  75. keys.add(ds.put(Book.newBookEntity("auth", "34", "yar")));
  76. com.google.appengine.api.datastore.Query query = new com.google.appengine.api.datastore.Query("Book");
  77. QueryResultIterator entityIter = ds.prepare(query).asQueryResultIterator();
  78. List<Cursor> lowLevelCursors = Utils.newArrayList();
  79. lowLevelCursors.add(entityIter.getCursor());
  80. entityIter.next();
  81. lowLevelCursors.add(entityIter.getCursor());
  82. entityIter.next();
  83. lowLevelCursors.add(entityIter.getCursor());
  84. entityIter.next();
  85. lowLevelCursors.add(entityIter.getCursor());
  86. Query q = em.createQuery("select from " + Book.class.getName() + " b");
  87. Iterator<Book> bookIter = q.getResultList().iterator();
  88. List<Cursor> ormCursors = Utils.newArrayList();
  89. ormCursors.add(JPACursorHelper.getCursor(bookIter));
  90. bookIter.next();
  91. ormCursors.add(JPACursorHelper.getCursor(bookIter));
  92. bookIter.next();
  93. ormCursors.add(JPACursorHelper.getCursor(bookIter));
  94. bookIter.next();
  95. ormCursors.add(JPACursorHelper.getCursor(bookIter));
  96. assertEquals(lowLevelCursors, ormCursors);
  97. for (int i = 0; i < lowLevelCursors.size(); i++) {
  98. Cursor lowLevelCursor = lowLevelCursors.get(i);
  99. @SuppressWarnings("deprecation")
  100. List<Entity> list = ds.prepare(query).asList(FetchOptions.Builder.withCursor(lowLevelCursor));
  101. assertEquals(3 - i, list.size());
  102. }
  103. }
  104. public void testGetCursor_Iterator() {
  105. List<Key> keys = Utils.newArrayList();
  106. for (int i = 0; i < 10; i++) {
  107. keys.add(ds.put(Book.newBookEntity("auth" + i, "34", "yar")));
  108. }
  109. beginTxn();
  110. Query q = em.createQuery("select from " + Book.class.getName() + " b");
  111. Iterator<Book> bookIter = q.getResultList().iterator();
  112. assertCursorResults(JPACursorHelper.getCursor(bookIter), keys);
  113. int index = 0;
  114. while (bookIter.hasNext()) {
  115. bookIter.next();
  116. assertCursorResults(JPACursorHelper.getCursor(bookIter), keys.subList(++index, keys.size()));
  117. }
  118. // setting a max result means we call asQueryResultList(), and there are no
  119. // intermediate cursors available from a List.
  120. q.setMaxResults(1);
  121. bookIter = q.getResultList().iterator();
  122. assertNull(JPACursorHelper.getCursor((bookIter)));
  123. while (bookIter.hasNext()) {
  124. bookIter.next();
  125. assertNull(JPACursorHelper.getCursor((bookIter)));
  126. }
  127. }
  128. public void testGetCursor_Iterable() {
  129. List<Key> keys = Utils.newArrayList();
  130. for (int i = 0; i < 10; i++) {
  131. keys.add(ds.put(Book.newBookEntity("auth" + i, "34", "yar")));
  132. }
  133. beginTxn();
  134. Query q = em.createQuery("select from " + Book.class.getName() + " b");
  135. // no limit specified so what we get back doesn't have an end cursor
  136. List<Book> bookList = q.getResultList();
  137. assertNull(JPACursorHelper.getCursor(bookList));
  138. for (@SuppressWarnings("unused") Book b : bookList) {
  139. // no cursor
  140. assertNull(JPACursorHelper.getCursor(bookList));
  141. }
  142. }
  143. private void assertCursorResults(Cursor cursor, List<Key> expectedKeys) {
  144. Query q = em.createQuery("select from " + Book.class.getName() + " b");
  145. q.setHint(JPACursorHelper.QUERY_CURSOR_PROPERTY_NAME, cursor);
  146. // if FlushModeType is AUTO and there is another query in progress
  147. // in this txn, that query result will get flushed before this one
  148. // runs, and as a result the cursor will get bumped to the end of the
  149. // result set, which is not what we want for this test. We set the
  150. // FlushModeType to COMMIT to prevent the flush from happening.
  151. q.setFlushMode(FlushModeType.COMMIT);
  152. List<Key> keys = Utils.newArrayList();
  153. for (Object b : q.getResultList()) {
  154. keys.add(KeyFactory.stringToKey(((Book) b).getId()));
  155. }
  156. assertEquals(expectedKeys, keys);
  157. }
  158. }