http://git-wip-us.apache.org/repos/asf/cayenne/blob/16a8cec6/cayenne-server/src/main/java/org/apache/cayenne/access/DbLoader.java ---------------------------------------------------------------------- diff --cc cayenne-server/src/main/java/org/apache/cayenne/access/DbLoader.java index a994ce2,c8589e0..e538e48 --- a/cayenne-server/src/main/java/org/apache/cayenne/access/DbLoader.java +++ b/cayenne-server/src/main/java/org/apache/cayenne/access/DbLoader.java @@@ -671,16 -734,14 +671,15 @@@ public class DbLoader } /** + * By default we want to load Tables and Views for mo types + * + * @see DbLoader#getTableTypes() - * - * @since 3.2 + * @since 4.0 */ public String[] getDefaultTableTypes() { - String viewType = adapter.tableTypeForView(); - String tableType = adapter.tableTypeForTable(); - - // use types that are not null List<String> list = new ArrayList<String>(2); + + String viewType = adapter.tableTypeForView(); if (viewType != null) { list.add(viewType); } @@@ -699,8 -760,8 +698,8 @@@ * tables and views. * * @since 1.0.7 - * @deprecated since 3.2 use + * @deprecated since 4.0 use - * {@link #load(DataMap, String, String, String, String...)} + * {@link #load(org.apache.cayenne.map.DataMap, DbLoaderConfiguration, String...)} * method that supports catalogs. */ @Deprecated @@@ -723,8 -781,8 +722,8 @@@ * contains default mapping of the tables and views. Allows to limit types * of tables to read. * - * @deprecated since 3.2 use + * @deprecated since 4.0 use - * {@link #load(DataMap, String, String, String, String...)} + * {@link #load(org.apache.cayenne.map.DataMap, DbLoaderConfiguration, String...)} * method that supports catalogs. */ @Deprecated @@@ -755,16 -799,21 +754,16 @@@ * schema, table name and table type patterns and fills the specified * DataMap object with DB and object mapping info. * - * @since 3.2 + * @since 4.0 */ - public void load(DataMap dataMap, String catalogPattern, String schemaPattern, String tablePattern, - String... tableTypes) throws SQLException { - - if (tablePattern == null) { - tablePattern = WILDCARD; - } + public void load(DataMap dataMap, DbLoaderConfiguration config, String... tableTypes) throws SQLException { - List<DbEntity> tables = getTables(catalogPattern, schemaPattern, tablePattern, tableTypes); + List<DbEntity> entities = loadDbEntities(dataMap, config, getTables(config, tableTypes)); - if (loadDbEntities(dataMap, tables)) { - loadDbRelationships(dataMap); + if (entities != null) { + loadDbRelationships(dataMap, config, entities); + loadObjEntities(dataMap, config, entities); - loadObjEntities(dataMap); flattenManyToManyRelationships(dataMap); fireObjEntitiesAddedEvents(dataMap); } @@@ -798,17 -829,12 +797,17 @@@ * </p> * * @since 1.1 - * @deprecated since 3.2 use - * {@link #loadProcedures(org.apache.cayenne.map.DataMap, org.apache.cayenne.access.loader.DbLoaderConfiguration)} that + * @deprecated since 4.0 use + * {@link #loadProcedures(DataMap, String, String, String)} that * supports "catalog" pattern. */ + @Deprecated public void loadProceduresFromDB(String schemaPattern, String namePattern, DataMap dataMap) throws SQLException { - loadProcedures(dataMap, null, schemaPattern, namePattern); + DbLoaderConfiguration configuration = new DbLoaderConfiguration(); + configuration.setFiltersConfig(new FiltersConfig(new EntityFilters( + new DbPath(null, schemaPattern), NULL, NULL, include(namePattern)))); + + loadProcedures(dataMap, configuration); } /** @@@ -820,27 -846,61 +819,27 @@@ * be invoked explicitly by the user. </i> * </p> * - * @since 3.2 + * @since 4.0 */ - public void loadProcedures(DataMap dataMap, String catalogPattern, String schemaPattern, String namePattern) + public Map<String, Procedure> loadProcedures(DataMap dataMap, DbLoaderConfiguration config) throws SQLException { - Map<String, Procedure> procedures = null; - - // get procedures - ResultSet rs = getMetaData().getProcedures(catalogPattern, schemaPattern, namePattern); - try { - while (rs.next()) { - String name = rs.getString("PROCEDURE_NAME"); - - // TODO: this will be moved to Delegate... - if (EXCLUDED_PROCEDURES.contains(name)) { - logger.info("skipping Cayenne PK procedure: " + name); - continue; - } - - String catalog = rs.getString("PROCEDURE_CAT"); - String schema = rs.getString("PROCEDURE_SCHEM"); - - short type = rs.getShort("PROCEDURE_TYPE"); - - Procedure procedure = new Procedure(name); - procedure.setCatalog(catalog); - procedure.setSchema(schema); - - switch (type) { - case DatabaseMetaData.procedureNoResult: - case DatabaseMetaData.procedureResultUnknown: - procedure.setReturningValue(false); - break; - case DatabaseMetaData.procedureReturnsResult: - procedure.setReturningValue(true); - break; - } + Map<String, Procedure> procedures = loadProcedures(config); + if (procedures.isEmpty()) { + return procedures; + } - if (procedures == null) { - procedures = new HashMap<String, Procedure>(); - } + loadProceduresColumns(procedures); - procedures.put(procedure.getFullyQualifiedName(), procedure); - } - } finally { - rs.close(); + for (Procedure procedure : procedures.values()) { + dataMap.addProcedure(procedure); } - // if nothing found, return - if (procedures == null) { - return; - } + return procedures; + } - // get columns - ResultSet columnsRS = getMetaData().getProcedureColumns(null, schemaPattern, namePattern, null); + private void loadProceduresColumns(Map<String, Procedure> procedures) throws SQLException { + ResultSet columnsRS = getMetaData().getProcedureColumns(null, null, null, null); // TODO catalog, schema try { while (columnsRS.next()) {
http://git-wip-us.apache.org/repos/asf/cayenne/blob/16a8cec6/cayenne-server/src/main/java/org/apache/cayenne/access/loader/DefaultDbLoaderDelegate.java ---------------------------------------------------------------------- diff --cc cayenne-server/src/main/java/org/apache/cayenne/access/loader/DefaultDbLoaderDelegate.java index 2ca2d97,0000000..bc91162 mode 100644,000000..100644 --- a/cayenne-server/src/main/java/org/apache/cayenne/access/loader/DefaultDbLoaderDelegate.java +++ b/cayenne-server/src/main/java/org/apache/cayenne/access/loader/DefaultDbLoaderDelegate.java @@@ -1,55 -1,0 +1,55 @@@ +/***************************************************************** + * 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.loader; + +import org.apache.cayenne.CayenneException; +import org.apache.cayenne.access.DbLoaderDelegate; +import org.apache.cayenne.map.DbEntity; +import org.apache.cayenne.map.ObjEntity; + +/** - * @since 3.2. ++ * @since 4.0. + */ +public class DefaultDbLoaderDelegate implements DbLoaderDelegate { + + @Override + public boolean overwriteDbEntity(DbEntity entity) throws CayenneException { + return false; + } + + @Override + public void dbEntityAdded(DbEntity entity) { + + } + + @Override + public void dbEntityRemoved(DbEntity entity) { + + } + + @Override + public void objEntityAdded(ObjEntity entity) { + + } + + @Override + public void objEntityRemoved(ObjEntity entity) { + + } +} http://git-wip-us.apache.org/repos/asf/cayenne/blob/16a8cec6/cayenne-server/src/main/java/org/apache/cayenne/access/loader/filters/ExcludeFilter.java ---------------------------------------------------------------------- diff --cc cayenne-server/src/main/java/org/apache/cayenne/access/loader/filters/ExcludeFilter.java index 5bc794a,0000000..932531f mode 100644,000000..100644 --- a/cayenne-server/src/main/java/org/apache/cayenne/access/loader/filters/ExcludeFilter.java +++ b/cayenne-server/src/main/java/org/apache/cayenne/access/loader/filters/ExcludeFilter.java @@@ -1,42 -1,0 +1,42 @@@ +/***************************************************************** + * 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.loader.filters; + +import java.util.regex.Pattern; + +/** - * @since 3.2. ++ * @since 4.0 + * @Immutable + */ +public class ExcludeFilter extends IncludeFilter { + + ExcludeFilter(Pattern pattern) { + super(pattern); + } + + @Override + public boolean isInclude(String obj) { + return !super.isInclude(obj); + } + + @Override + public String toString() { + return "-(" + super.getPattern() + ')'; + } +} http://git-wip-us.apache.org/repos/asf/cayenne/blob/16a8cec6/cayenne-server/src/main/java/org/apache/cayenne/dba/JdbcAdapter.java ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/cayenne/blob/16a8cec6/cayenne-server/src/main/java/org/apache/cayenne/map/DataMap.java ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/cayenne/blob/16a8cec6/cayenne-server/src/main/java/org/apache/cayenne/map/DbRelationship.java ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/cayenne/blob/16a8cec6/cayenne-server/src/main/java/org/apache/cayenne/map/ObjEntity.java ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/cayenne/blob/16a8cec6/cayenne-server/src/main/java/org/apache/cayenne/map/naming/DefaultUniqueNameGenerator.java ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/cayenne/blob/16a8cec6/cayenne-server/src/main/java/org/apache/cayenne/map/naming/NameCheckers.java ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/cayenne/blob/16a8cec6/cayenne-server/src/main/java/org/apache/cayenne/util/EntityMergeSupport.java ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/cayenne/blob/16a8cec6/cayenne-server/src/test/java/org/apache/cayenne/access/DbLoaderIT.java ---------------------------------------------------------------------- diff --cc cayenne-server/src/test/java/org/apache/cayenne/access/DbLoaderIT.java index 0000000,8bad0d2..04efb54 mode 000000,100644..100644 --- a/cayenne-server/src/test/java/org/apache/cayenne/access/DbLoaderIT.java +++ b/cayenne-server/src/test/java/org/apache/cayenne/access/DbLoaderIT.java @@@ -1,0 -1,388 +1,576 @@@ + /***************************************************************** + * 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.sql.Types; ++import java.util.Collection; ++import java.util.List; ++ ++import org.apache.cayenne.access.loader.DbLoaderConfiguration; + import org.apache.cayenne.configuration.server.ServerRuntime; + import org.apache.cayenne.dba.DbAdapter; + import org.apache.cayenne.dba.TypesMapping; + import org.apache.cayenne.di.Inject; + import org.apache.cayenne.map.DataMap; + import org.apache.cayenne.map.DbAttribute; + import org.apache.cayenne.map.DbEntity; + import org.apache.cayenne.map.DbRelationship; + import org.apache.cayenne.map.ObjAttribute; + import org.apache.cayenne.map.ObjEntity; + import org.apache.cayenne.unit.UnitDbAdapter; + import org.apache.cayenne.unit.di.server.ServerCase; + import org.apache.cayenne.unit.di.server.ServerCaseDataSourceFactory; + import org.apache.cayenne.unit.di.server.UseServerRuntime; + import org.junit.Test; + + import java.sql.Types; + import java.util.Collection; + import java.util.List; + + import static org.junit.Assert.assertEquals; + import static org.junit.Assert.assertFalse; + import static org.junit.Assert.assertNotNull; + import static org.junit.Assert.assertNull; + import static org.junit.Assert.assertTrue; + + @UseServerRuntime(ServerCase.TESTMAP_PROJECT) + public class DbLoaderIT extends ServerCase { + ++ public static final DbLoaderConfiguration CONFIG = new DbLoaderConfiguration(); + @Inject + private ServerRuntime runtime; + + @Inject + private DbAdapter adapter; + + @Inject + private ServerCaseDataSourceFactory dataSourceFactory; + + @Inject + private UnitDbAdapter accessStackAdapter; + + private DbLoader loader; + + @Override + protected void setUpAfterInjection() throws Exception { + loader = new DbLoader(dataSourceFactory.getSharedDataSource().getConnection(), adapter, null); + } + + @Override + protected void tearDownBeforeInjection() throws Exception { + loader.getConnection().close(); + } + + @Test + public void testGetTableTypes() throws Exception { + + List<?> tableTypes = loader.getTableTypes(); + + assertNotNull(tableTypes); + + String tableLabel = adapter.tableTypeForTable(); + if (tableLabel != null) { + assertTrue("Missing type for table '" + tableLabel + "' - " + tableTypes, tableTypes.contains(tableLabel)); + } + + String viewLabel = adapter.tableTypeForView(); + if (viewLabel != null) { + assertTrue("Missing type for view '" + viewLabel + "' - " + tableTypes, tableTypes.contains(viewLabel)); + } + } + + @Test + public void testGetTables() throws Exception { + + String tableLabel = adapter.tableTypeForTable(); + - List<DbEntity> tables = loader.getTables(null, null, "%", new String[] { tableLabel }); ++ List<DbEntity> tables = loader.getTables(new DbLoaderConfiguration(), new String[] { tableLabel }); + + assertNotNull(tables); + + boolean foundArtist = false; + + for (DbEntity table : tables) { + if ("ARTIST".equalsIgnoreCase(table.getName())) { + foundArtist = true; + break; + } + } + + assertTrue("'ARTIST' is missing from the table list: " + tables, foundArtist); + } + + @Test + public void testLoadWithMeaningfulPK() throws Exception { + + DataMap map = new DataMap(); - String tableLabel = adapter.tableTypeForTable(); ++ String[] tableLabel = { adapter.tableTypeForTable() }; + + loader.setCreatingMeaningfulPK(true); + - List<DbEntity> testLoader = loader.getTables(null, null, "artist", new String[] { tableLabel }); - if (testLoader.size() == 0) { - testLoader = loader.getTables(null, null, "ARTIST", new String[] { tableLabel }); ++ List<DbEntity> testLoader = loader.getTables(CONFIG, tableLabel); ++ if (testLoader.isEmpty()) { ++ testLoader = loader.getTables(CONFIG, tableLabel); + } + - loader.loadDbEntities(map, testLoader); ++ List<DbEntity> entities = loader.loadDbEntities(map, CONFIG, testLoader); ++ loader.loadObjEntities(map, CONFIG, entities); + - loader.loadObjEntities(map); + ObjEntity artist = map.getObjEntity("Artist"); + assertNotNull(artist); ++ + ObjAttribute id = artist.getAttribute("artistId"); + assertNotNull(id); + } + + /** + * DataMap loading is in one big test method, since breaking it in + * individual tests would require multiple reads of metatdata which is + * extremely slow on some RDBMS (Sybase). + */ + @Test + public void testLoad() throws Exception { + + boolean supportsUnique = runtime.getDataDomain().getDataNodes().iterator().next().getAdapter() + .supportsUniqueConstraints(); + boolean supportsLobs = accessStackAdapter.supportsLobs(); + boolean supportsFK = accessStackAdapter.supportsFKConstraints(); + + DataMap map = new DataMap(); + map.setDefaultPackage("foo.x"); + + String tableLabel = adapter.tableTypeForTable(); + + // *** TESTING THIS *** - loader.loadDbEntities(map, loader.getTables(null, null, "%", new String[] { tableLabel })); ++ List<DbEntity> entities = loader.loadDbEntities(map, CONFIG, loader.getTables(CONFIG, new String[]{tableLabel})); + + assertDbEntities(map); + + if (supportsLobs) { + assertLobDbEntities(map); + } + + // *** TESTING THIS *** - loader.loadDbRelationships(map); ++ loader.loadDbRelationships(map, CONFIG, entities); + + if (supportsFK) { + Collection<DbRelationship> rels = getDbEntity(map, "ARTIST").getRelationships(); + assertNotNull(rels); - assertTrue(rels.size() > 0); ++ assertTrue(!rels.isEmpty()); + + // test one-to-one + rels = getDbEntity(map, "PAINTING").getRelationships(); + assertNotNull(rels); + + // find relationship to PAINTING_INFO + DbRelationship oneToOne = null; + for (DbRelationship rel : rels) { + if ("PAINTING_INFO".equalsIgnoreCase(rel.getTargetEntityName())) { + oneToOne = rel; + break; + } + } + + assertNotNull("No relationship to PAINTING_INFO", oneToOne); + assertFalse("Relationship to PAINTING_INFO must be to-one", oneToOne.isToMany()); + assertTrue("Relationship to PAINTING_INFO must be to-one", oneToOne.isToDependentPK()); + + // test UNIQUE only if FK is supported... + if (supportsUnique) { + assertUniqueConstraintsInRelationships(map); + } + } + + // *** TESTING THIS *** + loader.setCreatingMeaningfulPK(false); - loader.loadObjEntities(map); ++ loader.loadObjEntities(map, CONFIG, entities); + + assertObjEntities(map); + + // now when the map is loaded, test + // various things + // selectively check how different types were processed + if (accessStackAdapter.supportsColumnTypeReengineering()) { + checkTypes(map); + } + } + + private void assertUniqueConstraintsInRelationships(DataMap map) { + // unfortunately JDBC metadata doesn't provide info for UNIQUE + // constraints.... + // cant reengineer them... + + // find rel to TO_ONEFK1 + /* + * Iterator it = getDbEntity(map, + * "TO_ONEFK2").getRelationships().iterator(); DbRelationship rel = + * (DbRelationship) it.next(); assertEquals("TO_ONEFK1", + * rel.getTargetEntityName()); + * assertFalse("UNIQUE constraint was ignored...", rel.isToMany()); + */ + } + + private void assertDbEntities(DataMap map) { + DbEntity dae = getDbEntity(map, "ARTIST"); + assertNotNull("Null 'ARTIST' entity, other DbEntities: " + map.getDbEntityMap(), dae); + assertEquals("ARTIST", dae.getName().toUpperCase()); + + if (accessStackAdapter.supportsCatalogs()) { + assertNotNull(dae.getCatalog()); + assertEquals("CAYENNE", dae.getCatalog().toUpperCase()); + } + + DbAttribute a = getDbAttribute(dae, "ARTIST_ID"); + assertNotNull(a); + assertTrue(a.isPrimaryKey()); + assertFalse(a.isGenerated()); + + if (adapter.supportsGeneratedKeys()) { + DbEntity bag = getDbEntity(map, "BAG"); + DbAttribute id = bag.getAttribute("ID"); + assertTrue(id.isPrimaryKey()); + assertTrue(id.isGenerated()); + } + } + + private void assertObjEntities(DataMap map) { + + boolean supportsLobs = accessStackAdapter.supportsLobs(); + boolean supportsFK = accessStackAdapter.supportsFKConstraints(); + + ObjEntity ae = map.getObjEntity("Artist"); + assertNotNull(ae); + assertEquals("Artist", ae.getName()); + + // assert primary key is not an attribute + assertNull(ae.getAttribute("artistId")); + + if (supportsLobs) { + assertLobObjEntities(map); + } + + if (supportsFK) { + Collection<?> rels1 = ae.getRelationships(); + assertNotNull(rels1); + assertTrue(rels1.size() > 0); + } + + assertEquals("foo.x.Artist", ae.getClassName()); + } + + private void assertLobDbEntities(DataMap map) { + DbEntity blobEnt = getDbEntity(map, "BLOB_TEST"); + assertNotNull(blobEnt); + DbAttribute blobAttr = getDbAttribute(blobEnt, "BLOB_COL"); + assertNotNull(blobAttr); + assertTrue(msgForTypeMismatch(Types.BLOB, blobAttr), Types.BLOB == blobAttr.getType() + || Types.LONGVARBINARY == blobAttr.getType()); + DbEntity clobEnt = getDbEntity(map, "CLOB_TEST"); + assertNotNull(clobEnt); + DbAttribute clobAttr = getDbAttribute(clobEnt, "CLOB_COL"); + assertNotNull(clobAttr); + assertTrue(msgForTypeMismatch(Types.CLOB, clobAttr), Types.CLOB == clobAttr.getType() + || Types.LONGVARCHAR == clobAttr.getType()); + } + + private void assertLobObjEntities(DataMap map) { + ObjEntity blobEnt = map.getObjEntity("BlobTest"); + assertNotNull(blobEnt); + // BLOBs should be mapped as byte[] + ObjAttribute blobAttr = blobEnt.getAttribute("blobCol"); - assertNotNull("BlobTest.blobCol failed to load", blobAttr); ++ assertNotNull("BlobTest.blobCol failed to doLoad", blobAttr); + assertEquals("byte[]", blobAttr.getType()); + ObjEntity clobEnt = map.getObjEntity("ClobTest"); + assertNotNull(clobEnt); + // CLOBs should be mapped as Strings by default + ObjAttribute clobAttr = clobEnt.getAttribute("clobCol"); + assertNotNull(clobAttr); + assertEquals(String.class.getName(), clobAttr.getType()); + } + + private DbEntity getDbEntity(DataMap map, String name) { + DbEntity de = map.getDbEntity(name); + // sometimes table names get converted to lowercase + if (de == null) { + de = map.getDbEntity(name.toLowerCase()); + } + + return de; + } + + 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 DataMap originalMap() { + return runtime.getDataDomain().getDataNodes().iterator().next().getDataMaps().iterator().next(); + } + + /** + * Selectively check how different types were processed. + */ + public void checkTypes(DataMap map) { + DbEntity dbe = getDbEntity(map, "PAINTING"); + DbEntity floatTest = getDbEntity(map, "FLOAT_TEST"); + DbEntity smallintTest = getDbEntity(map, "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()); + } + + public void checkAllDBEntities(DataMap map) { + + for (DbEntity origEnt : originalMap().getDbEntities()) { + DbEntity newEnt = map.getDbEntity(origEnt.getName()); + for (DbAttribute origAttr : origEnt.getAttributes()) { + DbAttribute newAttr = newEnt.getAttribute(origAttr.getName()); + assertNotNull("No matching DbAttribute for '" + origAttr.getName(), newAttr); + assertEquals(msgForTypeMismatch(origAttr, newAttr), origAttr.getType(), newAttr.getType()); + // length and precision doesn't have to be the same + // it must be greater or equal + assertTrue(origAttr.getMaxLength() <= newAttr.getMaxLength()); + assertTrue(origAttr.getScale() <= newAttr.getScale()); + } + } + } + - private String msgForTypeMismatch(DbAttribute origAttr, DbAttribute newAttr) { ++ private static String msgForTypeMismatch(DbAttribute origAttr, DbAttribute newAttr) { + return msgForTypeMismatch(origAttr.getType(), newAttr); + } + - private String msgForTypeMismatch(int origType, DbAttribute newAttr) { ++ 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 String attrMismatch(String attrName, String msg) { - StringBuffer buf = new StringBuffer(); - buf.append("[Error loading attribute '").append(attrName).append("': ").append(msg).append("]"); - return buf.toString(); ++ private static String attrMismatch(String attrName, String msg) { ++ return "[Error loading attribute '" + attrName + "': " + msg + "]"; ++ } ++ ++/* ++ TODO ++ ++ @Test ++ public void testCreateLoader() throws Exception { ++ ++ DbLoader loader = parameters.createLoader(mock(DbAdapter.class), connection, ++ mock(DbLoaderDelegate.class)); ++ assertNotNull(loader); ++ assertSame(connection, loader.getConnection()); ++ ++ assertTrue(loader.includeTableName("dummy")); ++ } ++ ++ @Test ++ public void testCreateLoader_IncludeExclude() throws Exception { ++ DbImportConfiguration parameters = new DbImportConfiguration(); ++ parameters.setIncludeTables("a,b,c*"); ++ ++ DbLoader loader1 = parameters.createLoader(mock(DbAdapter.class), mock(Connection.class), ++ mock(DbLoaderDelegate.class)); ++ ++ assertFalse(loader1.includeTableName("dummy")); ++ assertFalse(loader1.includeTableName("ab")); ++ assertTrue(loader1.includeTableName("a")); ++ assertTrue(loader1.includeTableName("b")); ++ assertTrue(loader1.includeTableName("cd")); ++ ++ parameters.setExcludeTables("cd"); ++ ++ DbLoader loader2 = parameters.createLoader(mock(DbAdapter.class), mock(Connection.class), ++ mock(DbLoaderDelegate.class)); ++ ++ assertFalse(loader2.includeTableName("dummy")); ++ assertFalse(loader2.includeTableName("ab")); ++ assertTrue(loader2.includeTableName("a")); ++ assertTrue(loader2.includeTableName("b")); ++ assertFalse(loader2.includeTableName("cd")); ++ assertTrue(loader2.includeTableName("cx")); ++ } ++ ++ ++ @Test ++ public void testCreateLoader_MeaningfulPk_Default() throws Exception { ++ DbImportConfiguration parameters = new DbImportConfiguration(); ++ assertNull(parameters.getMeaningfulPkTables()); ++ ++ DbLoader loader1 = parameters.createLoader(mock(DbAdapter.class), mock(Connection.class), ++ mock(DbLoaderDelegate.class)); ++ ++ DataMap map = new DataMap(); ++ ++ DbEntity e1 = new DbEntity("e1"); ++ DbAttribute pk = new DbAttribute("pk", Types.INTEGER, e1); ++ pk.setPrimaryKey(true); ++ e1.addAttribute(pk); ++ DbAttribute nonPk = new DbAttribute("nonPk", Types.INTEGER, e1); ++ e1.addAttribute(nonPk); ++ ++ map.addDbEntity(e1); ++ ++ // DbLoader is so ugly and hard to test.. ++ Field dbEntityList = DbLoader.class.getDeclaredField("dbEntityList"); ++ dbEntityList.setAccessible(true); ++ List<DbEntity> entities = (List<DbEntity>) dbEntityList.get(loader1); ++ entities.add(e1); ++ ++ loader1.loadObjEntities(map, entities); ++ ++ ObjEntity oe1 = map.getObjEntity("E1"); ++ assertEquals(1, oe1.getAttributes().size()); ++ assertNotNull(oe1.getAttribute("nonPk")); ++ } ++ ++ @Test ++ public void testCreateLoader_MeaningfulPk_Specified() throws Exception { ++ DbImportConfiguration parameters = new DbImportConfiguration(); ++ parameters.setMeaningfulPkTables("a*"); ++ ++ DbLoader loader1 = parameters.createLoader(mock(DbAdapter.class), mock(Connection.class), ++ mock(DbLoaderDelegate.class)); ++ ++ // DbLoader is so ugly and hard to test.. ++ Field dbEntityList = DbLoader.class.getDeclaredField("dbEntityList"); ++ dbEntityList.setAccessible(true); ++ Collection<DbEntity> entities = (List<DbEntity>) dbEntityList.get(loader1); ++ ++ DataMap map = new DataMap(); ++ ++ DbEntity e1 = new DbEntity("e1"); ++ DbAttribute pk = new DbAttribute("pk", Types.INTEGER, e1); ++ pk.setPrimaryKey(true); ++ e1.addAttribute(pk); ++ DbAttribute nonPk = new DbAttribute("nonPk", Types.INTEGER, e1); ++ e1.addAttribute(nonPk); ++ ++ map.addDbEntity(e1); ++ entities.add(e1); ++ ++ DbEntity a1 = new DbEntity("a1"); ++ DbAttribute apk = new DbAttribute("pk", Types.INTEGER, a1); ++ apk.setPrimaryKey(true); ++ a1.addAttribute(apk); ++ DbAttribute anonPk = new DbAttribute("nonPk", Types.INTEGER, a1); ++ a1.addAttribute(anonPk); ++ ++ map.addDbEntity(a1); ++ entities.add(a1); ++ ++ loader1.loadObjEntities(map, entities); ++ ++ ObjEntity oe1 = map.getObjEntity("E1"); ++ assertEquals(1, oe1.getAttributes().size()); ++ assertNotNull(oe1.getAttribute("nonPk")); ++ ++ ObjEntity oe2 = map.getObjEntity("A1"); ++ assertEquals(2, oe2.getAttributes().size()); ++ assertNotNull(oe2.getAttribute("nonPk")); ++ assertNotNull(oe2.getAttribute("pk")); ++ } ++ ++ @Test ++ public void testCreateLoader_UsePrimitives_False() throws Exception { ++ DbImportConfiguration parameters = new DbImportConfiguration(); ++ parameters.setUsePrimitives(false); ++ ++ DbLoader loader1 = parameters.createLoader(mock(DbAdapter.class), mock(Connection.class), ++ mock(DbLoaderDelegate.class)); ++ ++ DataMap map = new DataMap(); ++ ++ DbEntity e1 = new DbEntity("e1"); ++ DbAttribute nonPk = new DbAttribute("nonPk", Types.INTEGER, e1); ++ e1.addAttribute(nonPk); ++ ++ map.addDbEntity(e1); ++ ++ // DbLoader is so ugly and hard to test.. ++ Field dbEntityList = DbLoader.class.getDeclaredField("dbEntityList"); ++ dbEntityList.setAccessible(true); ++ List<DbEntity> entities = (List<DbEntity>) dbEntityList.get(loader1); ++ entities.add(e1); ++ ++ loader1.loadObjEntities(map, entities); ++ ++ ObjEntity oe1 = map.getObjEntity("E1"); ++ ++ ObjAttribute oa1 = oe1.getAttribute("nonPk"); ++ assertEquals("java.lang.Integer", oa1.getType()); ++ } ++ ++ @Test ++ public void testCreateLoader_UsePrimitives_True() throws Exception { ++ DbImportConfiguration parameters = new DbImportConfiguration(); ++ parameters.setUsePrimitives(true); ++ ++ DbLoader loader1 = parameters.createLoader(mock(DbAdapter.class), mock(Connection.class), ++ mock(DbLoaderDelegate.class)); ++ ++ DataMap map = new DataMap(); ++ ++ DbEntity e1 = new DbEntity("e1"); ++ DbAttribute nonPk = new DbAttribute("nonPk", Types.INTEGER, e1); ++ e1.addAttribute(nonPk); ++ ++ map.addDbEntity(e1); ++ ++ // DbLoader is so ugly and hard to test.. ++ Field dbEntityList = DbLoader.class.getDeclaredField("dbEntityList"); ++ dbEntityList.setAccessible(true); ++ List<DbEntity> entities = (List<DbEntity>) dbEntityList.get(loader1); ++ entities.add(e1); ++ ++ loader1.loadObjEntities(map, entities); ++ ++ ObjEntity oe1 = map.getObjEntity("E1"); ++ ++ ObjAttribute oa1 = oe1.getAttribute("nonPk"); ++ assertEquals("int", oa1.getType()); + } ++*/ ++ + } http://git-wip-us.apache.org/repos/asf/cayenne/blob/16a8cec6/cayenne-server/src/test/java/org/apache/cayenne/access/DbLoaderPartialIT.java ---------------------------------------------------------------------- diff --cc cayenne-server/src/test/java/org/apache/cayenne/access/DbLoaderPartialIT.java index 0000000,4b0a9cd..4cac2b2 mode 000000,100644..100644 --- a/cayenne-server/src/test/java/org/apache/cayenne/access/DbLoaderPartialIT.java +++ b/cayenne-server/src/test/java/org/apache/cayenne/access/DbLoaderPartialIT.java @@@ -1,0 -1,122 +1,123 @@@ + /***************************************************************** + * 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.CayenneException; + import org.apache.cayenne.dba.DbAdapter; + import org.apache.cayenne.di.Inject; + import org.apache.cayenne.map.DataMap; + import org.apache.cayenne.map.DbEntity; ++import org.apache.cayenne.access.loader.DefaultDbLoaderDelegate; + import org.apache.cayenne.unit.di.server.ServerCase; + import org.apache.cayenne.unit.di.server.ServerCaseDataSourceFactory; + import org.apache.cayenne.unit.di.server.UseServerRuntime; + import org.junit.Test; + + import java.util.Collection; + + import static org.junit.Assert.assertEquals; + import static org.junit.Assert.assertNotNull; + + @UseServerRuntime(ServerCase.TESTMAP_PROJECT) + public class DbLoaderPartialIT extends ServerCase { + + @Inject + private DbAdapter adapter; + + @Inject + private ServerCaseDataSourceFactory dataSourceFactory; + + private DbLoader loader; + + @Override + protected void setUpAfterInjection() throws Exception { + loader = new DbLoader( + dataSourceFactory.getSharedDataSource().getConnection(), + adapter, + new DefaultDbLoaderDelegate() { + + public boolean overwriteDbEntity(DbEntity ent) throws CayenneException { + return !(ent.getName().equalsIgnoreCase("ARTIST") + || ent.getName().equalsIgnoreCase("PAINTING")); + } + }); + } + + @Override + protected void tearDownBeforeInjection() throws Exception { + loader.getConnection().close(); + } + + /** + * Tests that FKs are properly loaded when the relationship source is not loaded. See + * CAY-479. This test will perform two reverse engineers. The second reverse engineer + * will skip two tables that share relationships with PAINTING. Relationships in + * ARTIST and GALLERY should remain unmodified, and all PAINTING relationships should + * be loaded. + */ + @Test + public void testPartialLoad() throws Exception { + + DataMap map = new DataMap(); + String tableLabel = adapter.tableTypeForTable(); + + loader.loadDataMapFromDB(null, "%", new String[] { + tableLabel + }, map); + + Collection<?> rels = getDbEntity(map, "ARTIST").getRelationships(); + assertNotNull(rels); + int artistRels = rels.size(); + + rels = getDbEntity(map, "GALLERY").getRelationships(); + assertNotNull(rels); + int galleryRels = rels.size(); + + rels = getDbEntity(map, "PAINTING").getRelationships(); + assertNotNull(rels); + int paintingRels = rels.size(); + + loader.loadDataMapFromDB(null, "%", new String[] { + tableLabel + }, map); + + rels = getDbEntity(map, "ARTIST").getRelationships(); + assertNotNull(rels); + assertEquals(artistRels, rels.size()); + + rels = getDbEntity(map, "GALLERY").getRelationships(); + assertNotNull(rels); + assertEquals(galleryRels, rels.size()); + + rels = getDbEntity(map, "PAINTING").getRelationships(); + assertNotNull(rels); + assertEquals(paintingRels, rels.size()); + } + + private DbEntity getDbEntity(DataMap map, String name) { + DbEntity de = map.getDbEntity(name); + // sometimes table names get converted to lowercase + if (de == null) { + de = map.getDbEntity(name.toLowerCase()); + } + + return de; + } + } http://git-wip-us.apache.org/repos/asf/cayenne/blob/16a8cec6/cayenne-server/src/test/java/org/apache/cayenne/access/loader/ManyToManyCandidateEntityTest.java ---------------------------------------------------------------------- diff --cc cayenne-server/src/test/java/org/apache/cayenne/access/loader/ManyToManyCandidateEntityTest.java index 4348edf,0000000..ad4238f mode 100644,000000..100644 --- a/cayenne-server/src/test/java/org/apache/cayenne/access/loader/ManyToManyCandidateEntityTest.java +++ b/cayenne-server/src/test/java/org/apache/cayenne/access/loader/ManyToManyCandidateEntityTest.java @@@ -1,106 -1,0 +1,113 @@@ +/***************************************************************** + * 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.loader; + - import junit.framework.TestCase; - +import org.apache.cayenne.configuration.ConfigurationNameMapper; +import org.apache.cayenne.configuration.ConfigurationTree; +import org.apache.cayenne.configuration.DataChannelDescriptor; +import org.apache.cayenne.configuration.DataMapLoader; +import org.apache.cayenne.configuration.DefaultConfigurationNameMapper; +import org.apache.cayenne.configuration.XMLDataChannelDescriptorLoader; +import org.apache.cayenne.configuration.XMLDataMapLoader; +import org.apache.cayenne.di.AdhocObjectFactory; +import org.apache.cayenne.di.Binder; +import org.apache.cayenne.di.ClassLoaderManager; +import org.apache.cayenne.di.DIBootstrap; +import org.apache.cayenne.di.Injector; +import org.apache.cayenne.di.Module; +import org.apache.cayenne.di.spi.DefaultAdhocObjectFactory; +import org.apache.cayenne.di.spi.DefaultClassLoaderManager; +import org.apache.cayenne.map.DataMap; +import org.apache.cayenne.map.ObjEntity; +import org.apache.cayenne.map.Relationship; +import org.apache.cayenne.map.naming.LegacyNameGenerator; +import org.apache.cayenne.resource.URLResource; ++import org.junit.Before; ++import org.junit.Test; + +import java.net.URL; +import java.util.ArrayList; + - public class ManyToManyCandidateEntityTest extends TestCase { ++import static org.junit.Assert.assertEquals; ++import static org.junit.Assert.assertNotNull; ++import static org.junit.Assert.assertNull; ++ ++public class ManyToManyCandidateEntityTest { + + private DataMap map; + - @Override ++ @Before + public void setUp() throws Exception { + Module testModule = new Module() { + + public void configure(Binder binder) { + binder.bind(ClassLoaderManager.class).to(DefaultClassLoaderManager.class); + binder.bind(AdhocObjectFactory.class).to(DefaultAdhocObjectFactory.class); + binder.bind(DataMapLoader.class).to(XMLDataMapLoader.class); + binder.bind(ConfigurationNameMapper.class).to(DefaultConfigurationNameMapper.class); + } + }; + + Injector injector = DIBootstrap.createInjector(testModule); + + // create and initialize loader instance to test + XMLDataChannelDescriptorLoader loader = new XMLDataChannelDescriptorLoader(); + injector.injectMembers(loader); + + String testConfigName = "relationship-optimisation"; + URL url = getClass().getResource("cayenne-" + testConfigName + ".xml"); + + ConfigurationTree<DataChannelDescriptor> tree = loader.load(new URLResource(url)); + + map = tree.getRootNode().getDataMap(testConfigName); + } + ++ @Test + public void testMatchingForManyToManyEntity() throws Exception { + ObjEntity manyToManyEntity = map.getObjEntity("Table1Table2"); + + assertNotNull(ManyToManyCandidateEntity.build(manyToManyEntity)); + } + ++ @Test + public void testMatchingForNotManyToManyEntity() throws Exception { + ObjEntity entity = map.getObjEntity("Table1"); + + assertNull(ManyToManyCandidateEntity.build(entity)); + } + ++ @Test + public void testOptimisationForManyToManyEntity() { + ObjEntity manyToManyEntity = map.getObjEntity("Table1Table2"); + + ManyToManyCandidateEntity.build(manyToManyEntity).optimizeRelationships(new LegacyNameGenerator()); + + ObjEntity table1Entity = map.getObjEntity("Table1"); + ObjEntity table2Entity = map.getObjEntity("Table2"); + + assertEquals(1, table1Entity.getRelationships().size()); + assertEquals(table2Entity, new ArrayList<Relationship>(table1Entity.getRelationships()).get(0) + .getTargetEntity()); + + assertEquals(1, table2Entity.getRelationships().size()); + assertEquals(table1Entity, new ArrayList<Relationship>(table2Entity.getRelationships()).get(0) + .getTargetEntity()); + } + +} http://git-wip-us.apache.org/repos/asf/cayenne/blob/16a8cec6/cayenne-server/src/test/java/org/apache/cayenne/merge/MergeCase.java ---------------------------------------------------------------------- diff --cc cayenne-server/src/test/java/org/apache/cayenne/merge/MergeCase.java index 1305229,d8fac76..2e75d6b --- a/cayenne-server/src/test/java/org/apache/cayenne/merge/MergeCase.java +++ b/cayenne-server/src/test/java/org/apache/cayenne/merge/MergeCase.java @@@ -18,15 -18,7 +18,8 @@@ ****************************************************************/ package org.apache.cayenne.merge; - import java.sql.Connection; - import java.sql.Statement; - import java.sql.Types; - import java.util.ArrayList; - import java.util.Arrays; - import java.util.List; - import org.apache.cayenne.access.DataNode; +import org.apache.cayenne.access.loader.DbLoaderConfiguration; import org.apache.cayenne.configuration.server.ServerRuntime; import org.apache.cayenne.dba.DbAdapter; import org.apache.cayenne.di.Inject; http://git-wip-us.apache.org/repos/asf/cayenne/blob/16a8cec6/cayenne-tools/pom.xml ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/cayenne/blob/16a8cec6/cayenne-tools/src/main/java/org/apache/cayenne/tools/AntDataPortDelegate.java ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/cayenne/blob/16a8cec6/cayenne-tools/src/main/java/org/apache/cayenne/tools/DbImporterTask.java ---------------------------------------------------------------------- diff --cc cayenne-tools/src/main/java/org/apache/cayenne/tools/DbImporterTask.java index 0407649,b641759..23fe2bd --- a/cayenne-tools/src/main/java/org/apache/cayenne/tools/DbImporterTask.java +++ b/cayenne-tools/src/main/java/org/apache/cayenne/tools/DbImporterTask.java @@@ -121,32 -114,31 +121,32 @@@ public class DbImporterTask extends Tas } /** - * @since 3.2 + * @since 4.0 */ public void setOverwrite(boolean overwrite) { - parameters.setOverwrite(overwrite); + config.setOverwrite(overwrite); } /** - * @deprecated since 3.2 use {@link #setSchema(String)} + * @deprecated since 4.0 use {@link #setSchema(String)} */ + @Deprecated public void setSchemaName(String schemaName) { - this.schemaName = schemaName; + this.setSchema(schemaName); } /** - * @since 3.2 + * @since 4.0 */ public void setSchema(String schema) { - parameters.setSchema(schema); + filterBuilder.schema(schema); } /** - * @since 3.2 + * @since 4.0 */ public void setDefaultPackage(String defaultPackage) { - parameters.setDefaultPackage(defaultPackage); + config.setDefaultPackage(defaultPackage); } public void setTablePattern(String tablePattern) { @@@ -162,21 -154,17 +162,21 @@@ } /** - * @deprecated since 3.2 use {@link #setMeaningfulPkTables(String)} + * @deprecated since 4.0 use {@link #setMeaningfulPkTables(String)} */ public void setMeaningfulPk(boolean meaningfulPk) { - this.meaningfulPk = meaningfulPk; + log("'meaningfulPk' property is deprecated. Use 'meaningfulPkTables' pattern instead", Project.MSG_WARN); + + if (meaningfulPk) { + setMeaningfulPkTables("*"); + } } /** - * @since 3.2 + * @since 4.0 */ public void setMeaningfulPkTables(String meaningfulPkTables) { - parameters.setMeaningfulPkTables(meaningfulPkTables); + config.setMeaningfulPkTables(meaningfulPkTables); } public void setNamingStrategy(String namingStrategy) { @@@ -208,67 -196,43 +208,67 @@@ } /** - * @since 3.2 + * @since 4.0 */ public void setIncludeTables(String includeTables) { - parameters.setIncludeTables(includeTables); + filterBuilder.includeTables(includeTables); } /** - * @since 3.2 + * @since 4.0 */ public void setExcludeTables(String excludeTables) { - parameters.setExcludeTables(excludeTables); + filterBuilder.excludeTables(excludeTables); } /** - * @since 3.2 + * @since 4.0 */ public void setUsePrimitives(boolean usePrimitives) { - parameters.setUsePrimitives(usePrimitives); + config.setUsePrimitives(usePrimitives); } - private void initSchema() { - if (schemaName != null) { - log("'schemaName' property is deprecated. Use 'schema' instead", Project.MSG_WARN); - } + public void addConfiguredIncludeColumn(IncludeColumn includeColumn) { + reverseEngineering.addIncludeColumn(includeColumn); + } - if (parameters.getSchema() == null) { - parameters.setSchema(schemaName); - } + public void addConfiguredExcludeColumn(ExcludeColumn excludeColumn) { + reverseEngineering.addExcludeColumn(excludeColumn); } - private void initMeaningfulPkTables() { - if (meaningfulPk) { - log("'meaningfulPk' property is deprecated. Use 'meaningfulPkTables' pattern instead", Project.MSG_WARN); - } + public void addConfiguredIncludeTable(IncludeTable includeTable) { + reverseEngineering.addIncludeTable(includeTable); + } - if (parameters.getMeaningfulPkTables() == null && meaningfulPk) { - parameters.setMeaningfulPkTables("*"); - } + public void addConfiguredExcludeTable(ExcludeTable excludeTable) { + reverseEngineering.addExcludeTable(excludeTable); + } + + public void addConfiguredIncludeProcedure(IncludeProcedure includeProcedure) { + reverseEngineering.addIncludeProcedure(includeProcedure); + } + + public void addConfiguredExcludeProcedure(ExcludeProcedure excludeProcedure) { + reverseEngineering.addExcludeProcedure(excludeProcedure); + } + + public void addConfiguredSchema(Schema schema) { + reverseEngineering.addSchema(schema); + } + + public void addConfiguredCatalog(Catalog catalog) { + reverseEngineering.addCatalog(catalog); + } + + public ReverseEngineering getReverseEngineering() { + return reverseEngineering; + } + + public File getMap() { + return config.getDataMapFile(); + } + + public DbImportConfiguration toParameters() { + return config; } } http://git-wip-us.apache.org/repos/asf/cayenne/blob/16a8cec6/cayenne-tools/src/main/java/org/apache/cayenne/tools/dbimport/DbImportAction.java ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/cayenne/blob/16a8cec6/cayenne-tools/src/main/java/org/apache/cayenne/tools/dbimport/DbImportConfiguration.java ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/cayenne/blob/16a8cec6/cayenne-tools/src/test/java/org/apache/cayenne/tools/NamePatternMatcherTest.java ---------------------------------------------------------------------- diff --cc cayenne-tools/src/test/java/org/apache/cayenne/tools/NamePatternMatcherTest.java index a67e85b,67fe11c..14183dc --- a/cayenne-tools/src/test/java/org/apache/cayenne/tools/NamePatternMatcherTest.java +++ b/cayenne-tools/src/test/java/org/apache/cayenne/tools/NamePatternMatcherTest.java @@@ -19,27 -19,44 +19,29 @@@ package org.apache.cayenne.tools; - import junit.framework.TestCase; - +import org.apache.cayenne.access.loader.NamePatternMatcher; import org.apache.tools.ant.Task; + import org.junit.Test; + + import static org.junit.Assert.assertEquals; +import static org.apache.cayenne.access.loader.NamePatternMatcher.replaceWildcardInStringWithString; + - public class NamePatternMatcherTest extends TestCase { + public class NamePatternMatcherTest { /** * Test pattern expansion. */ + @Test public void testReplaceWildcardInStringWithString() throws Exception { - assertEquals(null, NamePatternMatcher.replaceWildcardInStringWithString( - "*", - null, - "Entity")); - assertEquals("*.java", NamePatternMatcher.replaceWildcardInStringWithString( - null, - "*.java", - "Entity")); - assertEquals("Entity.java", NamePatternMatcher.replaceWildcardInStringWithString( - "*", - "*.java", - "Entity")); - assertEquals("java.Entity", NamePatternMatcher.replaceWildcardInStringWithString( - "*", - "java.*", - "Entity")); - assertEquals("Entity.Entity", NamePatternMatcher - .replaceWildcardInStringWithString("*", "*.*", "Entity")); - assertEquals("EntityEntity", NamePatternMatcher - .replaceWildcardInStringWithString("*", "**", "Entity")); - assertEquals("EditEntityReport.vm", NamePatternMatcher - .replaceWildcardInStringWithString("*", "Edit*Report.vm", "Entity")); - assertEquals("Entity", NamePatternMatcher.replaceWildcardInStringWithString( - "*", - "*", - "Entity")); + assertEquals(null, replaceWildcardInStringWithString("*", null, "Entity")); + assertEquals("*.java", replaceWildcardInStringWithString(null, "*.java", "Entity")); + assertEquals("Entity.java", replaceWildcardInStringWithString("*", "*.java", "Entity")); + assertEquals("java.Entity", replaceWildcardInStringWithString("*", "java.*", "Entity")); + assertEquals("Entity.Entity", replaceWildcardInStringWithString("*", "*.*", "Entity")); + assertEquals("EntityEntity", replaceWildcardInStringWithString("*", "**", "Entity")); + assertEquals("EditEntityReport.vm", replaceWildcardInStringWithString("*", "Edit*Report.vm", "Entity")); + assertEquals("Entity", replaceWildcardInStringWithString("*", "*", "Entity")); } /** http://git-wip-us.apache.org/repos/asf/cayenne/blob/16a8cec6/plugins/maven-cayenne-plugin/pom.xml ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/cayenne/blob/16a8cec6/plugins/maven-cayenne-plugin/src/main/java/org/apache/cayenne/tools/CayenneGeneratorMojo.java ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/cayenne/blob/16a8cec6/plugins/maven-cayenne-plugin/src/main/java/org/apache/cayenne/tools/DbImporterMojo.java ---------------------------------------------------------------------- diff --cc plugins/maven-cayenne-plugin/src/main/java/org/apache/cayenne/tools/DbImporterMojo.java index 1918106,2a11e23..1e07ca1 --- a/plugins/maven-cayenne-plugin/src/main/java/org/apache/cayenne/tools/DbImporterMojo.java +++ b/plugins/maven-cayenne-plugin/src/main/java/org/apache/cayenne/tools/DbImporterMojo.java @@@ -82,8 -71,88 +82,8 @@@ public class DbImporterMojo extends Abs private boolean overwrite; /** - * DB schema to use for DB importing. - * - * @parameter expression="${cdbimport.schemaName}" - * @deprecated since 4.0 renamed to "schema" - */ - private String schemaName; - - /** - * DB schema to use for DB importing. - * - * @parameter expression="${cdbimport.catalog}" - * @since 4.0 - */ - private String catalog; - - /** - * DB schema to use for DB importing. - * - * @parameter expression="${cdbimport.schema}" - * @since 4.0 - */ - private String schema; - - /** - * Pattern for tables to import from DB. - * - * The default is to match against all tables. - * - * @parameter expression="${cdbimport.tablePattern}" - */ - private String tablePattern; - - /** - * A comma-separated list of Perl5 regex that defines tables that should be - * included in import. - * - * @parameter expression="${cdbimport.includeTables}" - */ - private String includeTables; - - /** - * A comma-separated list of Perl5 regex that defines tables that should be - * skipped from import. - * - * @parameter expression="${cdbimport.excludeTables}" - */ - private String excludeTables; - - /** - * Indicates whether stored procedures should be imported. - * - * Default is <code>false</code>. - * - * @parameter expression="${cdbimport.importProcedures}" - * default-value="false" - */ - private boolean importProcedures; - - /** - * Pattern for stored procedures to import from DB. This is only meaningful - * if <code>importProcedures</code> is set to <code>true</code>. - * - * The default is to match against all stored procedures. - * - * @parameter expression="${cdbimport.procedurePattern}" - */ - private String procedurePattern; - - /** - * Indicates whether primary keys should be mapped as meaningful attributes - * in the object entities. - * - * Default is <code>false</code>. - * - * @parameter expression="${cdbimport.meaningfulPk}" default-value="false" - * @deprecated since 4.0 use meaningfulPkTables - */ - private boolean meaningfulPk; - - /** * @parameter expression="${cdbimport.meaningfulPkTables}" - * @since 3.2 + * @since 4.0 */ private String meaningfulPkTables; @@@ -146,92 -215,6 +146,92 @@@ */ private boolean usePrimitives; + private final ReverseEngineering reverseEngineering = new ReverseEngineering(); + + private final EntityFilters.Builder filterBuilder = new EntityFilters.Builder(); + + /** + * DB schema to use for DB importing. + * + * @parameter expression="${cdbimport.schemaName}" - * @deprecated since 3.2 renamed to "schema" ++ * @deprecated since 4.0 renamed to "schema" + */ + private void setSchemaName(String schemaName) { + getLog().warn("'schemaName' property is deprecated. Use 'schema' instead"); + + filterBuilder.schema(schemaName); + } + + /** + * DB schema to use for DB importing. + * + * @parameter expression="${cdbimport.catalog}" - * @since 3.2 ++ * @since 4.0 + */ + private void setCatalog(String catalog) { + filterBuilder.catalog(catalog); + } + + /** + * DB schema to use for DB importing. + * + * @parameter expression="${cdbimport.schema}" - * @since 3.2 ++ * @since 4.0 + */ + private void setSchema(String schema) { + filterBuilder.schema(schema); + } + + /** + * Pattern for tables to import from DB. + * + * The default is to match against all tables. + * + * @parameter expression="${cdbimport.tablePattern}" + */ + private void setTablePattern(String tablePattern) { + filterBuilder.includeTables(tablePattern); + } + + /** + * Indicates whether stored procedures should be imported. + * + * Default is <code>false</code>. + * + * @parameter expression="${cdbimport.importProcedures}" + * default-value="false" + */ + private void setImportProcedures(boolean importProcedures) { + filterBuilder.setProceduresFilters(importProcedures ? FilterFactory.TRUE : FilterFactory.NULL); + } + + /** + * Pattern for stored procedures to import from DB. This is only meaningful + * if <code>importProcedures</code> is set to <code>true</code>. + * + * The default is to match against all stored procedures. + * + * @parameter expression="${cdbimport.procedurePattern}" + */ + private void setProcedurePattern(String procedurePattern) { + filterBuilder.includeProcedures(procedurePattern); + } + + /** + * Indicates whether primary keys should be mapped as meaningful attributes + * in the object entities. + * + * Default is <code>false</code>. + * + * @parameter expression="${cdbimport.meaningfulPk}" default-value="false" - * @deprecated since 3.2 use meaningfulPkTables ++ * @deprecated since 4.0 use meaningfulPkTables + */ + public void setMeaningfulPk(boolean meaningfulPk) { + getLog().warn("'meaningfulPk' property is deprecated. Use 'meaningfulPkTables' pattern instead"); + + this.meaningfulPkTables = meaningfulPk ? "*" : null; + } + public void execute() throws MojoExecutionException, MojoFailureException { Log logger = new MavenLogger(this); http://git-wip-us.apache.org/repos/asf/cayenne/blob/16a8cec6/plugins/pom.xml ----------------------------------------------------------------------