/tests/com/google/appengine/datanucleus/query/JDOQLQueryTest.java
Java | 3513 lines | 3027 code | 379 blank | 107 comment | 69 complexity | 9f9753ac1411133e88541b3c78d14a72 MD5 | raw file
Large files files are truncated, but you can click here to view the full file
1/********************************************************************** 2Copyright (c) 2009 Google Inc. 3 4Licensed under the Apache License, Version 2.0 (the "License"); 5you may not use this file except in compliance with the License. 6You may obtain a copy of the License at 7 8http://www.apache.org/licenses/LICENSE-2.0 9 10Unless required by applicable law or agreed to in writing, software 11distributed under the License is distributed on an "AS IS" BASIS, 12WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13See the License for the specific language governing permissions and 14limitations under the License. 15**********************************************************************/ 16package com.google.appengine.datanucleus.query; 17 18import static com.google.appengine.datanucleus.test.jdo.Flight.newFlightEntity; 19 20import com.google.appengine.api.datastore.DatastoreFailureException; 21import com.google.appengine.api.datastore.DatastoreTimeoutException; 22import com.google.appengine.api.datastore.Entity; 23import com.google.appengine.api.datastore.Key; 24import com.google.appengine.api.datastore.KeyFactory; 25import com.google.appengine.api.datastore.Query.FilterOperator; 26import com.google.appengine.api.datastore.Query.FilterPredicate; 27import com.google.appengine.api.datastore.Query.SortDirection; 28import com.google.appengine.api.datastore.Query.SortPredicate; 29import com.google.appengine.api.datastore.ShortBlob; 30import com.google.appengine.api.datastore.dev.LocalDatastoreService; 31import com.google.appengine.api.users.User; 32import com.google.appengine.datanucleus.DatastoreManager; 33import com.google.appengine.datanucleus.DatastoreServiceFactoryInternal; 34import com.google.appengine.datanucleus.DatastoreServiceInterceptor; 35import com.google.appengine.datanucleus.ExceptionThrowingDatastoreDelegate; 36import com.google.appengine.datanucleus.PrimitiveArrays; 37import com.google.appengine.datanucleus.TestUtils; 38import com.google.appengine.datanucleus.Utils; 39import com.google.appengine.datanucleus.WriteBlocker; 40import com.google.appengine.datanucleus.jdo.JDOTestCase; 41import com.google.appengine.datanucleus.test.jdo.AbstractBaseClassesJDO.Base1; 42import com.google.appengine.datanucleus.test.jdo.BidirectionalChildListJDO; 43import com.google.appengine.datanucleus.test.jdo.BidirectionalChildLongPkListJDO; 44import com.google.appengine.datanucleus.test.jdo.BidirectionalGrandchildListJDO; 45import com.google.appengine.datanucleus.test.jdo.Flight; 46import com.google.appengine.datanucleus.test.jdo.HasBytesJDO; 47import com.google.appengine.datanucleus.test.jdo.HasEmbeddedJDO; 48import com.google.appengine.datanucleus.test.jdo.HasEncodedStringPkJDO; 49import com.google.appengine.datanucleus.test.jdo.HasEncodedStringPkSeparateIdFieldJDO; 50import com.google.appengine.datanucleus.test.jdo.HasEncodedStringPkSeparateNameFieldJDO; 51import com.google.appengine.datanucleus.test.jdo.HasEnumJDO; 52import com.google.appengine.datanucleus.test.jdo.HasKeyAncestorKeyPkJDO; 53import com.google.appengine.datanucleus.test.jdo.HasKeyAncestorStringPkJDO; 54import com.google.appengine.datanucleus.test.jdo.HasKeyPkJDO; 55import com.google.appengine.datanucleus.test.jdo.HasLongPkJDO; 56import com.google.appengine.datanucleus.test.jdo.HasMultiValuePropsJDO; 57import com.google.appengine.datanucleus.test.jdo.HasOneToManyKeyPkListJDO; 58import com.google.appengine.datanucleus.test.jdo.HasOneToManyKeyPkSetJDO; 59import com.google.appengine.datanucleus.test.jdo.HasOneToManyListJDO; 60import com.google.appengine.datanucleus.test.jdo.HasOneToManyLongPkListJDO; 61import com.google.appengine.datanucleus.test.jdo.HasOneToManyLongPkSetJDO; 62import com.google.appengine.datanucleus.test.jdo.HasOneToManyUnencodedStringPkListJDO; 63import com.google.appengine.datanucleus.test.jdo.HasOneToManyUnencodedStringPkSetJDO; 64import com.google.appengine.datanucleus.test.jdo.HasOneToOneJDO; 65import com.google.appengine.datanucleus.test.jdo.HasOneToOneParentJDO; 66import com.google.appengine.datanucleus.test.jdo.HasStringAncestorStringPkJDO; 67import com.google.appengine.datanucleus.test.jdo.HasUnencodedStringPkJDO; 68import com.google.appengine.datanucleus.test.jdo.KitchenSink; 69import com.google.appengine.datanucleus.test.jdo.NullDataJDO; 70import com.google.appengine.datanucleus.test.jdo.Person; 71import com.google.appengine.datanucleus.test.jdo.UnidirectionalSuperclassTableChildJDO.UnidirTop; 72import com.google.appengine.datanucleus.test.jpa.Book; 73import com.google.apphosting.api.ApiProxy; 74import com.google.apphosting.api.DatastorePb; 75 76import junit.framework.Assert; 77 78import org.datanucleus.api.jdo.JDOPersistenceManagerFactory; 79import org.datanucleus.api.jdo.JDOQuery; 80import org.datanucleus.exceptions.NucleusUserException; 81import org.datanucleus.query.expression.Expression; 82import org.datanucleus.store.query.cache.QueryResultsCache; 83import org.easymock.EasyMock; 84 85import java.io.ByteArrayOutputStream; 86import java.io.IOException; 87import java.io.ObjectOutputStream; 88import java.math.BigDecimal; 89import java.util.Arrays; 90import java.util.Collection; 91import java.util.Collections; 92import java.util.HashMap; 93import java.util.HashSet; 94import java.util.Iterator; 95import java.util.LinkedList; 96import java.util.List; 97import java.util.Map; 98import java.util.Set; 99import java.util.concurrent.Future; 100 101import javax.jdo.Extent; 102import javax.jdo.JDODataStoreException; 103import javax.jdo.JDOException; 104import javax.jdo.JDOFatalUserException; 105import javax.jdo.JDOUserException; 106import javax.jdo.Query; 107import javax.jdo.listener.InstanceLifecycleEvent; 108import javax.jdo.listener.LoadLifecycleListener; 109 110/** 111 * @author Max Ross <maxr@google.com> 112 */ 113public class JDOQLQueryTest extends JDOTestCase { 114 115 private static final List<SortPredicate> NO_SORTS = Collections.emptyList(); 116 private static final List<FilterPredicate> NO_FILTERS = Collections.emptyList(); 117 118 private static final FilterPredicate ORIGIN_EQ_2 = 119 new FilterPredicate("origin", FilterOperator.EQUAL, 2); 120 private static final FilterPredicate ORIGIN_EQ_2_LITERAL = 121 new FilterPredicate("origin", FilterOperator.EQUAL, 2L); 122 private static final FilterPredicate ORIGIN_NEQ_NULL_LITERAL = 123 new FilterPredicate("origin", FilterOperator.NOT_EQUAL, null); 124 private static final FilterPredicate ORIGIN_EQ_2STR = 125 new FilterPredicate("origin", FilterOperator.EQUAL, "2"); 126 private static final FilterPredicate ORIGIN_NEQ_2_LITERAL = 127 new FilterPredicate("origin", FilterOperator.NOT_EQUAL, 2L); 128 private static final FilterPredicate DEST_EQ_4_LITERAL = 129 new FilterPredicate("dest", FilterOperator.EQUAL, 4L); 130 private static final FilterPredicate ORIG_GT_2_LITERAL = 131 new FilterPredicate("origin", FilterOperator.GREATER_THAN, 2L); 132 private static final FilterPredicate ORIG_GTE_2_LITERAL = 133 new FilterPredicate("origin", FilterOperator.GREATER_THAN_OR_EQUAL, 2L); 134 private static final FilterPredicate DEST_LT_4_LITERAL = 135 new FilterPredicate("dest", FilterOperator.LESS_THAN, 4L); 136 private static final FilterPredicate DEST_LTE_4_LITERAL = 137 new FilterPredicate("dest", FilterOperator.LESS_THAN_OR_EQUAL, 4L); 138 private static final SortPredicate ORIG_ASC = 139 new SortPredicate("origin", SortDirection.ASCENDING); 140 private static final SortPredicate DESC_DESC = 141 new SortPredicate("dest", SortDirection.DESCENDING); 142 private static final FilterPredicate ORIGIN_IN_2_ARGS = 143 new FilterPredicate("origin", FilterOperator.IN, Arrays.asList("2", 2L)); 144 private static final FilterPredicate ORIGIN_IN_3_ARGS = 145 new FilterPredicate("origin", FilterOperator.IN, Arrays.asList("2", 2L, false)); 146 147 @Override 148 protected void setUp() throws Exception { 149 super.setUp(); 150 DatastoreServiceInterceptor.install(getStoreManager(), new WriteBlocker()); 151 beginTxn(); 152 } 153 154 @Override 155 protected void tearDown() throws Exception { 156 if (!pm.isClosed() && pm.currentTransaction().isActive()) { 157 commitTxn(); 158 } 159 try { 160 super.tearDown(); 161 } finally { 162 DatastoreServiceInterceptor.uninstall(); 163 } 164 } 165 166 public void testUnsupportedFilters() { 167 168 Set<Expression.Operator> unsupportedOps = Utils.newHashSet(DatastoreQuery.UNSUPPORTED_OPERATORS); 169 assertQueryUnsupportedByOrm(Flight.class, "!origin", Expression.OP_NOT, unsupportedOps); 170 assertQueryUnsupportedByOrm(Flight.class, "(origin + dest) == 4", Expression.OP_ADD, unsupportedOps); 171 assertQueryUnsupportedByOrm(Flight.class, "origin + dest == 4", Expression.OP_ADD, unsupportedOps); 172 assertQueryUnsupportedByOrm(Flight.class, "(origin - dest) == 4", Expression.OP_SUB, unsupportedOps); 173 assertQueryUnsupportedByOrm(Flight.class, "origin - dest == 4", Expression.OP_SUB, unsupportedOps); 174 assertQueryUnsupportedByOrm(Flight.class, "(origin / dest) == 4", Expression.OP_DIV, unsupportedOps); 175 assertQueryUnsupportedByOrm(Flight.class, "origin / dest == 4", Expression.OP_DIV, unsupportedOps); 176 assertQueryUnsupportedByOrm(Flight.class, "(origin * dest) == 4", Expression.OP_MUL, unsupportedOps); 177 assertQueryUnsupportedByOrm(Flight.class, "origin * dest == 4", Expression.OP_MUL, unsupportedOps); 178 assertQueryUnsupportedByOrm(Flight.class, "(origin % dest) == 4", Expression.OP_MOD, unsupportedOps); 179 assertQueryUnsupportedByOrm(Flight.class, "origin % dest == 4", Expression.OP_MOD, unsupportedOps); 180 assertQueryUnsupportedByOrm(Flight.class, "~origin == 4", Expression.OP_COM, unsupportedOps); 181 assertQueryUnsupportedByOrm(Flight.class, "!origin == 4", Expression.OP_NOT, unsupportedOps); 182 assertQueryUnsupportedByOrm(Flight.class, "-origin == 4", Expression.OP_NEG, unsupportedOps); 183 assertQueryUnsupportedByOrm(Flight.class, "origin instanceof " + Flight.class.getName(), 184 Expression.OP_IS, unsupportedOps); 185 assertEquals(Utils.<Expression.Operator>newHashSet(Expression.OP_CONCAT, Expression.OP_LIKE, 186 Expression.OP_ISNOT), unsupportedOps); 187 String baseQuery = "select from " + Flight.class.getName() + " where "; 188 // multiple inequality filters 189 // TODO(maxr) Make this pass against the real datastore. 190 // We need to have it return BadRequest instead of NeedIndex for that to 191 // happen. 192 assertQueryUnsupportedByDatastore(baseQuery + "(origin > 2 && dest < 4)"); 193 // inequality filter prop is not the same as the first order by prop 194 assertQueryUnsupportedByDatastore(baseQuery + "origin > 2 order by dest"); 195 // gets split into multiple inequality filters 196 assertQueryUnsupportedByDatastore(baseQuery + "origin != 2 && dest != 4"); 197 198 // can't have 'or' on multiple properties 199 assertQueryRequiresUnsupportedDatastoreFeature(baseQuery + "origin == 'yar' || dest == null"); 200 assertQueryRequiresUnsupportedDatastoreFeature(baseQuery + "origin == 4 && (dest == 'yar' || name == 'yam')"); 201 // TODO This query is flawed - defines a parameter but doesn't provide it (now an error in DN 3.x) 202// assertQueryRequiresUnsupportedDatastoreFeature(baseQuery + ":p1.contains(origin) || name == 'yam'"); 203 // can only check equality 204 assertQueryRequiresUnsupportedDatastoreFeature(baseQuery + "origin > 5 || origin < 2"); 205 } 206 207 private void assertQueryRequiresUnsupportedDatastoreFeature(String query) { 208 Query q = pm.newQuery(query); 209 q.addExtension(DatastoreManager.QUERYEXT_INMEMORY_WHEN_UNSUPPORTED, "false"); 210 try { 211 q.execute(); 212 fail("expected JDOUserException->UnsupportedDatastoreFeatureException for query <" + query + ">"); 213 } catch (JDOUserException jdoe) { 214 if (jdoe.getCause() instanceof DatastoreQuery.UnsupportedDatastoreFeatureException) { 215 // good 216 } 217 else { 218 throw jdoe; 219 } 220 } 221 } 222 223 public void testEvaluateInMemory() { 224 ds.put(null, newFlightEntity("1", "yar", "bam", 1, 2)); 225 ds.put(null, newFlightEntity("1", "yam", null, 1, 2)); 226 227 // This is impossible in the datastore, so run totally in-memory 228 String query = "SELECT FROM " + Flight.class.getName() + " WHERE origin == 'yar' || dest == null"; 229 Query q = pm.newQuery(query); 230 q.addExtension("datanucleus.query.evaluateInMemory", "true"); 231 try { 232 List<Flight> results = (List<Flight>) q.execute(); 233 Assert.assertEquals("Number of results was wrong", 2, results.size()); 234 } catch (JDOException jdoe) { 235 fail("Threw exception when evaluating query in-memory, but should have run"); 236 } 237 } 238 239 public void testCacheQueryResults() { 240 ds.put(null, newFlightEntity("1", "yar", "bam", 1, 2)); 241 ds.put(null, newFlightEntity("1", "yam", null, 1, 2)); 242 243 QueryResultsCache cache = null; 244 try { 245 String query = "SELECT FROM " + Flight.class.getName(); 246 Query q = pm.newQuery(query); 247 q.addExtension("datanucleus.query.results.cached", "true"); 248 try { 249 List<Flight> results = (List<Flight>) q.execute(); 250 Assert.assertEquals("Number of results was wrong", 2, results.size()); 251 } catch (JDOException jdoe) { 252 fail("Threw exception when evaluating query and caching results : " + jdoe.getMessage()); 253 } 254 q.closeAll(); 255 if (pm.currentTransaction().isActive()) { 256 pm.currentTransaction().rollback(); 257 } 258 pm.close(); 259 cache = 260 ((JDOPersistenceManagerFactory)pmf).getNucleusContext().getStoreManager().getQueryManager().getQueryResultsCache(); 261 assertEquals("Number of entries in the query results cache is wrong", 1, cache.size()); 262 263 pm = pmf.getPersistenceManager(); 264 Query q2 = pm.newQuery(query); 265 try { 266 List<Flight> results = (List<Flight>) q2.execute(); 267 Assert.assertEquals("Number of results was wrong", 2, results.size()); 268 } catch (JDOException jdoe) { 269 fail("Threw exception when evaluating query with cached results : " + jdoe.getMessage()); 270 } 271 q2.closeAll(); 272 } finally { 273 // Evict the cached results 274 cache.evictAll(); 275 } 276 } 277 278 public void testCandidateCollectionInMemory() { 279 ds.put(null, newFlightEntity("1", "yar", "bam", 1, 2)); 280 ds.put(null, newFlightEntity("1", "yam", null, 1, 2)); 281 282 Collection<Flight> coll = new HashSet<Flight>(); 283 Iterator<Flight> iter = pm.getExtent(Flight.class).iterator(); 284 while (iter.hasNext()) { 285 coll.add(iter.next()); 286 } 287 288 // Query is impossible in-datastore, and run against candidates so has to be in-memory 289 String query = "SELECT FROM " + Flight.class.getName() + " WHERE origin == 'yar' || dest == null"; 290 Query q = pm.newQuery(query); 291 q.setCandidates(coll); 292 try { 293 List<Flight> results = (List<Flight>) q.execute(); 294 Assert.assertEquals("Number of results was wrong", 2, results.size()); 295 } catch (JDOException jdoe) { 296 fail("Threw exception when evaluating query in-memory, but should have run"); 297 } 298 } 299 300 public void testSupportedFilters() { 301 assertQuerySupported(Flight.class, "", NO_FILTERS, NO_SORTS); 302 assertQuerySupported(Flight.class, "origin == 2", Utils.newArrayList(ORIGIN_EQ_2_LITERAL), NO_SORTS); 303 assertQuerySupported( 304 Flight.class, "origin == \"2\"", Utils.newArrayList(ORIGIN_EQ_2STR), NO_SORTS); 305 assertQuerySupported(Flight.class, "(origin == 2)", Utils.newArrayList(ORIGIN_EQ_2_LITERAL), NO_SORTS); 306 assertQuerySupported(Flight.class, "origin == 2 && dest == 4", Utils.newArrayList(ORIGIN_EQ_2_LITERAL, 307 DEST_EQ_4_LITERAL), NO_SORTS); 308 assertQuerySupported(Flight.class, "(origin == 2 && dest == 4)", Utils.newArrayList(ORIGIN_EQ_2_LITERAL, 309 DEST_EQ_4_LITERAL), NO_SORTS); 310 assertQuerySupported(Flight.class, "(origin == 2) && (dest == 4)", Utils.newArrayList( 311 ORIGIN_EQ_2_LITERAL, DEST_EQ_4_LITERAL), NO_SORTS); 312 313 assertQuerySupported(Flight.class, "origin > 2", Utils.newArrayList(ORIG_GT_2_LITERAL), NO_SORTS); 314 assertQuerySupported(Flight.class, "origin >= 2", Utils.newArrayList(ORIG_GTE_2_LITERAL), NO_SORTS); 315 assertQuerySupported(Flight.class, "dest < 4", Utils.newArrayList(DEST_LT_4_LITERAL), NO_SORTS); 316 assertQuerySupported(Flight.class, "dest <= 4", Utils.newArrayList(DEST_LTE_4_LITERAL), NO_SORTS); 317 318 assertQuerySupported("select from " + Flight.class.getName() + " order by origin asc", 319 NO_FILTERS, Utils.newArrayList(ORIG_ASC)); 320 assertQuerySupported("select from " + Flight.class.getName() + " order by dest desc", 321 NO_FILTERS, Utils.newArrayList(DESC_DESC)); 322 assertQuerySupported("select from " + Flight.class.getName() 323 + " order by origin asc, dest desc", NO_FILTERS, Utils.newArrayList(ORIG_ASC, DESC_DESC)); 324 325 assertQuerySupported("select from " + Flight.class.getName() 326 + " where origin == 2 && dest == 4 order by origin asc, dest desc", 327 Utils.newArrayList(ORIGIN_EQ_2_LITERAL, DEST_EQ_4_LITERAL), Utils.newArrayList(ORIG_ASC, DESC_DESC)); 328 assertQuerySupported(Flight.class, "origin != 2", Utils.newArrayList(ORIGIN_NEQ_2_LITERAL), NO_SORTS); 329 assertQuerySupported("select from " + Flight.class.getName() + " where origin != null", 330 Utils.newArrayList(ORIGIN_NEQ_NULL_LITERAL), NO_SORTS); 331 assertQuerySupported(Flight.class, "origin == '2' || origin == 2", 332 Utils.newArrayList(ORIGIN_IN_2_ARGS), NO_SORTS); 333 assertQuerySupported(Flight.class, "origin == '2' || origin == 2 || origin == false", 334 Utils.newArrayList(ORIGIN_IN_3_ARGS), NO_SORTS); 335 assertQuerySupported(Flight.class, ":p1.contains(origin)", 336 Utils.newArrayList(ORIGIN_IN_2_ARGS), NO_SORTS, Arrays.asList("2", 2L)); 337 assertQuerySupported(Flight.class, ":p1.contains(origin)", 338 Utils.newArrayList(ORIGIN_IN_3_ARGS), NO_SORTS, Arrays.asList("2", 2L, false)); 339 assertQuerySupported(Flight.class, "(origin == '2' || origin == 2) && dest == 4", 340 Utils.newArrayList(DEST_EQ_4_LITERAL, ORIGIN_IN_2_ARGS), NO_SORTS); 341 assertQuerySupported(Flight.class, ":p1.contains(origin) && dest == 4", 342 Utils.newArrayList(ORIGIN_IN_2_ARGS, DEST_EQ_4_LITERAL), NO_SORTS, Arrays.asList("2", 2L)); 343 assertQuerySupported(Flight.class, "(origin == '2' || origin == 2 || origin == false) && dest == 4", 344 Utils.newArrayList(DEST_EQ_4_LITERAL, ORIGIN_IN_3_ARGS), NO_SORTS); 345 assertQuerySupported(Flight.class, ":p1.contains(origin) && dest == 4", 346 Utils.newArrayList(ORIGIN_IN_3_ARGS, DEST_EQ_4_LITERAL), NO_SORTS, Arrays.asList("2", 2L, false)); 347 } 348 349 public void testBindVariables() { 350 String queryStr = "select from " + Flight.class.getName() + " where origin == two "; 351 assertQuerySupported(queryStr + " parameters String two", 352 Utils.newArrayList(ORIGIN_EQ_2STR), NO_SORTS, "2"); 353 assertQuerySupportedWithExplicitParams(queryStr, 354 Utils.newArrayList(ORIGIN_EQ_2STR), NO_SORTS, "String two", "2"); 355 356 queryStr = "select from " + Flight.class.getName() + " where origin == two && dest == four "; 357 assertQuerySupported(queryStr + "parameters int two, int four", 358 Utils.newArrayList(ORIGIN_EQ_2, DEST_EQ_4_LITERAL), NO_SORTS, 2, 4L); 359 assertQuerySupportedWithExplicitParams(queryStr, 360 Utils.newArrayList(ORIGIN_EQ_2, DEST_EQ_4_LITERAL), NO_SORTS, "int two, int four", 2, 4L); 361 362 queryStr = "select from " + Flight.class.getName() + " where origin == two && dest == four "; 363 String orderStr = "order by origin asc, dest desc"; 364 assertQuerySupported(queryStr + "parameters int two, int four " + orderStr, 365 Utils.newArrayList(ORIGIN_EQ_2, DEST_EQ_4_LITERAL), 366 Utils.newArrayList(ORIG_ASC, DESC_DESC), 2, 4L); 367 assertQuerySupportedWithExplicitParams(queryStr + orderStr, 368 Utils.newArrayList(ORIGIN_EQ_2, DEST_EQ_4_LITERAL), 369 Utils.newArrayList(ORIG_ASC, DESC_DESC), "int two, int four", 2, 4L); 370 } 371 372 public void test2Equals2OrderBy() { 373 ds.put(null, newFlightEntity("1", "yam", "bam", 1, 2)); 374 ds.put(null, newFlightEntity("2", "yam", "bam", 1, 1)); 375 ds.put(null, newFlightEntity("3", "yam", "bam", 2, 1)); 376 ds.put(null ,newFlightEntity("4", "yam", "bam", 2, 2)); 377 ds.put(null, newFlightEntity("5", "notyam", "bam", 2, 2)); 378 ds.put(null, newFlightEntity("5", "yam", "notbam", 2, 2)); 379 Query q = pm.newQuery( 380 "select from " + Flight.class.getName() 381 + " where origin == \"yam\" && dest == \"bam\"" 382 + " order by you asc, me desc"); 383 @SuppressWarnings("unchecked") 384 List<Flight> result = (List<Flight>) q.execute(); 385 assertEquals(4, result.size()); 386 387 assertEquals("1", result.get(0).getName()); 388 assertEquals("2", result.get(1).getName()); 389 assertEquals("4", result.get(2).getName()); 390 assertEquals("3", result.get(3).getName()); 391 } 392 393 public void testSetFilter() { 394 ds.put(null, newFlightEntity("1", "yam", "bam", 1, 1)); 395 ds.put(null, newFlightEntity("2", "yam", "bam", 2, 2)); 396 Query q = pm.newQuery( 397 "select from " + Flight.class.getName()); 398 q.setFilter("origin == \"yam\" && you == 2"); 399 @SuppressWarnings("unchecked") 400 List<Flight> result = (List<Flight>) q.execute(); 401 assertEquals(1, result.size()); 402 } 403 404 public void testSetInvalidFilter() { 405 Query q = pm.newQuery( 406 "select from " + Flight.class.getName()); 407 q.setFilter("origin == \"yam\" AND you == 2"); 408 try { 409 q.execute(); 410 fail("expected exception"); 411 } catch (JDOUserException e) { 412 // good 413 } 414 } 415 416 public void testDefaultOrderingIsAsc() { 417 ds.put(null, newFlightEntity("1", "yam", "bam", 1, 2)); 418 ds.put(null, newFlightEntity("2", "yam", "bam", 1, 1)); 419 ds.put(null, newFlightEntity("3", "yam", "bam", 2, 1)); 420 ds.put(null, newFlightEntity("4", "yam", "bam", 2, 2)); 421 ds.put(null, newFlightEntity("5", "notyam", "bam", 2, 2)); 422 ds.put(null, newFlightEntity("5", "yam", "notbam", 2, 2)); 423 Query q = pm.newQuery( 424 "select from " + Flight.class.getName() 425 + " where origin == \"yam\" && dest == \"bam\"" 426 + " order by you"); 427 @SuppressWarnings("unchecked") 428 List<Flight> result = (List<Flight>) q.execute(); 429 assertEquals(4, result.size()); 430 431 assertEquals("1", result.get(0).getName()); 432 assertEquals("2", result.get(1).getName()); 433 assertEquals("3", result.get(2).getName()); 434 assertEquals("4", result.get(3).getName()); 435 } 436 437 public void testLimitQuery() { 438 ds.put(null, newFlightEntity("1", "yam", "bam", 1, 2)); 439 ds.put(null, newFlightEntity("2", "yam", "bam", 1, 1)); 440 ds.put(null, newFlightEntity("3", "yam", "bam", 2, 1)); 441 ds.put(null, newFlightEntity("4", "yam", "bam", 2, 2)); 442 ds.put(null, newFlightEntity("5", "notyam", "bam", 2, 2)); 443 ds.put(null, newFlightEntity("5", "yam", "notbam", 2, 2)); 444 Query q = pm.newQuery( 445 "select from " + Flight.class.getName() 446 + " where origin == \"yam\" && dest == \"bam\"" 447 + " order by you asc, me desc"); 448 449 q.setRange(0, 1); 450 @SuppressWarnings("unchecked") 451 List<Flight> result1 = (List<Flight>) q.execute(); 452 assertEquals(1, result1.size()); 453 assertEquals("1", result1.get(0).getName()); 454 455 q.setRange(0, Long.MAX_VALUE); 456 @SuppressWarnings("unchecked") 457 List<Flight> result2 = (List<Flight>) q.execute(); 458 assertEquals(4, result2.size()); 459 assertEquals("1", result2.get(0).getName()); 460 461 q.setRange(0, 0); 462 @SuppressWarnings("unchecked") 463 List<Flight> result3 = (List<Flight>) q.execute(); 464 assertEquals(0, result3.size()); 465 } 466 467 public void testOffsetQuery() { 468 ds.put(null, newFlightEntity("1", "yam", "bam", 1, 2)); 469 ds.put(null, newFlightEntity("2", "yam", "bam", 1, 1)); 470 ds.put(null, newFlightEntity("3", "yam", "bam", 2, 1)); 471 ds.put(null, newFlightEntity("4", "yam", "bam", 2, 2)); 472 ds.put(null, newFlightEntity("5", "notyam", "bam", 2, 2)); 473 ds.put(null, newFlightEntity("5", "yam", "notbam", 2, 2)); 474 Query q = pm.newQuery( 475 "select from " + Flight.class.getName() 476 + " where origin == \"yam\" && dest == \"bam\"" 477 + " order by you asc, me desc"); 478 479 q.setRange(0, Long.MAX_VALUE); 480 @SuppressWarnings("unchecked") 481 List<Flight> result1 = (List<Flight>) q.execute(); 482 assertEquals(4, result1.size()); 483 assertEquals("1", result1.get(0).getName()); 484 485 q.setRange(1, Long.MAX_VALUE); 486 @SuppressWarnings("unchecked") 487 List<Flight> result2 = (List<Flight>) q.execute(); 488 assertEquals(3, result2.size()); 489 assertEquals("2", result2.get(0).getName()); 490 491 q.setRange(0, Long.MAX_VALUE); 492 @SuppressWarnings("unchecked") 493 List<Flight> result3 = (List<Flight>) q.execute(); 494 assertEquals(4, result3.size()); 495 assertEquals("1", result3.get(0).getName()); 496 } 497 498 public void testOffsetLimitQuery() { 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 Query q = pm.newQuery( 506 "select from " + Flight.class.getName() 507 + " where origin == \"yam\" && dest == \"bam\"" 508 + " order by you asc, me desc"); 509 510 q.setRange(0, 0); 511 @SuppressWarnings("unchecked") 512 List<Flight> result1 = (List<Flight>) q.execute(); 513 assertEquals(0, result1.size()); 514 515 q.setRange(1, 0); 516 @SuppressWarnings("unchecked") 517 List<Flight> result2 = (List<Flight>) q.execute(); 518 assertEquals(0, result2.size()); 519 520 q.setRange(0, 1); 521 @SuppressWarnings("unchecked") 522 List<Flight> result3 = (List<Flight>) q.execute(); 523 assertEquals(1, result3.size()); 524 assertEquals("1", result3.get(0).getName()); 525 526 q.setRange(0, 2); 527 @SuppressWarnings("unchecked") 528 List<Flight> result4 = (List<Flight>) q.execute(); 529 assertEquals(2, result4.size()); 530 assertEquals("1", result4.get(0).getName()); 531 532 q.setRange(1, 2); 533 @SuppressWarnings("unchecked") 534 List<Flight> result5 = (List<Flight>) q.execute(); 535 assertEquals(1, result5.size()); 536 assertEquals("2", result5.get(0).getName()); 537 538 q.setRange(2, 5); 539 @SuppressWarnings("unchecked") 540 List<Flight> result6 = (List<Flight>) q.execute(); 541 assertEquals(2, result6.size()); 542 assertEquals("4", result6.get(0).getName()); 543 544 q.setRange(2, 2); 545 @SuppressWarnings("unchecked") 546 List<Flight> result7 = (List<Flight>) q.execute(); 547 assertEquals(0, result7.size()); 548 549 q.setRange(2, 1); 550 @SuppressWarnings("unchecked") 551 List<Flight> result8 = (List<Flight>) q.execute(); 552 assertEquals(0, result8.size()); 553 } 554 555 public void testOffsetLimitSingleStringQuery() { 556 ds.put(null, newFlightEntity("1", "yam", "bam", 1, 2)); 557 ds.put(null, newFlightEntity("2", "yam", "bam", 1, 1)); 558 ds.put(null, newFlightEntity("3", "yam", "bam", 2, 1)); 559 ds.put(null, newFlightEntity("4", "yam", "bam", 2, 2)); 560 ds.put(null, newFlightEntity("5", "notyam", "bam", 2, 2)); 561 ds.put(null, newFlightEntity("5", "yam", "notbam", 2, 2)); 562 String queryFormat = 563 "select from " + Flight.class.getName() 564 + " where origin == \"yam\" && dest == \"bam\"" 565 + " order by you asc, me desc range %d,%d"; 566 Query q = pm.newQuery(String.format(queryFormat, 0, 0)); 567 @SuppressWarnings("unchecked") 568 List<Flight> result1 = (List<Flight>) q.execute(); 569 assertEquals(0, result1.size()); 570 571 q = pm.newQuery(String.format(queryFormat, 1, 0)); 572 @SuppressWarnings("unchecked") 573 List<Flight> result2 = (List<Flight>) q.execute(); 574 assertEquals(0, result2.size()); 575 576 q = pm.newQuery(String.format(queryFormat, 0, 1)); 577 @SuppressWarnings("unchecked") 578 List<Flight> result3 = (List<Flight>) q.execute(); 579 assertEquals(1, result3.size()); 580 581 q = pm.newQuery(String.format(queryFormat, 0, 2)); 582 @SuppressWarnings("unchecked") 583 List<Flight> result4 = (List<Flight>) q.execute(); 584 assertEquals(2, result4.size()); 585 assertEquals("1", result4.get(0).getName()); 586 587 q = pm.newQuery(String.format(queryFormat, 1, 2)); 588 @SuppressWarnings("unchecked") 589 List<Flight> result5 = (List<Flight>) q.execute(); 590 assertEquals(1, result5.size()); 591 assertEquals("2", result5.get(0).getName()); 592 593 q = pm.newQuery(String.format(queryFormat, 2, 5)); 594 @SuppressWarnings("unchecked") 595 List<Flight> result6 = (List<Flight>) q.execute(); 596 assertEquals(2, result6.size()); 597 assertEquals("4", result6.get(0).getName()); 598 599 q = pm.newQuery(String.format(queryFormat, 2, 2)); 600 @SuppressWarnings("unchecked") 601 List<Flight> result7 = (List<Flight>) q.execute(); 602 assertEquals(0, result7.size()); 603 604 q = pm.newQuery(String.format(queryFormat, 2, 1)); 605 @SuppressWarnings("unchecked") 606 List<Flight> result8 = (List<Flight>) q.execute(); 607 assertEquals(0, result8.size()); 608 } 609 610 public void testSerialization() throws IOException { 611 Query q = pm.newQuery("select from " + Flight.class.getName()); 612 q.execute(); 613 614 JDOQLQuery innerQuery = (JDOQLQuery)((JDOQuery)q).getInternalQuery(); 615 ByteArrayOutputStream baos = new ByteArrayOutputStream(); 616 ObjectOutputStream oos = new ObjectOutputStream(baos); 617 // the fact that this doesn't blow up is the test 618 oos.writeObject(innerQuery); 619 } 620 621 public void testKeyQuery_StringPk() { 622 Entity flightEntity = newFlightEntity("1", "yam", "bam", 1, 2); 623 ds.put(null, flightEntity); 624 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(flightEntity.getKey())); 629 assertEquals(1, flights.size()); 630 assertEquals(flightEntity.getKey(), KeyFactory.stringToKey(flights.get(0).getId())); 631 } 632 633 public void testKeyQuery_KeyPk() { 634 Entity entityWithName = new Entity(HasKeyPkJDO.class.getSimpleName(), "blarg"); 635 Entity entityWithId = new Entity(HasKeyPkJDO.class.getSimpleName()); 636 ds.put(null, entityWithName); 637 ds.put(null, entityWithId); 638 639 Query q = pm.newQuery( 640 "select from " + HasKeyPkJDO.class.getName() + 641 " where key == mykey parameters " + Key.class.getName() + " mykey"); 642 @SuppressWarnings("unchecked") 643 List<HasKeyPkJDO> result = (List<HasKeyPkJDO>) q.execute(entityWithName.getKey()); 644 assertEquals(1, result.size()); 645 assertEquals(entityWithName.getKey(), result.get(0).getKey()); 646 647 q = pm.newQuery( 648 "select from " + HasKeyPkJDO.class.getName() + 649 " where key == mykey parameters " + Key.class.getName() + " mykey"); 650 @SuppressWarnings("unchecked") 651 List<HasKeyPkJDO> result2 = (List<HasKeyPkJDO>) q.execute(entityWithId.getKey()); 652 assertEquals(1, result2.size()); 653 assertEquals(entityWithId.getKey(), result2.get(0).getKey()); 654 655 q = pm.newQuery( 656 "select from " + HasKeyPkJDO.class.getName() + 657 " where key == mykeyname parameters " + String.class.getName() + " mykeyname"); 658 @SuppressWarnings("unchecked") 659 List<HasKeyPkJDO> result3 = (List<HasKeyPkJDO>) q.execute(entityWithName.getKey().getName()); 660 assertEquals(1, result3.size()); 661 assertEquals(entityWithName.getKey(), result3.get(0).getKey()); 662 663 q = pm.newQuery( 664 "select from " + HasKeyPkJDO.class.getName() + 665 " where key == mykeyid parameters " + String.class.getName() + " mykeyid"); 666 @SuppressWarnings("unchecked") 667 List<HasKeyPkJDO> result4 = (List<HasKeyPkJDO>) q.execute(entityWithId.getKey().getId()); 668 assertEquals(1, result4.size()); 669 assertEquals(entityWithId.getKey(), result4.get(0).getKey()); 670 } 671 672 public void testKeyQueryWithSorts() { 673 Entity flightEntity = newFlightEntity("1", "yam", "bam", 1, 2); 674 ds.put(null, flightEntity); 675 676 Query q = pm.newQuery( 677 "select from " + Flight.class.getName() 678 + " where id == key parameters String key order by id asc"); 679 @SuppressWarnings("unchecked") 680 List<Flight> flights = (List<Flight>) q.execute(KeyFactory.keyToString(flightEntity.getKey())); 681 assertEquals(1, flights.size()); 682 assertEquals(flightEntity.getKey(), KeyFactory.stringToKey(flights.get(0).getId())); 683 } 684 685 public void testKeyQuery_MultipleFilters() { 686 Entity flightEntity = newFlightEntity("1", "yam", "bam", 1, 2); 687 ds.put(null, flightEntity); 688 689 Query q = pm.newQuery( 690 "select from " + Flight.class.getName() 691 + " where id == key && origin == \"yam\" parameters String key"); 692 @SuppressWarnings("unchecked") 693 List<Flight> flights = (List<Flight>) q.execute(KeyFactory.keyToString(flightEntity.getKey())); 694 assertEquals(1, flights.size()); 695 assertEquals(flightEntity.getKey(), KeyFactory.stringToKey(flights.get(0).getId())); 696 } 697 698 public void testKeyQuery_NonEqualityFilter() { 699 Entity flightEntity1 = newFlightEntity("1", "yam", "bam", 1, 2); 700 ds.put(null, flightEntity1); 701 Entity flightEntity2 = newFlightEntity("1", "yam", "bam", 1, 2); 702 ds.put(null, flightEntity2); 703 704 Query q = pm.newQuery( 705 "select from " + Flight.class.getName() + " where id > key parameters String key"); 706 @SuppressWarnings("unchecked") 707 List<Flight> flights = (List<Flight>) q.execute(KeyFactory.keyToString(flightEntity1.getKey())); 708 assertEquals(1, flights.size()); 709 assertEquals(flightEntity2.getKey(), KeyFactory.stringToKey(flights.get(0).getId())); 710 } 711 712 public void testKeyQuery_SortByKey() { 713 Entity flightEntity1 = newFlightEntity("1", "yam", "bam", 1, 2); 714 ds.put(null, flightEntity1); 715 716 Entity flightEntity2 = newFlightEntity("1", "yam", "bam", 1, 2); 717 ds.put(null, flightEntity2); 718 719 Query q = pm.newQuery( 720 "select from " + Flight.class.getName() + " where origin == 'yam' order by id DESC"); 721 @SuppressWarnings("unchecked") 722 List<Flight> flights = (List<Flight>) q.execute(); 723 assertEquals(2, flights.size()); 724 assertEquals(flightEntity2.getKey(), KeyFactory.stringToKey(flights.get(0).getId())); 725 assertEquals(flightEntity1.getKey(), KeyFactory.stringToKey(flights.get(1).getId())); 726 } 727 728 public void testKeyQuery_FilterAndSortByKeyComponent() { 729 // filter by pk-id 730 assertQueryUnsupportedByDatastore( 731 "select from " + HasEncodedStringPkSeparateIdFieldJDO.class.getName() + " where id == 4"); 732 // sort by pk-id 733 assertQueryUnsupportedByDatastore( 734 "select from " + HasEncodedStringPkSeparateIdFieldJDO.class.getName() + " order by id"); 735 // filter by pk-id 736 assertQueryUnsupportedByDatastore( 737 "select from " + HasEncodedStringPkSeparateNameFieldJDO.class.getName() + " where name == 4"); 738 // sort by pk-id 739 assertQueryUnsupportedByDatastore( 740 "select from " + HasEncodedStringPkSeparateNameFieldJDO.class.getName() + " order by name"); 741 } 742 743 public void testAncestorQueryWithStringAncestor() { 744 Entity flightEntity = newFlightEntity("1", "yam", "bam", 1, 2); 745 ds.put(null, flightEntity); 746 Entity hasAncestorEntity = new Entity(HasStringAncestorStringPkJDO.class.getSimpleName(), flightEntity.getKey()); 747 ds.put(null, hasAncestorEntity); 748 749 Query q = pm.newQuery( 750 "select from " + HasStringAncestorStringPkJDO.class.getName() 751 + " where ancestorId == ancId parameters String ancId"); 752 @SuppressWarnings("unchecked") 753 List<HasStringAncestorStringPkJDO> haList = 754 (List<HasStringAncestorStringPkJDO>) q.execute(KeyFactory.keyToString(flightEntity.getKey())); 755 assertEquals(1, haList.size()); 756 assertEquals(flightEntity.getKey(), KeyFactory.stringToKey(haList.get(0).getAncestorId())); 757 758 assertEquals( 759 flightEntity.getKey(), getDatastoreQuery(q).getLatestDatastoreQuery().getAncestor()); 760 assertEquals(NO_FILTERS, getFilterPredicates(q)); 761 assertEquals(NO_SORTS, getSortPredicates(q)); 762 } 763 764 public void testAncestorQueryWithKeyAncestor() { 765 Entity e = new Entity("parent"); 766 ds.put(null, e); 767 Entity childEntity = new Entity(HasKeyAncestorStringPkJDO.class.getSimpleName(), e.getKey()); 768 ds.put(null, childEntity); 769 770 Query q = pm.newQuery( 771 "select from " + HasKeyAncestorStringPkJDO.class.getName() 772 + " where ancestorKey == ancId parameters " + Key.class.getName() + " ancId"); 773 @SuppressWarnings("unchecked") 774 List<HasKeyAncestorStringPkJDO> result = 775 (List<HasKeyAncestorStringPkJDO>) q.execute(e.getKey()); 776 assertEquals(1, result.size()); 777 assertEquals(e.getKey(), result.get(0).getAncestorKey()); 778 } 779 780 public void testIllegalAncestorQuery_BadOperator() { 781 Entity flightEntity = newFlightEntity("1", "yam", "bam", 1, 2); 782 ds.put(null, flightEntity); 783 Entity hasAncestorEntity = new Entity(HasStringAncestorStringPkJDO.class.getName(), flightEntity.getKey()); 784 ds.put(null, hasAncestorEntity); 785 786 Query q = pm.newQuery( 787 "select from " + HasStringAncestorStringPkJDO.class.getName() 788 + " where ancestorId > ancId parameters String ancId"); 789 q.addExtension(DatastoreManager.QUERYEXT_INMEMORY_WHEN_UNSUPPORTED, "false"); 790 try { 791 q.execute(KeyFactory.keyToString(flightEntity.getKey())); 792 fail ("expected udfe"); 793 } catch (JDOUserException jdoe) { 794 if (jdoe.getCause() instanceof DatastoreQuery.UnsupportedDatastoreFeatureException) { 795 // good 796 } 797 else { 798 throw jdoe; 799 } 800 } 801 } 802 803 public void testSortByFieldWithCustomColumn() { 804 ds.put(null, newFlightEntity("1", "yam", "bam", 1, 2, 400)); 805 ds.put(null, newFlightEntity("2", "yam", "bam", 1, 1, 300)); 806 ds.put(null, newFlightEntity("3", "yam", "bam", 2, 1, 200)); 807 Query q = pm.newQuery( 808 "select from " + Flight.class.getName() 809 + " where origin == \"yam\" && dest == \"bam\"" 810 + " order by flightNumber asc"); 811 @SuppressWarnings("unchecked") 812 List<Flight> result = (List<Flight>) q.execute(); 813 assertEquals(3, result.size()); 814 815 assertEquals("3", result.get(0).getName()); 816 assertEquals("2", result.get(1).getName()); 817 assertEquals("1", result.get(2).getName()); 818 } 819 820 public void testIllegalAncestorQuery_SortByAncestor() { 821 Entity flightEntity = newFlightEntity("1", "yam", "bam", 1, 2); 822 ds.put(null, flightEntity); 823 Entity hasAncestorEntity = new Entity(HasStringAncestorStringPkJDO.class.getName(), flightEntity.getKey()); 824 ds.put(null, hasAncestorEntity); 825 826 Query q = pm.newQuery( 827 "select from " + HasStringAncestorStringPkJDO.class.getName() 828 + " where ancestorId == ancId parameters String ancId order by ancestorId ASC"); 829 q.addExtension(DatastoreManager.QUERYEXT_INMEMORY_WHEN_UNSUPPORTED, "false"); 830 try { 831 q.execute(KeyFactory.keyToString(flightEntity.getKey())); 832 fail ("expected udfe"); 833 } catch (JDOUserException jdoe) { 834 if (jdoe.getCause() instanceof DatastoreQuery.UnsupportedDatastoreFeatureException) { 835 // good 836 } 837 else { 838 throw jdoe; 839 } 840 } 841 } 842 843 private interface FlightProvider { 844 Flight getFlight(Key key); 845 } 846 847 private class AttachedFlightProvider implements FlightProvider { 848 public Flight getFlight(Key key) { 849 return pm.getObjectById(Flight.class, key); 850 } 851 } 852 853 private class TransientFlightProvider implements FlightProvider { 854 public Flight getFlight(Key key) { 855 Flight f = new Flight(); 856 f.setId(KeyFactory.keyToString(key)); 857 return f; 858 } 859 } 860 861 private void testFilterByChildObject(FlightProvider fp) { 862 Entity parentEntity = new Entity(HasOneToOneJDO.class.getSimpleName()); 863 ds.put(null, parentEntity); 864 Entity flightEntity = newFlightEntity(parentEntity.getKey(), null, "f", "bos", "mia", 2, 4, 33); 865 ds.put(null, flightEntity); 866 867 Flight flight = fp.getFlight(flightEntity.getKey()); 868 Query q = pm.newQuery( 869 "select from " + HasOneToOneJDO.class.getName() 870 + " where flight == f parameters " + Flight.class.getName() + " f"); 871 List<HasOneToOneJDO> result = (List<HasOneToOneJDO>) q.execute(flight); 872 assertEquals(1, result.size()); 873 assertEquals(parentEntity.getKey(), KeyFactory.stringToKey(result.get(0).getId())); 874 } 875 876 public void testFilterByChildObject() { 877 testFilterByChildObject(new AttachedFlightProvider()); 878 commitTxn(); 879 beginTxn(); 880 testFilterByChildObject(new TransientFlightProvider()); 881 } 882 883 public void testFilterByNullChildObject() { 884 Entity parentEntity = new Entity(HasOneToOneJDO.class.getSimpleName()); 885 ds.put(null, parentEntity); 886 Entity flightEntity = newFlightEntity(parentEntity.getKey(), null, "f", "bos", "mia", 2, 4, 33); 887 ds.put(null, flightEntity); 888 889 Query q = pm.newQuery( 890 "select from " + HasOneToOneJDO.class.getName() 891 + " where flight == f parameters " + Flight.class.getName() + " f"); 892 q.addExtension(DatastoreManager.QUERYEXT_INMEMORY_WHEN_UNSUPPORTED, "false"); 893 try { 894 q.execute(null); 895 fail("expected exception"); 896 } catch (JDOFatalUserException e) { 897 // good 898 } 899 } 900 901 public void testContains() { 902 Entity e = Flight.newFlightEntity("name1", "bos1", "mia1", 23, 24); 903 Entity e2 = Flight.newFlightEntity("name2", "bos2", null, 25, 26); 904 Entity e3 = Flight.newFlightEntity("name3", "bos3", "mia2", 27, 28); 905 ds.put(null, Arrays.asList(e, e2, e3)); 906 907 Query q = pm.newQuery("select from " + Flight.class.getName() + " where :p1.contains(name)"); 908 List<Flight> flights = (List<Flight>) q.execute(Arrays.asList("name1", "name3")); 909 assertEquals(2, flights.size()); 910 assertEquals(KeyFactory.keyToString(e.getKey()), flights.get(0).getId()); 911 assertEquals(KeyFactory.keyToString(e3.getKey()), flights.get(1).getId()); 912 913 // Same but using executeWithMap 914 Query q2 = pm.newQuery("select from " + Flight.class.getName() + " where :p1.contains(name)"); 915 Map params = new HashMap(); 916 params.put("p1", Arrays.asList("name1", "name3")); 917 List<Flight> flights2 = (List<Flight>) q2.executeWithMap(params); 918 assertEquals(2, flights2.size()); 919 assertEquals(KeyFactory.keyToString(e.getKey()), flights2.get(0).getId()); 920 assertEquals(KeyFactory.keyToString(e3.getKey()), flights2.get(1).getId()); 921 922 q = pm.newQuery("select from " + Flight.class.getName() + " where :p1.contains(dest)"); 923 flights = (List<Flight>) q.execute(Arrays.asList(null, "mia1")); 924 assertEquals(2, flights.size()); 925 assertEquals(KeyFactory.keyToString(e2.getKey()), flights.get(0).getId()); 926 assertEquals(KeyFactory.keyToString(e.getKey()), flights.get(1).getId()); 927 928 q = pm.newQuery("select from " + Flight.class.getName() + " where :p1.contains(dest) || :p2.contains(dest)"); 929 flights = (List<Flight>) q.execute(Arrays.asList(null, "mia1"), Arrays.asList("mia2")); 930 assertEquals(3, flights.size()); 931 assertEquals(KeyFactory.keyToString(e2.getKey()), flights.get(0).getId()); 932 assertEquals(KeyFactory.keyToString(e.getKey()), flights.get(1).getId()); 933 assertEquals(KeyFactory.keyToString(e3.getKey()), flights.get(2).getId()); 934 } 935 936 public void testContainsOnlyForCollection() { 937 Entity e = Flight.newFlightEntity("name1", "bos1", "mia1", 23, 24); 938 Entity e2 = Flight.newFlightEntity("name2", "bos2", null, 25, 26); 939 Entity e3 = Flight.newFlightEntity("name3", "bos3", "mia2", 27, 28); 940 ds.put(null, Arrays.asList(e, e2, e3)); 941 942 try { 943 Query q = pm.newQuery("select from " + Flight.class.getName() + " where name.contains(:param)"); 944 q.addExtension(DatastoreManager.QUERYEXT_INMEMORY_WHEN_UNSUPPORTED, "false"); 945 q.execute("na"); 946 fail("Should have thrown an exception when invoking 'contains' on a String"); 947 } catch (JDOUserException ue) { 948 // Expected 949 } 950 } 951 952 public void testMultipleIn_Params() { 953 Entity e = Flight.newFlightEntity("name1", "mia1", "bos1", 23, 24); 954 Entity e2 = Flight.newFlightEntity("name2", "mia2", "bos2", 25, 26); 955 Entity e3 = Flight.newFlightEntity("name3", "mia3", "bos3", 27, 28); 956 ds.put(null, Arrays.asList(e, e2, e3)); 957 Query q = pm.newQuery("select from " + Flight.class.getName() + " where :p1.contains(name) && :p2.contains(origin)"); 958 List<Flight> flights = 959 (List<Flight>) q.execute(Utils.newArrayList("name1", "name3"), Utils.newArrayList("mia3", "mia2")); 960 assertEquals(1, flights.size()); 961 assertEquals(KeyFactory.keyToString(e3.getKey()), flights.get(0).getId()); 962 963 q = pm.newQuery("select from " + Flight.class.getName() + " where :p1.contains(name) || :p2.contains(name)"); 964 flights = 965 (List<Flight>) q.execute(Utils.newArrayList("name1", "name3"), Utils.newArrayList("name4", "name5")); 966 967 assertEquals(2, flights.size()); 968 assertEquals(KeyFactory.keyToString(e.getKey()), flights.get(0).getId()); 969 assertEquals(KeyFactory.keyToString(e3.getKey()), flights.get(1).getId()); 970 } 971 972 public void testMultipleIn_Params_KeyFilter() { 973 Entity e = Flight.newFlightEntity("name1", "mia1", "bos1", 23, 24); 974 Entity e2 = Flight.newFlightEntity("name2", "mia2", "bos2", 25, 26); 975 Entity e3 = Flight.newFlightEntity("name3", "mia3", "bos3", 27, 28); 976 ds.put(null, Arrays.asList(e, e2, e3)); 977 Query q = pm.newQuery( 978 "select from " + Flight.class.getName() + " where :p1.contains(id) && :p2.contains(origin)"); 979 @SuppressWarnings("unchecked") 980 List<Flight> flights = (List<Flight>) q.execute( 981 Utils.newArrayList(KeyFactory.keyToString(e2.getKey())), Utils.newArrayList("mia3", "mia2")); 982 assertEquals(1, flights.size()); 983 assertEquals(KeyFactory.keyToString(e2.getKey()), flights.get(0).getId()); 984 985 q = pm.newQuery( 986 "select from " + Flight.class.getName() + " where (id == :p1 || id ==:p2) && :p3.contains(origin)"); 987 @SuppressWarnings("unchecked") 988 List<Flight> flights2 = (List<Flight>) q.execute( 989 e2.getKey(), e3.getKey(), Utils.newArrayList("mia3", "dne")); 990 assertEquals(1, flights2.size()); 991 } 992 993 public void testOr_Literals() { 994 Entity e = Flight.newFlightEntity("name1", "bos1", "mia1", 23, 24); 995 Entity e2 = Flight.newFlightEntity("name2", "bos2", null, 25, 26); 996 Entity e3 = Flight.newFlightEntity("name3", "bos3", "mia2", 27, 28); 997 ds.put(null, Arrays.asList(e, e2, e3)); 998 Query q = pm.newQuery("select from " + Flight.class.getName() + 999 " where name == 'name1' || name == 'name3'"); 1000 List<Flight> flights = (List<Flight>) q.execute(); 1001 assertEquals(2, flights.size()); 1002 assertEquals(KeyFactory.keyToString(e.getKey()), flights.get(0).getId()); 1003 assertEquals(KeyFactory.keyToString(e3.getKey()), flights.get(1).getId()); 1004 1005 q = pm.newQuery("select from " + Flight.class.getName() + 1006 " where dest == null || dest == 'mia1'"); 1007 flights = (List<Flight>) q.execute(); 1008 assertEquals(2, flights.size()); 1009 assertEquals(KeyFactory.keyToString(e2.getKey()), flights.get(0).getId()); 1010 assertEquals(KeyFactory.keyToString(e.getKey()), flights.get(1).getId()); 1011 } 1012 1013 public void testOr_Params() { 1014 Entity e = Flight.newFlightEntity("name1", "bos1", "mia1", 23, 24); 1015 Entity e2 = Flight.newFlightEntity("name2", "bos2", "mia2", 25, 26); 1016 Entity e3 = Flight.newFlightEntity("name3", "bos3", "mia3", 27, 28); 1017 ds.put(null, Arrays.asList(e, e2, e3)); 1018 Query q = pm.newQuery("select from " + Flight.class.getName() + 1019 " where name == :p1 || name == :p2"); 1020 List<Flight> flights = (List<Flight>) q.execute("name1", "name3"); 1021 assertEquals(2, flights.size()); 1022 assertEquals(KeyFactory.keyToString(e.getKey()), flights.get(0).getId()); 1023 assertEquals(KeyFactory.keyToString(e3.getKey()), flights.get(1).getId()); 1024 } 1025 1026 public void testMultipleOr_Literals() { 1027 Entity e = Flight.newFlightEntity("name1", "bos1", "mia1", 23, 24); 1028 Entity e2 = Flight.newFlightEntity("name2", "bos2", "mia2", 25, 26); 1029 Entity e3 = Flight.newFlightEntity("name3", "bos3", "mia3", 27, 28); 1030 ds.put(null, Arrays.asList(e, e2, e3)); 1031 Query q = pm.newQuery("select from " + Flight.class.getName() + " where " 1032 + "(name == 'name1' || name == 'name3') && " 1033 + "(origin == 'bos3' || origin == 'bos2')"); 1034 List<Flight> flights = (List<Flight>) q.execute(); 1035 assertEquals(1, flights.size()); 1036 assertEquals(KeyFactory.keyToString(e3.getKey()), flights.get(0).getId()); 1037 } 1038 1039 public void testMultipleOr_Params() { 1040 Entity e = Flight.newFlightEntity("name1", "bos1", "mia1", 23, 24); 1041 Entity e2 = Flight.newFlightEntity("name2", "bos2", "mia2", 25, 26); 1042 Entity e3 = Flight.newFlightEntity("name3", "bos3", "mia3", 27, 28); 1043 ds.put(null, Arrays.asList(e, e2, e3)); 1044 Query q = pm.newQuery("select from " + Flight.class.getName() + " where " 1045 + "(name == :p1 || name == :p2) && " 1046 + "(origin == :p3 || origin == :p4)"); 1047 Map<String, String> paramMap = Utils.newHashMap(); 1048 paramMap.put("p1", "name1"); 1049 paramMap.put("p2", "name3"); 1050 paramMap.put("p3", "bos3"); 1051 paramMap.put("p4", "bos2"); 1052 List<Flight> flights = (List<Flight>) q.executeWithMap(paramMap); 1053 assertEquals(1, flights.size()); 1054 assertEquals(KeyFactory.keyToString(e3.getKey()), flights.get(0).getId()); 1055 } 1056 1057 public void testExecuteWithArray() { 1058 Entity e = Flight.newFlightEntity("name1", "bos1", "mia1", 23, 24); 1059 Entity e2 = Flight.newFlightEntity("name2", "bos2", "mia2", 25, 26); 1060 Entity e3 = Flight.newFlightEntity("name3", "bos3", "mia3", 27, 28); 1061 ds.put(null, Arrays.asList(e, e2, e3)); 1062 Query q = pm.newQuery("select from " + Flight.class.getName() + " where " 1063 + "(name == :p1 || name == :p2) && " 1064 + "(origin == :p3 || origin == :p4)"); 1065 Map<String, String> paramMap = Utils.newHashMap(); 1066 paramMap.put("p1", "name1"); 1067 paramMap.put("p2", "name3"); 1068 paramMap.put("p3", "bos3"); 1069 paramMap.put("p4", "bos2"); 1070 List<Flight> flights = (List<Flight>) q.executeWithArray("name1", "name3", "bos3", "bos2"); 1071 assertEquals(1, flights.size()); 1072 …
Large files files are truncated, but you can click here to view the full file