Package org.apache.cayenne.access.dbsync

Source Code of org.apache.cayenne.access.dbsync.SchemaUpdateStrategyTest

/*****************************************************************
*   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.dbsync;

import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import org.apache.cayenne.CayenneRuntimeException;
import org.apache.cayenne.access.DataNode;
import org.apache.cayenne.access.MockOperationObserver;
import org.apache.cayenne.access.dbsync.CreateIfNoSchemaStrategy;
import org.apache.cayenne.access.dbsync.SchemaUpdateStrategy;
import org.apache.cayenne.access.dbsync.ThrowOnPartialOrCreateSchemaStrategy;
import org.apache.cayenne.access.dbsync.ThrowOnPartialSchemaStrategy;
import org.apache.cayenne.dba.JdbcAdapter;
import org.apache.cayenne.map.DataMap;
import org.apache.cayenne.map.DbEntity;
import org.apache.cayenne.map.EntityResolver;
import org.apache.cayenne.map.MapLoader;
import org.apache.cayenne.query.Query;
import org.apache.cayenne.query.SQLTemplate;
import org.apache.cayenne.unit.CayenneCase;
import org.apache.cayenne.unit.CayenneResources;
import org.xml.sax.InputSource;

public class SchemaUpdateStrategyTest extends CayenneCase {

    private DataMap dataMap;

    public DataMap getDataMap() {
        if (dataMap == null) {
            MapLoader mapLoader = new MapLoader();
            dataMap = mapLoader.loadDataMap(getMapXml("sus-map.map.xml"));
        }
        return dataMap;
    }

    private InputSource getMapXml(String mapName) {
        return new InputSource(getClass().getClassLoader().getResourceAsStream(mapName));
    }

    public void testDBGeneratorStrategy() throws Exception {

        String template = "SELECT #result('id' 'int') FROM SUS1";
        SQLTemplate query = new SQLTemplate(Object.class, template);
        DataMap map = getDataMap();
        assertNotNull(map);
        DataNode dataNode = createDataNode(map);
        int sizeDB = getNameTablesInDB(dataNode).size();
        MockOperationObserver observer = new MockOperationObserver();
        try {

            generateDBWithDBGeneratorStrategy(dataNode, query, observer);
            int sizeDB2 = getNameTablesInDB(dataNode).size();
            assertEquals(2, sizeDB2 - sizeDB);
            dataNode.performQueries(Collections.singletonList((Query) query), observer);
            int sizeDB3 = getNameTablesInDB(dataNode).size();
            assertEquals(sizeDB2, sizeDB3);
        }
        finally {
            DataNode dataNode2 = createDataNode(map);
            dataNode2.setSchemaUpdateStrategy((SchemaUpdateStrategy) Class.forName(
                    dataNode2.getSchemaUpdateStrategyName()).newInstance());
            dropTables(map, dataNode2, observer);
        }
        assertEquals(getNameTablesInDB(dataNode).size(), sizeDB);
    }

    public void testThrowOnPartialStrategyTableNoExist() throws Exception {

        String template = "SELECT #result('ARTIST_ID' 'int') FROM ARTIST ORDER BY ARTIST_ID";
        SQLTemplate query = new SQLTemplate(Object.class, template);
        DataMap map = getDataMap();
        assertNotNull(map);
        MockOperationObserver observer = new MockOperationObserver();
        DataNode dataNode = createDataNode(map);

        setStrategy(ThrowOnPartialSchemaStrategy.class.getName(), dataNode);

        try {
            dataNode.performQueries(Collections.singletonList((Query) query), observer);
        }
        catch (CayenneRuntimeException e) {
            assertNotNull(e);
        }

        try {
            dataNode.performQueries(Collections.singletonList((Query) query), observer);
        }
        catch (CayenneRuntimeException e) {
            assertNotNull(e);
        }
    }

    public void testThrowOnPartialStrategyTableExist() throws Exception {
        tableExistfForThrowOnPartialAndMixStrategy(ThrowOnPartialSchemaStrategy.class
                .getName());
    }

    public void testThrowOnPartialStrategyWithOneTable() throws Exception {
        withOneTableForThrowOnPartialAndMixStrategy(ThrowOnPartialSchemaStrategy.class
                .getName());
    }

    public void testMixedStrategyTableNoExist() throws Exception {

        String template = "SELECT #result('id' 'int') FROM SUS1";
        SQLTemplate query = new SQLTemplate(Object.class, template);
        DataMap map = getDataMap();
        assertNotNull(map);
        DataNode dataNode = createDataNode(map);
        int sizeDB = getNameTablesInDB(dataNode).size();
        MockOperationObserver observer = new MockOperationObserver();

        setStrategy(ThrowOnPartialOrCreateSchemaStrategy.class.getName(), dataNode);

        try {
            dataNode.performQueries(Collections.singletonList((Query) query), observer);
            Map<String, Boolean> nameTables = getNameTablesInDB(dataNode);
            assertTrue(nameTables.get("sus1") != null || nameTables.get("SUS1") != null);
            int sizeDB2 = getNameTablesInDB(dataNode).size();
            assertEquals(2, sizeDB2 - sizeDB);
            dataNode.performQueries(Collections.singletonList((Query) query), observer);
            int sizeDB3 = getNameTablesInDB(dataNode).size();
            assertEquals(sizeDB2, sizeDB3);
        }
        finally {
            DataNode dataNode2 = createDataNode(map);
            dataNode2.setSchemaUpdateStrategy((SchemaUpdateStrategy) Class.forName(
                    dataNode2.getSchemaUpdateStrategyName()).newInstance());
            dropTables(map, dataNode2, observer);
        }
        assertEquals(getNameTablesInDB(dataNode).size(), sizeDB);

    }

    public void testMixedStrategyTableExist() throws Exception {
        tableExistfForThrowOnPartialAndMixStrategy(ThrowOnPartialOrCreateSchemaStrategy.class
                .getName());
    }

    public void testMixedStrategyWithOneTable() throws Exception {
        withOneTableForThrowOnPartialAndMixStrategy(ThrowOnPartialOrCreateSchemaStrategy.class
                .getName());
    };

    public void testNoStandartSchema() {
        String template = "SELECT #result('ARTIST_ID' 'int') FROM ARTIST ORDER BY ARTIST_ID";
        SQLTemplate query = new SQLTemplate(Object.class, template);
        MockOperationObserver observer = new MockOperationObserver();
        DataMap map = getDataMap();
        assertNotNull(map);
        DataNode dataNode = createDataNode(map);

        setStrategy(TestSchemaUpdateStrategy.class.getName(), dataNode);

        dataNode.performQueries(Collections.singletonList((Query) query), observer);
        assertTrue(dataNode.getSchemaUpdateStrategy() instanceof TestSchemaUpdateStrategy);
    }

    private void withOneTableForThrowOnPartialAndMixStrategy(String strategy) {
        DbEntity entity = null;
        String template = "SELECT #result('ARTIST_ID' 'int') FROM ARTIST ORDER BY ARTIST_ID";
        SQLTemplate query = new SQLTemplate(Object.class, template);
        DataMap map = getDataMap();
        assertNotNull(map);
        MockOperationObserver observer = new MockOperationObserver();
        DataNode dataNode = createDataNode(map);

        DataNode dataNode2 = createDataNode(map);

        try {

            int sizeDB = getNameTablesInDB(dataNode).size();
            entity = createOneTable(dataNode);
            int sizeDB2 = getNameTablesInDB(dataNode).size();
            assertEquals(1, sizeDB2 - sizeDB);
            setStrategy(strategy, dataNode2);
            dataNode2.performQueries(Collections.singletonList((Query) query), observer);

        }
        catch (CayenneRuntimeException e) {
            assertNotNull(e);
        }
        try {
            dataNode2.performQueries(Collections.singletonList((Query) query), observer);
        }
        catch (CayenneRuntimeException e) {
            assertNotNull(e);
        }
        finally {

            if (entity != null) {

                Collection<String> template2 = dataNode.getAdapter().dropTableStatements(
                        entity);
                Iterator<String> it = template2.iterator();
                List<Query> list = new ArrayList<Query>();
                while (it.hasNext()) {
                    SQLTemplate q = new SQLTemplate(Object.class, it.next());
                    list.add(q);
                }
                dataNode.performQueries(list, observer);
            }
        }
    }

    private void tableExistfForThrowOnPartialAndMixStrategy(String strategy)
            throws Exception {

        String template = "SELECT #result('ARTIST_ID' 'int') FROM ARTIST ORDER BY ARTIST_ID";
        SQLTemplate query = new SQLTemplate(Object.class, template);
        DataMap map = getDataMap();
        assertNotNull(map);
        MockOperationObserver observer = new MockOperationObserver();
        DataNode dataNode = createDataNode(map);
        int sizeDB = getNameTablesInDB(dataNode).size();
        generateDBWithDBGeneratorStrategy(dataNode, query, observer);
        int sizeDB2 = getNameTablesInDB(dataNode).size();
        assertEquals(2, sizeDB2 - sizeDB);
        try {
            DataNode dataNode2 = createDataNode(map);
            setStrategy(strategy, dataNode2);
            dataNode2.performQueries(Collections.singletonList((Query) query), observer);
        }
        finally {
            dropTables(map, dataNode, observer);
        }

    }

    private DbEntity createOneTable(DataNode dataNode) {
        DataMap map = getDataMap();
        Collection<DbEntity> ent = map.getDbEntities();
        DbEntity entity = ent.iterator().next();
        String template = dataNode.getAdapter().createTable(entity);

        SQLTemplate query = new SQLTemplate(Object.class, template);
        MockOperationObserver observer = new MockOperationObserver();

        setStrategy(null, dataNode);

        dataNode.performQueries(Collections.singletonList((Query) query), observer);
        return entity;
    }

    private DataNode createDataNode(DataMap map) {
        JdbcAdapter adapter = (JdbcAdapter) getAccessStackAdapter().getAdapter();
        Collection<DataMap> colection = new ArrayList<DataMap>();
        colection.add(map);
        DataNode dataNode = new DataNode();
        dataNode.setDataMaps(colection);
        dataNode.setAdapter(adapter);
        dataNode.setDataSource(CayenneResources.getResources().getDataSource());
        dataNode.setDataSourceFactory(getNode().getDataSourceFactory());
        dataNode.setSchemaUpdateStrategyName(getNode().getSchemaUpdateStrategyName());
        dataNode.setEntityResolver(new EntityResolver(colection));
        return dataNode;
    }

    private void generateDBWithDBGeneratorStrategy(
            DataNode dataNode,
            SQLTemplate query,
            MockOperationObserver observer) {

        setStrategy(CreateIfNoSchemaStrategy.class.getName(), dataNode);

        dataNode.performQueries(Collections.singletonList((Query) query), observer);
        Map<String, Boolean> nameTables = getNameTablesInDB(dataNode);
        assertTrue(nameTables.get("sus1") != null || nameTables.get("SUS1") != null);

    }

    private void setStrategy(String name, DataNode dataNode) {
        dataNode.setSchemaUpdateStrategyName(name);
        try {
            dataNode.setSchemaUpdateStrategy((SchemaUpdateStrategy) Class.forName(
                    dataNode.getSchemaUpdateStrategyName()).newInstance());
        }
        catch (Exception e) {
            throw new CayenneRuntimeException(e);
        }
    }

    private void dropTables(DataMap map, DataNode dataNode, MockOperationObserver observer) {
        Collection<DbEntity> ent = map.getDbEntities();
        Iterator<DbEntity> iterator = ent.iterator();
        while (iterator.hasNext()) {
            Collection<String> collectionDrop = dataNode
                    .getAdapter()
                    .dropTableStatements(iterator.next());
            for (String s : collectionDrop) {
                SQLTemplate queryDrop = new SQLTemplate(Object.class, s);
                dataNode.performQueries(
                        Collections.singletonList((Query) queryDrop),
                        observer);
            }
        }
    }

    private Map<String, Boolean> getNameTablesInDB(DataNode dataNode) {
        String tableLabel = dataNode.getAdapter().tableTypeForTable();
        Connection con = null;
        Map<String, Boolean> nameTables = new HashMap<String, Boolean>();
        try {
            con = dataNode.getDataSource().getConnection();
            ResultSet rs = con.getMetaData().getTables(null, null, "%", new String[] {
                tableLabel
            });
            while (rs.next()) {
                String name = rs.getString("TABLE_NAME");
                nameTables.put(name, false);
            }
            rs.close();
        }
        catch (SQLException e) {
            throw new CayenneRuntimeException(e);
        }
        finally {
            try {
                con.close();
            }
            catch (SQLException e) {
                throw new CayenneRuntimeException(e);
            }
        }
        return nameTables;
    }
}
TOP

Related Classes of org.apache.cayenne.access.dbsync.SchemaUpdateStrategyTest

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.