/***************************************************************** * 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.dbsync.reverse.dbload; import java.sql.DatabaseMetaData; import java.sql.Types; import org.apache.cayenne.dba.TypesMapping; import org.apache.cayenne.map.DbAttribute; import org.apache.cayenne.map.DbEntity; import org.junit.Test; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertTrue; public class AttributeLoaderIT extends BaseLoaderIT { @Test public void testAttributeLoad() throws Exception { createDbEntities(); AttributeLoader loader = new AttributeLoader(adapter, EMPTY_CONFIG, new DefaultDbLoaderDelegate()); loader.load(connection.getMetaData(), store); DbEntity artist = getDbEntity("ARTIST"); DbAttribute a = getDbAttribute(artist, "ARTIST_ID"); assertNotNull(a); if(accessStackAdapter.onlyGenericNumberType()) { assertEquals(Types.INTEGER, a.getType()); } else { assertEquals(Types.BIGINT, a.getType()); } assertTrue(a.isMandatory()); assertFalse(a.isGenerated()); a = getDbAttribute(artist, "ARTIST_NAME"); assertNotNull(a); assertEquals(Types.CHAR, a.getType()); assertEquals(254, a.getMaxLength()); assertTrue(a.isMandatory()); a = getDbAttribute(artist, "DATE_OF_BIRTH"); assertNotNull(a); if(accessStackAdapter.onlyGenericDateType()) { assertTrue(Types.DATE == a.getType() || Types.TIMESTAMP == a.getType()); } else { assertEquals(Types.DATE, a.getType()); } assertFalse(a.isMandatory()); if(accessStackAdapter.supportsLobs()) { assertLobDbEntities(); } if (adapter.supportsGeneratedKeys()) { assertGenerated(); } } @Test public void testAttributeLoadTypes() throws Exception { DatabaseMetaData metaData = connection.getMetaData(); DbLoaderDelegate delegate = new DefaultDbLoaderDelegate(); // We need all data to check relationships, so simply load it all EntityLoader entityLoader = new EntityLoader(adapter, EMPTY_CONFIG, delegate); AttributeLoader attributeLoader = new AttributeLoader(adapter, EMPTY_CONFIG, delegate); entityLoader.load(metaData, store); attributeLoader.load(metaData, store); DbEntity dbe = getDbEntity("PAINTING"); DbEntity floatTest = getDbEntity("FLOAT_TEST"); DbEntity smallintTest = getDbEntity("SMALLINT_TEST"); DbAttribute integerAttr = getDbAttribute(dbe, "PAINTING_ID"); DbAttribute decimalAttr = getDbAttribute(dbe, "ESTIMATED_PRICE"); DbAttribute varcharAttr = getDbAttribute(dbe, "PAINTING_TITLE"); DbAttribute floatAttr = getDbAttribute(floatTest, "FLOAT_COL"); DbAttribute smallintAttr = getDbAttribute(smallintTest, "SMALLINT_COL"); // check decimal assertTrue(msgForTypeMismatch(Types.DECIMAL, decimalAttr), Types.DECIMAL == decimalAttr.getType() || Types.NUMERIC == decimalAttr.getType()); assertEquals(2, decimalAttr.getScale()); // check varchar assertEquals(msgForTypeMismatch(Types.VARCHAR, varcharAttr), Types.VARCHAR, varcharAttr.getType()); assertEquals(255, varcharAttr.getMaxLength()); // check integer assertEquals(msgForTypeMismatch(Types.INTEGER, integerAttr), Types.INTEGER, integerAttr.getType()); // check float assertTrue(msgForTypeMismatch(Types.FLOAT, floatAttr), Types.FLOAT == floatAttr.getType() || Types.DOUBLE == floatAttr.getType() || Types.REAL == floatAttr.getType()); // check smallint assertTrue(msgForTypeMismatch(Types.SMALLINT, smallintAttr), Types.SMALLINT == smallintAttr.getType() || Types.INTEGER == smallintAttr.getType()); } private void assertGenerated() { DbEntity bag = getDbEntity("GENERATED_COLUMN_TEST"); DbAttribute id = getDbAttribute(bag, "GENERATED_COLUMN"); assertTrue(id.isGenerated()); } private void assertLobDbEntities() { DbEntity blobEnt = getDbEntity("BLOB_TEST"); assertNotNull(blobEnt); DbAttribute blobAttr = getDbAttribute(blobEnt, "BLOB_COL"); assertNotNull(blobAttr); assertTrue(msgForTypeMismatch(Types.BLOB, blobAttr), Types.BLOB == blobAttr.getType() || Types.VARBINARY == blobAttr.getType() || Types.LONGVARBINARY == blobAttr.getType()); DbEntity clobEnt = getDbEntity("CLOB_TEST"); assertNotNull(clobEnt); DbAttribute clobAttr = getDbAttribute(clobEnt, "CLOB_COL"); assertNotNull(clobAttr); assertTrue(msgForTypeMismatch(Types.CLOB, clobAttr), Types.CLOB == clobAttr.getType() || Types.VARCHAR == clobAttr.getType() || Types.LONGVARCHAR == clobAttr.getType()); } private DbAttribute getDbAttribute(DbEntity ent, String name) { DbAttribute da = ent.getAttribute(name); // sometimes table names get converted to lowercase if (da == null) { da = ent.getAttribute(name.toLowerCase()); } return da; } private static String msgForTypeMismatch(int origType, DbAttribute newAttr) { String nt = TypesMapping.getSqlNameByType(newAttr.getType()); String ot = TypesMapping.getSqlNameByType(origType); return attrMismatch(newAttr.getName(), "expected type: <" + ot + ">, but was <" + nt + ">"); } private static String attrMismatch(String attrName, String msg) { return "[Error loading attribute '" + attrName + "': " + msg + "]"; } }