/*****************************************************************
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
****************************************************************/
package org.apache.cayenne.query;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertSame;
import static org.junit.Assert.assertTrue;
import java.sql.Types;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import org.apache.cayenne.Cayenne;
import org.apache.cayenne.DataRow;
import org.apache.cayenne.ObjectContext;
import org.apache.cayenne.ResultBatchIterator;
import org.apache.cayenne.ResultIterator;
import org.apache.cayenne.ResultIteratorCallback;
import org.apache.cayenne.di.Inject;
import org.apache.cayenne.exp.Expression;
import org.apache.cayenne.exp.ExpressionFactory;
import org.apache.cayenne.map.DbEntity;
import org.apache.cayenne.map.EntityResolver;
import org.apache.cayenne.map.ObjEntity;
import org.apache.cayenne.map.ObjRelationship;
import org.apache.cayenne.test.jdbc.DBHelper;
import org.apache.cayenne.test.jdbc.TableHelper;
import org.apache.cayenne.testdo.testmap.Artist;
import org.apache.cayenne.testdo.testmap.ArtistExhibit;
import org.apache.cayenne.testdo.testmap.Exhibit;
import org.apache.cayenne.testdo.testmap.Gallery;
import org.apache.cayenne.testdo.testmap.Painting;
import org.apache.cayenne.unit.UnitDbAdapter;
import org.apache.cayenne.unit.di.server.CayenneProjects;
import org.apache.cayenne.unit.di.server.ServerCase;
import org.apache.cayenne.unit.di.server.UseServerRuntime;
import org.junit.Before;
import org.junit.Test;
@UseServerRuntime(CayenneProjects.TESTMAP_PROJECT)
public class SelectQueryIT extends ServerCase {
@Inject
private ObjectContext context;
@Inject
private DBHelper dbHelper;
@Inject
private UnitDbAdapter accessStackAdapter;
private TableHelper tArtist;
private TableHelper tPainting;
@Before
public void before() {
this.tArtist = new TableHelper(dbHelper, "ARTIST").setColumns("ARTIST_ID", "ARTIST_NAME", "DATE_OF_BIRTH")
.setColumnTypes(Types.BIGINT, Types.CHAR, Types.DATE);
tPainting = new TableHelper(dbHelper, "PAINTING").setColumns("PAINTING_ID", "ARTIST_ID", "PAINTING_TITLE")
.setColumnTypes(Types.INTEGER, Types.BIGINT, Types.VARCHAR);
}
protected void createArtistsDataSet() throws Exception {
long dateBase = System.currentTimeMillis();
for (int i = 1; i <= 20; i++) {
tArtist.insert(i, "artist" + i, new java.sql.Date(dateBase + 10000 * i));
}
}
protected void createArtistsWildcardDataSet() throws Exception {
tArtist.insert(1, "_X", null);
tArtist.insert(2, "Y_", null);
}
@Test
public void testSelect_QualfierOnToMany() throws Exception {
tArtist.insert(1, "A1", new java.sql.Date(System.currentTimeMillis()));
tPainting.insert(4, 1, "P1");
tPainting.insert(5, 1, "P2");
tPainting.insert(6, null, "P3");
List<Artist> objects = SelectQuery.query(Artist.class,
Artist.PAINTING_ARRAY.dot(Painting.PAINTING_TITLE).like("P%")).select(context);
// make sure no duplicate objects are returned when matching on a
// to-many relationship
assertEquals(1, objects.size());
}
@Test
public void testFetchLimit() throws Exception {
createArtistsDataSet();
SelectQuery<Artist> query = new SelectQuery<>(Artist.class);
query.setFetchLimit(7);
List<?> objects = context.performQuery(query);
assertNotNull(objects);
assertEquals(7, objects.size());
}
@Test
public void testFetchOffset() throws Exception {
createArtistsDataSet();
int totalRows = new SelectQuery<>(Artist.class).select(context).size();
SelectQuery<Artist> query = new SelectQuery<>(Artist.class);
query.addOrdering("db:" + Artist.ARTIST_ID_PK_COLUMN, SortOrder.ASCENDING);
query.setFetchOffset(5);
List<Artist> results = context.select(query);
assertEquals(totalRows - 5, results.size());
assertEquals("artist6", results.get(0).getArtistName());
}
@Test
public void testDbEntityRoot() throws Exception {
createArtistsDataSet();
DbEntity artistDbEntity = context.getEntityResolver().getDbEntity("ARTIST");
SelectQuery<DataRow> query = new SelectQuery<>(artistDbEntity);
List<DataRow> results = context.select(query);
assertEquals(20, results.size());
assertTrue(results.get(0) instanceof DataRow);
}
@Test
public void testFetchLimitWithOffset() throws Exception {
createArtistsDataSet();
SelectQuery<Artist> query = new SelectQuery<>(Artist.class);
query.addOrdering("db:" + Artist.ARTIST_ID_PK_COLUMN, SortOrder.ASCENDING);
query.setFetchOffset(15);
query.setFetchLimit(4);
List<Artist> results = context.select(query);
assertEquals(4, results.size());
assertEquals("artist16", results.get(0).getArtistName());
}
@Test
public void testFetchOffsetWithQualifier() throws Exception {
createArtistsDataSet();
SelectQuery<Artist> query = new SelectQuery<>(Artist.class);
query.setQualifier(ExpressionFactory.exp("db:ARTIST_ID > 3"));
query.setFetchOffset(5);
List<Artist> objects = query.select(context);
int size = objects.size();
SelectQuery<Artist> sizeQ = new SelectQuery<>(Artist.class);
sizeQ.setQualifier(ExpressionFactory.exp("db:ARTIST_ID > 3"));
List<Artist> objects1 = sizeQ.select(context);
int sizeAll = objects1.size();
assertEquals(size, sizeAll - 5);
}
@Test
public void testFetchLimitWithQualifier() throws Exception {
createArtistsDataSet();
SelectQuery<Artist> query = new SelectQuery<>(Artist.class);
query.setQualifier(ExpressionFactory.exp("db:ARTIST_ID > 3"));
query.setFetchLimit(7);
List<Artist> objects = query.select(context);
assertEquals(7, objects.size());
}
@Test
public void testSelectAllObjectsRootEntityName() throws Exception {
createArtistsDataSet();
SelectQuery<Artist> query = new SelectQuery<>("Artist");
List<?> objects = context.performQuery(query);
assertEquals(20, objects.size());
}
@Test
public void testSelectAllObjectsRootClass() throws Exception {
createArtistsDataSet();
SelectQuery<Artist> query = new SelectQuery<>(Artist.class);
List<?> objects = context.performQuery(query);
assertEquals(20, objects.size());
}
@Test
public void testSelectAllObjectsRootObjEntity() throws Exception {
createArtistsDataSet();
ObjEntity artistEntity = context.getEntityResolver().getObjEntity(Artist.class);
SelectQuery<Artist> query = new SelectQuery<>(artistEntity);
List<?> objects = context.performQuery(query);
assertEquals(20, objects.size());
}
@Test
public void testSelectLikeExactMatch() throws Exception {
createArtistsDataSet();
SelectQuery<Artist> query = new SelectQuery<>(Artist.class);
Expression qual = ExpressionFactory.likeExp("artistName", "artist1");
query.setQualifier(qual);
List<?> objects = context.performQuery(query);
assertEquals(1, objects.size());
}
@Test
public void testSelectNotLikeSingleWildcardMatch() throws Exception {
createArtistsDataSet();
SelectQuery<Artist> query = new SelectQuery<>(Artist.class);
Expression qual = ExpressionFactory.notLikeExp("artistName", "artist11%");
query.setQualifier(qual);
List<?> objects = context.performQuery(query);
assertEquals(19, objects.size());
}
@Test
public void testSelectNotLikeIgnoreCaseSingleWildcardMatch() throws Exception {
createArtistsDataSet();
SelectQuery<Artist> query = new SelectQuery<>(Artist.class);
Expression qual = ExpressionFactory.notLikeIgnoreCaseExp("artistName", "aRtIsT11%");
query.setQualifier(qual);
List<?> objects = context.performQuery(query);
assertEquals(19, objects.size());
}
/**
* SQL Server failure:
* http://stackoverflow.com/questions/14962419/is-the-like-operator-case-sensitive-with-ms-sql-server
*/
@Test
public void testSelectLikeCaseSensitive() throws Exception {
if (!accessStackAdapter.supportsCaseSensitiveLike()) {
return;
}
createArtistsDataSet();
SelectQuery<Artist> query = new SelectQuery<>(Artist.class);
Expression qual = ExpressionFactory.likeExp("artistName", "aRtIsT%");
query.setQualifier(qual);
List<?> objects = context.performQuery(query);
assertEquals(0, objects.size());
}
@Test
public void testSelectLikeSingle_WildcardMatch() throws Exception {
createArtistsDataSet();
SelectQuery<Artist> query = new SelectQuery<>(Artist.class);
Expression qual = ExpressionFactory.likeExp("artistName", "artist11%");
query.setQualifier(qual);
List<?> objects = context.performQuery(query);
assertEquals(1, objects.size());
}
@Test
public void testSelectLikeSingle_WildcardMatchAndEscape() throws Exception {
if(!accessStackAdapter.supportsEscapeInLike()) {
return;
}
createArtistsWildcardDataSet();
SelectQuery<Artist> query = new SelectQuery<>(Artist.class);
query.andQualifier(ExpressionFactory.likeExp("artistName", "=_%", '='));
List<?> objects = context.performQuery(query);
assertEquals(1, objects.size());
}
@Test
public void testSelectLike_WildcardMatchAndEscape_AndOtherCriteria() throws Exception {
if(!accessStackAdapter.supportsEscapeInLike()) {
return;
}
createArtistsWildcardDataSet();
// CAY-1978 - combining LIKE..ESCAPE with another clause generated bad
// syntax
SelectQuery<Artist> query = new SelectQuery<>(Artist.class);
query.andQualifier(ExpressionFactory.likeExp("artistName", "=_%", '='));
query.andQualifier(Artist.ARTIST_NAME.eq("_X"));
List<?> objects = context.performQuery(query);
assertEquals(1, objects.size());
}
@Test
public void testSelectLike_WildcardMatchIgnoreCaseAndEscape_AndOtherCriteria() throws Exception {
if(!accessStackAdapter.supportsEscapeInLike()) {
return;
}
createArtistsWildcardDataSet();
// CAY-1978 - combining LIKE..ESCAPE with another clause generated bad
// SQL
SelectQuery<Artist> query = new SelectQuery<>(Artist.class);
query.andQualifier(ExpressionFactory.likeIgnoreCaseExp("artistName", "=_%", '='));
query.andQualifier(Artist.ARTIST_NAME.eq("_X"));
List<?> objects = context.performQuery(query);
assertEquals(1, objects.size());
}
@Test
public void testSelectLike_WildcardMatchAndEscapeMulti_AndOtherCriteria() throws Exception {
if(!accessStackAdapter.supportsEscapeInLike()) {
return;
}
tArtist.insert(1, "_X_", null);
tArtist.insert(2, "_X", null);
SelectQuery<Artist> query = new SelectQuery<>(Artist.class);
query.andQualifier(ExpressionFactory.likeExp("artistName", "#_%#_", '#'));
query.andQualifier(Artist.ARTIST_NAME.eq("_X_"));
List<?> objects = context.performQuery(query);
assertEquals(1, objects.size());
}
@Test
public void testSelectLikeMultiple_WildcardMatch() throws Exception {
createArtistsDataSet();
SelectQuery<Artist> query = new SelectQuery<>(Artist.class);
Expression qual = ExpressionFactory.likeExp("artistName", "artist1%");
query.setQualifier(qual);
List<?> objects = context.performQuery(query);
assertEquals(11, objects.size());
}
/**
* Test how "like ignore case" works when using uppercase parameter.
*/
@Test
public void testSelectLikeIgnoreCaseObjects1() throws Exception {
createArtistsDataSet();
SelectQuery<Artist> query = new SelectQuery<>(Artist.class);
Expression qual = ExpressionFactory.likeIgnoreCaseExp("artistName", "ARTIST%");
query.setQualifier(qual);
List<?> objects = context.performQuery(query);
assertEquals(20, objects.size());
}
/** Test how "like ignore case" works when using lowercase parameter. */
@Test
public void testSelectLikeIgnoreCaseObjects2() throws Exception {
createArtistsDataSet();
SelectQuery<Artist> query = new SelectQuery<>(Artist.class);
Expression qual = ExpressionFactory.likeIgnoreCaseExp("artistName", "artist%");
query.setQualifier(qual);
List<?> objects = context.performQuery(query);
assertEquals(20, objects.size());
}
@Test
public void testSelectIn() throws Exception {
createArtistsDataSet();
SelectQuery<Artist> query = new SelectQuery<>(Artist.class);
Expression qual = ExpressionFactory.exp("artistName in ('artist1', 'artist2')");
query.setQualifier(qual);
List<?> objects = context.performQuery(query);
assertEquals(2, objects.size());
}
@Test
public void testSelectParameterizedIn() throws Exception {
createArtistsDataSet();
SelectQuery<Artist> query = new SelectQuery<>(Artist.class);
Expression qual = ExpressionFactory.exp("artistName in $list");
query.setQualifier(qual);
query = query.queryWithParameters(Collections.singletonMap("list", new Object[] { "artist1", "artist2" }));
List<?> objects = context.performQuery(query);
assertEquals(2, objects.size());
}
@Test
public void testSelectParameterizedEmptyIn() throws Exception {
createArtistsDataSet();
SelectQuery<Artist> query = new SelectQuery<>(Artist.class);
Expression qual = ExpressionFactory.exp("artistName in $list");
query.setQualifier(qual);
query = query.queryWithParameters(Collections.singletonMap("list", new Object[] {}));
List<?> objects = context.performQuery(query);
assertEquals(0, objects.size());
}
@Test
public void testSelectParameterizedEmptyNotIn() throws Exception {
createArtistsDataSet();
SelectQuery<Artist> query = new SelectQuery<>(Artist.class);
Expression qual = ExpressionFactory.exp("artistName not in $list");
query.setQualifier(qual);
query = query.queryWithParameters(Collections.singletonMap("list", new Object[] {}));
List<?> objects = context.performQuery(query);
assertEquals(20, objects.size());
}
@Test
public void testSelectEmptyIn() throws Exception {
createArtistsDataSet();
SelectQuery<Artist> query = new SelectQuery<>(Artist.class);
Expression qual = ExpressionFactory.inExp("artistName");
query.setQualifier(qual);
List<?> objects = context.performQuery(query);
assertEquals(0, objects.size());
}
@Test
public void testSelectEmptyNotIn() throws Exception {
createArtistsDataSet();
SelectQuery<Artist> query = new SelectQuery<>(Artist.class);
Expression qual = ExpressionFactory.notInExp("artistName");
query.setQualifier(qual);
List<?> objects = context.performQuery(query);
assertEquals(20, objects.size());
}
@Test
public void testSelectBooleanTrue() throws Exception {
createArtistsDataSet();
SelectQuery<Artist> query = new SelectQuery<>(Artist.class);
Expression qual = ExpressionFactory.expTrue();
qual = qual.andExp(ExpressionFactory.matchExp("artistName", "artist1"));
query.setQualifier(qual);
List<?> objects = context.performQuery(query);
assertEquals(1, objects.size());
}
@Test
public void testSelectBooleanNotTrueOr() throws Exception {
createArtistsDataSet();
SelectQuery<Artist> query = new SelectQuery<>(Artist.class);
Expression qual = ExpressionFactory.expTrue();
qual = qual.notExp();
qual = qual.orExp(ExpressionFactory.matchExp("artistName", "artist1"));
query.setQualifier(qual);
List<?> objects = context.performQuery(query);
assertEquals(1, objects.size());
}
@Test
public void testSelectBooleanFalse() throws Exception {
createArtistsDataSet();
SelectQuery<Artist> query = new SelectQuery<>(Artist.class);
Expression qual = ExpressionFactory.expFalse();
qual = qual.andExp(ExpressionFactory.matchExp("artistName", "artist1"));
query.setQualifier(qual);
List<?> objects = context.performQuery(query);
assertEquals(0, objects.size());
}
@Test
public void testSelectBooleanFalseOr() throws Exception {
createArtistsDataSet();
SelectQuery<Artist> query = new SelectQuery<>(Artist.class);
Expression qual = ExpressionFactory.expFalse();
qual = qual.orExp(ExpressionFactory.matchExp("artistName", "artist1"));
query.setQualifier(qual);
List<?> objects = context.performQuery(query);
assertEquals(1, objects.size());
}
@Test
public void testSelect() throws Exception {
createArtistsDataSet();
SelectQuery<Artist> query = new SelectQuery<>(Artist.class);
List<?> objects = query.select(context);
assertEquals(20, objects.size());
}
@Test
public void testSelectOne() throws Exception {
createArtistsDataSet();
SelectQuery<Artist> query = new SelectQuery<>(Artist.class);
Expression qual = ExpressionFactory.matchExp("artistName", "artist1");
query.setQualifier(qual);
Artist artist = (Artist) query.selectOne(context);
assertEquals("artist1", artist.getArtistName());
}
@Test
public void testSelectFirst() throws Exception {
createArtistsDataSet();
SelectQuery<Artist> query = new SelectQuery<>(Artist.class);
query.addOrdering(new Ordering(Artist.ARTIST_NAME.getName()));
Artist artist = query.selectFirst(context);
assertNotNull(artist);
assertEquals("artist1", artist.getArtistName());
}
@Test
public void testSelectFirstByContext() throws Exception {
createArtistsDataSet();
SelectQuery<Artist> query = new SelectQuery<>(Artist.class);
query.addOrdering(new Ordering(Artist.ARTIST_NAME.getName()));
Artist artist = context.selectFirst(query);
assertNotNull(artist);
assertEquals("artist1", artist.getArtistName());
}
@Test
public void testIterate() throws Exception {
createArtistsDataSet();
SelectQuery<Artist> q1 = new SelectQuery<>(Artist.class);
final int[] count = new int[1];
q1.iterate(context, new ResultIteratorCallback<Artist>() {
@Override
public void next(Artist object) {
assertNotNull(object.getArtistName());
count[0]++;
}
});
assertEquals(20, count[0]);
}
@Test
public void testIterator() throws Exception {
createArtistsDataSet();
SelectQuery<Artist> q1 = new SelectQuery<>(Artist.class);
try (ResultIterator<Artist> it = q1.iterator(context);) {
int count = 0;
for (@SuppressWarnings("unused")
Artist a : it) {
count++;
}
assertEquals(20, count);
}
}
@Test
public void testBatchIterator() throws Exception {
createArtistsDataSet();
SelectQuery<Artist> q1 = new SelectQuery<>(Artist.class);
try (ResultBatchIterator<Artist> it = q1.batchIterator(context, 5);) {
int count = 0;
for (List<Artist> artistList : it) {
count++;
assertEquals(5, artistList.size());
}
assertEquals(4, count);
}
}
/**
* Tests that all queries specified in prefetch are executed in a more
* complex prefetch scenario.
*/
@Test
public void testRouteWithPrefetches() {
EntityResolver resolver = context.getEntityResolver();
MockQueryRouter router = new MockQueryRouter();
SelectQuery<Artist> q = new SelectQuery<>(Artist.class, ExpressionFactory.matchExp("artistName", "a"));
q.route(router, resolver, null);
assertEquals(1, router.getQueryCount());
q.addPrefetch("paintingArray");
router.reset();
q.route(router, resolver, null);
assertEquals(2, router.getQueryCount());
q.addPrefetch("paintingArray.toGallery");
router.reset();
q.route(router, resolver, null);
assertEquals(3, router.getQueryCount());
q.addPrefetch("artistExhibitArray.toExhibit");
router.reset();
q.route(router, resolver, null);
assertEquals(4, router.getQueryCount());
q.removePrefetch("paintingArray");
router.reset();
q.route(router, resolver, null);
assertEquals(3, router.getQueryCount());
}
/**
* Tests that all queries specified in prefetch are executed in a more
* complex prefetch scenario with no reverse obj relationships.
*/
@Test
public void testRouteQueryWithPrefetchesNoReverse() {
EntityResolver resolver = context.getEntityResolver();
ObjEntity paintingEntity = resolver.getObjEntity(Painting.class);
ObjEntity galleryEntity = resolver.getObjEntity(Gallery.class);
ObjEntity artistExhibitEntity = resolver.getObjEntity(ArtistExhibit.class);
ObjEntity exhibitEntity = resolver.getObjEntity(Exhibit.class);
ObjRelationship paintingToArtistRel = paintingEntity.getRelationship("toArtist");
paintingEntity.removeRelationship("toArtist");
ObjRelationship galleryToPaintingRel = galleryEntity.getRelationship("paintingArray");
galleryEntity.removeRelationship("paintingArray");
ObjRelationship artistExhibitToArtistRel = artistExhibitEntity.getRelationship("toArtist");
artistExhibitEntity.removeRelationship("toArtist");
ObjRelationship exhibitToArtistExhibitRel = exhibitEntity.getRelationship("artistExhibitArray");
exhibitEntity.removeRelationship("artistExhibitArray");
Expression e = ExpressionFactory.matchExp("artistName", "artist1");
SelectQuery<Artist> q = new SelectQuery<>(Artist.class, e);
q.addPrefetch("paintingArray");
q.addPrefetch("paintingArray.toGallery");
q.addPrefetch("artistExhibitArray.toExhibit");
try {
MockQueryRouter router = new MockQueryRouter();
q.route(router, resolver, null);
assertEquals(4, router.getQueryCount());
} finally {
paintingEntity.addRelationship(paintingToArtistRel);
galleryEntity.addRelationship(galleryToPaintingRel);
artistExhibitEntity.addRelationship(artistExhibitToArtistRel);
exhibitEntity.addRelationship(exhibitToArtistExhibitRel);
}
}
/**
* Test prefetching with qualifier on the root query being the path to the
* prefetch.
*/
@Test
public void testRouteQueryWithPrefetchesPrefetchExpressionPath() {
// find the painting not matching the artist (this is the case where
// such prefetch
// at least makes sense)
Expression exp = ExpressionFactory.noMatchExp("toArtist", new Object());
SelectQuery<Painting> q = new SelectQuery<>(Painting.class, exp);
q.addPrefetch("toArtist");
// test how prefetches are resolved in this case - this was a stumbling
// block for
// a while
EntityResolver resolver = context.getEntityResolver();
MockQueryRouter router = new MockQueryRouter();
q.route(router, resolver, null);
assertEquals(2, router.getQueryCount());
}
@Test
public void testLeftJoinAndPrefetchToMany() throws Exception {
createArtistsDataSet();
SelectQuery<Artist> query = new SelectQuery<>(Artist.class, ExpressionFactory.matchExp(
"paintingArray+.toGallery", null));
query.addPrefetch("artistExhibitArray");
context.select(query);
// TODO: assertions?
}
@Test
public void testLeftJoinAndPrefetchToOne() throws Exception {
createArtistsDataSet();
SelectQuery<Painting> query = new SelectQuery<>(Painting.class, ExpressionFactory.matchExp(
"toArtist+.artistName", null));
query.addPrefetch("toGallery");
context.select(query);
// TODO: assertions?
}
@Test
public void testMatchObject() {
Artist a1 = context.newObject(Artist.class);
a1.setArtistName("a1");
Artist a2 = context.newObject(Artist.class);
a2.setArtistName("a2");
Artist a3 = context.newObject(Artist.class);
a3.setArtistName("a3");
context.commitChanges();
SelectQuery<Artist> query = new SelectQuery<>(Artist.class);
query.setQualifier(ExpressionFactory.matchExp(a2));
Artist result = query.selectOne(context);
assertSame(a2, result);
}
@Test
public void testMatchObjects() {
Artist a1 = context.newObject(Artist.class);
a1.setArtistName("a1");
Artist a2 = context.newObject(Artist.class);
a2.setArtistName("a2");
Artist a3 = context.newObject(Artist.class);
a3.setArtistName("a3");
context.commitChanges();
SelectQuery<Artist> query = new SelectQuery<>(Artist.class);
query.setQualifier(ExpressionFactory.matchAnyExp(a1, a3));
query.addOrdering(Artist.ARTIST_NAME.asc());
List<Artist> list = query.select(context);
assertEquals(list.size(), 2);
assertSame(a1, list.get(0));
assertSame(a3, list.get(1));
}
@Test
public void testMatchByRelatedObject() {
Artist a1 = context.newObject(Artist.class);
a1.setArtistName("a1");
Artist a2 = context.newObject(Artist.class);
a2.setArtistName("a2");
Painting p1 = context.newObject(Painting.class);
p1.setPaintingTitle("p1");
p1.setToArtist(a1);
Painting p2 = context.newObject(Painting.class);
p2.setPaintingTitle("p2");
p2.setToArtist(a2);
context.commitChanges();
SelectQuery<Painting> query = new SelectQuery<>(Painting.class);
query.setQualifier(ExpressionFactory.matchExp("toArtist", a1));
assertSame(p1, query.selectOne(context));
}
@Test
public void testMatchByRelatedObjectId() {
Artist a1 = context.newObject(Artist.class);
a1.setArtistName("a1");
Artist a2 = context.newObject(Artist.class);
a2.setArtistName("a2");
Painting p1 = context.newObject(Painting.class);
p1.setPaintingTitle("p1");
p1.setToArtist(a1);
Painting p2 = context.newObject(Painting.class);
p2.setPaintingTitle("p2");
p2.setToArtist(a2);
context.commitChanges();
SelectQuery<Painting> query = new SelectQuery<>(Painting.class);
query.setQualifier(ExpressionFactory.matchExp("toArtist", a1.getObjectId()));
assertSame(p1, query.selectOne(context));
}
@Test
public void testMatchByRelatedObjectIdValue() {
Artist a1 = context.newObject(Artist.class);
a1.setArtistName("a1");
Artist a2 = context.newObject(Artist.class);
a2.setArtistName("a2");
Painting p1 = context.newObject(Painting.class);
p1.setPaintingTitle("p1");
p1.setToArtist(a1);
Painting p2 = context.newObject(Painting.class);
p2.setPaintingTitle("p2");
p2.setToArtist(a2);
context.commitChanges();
SelectQuery<Painting> query = new SelectQuery<>(Painting.class);
query.setQualifier(ExpressionFactory.matchExp("toArtist", Cayenne.longPKForObject(a1)));
assertSame(p1, query.selectOne(context));
}
@Test
public void testSelect_WithOrdering() {
Artist a1 = context.newObject(Artist.class);
a1.setArtistName("a1");
Artist a2 = context.newObject(Artist.class);
a2.setArtistName("a2");
Artist a3 = context.newObject(Artist.class);
a3.setArtistName("a3");
context.commitChanges();
List<Ordering> orderings = Arrays.asList(new Ordering("artistName", SortOrder.ASCENDING));
SelectQuery<Artist> query = new SelectQuery<>(Artist.class, null, orderings);
List<Artist> list = context.select(query);
assertEquals(list.size(), 3);
assertSame(list.get(0), a1);
assertSame(list.get(1), a2);
assertSame(list.get(2), a3);
}
/**
* Tests INs with more than 1000 elements
*/
@Test
public void testSelectLongIn() {
// not all adapters strip INs, so we just make sure query with such
// qualifier
// fires OK
Object[] numbers = new String[2009];
for (int i = 0; i < numbers.length; i++) {
numbers[i] = "" + i;
}
SelectQuery<Artist> query = new SelectQuery<>(Artist.class,
ExpressionFactory.inExp("artistName", numbers));
context.performQuery(query);
}
@Test
public void testCacheOffsetAndLimit() throws Exception {
createArtistsDataSet();
SelectQuery<Artist> query1 = new SelectQuery<>(Artist.class);
query1.setCacheStrategy(QueryCacheStrategy.SHARED_CACHE);
query1.setFetchOffset(0);
query1.setFetchLimit(10);
context.performQuery(query1);
SelectQuery<Artist> query2 = new SelectQuery<>(Artist.class);
query2.setCacheStrategy(QueryCacheStrategy.SHARED_CACHE);
query2.setFetchOffset(10);
query2.setFetchLimit(10);
context.performQuery(query2);
SelectQuery<Artist> query3 = new SelectQuery<>(Artist.class);
query3.setCacheStrategy(QueryCacheStrategy.SHARED_CACHE);
query3.setFetchOffset(10);
query3.setFetchLimit(10);
context.performQuery(query3);
assertFalse(query1.metaData.getCacheKey().equals(query2.metaData.cacheKey));
assertEquals(query2.metaData.getCacheKey(), query3.metaData.getCacheKey());
}
}