PageRenderTime 17ms CodeModel.GetById 18ms RepoModel.GetById 1ms 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

Large files files are truncated, but you can click here to view the full file

  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());

Large files files are truncated, but you can click here to view the full file