PageRenderTime 71ms CodeModel.GetById 15ms RepoModel.GetById 0ms app.codeStats 0ms

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

http://datanucleus-appengine.googlecode.com/
Java | 3513 lines | 3027 code | 379 blank | 107 comment | 69 complexity | 9f9753ac1411133e88541b3c78d14a72 MD5 | raw file
Possible License(s): Apache-2.0
  1. /**********************************************************************
  2. Copyright (c) 2009 Google Inc.
  3. Licensed under the Apache License, Version 2.0 (the "License");
  4. you may not use this file except in compliance with the License.
  5. You may obtain a copy of the License at
  6. http://www.apache.org/licenses/LICENSE-2.0
  7. Unless required by applicable law or agreed to in writing, software
  8. distributed under the License is distributed on an "AS IS" BASIS,
  9. WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  10. See the License for the specific language governing permissions and
  11. limitations under the License.
  12. **********************************************************************/
  13. package com.google.appengine.datanucleus.query;
  14. import static com.google.appengine.datanucleus.test.jdo.Flight.newFlightEntity;
  15. import com.google.appengine.api.datastore.DatastoreFailureException;
  16. import com.google.appengine.api.datastore.DatastoreTimeoutException;
  17. import com.google.appengine.api.datastore.Entity;
  18. import com.google.appengine.api.datastore.Key;
  19. import com.google.appengine.api.datastore.KeyFactory;
  20. import com.google.appengine.api.datastore.Query.FilterOperator;
  21. import com.google.appengine.api.datastore.Query.FilterPredicate;
  22. import com.google.appengine.api.datastore.Query.SortDirection;
  23. import com.google.appengine.api.datastore.Query.SortPredicate;
  24. import com.google.appengine.api.datastore.ShortBlob;
  25. import com.google.appengine.api.datastore.dev.LocalDatastoreService;
  26. import com.google.appengine.api.users.User;
  27. import com.google.appengine.datanucleus.DatastoreManager;
  28. import com.google.appengine.datanucleus.DatastoreServiceFactoryInternal;
  29. import com.google.appengine.datanucleus.DatastoreServiceInterceptor;
  30. import com.google.appengine.datanucleus.ExceptionThrowingDatastoreDelegate;
  31. import com.google.appengine.datanucleus.PrimitiveArrays;
  32. import com.google.appengine.datanucleus.TestUtils;
  33. import com.google.appengine.datanucleus.Utils;
  34. import com.google.appengine.datanucleus.WriteBlocker;
  35. import com.google.appengine.datanucleus.jdo.JDOTestCase;
  36. import com.google.appengine.datanucleus.test.jdo.AbstractBaseClassesJDO.Base1;
  37. import com.google.appengine.datanucleus.test.jdo.BidirectionalChildListJDO;
  38. import com.google.appengine.datanucleus.test.jdo.BidirectionalChildLongPkListJDO;
  39. import com.google.appengine.datanucleus.test.jdo.BidirectionalGrandchildListJDO;
  40. import com.google.appengine.datanucleus.test.jdo.Flight;
  41. import com.google.appengine.datanucleus.test.jdo.HasBytesJDO;
  42. import com.google.appengine.datanucleus.test.jdo.HasEmbeddedJDO;
  43. import com.google.appengine.datanucleus.test.jdo.HasEncodedStringPkJDO;
  44. import com.google.appengine.datanucleus.test.jdo.HasEncodedStringPkSeparateIdFieldJDO;
  45. import com.google.appengine.datanucleus.test.jdo.HasEncodedStringPkSeparateNameFieldJDO;
  46. import com.google.appengine.datanucleus.test.jdo.HasEnumJDO;
  47. import com.google.appengine.datanucleus.test.jdo.HasKeyAncestorKeyPkJDO;
  48. import com.google.appengine.datanucleus.test.jdo.HasKeyAncestorStringPkJDO;
  49. import com.google.appengine.datanucleus.test.jdo.HasKeyPkJDO;
  50. import com.google.appengine.datanucleus.test.jdo.HasLongPkJDO;
  51. import com.google.appengine.datanucleus.test.jdo.HasMultiValuePropsJDO;
  52. import com.google.appengine.datanucleus.test.jdo.HasOneToManyKeyPkListJDO;
  53. import com.google.appengine.datanucleus.test.jdo.HasOneToManyKeyPkSetJDO;
  54. import com.google.appengine.datanucleus.test.jdo.HasOneToManyListJDO;
  55. import com.google.appengine.datanucleus.test.jdo.HasOneToManyLongPkListJDO;
  56. import com.google.appengine.datanucleus.test.jdo.HasOneToManyLongPkSetJDO;
  57. import com.google.appengine.datanucleus.test.jdo.HasOneToManyUnencodedStringPkListJDO;
  58. import com.google.appengine.datanucleus.test.jdo.HasOneToManyUnencodedStringPkSetJDO;
  59. import com.google.appengine.datanucleus.test.jdo.HasOneToOneJDO;
  60. import com.google.appengine.datanucleus.test.jdo.HasOneToOneParentJDO;
  61. import com.google.appengine.datanucleus.test.jdo.HasStringAncestorStringPkJDO;
  62. import com.google.appengine.datanucleus.test.jdo.HasUnencodedStringPkJDO;
  63. import com.google.appengine.datanucleus.test.jdo.KitchenSink;
  64. import com.google.appengine.datanucleus.test.jdo.NullDataJDO;
  65. import com.google.appengine.datanucleus.test.jdo.Person;
  66. import com.google.appengine.datanucleus.test.jdo.UnidirectionalSuperclassTableChildJDO.UnidirTop;
  67. import com.google.appengine.datanucleus.test.jpa.Book;
  68. import com.google.apphosting.api.ApiProxy;
  69. import com.google.apphosting.api.DatastorePb;
  70. import junit.framework.Assert;
  71. import org.datanucleus.api.jdo.JDOPersistenceManagerFactory;
  72. import org.datanucleus.api.jdo.JDOQuery;
  73. import org.datanucleus.exceptions.NucleusUserException;
  74. import org.datanucleus.query.expression.Expression;
  75. import org.datanucleus.store.query.cache.QueryResultsCache;
  76. import org.easymock.EasyMock;
  77. import java.io.ByteArrayOutputStream;
  78. import java.io.IOException;
  79. import java.io.ObjectOutputStream;
  80. import java.math.BigDecimal;
  81. import java.util.Arrays;
  82. import java.util.Collection;
  83. import java.util.Collections;
  84. import java.util.HashMap;
  85. import java.util.HashSet;
  86. import java.util.Iterator;
  87. import java.util.LinkedList;
  88. import java.util.List;
  89. import java.util.Map;
  90. import java.util.Set;
  91. import java.util.concurrent.Future;
  92. import javax.jdo.Extent;
  93. import javax.jdo.JDODataStoreException;
  94. import javax.jdo.JDOException;
  95. import javax.jdo.JDOFatalUserException;
  96. import javax.jdo.JDOUserException;
  97. import javax.jdo.Query;
  98. import javax.jdo.listener.InstanceLifecycleEvent;
  99. import javax.jdo.listener.LoadLifecycleListener;
  100. /**
  101. * @author Max Ross <maxr@google.com>
  102. */
  103. public class JDOQLQueryTest extends JDOTestCase {
  104. private static final List<SortPredicate> NO_SORTS = Collections.emptyList();
  105. private static final List<FilterPredicate> NO_FILTERS = Collections.emptyList();
  106. private static final FilterPredicate ORIGIN_EQ_2 =
  107. new FilterPredicate("origin", FilterOperator.EQUAL, 2);
  108. private static final FilterPredicate ORIGIN_EQ_2_LITERAL =
  109. new FilterPredicate("origin", FilterOperator.EQUAL, 2L);
  110. private static final FilterPredicate ORIGIN_NEQ_NULL_LITERAL =
  111. new FilterPredicate("origin", FilterOperator.NOT_EQUAL, null);
  112. private static final FilterPredicate ORIGIN_EQ_2STR =
  113. new FilterPredicate("origin", FilterOperator.EQUAL, "2");
  114. private static final FilterPredicate ORIGIN_NEQ_2_LITERAL =
  115. new FilterPredicate("origin", FilterOperator.NOT_EQUAL, 2L);
  116. private static final FilterPredicate DEST_EQ_4_LITERAL =
  117. new FilterPredicate("dest", FilterOperator.EQUAL, 4L);
  118. private static final FilterPredicate ORIG_GT_2_LITERAL =
  119. new FilterPredicate("origin", FilterOperator.GREATER_THAN, 2L);
  120. private static final FilterPredicate ORIG_GTE_2_LITERAL =
  121. new FilterPredicate("origin", FilterOperator.GREATER_THAN_OR_EQUAL, 2L);
  122. private static final FilterPredicate DEST_LT_4_LITERAL =
  123. new FilterPredicate("dest", FilterOperator.LESS_THAN, 4L);
  124. private static final FilterPredicate DEST_LTE_4_LITERAL =
  125. new FilterPredicate("dest", FilterOperator.LESS_THAN_OR_EQUAL, 4L);
  126. private static final SortPredicate ORIG_ASC =
  127. new SortPredicate("origin", SortDirection.ASCENDING);
  128. private static final SortPredicate DESC_DESC =
  129. new SortPredicate("dest", SortDirection.DESCENDING);
  130. private static final FilterPredicate ORIGIN_IN_2_ARGS =
  131. new FilterPredicate("origin", FilterOperator.IN, Arrays.asList("2", 2L));
  132. private static final FilterPredicate ORIGIN_IN_3_ARGS =
  133. new FilterPredicate("origin", FilterOperator.IN, Arrays.asList("2", 2L, false));
  134. @Override
  135. protected void setUp() throws Exception {
  136. super.setUp();
  137. DatastoreServiceInterceptor.install(getStoreManager(), new WriteBlocker());
  138. beginTxn();
  139. }
  140. @Override
  141. protected void tearDown() throws Exception {
  142. if (!pm.isClosed() && pm.currentTransaction().isActive()) {
  143. commitTxn();
  144. }
  145. try {
  146. super.tearDown();
  147. } finally {
  148. DatastoreServiceInterceptor.uninstall();
  149. }
  150. }
  151. public void testUnsupportedFilters() {
  152. Set<Expression.Operator> unsupportedOps = Utils.newHashSet(DatastoreQuery.UNSUPPORTED_OPERATORS);
  153. assertQueryUnsupportedByOrm(Flight.class, "!origin", Expression.OP_NOT, unsupportedOps);
  154. assertQueryUnsupportedByOrm(Flight.class, "(origin + dest) == 4", Expression.OP_ADD, unsupportedOps);
  155. assertQueryUnsupportedByOrm(Flight.class, "origin + dest == 4", Expression.OP_ADD, unsupportedOps);
  156. assertQueryUnsupportedByOrm(Flight.class, "(origin - dest) == 4", Expression.OP_SUB, unsupportedOps);
  157. assertQueryUnsupportedByOrm(Flight.class, "origin - dest == 4", Expression.OP_SUB, unsupportedOps);
  158. assertQueryUnsupportedByOrm(Flight.class, "(origin / dest) == 4", Expression.OP_DIV, unsupportedOps);
  159. assertQueryUnsupportedByOrm(Flight.class, "origin / dest == 4", Expression.OP_DIV, unsupportedOps);
  160. assertQueryUnsupportedByOrm(Flight.class, "(origin * dest) == 4", Expression.OP_MUL, unsupportedOps);
  161. assertQueryUnsupportedByOrm(Flight.class, "origin * dest == 4", Expression.OP_MUL, unsupportedOps);
  162. assertQueryUnsupportedByOrm(Flight.class, "(origin % dest) == 4", Expression.OP_MOD, unsupportedOps);
  163. assertQueryUnsupportedByOrm(Flight.class, "origin % dest == 4", Expression.OP_MOD, unsupportedOps);
  164. assertQueryUnsupportedByOrm(Flight.class, "~origin == 4", Expression.OP_COM, unsupportedOps);
  165. assertQueryUnsupportedByOrm(Flight.class, "!origin == 4", Expression.OP_NOT, unsupportedOps);
  166. assertQueryUnsupportedByOrm(Flight.class, "-origin == 4", Expression.OP_NEG, unsupportedOps);
  167. assertQueryUnsupportedByOrm(Flight.class, "origin instanceof " + Flight.class.getName(),
  168. Expression.OP_IS, unsupportedOps);
  169. assertEquals(Utils.<Expression.Operator>newHashSet(Expression.OP_CONCAT, Expression.OP_LIKE,
  170. Expression.OP_ISNOT), unsupportedOps);
  171. String baseQuery = "select from " + Flight.class.getName() + " where ";
  172. // multiple inequality filters
  173. // TODO(maxr) Make this pass against the real datastore.
  174. // We need to have it return BadRequest instead of NeedIndex for that to
  175. // happen.
  176. assertQueryUnsupportedByDatastore(baseQuery + "(origin > 2 && dest < 4)");
  177. // inequality filter prop is not the same as the first order by prop
  178. assertQueryUnsupportedByDatastore(baseQuery + "origin > 2 order by dest");
  179. // gets split into multiple inequality filters
  180. assertQueryUnsupportedByDatastore(baseQuery + "origin != 2 && dest != 4");
  181. // can't have 'or' on multiple properties
  182. assertQueryRequiresUnsupportedDatastoreFeature(baseQuery + "origin == 'yar' || dest == null");
  183. assertQueryRequiresUnsupportedDatastoreFeature(baseQuery + "origin == 4 && (dest == 'yar' || name == 'yam')");
  184. // TODO This query is flawed - defines a parameter but doesn't provide it (now an error in DN 3.x)
  185. // assertQueryRequiresUnsupportedDatastoreFeature(baseQuery + ":p1.contains(origin) || name == 'yam'");
  186. // can only check equality
  187. assertQueryRequiresUnsupportedDatastoreFeature(baseQuery + "origin > 5 || origin < 2");
  188. }
  189. private void assertQueryRequiresUnsupportedDatastoreFeature(String query) {
  190. Query q = pm.newQuery(query);
  191. q.addExtension(DatastoreManager.QUERYEXT_INMEMORY_WHEN_UNSUPPORTED, "false");
  192. try {
  193. q.execute();
  194. fail("expected JDOUserException->UnsupportedDatastoreFeatureException for query <" + query + ">");
  195. } catch (JDOUserException jdoe) {
  196. if (jdoe.getCause() instanceof DatastoreQuery.UnsupportedDatastoreFeatureException) {
  197. // good
  198. }
  199. else {
  200. throw jdoe;
  201. }
  202. }
  203. }
  204. public void testEvaluateInMemory() {
  205. ds.put(null, newFlightEntity("1", "yar", "bam", 1, 2));
  206. ds.put(null, newFlightEntity("1", "yam", null, 1, 2));
  207. // This is impossible in the datastore, so run totally in-memory
  208. String query = "SELECT FROM " + Flight.class.getName() + " WHERE origin == 'yar' || dest == null";
  209. Query q = pm.newQuery(query);
  210. q.addExtension("datanucleus.query.evaluateInMemory", "true");
  211. try {
  212. List<Flight> results = (List<Flight>) q.execute();
  213. Assert.assertEquals("Number of results was wrong", 2, results.size());
  214. } catch (JDOException jdoe) {
  215. fail("Threw exception when evaluating query in-memory, but should have run");
  216. }
  217. }
  218. public void testCacheQueryResults() {
  219. ds.put(null, newFlightEntity("1", "yar", "bam", 1, 2));
  220. ds.put(null, newFlightEntity("1", "yam", null, 1, 2));
  221. QueryResultsCache cache = null;
  222. try {
  223. String query = "SELECT FROM " + Flight.class.getName();
  224. Query q = pm.newQuery(query);
  225. q.addExtension("datanucleus.query.results.cached", "true");
  226. try {
  227. List<Flight> results = (List<Flight>) q.execute();
  228. Assert.assertEquals("Number of results was wrong", 2, results.size());
  229. } catch (JDOException jdoe) {
  230. fail("Threw exception when evaluating query and caching results : " + jdoe.getMessage());
  231. }
  232. q.closeAll();
  233. if (pm.currentTransaction().isActive()) {
  234. pm.currentTransaction().rollback();
  235. }
  236. pm.close();
  237. cache =
  238. ((JDOPersistenceManagerFactory)pmf).getNucleusContext().getStoreManager().getQueryManager().getQueryResultsCache();
  239. assertEquals("Number of entries in the query results cache is wrong", 1, cache.size());
  240. pm = pmf.getPersistenceManager();
  241. Query q2 = pm.newQuery(query);
  242. try {
  243. List<Flight> results = (List<Flight>) q2.execute();
  244. Assert.assertEquals("Number of results was wrong", 2, results.size());
  245. } catch (JDOException jdoe) {
  246. fail("Threw exception when evaluating query with cached results : " + jdoe.getMessage());
  247. }
  248. q2.closeAll();
  249. } finally {
  250. // Evict the cached results
  251. cache.evictAll();
  252. }
  253. }
  254. public void testCandidateCollectionInMemory() {
  255. ds.put(null, newFlightEntity("1", "yar", "bam", 1, 2));
  256. ds.put(null, newFlightEntity("1", "yam", null, 1, 2));
  257. Collection<Flight> coll = new HashSet<Flight>();
  258. Iterator<Flight> iter = pm.getExtent(Flight.class).iterator();
  259. while (iter.hasNext()) {
  260. coll.add(iter.next());
  261. }
  262. // Query is impossible in-datastore, and run against candidates so has to be in-memory
  263. String query = "SELECT FROM " + Flight.class.getName() + " WHERE origin == 'yar' || dest == null";
  264. Query q = pm.newQuery(query);
  265. q.setCandidates(coll);
  266. try {
  267. List<Flight> results = (List<Flight>) q.execute();
  268. Assert.assertEquals("Number of results was wrong", 2, results.size());
  269. } catch (JDOException jdoe) {
  270. fail("Threw exception when evaluating query in-memory, but should have run");
  271. }
  272. }
  273. public void testSupportedFilters() {
  274. assertQuerySupported(Flight.class, "", NO_FILTERS, NO_SORTS);
  275. assertQuerySupported(Flight.class, "origin == 2", Utils.newArrayList(ORIGIN_EQ_2_LITERAL), NO_SORTS);
  276. assertQuerySupported(
  277. Flight.class, "origin == \"2\"", Utils.newArrayList(ORIGIN_EQ_2STR), NO_SORTS);
  278. assertQuerySupported(Flight.class, "(origin == 2)", Utils.newArrayList(ORIGIN_EQ_2_LITERAL), NO_SORTS);
  279. assertQuerySupported(Flight.class, "origin == 2 && dest == 4", Utils.newArrayList(ORIGIN_EQ_2_LITERAL,
  280. DEST_EQ_4_LITERAL), NO_SORTS);
  281. assertQuerySupported(Flight.class, "(origin == 2 && dest == 4)", Utils.newArrayList(ORIGIN_EQ_2_LITERAL,
  282. DEST_EQ_4_LITERAL), NO_SORTS);
  283. assertQuerySupported(Flight.class, "(origin == 2) && (dest == 4)", Utils.newArrayList(
  284. ORIGIN_EQ_2_LITERAL, DEST_EQ_4_LITERAL), NO_SORTS);
  285. assertQuerySupported(Flight.class, "origin > 2", Utils.newArrayList(ORIG_GT_2_LITERAL), NO_SORTS);
  286. assertQuerySupported(Flight.class, "origin >= 2", Utils.newArrayList(ORIG_GTE_2_LITERAL), NO_SORTS);
  287. assertQuerySupported(Flight.class, "dest < 4", Utils.newArrayList(DEST_LT_4_LITERAL), NO_SORTS);
  288. assertQuerySupported(Flight.class, "dest <= 4", Utils.newArrayList(DEST_LTE_4_LITERAL), NO_SORTS);
  289. assertQuerySupported("select from " + Flight.class.getName() + " order by origin asc",
  290. NO_FILTERS, Utils.newArrayList(ORIG_ASC));
  291. assertQuerySupported("select from " + Flight.class.getName() + " order by dest desc",
  292. NO_FILTERS, Utils.newArrayList(DESC_DESC));
  293. assertQuerySupported("select from " + Flight.class.getName()
  294. + " order by origin asc, dest desc", NO_FILTERS, Utils.newArrayList(ORIG_ASC, DESC_DESC));
  295. assertQuerySupported("select from " + Flight.class.getName()
  296. + " where origin == 2 && dest == 4 order by origin asc, dest desc",
  297. Utils.newArrayList(ORIGIN_EQ_2_LITERAL, DEST_EQ_4_LITERAL), Utils.newArrayList(ORIG_ASC, DESC_DESC));
  298. assertQuerySupported(Flight.class, "origin != 2", Utils.newArrayList(ORIGIN_NEQ_2_LITERAL), NO_SORTS);
  299. assertQuerySupported("select from " + Flight.class.getName() + " where origin != null",
  300. Utils.newArrayList(ORIGIN_NEQ_NULL_LITERAL), NO_SORTS);
  301. assertQuerySupported(Flight.class, "origin == '2' || origin == 2",
  302. Utils.newArrayList(ORIGIN_IN_2_ARGS), NO_SORTS);
  303. assertQuerySupported(Flight.class, "origin == '2' || origin == 2 || origin == false",
  304. Utils.newArrayList(ORIGIN_IN_3_ARGS), NO_SORTS);
  305. assertQuerySupported(Flight.class, ":p1.contains(origin)",
  306. Utils.newArrayList(ORIGIN_IN_2_ARGS), NO_SORTS, Arrays.asList("2", 2L));
  307. assertQuerySupported(Flight.class, ":p1.contains(origin)",
  308. Utils.newArrayList(ORIGIN_IN_3_ARGS), NO_SORTS, Arrays.asList("2", 2L, false));
  309. assertQuerySupported(Flight.class, "(origin == '2' || origin == 2) && dest == 4",
  310. Utils.newArrayList(DEST_EQ_4_LITERAL, ORIGIN_IN_2_ARGS), NO_SORTS);
  311. assertQuerySupported(Flight.class, ":p1.contains(origin) && dest == 4",
  312. Utils.newArrayList(ORIGIN_IN_2_ARGS, DEST_EQ_4_LITERAL), NO_SORTS, Arrays.asList("2", 2L));
  313. assertQuerySupported(Flight.class, "(origin == '2' || origin == 2 || origin == false) && dest == 4",
  314. Utils.newArrayList(DEST_EQ_4_LITERAL, ORIGIN_IN_3_ARGS), NO_SORTS);
  315. assertQuerySupported(Flight.class, ":p1.contains(origin) && dest == 4",
  316. Utils.newArrayList(ORIGIN_IN_3_ARGS, DEST_EQ_4_LITERAL), NO_SORTS, Arrays.asList("2", 2L, false));
  317. }
  318. public void testBindVariables() {
  319. String queryStr = "select from " + Flight.class.getName() + " where origin == two ";
  320. assertQuerySupported(queryStr + " parameters String two",
  321. Utils.newArrayList(ORIGIN_EQ_2STR), NO_SORTS, "2");
  322. assertQuerySupportedWithExplicitParams(queryStr,
  323. Utils.newArrayList(ORIGIN_EQ_2STR), NO_SORTS, "String two", "2");
  324. queryStr = "select from " + Flight.class.getName() + " where origin == two && dest == four ";
  325. assertQuerySupported(queryStr + "parameters int two, int four",
  326. Utils.newArrayList(ORIGIN_EQ_2, DEST_EQ_4_LITERAL), NO_SORTS, 2, 4L);
  327. assertQuerySupportedWithExplicitParams(queryStr,
  328. Utils.newArrayList(ORIGIN_EQ_2, DEST_EQ_4_LITERAL), NO_SORTS, "int two, int four", 2, 4L);
  329. queryStr = "select from " + Flight.class.getName() + " where origin == two && dest == four ";
  330. String orderStr = "order by origin asc, dest desc";
  331. assertQuerySupported(queryStr + "parameters int two, int four " + orderStr,
  332. Utils.newArrayList(ORIGIN_EQ_2, DEST_EQ_4_LITERAL),
  333. Utils.newArrayList(ORIG_ASC, DESC_DESC), 2, 4L);
  334. assertQuerySupportedWithExplicitParams(queryStr + orderStr,
  335. Utils.newArrayList(ORIGIN_EQ_2, DEST_EQ_4_LITERAL),
  336. Utils.newArrayList(ORIG_ASC, DESC_DESC), "int two, int four", 2, 4L);
  337. }
  338. public void test2Equals2OrderBy() {
  339. ds.put(null, newFlightEntity("1", "yam", "bam", 1, 2));
  340. ds.put(null, newFlightEntity("2", "yam", "bam", 1, 1));
  341. ds.put(null, newFlightEntity("3", "yam", "bam", 2, 1));
  342. ds.put(null ,newFlightEntity("4", "yam", "bam", 2, 2));
  343. ds.put(null, newFlightEntity("5", "notyam", "bam", 2, 2));
  344. ds.put(null, newFlightEntity("5", "yam", "notbam", 2, 2));
  345. Query q = pm.newQuery(
  346. "select from " + Flight.class.getName()
  347. + " where origin == \"yam\" && dest == \"bam\""
  348. + " order by you asc, me desc");
  349. @SuppressWarnings("unchecked")
  350. List<Flight> result = (List<Flight>) q.execute();
  351. assertEquals(4, result.size());
  352. assertEquals("1", result.get(0).getName());
  353. assertEquals("2", result.get(1).getName());
  354. assertEquals("4", result.get(2).getName());
  355. assertEquals("3", result.get(3).getName());
  356. }
  357. public void testSetFilter() {
  358. ds.put(null, newFlightEntity("1", "yam", "bam", 1, 1));
  359. ds.put(null, newFlightEntity("2", "yam", "bam", 2, 2));
  360. Query q = pm.newQuery(
  361. "select from " + Flight.class.getName());
  362. q.setFilter("origin == \"yam\" && you == 2");
  363. @SuppressWarnings("unchecked")
  364. List<Flight> result = (List<Flight>) q.execute();
  365. assertEquals(1, result.size());
  366. }
  367. public void testSetInvalidFilter() {
  368. Query q = pm.newQuery(
  369. "select from " + Flight.class.getName());
  370. q.setFilter("origin == \"yam\" AND you == 2");
  371. try {
  372. q.execute();
  373. fail("expected exception");
  374. } catch (JDOUserException e) {
  375. // good
  376. }
  377. }
  378. public void testDefaultOrderingIsAsc() {
  379. ds.put(null, newFlightEntity("1", "yam", "bam", 1, 2));
  380. ds.put(null, newFlightEntity("2", "yam", "bam", 1, 1));
  381. ds.put(null, newFlightEntity("3", "yam", "bam", 2, 1));
  382. ds.put(null, newFlightEntity("4", "yam", "bam", 2, 2));
  383. ds.put(null, newFlightEntity("5", "notyam", "bam", 2, 2));
  384. ds.put(null, newFlightEntity("5", "yam", "notbam", 2, 2));
  385. Query q = pm.newQuery(
  386. "select from " + Flight.class.getName()
  387. + " where origin == \"yam\" && dest == \"bam\""
  388. + " order by you");
  389. @SuppressWarnings("unchecked")
  390. List<Flight> result = (List<Flight>) q.execute();
  391. assertEquals(4, result.size());
  392. assertEquals("1", result.get(0).getName());
  393. assertEquals("2", result.get(1).getName());
  394. assertEquals("3", result.get(2).getName());
  395. assertEquals("4", result.get(3).getName());
  396. }
  397. public void testLimitQuery() {
  398. ds.put(null, newFlightEntity("1", "yam", "bam", 1, 2));
  399. ds.put(null, newFlightEntity("2", "yam", "bam", 1, 1));
  400. ds.put(null, newFlightEntity("3", "yam", "bam", 2, 1));
  401. ds.put(null, newFlightEntity("4", "yam", "bam", 2, 2));
  402. ds.put(null, newFlightEntity("5", "notyam", "bam", 2, 2));
  403. ds.put(null, newFlightEntity("5", "yam", "notbam", 2, 2));
  404. Query q = pm.newQuery(
  405. "select from " + Flight.class.getName()
  406. + " where origin == \"yam\" && dest == \"bam\""
  407. + " order by you asc, me desc");
  408. q.setRange(0, 1);
  409. @SuppressWarnings("unchecked")
  410. List<Flight> result1 = (List<Flight>) q.execute();
  411. assertEquals(1, result1.size());
  412. assertEquals("1", result1.get(0).getName());
  413. q.setRange(0, Long.MAX_VALUE);
  414. @SuppressWarnings("unchecked")
  415. List<Flight> result2 = (List<Flight>) q.execute();
  416. assertEquals(4, result2.size());
  417. assertEquals("1", result2.get(0).getName());
  418. q.setRange(0, 0);
  419. @SuppressWarnings("unchecked")
  420. List<Flight> result3 = (List<Flight>) q.execute();
  421. assertEquals(0, result3.size());
  422. }
  423. public void testOffsetQuery() {
  424. ds.put(null, newFlightEntity("1", "yam", "bam", 1, 2));
  425. ds.put(null, newFlightEntity("2", "yam", "bam", 1, 1));
  426. ds.put(null, newFlightEntity("3", "yam", "bam", 2, 1));
  427. ds.put(null, newFlightEntity("4", "yam", "bam", 2, 2));
  428. ds.put(null, newFlightEntity("5", "notyam", "bam", 2, 2));
  429. ds.put(null, newFlightEntity("5", "yam", "notbam", 2, 2));
  430. Query q = pm.newQuery(
  431. "select from " + Flight.class.getName()
  432. + " where origin == \"yam\" && dest == \"bam\""
  433. + " order by you asc, me desc");
  434. q.setRange(0, Long.MAX_VALUE);
  435. @SuppressWarnings("unchecked")
  436. List<Flight> result1 = (List<Flight>) q.execute();
  437. assertEquals(4, result1.size());
  438. assertEquals("1", result1.get(0).getName());
  439. q.setRange(1, Long.MAX_VALUE);
  440. @SuppressWarnings("unchecked")
  441. List<Flight> result2 = (List<Flight>) q.execute();
  442. assertEquals(3, result2.size());
  443. assertEquals("2", result2.get(0).getName());
  444. q.setRange(0, Long.MAX_VALUE);
  445. @SuppressWarnings("unchecked")
  446. List<Flight> result3 = (List<Flight>) q.execute();
  447. assertEquals(4, result3.size());
  448. assertEquals("1", result3.get(0).getName());
  449. }
  450. public void testOffsetLimitQuery() {
  451. ds.put(null, newFlightEntity("1", "yam", "bam", 1, 2));
  452. ds.put(null, newFlightEntity("2", "yam", "bam", 1, 1));
  453. ds.put(null, newFlightEntity("3", "yam", "bam", 2, 1));
  454. ds.put(null, newFlightEntity("4", "yam", "bam", 2, 2));
  455. ds.put(null, newFlightEntity("5", "notyam", "bam", 2, 2));
  456. ds.put(null, newFlightEntity("5", "yam", "notbam", 2, 2));
  457. Query q = pm.newQuery(
  458. "select from " + Flight.class.getName()
  459. + " where origin == \"yam\" && dest == \"bam\""
  460. + " order by you asc, me desc");
  461. q.setRange(0, 0);
  462. @SuppressWarnings("unchecked")
  463. List<Flight> result1 = (List<Flight>) q.execute();
  464. assertEquals(0, result1.size());
  465. q.setRange(1, 0);
  466. @SuppressWarnings("unchecked")
  467. List<Flight> result2 = (List<Flight>) q.execute();
  468. assertEquals(0, result2.size());
  469. q.setRange(0, 1);
  470. @SuppressWarnings("unchecked")
  471. List<Flight> result3 = (List<Flight>) q.execute();
  472. assertEquals(1, result3.size());
  473. assertEquals("1", result3.get(0).getName());
  474. q.setRange(0, 2);
  475. @SuppressWarnings("unchecked")
  476. List<Flight> result4 = (List<Flight>) q.execute();
  477. assertEquals(2, result4.size());
  478. assertEquals("1", result4.get(0).getName());
  479. q.setRange(1, 2);
  480. @SuppressWarnings("unchecked")
  481. List<Flight> result5 = (List<Flight>) q.execute();
  482. assertEquals(1, result5.size());
  483. assertEquals("2", result5.get(0).getName());
  484. q.setRange(2, 5);
  485. @SuppressWarnings("unchecked")
  486. List<Flight> result6 = (List<Flight>) q.execute();
  487. assertEquals(2, result6.size());
  488. assertEquals("4", result6.get(0).getName());
  489. q.setRange(2, 2);
  490. @SuppressWarnings("unchecked")
  491. List<Flight> result7 = (List<Flight>) q.execute();
  492. assertEquals(0, result7.size());
  493. q.setRange(2, 1);
  494. @SuppressWarnings("unchecked")
  495. List<Flight> result8 = (List<Flight>) q.execute();
  496. assertEquals(0, result8.size());
  497. }
  498. public void testOffsetLimitSingleStringQuery() {
  499. ds.put(null, newFlightEntity("1", "yam", "bam", 1, 2));
  500. ds.put(null, newFlightEntity("2", "yam", "bam", 1, 1));
  501. ds.put(null, newFlightEntity("3", "yam", "bam", 2, 1));
  502. ds.put(null, newFlightEntity("4", "yam", "bam", 2, 2));
  503. ds.put(null, newFlightEntity("5", "notyam", "bam", 2, 2));
  504. ds.put(null, newFlightEntity("5", "yam", "notbam", 2, 2));
  505. String queryFormat =
  506. "select from " + Flight.class.getName()
  507. + " where origin == \"yam\" && dest == \"bam\""
  508. + " order by you asc, me desc range %d,%d";
  509. Query q = pm.newQuery(String.format(queryFormat, 0, 0));
  510. @SuppressWarnings("unchecked")
  511. List<Flight> result1 = (List<Flight>) q.execute();
  512. assertEquals(0, result1.size());
  513. q = pm.newQuery(String.format(queryFormat, 1, 0));
  514. @SuppressWarnings("unchecked")
  515. List<Flight> result2 = (List<Flight>) q.execute();
  516. assertEquals(0, result2.size());
  517. q = pm.newQuery(String.format(queryFormat, 0, 1));
  518. @SuppressWarnings("unchecked")
  519. List<Flight> result3 = (List<Flight>) q.execute();
  520. assertEquals(1, result3.size());
  521. q = pm.newQuery(String.format(queryFormat, 0, 2));
  522. @SuppressWarnings("unchecked")
  523. List<Flight> result4 = (List<Flight>) q.execute();
  524. assertEquals(2, result4.size());
  525. assertEquals("1", result4.get(0).getName());
  526. q = pm.newQuery(String.format(queryFormat, 1, 2));
  527. @SuppressWarnings("unchecked")
  528. List<Flight> result5 = (List<Flight>) q.execute();
  529. assertEquals(1, result5.size());
  530. assertEquals("2", result5.get(0).getName());
  531. q = pm.newQuery(String.format(queryFormat, 2, 5));
  532. @SuppressWarnings("unchecked")
  533. List<Flight> result6 = (List<Flight>) q.execute();
  534. assertEquals(2, result6.size());
  535. assertEquals("4", result6.get(0).getName());
  536. q = pm.newQuery(String.format(queryFormat, 2, 2));
  537. @SuppressWarnings("unchecked")
  538. List<Flight> result7 = (List<Flight>) q.execute();
  539. assertEquals(0, result7.size());
  540. q = pm.newQuery(String.format(queryFormat, 2, 1));
  541. @SuppressWarnings("unchecked")
  542. List<Flight> result8 = (List<Flight>) q.execute();
  543. assertEquals(0, result8.size());
  544. }
  545. public void testSerialization() throws IOException {
  546. Query q = pm.newQuery("select from " + Flight.class.getName());
  547. q.execute();
  548. JDOQLQuery innerQuery = (JDOQLQuery)((JDOQuery)q).getInternalQuery();
  549. ByteArrayOutputStream baos = new ByteArrayOutputStream();
  550. ObjectOutputStream oos = new ObjectOutputStream(baos);
  551. // the fact that this doesn't blow up is the test
  552. oos.writeObject(innerQuery);
  553. }
  554. public void testKeyQuery_StringPk() {
  555. Entity flightEntity = newFlightEntity("1", "yam", "bam", 1, 2);
  556. ds.put(null, flightEntity);
  557. Query q = pm.newQuery(
  558. "select from " + Flight.class.getName() + " where id == key parameters String key");
  559. @SuppressWarnings("unchecked")
  560. List<Flight> flights = (List<Flight>) q.execute(KeyFactory.keyToString(flightEntity.getKey()));
  561. assertEquals(1, flights.size());
  562. assertEquals(flightEntity.getKey(), KeyFactory.stringToKey(flights.get(0).getId()));
  563. }
  564. public void testKeyQuery_KeyPk() {
  565. Entity entityWithName = new Entity(HasKeyPkJDO.class.getSimpleName(), "blarg");
  566. Entity entityWithId = new Entity(HasKeyPkJDO.class.getSimpleName());
  567. ds.put(null, entityWithName);
  568. ds.put(null, entityWithId);
  569. Query q = pm.newQuery(
  570. "select from " + HasKeyPkJDO.class.getName() +
  571. " where key == mykey parameters " + Key.class.getName() + " mykey");
  572. @SuppressWarnings("unchecked")
  573. List<HasKeyPkJDO> result = (List<HasKeyPkJDO>) q.execute(entityWithName.getKey());
  574. assertEquals(1, result.size());
  575. assertEquals(entityWithName.getKey(), result.get(0).getKey());
  576. q = pm.newQuery(
  577. "select from " + HasKeyPkJDO.class.getName() +
  578. " where key == mykey parameters " + Key.class.getName() + " mykey");
  579. @SuppressWarnings("unchecked")
  580. List<HasKeyPkJDO> result2 = (List<HasKeyPkJDO>) q.execute(entityWithId.getKey());
  581. assertEquals(1, result2.size());
  582. assertEquals(entityWithId.getKey(), result2.get(0).getKey());
  583. q = pm.newQuery(
  584. "select from " + HasKeyPkJDO.class.getName() +
  585. " where key == mykeyname parameters " + String.class.getName() + " mykeyname");
  586. @SuppressWarnings("unchecked")
  587. List<HasKeyPkJDO> result3 = (List<HasKeyPkJDO>) q.execute(entityWithName.getKey().getName());
  588. assertEquals(1, result3.size());
  589. assertEquals(entityWithName.getKey(), result3.get(0).getKey());
  590. q = pm.newQuery(
  591. "select from " + HasKeyPkJDO.class.getName() +
  592. " where key == mykeyid parameters " + String.class.getName() + " mykeyid");
  593. @SuppressWarnings("unchecked")
  594. List<HasKeyPkJDO> result4 = (List<HasKeyPkJDO>) q.execute(entityWithId.getKey().getId());
  595. assertEquals(1, result4.size());
  596. assertEquals(entityWithId.getKey(), result4.get(0).getKey());
  597. }
  598. public void testKeyQueryWithSorts() {
  599. Entity flightEntity = newFlightEntity("1", "yam", "bam", 1, 2);
  600. ds.put(null, flightEntity);
  601. Query q = pm.newQuery(
  602. "select from " + Flight.class.getName()
  603. + " where id == key parameters String key order by id asc");
  604. @SuppressWarnings("unchecked")
  605. List<Flight> flights = (List<Flight>) q.execute(KeyFactory.keyToString(flightEntity.getKey()));
  606. assertEquals(1, flights.size());
  607. assertEquals(flightEntity.getKey(), KeyFactory.stringToKey(flights.get(0).getId()));
  608. }
  609. public void testKeyQuery_MultipleFilters() {
  610. Entity flightEntity = newFlightEntity("1", "yam", "bam", 1, 2);
  611. ds.put(null, flightEntity);
  612. Query q = pm.newQuery(
  613. "select from " + Flight.class.getName()
  614. + " where id == key && origin == \"yam\" parameters String key");
  615. @SuppressWarnings("unchecked")
  616. List<Flight> flights = (List<Flight>) q.execute(KeyFactory.keyToString(flightEntity.getKey()));
  617. assertEquals(1, flights.size());
  618. assertEquals(flightEntity.getKey(), KeyFactory.stringToKey(flights.get(0).getId()));
  619. }
  620. public void testKeyQuery_NonEqualityFilter() {
  621. Entity flightEntity1 = newFlightEntity("1", "yam", "bam", 1, 2);
  622. ds.put(null, flightEntity1);
  623. Entity flightEntity2 = newFlightEntity("1", "yam", "bam", 1, 2);
  624. ds.put(null, flightEntity2);
  625. Query q = pm.newQuery(
  626. "select from " + Flight.class.getName() + " where id > key parameters String key");
  627. @SuppressWarnings("unchecked")
  628. List<Flight> flights = (List<Flight>) q.execute(KeyFactory.keyToString(flightEntity1.getKey()));
  629. assertEquals(1, flights.size());
  630. assertEquals(flightEntity2.getKey(), KeyFactory.stringToKey(flights.get(0).getId()));
  631. }
  632. public void testKeyQuery_SortByKey() {
  633. Entity flightEntity1 = newFlightEntity("1", "yam", "bam", 1, 2);
  634. ds.put(null, flightEntity1);
  635. Entity flightEntity2 = newFlightEntity("1", "yam", "bam", 1, 2);
  636. ds.put(null, flightEntity2);
  637. Query q = pm.newQuery(
  638. "select from " + Flight.class.getName() + " where origin == 'yam' order by id DESC");
  639. @SuppressWarnings("unchecked")
  640. List<Flight> flights = (List<Flight>) q.execute();
  641. assertEquals(2, flights.size());
  642. assertEquals(flightEntity2.getKey(), KeyFactory.stringToKey(flights.get(0).getId()));
  643. assertEquals(flightEntity1.getKey(), KeyFactory.stringToKey(flights.get(1).getId()));
  644. }
  645. public void testKeyQuery_FilterAndSortByKeyComponent() {
  646. // filter by pk-id
  647. assertQueryUnsupportedByDatastore(
  648. "select from " + HasEncodedStringPkSeparateIdFieldJDO.class.getName() + " where id == 4");
  649. // sort by pk-id
  650. assertQueryUnsupportedByDatastore(
  651. "select from " + HasEncodedStringPkSeparateIdFieldJDO.class.getName() + " order by id");
  652. // filter by pk-id
  653. assertQueryUnsupportedByDatastore(
  654. "select from " + HasEncodedStringPkSeparateNameFieldJDO.class.getName() + " where name == 4");
  655. // sort by pk-id
  656. assertQueryUnsupportedByDatastore(
  657. "select from " + HasEncodedStringPkSeparateNameFieldJDO.class.getName() + " order by name");
  658. }
  659. public void testAncestorQueryWithStringAncestor() {
  660. Entity flightEntity = newFlightEntity("1", "yam", "bam", 1, 2);
  661. ds.put(null, flightEntity);
  662. Entity hasAncestorEntity = new Entity(HasStringAncestorStringPkJDO.class.getSimpleName(), flightEntity.getKey());
  663. ds.put(null, hasAncestorEntity);
  664. Query q = pm.newQuery(
  665. "select from " + HasStringAncestorStringPkJDO.class.getName()
  666. + " where ancestorId == ancId parameters String ancId");
  667. @SuppressWarnings("unchecked")
  668. List<HasStringAncestorStringPkJDO> haList =
  669. (List<HasStringAncestorStringPkJDO>) q.execute(KeyFactory.keyToString(flightEntity.getKey()));
  670. assertEquals(1, haList.size());
  671. assertEquals(flightEntity.getKey(), KeyFactory.stringToKey(haList.get(0).getAncestorId()));
  672. assertEquals(
  673. flightEntity.getKey(), getDatastoreQuery(q).getLatestDatastoreQuery().getAncestor());
  674. assertEquals(NO_FILTERS, getFilterPredicates(q));
  675. assertEquals(NO_SORTS, getSortPredicates(q));
  676. }
  677. public void testAncestorQueryWithKeyAncestor() {
  678. Entity e = new Entity("parent");
  679. ds.put(null, e);
  680. Entity childEntity = new Entity(HasKeyAncestorStringPkJDO.class.getSimpleName(), e.getKey());
  681. ds.put(null, childEntity);
  682. Query q = pm.newQuery(
  683. "select from " + HasKeyAncestorStringPkJDO.class.getName()
  684. + " where ancestorKey == ancId parameters " + Key.class.getName() + " ancId");
  685. @SuppressWarnings("unchecked")
  686. List<HasKeyAncestorStringPkJDO> result =
  687. (List<HasKeyAncestorStringPkJDO>) q.execute(e.getKey());
  688. assertEquals(1, result.size());
  689. assertEquals(e.getKey(), result.get(0).getAncestorKey());
  690. }
  691. public void testIllegalAncestorQuery_BadOperator() {
  692. Entity flightEntity = newFlightEntity("1", "yam", "bam", 1, 2);
  693. ds.put(null, flightEntity);
  694. Entity hasAncestorEntity = new Entity(HasStringAncestorStringPkJDO.class.getName(), flightEntity.getKey());
  695. ds.put(null, hasAncestorEntity);
  696. Query q = pm.newQuery(
  697. "select from " + HasStringAncestorStringPkJDO.class.getName()
  698. + " where ancestorId > ancId parameters String ancId");
  699. q.addExtension(DatastoreManager.QUERYEXT_INMEMORY_WHEN_UNSUPPORTED, "false");
  700. try {
  701. q.execute(KeyFactory.keyToString(flightEntity.getKey()));
  702. fail ("expected udfe");
  703. } catch (JDOUserException jdoe) {
  704. if (jdoe.getCause() instanceof DatastoreQuery.UnsupportedDatastoreFeatureException) {
  705. // good
  706. }
  707. else {
  708. throw jdoe;
  709. }
  710. }
  711. }
  712. public void testSortByFieldWithCustomColumn() {
  713. ds.put(null, newFlightEntity("1", "yam", "bam", 1, 2, 400));
  714. ds.put(null, newFlightEntity("2", "yam", "bam", 1, 1, 300));
  715. ds.put(null, newFlightEntity("3", "yam", "bam", 2, 1, 200));
  716. Query q = pm.newQuery(
  717. "select from " + Flight.class.getName()
  718. + " where origin == \"yam\" && dest == \"bam\""
  719. + " order by flightNumber asc");
  720. @SuppressWarnings("unchecked")
  721. List<Flight> result = (List<Flight>) q.execute();
  722. assertEquals(3, result.size());
  723. assertEquals("3", result.get(0).getName());
  724. assertEquals("2", result.get(1).getName());
  725. assertEquals("1", result.get(2).getName());
  726. }
  727. public void testIllegalAncestorQuery_SortByAncestor() {
  728. Entity flightEntity = newFlightEntity("1", "yam", "bam", 1, 2);
  729. ds.put(null, flightEntity);
  730. Entity hasAncestorEntity = new Entity(HasStringAncestorStringPkJDO.class.getName(), flightEntity.getKey());
  731. ds.put(null, hasAncestorEntity);
  732. Query q = pm.newQuery(
  733. "select from " + HasStringAncestorStringPkJDO.class.getName()
  734. + " where ancestorId == ancId parameters String ancId order by ancestorId ASC");
  735. q.addExtension(DatastoreManager.QUERYEXT_INMEMORY_WHEN_UNSUPPORTED, "false");
  736. try {
  737. q.execute(KeyFactory.keyToString(flightEntity.getKey()));
  738. fail ("expected udfe");
  739. } catch (JDOUserException jdoe) {
  740. if (jdoe.getCause() instanceof DatastoreQuery.UnsupportedDatastoreFeatureException) {
  741. // good
  742. }
  743. else {
  744. throw jdoe;
  745. }
  746. }
  747. }
  748. private interface FlightProvider {
  749. Flight getFlight(Key key);
  750. }
  751. private class AttachedFlightProvider implements FlightProvider {
  752. public Flight getFlight(Key key) {
  753. return pm.getObjectById(Flight.class, key);
  754. }
  755. }
  756. private class TransientFlightProvider implements FlightProvider {
  757. public Flight getFlight(Key key) {
  758. Flight f = new Flight();
  759. f.setId(KeyFactory.keyToString(key));
  760. return f;
  761. }
  762. }
  763. private void testFilterByChildObject(FlightProvider fp) {
  764. Entity parentEntity = new Entity(HasOneToOneJDO.class.getSimpleName());
  765. ds.put(null, parentEntity);
  766. Entity flightEntity = newFlightEntity(parentEntity.getKey(), null, "f", "bos", "mia", 2, 4, 33);
  767. ds.put(null, flightEntity);
  768. Flight flight = fp.getFlight(flightEntity.getKey());
  769. Query q = pm.newQuery(
  770. "select from " + HasOneToOneJDO.class.getName()
  771. + " where flight == f parameters " + Flight.class.getName() + " f");
  772. List<HasOneToOneJDO> result = (List<HasOneToOneJDO>) q.execute(flight);
  773. assertEquals(1, result.size());
  774. assertEquals(parentEntity.getKey(), KeyFactory.stringToKey(result.get(0).getId()));
  775. }
  776. public void testFilterByChildObject() {
  777. testFilterByChildObject(new AttachedFlightProvider());
  778. commitTxn();
  779. beginTxn();
  780. testFilterByChildObject(new TransientFlightProvider());
  781. }
  782. public void testFilterByNullChildObject() {
  783. Entity parentEntity = new Entity(HasOneToOneJDO.class.getSimpleName());
  784. ds.put(null, parentEntity);
  785. Entity flightEntity = newFlightEntity(parentEntity.getKey(), null, "f", "bos", "mia", 2, 4, 33);
  786. ds.put(null, flightEntity);
  787. Query q = pm.newQuery(
  788. "select from " + HasOneToOneJDO.class.getName()
  789. + " where flight == f parameters " + Flight.class.getName() + " f");
  790. q.addExtension(DatastoreManager.QUERYEXT_INMEMORY_WHEN_UNSUPPORTED, "false");
  791. try {
  792. q.execute(null);
  793. fail("expected exception");
  794. } catch (JDOFatalUserException e) {
  795. // good
  796. }
  797. }
  798. public void testContains() {
  799. Entity e = Flight.newFlightEntity("name1", "bos1", "mia1", 23, 24);
  800. Entity e2 = Flight.newFlightEntity("name2", "bos2", null, 25, 26);
  801. Entity e3 = Flight.newFlightEntity("name3", "bos3", "mia2", 27, 28);
  802. ds.put(null, Arrays.asList(e, e2, e3));
  803. Query q = pm.newQuery("select from " + Flight.class.getName() + " where :p1.contains(name)");
  804. List<Flight> flights = (List<Flight>) q.execute(Arrays.asList("name1", "name3"));
  805. assertEquals(2, flights.size());
  806. assertEquals(KeyFactory.keyToString(e.getKey()), flights.get(0).getId());
  807. assertEquals(KeyFactory.keyToString(e3.getKey()), flights.get(1).getId());
  808. // Same but using executeWithMap
  809. Query q2 = pm.newQuery("select from " + Flight.class.getName() + " where :p1.contains(name)");
  810. Map params = new HashMap();
  811. params.put("p1", Arrays.asList("name1", "name3"));
  812. List<Flight> flights2 = (List<Flight>) q2.executeWithMap(params);
  813. assertEquals(2, flights2.size());
  814. assertEquals(KeyFactory.keyToString(e.getKey()), flights2.get(0).getId());
  815. assertEquals(KeyFactory.keyToString(e3.getKey()), flights2.get(1).getId());
  816. q = pm.newQuery("select from " + Flight.class.getName() + " where :p1.contains(dest)");
  817. flights = (List<Flight>) q.execute(Arrays.asList(null, "mia1"));
  818. assertEquals(2, flights.size());
  819. assertEquals(KeyFactory.keyToString(e2.getKey()), flights.get(0).getId());
  820. assertEquals(KeyFactory.keyToString(e.getKey()), flights.get(1).getId());
  821. q = pm.newQuery("select from " + Flight.class.getName() + " where :p1.contains(dest) || :p2.contains(dest)");
  822. flights = (List<Flight>) q.execute(Arrays.asList(null, "mia1"), Arrays.asList("mia2"));
  823. assertEquals(3, flights.size());
  824. assertEquals(KeyFactory.keyToString(e2.getKey()), flights.get(0).getId());
  825. assertEquals(KeyFactory.keyToString(e.getKey()), flights.get(1).getId());
  826. assertEquals(KeyFactory.keyToString(e3.getKey()), flights.get(2).getId());
  827. }
  828. public void testContainsOnlyForCollection() {
  829. Entity e = Flight.newFlightEntity("name1", "bos1", "mia1", 23, 24);
  830. Entity e2 = Flight.newFlightEntity("name2", "bos2", null, 25, 26);
  831. Entity e3 = Flight.newFlightEntity("name3", "bos3", "mia2", 27, 28);
  832. ds.put(null, Arrays.asList(e, e2, e3));
  833. try {
  834. Query q = pm.newQuery("select from " + Flight.class.getName() + " where name.contains(:param)");
  835. q.addExtension(DatastoreManager.QUERYEXT_INMEMORY_WHEN_UNSUPPORTED, "false");
  836. q.execute("na");
  837. fail("Should have thrown an exception when invoking 'contains' on a String");
  838. } catch (JDOUserException ue) {
  839. // Expected
  840. }
  841. }
  842. public void testMultipleIn_Params() {
  843. Entity e = Flight.newFlightEntity("name1", "mia1", "bos1", 23, 24);
  844. Entity e2 = Flight.newFlightEntity("name2", "mia2", "bos2", 25, 26);
  845. Entity e3 = Flight.newFlightEntity("name3", "mia3", "bos3", 27, 28);
  846. ds.put(null, Arrays.asList(e, e2, e3));
  847. Query q = pm.newQuery("select from " + Flight.class.getName() + " where :p1.contains(name) && :p2.contains(origin)");
  848. List<Flight> flights =
  849. (List<Flight>) q.execute(Utils.newArrayList("name1", "name3"), Utils.newArrayList("mia3", "mia2"));
  850. assertEquals(1, flights.size());
  851. assertEquals(KeyFactory.keyToString(e3.getKey()), flights.get(0).getId());
  852. q = pm.newQuery("select from " + Flight.class.getName() + " where :p1.contains(name) || :p2.contains(name)");
  853. flights =
  854. (List<Flight>) q.execute(Utils.newArrayList("name1", "name3"), Utils.newArrayList("name4", "name5"));
  855. assertEquals(2, flights.size());
  856. assertEquals(KeyFactory.keyToString(e.getKey()), flights.get(0).getId());
  857. assertEquals(KeyFactory.keyToString(e3.getKey()), flights.get(1).getId());
  858. }
  859. public void testMultipleIn_Params_KeyFilter() {
  860. Entity e = Flight.newFlightEntity("name1", "mia1", "bos1", 23, 24);
  861. Entity e2 = Flight.newFlightEntity("name2", "mia2", "bos2", 25, 26);
  862. Entity e3 = Flight.newFlightEntity("name3", "mia3", "bos3", 27, 28);
  863. ds.put(null, Arrays.asList(e, e2, e3));
  864. Query q = pm.newQuery(
  865. "select from " + Flight.class.getName() + " where :p1.contains(id) && :p2.contains(origin)");
  866. @SuppressWarnings("unchecked")
  867. List<Flight> flights = (List<Flight>) q.execute(
  868. Utils.newArrayList(KeyFactory.keyToString(e2.getKey())), Utils.newArrayList("mia3", "mia2"));
  869. assertEquals(1, flights.size());
  870. assertEquals(KeyFactory.keyToString(e2.getKey()), flights.get(0).getId());
  871. q = pm.newQuery(
  872. "select from " + Flight.class.getName() + " where (id == :p1 || id ==:p2) && :p3.contains(origin)");
  873. @SuppressWarnings("unchecked")
  874. List<Flight> flights2 = (List<Flight>) q.execute(
  875. e2.getKey(), e3.getKey(), Utils.newArrayList("mia3", "dne"));
  876. assertEquals(1, flights2.size());
  877. }
  878. public void testOr_Literals() {
  879. Entity e = Flight.newFlightEntity("name1", "bos1", "mia1", 23, 24);
  880. Entity e2 = Flight.newFlightEntity("name2", "bos2", null, 25, 26);
  881. Entity e3 = Flight.newFlightEntity("name3", "bos3", "mia2", 27, 28);
  882. ds.put(null, Arrays.asList(e, e2, e3));
  883. Query q = pm.newQuery("select from " + Flight.class.getName() +
  884. " where name == 'name1' || name == 'name3'");
  885. List<Flight> flights = (List<Flight>) q.execute();
  886. assertEquals(2, flights.size());
  887. assertEquals(KeyFactory.keyToString(e.getKey()), flights.get(0).getId());
  888. assertEquals(KeyFactory.keyToString(e3.getKey()), flights.get(1).getId());
  889. q = pm.newQuery("select from " + Flight.class.getName() +
  890. " where dest == null || dest == 'mia1'");
  891. flights = (List<Flight>) q.execute();
  892. assertEquals(2, flights.size());
  893. assertEquals(KeyFactory.keyToString(e2.getKey()), flights.get(0).getId());
  894. assertEquals(KeyFactory.keyToString(e.getKey()), flights.get(1).getId());
  895. }
  896. public void testOr_Params() {
  897. Entity e = Flight.newFlightEntity("name1", "bos1", "mia1", 23, 24);
  898. Entity e2 = Flight.newFlightEntity("name2", "bos2", "mia2", 25, 26);
  899. Entity e3 = Flight.newFlightEntity("name3", "bos3", "mia3", 27, 28);
  900. ds.put(null, Arrays.asList(e, e2, e3));
  901. Query q = pm.newQuery("select from " + Flight.class.getName() +
  902. " where name == :p1 || name == :p2");
  903. List<Flight> flights = (List<Flight>) q.execute("name1", "name3");
  904. assertEquals(2, flights.size());
  905. assertEquals(KeyFactory.keyToString(e.getKey()), flights.get(0).getId());
  906. assertEquals(KeyFactory.keyToString(e3.getKey()), flights.get(1).getId());
  907. }
  908. public void testMultipleOr_Literals() {
  909. Entity e = Flight.newFlightEntity("name1", "bos1", "mia1", 23, 24);
  910. Entity e2 = Flight.newFlightEntity("name2", "bos2", "mia2", 25, 26);
  911. Entity e3 = Flight.newFlightEntity("name3", "bos3", "mia3", 27, 28);
  912. ds.put(null, Arrays.asList(e, e2, e3));
  913. Query q = pm.newQuery("select from " + Flight.class.getName() + " where "
  914. + "(name == 'name1' || name == 'name3') && "
  915. + "(origin == 'bos3' || origin == 'bos2')");
  916. List<Flight> flights = (List<Flight>) q.execute();
  917. assertEquals(1, flights.size());
  918. assertEquals(KeyFactory.keyToString(e3.getKey()), flights.get(0).getId());
  919. }
  920. public void testMultipleOr_Params() {
  921. Entity e = Flight.newFlightEntity("name1", "bos1", "mia1", 23, 24);
  922. Entity e2 = Flight.newFlightEntity("name2", "bos2", "mia2", 25, 26);
  923. Entity e3 = Flight.newFlightEntity("name3", "bos3", "mia3", 27, 28);
  924. ds.put(null, Arrays.asList(e, e2, e3));
  925. Query q = pm.newQuery("select from " + Flight.class.getName() + " where "
  926. + "(name == :p1 || name == :p2) && "
  927. + "(origin == :p3 || origin == :p4)");
  928. Map<String, String> paramMap = Utils.newHashMap();
  929. paramMap.put("p1", "name1");
  930. paramMap.put("p2", "name3");
  931. paramMap.put("p3", "bos3");
  932. paramMap.put("p4", "bos2");
  933. List<Flight> flights = (List<Flight>) q.executeWithMap(paramMap);
  934. assertEquals(1, flights.size());
  935. assertEquals(KeyFactory.keyToString(e3.getKey()), flights.get(0).getId());
  936. }
  937. public void testExecuteWithArray() {
  938. Entity e = Flight.newFlightEntity("name1", "bos1", "mia1", 23, 24);
  939. Entity e2 = Flight.newFlightEntity("name2", "bos2", "mia2", 25, 26);
  940. Entity e3 = Flight.newFlightEntity("name3", "bos3", "mia3", 27, 28);
  941. ds.put(null, Arrays.asList(e, e2, e3));
  942. Query q = pm.newQuery("select from " + Flight.class.getName() + " where "
  943. + "(name == :p1 || name == :p2) && "
  944. + "(origin == :p3 || origin == :p4)");
  945. Map<String, String> paramMap = Utils.newHashMap();
  946. paramMap.put("p1", "name1");
  947. paramMap.put("p2", "name3");
  948. paramMap.put("p3", "bos3");
  949. paramMap.put("p4", "bos2");
  950. List<Flight> flights = (List<Flight>) q.executeWithArray("name1", "name3", "bos3", "bos2");
  951. assertEquals(1, flights.size());
  952. assertEquals(KeyFactory.keyToString(e3.getKey()), flights.get(0).getId());
  953. }
  954. public void testIsNullChild() {
  955. Entity e = new Entity(HasOneToOneJDO.class.getSimpleName());
  956. ds.put(null, e);
  957. Query q = pm.newQuery("select from " + HasOneToOneJDO.class.getName() + " where flight == null");
  958. q.addExtension(DatastoreManager.QUERYEXT_INMEMORY_WHEN_UNSUPPORTED, "false");
  959. try {
  960. q.execute();
  961. fail("expected");
  962. } catch (JDOFatalUserException ex) {
  963. // good
  964. }
  965. }
  966. public void testIsNullParent() {
  967. Entity e = new Entity(HasOneToOneJDO.class.getSimpleName());
  968. Key key = ds.put(null, e);
  969. e = new Entity(HasOneToOneParentJDO.class.getSimpleName(), key);
  970. ds.put(null, e);
  971. Query q = pm.newQuery(
  972. "select from " + HasOneToOneParentJDO.class.getName() + " where parent == null");
  973. q.addExtension(DatastoreManager.QUERYEXT_INMEMORY_WHEN_UNSUPPORTED, "false");
  974. try {
  975. q.execute();
  976. fail("expected");
  977. } catch (JDOFatalUserException ex) {
  978. // good
  979. }
  980. }
  981. private void testFilterByChildObject_AdditionalFilterOnParent(FlightProvider fp) {
  982. Entity parentEntity = new Entity(HasOneToOneJDO.class.getSimpleName());
  983. ds.put(null, parentEntity);
  984. Entity flightEntity = newFlightEntity(parentEntity.getKey(), null, "f", "bos", "mia", 2, 4, 33);
  985. ds.put(null, flightEntity);
  986. Flight flight = fp.getFlight(flightEntity.getKey());
  987. Query q = pm.newQuery(
  988. "select from " + HasOneToOneJDO.class.getName()
  989. + " where id == parentId && flight == f "
  990. + "parameters String parentId, " + Flight.class.getName() + " f");
  991. List<HasOneToOneJDO> result = (List<HasOneToOneJDO>) q.execute(KeyFactory.keyToString(flightEntity.getKey()), flight);
  992. assertTrue(result.isEmpty());
  993. result = (List<HasOneToOneJDO>) q.execute(KeyFactory.keyToString(parentEntity.getKey()), flight);
  994. assertEquals(1, result.size());
  995. assertEquals(parentEntity.getKey(), KeyFactory.stringToKey(result.get(0).getId()));
  996. }
  997. public void testFilterByChildObject_AdditionalFilterOnParent() {
  998. testFilterByChildObject_AdditionalFilterOnParent(new AttachedFlightProvider());
  999. commitTxn();
  1000. beginTxn();
  1001. testFilterByChildObject_AdditionalFilterOnParent(new TransientFlightProvider());
  1002. }
  1003. private void testFilterByChildObject_UnsupportedOperator(FlightProvider fp) {
  1004. Entity parentEntity = new Entity(HasOneToOneJDO.class.getSimpleName());
  1005. ds.put(null, parentEntity);
  1006. Entity flightEntity = newFlightEntity(parentEntity.getKey(), null, "f", "bos", "mia", 2, 4, 33);
  1007. ds.put(null, flightEntity);
  1008. Flight flight = fp.getFlight(flightEntity.getKey());
  1009. Query q = pm.newQuery(
  1010. "select from " + HasOneToOneJDO.class.getName()
  1011. + " where flight > f parameters " + Flight.class.getName() + " f");
  1012. q.addExtension(DatastoreManager.QUERYEXT_INMEMORY_WHEN_UNSUPPORTED, "false");
  1013. try {
  1014. q.execute(flight);
  1015. fail("expected udfe");
  1016. } catch (JDOUserException jdoe) {
  1017. if (jdoe.getCause() instanceof DatastoreQuery.UnsupportedDatastoreFeatureException) {
  1018. // good
  1019. }
  1020. else {
  1021. throw jdoe;
  1022. }
  1023. }
  1024. }
  1025. public void testFilterByChildObject_UnsupportedOperator() {
  1026. testFilterByChildObject_UnsupportedOperator(new AttachedFlightProvider());
  1027. commitTxn();
  1028. beginTxn();
  1029. testFilterByChildObject_UnsupportedOperator(new TransientFlightProvider());
  1030. }
  1031. private void testFilterByChildObject_ValueWithoutAncestor(FlightProvider fp) {
  1032. Entity parentEntity = new Entity(HasOneToOneJDO.class.getSimpleName());
  1033. ds.put(null, parentEntity);
  1034. Entity flightEntity = newFlightEntity("f", "bos", "mia", 2, 4, 33);
  1035. ds.put(null, flightEntity);
  1036. Flight flight = fp.getFlight(flightEntity.getKey());
  1037. Query q = pm.newQuery(
  1038. "select from " + HasOneToOneJDO.class.getName()
  1039. + " where flight == f parameters " + Flight.class.getName() + " f");
  1040. q.addExtension(DatastoreManager.QUERYEXT_INMEMORY_WHEN_UNSUPPORTED, "false");
  1041. try {
  1042. q.execute(flight);
  1043. fail("expected JDOException");
  1044. } catch (JDOException e) {
  1045. // good
  1046. }
  1047. }
  1048. public void testFilterByChildObject_ValueWithoutAncestor() {
  1049. testFilterByChildObject_ValueWithoutAncestor(new AttachedFlightProvider());
  1050. commitTxn();
  1051. beginTxn();
  1052. testFilterByChildObject_ValueWithoutAncestor(new TransientFlightProvider());
  1053. }
  1054. public void testFilterByChildObject_KeyIsWrongType() {
  1055. Entity parentEntity = new Entity(HasOneToOneJDO.class.getSimpleName());
  1056. ds.put(null, parentEntity);
  1057. Query q = pm.newQuery(
  1058. "select from " + HasOneToOneJDO.class.getName()
  1059. + " where flight == f parameters " + Flight.class.getName() + " f");
  1060. q.addExtension(DatastoreManager.QUERYEXT_INMEMORY_WHEN_UNSUPPORTED, "false");
  1061. try {
  1062. q.execute(parentEntity.getKey());
  1063. fail("expected JDOException");
  1064. } catch (JDOException e) {
  1065. // good
  1066. }
  1067. }
  1068. public void testFilterByChildObject_KeyParentIsWrongType() {
  1069. Key parent = KeyFactory.createKey("yar", 44);
  1070. Entity flightEntity = new Entity(Flight.class.getSimpleName(), parent);
  1071. Query q = pm.newQuery(
  1072. "select from " + HasOneToOneJDO.class.getName()
  1073. + " where flight == f parameters " + Flight.class.getName() + " f");
  1074. assertTrue(((Collection)q.execute(flightEntity.getKey())).isEmpty());
  1075. }
  1076. public void testFilterByChildObject_ValueWithoutId() {
  1077. Entity parentEntity = new Entity(HasOneToOneJDO.class.getSimpleName());
  1078. ds.put(null, parentEntity);
  1079. Entity flightEntity = newFlightEntity("f", "bos", "mia", 2, 4, 33);
  1080. ds.put(null, flightEntity);
  1081. Flight flight = new Flight();
  1082. Query q = pm.newQuery(
  1083. "select from " + HasOneToOneJDO.class.getName()
  1084. + " where flight == f parameters " + Flight.class.getName() + " f");
  1085. q.addExtension(DatastoreManager.QUERYEXT_INMEMORY_WHEN_UNSUPPORTED, "false");
  1086. try {
  1087. q.execute(flight);
  1088. fail("expected JDOException");
  1089. } catch (JDOException e) {
  1090. // good
  1091. }
  1092. }
  1093. public void testFilterByParentObject() {
  1094. Entity parentEntity = new Entity(HasOneToManyListJDO.class.getSimpleName());
  1095. ds.put(null, parentEntity);
  1096. Entity bidirEntity = new Entity(BidirectionalChildListJDO.class.getSimpleName(), parentEntity.getKey());
  1097. ds.put(null, bidirEntity);
  1098. Entity bidirEntity2 = new Entity(BidirectionalChildListJDO.class.getSimpleName(), parentEntity.getKey());
  1099. ds.put(null, bidirEntity2);
  1100. HasOneToManyListJDO parent =
  1101. pm.getObjectById(HasOneToManyListJDO.class, KeyFactory.keyToString(parentEntity.getKey()));
  1102. Query q = pm.newQuery(
  1103. "select from " + BidirectionalChildListJDO.class.getName()
  1104. + " where parent == p parameters " + HasOneToManyListJDO.class.getName() + " p");
  1105. List<BidirectionalChildListJDO> result = (List<BidirectionalChildListJDO>) q.execute(parent);
  1106. assertEquals(2, result.size());
  1107. assertEquals(bidirEntity.getKey(), KeyFactory.stringToKey(result.get(0).getId()));
  1108. assertEquals(bidirEntity2.getKey(), KeyFactory.stringToKey(result.get(1).getId()));
  1109. }
  1110. public void testFilterByParentLongObjectId() throws Exception {
  1111. Entity parentEntity = new Entity(HasOneToManyLongPkListJDO.class.getSimpleName());
  1112. ds.put(null, parentEntity);
  1113. Entity bidirEntity = new Entity(BidirectionalChildLongPkListJDO.class.getSimpleName(), parentEntity.getKey());
  1114. ds.put(null, bidirEntity);
  1115. Entity bidirEntity2 = new Entity(BidirectionalChildLongPkListJDO.class.getSimpleName(), parentEntity.getKey());
  1116. ds.put(null, bidirEntity2);
  1117. HasOneToManyLongPkListJDO parent =
  1118. pm.getObjectById(HasOneToManyLongPkListJDO.class, KeyFactory.keyToString(parentEntity.getKey()));
  1119. Query q = pm.newQuery(
  1120. "select from " + BidirectionalChildLongPkListJDO.class.getName()
  1121. + " where parent == p parameters long p");
  1122. List<BidirectionalChildLongPkListJDO> result =
  1123. (List<BidirectionalChildLongPkListJDO>) q.execute(parent.getId());
  1124. assertEquals(2, result.size());
  1125. assertEquals(bidirEntity.getKey(), KeyFactory.stringToKey(result.get(0).getId()));
  1126. assertEquals(bidirEntity2.getKey(), KeyFactory.stringToKey(result.get(1).getId()));
  1127. }
  1128. public void testFilterByParentIntObjectId() {
  1129. Entity parentEntity = new Entity(HasOneToManyLongPkListJDO.class.getSimpleName());
  1130. ds.put(null, parentEntity);
  1131. Entity bidirEntity = new Entity(BidirectionalChildLongPkListJDO.class.getSimpleName(), parentEntity.getKey());
  1132. ds.put(null, bidirEntity);
  1133. Entity bidirEntity2 = new Entity(BidirectionalChildLongPkListJDO.class.getSimpleName(), parentEntity.getKey());
  1134. ds.put(null, bidirEntity2);
  1135. HasOneToManyLongPkListJDO parent =
  1136. pm.getObjectById(HasOneToManyLongPkListJDO.class, KeyFactory.keyToString(parentEntity.getKey()));
  1137. Query q = pm.newQuery(
  1138. "select from " + BidirectionalChildLongPkListJDO.class.getName()
  1139. + " where parent == p parameters int p");
  1140. List<BidirectionalChildLongPkListJDO> result =
  1141. (List<BidirectionalChildLongPkListJDO>) q.execute(parent.getId().intValue());
  1142. assertEquals(2, result.size());
  1143. assertEquals(bidirEntity.getKey(), KeyFactory.stringToKey(result.get(0).getId()));
  1144. assertEquals(bidirEntity2.getKey(), KeyFactory.stringToKey(result.get(1).getId()));
  1145. }
  1146. public void testFilterByParentObjectWhereParentIsAChild() {
  1147. Entity parentEntity = new Entity(HasOneToManyListJDO.class.getSimpleName());
  1148. ds.put(null, parentEntity);
  1149. Entity childEntity = new Entity(BidirectionalChildListJDO.class.getSimpleName(), parentEntity.getKey());
  1150. ds.put(null, childEntity);
  1151. Entity grandChildEntity1 =
  1152. new Entity(BidirectionalGrandchildListJDO.class.getSimpleName(), childEntity.getKey());
  1153. ds.put(null, grandChildEntity1);
  1154. Entity grandChildEntity2 =
  1155. new Entity(BidirectionalGrandchildListJDO.class.getSimpleName(), childEntity.getKey());
  1156. ds.put(null, grandChildEntity2);
  1157. BidirectionalChildListJDO child =
  1158. pm.getObjectById(BidirectionalChildListJDO.class, KeyFactory.keyToString(childEntity.getKey()));
  1159. Query q = pm.newQuery(
  1160. "select from " + BidirectionalGrandchildListJDO.class.getName()
  1161. + " where parent == p parameters " + BidirectionalChildListJDO.class.getName() + " p");
  1162. List<BidirectionalGrandchildListJDO> result = (List<BidirectionalGrandchildListJDO>) q.execute(child);
  1163. assertEquals(2, result.size());
  1164. assertEquals(grandChildEntity1.getKey(), KeyFactory.stringToKey(result.get(0).getId()));
  1165. assertEquals(grandChildEntity2.getKey(), KeyFactory.stringToKey(result.get(1).getId()));
  1166. }
  1167. public void testFilterByMultiValueProperty() {
  1168. Entity entity = new Entity(HasMultiValuePropsJDO.class.getSimpleName());
  1169. entity.setProperty("strList", Utils.newArrayList("1", "2", "3"));
  1170. entity.setProperty("keyList",
  1171. Utils.newArrayList(KeyFactory.createKey("be", "bo"), KeyFactory.createKey("bo", "be")));
  1172. ds.put(null, entity);
  1173. Query q = pm.newQuery(
  1174. "select from " + HasMultiValuePropsJDO.class.getName()
  1175. + " where strList == p1 && strList == p2 parameters String p1, String p2");
  1176. List<HasMultiValuePropsJDO> result = (List<HasMultiValuePropsJDO>) q.execute("1", "3");
  1177. assertEquals(1, result.size());
  1178. result = (List<HasMultiValuePropsJDO>) q.execute("1", "4");
  1179. assertEquals(0, result.size());
  1180. q = pm.newQuery(
  1181. "select from " + HasMultiValuePropsJDO.class.getName()
  1182. + " where keyList == p1 && keyList == p2 parameters " + Key.class.getName() + " p1, "
  1183. + Key.class.getName() + " p2");
  1184. result = (List<HasMultiValuePropsJDO>) q.execute(KeyFactory.createKey("be", "bo"), KeyFactory.createKey("bo", "be"));
  1185. assertEquals(1, result.size());
  1186. result = (List<HasMultiValuePropsJDO>) q.execute(KeyFactory.createKey("be", "bo"), KeyFactory.createKey("bo", "be2"));
  1187. assertEquals(0, result.size());
  1188. }
  1189. public void testNoPutsAfterLoadingMultiValueProperty() throws NoSuchMethodException {
  1190. commitTxn();
  1191. switchDatasource(PersistenceManagerFactoryName.nontransactional);
  1192. testFilterByMultiValueProperty();
  1193. pm.close();
  1194. }
  1195. public void testFilterByMultiValueProperty_ContainsWithParam() {
  1196. Entity entity = new Entity(HasMultiValuePropsJDO.class.getSimpleName());
  1197. entity.setProperty("strList", Utils.newArrayList("1", "2", "3"));
  1198. entity.setProperty("keyList",
  1199. Utils.newArrayList(KeyFactory.createKey("be", "bo"), KeyFactory.createKey("bo", "be")));
  1200. ds.put(null, entity);
  1201. Query q = pm.newQuery(
  1202. "select from " + HasMultiValuePropsJDO.class.getName()
  1203. + " where strList.contains(p1) parameters String p1");
  1204. List<HasMultiValuePropsJDO> result = (List<HasMultiValuePropsJDO>) q.execute("1");
  1205. assertEquals(1, result.size());
  1206. result = (List<HasMultiValuePropsJDO>) q.execute("4");
  1207. assertEquals(0, result.size());
  1208. q = pm.newQuery(
  1209. "select from " + HasMultiValuePropsJDO.class.getName()
  1210. + " where keyList.contains(p1) && keyList.contains(p2) parameters "
  1211. + Key.class.getName() + " p1, " + Key.class.getName() + " p2");
  1212. result = (List<HasMultiValuePropsJDO>) q.execute(KeyFactory.createKey("be", "bo"), KeyFactory.createKey("bo", "be"));
  1213. assertEquals(1, result.size());
  1214. result = (List<HasMultiValuePropsJDO>) q.execute(KeyFactory.createKey("be", "bo"), KeyFactory.createKey("bo", "be2"));
  1215. assertEquals(0, result.size());
  1216. }
  1217. public void testFilterByMultiValueProperty_ContainsWithImplicitParam() {
  1218. Entity entity = new Entity(HasMultiValuePropsJDO.class.getSimpleName());
  1219. entity.setProperty("strList", Utils.newArrayList("1", "2", "3"));
  1220. entity.setProperty("keyList",
  1221. Utils.newArrayList(KeyFactory.createKey("be", "bo"), KeyFactory.createKey("bo", "be")));
  1222. ds.put(null, entity);
  1223. Query q = pm.newQuery(
  1224. "select from " + HasMultiValuePropsJDO.class.getName()
  1225. + " where strList.contains(:p)");
  1226. List<HasMultiValuePropsJDO> result = (List<HasMultiValuePropsJDO>) q.execute("1");
  1227. assertEquals(1, result.size());
  1228. result = (List<HasMultiValuePropsJDO>) q.execute("4");
  1229. assertEquals(0, result.size());
  1230. q = pm.newQuery(
  1231. "select from " + HasMultiValuePropsJDO.class.getName()
  1232. + " where keyList.contains(:p1) && keyList.contains(:p2)");
  1233. result = (List<HasMultiValuePropsJDO>) q.execute(KeyFactory.createKey("be", "bo"), KeyFactory.createKey("bo", "be"));
  1234. assertEquals(1, result.size());
  1235. result = (List<HasMultiValuePropsJDO>) q.execute(KeyFactory.createKey("be", "bo"), KeyFactory.createKey("bo", "be2"));
  1236. assertEquals(0, result.size());
  1237. }
  1238. public void testFilterByMultiValueProperty_ContainsWithLiteralString() {
  1239. Entity entity = new Entity(HasMultiValuePropsJDO.class.getSimpleName());
  1240. entity.setProperty("strList", Utils.newArrayList("1", "2", "3"));
  1241. ds.put(null, entity);
  1242. Query q = pm.newQuery(
  1243. "select from " + HasMultiValuePropsJDO.class.getName()
  1244. + " where strList.contains(\"1\")");
  1245. List<HasMultiValuePropsJDO> result = (List<HasMultiValuePropsJDO>) q.execute();
  1246. assertEquals(1, result.size());
  1247. }
  1248. public void testFilterByEmbeddedField() {
  1249. Entity entity = new Entity(Person.class.getSimpleName());
  1250. entity.setProperty("first", "max");
  1251. entity.setProperty("last", "ross");
  1252. entity.setProperty("anotherFirst", "notmax");
  1253. entity.setProperty("anotherLast", "notross");
  1254. ds.put(null, entity);
  1255. Query q = pm.newQuery(
  1256. "select from " + Person.class.getName()
  1257. + " where name.first == \"max\"");
  1258. @SuppressWarnings("unchecked")
  1259. List<Person> result = (List<Person>) q.execute();
  1260. assertEquals(1, result.size());
  1261. }
  1262. public void testFilterByEmbeddedField_2LevelsDeep() {
  1263. Entity entity = new Entity(HasEmbeddedJDO.class.getSimpleName());
  1264. entity.setProperty("val1", "v1");
  1265. entity.setProperty("val2", "v2");
  1266. ds.put(null, entity);
  1267. Query q = pm.newQuery(
  1268. "select from " + HasEmbeddedJDO.class.getName()
  1269. + " where embedded1.embedded2.val2 == \"v2\"");
  1270. @SuppressWarnings("unchecked")
  1271. List<HasEmbeddedJDO> result = (List<HasEmbeddedJDO>) q.execute();
  1272. assertEquals(1, result.size());
  1273. }
  1274. public void testFilterByEmbeddedField_OverriddenColumn() {
  1275. Entity entity = new Entity(Person.class.getSimpleName());
  1276. entity.setProperty("first", "max");
  1277. entity.setProperty("last", "ross");
  1278. entity.setProperty("anotherFirst", "notmax");
  1279. entity.setProperty("anotherLast", "notross");
  1280. ds.put(null, entity);
  1281. Query q = pm.newQuery(
  1282. "select from " + Person.class.getName()
  1283. + " where anotherName.last == \"notross\"");
  1284. @SuppressWarnings("unchecked")
  1285. List<Person> result = (List<Person>) q.execute();
  1286. assertEquals(1, result.size());
  1287. }
  1288. public void testFilterByEmbeddedField_MultipleFields() {
  1289. Entity entity = new Entity(Person.class.getSimpleName());
  1290. entity.setProperty("first", "max");
  1291. entity.setProperty("last", "ross");
  1292. entity.setProperty("anotherFirst", "max");
  1293. entity.setProperty("anotherLast", "notross");
  1294. ds.put(null, entity);
  1295. Query q = pm.newQuery(
  1296. "select from " + Person.class.getName()
  1297. + " where name.first == \"max\" && anotherName.last == \"notross\"");
  1298. @SuppressWarnings("unchecked")
  1299. List<Person> result = (List<Person>) q.execute();
  1300. assertEquals(1, result.size());
  1301. }
  1302. public void testFilterBySubObject_UnknownField() {
  1303. try {
  1304. Query q = pm.newQuery(
  1305. "select from " + Flight.class.getName() + " where origin.doesnotexist == \"max\"");
  1306. q.addExtension(DatastoreManager.QUERYEXT_INMEMORY_WHEN_UNSUPPORTED, "false");
  1307. q.execute();
  1308. fail("expected exception");
  1309. } catch (JDOFatalUserException e) {
  1310. // good
  1311. }
  1312. }
  1313. public void testFilterBySubObject_NotEmbeddable() {
  1314. try {
  1315. Query q = pm.newQuery(
  1316. "select from " + HasOneToOneJDO.class.getName() + " where flight.origin == \"max\"");
  1317. q.addExtension(DatastoreManager.QUERYEXT_INMEMORY_WHEN_UNSUPPORTED, "false");
  1318. q.execute();
  1319. fail("expected exception");
  1320. } catch (JDOFatalUserException e) {
  1321. // good
  1322. }
  1323. }
  1324. public void testSortByEmbeddedField() {
  1325. Entity entity = new Entity(Person.class.getSimpleName());
  1326. entity.setProperty("first", "max");
  1327. entity.setProperty("last", "ross");
  1328. entity.setProperty("anotherFirst", "notmax");
  1329. entity.setProperty("anotherLast", "notross");
  1330. ds.put(null, entity);
  1331. entity = new Entity(Person.class.getSimpleName());
  1332. entity.setProperty("first", "max2");
  1333. entity.setProperty("last", "ross2");
  1334. entity.setProperty("anotherFirst", "notmax2");
  1335. entity.setProperty("anotherLast", "notross2");
  1336. ds.put(null, entity);
  1337. Query q = pm.newQuery(
  1338. "select from " + Person.class.getName() + " order by name.first desc");
  1339. @SuppressWarnings("unchecked")
  1340. List<Person> result = (List<Person>) q.execute();
  1341. assertEquals(2, result.size());
  1342. assertEquals("max2", result.get(0).getName().getFirst());
  1343. assertEquals("max", result.get(1).getName().getFirst());
  1344. }
  1345. public void testSortByEmbeddedField_OverriddenColumn() {
  1346. Entity entity = new Entity(Person.class.getSimpleName());
  1347. entity.setProperty("first", "max");
  1348. entity.setProperty("last", "ross");
  1349. entity.setProperty("anotherFirst", "notmax");
  1350. entity.setProperty("anotherLast", "notross");
  1351. ds.put(null, entity);
  1352. entity = new Entity(Person.class.getSimpleName());
  1353. entity.setProperty("first", "max2");
  1354. entity.setProperty("last", "ross2");
  1355. entity.setProperty("anotherFirst", "notmax2");
  1356. entity.setProperty("anotherLast", "notross2");
  1357. ds.put(null, entity);
  1358. Query q =
  1359. pm.newQuery("select from " + Person.class.getName() + " order by anotherName.last desc");
  1360. @SuppressWarnings("unchecked")
  1361. List<Person> result = (List<Person>) q.execute();
  1362. assertEquals(2, result.size());
  1363. assertEquals("notross2", result.get(0).getAnotherName().getLast());
  1364. assertEquals("notross", result.get(1).getAnotherName().getLast());
  1365. }
  1366. public void testSortByEmbeddedField_MultipleFields() {
  1367. Entity entity0 = new Entity(Person.class.getSimpleName());
  1368. entity0.setProperty("first", "max");
  1369. entity0.setProperty("last", "ross");
  1370. entity0.setProperty("anotherFirst", "notmax");
  1371. entity0.setProperty("anotherLast", "z");
  1372. ds.put(null, entity0);
  1373. Entity entity1 = new Entity(Person.class.getSimpleName());
  1374. entity1.setProperty("first", "max");
  1375. entity1.setProperty("last", "ross2");
  1376. entity1.setProperty("anotherFirst", "notmax2");
  1377. entity1.setProperty("anotherLast", "notross2");
  1378. ds.put(null, entity1);
  1379. Entity entity2 = new Entity(Person.class.getSimpleName());
  1380. entity2.setProperty("first", "a");
  1381. entity2.setProperty("last", "b");
  1382. entity2.setProperty("anotherFirst", "c");
  1383. entity2.setProperty("anotherLast", "d");
  1384. ds.put(null, entity2);
  1385. Query q = pm.newQuery(
  1386. "select from " + Person.class.getName() + " order by name.first asc, anotherName.last desc");
  1387. @SuppressWarnings("unchecked")
  1388. List<Person> result = (List<Person>) q.execute();
  1389. assertEquals(3, result.size());
  1390. assertEquals(Long.valueOf(entity2.getKey().getId()), result.get(0).getId());
  1391. assertEquals(Long.valueOf(entity0.getKey().getId()), result.get(1).getId());
  1392. assertEquals(Long.valueOf(entity1.getKey().getId()), result.get(2).getId());
  1393. }
  1394. public void testSortBySubObject_UnknownField() {
  1395. try {
  1396. Query q = pm.newQuery("select from " + Flight.class.getName() + " order by origin.first");
  1397. q.addExtension(DatastoreManager.QUERYEXT_INMEMORY_WHEN_UNSUPPORTED, "false");
  1398. q.execute();
  1399. fail("expected exception");
  1400. } catch (JDOFatalUserException e) {
  1401. // good
  1402. }
  1403. }
  1404. public void testSortBySubObject_NotEmbeddable() {
  1405. try {
  1406. Query q = pm.newQuery("select from " + HasOneToOneJDO.class.getName() + " order by flight.origin");
  1407. q.addExtension(DatastoreManager.QUERYEXT_INMEMORY_WHEN_UNSUPPORTED, "false");
  1408. q.execute();
  1409. fail("expected exception");
  1410. } catch (JDOFatalUserException e) {
  1411. // good
  1412. }
  1413. }
  1414. public void testUserQuery() {
  1415. Entity e = KitchenSink.newKitchenSinkEntity("blarg", null);
  1416. ds.put(null, e);
  1417. Query q = pm.newQuery(
  1418. "select from " + KitchenSink.class.getName() + " where userVal == u parameters " + User.class.getName() + " u");
  1419. @SuppressWarnings("unchecked")
  1420. List<KitchenSink> results = (List<KitchenSink>) q.execute(KitchenSink.USER1);
  1421. assertEquals(1, results.size());
  1422. Query q2 = pm.newQuery(KitchenSink.class, "userVal == u");
  1423. q2.declareParameters(User.class.getName() + " u");
  1424. @SuppressWarnings("unchecked")
  1425. List<KitchenSink> results2 = (List<KitchenSink>) q2.execute(KitchenSink.USER1);
  1426. assertEquals(1, results2.size());
  1427. }
  1428. public void testBigDecimalQuery() {
  1429. Entity e = KitchenSink.newKitchenSinkEntity("blarg", null);
  1430. ds.put(null, e);
  1431. Query q = pm.newQuery("select from " + KitchenSink.class.getName()
  1432. + " where bigDecimal == bd parameters " + BigDecimal.class.getName()
  1433. + " bd");
  1434. @SuppressWarnings("unchecked")
  1435. List<KitchenSink> results = (List<KitchenSink>) q.execute(
  1436. new BigDecimal("2.444"));
  1437. assertEquals(1, results.size());
  1438. }
  1439. public void testBigDecimalInequalityQuery() {
  1440. Entity e = KitchenSink.newKitchenSinkEntity("blarg", null);
  1441. ds.put(null, e);
  1442. Query q = pm.newQuery("select from " + KitchenSink.class.getName()
  1443. + " where bigDecimal > bd1 && bigDecimal < bd2 parameters "
  1444. + BigDecimal.class.getName() + " bd1, " + BigDecimal.class.getName()
  1445. + " bd2");
  1446. @SuppressWarnings("unchecked")
  1447. List<KitchenSink> results = (List<KitchenSink>) q.execute(
  1448. new BigDecimal("2"), new BigDecimal("3"));
  1449. assertEquals(1, results.size());
  1450. }
  1451. public void testQueryWithNegativeLiteralLong() {
  1452. ds.put(null, newFlightEntity("1", "yam", "bam", -1, 2));
  1453. Query q = pm.newQuery(
  1454. "select from " + Flight.class.getName() + " where you == -1");
  1455. @SuppressWarnings("unchecked")
  1456. List<Flight> results = (List<Flight>) q.execute();
  1457. assertEquals(1, results.size());
  1458. q = pm.newQuery(
  1459. "select from " + Flight.class.getName() + " where you > -2");
  1460. @SuppressWarnings("unchecked")
  1461. List<Flight> results2 = (List<Flight>) q.execute();
  1462. assertEquals(1, results2.size());
  1463. }
  1464. public void testQueryWithNegativeLiteralDouble() {
  1465. ds.put(null, KitchenSink.newKitchenSinkEntity("blarg", null));
  1466. Query q = pm.newQuery(
  1467. "select from " + KitchenSink.class.getName() + " where doubleVal > -2.25");
  1468. @SuppressWarnings("unchecked")
  1469. List<KitchenSink> results = (List<KitchenSink>) q.execute();
  1470. assertEquals(1, results.size());
  1471. }
  1472. public void testQueryWithNegativeParam() {
  1473. ds.put(null, newFlightEntity("1", "yam", "bam", -1, 2));
  1474. Query q = pm.newQuery(
  1475. "select from " + Flight.class.getName() + " where you == p parameters int p");
  1476. @SuppressWarnings("unchecked")
  1477. List<Flight> results = (List<Flight>) q.execute(-1);
  1478. assertEquals(1, results.size());
  1479. }
  1480. public void testKeyQueryWithUnencodedStringPk() {
  1481. Entity e = new Entity(HasUnencodedStringPkJDO.class.getSimpleName(), "yar");
  1482. ds.put(null, e);
  1483. Query q = pm.newQuery(
  1484. "select from " + HasUnencodedStringPkJDO.class.getName() + " where id == p parameters String p");
  1485. @SuppressWarnings("unchecked")
  1486. List<HasUnencodedStringPkJDO> results =
  1487. (List<HasUnencodedStringPkJDO>) q.execute(e.getKey().getName());
  1488. assertEquals(1, results.size());
  1489. assertEquals(e.getKey().getName(), results.get(0).getId());
  1490. q = pm.newQuery(
  1491. "select from " + HasUnencodedStringPkJDO.class.getName() + " where id == p parameters "
  1492. + Key.class.getName() + " p");
  1493. @SuppressWarnings("unchecked")
  1494. List<HasUnencodedStringPkJDO> results2 =
  1495. (List<HasUnencodedStringPkJDO>) q.execute(e.getKey());
  1496. assertEquals(1, results2.size());
  1497. assertEquals(e.getKey().getName(), results2.get(0).getId());
  1498. }
  1499. public void testKeyQueryWithLongPk() {
  1500. Entity e = new Entity(HasLongPkJDO.class.getSimpleName());
  1501. ds.put(null, e);
  1502. Query q = pm.newQuery(
  1503. "select from " + HasLongPkJDO.class.getName() + " where id == p parameters Long p");
  1504. @SuppressWarnings("unchecked")
  1505. List<HasLongPkJDO> results = (List<HasLongPkJDO>) q.execute(e.getKey().getId());
  1506. assertEquals(1, results.size());
  1507. assertEquals(Long.valueOf(e.getKey().getId()), results.get(0).getId());
  1508. q = pm.newQuery(
  1509. "select from " + HasLongPkJDO.class.getName() + " where id == p parameters "
  1510. + Key.class.getName() + " p");
  1511. @SuppressWarnings("unchecked")
  1512. List<HasLongPkJDO> results2 = (List<HasLongPkJDO>) q.execute(e.getKey().getId());
  1513. assertEquals(1, results2.size());
  1514. assertEquals(Long.valueOf(e.getKey().getId()), results2.get(0).getId());
  1515. }
  1516. public void testKeyQueryWithEncodedStringPk() {
  1517. Entity e = new Entity(HasEncodedStringPkJDO.class.getSimpleName(), "yar");
  1518. ds.put(null, e);
  1519. Query q = pm.newQuery(
  1520. "select from " + HasEncodedStringPkJDO.class.getName() + " where id == p parameters String p");
  1521. @SuppressWarnings("unchecked")
  1522. List<HasEncodedStringPkJDO> results =
  1523. (List<HasEncodedStringPkJDO>) q.execute(e.getKey().getName());
  1524. assertEquals(1, results.size());
  1525. assertEquals(KeyFactory.keyToString(e.getKey()), results.get(0).getId());
  1526. q = pm.newQuery(
  1527. "select from " + HasEncodedStringPkJDO.class.getName() + " where id == p parameters "
  1528. + Key.class.getName() + " p");
  1529. @SuppressWarnings("unchecked")
  1530. List<HasEncodedStringPkJDO> results2 =
  1531. (List<HasEncodedStringPkJDO>) q.execute(e.getKey());
  1532. assertEquals(1, results2.size());
  1533. assertEquals(KeyFactory.keyToString(e.getKey()), results2.get(0).getId());
  1534. q = pm.newQuery(
  1535. "select from " + HasEncodedStringPkJDO.class.getName() + " where id == p parameters String p");
  1536. @SuppressWarnings("unchecked")
  1537. List<HasEncodedStringPkJDO> results3 =
  1538. (List<HasEncodedStringPkJDO>) q.execute(e.getKey().getName());
  1539. assertEquals(1, results3.size());
  1540. assertEquals(KeyFactory.keyToString(e.getKey()), results3.get(0).getId());
  1541. }
  1542. public void testUniqueQuery_OneResult() {
  1543. Entity e = newFlightEntity("harold", "bos", "mia", 23, 24, 25);
  1544. ds.put(null, e);
  1545. Query q = pm.newQuery(
  1546. "select from " + Flight.class.getName() + " where you == p parameters Long p");
  1547. q.setUnique(true);
  1548. @SuppressWarnings("unchecked")
  1549. Flight result = (Flight) q.execute(23);
  1550. assertEquals(e.getKey(), KeyFactory.stringToKey(result.getId()));
  1551. }
  1552. public void testUniqueQuery_NoResult() {
  1553. Entity e = newFlightEntity("harold", "bos", "mia", 23, 24, 25);
  1554. ds.put(null, e);
  1555. Query q = pm.newQuery(
  1556. "select from " + Flight.class.getName() + " where you == p parameters Long p");
  1557. q.setUnique(true);
  1558. assertNull(q.execute(43));
  1559. }
  1560. public void testUniqueQuery_MultipleResults() {
  1561. Entity e1 = newFlightEntity("harold", "bos", "mia", 23, 24, 25);
  1562. Entity e2 = newFlightEntity("harold", "bos", "mia", 23, 24, 25);
  1563. ds.put(null, e1);
  1564. ds.put(null, e2);
  1565. Query q = pm.newQuery(
  1566. "select from " + Flight.class.getName() + " where you == p parameters Long p");
  1567. q.setUnique(true);
  1568. try {
  1569. q.execute(23);
  1570. fail("expected exception");
  1571. } catch (JDOUserException e) {
  1572. // good
  1573. }
  1574. }
  1575. public void testSortByUnknownProperty() {
  1576. try {
  1577. Query q = pm.newQuery("select from " + Flight.class.getName() + " order by dne");
  1578. q.addExtension(DatastoreManager.QUERYEXT_INMEMORY_WHEN_UNSUPPORTED, "false");
  1579. q.execute();
  1580. fail("expected exception");
  1581. } catch (JDOFatalUserException e) {
  1582. // good
  1583. }
  1584. }
  1585. public void testSetOrdering() {
  1586. Entity e1 = newFlightEntity("harold", "bos", "mia", 23, 24, 25);
  1587. Entity e2 = newFlightEntity("harold", "bos", "mia", 33, 34, 35);
  1588. ds.put(null, e1);
  1589. ds.put(null, e2);
  1590. Query q = pm.newQuery(Flight.class);
  1591. q.setOrdering("you");
  1592. @SuppressWarnings("unchecked")
  1593. List<Flight> results = (List<Flight>) q.execute();
  1594. assertEquals(2, results.size());
  1595. Flight f1 = results.get(0);
  1596. Flight f2 = results.get(1);
  1597. assertEquals(KeyFactory.stringToKey(f2.getId()), e2.getKey());
  1598. assertEquals(KeyFactory.stringToKey(f1.getId()), e1.getKey());
  1599. }
  1600. public void testSize() {
  1601. for (int i = 0; i < 10; i++) {
  1602. Entity e = newFlightEntity("harold", "bos", "mia", 23, 24, 25);
  1603. ds.put(null, e);
  1604. }
  1605. Query q = pm.newQuery(Flight.class);
  1606. @SuppressWarnings("unchecked")
  1607. List<Flight> results = (List<Flight>) q.execute();
  1608. assertEquals(10, results.size());
  1609. }
  1610. public void testDatastoreFailureWhileIterating() {
  1611. // Need to have enough data to ensure a Next call
  1612. for (int i = 0; i < 21; i++) {
  1613. Entity e = newFlightEntity("harold", "bos", "mia", 23, 24, 25);
  1614. ds.put(null, e);
  1615. }
  1616. ExceptionThrowingDatastoreDelegate.ExceptionPolicy policy =
  1617. new ExceptionThrowingDatastoreDelegate.BaseExceptionPolicy() {
  1618. boolean exploded = false;
  1619. protected void doIntercept(String methodName) {
  1620. if (!exploded && methodName.equals("Next")) {
  1621. exploded = true;
  1622. throw new DatastoreFailureException("boom: " + methodName);
  1623. }
  1624. }
  1625. };
  1626. ExceptionThrowingDatastoreDelegate dd =
  1627. new ExceptionThrowingDatastoreDelegate(getDelegateForThread(), policy);
  1628. ApiProxy.Delegate original = getDelegateForThread();
  1629. setDelegateForThread(dd);
  1630. try {
  1631. Query q = pm.newQuery(Flight.class);
  1632. @SuppressWarnings("unchecked")
  1633. List<Flight> results = (List<Flight>) q.execute();
  1634. try {
  1635. results.size();
  1636. fail("expected exception");
  1637. } catch (JDODataStoreException e) {
  1638. // good
  1639. assertTrue(e.getCause() instanceof DatastoreFailureException);
  1640. }
  1641. } finally {
  1642. setDelegateForThread(original);
  1643. }
  1644. }
  1645. public void testBadRequest() {
  1646. ExceptionThrowingDatastoreDelegate.ExceptionPolicy policy =
  1647. new ExceptionThrowingDatastoreDelegate.BaseExceptionPolicy() {
  1648. int count = 0;
  1649. protected void doIntercept(String methodName) {
  1650. count++;
  1651. if (count == 1) {
  1652. throw new IllegalArgumentException("boom");
  1653. }
  1654. }
  1655. };
  1656. ExceptionThrowingDatastoreDelegate dd =
  1657. new ExceptionThrowingDatastoreDelegate(getDelegateForThread(), policy);
  1658. ApiProxy.Delegate original = getDelegateForThread();
  1659. setDelegateForThread(dd);
  1660. try {
  1661. Query q = pm.newQuery(Flight.class);
  1662. try {
  1663. q.execute();
  1664. fail("expected exception");
  1665. } catch (JDOFatalUserException e) {
  1666. // good
  1667. assertTrue(e.getCause() instanceof IllegalArgumentException);
  1668. }
  1669. } finally {
  1670. setDelegateForThread(original);
  1671. }
  1672. }
  1673. public void testCountQuery_SetResult() {
  1674. Entity e1 = newFlightEntity("harold", "bos", "mia", 23, 24, 25);
  1675. Entity e2 = newFlightEntity("harold", "bos", "mia", 33, 34, 35);
  1676. ds.put(null, e1);
  1677. ds.put(null, e2);
  1678. Query q = pm.newQuery(Flight.class);
  1679. q.setResult("count(id)");
  1680. Object val = q.execute();
  1681. assertEquals(2l, val);
  1682. }
  1683. public void testCountQuery_SingleString() {
  1684. Entity e1 = newFlightEntity("harold", "bos", "mia", 23, 24, 25);
  1685. Entity e2 = newFlightEntity("harold", "bos", "mia", 33, 34, 35);
  1686. ds.put(null, e1);
  1687. ds.put(null, e2);
  1688. Query q = pm.newQuery("select count(id) from " + Flight.class.getName());
  1689. assertEquals(2l, q.execute());
  1690. q = pm.newQuery("select COUNT(id) from " + Flight.class.getName());
  1691. assertEquals(2l, q.execute());
  1692. }
  1693. public void testMaxQuery_SingleString() {
  1694. Entity e1 = newFlightEntity("harold", "bos", "mia", 23, 24, 25);
  1695. Entity e2 = newFlightEntity("harold", "bos", "mia", 33, 34, 35);
  1696. ds.put(null, e1);
  1697. ds.put(null, e2);
  1698. Query q = pm.newQuery("select max(me) from " + Flight.class.getName());
  1699. q.addExtension(DatastoreManager.QUERYEXT_INMEMORY_WHEN_UNSUPPORTED, "true");
  1700. assertEquals(34, q.execute());
  1701. }
  1702. public void testCountQueryWithFilter_SingleString() {
  1703. Entity e1 = newFlightEntity("harold", "bos", "mia", 23, 24, 25);
  1704. Entity e2 = newFlightEntity("harold", "bos", "mia", 33, 34, 35);
  1705. ds.put(null, e1);
  1706. ds.put(null, e2);
  1707. Query q = pm.newQuery("select count(id) from " + Flight.class.getName() + " where you == 23");
  1708. assertEquals(1l, q.execute());
  1709. }
  1710. public void testCountQueryWithUnknownCountProp_SingleString() {
  1711. Entity e1 = newFlightEntity("harold", "bos", "mia", 23, 24, 25);
  1712. Entity e2 = newFlightEntity("harold", "bos", "mia", 33, 34, 35);
  1713. ds.put(null, e1);
  1714. ds.put(null, e2);
  1715. // letting this go through intentionally
  1716. // we may want to circle back and lock this down but for now it's really
  1717. // not a big deal
  1718. Query q = pm.newQuery("select count(doesnotexist) from " + Flight.class.getName());
  1719. assertEquals(2l, q.execute());
  1720. }
  1721. public void testCountQueryWithOffset() {
  1722. Entity e1 = newFlightEntity("harold", "bos", "mia", 23, 24, 25);
  1723. Entity e2 = newFlightEntity("harold", "bos", "mia", 33, 34, 35);
  1724. ds.put(null, e1);
  1725. ds.put(null, e2);
  1726. Query q = pm.newQuery("select count(id) from " + Flight.class.getName());
  1727. q.setRange(1, Long.MAX_VALUE);
  1728. assertEquals(1l, q.execute());
  1729. }
  1730. public void testCountQueryWithLimit() {
  1731. Entity e1 = newFlightEntity("harold", "bos", "mia", 23, 24, 25);
  1732. Entity e2 = newFlightEntity("harold", "bos", "mia", 33, 34, 35);
  1733. ds.put(null, e1);
  1734. ds.put(null, e2);
  1735. Query q = pm.newQuery("select count(id) from " + Flight.class.getName());
  1736. q.setRange(0, 1);
  1737. assertEquals(1l, q.execute());
  1738. }
  1739. public void testCountQueryWithOffsetAndLimit() {
  1740. Entity e1 = newFlightEntity("harold", "bos", "mia", 23, 24, 25);
  1741. Entity e2 = newFlightEntity("harold", "bos", "mia", 33, 34, 35);
  1742. Entity e3 = newFlightEntity("harold", "bos", "mia", 43, 44, 45);
  1743. ds.put(null, e1);
  1744. ds.put(null, e2);
  1745. ds.put(null, e3);
  1746. Query q = pm.newQuery("select count(id) from " + Flight.class.getName());
  1747. q.setRange(1, 2);
  1748. assertEquals(1l, q.execute());
  1749. }
  1750. public void testFilterByEnum_ProvideStringExplicitly() {
  1751. Entity e = new Entity(HasEnumJDO.class.getSimpleName());
  1752. e.setProperty("myEnum", HasEnumJDO.MyEnum.V1.name());
  1753. ds.put(null, e);
  1754. Query q = pm.newQuery("select from " + HasEnumJDO.class.getName() + " where myEnum == p1");
  1755. q.declareParameters(String.class.getName() + " p1");
  1756. List<HasEnumJDO> result = (List<HasEnumJDO>) q.execute(HasEnumJDO.MyEnum.V1.name());
  1757. assertEquals(1, result.size());
  1758. }
  1759. public void testFilterByEnum_ProvideEnumExplicitly() {
  1760. Entity e = new Entity(HasEnumJDO.class.getSimpleName());
  1761. e.setProperty("myEnum", HasEnumJDO.MyEnum.V1.name());
  1762. ds.put(null, e);
  1763. Query q = pm.newQuery("select from " + HasEnumJDO.class.getName() + " where myEnum == p1");
  1764. q.declareParameters(HasEnumJDO.MyEnum.class.getName() + " p1");
  1765. List<HasEnumJDO> result = (List<HasEnumJDO>) q.execute(HasEnumJDO.MyEnum.V1);
  1766. assertEquals(1, result.size());
  1767. }
  1768. public void testFilterByEnum_ProvideStringParameterInline() {
  1769. Entity e = new Entity(HasEnumJDO.class.getSimpleName());
  1770. e.setProperty("myEnum", HasEnumJDO.MyEnum.V1.name());
  1771. ds.put(null, e);
  1772. Query q = pm.newQuery("select from " + HasEnumJDO.class.getName() + " where myEnum == p1 parameters String p1");
  1773. List<HasEnumJDO> result = (List<HasEnumJDO>) q.execute(HasEnumJDO.MyEnum.V1.name());
  1774. assertEquals(1, result.size());
  1775. }
  1776. public void testFilterByEnum_ProvideEnumParameterInline() {
  1777. Entity e = new Entity(HasEnumJDO.class.getSimpleName());
  1778. e.setProperty("myEnum", HasEnumJDO.MyEnum.V1.name());
  1779. ds.put(null, e);
  1780. Query q = pm.newQuery("select from " + HasEnumJDO.class.getName() + " where myEnum == p1 parameters " + HasEnumJDO.MyEnum.class.getName() + " p1");
  1781. List<HasEnumJDO> result = (List<HasEnumJDO>) q.execute(HasEnumJDO.MyEnum.V1);
  1782. assertEquals(1, result.size());
  1783. }
  1784. public void testFilterByEnum_ProvideLiteral() {
  1785. Entity e = new Entity(HasEnumJDO.class.getSimpleName());
  1786. e.setProperty("myEnum", HasEnumJDO.MyEnum.V1.name());
  1787. ds.put(null, e);
  1788. Query q = pm.newQuery(
  1789. "select from " + HasEnumJDO.class.getName() + " where myEnum == '"
  1790. + HasEnumJDO.MyEnum.V1.name() + "'");
  1791. List<HasEnumJDO> result = (List<HasEnumJDO>) q.execute();
  1792. assertEquals(1, result.size());
  1793. }
  1794. public void testFilterByShortBlob() {
  1795. Entity e = new Entity(HasBytesJDO.class.getSimpleName());
  1796. e.setProperty("onePrimByte", 8L);
  1797. e.setProperty("shortBlob", new ShortBlob("short blob".getBytes()));
  1798. ds.put(null, e);
  1799. Query q = pm.newQuery("select from " + HasBytesJDO.class.getName() + " where shortBlob == p1");
  1800. q.declareParameters(ShortBlob.class.getName() + " p1");
  1801. List<HasBytesJDO> result =
  1802. (List<HasBytesJDO>) q.execute(new ShortBlob("short blob".getBytes()));
  1803. assertEquals(1, result.size());
  1804. }
  1805. public void testFilterByPrimitiveByteArray() {
  1806. Entity e = new Entity(HasBytesJDO.class.getSimpleName());
  1807. e.setProperty("onePrimByte", 8L);
  1808. e.setProperty("primBytes", new ShortBlob("short blob".getBytes()));
  1809. ds.put(null, e);
  1810. Query q = pm.newQuery("select from " + HasBytesJDO.class.getName() + " where primBytes == p1");
  1811. q.declareParameters("byte[] p1");
  1812. List<HasBytesJDO> result = (List<HasBytesJDO>) q.execute("short blob".getBytes());
  1813. assertEquals(1, result.size());
  1814. }
  1815. public void testFilterByByteArray() {
  1816. Entity e = new Entity(HasBytesJDO.class.getSimpleName());
  1817. e.setProperty("onePrimByte", 8L);
  1818. e.setProperty("bytes", new ShortBlob("short blob".getBytes()));
  1819. ds.put(null, e);
  1820. Query q = pm.newQuery("select from " + HasBytesJDO.class.getName() + " where bytes == p1");
  1821. q.declareParameters("Byte[] p1");
  1822. List<HasBytesJDO> result = (List<HasBytesJDO>) q.execute(
  1823. PrimitiveArrays.asList("short blob".getBytes()).toArray(new Byte[0]));
  1824. assertEquals(1, result.size());
  1825. }
  1826. public void testFilterByDate() {
  1827. Key key = ds.put(null, KitchenSink.newKitchenSinkEntity(null));
  1828. Query q = pm.newQuery("select from " + KitchenSink.class.getName()
  1829. + " where dateVal >= p1 parameters java.util.Date p1");
  1830. List<KitchenSink> result = (List<KitchenSink>) q.execute(KitchenSink.DATE1);
  1831. assertEquals(1, result.size());
  1832. assertEquals(key, KeyFactory.stringToKey(result.get(0).key));
  1833. }
  1834. public void testExtents() {
  1835. LinkedList<Key> keyStack = new LinkedList<Key>();
  1836. keyStack.addFirst(ds.put(null, new Entity(HasLongPkJDO.class.getSimpleName())));
  1837. keyStack.addFirst(ds.put(null, new Entity(HasLongPkJDO.class.getSimpleName())));
  1838. keyStack.addFirst(ds.put(null, new Entity(HasLongPkJDO.class.getSimpleName())));
  1839. Extent<HasLongPkJDO> ext = pm.getExtent(HasLongPkJDO.class);
  1840. for (HasLongPkJDO pojo : ext) {
  1841. assertEquals(keyStack.removeLast(), TestUtils.createKey(pojo, pojo.getId()));
  1842. }
  1843. assertTrue(keyStack.isEmpty());
  1844. }
  1845. public void testNullExtentAndClose() {
  1846. try {
  1847. Extent<Flight> ex = pm.getExtent(Flight.class);
  1848. Iterator<Flight> exIter = ex.iterator();
  1849. while (exIter.hasNext()) {
  1850. exIter.next();
  1851. }
  1852. ex.closeAll();
  1853. } catch (Exception e) {
  1854. fail("Exception thrown on Extent iteration and close");
  1855. }
  1856. }
  1857. public void testAliasedFilter() {
  1858. Entity flightEntity = newFlightEntity("1", "yam", "bam", 1, 2);
  1859. ds.put(null, flightEntity);
  1860. Query q = pm.newQuery(
  1861. "select from " + Flight.class.getName() + " where this.id == key parameters String key");
  1862. @SuppressWarnings("unchecked")
  1863. List<Flight> flights = (List<Flight>) q.execute(KeyFactory.keyToString(flightEntity.getKey()));
  1864. assertEquals(1, flights.size());
  1865. assertEquals(flightEntity.getKey(), KeyFactory.stringToKey(flights.get(0).getId()));
  1866. }
  1867. public void testAliasedSort() {
  1868. Entity flightEntity1 = newFlightEntity("1", "yam", "bam", 2, 2);
  1869. Entity flightEntity2 = newFlightEntity("1", "yam", "bam", 1, 2);
  1870. ds.put(null, flightEntity1);
  1871. ds.put(null, flightEntity2);
  1872. Query q = pm.newQuery(
  1873. "select from " + Flight.class.getName() + " order by this.you");
  1874. @SuppressWarnings("unchecked")
  1875. List<Flight> flights = (List<Flight>) q.execute();
  1876. assertEquals(2, flights.size());
  1877. assertEquals(flightEntity2.getKey(), KeyFactory.stringToKey(flights.get(0).getId()));
  1878. assertEquals(flightEntity1.getKey(), KeyFactory.stringToKey(flights.get(1).getId()));
  1879. }
  1880. public void testAliasedEmbeddedFilter() {
  1881. Entity entity = new Entity(Person.class.getSimpleName());
  1882. entity.setProperty("first", "max");
  1883. entity.setProperty("last", "ross");
  1884. entity.setProperty("anotherFirst", "notmax");
  1885. entity.setProperty("anotherLast", "notross");
  1886. ds.put(null, entity);
  1887. Query q = pm.newQuery(
  1888. "select from " + Person.class.getName() + " where this.name.first == \"max\"");
  1889. @SuppressWarnings("unchecked")
  1890. List<Person> result = (List<Person>) q.execute();
  1891. assertEquals(1, result.size());
  1892. }
  1893. public void testAliasedEmbeddedSort() {
  1894. Entity entity1 = new Entity(Person.class.getSimpleName());
  1895. entity1.setProperty("first", "max");
  1896. entity1.setProperty("last", "ross");
  1897. entity1.setProperty("anotherFirst", "notmax2");
  1898. entity1.setProperty("anotherLast", "notross");
  1899. ds.put(null, entity1);
  1900. Entity entity2 = new Entity(Person.class.getSimpleName());
  1901. entity2.setProperty("first", "max");
  1902. entity2.setProperty("last", "ross");
  1903. entity2.setProperty("anotherFirst", "notmax1");
  1904. entity2.setProperty("anotherLast", "notross");
  1905. ds.put(null, entity2);
  1906. Query q = pm.newQuery(
  1907. "select from " + Person.class.getName() + " order by this.anotherName.first");
  1908. @SuppressWarnings("unchecked")
  1909. List<Person> result = (List<Person>) q.execute();
  1910. assertEquals(2, result.size());
  1911. assertEquals(entity2.getKey(), TestUtils.createKey(Person.class, result.get(0).getId()));
  1912. assertEquals(entity1.getKey(), TestUtils.createKey(Person.class, result.get(1).getId()));
  1913. }
  1914. public void testFilterByLiteralDoubleValue() {
  1915. Entity e = KitchenSink.newKitchenSinkEntity("blarg", null);
  1916. ds.put(null, e);
  1917. Query q = pm.newQuery(
  1918. "select from " + KitchenSink.class.getName() + " where doublePrimVal > 2.1");
  1919. @SuppressWarnings("unchecked")
  1920. List<KitchenSink> results = (List<KitchenSink>) q.execute();
  1921. assertEquals(1, results.size());
  1922. }
  1923. public void testFilterByParameterDoubleValue() {
  1924. Entity e = KitchenSink.newKitchenSinkEntity("blarg", null);
  1925. ds.put(null, e);
  1926. Query q = pm.newQuery(
  1927. "select from " + KitchenSink.class.getName() + " where doublePrimVal > p parameters double p");
  1928. @SuppressWarnings("unchecked")
  1929. List<KitchenSink> results = (List<KitchenSink>) q.execute(2.1d);
  1930. assertEquals(1, results.size());
  1931. }
  1932. public void testFilterByNullValue_Literal() {
  1933. Entity e = new Entity(NullDataJDO.class.getSimpleName());
  1934. e.setProperty("string", null);
  1935. ds.put(null, e);
  1936. Query q = pm.newQuery("select from " + NullDataJDO.class.getName() + " where string == null");
  1937. @SuppressWarnings("unchecked")
  1938. List<NullDataJDO> results = (List<NullDataJDO>) q.execute();
  1939. assertEquals(1, results.size());
  1940. }
  1941. public void testFilterByNullValue_Param() {
  1942. Entity e = new Entity(NullDataJDO.class.getSimpleName());
  1943. e.setProperty("string", null);
  1944. ds.put(null, e);
  1945. Query q = pm.newQuery("select from " + NullDataJDO.class.getName() + " where string == p");
  1946. q.declareParameters("String p");
  1947. @SuppressWarnings("unchecked")
  1948. List<NullDataJDO> results = (List<NullDataJDO>) q.execute(null);
  1949. assertEquals(1, results.size());
  1950. }
  1951. public void testIsNotNull() {
  1952. Entity e = Flight.newFlightEntity("name", "origin", null, 23, 24);
  1953. ds.put(null, e);
  1954. assertEquals(1, countForClass(Flight.class));
  1955. Query q = pm.newQuery("select from " + Flight.class.getName() + " where dest != null");
  1956. assertTrue(((List)q.execute()).isEmpty());
  1957. commitTxn();
  1958. beginTxn();
  1959. e = Flight.newFlightEntity("name", "origin", "not null", 23, 24);
  1960. ds.put(null, e);
  1961. q.setUnique(true);
  1962. Flight flight = (Flight) q.execute();
  1963. assertEquals("not null", flight.getDest());
  1964. }
  1965. public void testIsNotNull_Param() {
  1966. Entity e = Flight.newFlightEntity("name", "origin", null, 23, 24);
  1967. ds.put(null, e);
  1968. Query q = pm.newQuery("select from " + Flight.class.getName() + " where dest != :p");
  1969. assertTrue(((List)q.execute((String) null)).isEmpty());
  1970. commitTxn();
  1971. beginTxn();
  1972. e = Flight.newFlightEntity("name", "origin", "not null", 23, 24);
  1973. ds.put(null, e);
  1974. q.setUnique(true);
  1975. Flight flight = (Flight) q.execute((String) null);
  1976. assertEquals("not null", flight.getDest());
  1977. }
  1978. public void testNotEqual() {
  1979. Entity e = Flight.newFlightEntity("name", "origin", "mia", 23, 24);
  1980. ds.put(null, e);
  1981. assertEquals(1, countForClass(Flight.class));
  1982. Query q = pm.newQuery("select from " + Flight.class.getName() + " where dest != 'mia'");
  1983. assertTrue(((List)q.execute()).isEmpty());
  1984. commitTxn();
  1985. beginTxn();
  1986. e = Flight.newFlightEntity("name", "origin", "not mia", 23, 24);
  1987. ds.put(null, e);
  1988. q.setUnique(true);
  1989. Flight flight = (Flight) q.execute();
  1990. assertEquals("not mia", flight.getDest());
  1991. }
  1992. public void testNotEqual_Param() {
  1993. Entity e = Flight.newFlightEntity("name", "origin", "mia", 23, 24);
  1994. ds.put(null, e);
  1995. Query q = pm.newQuery("select from " + Flight.class.getName() + " where dest != :p");
  1996. assertTrue(((List)q.execute("mia")).isEmpty());
  1997. commitTxn();
  1998. beginTxn();
  1999. e = Flight.newFlightEntity("name", "origin", "not mia", 23, 24);
  2000. ds.put(null, e);
  2001. q.setUnique(true);
  2002. Flight flight = (Flight) q.execute("mia");
  2003. assertEquals("not mia", flight.getDest());
  2004. }
  2005. public void testQueryForOneToManySetWithKeyPk() {
  2006. Entity e = new Entity(HasOneToManyKeyPkSetJDO.class.getSimpleName());
  2007. ds.put(null, e);
  2008. Query q = pm.newQuery("select from " + HasOneToManyKeyPkSetJDO.class.getName());
  2009. @SuppressWarnings("unchecked")
  2010. List<HasOneToManyKeyPkSetJDO> results = (List<HasOneToManyKeyPkSetJDO>) q.execute();
  2011. assertEquals(1, results.size());
  2012. assertEquals(0, results.get(0).getFlights().size());
  2013. }
  2014. public void testQueryForOneToManyListWithKeyPk() {
  2015. Entity e = new Entity(HasOneToManyKeyPkListJDO.class.getSimpleName());
  2016. ds.put(null, e);
  2017. Query q = pm.newQuery("select from " + HasOneToManyKeyPkListJDO.class.getName());
  2018. @SuppressWarnings("unchecked")
  2019. List<HasOneToManyKeyPkListJDO> results = (List<HasOneToManyKeyPkListJDO>) q.execute();
  2020. assertEquals(1, results.size());
  2021. assertEquals(0, results.get(0).getFlights().size());
  2022. }
  2023. public void testQueryForOneToManySetWithLongPk() {
  2024. Entity e = new Entity(HasOneToManyLongPkSetJDO.class.getSimpleName());
  2025. ds.put(null, e);
  2026. Query q = pm.newQuery("select from " + HasOneToManyLongPkSetJDO.class.getName());
  2027. @SuppressWarnings("unchecked")
  2028. List<HasOneToManyLongPkSetJDO> results = (List<HasOneToManyLongPkSetJDO>) q.execute();
  2029. assertEquals(1, results.size());
  2030. assertEquals(0, results.get(0).getFlights().size());
  2031. }
  2032. public void testQueryForOneToManyListWithLongPk() {
  2033. Entity e = new Entity(HasOneToManyLongPkListJDO.class.getSimpleName());
  2034. ds.put(null, e);
  2035. Query q = pm.newQuery("select from " + HasOneToManyLongPkListJDO.class.getName());
  2036. @SuppressWarnings("unchecked")
  2037. List<HasOneToManyLongPkListJDO> results = (List<HasOneToManyLongPkListJDO>) q.execute();
  2038. assertEquals(1, results.size());
  2039. assertEquals(0, results.get(0).getFlights().size());
  2040. }
  2041. public void testQueryForOneToManySetWithUnencodedStringPk() {
  2042. Entity e = new Entity(HasOneToManyUnencodedStringPkSetJDO.class.getSimpleName(), "yar");
  2043. ds.put(null, e);
  2044. Query q = pm.newQuery("select from " + HasOneToManyUnencodedStringPkSetJDO.class.getName());
  2045. @SuppressWarnings("unchecked")
  2046. List<HasOneToManyUnencodedStringPkSetJDO> results =
  2047. (List<HasOneToManyUnencodedStringPkSetJDO>) q.execute();
  2048. assertEquals(1, results.size());
  2049. assertEquals(0, results.get(0).getFlights().size());
  2050. }
  2051. public void testQueryForOneToManyListWithUnencodedStringPk() {
  2052. Entity e = new Entity(HasOneToManyUnencodedStringPkListJDO.class.getSimpleName(), "yar");
  2053. ds.put(null, e);
  2054. Query q = pm.newQuery("select from " + HasOneToManyUnencodedStringPkListJDO.class.getName());
  2055. @SuppressWarnings("unchecked")
  2056. List<HasOneToManyUnencodedStringPkListJDO> results =
  2057. (List<HasOneToManyUnencodedStringPkListJDO>) q.execute();
  2058. assertEquals(1, results.size());
  2059. assertEquals(0, results.get(0).getFlights().size());
  2060. }
  2061. public void testImplicitParams() {
  2062. Entity e1 = newFlightEntity("the name", "bos", "mia", 23, 24, 25);
  2063. ds.put(null, e1);
  2064. Entity e2 = newFlightEntity("the name", "bos", "mia", 23, 24, 25);
  2065. ds.put(null, e2);
  2066. Query q = pm.newQuery("select from " + Flight.class.getName() + " where origin == :orig");
  2067. @SuppressWarnings("unchecked")
  2068. List<Flight> flights = (List<Flight>) q.execute("bos");
  2069. assertEquals(2, flights.size());
  2070. }
  2071. public void testBatchGet_NoTxn() {
  2072. commitTxn();
  2073. switchDatasource(PersistenceManagerFactoryName.nontransactional);
  2074. Entity e1 = newFlightEntity("the name", "bos", "mia", 23, 24, 25);
  2075. ds.put(null, e1);
  2076. Entity e2 = newFlightEntity("the name", "bos", "mia", 23, 24, 25);
  2077. ds.put(null, e2);
  2078. Entity e3 = newFlightEntity("the name", "bos", "mia", 23, 24, 25);
  2079. ds.put(null, e3);
  2080. Key key = KeyFactory.createKey("yar", "does not exist");
  2081. NoQueryDelegate nqd = new NoQueryDelegate().install();
  2082. try {
  2083. Query q = pm.newQuery("select from " + Flight.class.getName() + " where id == :ids");
  2084. @SuppressWarnings("unchecked")
  2085. List<Flight> flights = (List<Flight>) q.execute(Utils.newArrayList(key, e1.getKey(), e2.getKey()));
  2086. assertEquals(2, flights.size());
  2087. assertEquals(e1.getKey(), KeyFactory.stringToKey(flights.get(0).getId()));
  2088. assertEquals(e2.getKey(), KeyFactory.stringToKey(flights.get(1).getId()));
  2089. } finally {
  2090. nqd.uninstall();
  2091. }
  2092. }
  2093. public void testBatchGet_NoTxn_EncodedStringKey() {
  2094. commitTxn();
  2095. switchDatasource(PersistenceManagerFactoryName.nontransactional);
  2096. Entity e1 = newFlightEntity("the name", "bos", "mia", 23, 24, 25);
  2097. ds.put(null, e1);
  2098. Entity e2 = newFlightEntity("the name", "bos", "mia", 23, 24, 25);
  2099. ds.put(null, e2);
  2100. Entity e3 = newFlightEntity("the name", "bos", "mia", 23, 24, 25);
  2101. ds.put(null, e3);
  2102. Key key = KeyFactory.createKey("yar", "does not exist");
  2103. NoQueryDelegate nqd = new NoQueryDelegate().install();
  2104. try {
  2105. Query q = pm.newQuery("select from " + Flight.class.getName() + " where id == :ids");
  2106. @SuppressWarnings("unchecked")
  2107. List<Flight> flights = (List<Flight>) q.execute(Utils.newArrayList(
  2108. KeyFactory.keyToString(key),
  2109. KeyFactory.keyToString(e1.getKey()),
  2110. KeyFactory.keyToString(e2.getKey())));
  2111. assertEquals(2, flights.size());
  2112. assertEquals(e1.getKey(), KeyFactory.stringToKey(flights.get(0).getId()));
  2113. assertEquals(e2.getKey(), KeyFactory.stringToKey(flights.get(1).getId()));
  2114. } finally {
  2115. nqd.uninstall();
  2116. }
  2117. }
  2118. public void testBatchGet_NoTxn_Contains() {
  2119. commitTxn();
  2120. switchDatasource(PersistenceManagerFactoryName.nontransactional);
  2121. Entity e1 = newFlightEntity("the name", "bos", "mia", 23, 24, 25);
  2122. ds.put(null, e1);
  2123. Entity e2 = newFlightEntity("the name", "bos", "mia", 23, 24, 25);
  2124. ds.put(null, e2);
  2125. Entity e3 = newFlightEntity("the name", "bos", "mia", 23, 24, 25);
  2126. ds.put(null, e3);
  2127. Key key = KeyFactory.createKey("yar", "does not exist");
  2128. NoQueryDelegate nqd = new NoQueryDelegate().install();
  2129. try {
  2130. Query q = pm.newQuery("select from " + Flight.class.getName() + " where :ids.contains(id)");
  2131. @SuppressWarnings("unchecked")
  2132. List<Flight> flights = (List<Flight>) q.execute(Utils.newArrayList(key, e1.getKey(), e2.getKey()));
  2133. assertEquals(2, flights.size());
  2134. assertEquals(e1.getKey(), KeyFactory.stringToKey(flights.get(0).getId()));
  2135. assertEquals(e2.getKey(), KeyFactory.stringToKey(flights.get(1).getId()));
  2136. } finally {
  2137. nqd.uninstall();
  2138. }
  2139. }
  2140. public void testBatchGet_Count_NoTxn() {
  2141. commitTxn();
  2142. switchDatasource(PersistenceManagerFactoryName.nontransactional);
  2143. Entity e1 = newFlightEntity("the name", "bos", "mia", 23, 24, 25);
  2144. ds.put(null, e1);
  2145. Entity e2 = newFlightEntity("the name", "bos", "mia", 23, 24, 25);
  2146. ds.put(null, e2);
  2147. Entity e3 = newFlightEntity("the name", "bos", "mia", 23, 24, 25);
  2148. ds.put(null, e3);
  2149. Key key = KeyFactory.createKey("yar", "does not exist");
  2150. NoQueryDelegate nqd = new NoQueryDelegate().install();
  2151. try {
  2152. Query q = pm.newQuery("select count(id) from " + Flight.class.getName() + " where id == :ids");
  2153. long count = (Long) q.execute(Utils.newArrayList(key, e1.getKey(), e2.getKey()));
  2154. assertEquals(2l, count);
  2155. } finally {
  2156. nqd.uninstall();
  2157. }
  2158. }
  2159. public void testBatchGet_Txn() {
  2160. Entity e1 = newFlightEntity("the name", "bos", "mia", 23, 24, 25);
  2161. ds.put(null, e1);
  2162. Entity e2 = newFlightEntity(e1.getKey(), "blar", "the name", "bos", "mia", 23, 24, 25);
  2163. ds.put(null, e2);
  2164. Entity e3 = newFlightEntity("the name", "bos", "mia", 23, 24, 25);
  2165. ds.put(null, e3);
  2166. Key key = KeyFactory.createKey(e1.getKey(), "yar", "does not exist");
  2167. NoQueryDelegate nqd = new NoQueryDelegate().install();
  2168. try {
  2169. Query q = pm.newQuery("select from " + Flight.class.getName() + " where id == :ids");
  2170. @SuppressWarnings("unchecked")
  2171. List<Flight> flights = (List<Flight>) q.execute(Utils.newArrayList(key, e1.getKey(), e2.getKey()));
  2172. assertEquals(2, flights.size());
  2173. assertEquals(e1.getKey(), KeyFactory.stringToKey(flights.get(0).getId()));
  2174. assertEquals(e2.getKey(), KeyFactory.stringToKey(flights.get(1).getId()));
  2175. } finally {
  2176. nqd.uninstall();
  2177. }
  2178. }
  2179. public void testBatchGet_Illegal() {
  2180. commitTxn();
  2181. switchDatasource(PersistenceManagerFactoryName.nontransactional);
  2182. Query q = pm.newQuery("select from " + Flight.class.getName() + " where origin == :ids");
  2183. q.addExtension(DatastoreManager.QUERYEXT_INMEMORY_WHEN_UNSUPPORTED, "false");
  2184. try {
  2185. q.execute(Utils.newArrayList());
  2186. fail("expected exception");
  2187. } catch (JDOFatalUserException e) {
  2188. // good
  2189. }
  2190. q = pm.newQuery("select from " + Flight.class.getName() + " where id == :ids && origin == :origin");
  2191. q.addExtension(DatastoreManager.QUERYEXT_INMEMORY_WHEN_UNSUPPORTED, "false");
  2192. try {
  2193. q.execute(Utils.newArrayList(), "bos");
  2194. fail("expected exception");
  2195. } catch (JDOFatalUserException e) {
  2196. // good
  2197. }
  2198. q = pm.newQuery("select from " + Flight.class.getName() + " where origin == :origin && id == :ids");
  2199. q.addExtension(DatastoreManager.QUERYEXT_INMEMORY_WHEN_UNSUPPORTED, "false");
  2200. try {
  2201. q.execute("bos", Utils.newArrayList());
  2202. fail("expected exception");
  2203. } catch (JDOFatalUserException e) {
  2204. // good
  2205. }
  2206. q = pm.newQuery("select from " + Flight.class.getName() + " where id > :ids");
  2207. q.addExtension(DatastoreManager.QUERYEXT_INMEMORY_WHEN_UNSUPPORTED, "false");
  2208. try {
  2209. q.execute(Utils.newArrayList());
  2210. fail("expected exception");
  2211. } catch (JDOFatalUserException e) {
  2212. // good
  2213. }
  2214. q = pm.newQuery("select from " + Flight.class.getName() + " where id == :ids order by id");
  2215. q.addExtension(DatastoreManager.QUERYEXT_INMEMORY_WHEN_UNSUPPORTED, "false");
  2216. try {
  2217. q.execute(Utils.newArrayList());
  2218. fail("expected exception");
  2219. } catch (JDOFatalUserException e) {
  2220. // good
  2221. }
  2222. }
  2223. public void testSetKeysOnly() {
  2224. DatastoreServiceFactoryInternal.setDatastoreService(null);
  2225. ApiProxy.Delegate original = getDelegateForThread();
  2226. Future<DatastorePb.QueryResult> result = EasyMock.createNiceMock(Future.class);
  2227. try {
  2228. ApiProxy.Delegate delegate = EasyMock.createMock(ApiProxy.Delegate.class);
  2229. setDelegateForThread(delegate);
  2230. ApiProxy.ApiConfig config = new ApiProxy.ApiConfig();
  2231. EasyMock.expect(delegate.makeAsyncCall(EasyMock.isA(ApiProxy.Environment.class),
  2232. EasyMock.eq(LocalDatastoreService.PACKAGE),
  2233. EasyMock.eq("RunQuery"),
  2234. KeysOnlyMatcher.eqKeysOnly(true),
  2235. ApiConfigMatcher.eqApiConfig(config))).andReturn(result);
  2236. EasyMock.replay(delegate, result);
  2237. Query q = pm.newQuery("select id from " + Flight.class.getName());
  2238. List<String> ids = (List<String>) q.execute();
  2239. ids.size(); // force resolution of the entire result set
  2240. EasyMock.verify(delegate);
  2241. } finally {
  2242. setDelegateForThread(original);
  2243. }
  2244. }
  2245. public void testRestrictFetchedFields_OneField() {
  2246. Entity e1 = Flight.newFlightEntity("jimmy", "bos", "mia", 23, 24);
  2247. ds.put(null, e1);
  2248. commitTxn();
  2249. beginTxn();
  2250. Query q = pm.newQuery("select origin from " + Flight.class.getName());
  2251. @SuppressWarnings("unchecked")
  2252. List<String> origins = (List<String>) q.execute();
  2253. assertEquals(1, origins.size());
  2254. assertEquals("bos", origins.get(0));
  2255. Entity e2 = Flight.newFlightEntity("jimmy", "lax", "mia", 23, 24);
  2256. ds.put(null, e2);
  2257. commitTxn();
  2258. beginTxn();
  2259. @SuppressWarnings("unchecked")
  2260. List<String> origins2 = (List<String>) q.execute();
  2261. assertEquals(2, origins2.size());
  2262. assertEquals("bos", origins2.get(0));
  2263. assertEquals("lax", origins2.get(1));
  2264. }
  2265. public void testRestrictFetchedFields_OneIdField() {
  2266. Entity e1 = Flight.newFlightEntity("jimmy", "bos", "mia", 23, 24);
  2267. ds.put(null, e1);
  2268. Entity e2 = Flight.newFlightEntity("jimmy", "lax", "mia", 23, 24);
  2269. ds.put(null, e2);
  2270. // Remove this blocker since the test needs to update!
  2271. commitTxn();
  2272. DatastoreServiceInterceptor.uninstall();
  2273. beginTxn();
  2274. Query q = pm.newQuery("select id from " + Flight.class.getName());
  2275. @SuppressWarnings("unchecked")
  2276. List<String> ids = (List<String>) q.execute();
  2277. assertEquals(2, ids.size());
  2278. assertEquals(KeyFactory.keyToString(e1.getKey()), ids.get(0));
  2279. assertEquals(KeyFactory.keyToString(e2.getKey()), ids.get(1));
  2280. Flight f = pm.getObjectById(Flight.class, e1.getKey());
  2281. assertEquals("jimmy", f.getName());
  2282. f.setName("not jimmy");
  2283. commitTxn();
  2284. beginTxn();
  2285. f = pm.getObjectById(Flight.class, e1.getKey());
  2286. assertEquals("not jimmy", f.getName());
  2287. commitTxn();
  2288. }
  2289. public void testRestrictFetchedFields_TwoIdFields() {
  2290. Entity e1 = Flight.newFlightEntity("jimmy", "bos", "mia", 23, 24);
  2291. ds.put(null, e1);
  2292. Entity e2 = Flight.newFlightEntity("jimmy", "lax", "mia", 23, 24);
  2293. ds.put(null, e2);
  2294. // Remove this blocker since the test needs to update!
  2295. commitTxn();
  2296. DatastoreServiceInterceptor.uninstall();
  2297. beginTxn();
  2298. Query q = pm.newQuery("select id, id from " + Flight.class.getName());
  2299. @SuppressWarnings("unchecked")
  2300. List<Object[]> ids = (List<Object[]>) q.execute();
  2301. assertEquals(2, ids.size());
  2302. assertEquals(2, ids.get(0).length);
  2303. assertEquals(2, ids.get(1).length);
  2304. assertEquals(KeyFactory.keyToString(e1.getKey()), ids.get(0)[0]);
  2305. assertEquals(KeyFactory.keyToString(e1.getKey()), ids.get(0)[1]);
  2306. assertEquals(KeyFactory.keyToString(e2.getKey()), ids.get(1)[0]);
  2307. assertEquals(KeyFactory.keyToString(e2.getKey()), ids.get(1)[1]);
  2308. Flight f = pm.getObjectById(Flight.class, e1.getKey());
  2309. assertEquals("jimmy", f.getName());
  2310. f.setName("not jimmy");
  2311. commitTxn();
  2312. beginTxn();
  2313. f = pm.getObjectById(Flight.class, e1.getKey());
  2314. assertEquals("not jimmy", f.getName());
  2315. commitTxn();
  2316. }
  2317. public void testRestrictFetchedFields_TwoFields() {
  2318. Entity e1 = Flight.newFlightEntity("jimmy", "bos", "mia", 23, 24);
  2319. ds.put(null, e1);
  2320. Query q = pm.newQuery("select origin, dest from " + Flight.class.getName());
  2321. @SuppressWarnings("unchecked")
  2322. List<Object[]> results = (List<Object[]>) q.execute();
  2323. assertEquals(1, results.size());
  2324. assertEquals(2, results.get(0).length);
  2325. assertEquals("bos", results.get(0)[0]);
  2326. assertEquals("mia", results.get(0)[1]);
  2327. Entity e2 = Flight.newFlightEntity("jimmy", "lax", null, 23, 24);
  2328. ds.put(null, e2);
  2329. commitTxn();
  2330. beginTxn();
  2331. @SuppressWarnings("unchecked")
  2332. List<Object[]> results2 = (List<Object[]>) q.execute();
  2333. assertEquals(2, results2.size());
  2334. assertEquals(2, results2.get(0).length);
  2335. assertEquals("bos", results2.get(0)[0]);
  2336. assertEquals("mia", results2.get(0)[1]);
  2337. assertEquals(2, results2.get(0).length);
  2338. assertEquals("lax", results2.get(1)[0]);
  2339. assertNull(results2.get(1)[1]);
  2340. }
  2341. public void testRestrictFetchedFields_TwoFields_IdIsFirst() {
  2342. Entity e1 = Flight.newFlightEntity("jimmy", "bos", "mia", 23, 24);
  2343. ds.put(null, e1);
  2344. commitTxn();
  2345. beginTxn();
  2346. Query q = pm.newQuery("select id, dest from " + Flight.class.getName());
  2347. @SuppressWarnings("unchecked")
  2348. List<Object[]> results = (List<Object[]>) q.execute();
  2349. assertEquals(1, results.size());
  2350. assertEquals(2, results.get(0).length);
  2351. assertEquals(KeyFactory.keyToString(e1.getKey()), results.get(0)[0]);
  2352. assertEquals("mia", results.get(0)[1]);
  2353. Entity e2 = Flight.newFlightEntity("jimmy", "lax", null, 23, 24);
  2354. ds.put(null, e2);
  2355. commitTxn();
  2356. beginTxn();
  2357. @SuppressWarnings("unchecked")
  2358. List<Object[]> results2 = (List<Object[]>) q.execute();
  2359. assertEquals(2, results2.size());
  2360. assertEquals(2, results2.get(0).length);
  2361. assertEquals(KeyFactory.keyToString(e1.getKey()), results2.get(0)[0]);
  2362. assertEquals("mia", results2.get(0)[1]);
  2363. assertEquals(2, results2.get(0).length);
  2364. assertEquals(KeyFactory.keyToString(e2.getKey()), results2.get(1)[0]);
  2365. assertNull(results2.get(1)[1]);
  2366. }
  2367. public void testRestrictFetchedFields_TwoFields_IdIsSecond() {
  2368. Entity e1 = Flight.newFlightEntity("jimmy", "bos", "mia", 23, 24);
  2369. ds.put(null, e1);
  2370. commitTxn();
  2371. beginTxn();
  2372. Query q = pm.newQuery("select origin, id from " + Flight.class.getName());
  2373. @SuppressWarnings("unchecked")
  2374. List<Object[]> results = (List<Object[]>) q.execute();
  2375. assertEquals(1, results.size());
  2376. assertEquals(2, results.get(0).length);
  2377. assertEquals("bos", results.get(0)[0]);
  2378. assertEquals(KeyFactory.keyToString(e1.getKey()), results.get(0)[1]);
  2379. Entity e2 = Flight.newFlightEntity("jimmy", "lax", null, 23, 24);
  2380. ds.put(null, e2);
  2381. commitTxn();
  2382. beginTxn();
  2383. @SuppressWarnings("unchecked")
  2384. List<Object[]> results2 = (List<Object[]>) q.execute();
  2385. assertEquals(2, results2.size());
  2386. assertEquals(2, results2.get(0).length);
  2387. assertEquals("bos", results2.get(0)[0]);
  2388. assertEquals(KeyFactory.keyToString(e1.getKey()), results2.get(0)[1]);
  2389. assertEquals(2, results2.get(0).length);
  2390. assertEquals("lax", results2.get(1)[0]);
  2391. assertEquals(KeyFactory.keyToString(e2.getKey()), results2.get(1)[1]);
  2392. }
  2393. public void testRestrictFetchedFields_OneToOne() {
  2394. Entity e1 = new Entity(HasOneToOneJDO.class.getSimpleName());
  2395. ds.put(null, e1);
  2396. Entity e2 = Flight.newFlightEntity(e1.getKey(), "key name", "jimmy", "bos", "mia", 23, 24, 25);
  2397. ds.put(null, e2);
  2398. Query q = pm.newQuery("select id, flight from " + HasOneToOneJDO.class.getName());
  2399. @SuppressWarnings("unchecked")
  2400. List<Object[]> results = (List<Object[]>) q.execute();
  2401. assertEquals(1, results.size());
  2402. assertEquals(2, results.get(0).length);
  2403. assertEquals(KeyFactory.keyToString(e1.getKey()), results.get(0)[0]);
  2404. Flight f = pm.getObjectById(Flight.class, e2.getKey());
  2405. assertEquals(f, results.get(0)[1]);
  2406. }
  2407. public void testRestrictFetchedFields_OneToMany() {
  2408. Entity e1 = new Entity(HasOneToManyListJDO.class.getSimpleName());
  2409. ds.put(null, e1);
  2410. Entity e2 = Flight.newFlightEntity(e1.getKey(), "key name", "jimmy", "bos", "mia", 23, 24, 25);
  2411. e2.setProperty("flights_INTEGER_IDX", 0);
  2412. ds.put(null, e2);
  2413. e1.setProperty("flights", Utils.newArrayList(e2.getKey()));
  2414. ds.put(null, e1);
  2415. Query q = pm.newQuery("select id, flights from " + HasOneToManyListJDO.class.getName());
  2416. @SuppressWarnings("unchecked")
  2417. List<Object[]> results = (List<Object[]>) q.execute();
  2418. assertEquals(1, results.size());
  2419. assertEquals(2, results.get(0).length);
  2420. assertEquals(KeyFactory.keyToString(e1.getKey()), results.get(0)[0]);
  2421. Flight f = pm.getObjectById(Flight.class, e2.getKey());
  2422. List<Flight> flights = (List<Flight>) results.get(0)[1];
  2423. assertEquals(1, flights.size());
  2424. assertEquals(f, flights.get(0));
  2425. }
  2426. public void testRestrictFetchedFields_AliasedField() {
  2427. Entity e1 = Flight.newFlightEntity("jimmy", "bos", "mia", 23, 24);
  2428. ds.put(null, e1);
  2429. Query q = pm.newQuery("select this.origin from " + Flight.class.getName());
  2430. @SuppressWarnings("unchecked")
  2431. List<String> origins = (List<String>) q.execute();
  2432. assertEquals(1, origins.size());
  2433. assertEquals("bos", origins.get(0));
  2434. }
  2435. public void testRestrictFetchedFields_EmbeddedField() {
  2436. Entity entity = new Entity(Person.class.getSimpleName());
  2437. entity.setProperty("first", "max");
  2438. entity.setProperty("last", "ross");
  2439. entity.setProperty("anotherFirst", "notmax");
  2440. entity.setProperty("anotherLast", "notross");
  2441. ds.put(null, entity);
  2442. Query q = pm.newQuery("select name.first, anotherName.last from " + Person.class.getName());
  2443. @SuppressWarnings("unchecked")
  2444. List<Object[]> result = (List<Object[]>) q.execute();
  2445. assertEquals(1, result.size());
  2446. }
  2447. public void testAggregateInFilterFails() {
  2448. Query q = pm.newQuery("select from " + Flight.class.getName() + " where you == max(you)");
  2449. q.addExtension(DatastoreManager.QUERYEXT_INMEMORY_WHEN_UNSUPPORTED, "false");
  2450. try {
  2451. q.execute();
  2452. fail("expected exception");
  2453. } catch (JDOUserException jdoe) {
  2454. if (jdoe.getCause() instanceof DatastoreQuery.UnsupportedDatastoreFeatureException) {
  2455. // good
  2456. }
  2457. else {
  2458. throw jdoe;
  2459. }
  2460. }
  2461. }
  2462. public void testQueryWithSingleCharacterLiteral() {
  2463. Query q = pm.newQuery("select from " + Flight.class.getName() + " where name == 'y'");
  2464. List<Flight> result = (List<Flight>) q.execute();
  2465. assertTrue(result.isEmpty());
  2466. Entity e = Flight.newFlightEntity("y", "bos", "mia", 23, 24);
  2467. ds.put(null, e);
  2468. commitTxn();
  2469. beginTxn();
  2470. q.setUnique(true);
  2471. Flight f = (Flight) q.execute();
  2472. assertEquals(e.getKey(), KeyFactory.stringToKey(f.getId()));
  2473. }
  2474. public void testAccessResultsAfterClose() {
  2475. for (int i = 0; i < 3; i++) {
  2476. Entity e = Flight.newFlightEntity("this", "bos", "mia", 24, 25);
  2477. ds.put(null, e);
  2478. }
  2479. Query q = pm.newQuery("select from " + Flight.class.getName());
  2480. @SuppressWarnings("unchecked")
  2481. List<Flight> results = (List<Flight>) q.execute();
  2482. Iterator<Flight> iter = results.iterator();
  2483. iter.next();
  2484. commitTxn();
  2485. pm.close();
  2486. Flight f = iter.next();
  2487. f.getDest();
  2488. iter.next();
  2489. }
  2490. public void testParamReferencedTwice() {
  2491. Query q = pm.newQuery("select from " + Flight.class.getName() + " where name == p && origin == p");
  2492. q.declareParameters("String p");
  2493. q.execute("23");
  2494. }
  2495. public void testStartsWith_Literal() {
  2496. Entity e1 = Flight.newFlightEntity("y", "bos", "mia", 24, 25);
  2497. ds.put(null, e1);
  2498. Entity e2 = Flight.newFlightEntity("yam", "bos", "mia", 24, 25);
  2499. ds.put(null, e2);
  2500. Entity e3 = Flight.newFlightEntity("z", "bos", "mia", 24, 25);
  2501. ds.put(null, e3);
  2502. Query q = pm.newQuery("select from " + Flight.class.getName() + " where name.startsWith(\"y\")");
  2503. @SuppressWarnings("unchecked")
  2504. List<Flight> flights = (List<Flight>) q.execute();
  2505. assertEquals(2, flights.size());
  2506. q = pm.newQuery("select from " + Flight.class.getName() + " where name.startsWith(\"ya\")");
  2507. @SuppressWarnings("unchecked")
  2508. List<Flight> flights2 = (List<Flight>) q.execute();
  2509. assertEquals(1, flights2.size());
  2510. q = pm.newQuery("select from " + Flight.class.getName() + " where name.startsWith(\"za\")");
  2511. @SuppressWarnings("unchecked")
  2512. List<Flight> flights3 = (List<Flight>) q.execute();
  2513. assertTrue(flights3.isEmpty());
  2514. }
  2515. public void testEndsWith_Literal() {
  2516. Entity e1 = Flight.newFlightEntity("y", "bos", "mia", 24, 25);
  2517. ds.put(null, e1);
  2518. Entity e2 = Flight.newFlightEntity("yam", "bos", "mia", 24, 25);
  2519. ds.put(null, e2);
  2520. Entity e3 = Flight.newFlightEntity("z", "bos", "mia", 24, 25);
  2521. ds.put(null, e3);
  2522. Query q = pm.newQuery("select from " + Flight.class.getName() + " where name.endsWith(\"y\")");
  2523. q.addExtension(DatastoreManager.QUERYEXT_INMEMORY_WHEN_UNSUPPORTED, "true");
  2524. @SuppressWarnings("unchecked")
  2525. List<Flight> flights = (List<Flight>) q.execute();
  2526. assertEquals(1, flights.size());
  2527. q = pm.newQuery("select from " + Flight.class.getName() + " where name.endsWith(\"am\")");
  2528. q.addExtension(DatastoreManager.QUERYEXT_INMEMORY_WHEN_UNSUPPORTED, "true");
  2529. @SuppressWarnings("unchecked")
  2530. List<Flight> flights2 = (List<Flight>) q.execute();
  2531. assertEquals(1, flights2.size());
  2532. q = pm.newQuery("select from " + Flight.class.getName() + " where name.endsWith(\"za\")");
  2533. q.addExtension(DatastoreManager.QUERYEXT_INMEMORY_WHEN_UNSUPPORTED, "true");
  2534. @SuppressWarnings("unchecked")
  2535. List<Flight> flights3 = (List<Flight>) q.execute();
  2536. assertTrue(flights3.isEmpty());
  2537. }
  2538. public void testStartsWith_Param() {
  2539. Entity e1 = Flight.newFlightEntity("y", "bos", "mia", 24, 25);
  2540. ds.put(null, e1);
  2541. Entity e2 = Flight.newFlightEntity("yam", "bos", "mia", 24, 25);
  2542. ds.put(null, e2);
  2543. Entity e3 = Flight.newFlightEntity("z", "bos", "mia", 24, 25);
  2544. ds.put(null, e3);
  2545. Query q = pm.newQuery("select from " + Flight.class.getName() + " where name.startsWith(p)");
  2546. q.declareParameters("String p");
  2547. @SuppressWarnings("unchecked")
  2548. List<Flight> flights = (List<Flight>) q.execute("y");
  2549. assertEquals(2, flights.size());
  2550. List<Flight> flights2 = (List<Flight>) q.execute("ya");
  2551. assertEquals(1, flights2.size());
  2552. List<Flight> flights3 = (List<Flight>) q.execute("za");
  2553. assertTrue(flights3.isEmpty());
  2554. }
  2555. public void testStartsWith_ImplicitParam() {
  2556. Entity e1 = Flight.newFlightEntity("y", "bos", "mia", 24, 25);
  2557. ds.put(null, e1);
  2558. Entity e2 = Flight.newFlightEntity("yam", "bos", "mia", 24, 25);
  2559. ds.put(null, e2);
  2560. Entity e3 = Flight.newFlightEntity("z", "bos", "mia", 24, 25);
  2561. ds.put(null, e3);
  2562. Query q = pm.newQuery("select from " + Flight.class.getName() + " where name.startsWith(:p)");
  2563. @SuppressWarnings("unchecked")
  2564. List<Flight> flights = (List<Flight>) q.execute("y");
  2565. assertEquals(2, flights.size());
  2566. List<Flight> flights2 = (List<Flight>) q.execute("ya");
  2567. assertEquals(1, flights2.size());
  2568. List<Flight> flights3 = (List<Flight>) q.execute("za");
  2569. assertTrue(flights3.isEmpty());
  2570. }
  2571. public void testStartsWithOnlyOnString() {
  2572. Entity e1 = Flight.newFlightEntity("y", "bos", "mia", 24, 25);
  2573. ds.put(null, e1);
  2574. Entity e2 = Flight.newFlightEntity("yam", "bos", "mia", 24, 25);
  2575. ds.put(null, e2);
  2576. Entity e3 = Flight.newFlightEntity("z", "bos", "mia", 24, 25);
  2577. ds.put(null, e3);
  2578. try {
  2579. Query q = pm.newQuery("select from " + Flight.class.getName() + " where flightNumber.startsWith(\"y\")");
  2580. q.addExtension(DatastoreManager.QUERYEXT_INMEMORY_WHEN_UNSUPPORTED, "false");
  2581. q.execute();
  2582. fail("Should have thrown an exception when invoking 'int.startsWith' but didn't");
  2583. } catch (JDOUserException ue) {
  2584. // Expected
  2585. }
  2586. }
  2587. public void testMatches_ImplicitParam() {
  2588. Entity e1 = Flight.newFlightEntity("y", "bos", "mia", 24, 25);
  2589. ds.put(null, e1);
  2590. Entity e2 = Flight.newFlightEntity("yam", "bos", "mia", 24, 25);
  2591. ds.put(null, e2);
  2592. Entity e3 = Flight.newFlightEntity("z", "bos", "mia", 24, 25);
  2593. ds.put(null, e3);
  2594. Query q = pm.newQuery("select from " + Flight.class.getName() + " where name.matches(:p)");
  2595. @SuppressWarnings("unchecked")
  2596. List<Flight> flights = (List<Flight>) q.execute("y.*");
  2597. assertEquals(2, flights.size());
  2598. List<Flight> flights2 = (List<Flight>) q.execute("ya.*");
  2599. assertEquals(1, flights2.size());
  2600. List<Flight> flights3 = (List<Flight>) q.execute("za.*");
  2601. assertTrue(flights3.isEmpty());
  2602. }
  2603. public void testMatchesQuery_InvalidLiteral() {
  2604. Query q = pm.newQuery("select from " + Book.class.getName() + " where title.matches('.*y')");
  2605. q.addExtension(DatastoreManager.QUERYEXT_INMEMORY_WHEN_UNSUPPORTED, "false");
  2606. try {
  2607. ((List<?>) q.execute()).isEmpty();
  2608. fail("expected exception");
  2609. } catch (JDOUserException jdoe) {
  2610. if (jdoe.getCause() instanceof DatastoreQuery.UnsupportedDatastoreFeatureException) {
  2611. // good
  2612. }
  2613. else {
  2614. throw jdoe;
  2615. }
  2616. }
  2617. q = pm.newQuery("select from " + Book.class.getName() + " where title.matches('y.*y')");
  2618. q.addExtension(DatastoreManager.QUERYEXT_INMEMORY_WHEN_UNSUPPORTED, "false");
  2619. try {
  2620. ((List<?>) q.execute()).isEmpty();
  2621. fail("expected exception");
  2622. } catch (JDOUserException jdoe) {
  2623. if (jdoe.getCause() instanceof DatastoreQuery.UnsupportedDatastoreFeatureException) {
  2624. // good
  2625. }
  2626. else {
  2627. throw jdoe;
  2628. }
  2629. }
  2630. q = pm.newQuery("select from " + Book.class.getName() + " where title.matches('y')");
  2631. q.addExtension(DatastoreManager.QUERYEXT_INMEMORY_WHEN_UNSUPPORTED, "false");
  2632. try {
  2633. ((List<?>) q.execute()).isEmpty();
  2634. fail("expected exception");
  2635. } catch (JDOUserException jdoe) {
  2636. if (jdoe.getCause() instanceof DatastoreQuery.UnsupportedDatastoreFeatureException) {
  2637. // good
  2638. }
  2639. else {
  2640. throw jdoe;
  2641. }
  2642. }
  2643. q = pm.newQuery("select from " + Book.class.getName() + " where title.matches('y.*') && author.matches('z.*')");
  2644. q.addExtension(DatastoreManager.QUERYEXT_INMEMORY_WHEN_UNSUPPORTED, "false");
  2645. try {
  2646. ((List<?>) q.execute()).isEmpty();
  2647. fail("expected exception");
  2648. } catch (JDOFatalUserException e) {
  2649. // good
  2650. assertTrue(e.getCause().getClass().getName(), e.getCause() instanceof IllegalArgumentException);
  2651. }
  2652. }
  2653. public void testMatchesQuery_InvalidParameter() {
  2654. Query q = pm.newQuery("select from " + Book.class.getName() + " where title.matches(:p)");
  2655. q.addExtension(DatastoreManager.QUERYEXT_INMEMORY_WHEN_UNSUPPORTED, "false");
  2656. try {
  2657. ((List<?>) q.execute(".*y")).isEmpty();
  2658. fail("expected exception");
  2659. } catch (JDOUserException jdoe) {
  2660. if (jdoe.getCause() instanceof DatastoreQuery.UnsupportedDatastoreFeatureException) {
  2661. // good
  2662. }
  2663. else {
  2664. throw jdoe;
  2665. }
  2666. }
  2667. try {
  2668. ((List<?>) q.execute("y.*y")).isEmpty();
  2669. fail("expected exception");
  2670. } catch (JDOUserException jdoe) {
  2671. if (jdoe.getCause() instanceof DatastoreQuery.UnsupportedDatastoreFeatureException) {
  2672. // good
  2673. }
  2674. else {
  2675. throw jdoe;
  2676. }
  2677. }
  2678. try {
  2679. ((List<?>) q.execute("y")).isEmpty();
  2680. fail("expected exception");
  2681. } catch (JDOUserException jdoe) {
  2682. if (jdoe.getCause() instanceof DatastoreQuery.UnsupportedDatastoreFeatureException) {
  2683. // good
  2684. }
  2685. else {
  2686. throw jdoe;
  2687. }
  2688. }
  2689. try {
  2690. ((List<?>) q.execute(23)).isEmpty();
  2691. fail("expected exception");
  2692. } catch (JDOFatalUserException e) {
  2693. // good
  2694. }
  2695. q = pm.newQuery("select from " + Book.class.getName() + " where title.matches(:p) && author.matches(:q)");
  2696. try {
  2697. ((List<?>) q.execute("y.*", "y.*")).isEmpty();
  2698. fail("expected exception");
  2699. } catch (JDOFatalUserException e) {
  2700. // good
  2701. assertTrue(e.getCause().getClass().getName(), e.getCause() instanceof IllegalArgumentException);
  2702. }
  2703. }
  2704. public void testAncestorQueryForDifferentEntityGroupWithCurrentTxn() {
  2705. Entity e1 = Flight.newFlightEntity("y", "bos", "mia", 24, 25);
  2706. ds.put(null, e1);
  2707. // Not used, but associates the txn with the flight's entity group
  2708. /*Flight f = */pm.getObjectById(Flight.class, e1.getKey());
  2709. Query q = pm.newQuery(
  2710. "select from " + HasKeyAncestorKeyPkJDO.class.getName() + " where ancestorKey == :p");
  2711. try {
  2712. ((List<?>) q.execute(KeyFactory.createKey("yar", 33L))).isEmpty();
  2713. fail("expected iae");
  2714. } catch (JDOFatalUserException e) {
  2715. // good
  2716. }
  2717. Map<String, Object> extensions = Utils.newHashMap();
  2718. extensions.put("gae.exclude-query-from-txn", false);
  2719. q.setExtensions(extensions);
  2720. try {
  2721. ((List<?>) q.execute(KeyFactory.createKey("yar", 33L))).isEmpty();
  2722. fail("expected iae");
  2723. } catch (JDOFatalUserException e) {
  2724. // good
  2725. }
  2726. extensions.put("gae.exclude-query-from-txn", true);
  2727. q.setExtensions(extensions);
  2728. q.execute(KeyFactory.createKey("yar", 33L));
  2729. }
  2730. public void testNullAncestorParam() {
  2731. Query q = pm.newQuery(HasKeyAncestorStringPkJDO.class);
  2732. q.setFilter("ancestorKey == :p");
  2733. q.addExtension(DatastoreManager.QUERYEXT_INMEMORY_WHEN_UNSUPPORTED, "false");
  2734. try {
  2735. q.execute(null);
  2736. fail("expected exception");
  2737. } catch (JDOUserException jdoe) {
  2738. if (jdoe.getCause() instanceof DatastoreQuery.UnsupportedDatastoreFeatureException) {
  2739. // good
  2740. }
  2741. else {
  2742. throw jdoe;
  2743. }
  2744. }
  2745. }
  2746. public void testNonexistentClassThrowsReasonableException() {
  2747. try {
  2748. pm.newQuery("select from xyam order by date desc range 0,5").execute();
  2749. fail("expected exception");
  2750. } catch (JDOFatalUserException e) {
  2751. // good
  2752. }
  2753. }
  2754. public void testSubclassesNotSupported() {
  2755. JDOQLQuery q = new JDOQLQuery(getExecutionContext().getStoreManager(), getExecutionContext());
  2756. q.setCandidateClass(Base1.class);
  2757. q.setSubclasses(false);
  2758. try {
  2759. q.setSubclasses(true);
  2760. fail("expected nue");
  2761. } catch (NucleusUserException nue) {
  2762. // good
  2763. }
  2764. q.setCandidateClass(UnidirTop.class);
  2765. q.setSubclasses(false);
  2766. q.setSubclasses(true);
  2767. }
  2768. public void testQueryTimeout() {
  2769. DatastoreServiceFactoryInternal.setDatastoreService(null);
  2770. ApiProxy.ApiConfig config = new ApiProxy.ApiConfig();
  2771. config.setDeadlineInSeconds(3.0);
  2772. ApiProxy.Delegate delegate = EasyMock.createMock(ApiProxy.Delegate.class);
  2773. EasyMock.expect(delegate.makeAsyncCall(EasyMock.isA(ApiProxy.Environment.class),
  2774. EasyMock.eq(LocalDatastoreService.PACKAGE),
  2775. EasyMock.eq("RunQuery"),
  2776. EasyMock.isA(byte[].class),
  2777. ApiConfigMatcher.eqApiConfig(config)))
  2778. .andThrow(new DatastoreTimeoutException("too long")).anyTimes();
  2779. EasyMock.replay(delegate);
  2780. ApiProxy.Delegate original = getDelegateForThread();
  2781. setDelegateForThread(delegate);
  2782. try {
  2783. Query q = pm.newQuery(Flight.class);
  2784. q.setDatastoreReadTimeoutMillis(3000);
  2785. try {
  2786. ((List<?>) q.executeWithMap(new HashMap())).isEmpty();
  2787. fail("expected exception");
  2788. } catch (JDODataStoreException e) { // TODO Catch nested as QueryTimeoutException
  2789. // good
  2790. }
  2791. q = pm.newQuery(Flight.class);
  2792. q.setDatastoreReadTimeoutMillis(3000);
  2793. try {
  2794. ((List<?>) q.executeWithArray()).isEmpty();
  2795. fail("expected exception");
  2796. } catch (JDODataStoreException e) { // TODO Catch nested as QueryTimeoutException
  2797. // good
  2798. }
  2799. q = pm.newQuery(Flight.class);
  2800. q.setDatastoreReadTimeoutMillis(3000);
  2801. try {
  2802. ((List<?>) q.executeWithArray()).isEmpty();
  2803. fail("expected exception");
  2804. } catch (JDODataStoreException e) { // TODO Catch nested as QueryTimeoutException
  2805. // good
  2806. }
  2807. q = pm.newQuery(Flight.class);
  2808. q.setDatastoreReadTimeoutMillis(3000);
  2809. try {
  2810. ((List<?>) q.execute()).isEmpty();
  2811. fail("expected exception");
  2812. } catch (JDODataStoreException e) { // TODO Catch nested as QueryTimeoutException
  2813. // good
  2814. }
  2815. } finally {
  2816. setDelegateForThread(original);
  2817. }
  2818. EasyMock.verify(delegate);
  2819. }
  2820. public void testQueryTimeoutWhileIterating() {
  2821. DatastoreServiceFactoryInternal.setDatastoreService(null);
  2822. // Need to have enough data to ensure a Next call
  2823. for (int i = 0; i < 21; i++) {
  2824. Entity e = newFlightEntity("harold", "bos", "mia", 23, 24, 25);
  2825. ds.put(null, e);
  2826. }
  2827. ExceptionThrowingDatastoreDelegate.ExceptionPolicy policy =
  2828. new ExceptionThrowingDatastoreDelegate.BaseExceptionPolicy() {
  2829. boolean exploded = false;
  2830. protected void doIntercept(String methodName) {
  2831. if (!exploded && methodName.equals("Next")) {
  2832. exploded = true;
  2833. throw new DatastoreTimeoutException("boom: " + methodName);
  2834. }
  2835. }
  2836. };
  2837. ApiProxy.Delegate original = getDelegateForThread();
  2838. ExceptionThrowingDatastoreDelegate dd =
  2839. new ExceptionThrowingDatastoreDelegate(getDelegateForThread(), policy);
  2840. setDelegateForThread(dd);
  2841. try {
  2842. Query q = pm.newQuery(Flight.class);
  2843. @SuppressWarnings("unchecked")
  2844. List<Flight> results = (List<Flight>) q.execute();
  2845. try {
  2846. results.size();
  2847. fail("expected exception");
  2848. } catch (JDODataStoreException e) {
  2849. assertTrue(e.getCause() instanceof org.datanucleus.store.query.QueryTimeoutException);
  2850. assertTrue(e.getCause().getCause().toString(), e.getCause().getCause() instanceof DatastoreTimeoutException);
  2851. }
  2852. } finally {
  2853. setDelegateForThread(original);
  2854. }
  2855. }
  2856. public void testOverrideReadConsistency() {
  2857. DatastoreServiceFactoryInternal.setDatastoreService(null);
  2858. ApiProxy.Delegate original = getDelegateForThread();
  2859. Future<DatastorePb.QueryResult> result = EasyMock.createNiceMock(Future.class);
  2860. try {
  2861. ApiProxy.Delegate delegate = EasyMock.createMock(ApiProxy.Delegate.class);
  2862. setDelegateForThread(delegate);
  2863. ApiProxy.ApiConfig config = new ApiProxy.ApiConfig();
  2864. EasyMock.expect(delegate.makeAsyncCall(EasyMock.isA(ApiProxy.Environment.class),
  2865. EasyMock.eq(LocalDatastoreService.PACKAGE),
  2866. EasyMock.eq("RunQuery"),
  2867. FailoverMsMatcher.eqFailoverMs(null),
  2868. ApiConfigMatcher.eqApiConfig(config))).andReturn(result);
  2869. EasyMock.replay(delegate, result);
  2870. Query q = pm.newQuery(Flight.class);
  2871. q.execute();
  2872. EasyMock.verify(delegate);
  2873. delegate = EasyMock.createMock(ApiProxy.Delegate.class);
  2874. setDelegateForThread(delegate);
  2875. EasyMock.expect(delegate.makeAsyncCall(EasyMock.isA(ApiProxy.Environment.class),
  2876. EasyMock.eq(LocalDatastoreService.PACKAGE),
  2877. EasyMock.eq("RunQuery"),
  2878. FailoverMsMatcher.eqFailoverMs(null),
  2879. ApiConfigMatcher.eqApiConfig(config))).andReturn(result);
  2880. EasyMock.replay(delegate);
  2881. q = pm.newQuery(Flight.class);
  2882. q.addExtension("datanucleus.appengine.datastoreReadConsistency", null);
  2883. q.execute();
  2884. EasyMock.verify(delegate);
  2885. delegate = EasyMock.createMock(ApiProxy.Delegate.class);
  2886. setDelegateForThread(delegate);
  2887. EasyMock.expect(delegate.makeAsyncCall(EasyMock.isA(ApiProxy.Environment.class),
  2888. EasyMock.eq(LocalDatastoreService.PACKAGE),
  2889. EasyMock.eq("RunQuery"),
  2890. FailoverMsMatcher.eqFailoverMs(null),
  2891. ApiConfigMatcher.eqApiConfig(config))).andReturn(result);
  2892. EasyMock.replay(delegate);
  2893. q = pm.newQuery(Flight.class);
  2894. q.addExtension("datanucleus.appengine.datastoreReadConsistency", "STRONG");
  2895. q.execute();
  2896. EasyMock.verify(delegate);
  2897. delegate = EasyMock.createMock(ApiProxy.Delegate.class);
  2898. setDelegateForThread(delegate);
  2899. EasyMock.expect(delegate.makeAsyncCall(EasyMock.isA(ApiProxy.Environment.class),
  2900. EasyMock.eq(LocalDatastoreService.PACKAGE),
  2901. EasyMock.eq("RunQuery"),
  2902. FailoverMsMatcher.eqFailoverMs(-1L),
  2903. ApiConfigMatcher.eqApiConfig(config))).andReturn(result);
  2904. EasyMock.replay(delegate);
  2905. q = pm.newQuery(Flight.class);
  2906. q.addExtension("datanucleus.appengine.datastoreReadConsistency", "EVENTUAL");
  2907. q.execute();
  2908. EasyMock.verify(delegate);
  2909. } finally {
  2910. setDelegateForThread(original);
  2911. }
  2912. }
  2913. public void testSetChunkSize() {
  2914. DatastoreServiceFactoryInternal.setDatastoreService(null);
  2915. ApiProxy.Delegate original = getDelegateForThread();
  2916. Future<DatastorePb.QueryResult> result = EasyMock.createNiceMock(Future.class);
  2917. try {
  2918. ApiProxy.Delegate delegate = EasyMock.createMock(ApiProxy.Delegate.class);
  2919. setDelegateForThread(delegate);
  2920. ApiProxy.ApiConfig config = new ApiProxy.ApiConfig();
  2921. EasyMock.expect(delegate.makeAsyncCall(EasyMock.isA(ApiProxy.Environment.class),
  2922. EasyMock.eq(LocalDatastoreService.PACKAGE),
  2923. EasyMock.eq("RunQuery"),
  2924. ChunkMatcher.eqChunkSize(33),
  2925. ApiConfigMatcher.eqApiConfig(config))).andReturn(result);
  2926. EasyMock.replay(delegate, result);
  2927. Query q = pm.newQuery(Flight.class);
  2928. q.getFetchPlan().setFetchSize(33);
  2929. q.execute();
  2930. EasyMock.verify(delegate);
  2931. } finally {
  2932. setDelegateForThread(original);
  2933. }
  2934. }
  2935. public void testPostLoadOnQuery() {
  2936. Entity e1 = Flight.newFlightEntity("y", "bos", "mia", 24, 25);
  2937. ds.put(null, e1);
  2938. MyLoadListener listener = new MyLoadListener();
  2939. pm.addInstanceLifecycleListener(listener, (Class[])null);
  2940. Query q = pm.newQuery(Flight.class);
  2941. List<Flight> flights = (List<Flight>)q.execute();
  2942. Iterator<Flight> iter = flights.iterator();
  2943. while (iter.hasNext()) {
  2944. iter.next();
  2945. }
  2946. assertEquals("Number of postLoad calls is wrong", 1, listener.getNumPostLoads());
  2947. pm.removeInstanceLifecycleListener(listener);
  2948. }
  2949. public class MyLoadListener implements LoadLifecycleListener {
  2950. int num = 0;
  2951. public void postLoad(InstanceLifecycleEvent event)
  2952. {
  2953. num++;
  2954. }
  2955. public int getNumPostLoads() {
  2956. return num;
  2957. }
  2958. }
  2959. /**
  2960. * Test of projection "SELECT result FROM candidate" returning just the field rather than the whole entity.
  2961. */
  2962. public void testProjectionAsResultFields() {
  2963. ds.put(null, newFlightEntity("1", "yar", "bam", 3, 4));
  2964. ds.put(null, newFlightEntity("1", "yam", null, 1, 2));
  2965. String query = "SELECT origin, dest FROM " + Flight.class.getName() + " WHERE you == 3";
  2966. Query q = pm.newQuery(query);
  2967. List results = (List) q.execute();
  2968. assertEquals("Number of results is wrong", 1, results.size());
  2969. Object obj = results.iterator().next();
  2970. assertTrue("Result row is of invalid type", obj instanceof Object[]);
  2971. Object[] row = (Object[])obj;
  2972. assertEquals("Number of returned fields is incorrect", 2, row.length);
  2973. assertEquals("Origin field is wrong", "yar", row[0]);
  2974. assertEquals("Dest field is wrong", "bam", row[1]);
  2975. }
  2976. /**
  2977. * Test of projection "SELECT result INTO resultClass FROM candidate WHERE ..." with a result class
  2978. * that has a constructor taking arguments.
  2979. */
  2980. public void testProjectionWithResultClass1() {
  2981. ds.put(null, newFlightEntity("1", "yar", "bam", 3, 4));
  2982. ds.put(null, newFlightEntity("1", "yam", null, 1, 2));
  2983. String query = "SELECT origin, dest INTO " + FlightStartEnd1.class.getName() + " FROM " + Flight.class.getName() +
  2984. " WHERE you == 3";
  2985. Query q = pm.newQuery(query);
  2986. List results = (List) q.execute();
  2987. assertEquals("Number of results is wrong", 1, results.size());
  2988. Object obj = results.iterator().next();
  2989. assertTrue("Result row is of invalid type", obj instanceof FlightStartEnd1);
  2990. FlightStartEnd1 row = (FlightStartEnd1)obj;
  2991. assertEquals("Origin field is wrong", "yar", row.getOrigin());
  2992. assertEquals("Dest field is wrong", "bam", row.getDest());
  2993. }
  2994. /**
  2995. * Test of projection "SELECT result INTO resultClass FROM candidate WHERE ..." with a result class
  2996. * that has a default constructor and setters.
  2997. */
  2998. public void testProjectionWithResultClass2() {
  2999. ds.put(null, newFlightEntity("1", "yar", "bam", 3, 4));
  3000. ds.put(null, newFlightEntity("1", "yam", null, 1, 2));
  3001. String query = "SELECT origin, dest INTO " + FlightStartEnd2.class.getName() + " FROM " + Flight.class.getName() +
  3002. " WHERE you == 3";
  3003. Query q = pm.newQuery(query);
  3004. List results = (List) q.execute();
  3005. assertEquals("Number of results is wrong", 1, results.size());
  3006. Object obj = results.iterator().next();
  3007. assertTrue("Result row is of invalid type", obj instanceof FlightStartEnd2);
  3008. FlightStartEnd2 row = (FlightStartEnd2)obj;
  3009. assertEquals("Origin field is wrong", "yar", row.getOrigin());
  3010. assertEquals("Dest field is wrong", "bam", row.getDest());
  3011. }
  3012. /**
  3013. * Test of projection "SELECT NEW ResultClass(start,end) INTO ResultClass FROM candidate WHERE ...".
  3014. */
  3015. public void testProjectionWithCreatorAndResultClass2() {
  3016. ds.put(null, newFlightEntity("1", "yar", "bam", 3, 4));
  3017. ds.put(null, newFlightEntity("1", "yam", null, 1, 2));
  3018. String query = "SELECT new " + FlightStartEnd2.class.getName() + "(origin, dest)" +
  3019. " INTO " + FlightStartEnd2.class.getName() + " FROM " + Flight.class.getName() +
  3020. " WHERE you == 3";
  3021. Query q = pm.newQuery(query);
  3022. List results = (List) q.execute();
  3023. assertEquals("Number of results is wrong", 1, results.size());
  3024. Object obj = results.iterator().next();
  3025. assertTrue("Result row is of invalid type : " + obj, obj instanceof FlightStartEnd2);
  3026. FlightStartEnd2 row = (FlightStartEnd2)obj;
  3027. assertEquals("Origin field is wrong", "yar", row.getOrigin());
  3028. assertEquals("Dest field is wrong", "bam", row.getDest());
  3029. }
  3030. private void assertQueryUnsupportedByOrm(
  3031. Class<?> clazz, String query, Expression.Operator unsupportedOp,
  3032. Set<Expression.Operator> unsupportedOps) {
  3033. Query q = pm.newQuery(clazz, query);
  3034. q.addExtension(DatastoreManager.QUERYEXT_INMEMORY_WHEN_UNSUPPORTED, "false");
  3035. try {
  3036. q.execute();
  3037. fail("expected JDOUserException->UnsupportedOperationException for query <" + query + ">");
  3038. } catch (JDOUserException jdoe) {
  3039. Throwable cause = jdoe.getCause();
  3040. if (cause instanceof DatastoreQuery.UnsupportedDatastoreOperatorException) {
  3041. // good
  3042. assertEquals(unsupportedOp, ((DatastoreQuery.UnsupportedDatastoreOperatorException)cause).getOperation());
  3043. }
  3044. else {
  3045. throw jdoe;
  3046. }
  3047. }
  3048. unsupportedOps.remove(unsupportedOp);
  3049. }
  3050. private void assertQueryUnsupportedByDatastore(String query) {
  3051. Query q = pm.newQuery(query);
  3052. q.addExtension(DatastoreManager.QUERYEXT_INMEMORY_WHEN_UNSUPPORTED, "false");
  3053. try {
  3054. ((List<?>) q.execute()).isEmpty();
  3055. fail("expected exception for query <" + query + ">");
  3056. } catch (JDOFatalUserException e) {
  3057. // good
  3058. }
  3059. }
  3060. private void assertQuerySupported(Class<?> clazz, String query,
  3061. List<FilterPredicate> addedFilters, List<SortPredicate> addedSorts, Object... bindVariables) {
  3062. Query q;
  3063. if (query.equals("")) {
  3064. q = pm.newQuery(clazz);
  3065. } else {
  3066. q = pm.newQuery(clazz, query);
  3067. }
  3068. assertQuerySupported(q, addedFilters, addedSorts, bindVariables);
  3069. }
  3070. private void assertQuerySupported(String query,
  3071. List<FilterPredicate> addedFilters, List<SortPredicate> addedSorts, Object... bindVariables) {
  3072. assertQuerySupported(pm.newQuery(query), addedFilters, addedSorts, bindVariables);
  3073. }
  3074. private void assertQuerySupported(Query q, List<FilterPredicate> addedFilters,
  3075. List<SortPredicate> addedSorts, Object... bindVariables) {
  3076. if (bindVariables.length == 0) {
  3077. q.execute();
  3078. } else if (bindVariables.length == 1) {
  3079. q.execute(bindVariables[0]);
  3080. } else if (bindVariables.length == 2) {
  3081. q.execute(bindVariables[0], bindVariables[1]);
  3082. }
  3083. assertFilterPredicatesEqual(addedFilters, getFilterPredicates(q));
  3084. assertEquals(addedSorts, getSortPredicates(q));
  3085. }
  3086. // TODO(maxr): Get rid of this when we've fixed the npe in FilterPredicate.equals().
  3087. private static void assertFilterPredicatesEqual(
  3088. List<FilterPredicate> expected, List<FilterPredicate> actual) {
  3089. List<FilterPredicate> expected2 = Utils.newArrayList();
  3090. for (FilterPredicate fp : expected) {
  3091. if (fp.getValue() == null) {
  3092. expected2.add(new FilterPredicate(fp.getPropertyName(), fp.getOperator(), "____null"));
  3093. } else {
  3094. expected2.add(fp);
  3095. }
  3096. }
  3097. List<FilterPredicate> actual2 = Utils.newArrayList();
  3098. for (FilterPredicate fp : actual) {
  3099. if (fp.getValue() == null) {
  3100. actual2.add(new FilterPredicate(fp.getPropertyName(), fp.getOperator(), "____null"));
  3101. } else {
  3102. actual2.add(fp);
  3103. }
  3104. }
  3105. assertEquals(expected2, actual2);
  3106. }
  3107. private DatastoreQuery getDatastoreQuery(Query q) {
  3108. return ((JDOQLQuery)((JDOQuery)q).getInternalQuery()).getDatastoreQuery();
  3109. }
  3110. private List<FilterPredicate> getFilterPredicates(Query q) {
  3111. return getDatastoreQuery(q).getLatestDatastoreQuery().getFilterPredicates();
  3112. }
  3113. private List<SortPredicate> getSortPredicates(Query q) {
  3114. return getDatastoreQuery(q).getLatestDatastoreQuery().getSortPredicates();
  3115. }
  3116. private void assertQuerySupportedWithExplicitParams(String query,
  3117. List<FilterPredicate> addedFilters, List<SortPredicate> addedSorts, String explicitParams,
  3118. Object... bindVariables) {
  3119. Query q = pm.newQuery(query);
  3120. q.declareParameters(explicitParams);
  3121. if (bindVariables.length == 0) {
  3122. q.execute();
  3123. } else if (bindVariables.length == 1) {
  3124. q.execute(bindVariables[0]);
  3125. } else if (bindVariables.length == 2) {
  3126. q.execute(bindVariables[0], bindVariables[1]);
  3127. }
  3128. assertEquals(addedFilters, getFilterPredicates(q));
  3129. assertEquals(addedSorts, getSortPredicates(q));
  3130. }
  3131. }