/***************************************************************** * 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.access; import org.apache.cayenne.DataRow; 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.query.SelectQuery; 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.Painting; import org.apache.cayenne.tx.BaseTransaction; 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; import java.util.List; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertNull; @UseServerRuntime(CayenneProjects.TESTMAP_PROJECT) public class DataContextIteratedQueryIT extends ServerCase { @Inject protected DBHelper dbHelper; @Inject private DataContext context; private TableHelper tArtist; private TableHelper tExhibit; private TableHelper tGallery; private TableHelper tPainting; @Before public void before() throws Exception { tArtist = new TableHelper(dbHelper, "ARTIST"); tArtist.setColumns("ARTIST_ID", "ARTIST_NAME"); tExhibit = new TableHelper(dbHelper, "EXHIBIT"); tExhibit.setColumns("EXHIBIT_ID", "GALLERY_ID", "OPENING_DATE", "CLOSING_DATE"); tGallery = new TableHelper(dbHelper, "GALLERY"); tGallery.setColumns("GALLERY_ID", "GALLERY_NAME"); tPainting = new TableHelper(dbHelper, "PAINTING"); tPainting.setColumns("PAINTING_ID", "PAINTING_TITLE", "ARTIST_ID", "ESTIMATED_PRICE"); } private void createArtistsDataSet() throws Exception { tArtist.insert(33001, "artist1"); tArtist.insert(33002, "artist2"); tArtist.insert(33003, "artist3"); tArtist.insert(33004, "artist4"); tArtist.insert(33005, "artist5"); tArtist.insert(33006, "artist11"); tArtist.insert(33007, "artist21"); } protected void createArtistsAndPaintingsDataSet() throws Exception { createArtistsDataSet(); tPainting.insert(33001, "P_artist1", 33001, 1000); tPainting.insert(33002, "P_artist2", 33002, 2000); tPainting.insert(33003, "P_artist3", 33003, 3000); tPainting.insert(33004, "P_artist4", 33004, 4000); tPainting.insert(33005, "P_artist5", 33005, 5000); tPainting.insert(33006, "P_artist11", 33006, 11000); tPainting.insert(33007, "P_artist21", 33007, 21000); } private void createLargeArtistsDataSet() throws Exception { for (int i = 1; i <= 20; i++) { tArtist.insert(i, "artist" + i); } } @Test public void testIterate() throws Exception { createArtistsDataSet(); SelectQuery<Artist> q1 = new SelectQuery<Artist>(Artist.class); final int[] count = new int[1]; context.iterate(q1, new ResultIteratorCallback<Artist>() { @Override public void next(Artist object) { assertNotNull(object.getArtistName()); count[0]++; } }); assertEquals(7, count[0]); } @Test public void testIterateDataRows() throws Exception { createArtistsDataSet(); SelectQuery<DataRow> q1 = SelectQuery.dataRowQuery(Artist.class, null); final int[] count = new int[1]; context.iterate(q1, new ResultIteratorCallback<DataRow>() { @Override public void next(DataRow object) { assertNotNull(object.get("ARTIST_ID")); count[0]++; } }); assertEquals(7, count[0]); } @Test public void testIterator() throws Exception { createArtistsDataSet(); SelectQuery<Artist> q1 = new SelectQuery<Artist>(Artist.class); try (ResultIterator<Artist> it = context.iterator(q1);) { int count = 0; for (Artist a : it) { count++; } assertEquals(7, count); } } @Test public void testBatchIterator() throws Exception { createLargeArtistsDataSet(); SelectQuery<Artist> q1 = new SelectQuery<Artist>(Artist.class); try (ResultBatchIterator<Artist> it = context.batchIterator(q1, 5);) { int count = 0; for (List<Artist> artistList : it) { count++; assertEquals(5, artistList.size()); } assertEquals(4, count); } } @Test public void testPerformIteratedQuery_Count() throws Exception { createArtistsDataSet(); SelectQuery<Artist> q1 = new SelectQuery<Artist>(Artist.class); try (ResultIterator<?> it = context.performIteratedQuery(q1);) { int count = 0; while (it.hasNextRow()) { it.nextRow(); count++; } assertEquals(7, count); } } @Test public void testPerformIteratedQuery_resolve() throws Exception { createArtistsAndPaintingsDataSet(); try (ResultIterator<?> it = context.performIteratedQuery(SelectQuery.query(Artist.class));) { while (it.hasNextRow()) { DataRow row = (DataRow) it.nextRow(); // try instantiating an object and fetching its relationships Artist artist = context.objectFromDataRow(Artist.class, row); List<Painting> paintings = artist.getPaintingArray(); assertNotNull(paintings); assertEquals("Expected one painting for artist: " + artist, 1, paintings.size()); } } } @Test public void testPerformIteratedQuery_CommitWithinIterator() throws Exception { createArtistsAndPaintingsDataSet(); assertEquals(7, tPainting.getRowCount()); try (ResultIterator<?> it = context.performIteratedQuery(SelectQuery.query(Artist.class));) { while (it.hasNextRow()) { DataRow row = (DataRow) it.nextRow(); Artist artist = context.objectFromDataRow(Artist.class, row); Painting painting = context.newObject(Painting.class); painting.setPaintingTitle("P_" + artist.getArtistName()); painting.setToArtist(artist); context.commitChanges(); } } assertEquals(14, tPainting.getRowCount()); } @Test public void testPerformIteratedQuery_Transaction() throws Exception { createArtistsDataSet(); try (ResultIterator<?> it = context.performIteratedQuery(SelectQuery.query(Artist.class));) { assertNull("Iterator transaction was not unbound from thread", BaseTransaction.getThreadTransaction()); } // TODO: how do we test that transaction unbound from the thread is closed/committed at the end? } }