/***************************************************************** * 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.Cayenne; import org.apache.cayenne.di.Inject; import org.apache.cayenne.log.JdbcEventLogger; import org.apache.cayenne.query.SQLTemplate; 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.tx.ExternalTransaction; import org.apache.cayenne.tx.Transaction; import org.apache.cayenne.unit.UnitDbAdapter; import org.apache.cayenne.unit.di.DataChannelInterceptor; import org.apache.cayenne.unit.di.UnitTestClosure; 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.math.BigDecimal; import java.sql.Types; import java.util.Collections; import java.util.HashMap; import java.util.List; import java.util.Map; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNotNull; @UseServerRuntime(CayenneProjects.TESTMAP_PROJECT) public class DataContextPerformQueryAPIIT extends ServerCase { @Inject private DataContext context; @Inject private DataContext context2; @Inject private DBHelper dbHelper; @Inject private UnitDbAdapter accessStackAdapter; @Inject private DataChannelInterceptor queryInterceptor; @Inject private JdbcEventLogger jdbcEventLogger; private TableHelper tArtist; private TableHelper tPainting; @Before public void setUp() throws Exception { tArtist = new TableHelper(dbHelper, "ARTIST"); tArtist.setColumns("ARTIST_ID", "ARTIST_NAME"); tPainting = new TableHelper(dbHelper, "PAINTING"); tPainting.setColumns("PAINTING_ID", "ARTIST_ID", "PAINTING_TITLE", "ESTIMATED_PRICE").setColumnTypes( Types.INTEGER, Types.BIGINT, Types.VARCHAR, Types.DECIMAL); } private void createTwoArtists() throws Exception { tArtist.insert(21, "artist2"); tArtist.insert(201, "artist3"); } private void createTwoArtistsAndTwoPaintingsDataSet() throws Exception { tArtist.insert(11, "artist2"); tArtist.insert(101, "artist3"); tPainting.insert(6, 101, "p_artist3", 1000); tPainting.insert(7, 11, "p_artist2", 2000); } @Test public void testObjectQueryStringBoolean() throws Exception { createTwoArtistsAndTwoPaintingsDataSet(); List<?> paintings = context.performQuery("ObjectQuery", true); assertNotNull(paintings); assertEquals(2, paintings.size()); } @Test public void testObjectQueryStringMapBoolean() throws Exception { createTwoArtistsAndTwoPaintingsDataSet(); Artist a = Cayenne.objectForPK(context, Artist.class, 11); Map<String, Artist> parameters = Collections.singletonMap("artist", a); List<?> paintings = context2.performQuery("ObjectQuery", parameters, true); assertNotNull(paintings); assertEquals(1, paintings.size()); } @Test public void testProcedureQueryStringMapBoolean() throws Exception { if (!accessStackAdapter.supportsStoredProcedures()) { return; } if (!accessStackAdapter.canMakeObjectsOutOfProcedures()) { return; } createTwoArtistsAndTwoPaintingsDataSet(); // fetch artist Map<String, String> parameters = Collections.singletonMap("aName", "artist2"); List<?> artists; // Sybase blows whenever a transaction wraps a SP, so turn of // transactions Transaction t = new ExternalTransaction(jdbcEventLogger); BaseTransaction.bindThreadTransaction(t); try { artists = context.performQuery("ProcedureQuery", parameters, true); } finally { BaseTransaction.bindThreadTransaction(null); t.commit(); } assertNotNull(artists); assertEquals(1, artists.size()); Artist artist = (Artist) artists.get(0); assertEquals(11, ((Number) artist.getObjectId().getIdSnapshot().get(Artist.ARTIST_ID_PK_COLUMN)).intValue()); } @Test public void testNonSelectingQueryString() throws Exception { int[] counts = context.performNonSelectingQuery("NonSelectingQuery"); assertNotNull(counts); assertEquals(1, counts.length); assertEquals(1, counts[0]); Painting p = Cayenne.objectForPK(context, Painting.class, 512); assertEquals("No Painting Like This", p.getPaintingTitle()); } @Test public void testNonSelectingQueryStringMap() throws Exception { Map<String, Object> parameters = new HashMap<>(); parameters.put("id", 300); parameters.put("title", "Go Figure"); parameters.put("price", new BigDecimal("22.01")); int[] counts = context.performNonSelectingQuery("ParameterizedNonSelectingQuery", parameters); assertNotNull(counts); assertEquals(1, counts.length); assertEquals(1, counts[0]); Painting p = Cayenne.objectForPK(context, Painting.class, 300); assertEquals("Go Figure", p.getPaintingTitle()); } @Test public void testPerfomQueryNonSelecting() throws Exception { Artist a = context.newObject(Artist.class); a.setArtistName("aa"); context.commitChanges(); SQLTemplate q = new SQLTemplate(Artist.class, "DELETE FROM ARTIST"); // this way of executing a query makes no sense, but it shouldn't blow // either... List<?> result = context.performQuery(q); assertNotNull(result); assertEquals(0, result.size()); } @Test public void testObjectQueryWithLocalCache() throws Exception { createTwoArtists(); List<?> artists = context.performQuery("QueryWithLocalCache", true); assertEquals(2, artists.size()); queryInterceptor.runWithQueriesBlocked(new UnitTestClosure() { public void execute() { List<?> artists1 = context.performQuery("QueryWithLocalCache", false); assertEquals(2, artists1.size()); } }); } @Test public void testObjectQueryWithSharedCache() throws Exception { createTwoArtists(); List<?> artists = context.performQuery("QueryWithSharedCache", true); assertEquals(2, artists.size()); queryInterceptor.runWithQueriesBlocked(new UnitTestClosure() { public void execute() { List<?> artists1 = context2.performQuery("QueryWithSharedCache", false); assertEquals(2, artists1.size()); } }); } }