Package org.apache.cayenne.access

Source Code of org.apache.cayenne.access.DataContextTest

/*****************************************************************
*   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 java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.apache.art.Artist;
import org.apache.art.Exhibit;
import org.apache.art.Painting;
import org.apache.art.ROArtist;
import org.apache.cayenne.DataObject;
import org.apache.cayenne.DataRow;
import org.apache.cayenne.Fault;
import org.apache.cayenne.ObjectId;
import org.apache.cayenne.PersistenceState;
import org.apache.cayenne.conn.PoolManager;
import org.apache.cayenne.exp.Expression;
import org.apache.cayenne.exp.ExpressionFactory;
import org.apache.cayenne.query.EJBQLQuery;
import org.apache.cayenne.query.ObjectIdQuery;
import org.apache.cayenne.query.Ordering;
import org.apache.cayenne.query.SQLTemplate;
import org.apache.cayenne.query.SelectQuery;

public class DataContextTest extends DataContextCase {

    protected MockOperationObserver opObserver;

    @Override
    protected void setUp() throws Exception {
        super.setUp();

        opObserver = new MockOperationObserver();
    }

    public void testCurrentSnapshot1() throws Exception {
        Artist artist = fetchArtist("artist1", false);
        Map snapshot = context.currentSnapshot(artist);
        assertEquals(artist.getArtistName(), snapshot.get("ARTIST_NAME"));
        assertEquals(artist.getDateOfBirth(), snapshot.get("DATE_OF_BIRTH"));
    }

    public void testCurrentSnapshot2() throws Exception {
        // test null values
        Artist artist = fetchArtist("artist1", false);
        artist.setArtistName(null);
        artist.setDateOfBirth(null);

        Map snapshot = context.currentSnapshot(artist);
        assertTrue(snapshot.containsKey("ARTIST_NAME"));
        assertNull(snapshot.get("ARTIST_NAME"));

        assertTrue(snapshot.containsKey("DATE_OF_BIRTH"));
        assertNull(snapshot.get("DATE_OF_BIRTH"));
    }

    public void testCurrentSnapshot3() throws Exception {
        // test FK relationship snapshotting
        Artist a1 = fetchArtist("artist1", false);

        Painting p1 = new Painting();
        context.registerNewObject(p1);
        p1.setToArtist(a1);

        Map s1 = context.currentSnapshot(p1);
        Map idMap = a1.getObjectId().getIdSnapshot();
        assertEquals(idMap.get("ARTIST_ID"), s1.get("ARTIST_ID"));
    }

    /**
     * Testing snapshot with to-one fault. This was a bug CAY-96.
     */
    public void testCurrentSnapshotWithToOneFault() throws Exception {

        // Exhibit with Gallery as Fault must still include Gallery
        // Artist and Exhibit (Exhibit has unresolved to-one to gallery as in the
        // CAY-96 bug report)

        // first prepare test fixture
        createTestData("testGalleries");
        populateExhibits();

        ObjectId eId = new ObjectId("Exhibit", Exhibit.EXHIBIT_ID_PK_COLUMN, 2);
        Exhibit e = (Exhibit) context.performQuery(new ObjectIdQuery(eId)).get(0);

        assertTrue(e.readPropertyDirectly(Exhibit.TO_GALLERY_PROPERTY) instanceof Fault);

        DataRow snapshot = context.currentSnapshot(e);

        // assert that after taking a snapshot, we have FK in, but the relationship
        // is still a Fault
        assertTrue(e.readPropertyDirectly(Exhibit.TO_GALLERY_PROPERTY) instanceof Fault);
        assertEquals(new Integer(33002), snapshot.get("GALLERY_ID"));
    }

    /**
     * Tests how CHAR field is handled during fetch. Some databases (Oracle...) would pad
     * a CHAR column with extra spaces, returned to the client. Cayenne should trim it.
     */
    public void testCharFetch() throws Exception {
        SelectQuery q = new SelectQuery("Artist");
        List artists = context.performQuery(q);
        Artist a = (Artist) artists.get(0);
        assertEquals(a.getArtistName().trim(), a.getArtistName());
    }

    /**
     * Tests how CHAR field is handled during fetch in the WHERE clause. Some databases
     * (Oracle...) would pad a CHAR column with extra spaces, returned to the client.
     * Cayenne should trim it.
     */
    public void testCharInQualifier() throws Exception {
        Expression e = ExpressionFactory.matchExp("artistName", "artist1");
        SelectQuery q = new SelectQuery("Artist", e);
        List artists = context.performQuery(q);
        assertEquals(1, artists.size());
    }

    /**
     * Test fetching query with multiple relationship paths between the same 2 entities
     * used in qualifier.
     */
    public void testMultiObjRelFetch() throws Exception {
        createTestData("testPaintings");

        SelectQuery q = new SelectQuery("Painting");
        q.andQualifier(ExpressionFactory.matchExp("toArtist.artistName", "artist2"));
        q.orQualifier(ExpressionFactory.matchExp("toArtist.artistName", "artist4"));
        List results = context.performQuery(q);

        assertEquals(2, results.size());
    }

    /**
     * Test fetching query with multiple relationship paths between the same 2 entities
     * used in qualifier.
     */
    public void testMultiDbRelFetch() throws Exception {
        createTestData("testPaintings");

        SelectQuery q = new SelectQuery("Painting");
        q.andQualifier(ExpressionFactory.matchDbExp("toArtist.ARTIST_NAME", "artist2"));
        q.orQualifier(ExpressionFactory.matchDbExp("toArtist.ARTIST_NAME", "artist4"));
        List results = context.performQuery(q);

        assertEquals(2, results.size());
    }

    public void testSelectDate() throws Exception {
        createTestData("testGalleries");
        populateExhibits();

        List objects = context.performQuery(new SelectQuery(Exhibit.class));
        assertFalse(objects.isEmpty());

        Exhibit e1 = (Exhibit) objects.get(0);
        assertEquals(java.util.Date.class, e1.getClosingDate().getClass());
    }

    public void testCaseInsensitiveOrdering() throws Exception {
        if (!getAccessStackAdapter().supportsCaseInsensitiveOrder()) {
            return;
        }

        // case insensitive ordering appends extra columns
        // to the query when query is using DISTINCT...
        // verify that the result is not messaged up

        SelectQuery query = new SelectQuery(Artist.class);
        Ordering ordering = new Ordering("artistName", false);
        ordering.setCaseInsensitive(true);
        query.addOrdering(ordering);
        query.setDistinct(true);

        List objects = context.performQuery(query);
        assertEquals(artistCount, objects.size());

        Artist artist = (Artist) objects.get(0);
        Map snapshot = context.getObjectStore().getSnapshot(artist.getObjectId());
        assertEquals(3, snapshot.size());
    }

    public void testPerformSelectQuery1() throws Exception {
        SelectQuery query = new SelectQuery("Artist");
        List objects = context.performQuery(query);

        assertNotNull(objects);
        assertEquals(artistCount, objects.size());
        assertTrue(
                "Artist expected, got " + objects.get(0).getClass(),
                objects.get(0) instanceof Artist);
    }

    public void testPerformSelectQuery2() throws Exception {
        // do a query with complex qualifier
        List expressions = new ArrayList();
        expressions.add(ExpressionFactory.matchExp("artistName", "artist3"));
        expressions.add(ExpressionFactory.matchExp("artistName", "artist5"));
        expressions.add(ExpressionFactory.matchExp("artistName", "artist15"));

        SelectQuery query = new SelectQuery("Artist", ExpressionFactory.joinExp(
                Expression.OR,
                expressions));

        List objects = context.performQuery(query);

        assertNotNull(objects);
        assertEquals(3, objects.size());
        assertTrue(
                "Artist expected, got " + objects.get(0).getClass(),
                objects.get(0) instanceof Artist);
    }

    public void testPerformQuery() throws Exception {
        SelectQuery query = new SelectQuery("Artist");
        List objects = context.performQuery(query);
        assertNotNull(objects);
        assertEquals(artistCount, objects.size());
    }

    public void testPerformNonSelectingQuery() throws Exception {
        SelectQuery select = new SelectQuery(Painting.class, Expression
                .fromString("db:PAINTING_ID = 1"));

        assertEquals(0, context.performQuery(select).size());

        SQLTemplate query = new SQLTemplate(
                Painting.class,
                "INSERT INTO PAINTING (PAINTING_ID, PAINTING_TITLE, ARTIST_ID, ESTIMATED_PRICE) "
                        + "VALUES (1, 'PX', 33002, 1)");
        context.performNonSelectingQuery(query);
        assertEquals(1, context.performQuery(select).size());
    }

    public void testPerformNonSelectingQueryCounts1() throws Exception {
        SQLTemplate query = new SQLTemplate(
                Painting.class,
                "INSERT INTO PAINTING (PAINTING_ID, PAINTING_TITLE, ARTIST_ID, ESTIMATED_PRICE) "
                        + "VALUES ($pid, '$pt', $aid, $price)");

        Map map = new HashMap();
        map.put("pid", new Integer(1));
        map.put("pt", "P1");
        map.put("aid", new Integer(33002));
        map.put("price", new Double(1.1));

        // single batch of parameters
        query.setParameters(map);

        int[] counts = context.performNonSelectingQuery(query);
        assertNotNull(counts);
        assertEquals(1, counts.length);
        assertEquals(1, counts[0]);
    }

    public void testPerformNonSelectingQueryCounts2() throws Exception {
        SQLTemplate query = new SQLTemplate(
                Painting.class,
                "INSERT INTO PAINTING (PAINTING_ID, PAINTING_TITLE, ARTIST_ID, ESTIMATED_PRICE) "
                        + "VALUES ($pid, '$pt', $aid, #bind($price 'DECIMAL' 2))");

        Map[] maps = new Map[3];
        for (int i = 0; i < maps.length; i++) {
            maps[i] = new HashMap();
            maps[i].put("pid", new Integer(1 + i));
            maps[i].put("pt", "P-" + i);
            maps[i].put("aid", new Integer(33002));
            maps[i].put("price", new BigDecimal("1." + i));
        }

        // single batch of parameters
        query.setParameters(maps);

        int[] counts = context.performNonSelectingQuery(query);
        assertNotNull(counts);
        assertEquals(maps.length, counts.length);
        for (int i = 0; i < maps.length; i++) {
            assertEquals(1, counts[i]);
        }

        SQLTemplate delete = new SQLTemplate(Painting.class, "delete from PAINTING");
        counts = context.performNonSelectingQuery(delete);
        assertNotNull(counts);
        assertEquals(1, counts.length);
        assertEquals(3, counts[0]);
    }

    public void testPerformPaginatedQuery() throws Exception {
        SelectQuery query = new SelectQuery("Artist");
        query.setPageSize(5);
        List objects = context.performQuery(query);
        assertNotNull(objects);
        assertTrue(objects instanceof IncrementalFaultList);
        assertTrue(((IncrementalFaultList<?>) objects).elements.get(0) instanceof Long);
        assertTrue(((IncrementalFaultList<?>) objects).elements.get(7) instanceof Long);
       
        assertTrue(objects.get(0) instanceof Artist);
    }
   
    public void testPerformPaginatedQuery1() throws Exception {
        EJBQLQuery query = new EJBQLQuery("select a FROM Artist a");
        query.setPageSize(5);
        List objects = context.performQuery(query);
        assertNotNull(objects);
        assertTrue(objects instanceof IncrementalFaultList);
        assertTrue(((IncrementalFaultList<?>) objects).elements.get(0) instanceof Long);
        assertTrue(((IncrementalFaultList<?>) objects).elements.get(7) instanceof Long);
       
        assertTrue(objects.get(0) instanceof Artist);
    }

    public void testPerformPaginatedQueryBigPage() throws Exception {
        SelectQuery query = new SelectQuery("Artist");
        query.setPageSize(DataContextTest.artistCount + 2);
        List objects = context.performQuery(query);
        assertNotNull(objects);
        assertTrue(objects instanceof IncrementalFaultList);

        blockQueries();
        try {
            assertEquals(DataContextTest.artistCount, objects.size());
        }
        finally {
            unblockQueries();
        }
    }

    public void testPerformDataRowQuery() throws Exception {
        SelectQuery query = new SelectQuery("Artist");
        query.setFetchingDataRows(true);
        List objects = context.performQuery(query);

        assertNotNull(objects);
        assertEquals(artistCount, objects.size());
        assertTrue(
                "Map expected, got " + objects.get(0).getClass(),
                objects.get(0) instanceof Map);
    }

    public void testCommitChangesRO1() throws Exception {
        ROArtist a1 = (ROArtist) context.newObject("ROArtist");
        a1.writePropertyDirectly("artistName", "abc");
        a1.setPersistenceState(PersistenceState.MODIFIED);

        try {
            context.commitChanges();
            fail("Inserting a 'read-only' object must fail.");
        }
        catch (Exception ex) {
            // exception is expected,
            // must blow on saving new "read-only" object.
        }
    }

    public void testCommitChangesRO2() throws Exception {
        ROArtist a1 = fetchROArtist("artist1");
        a1.writeProperty("artistName", "abc");

        try {
            context.commitChanges();
            fail("Updating a 'read-only' object must fail.");
        }
        catch (Exception ex) {
            // exception is expected,
            // must blow on saving new "read-only" object.
        }
    }

    public void testCommitChangesRO3() throws Exception {
        ROArtist a1 = fetchROArtist("artist1");
        context.deleteObject(a1);

        try {
            context.commitChanges();
            fail("Deleting a 'read-only' object must fail.");
        }
        catch (Exception ex) {
            // exception is expected,
            // must blow on saving new "read-only" object.
        }
    }

    public void testCommitChangesRO4() throws Exception {
        ROArtist a1 = fetchROArtist("artist1");
        Painting painting = (Painting) context.newObject("Painting");
        painting.setPaintingTitle("paint");
        a1.addToPaintingArray(painting);

        assertEquals(PersistenceState.MODIFIED, a1.getPersistenceState());
        try {
            context.commitChanges();
        }
        catch (Exception ex) {
            fail("Updating 'read-only' object's to-many must succeed, instead an exception was thrown: "
                    + ex);
        }

        assertEquals(PersistenceState.COMMITTED, a1.getPersistenceState());
    }

    public void testPerformIteratedQuery1() throws Exception {
        SelectQuery q1 = new SelectQuery("Artist");
        ResultIterator it = context.performIteratedQuery(q1);

        try {
            int count = 0;
            while (it.hasNextRow()) {
                it.nextRow();
                count++;
            }

            assertEquals(DataContextTest.artistCount, count);
        }
        finally {
            it.close();
        }
    }

    public void testPerformIteratedQuery2() throws Exception {
        createTestData("testPaintings");

        ResultIterator it = context.performIteratedQuery(new SelectQuery(Artist.class));

        // just for this test increase pool size
        changeMaxConnections(1);

        try {
            while (it.hasNextRow()) {
                DataRow row = (DataRow) it.nextRow();

                // try instantiating an object and fetching its relationships
                Artist artist = context.objectFromDataRow(
                        Artist.class,
                        row,
                        false);
                List paintings = artist.getPaintingArray();
                assertNotNull(paintings);
                assertEquals("Expected one painting for artist: " + artist, 1, paintings
                        .size());
            }
        }
        finally {
            // change allowed connections back
            changeMaxConnections(-1);

            it.close();
        }
    }

    public void changeMaxConnections(int delta) {
        DataNode node = context
                .getParentDataDomain()
                .getDataNodes()
                .iterator()
                .next();

        // access DS directly as 'getDataSource' returns a wrapper.
        PoolManager manager = (PoolManager) node.dataSource;
        manager.setMaxConnections(manager.getMaxConnections() + delta);
    }

    /**
     * Tests that hasChanges performs correctly when an object is "modified" and the
     * property is simply set to the same value (an unreal modification)
     */
    public void testHasChangesPhantom() {
        String artistName = "ArtistName";
        Artist artist = (Artist) context.newObject("Artist");
        artist.setArtistName(artistName);
        context.commitChanges();

        // Set again to *exactly* the same value
        artist.setArtistName(artistName);

        // note that since 1.2 the polciy is for hasChanges to return true for phantom
        // modifications, as there is no way to detect some more subtle modifications like
        // a change of the master related object, until we actually create the PKs
        assertTrue(context.hasChanges());
    }

    /**
     * Tests that hasChanges performs correctly when an object is "modified" and the
     * property is simply set to the same value (an unreal modification)
     */
    public void testHasChangesRealModify() {
        Artist artist = (Artist) context.newObject("Artist");
        artist.setArtistName("ArtistName");
        context.commitChanges();

        artist.setArtistName("Something different");
        assertTrue(context.hasChanges());
    }

    public void testInvalidateObjects() throws Exception {
        DataContext context = createDataContext();

        DataRow row = new DataRow(10);
        row.put("ARTIST_ID", new Integer(1));
        row.put("ARTIST_NAME", "ArtistXYZ");
        row.put("DATE_OF_BIRTH", new Date());
        DataObject object = context.objectFromDataRow(Artist.class, row, false);
        ObjectId oid = object.getObjectId();

        // insert object into the ObjectStore
        context.getObjectStore().registerNode(oid, object);

        assertSame(object, context.getObjectStore().getNode(oid));
        assertNotNull(context.getObjectStore().getCachedSnapshot(oid));

        context.invalidateObjects(Collections.singletonList(object));

        assertSame(oid, object.getObjectId());
        assertNull(context.getObjectStore().getCachedSnapshot(oid));
        assertSame(object, context.getObjectStore().getNode(oid));
    }
   
    public void testBeforeHollowDeleteShouldChangeStateToCommited() throws Exception {
        ObjectId gid = new ObjectId("Artist","ARTIST_ID",33001)
        final Artist inflated = new Artist();
        inflated.setPersistenceState(PersistenceState.COMMITTED);
        inflated.setObjectId(gid);
        inflated.setArtistName("artist1");
       
        Artist hollow = (Artist) context.localObject(gid, null);
        assertEquals(PersistenceState.HOLLOW, hollow.getPersistenceState());

        // testing this...
        context.deleteObject(hollow);
        assertSame(hollow, context.getGraphManager().getNode(gid));
        assertEquals(inflated.getArtistName(), hollow.getArtistName());
         
        assertEquals(PersistenceState.DELETED, hollow.getPersistenceState());
    }

}
TOP

Related Classes of org.apache.cayenne.access.DataContextTest

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.