com.vecna.dbDiff.builder.RelationalDatabaseBuilderTest.java Source code

Java tutorial

Introduction

Here is the source code for com.vecna.dbDiff.builder.RelationalDatabaseBuilderTest.java

Source

/**
 * Copyright 2011 Vecna Technologies, Inc.
 *
 * Licensed 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 com.vecna.dbDiff.builder;

import java.io.InputStream;
import java.sql.Connection;
import java.sql.Types;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.List;

import junit.framework.TestCase;

import org.apache.commons.io.IOUtils;

import com.vecna.dbDiff.jdbc.MetadataFactory;
import com.vecna.dbDiff.jdbc.ThreadLocalMetadataFactory;
import com.vecna.dbDiff.model.CatalogSchema;
import com.vecna.dbDiff.model.db.Column;
import com.vecna.dbDiff.model.db.ForeignKey;
import com.vecna.dbDiff.model.relationalDb.RelationalDatabase;
import com.vecna.dbDiff.model.relationalDb.RelationalIndex;
import com.vecna.dbDiff.model.relationalDb.RelationalTable;

/**
 * Tests {@link RelationalDatabaseBuilderImpl}.
 *
 * @author ogolberg@vecna.com
 */
public class RelationalDatabaseBuilderTest extends TestCase {
    private RelationalDatabase getDatabase() throws Exception {
        try (MetadataFactory factory = new ThreadLocalMetadataFactory("jdbc:h2:mem:test;DB_CLOSE_DELAY=-1", "sa",
                "")) {
            try (InputStream stream = getClass().getResourceAsStream("/test-db.sql")) {
                String sql = IOUtils.toString(stream);

                Connection ddlConnection = factory.getMetadata().getConnection();
                ddlConnection.setAutoCommit(true);

                for (String sqlStatement : sql.split(";")) {
                    ddlConnection.createStatement().execute(sqlStatement);
                }
            }

            RelationalDatabaseBuilder builder = new RelationalDatabaseBuilderImpl(factory);
            return builder.createRelationalDatabase(new CatalogSchema(null, "PUBLIC"));
        }
    }

    /**
     * Find a unique index that spans a list of columns. Fail if there's no such unique index.
     */
    private RelationalIndex getIndex(RelationalTable table, String... columnNames) {
        Collection<RelationalIndex> indices = table.getIndicesByColumns().get(Arrays.asList(columnNames));

        assertEquals("cannot find a unique index for columns " + Arrays.asList(columnNames), 1, indices.size());
        return indices.iterator().next();
    }

    /**
     * Find a unique foreign key by name. Fail if there's no such unique foreign key.
     */
    private ForeignKey getForeignKey(RelationalTable table, String name) {
        Collection<ForeignKey> foreignKeys = table.getFksByName(name);
        assertEquals("cannot find a unique foreign key " + name, 1, foreignKeys.size());
        return foreignKeys.iterator().next();
    }

    /**
     * Test {@link RelationalDatabaseBuilderImpl#createRelationalDatabase(CatalogSchema)).
     * @throws Exception
     */
    public void testCreateRelationalDatabase() throws Exception {
        RelationalDatabase database = getDatabase();

        assertEquals("wrong number of tables", 2, database.getTables().size());

        RelationalTable personTable = database.getTableByName("PERSON");
        assertNotNull("table PERSON not found", personTable);

        List<Column> cols = new ArrayList<>(personTable.getColumns());
        assertEquals("wrong number of columns", 3, cols.size());
        assertEquals("wrong column", "ID", cols.get(0).getName());
        assertEquals("wrong column", Boolean.FALSE, cols.get(0).getIsNullable());
        assertEquals("wrong column", Types.BIGINT, cols.get(0).getType());

        assertEquals("wrong column", "NAME", cols.get(1).getName());
        assertEquals("wrong column", Boolean.FALSE, cols.get(1).getIsNullable());
        assertEquals("wrong column", Types.VARCHAR, cols.get(1).getType());

        assertEquals("wrong column", "DOB", cols.get(2).getName());
        assertEquals("wrong column", Boolean.FALSE, cols.get(2).getIsNullable());
        assertEquals("wrong column", Types.TIMESTAMP, cols.get(2).getType());

        assertEquals("wrong number PK columns", Arrays.asList("ID"), personTable.getPkColumns());

        assertEquals("wrong number of indices", 2, personTable.getIndices().size());

        RelationalIndex nameDOB = getIndex(personTable, "NAME", "DOB");
        assertEquals("NAME_DOB_IDX", nameDOB.getName());

        getIndex(personTable, "ID");

        RelationalTable joinTable = database.getTableByName("PERSON_RELATIVES");

        cols = new ArrayList<>(joinTable.getColumns());
        assertEquals("wrong number of columns", 3, cols.size());

        assertEquals("wrong column", "PERSON_ID", cols.get(0).getName());
        assertEquals("wrong column", Boolean.FALSE, cols.get(0).getIsNullable());
        assertEquals("wrong column", Types.BIGINT, cols.get(0).getType());

        assertEquals("wrong column", "RELATIVE_ID", cols.get(1).getName());
        assertEquals("wrong column", Boolean.FALSE, cols.get(1).getIsNullable());
        assertEquals("wrong column", Types.BIGINT, cols.get(1).getType());

        assertEquals("wrong column", "RELATIONSHIP", cols.get(2).getName());
        assertEquals("wrong column", Boolean.TRUE, cols.get(2).getIsNullable());
        assertEquals("wrong column", Types.VARCHAR, cols.get(2).getType());

        assertEquals("wrong PK columns", Arrays.asList("PERSON_ID", "RELATIVE_ID"), joinTable.getPkColumns());

        getIndex(joinTable, "PERSON_ID", "RELATIVE_ID");

        ForeignKey fkPerson = getForeignKey(joinTable, "FK_PERSON");
        assertEquals("PERSON_ID", fkPerson.getFkColumn());
        assertEquals("PERSON_RELATIVES", fkPerson.getFkTable());

        assertEquals("ID", fkPerson.getPkColumn());
        assertEquals("PERSON", fkPerson.getPkTable());

        ForeignKey fkRelative = getForeignKey(joinTable, "FK_RELATIVE");
        assertEquals("RELATIVE_ID", fkRelative.getFkColumn());
        assertEquals("PERSON_RELATIVES", fkRelative.getFkTable());

        assertEquals("ID", fkRelative.getPkColumn());
        assertEquals("PERSON", fkRelative.getPkTable());
    }
}