You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@cayenne.apache.org by nt...@apache.org on 2018/01/23 13:18:55 UTC
cayenne git commit: CAY-2395 cdbimport: add option to create project
file
Repository: cayenne
Updated Branches:
refs/heads/master 8c3c49a4d -> c4b110043
CAY-2395 cdbimport: add option to create project file
Project: http://git-wip-us.apache.org/repos/asf/cayenne/repo
Commit: http://git-wip-us.apache.org/repos/asf/cayenne/commit/c4b11004
Tree: http://git-wip-us.apache.org/repos/asf/cayenne/tree/c4b11004
Diff: http://git-wip-us.apache.org/repos/asf/cayenne/diff/c4b11004
Branch: refs/heads/master
Commit: c4b110043e89e3ad74f28d74d272ab3c56e4ba16
Parents: 8c3c49a
Author: Nikita Timofeev <st...@gmail.com>
Authored: Tue Jan 23 16:18:48 2018 +0300
Committer: Nikita Timofeev <st...@gmail.com>
Committed: Tue Jan 23 16:18:48 2018 +0300
----------------------------------------------------------------------
.../apache/cayenne/tools/DbImporterTask.java | 17 ++
.../cayenne/tools/DbImporterTaskTest.java | 5 +
.../apache/cayenne/tools/build-with-project.xml | 36 ++++
.../reverse/configuration/ToolsModule.java | 3 +
.../reverse/dbimport/DbImportConfiguration.java | 9 +
.../reverse/dbimport/DefaultDbImportAction.java | 65 ++++++-
.../dbimport/DefaultDbImportActionTest.java | 171 +++++++++++++++++--
.../org/apache/cayenne/tools/DbImportTask.java | 22 +++
.../org/apache/cayenne/tools/DbImportIT.java | 34 ++++
.../cayenne/tools/dbimport_with_project.gradle | 40 +++++
.../apache/cayenne/tools/test_project_db.sql | 53 ++++++
docs/doc/src/main/resources/RELEASE-NOTES.txt | 1 +
.../apache/cayenne/tools/DbImporterMojo.java | 9 +
.../dialog/db/load/ModelerDbImportAction.java | 6 +-
14 files changed, 453 insertions(+), 18 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/cayenne/blob/c4b11004/cayenne-ant/src/main/java/org/apache/cayenne/tools/DbImporterTask.java
----------------------------------------------------------------------
diff --git a/cayenne-ant/src/main/java/org/apache/cayenne/tools/DbImporterTask.java b/cayenne-ant/src/main/java/org/apache/cayenne/tools/DbImporterTask.java
index 5d22173..0d97213 100644
--- a/cayenne-ant/src/main/java/org/apache/cayenne/tools/DbImporterTask.java
+++ b/cayenne-ant/src/main/java/org/apache/cayenne/tools/DbImporterTask.java
@@ -224,6 +224,9 @@ public class DbImporterTask extends Task {
config.setUsePrimitives(flag);
}
+ /**
+ * @since 4.0
+ */
public void setUseJava7Types(boolean flag) {
config.setUseJava7Types(flag);
}
@@ -248,6 +251,20 @@ public class DbImporterTask extends Task {
config.setTargetDataMap(map);
}
+ /**
+ * @since 4.1
+ */
+ public File getCayenneProject() {
+ return config.getCayenneProject();
+ }
+
+ /**
+ * @since 4.1
+ */
+ public void setCayenneProject(File cayenneProject) {
+ config.setCayenneProject(cayenneProject);
+ }
+
public DbImportConfiguration toParameters() {
return config;
}
http://git-wip-us.apache.org/repos/asf/cayenne/blob/c4b11004/cayenne-ant/src/test/java/org/apache/cayenne/tools/DbImporterTaskTest.java
----------------------------------------------------------------------
diff --git a/cayenne-ant/src/test/java/org/apache/cayenne/tools/DbImporterTaskTest.java b/cayenne-ant/src/test/java/org/apache/cayenne/tools/DbImporterTaskTest.java
index 71ae4e3..43745e7 100644
--- a/cayenne-ant/src/test/java/org/apache/cayenne/tools/DbImporterTaskTest.java
+++ b/cayenne-ant/src/test/java/org/apache/cayenne/tools/DbImporterTaskTest.java
@@ -95,6 +95,11 @@ public class DbImporterTaskTest {
}
@Test
+ public void testBuildWithProject() throws Exception {
+ assertNotNull(getCdbImport("build-with-project.xml").getCayenneProject());
+ }
+
+ @Test
public void testIncludeTable() throws Exception {
test("build-include-table.xml");
}
http://git-wip-us.apache.org/repos/asf/cayenne/blob/c4b11004/cayenne-ant/src/test/resources/org/apache/cayenne/tools/build-with-project.xml
----------------------------------------------------------------------
diff --git a/cayenne-ant/src/test/resources/org/apache/cayenne/tools/build-with-project.xml b/cayenne-ant/src/test/resources/org/apache/cayenne/tools/build-with-project.xml
new file mode 100644
index 0000000..223de6a
--- /dev/null
+++ b/cayenne-ant/src/test/resources/org/apache/cayenne/tools/build-with-project.xml
@@ -0,0 +1,36 @@
+<!--~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ ~ 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.
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~-->
+
+<project name="MyProject" default="dist" basedir=".">
+
+ <taskdef name="cdbimport" classname="org.apache.cayenne.tools.DbImporterTask" taskname="cdbimport"
+ classpath="${basedir}"/>
+
+ <target name="dist">
+ <cdbimport map="${context.dir}/WEB-INF/DefaultMap.map.xml"
+ cayenneProject="${context.dir}/WEB-INF/cayenne-project.xml"
+ adapter="org.apache.cayenne.dba.hsqldb.HSQLDBAdapter"
+ driver="org.hsqldb.jdbcDriver"
+ url="jdbc:hsqldb:hsql://localhost/bookmarker"
+ username="sa">
+ </cdbimport>
+ </target>
+
+
+</project>
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/cayenne/blob/c4b11004/cayenne-dbsync/src/main/java/org/apache/cayenne/dbsync/reverse/configuration/ToolsModule.java
----------------------------------------------------------------------
diff --git a/cayenne-dbsync/src/main/java/org/apache/cayenne/dbsync/reverse/configuration/ToolsModule.java b/cayenne-dbsync/src/main/java/org/apache/cayenne/dbsync/reverse/configuration/ToolsModule.java
index 8e3673d..1ab51f0 100644
--- a/cayenne-dbsync/src/main/java/org/apache/cayenne/dbsync/reverse/configuration/ToolsModule.java
+++ b/cayenne-dbsync/src/main/java/org/apache/cayenne/dbsync/reverse/configuration/ToolsModule.java
@@ -24,6 +24,7 @@ import org.apache.cayenne.access.translator.batch.DefaultBatchTranslatorFactory;
import org.apache.cayenne.access.types.DefaultValueObjectTypeRegistry;
import org.apache.cayenne.access.types.ValueObjectTypeRegistry;
import org.apache.cayenne.configuration.Constants;
+import org.apache.cayenne.configuration.DataChannelDescriptorLoader;
import org.apache.cayenne.configuration.DataMapLoader;
import org.apache.cayenne.configuration.DefaultRuntimeProperties;
import org.apache.cayenne.configuration.RuntimeProperties;
@@ -34,6 +35,7 @@ import org.apache.cayenne.configuration.server.ServerModule;
import org.apache.cayenne.configuration.xml.DataChannelMetaData;
import org.apache.cayenne.configuration.xml.DefaultDataChannelMetaData;
import org.apache.cayenne.configuration.xml.HandlerFactory;
+import org.apache.cayenne.configuration.xml.XMLDataChannelDescriptorLoader;
import org.apache.cayenne.configuration.xml.XMLDataMapLoader;
import org.apache.cayenne.configuration.xml.XMLReaderProvider;
import org.apache.cayenne.dba.db2.DB2Sniffer;
@@ -117,6 +119,7 @@ public class ToolsModule implements Module {
binder.bind(DataSourceFactory.class).to(DriverDataSourceFactory.class);
binder.bind(DataMapLoader.class).to(XMLDataMapLoader.class);
+ binder.bind(DataChannelDescriptorLoader.class).to(XMLDataChannelDescriptorLoader.class);
binder.bind(HandlerFactory.class).to(ExtensionAwareHandlerFactory.class);
binder.bind(DataChannelMetaData.class).to(DefaultDataChannelMetaData.class);
binder.bind(XMLReader.class).toProviderInstance(new XMLReaderProvider(true)).withoutScope();
http://git-wip-us.apache.org/repos/asf/cayenne/blob/c4b11004/cayenne-dbsync/src/main/java/org/apache/cayenne/dbsync/reverse/dbimport/DbImportConfiguration.java
----------------------------------------------------------------------
diff --git a/cayenne-dbsync/src/main/java/org/apache/cayenne/dbsync/reverse/dbimport/DbImportConfiguration.java b/cayenne-dbsync/src/main/java/org/apache/cayenne/dbsync/reverse/dbimport/DbImportConfiguration.java
index 110a7ff..06b04f0 100644
--- a/cayenne-dbsync/src/main/java/org/apache/cayenne/dbsync/reverse/dbimport/DbImportConfiguration.java
+++ b/cayenne-dbsync/src/main/java/org/apache/cayenne/dbsync/reverse/dbimport/DbImportConfiguration.java
@@ -61,6 +61,7 @@ public class DbImportConfiguration {
private String stripFromTableNames;
private boolean forceDataMapCatalog;
private boolean forceDataMapSchema;
+ private File cayenneProject;
public DbImportConfiguration() {
this.dataSourceInfo = new DataSourceInfo();
@@ -154,6 +155,14 @@ public class DbImportConfiguration {
this.useJava7Types = useJava7Types;
}
+ public File getCayenneProject() {
+ return cayenneProject;
+ }
+
+ public void setCayenneProject(File cayenneProject) {
+ this.cayenneProject = cayenneProject;
+ }
+
public NameFilter createMeaningfulPKFilter() {
if (meaningfulPkTables == null) {
http://git-wip-us.apache.org/repos/asf/cayenne/blob/c4b11004/cayenne-dbsync/src/main/java/org/apache/cayenne/dbsync/reverse/dbimport/DefaultDbImportAction.java
----------------------------------------------------------------------
diff --git a/cayenne-dbsync/src/main/java/org/apache/cayenne/dbsync/reverse/dbimport/DefaultDbImportAction.java b/cayenne-dbsync/src/main/java/org/apache/cayenne/dbsync/reverse/dbimport/DefaultDbImportAction.java
index c31aaab..1e08844 100644
--- a/cayenne-dbsync/src/main/java/org/apache/cayenne/dbsync/reverse/dbimport/DefaultDbImportAction.java
+++ b/cayenne-dbsync/src/main/java/org/apache/cayenne/dbsync/reverse/dbimport/DefaultDbImportAction.java
@@ -18,7 +18,11 @@
****************************************************************/
package org.apache.cayenne.dbsync.reverse.dbimport;
+import org.apache.cayenne.CayenneRuntimeException;
+import org.apache.cayenne.configuration.ConfigurationNode;
import org.apache.cayenne.configuration.ConfigurationTree;
+import org.apache.cayenne.configuration.DataChannelDescriptor;
+import org.apache.cayenne.configuration.DataChannelDescriptorLoader;
import org.apache.cayenne.configuration.DataMapLoader;
import org.apache.cayenne.configuration.DataNodeDescriptor;
import org.apache.cayenne.configuration.server.DataSourceFactory;
@@ -55,8 +59,8 @@ import org.slf4j.Logger;
import javax.sql.DataSource;
import java.io.File;
-import java.io.FileNotFoundException;
import java.io.IOException;
+import java.net.MalformedURLException;
import java.sql.Connection;
import java.util.Collection;
import java.util.Collections;
@@ -77,19 +81,22 @@ public class DefaultDbImportAction implements DbImportAction {
private final DbAdapterFactory adapterFactory;
private final DataMapLoader mapLoader;
private final MergerTokenFactoryProvider mergerTokenFactoryProvider;
+ private final DataChannelDescriptorLoader dataChannelDescriptorLoader;
public DefaultDbImportAction(@Inject Logger logger,
@Inject ProjectSaver projectSaver,
@Inject DataSourceFactory dataSourceFactory,
@Inject DbAdapterFactory adapterFactory,
@Inject DataMapLoader mapLoader,
- @Inject MergerTokenFactoryProvider mergerTokenFactoryProvider) {
+ @Inject MergerTokenFactoryProvider mergerTokenFactoryProvider,
+ @Inject DataChannelDescriptorLoader dataChannelDescriptorLoader) {
this.logger = logger;
this.projectSaver = projectSaver;
this.dataSourceFactory = dataSourceFactory;
this.adapterFactory = adapterFactory;
this.mapLoader = mapLoader;
this.mergerTokenFactoryProvider = mergerTokenFactoryProvider;
+ this.dataChannelDescriptorLoader = dataChannelDescriptorLoader;
}
protected static List<MergerToken> sort(List<MergerToken> reverse) {
@@ -172,7 +179,7 @@ public class DefaultDbImportAction implements DbImportAction {
hasChanges |= syncProcedures(targetDataMap, sourceDataMap, loaderConfig.getFiltersConfig());
if (hasChanges) {
- saveLoaded(targetDataMap);
+ saveLoaded(targetDataMap, config);
}
}
@@ -383,10 +390,58 @@ public class DefaultDbImportAction implements DbImportAction {
return hasChanges;
}
- protected void saveLoaded(DataMap dataMap) throws FileNotFoundException {
- ConfigurationTree<DataMap> projectRoot = new ConfigurationTree<>(dataMap);
+ /**
+ * Save imported data.
+ * This can create DataMap and/or Project files.
+ */
+ protected void saveLoaded(DataMap dataMap, DbImportConfiguration config) throws MalformedURLException {
+ ConfigurationTree<ConfigurationNode> projectRoot;
+ if(config.getCayenneProject() == null) {
+ // Old version of cdbimport, no Cayenne project, need to save only DataMap
+ projectRoot = new ConfigurationTree<>(dataMap);
+ } else {
+ // Cayenne project is present
+ DataChannelDescriptor dataChannelDescriptor;
+ if(config.getCayenneProject().exists()) {
+ // Cayenne project file exists, need to read it and push DataMap inside
+ URLResource configurationResource = new URLResource(config.getCayenneProject().toURI().toURL());
+ ConfigurationTree<DataChannelDescriptor> configurationTree = dataChannelDescriptorLoader.load(configurationResource);
+ if(!configurationTree.getLoadFailures().isEmpty()) {
+ throw new CayenneRuntimeException("Unable to load cayenne project %s, %s", config.getCayenneProject(),
+ configurationTree.getLoadFailures().iterator().next().getDescription());
+ }
+ dataChannelDescriptor = configurationTree.getRootNode();
+ // remove old copy of DataMap if it's there
+ DataMap oldDataMap = dataChannelDescriptor.getDataMap(dataMap.getName());
+ if(oldDataMap != null) {
+ dataChannelDescriptor.getDataMaps().remove(oldDataMap);
+ }
+ } else {
+ // No project file yet, can simply create empty project with resulting DataMap
+ dataChannelDescriptor = new DataChannelDescriptor();
+ dataChannelDescriptor.setName(getProjectNameFromFileName(config.getCayenneProject().getName()));
+ dataChannelDescriptor.setConfigurationSource(new URLResource(config.getCayenneProject().toURI().toURL()));
+ logger.info("Project file does not exist. New project will be saved into '" + config.getCayenneProject().getAbsolutePath());
+ }
+
+ dataChannelDescriptor.getDataMaps().add(dataMap);
+ projectRoot = new ConfigurationTree<>(dataChannelDescriptor);
+ }
+
Project project = new Project(projectRoot);
projectSaver.save(project);
+
+ logger.info("");
+ logger.info("All changes saved.");
+ }
+
+ protected String getProjectNameFromFileName(String fileName) {
+ int xmlExtPosition = fileName.lastIndexOf(".xml");
+ String name = fileName.substring(0, xmlExtPosition == -1 ? fileName.length() : xmlExtPosition);
+ if(fileName.startsWith("cayenne-")) {
+ name = name.substring("cayenne-".length());
+ }
+ return name;
}
protected DataMap load(DbImportConfiguration config, DbAdapter adapter, Connection connection) throws Exception {
http://git-wip-us.apache.org/repos/asf/cayenne/blob/c4b11004/cayenne-dbsync/src/test/java/org/apache/cayenne/dbsync/reverse/dbimport/DefaultDbImportActionTest.java
----------------------------------------------------------------------
diff --git a/cayenne-dbsync/src/test/java/org/apache/cayenne/dbsync/reverse/dbimport/DefaultDbImportActionTest.java b/cayenne-dbsync/src/test/java/org/apache/cayenne/dbsync/reverse/dbimport/DefaultDbImportActionTest.java
index df8f8b1..364f770 100644
--- a/cayenne-dbsync/src/test/java/org/apache/cayenne/dbsync/reverse/dbimport/DefaultDbImportActionTest.java
+++ b/cayenne-dbsync/src/test/java/org/apache/cayenne/dbsync/reverse/dbimport/DefaultDbImportActionTest.java
@@ -19,11 +19,11 @@
package org.apache.cayenne.dbsync.reverse.dbimport;
import org.apache.cayenne.CayenneRuntimeException;
+import org.apache.cayenne.configuration.DataChannelDescriptorLoader;
import org.apache.cayenne.configuration.DataMapLoader;
import org.apache.cayenne.configuration.DataNodeDescriptor;
import org.apache.cayenne.configuration.server.DataSourceFactory;
import org.apache.cayenne.configuration.server.DbAdapterFactory;
-import org.apache.cayenne.configuration.xml.DataChannelMetaData;
import org.apache.cayenne.dba.DbAdapter;
import org.apache.cayenne.dbsync.DbSyncModule;
import org.apache.cayenne.dbsync.filter.NamePatternMatcher;
@@ -60,6 +60,8 @@ import org.junit.Test;
import javax.sql.DataSource;
import java.io.File;
import java.net.URL;
+import java.nio.charset.Charset;
+import java.nio.file.Files;
import java.sql.Connection;
import java.sql.SQLException;
import java.util.Collections;
@@ -132,7 +134,7 @@ public class DefaultDbImportActionTest {
};
final boolean[] haveWeTriedToSave = {false};
- DefaultDbImportAction action = buildDbImportAction(new FileProjectSaver(Collections.<ProjectExtension>emptyList()) {
+ DefaultDbImportAction action = buildDbImportAction(new FileProjectSaver(Collections.emptyList()) {
@Override
public void save(Project project) {
haveWeTriedToSave[0] = true;
@@ -299,7 +301,9 @@ public class DefaultDbImportActionTest {
MergerTokenFactoryProvider mergerTokenFactoryProvider = mock(MergerTokenFactoryProvider.class);
when(mergerTokenFactoryProvider.get((DbAdapter)any())).thenReturn(new DefaultMergerTokenFactory());
- return new DefaultDbImportAction(log, projectSaver, dataSourceFactory, adapterFactory, mapLoader, mergerTokenFactoryProvider) {
+ DataChannelDescriptorLoader dataChannelDescriptorLoader = mock(DataChannelDescriptorLoader.class);
+
+ return new DefaultDbImportAction(log, projectSaver, dataSourceFactory, adapterFactory, mapLoader, mergerTokenFactoryProvider, dataChannelDescriptorLoader) {
protected DbLoader createDbLoader(DbAdapter adapter,
Connection connection,
@@ -309,26 +313,32 @@ public class DefaultDbImportActionTest {
};
}
+ private URL getPackageURL() {
+ String packagePath = getClass().getPackage().getName().replace('.', '/');
+ URL packageUrl = getClass().getClassLoader().getResource(packagePath);
+ assertNotNull(packageUrl);
+ return packageUrl;
+ }
+
@Test
- public void testSaveLoaded() throws Exception {
+ public void testSaveLoadedNoProject() throws Exception {
Logger log = mock(Logger.class);
Injector i = DIBootstrap.createInjector(new DbSyncModule(), new ToolsModule(log), new DbImportModule());
+ DbImportConfiguration params = mock(DbImportConfiguration.class);
+ when(params.getCayenneProject()).thenReturn(null);
- DefaultDbImportAction action = (DefaultDbImportAction) i.getInstance(DbImportAction.class);
+ URL outUrl = new URL(getPackageURL(), "dbimport/testSaveLoaded1.map.xml");
- String packagePath = getClass().getPackage().getName().replace('.', '/');
- URL packageUrl = getClass().getClassLoader().getResource(packagePath);
- assertNotNull(packageUrl);
- URL outUrl = new URL(packageUrl, "dbimport/testSaveLoaded1.map.xml");
+ DefaultDbImportAction action = (DefaultDbImportAction) i.getInstance(DbImportAction.class);
File out = new File(outUrl.toURI());
out.delete();
- assertFalse(out.isFile());
+ assertFalse(out.exists());
DataMap map = new DataMap("testSaveLoaded1");
map.setConfigurationSource(new URLResource(outUrl));
- action.saveLoaded(map);
+ action.saveLoaded(map, params);
assertTrue(out.isFile());
@@ -337,6 +347,145 @@ public class DefaultDbImportActionTest {
}
@Test
+ public void testSaveLoadedWithEmptyProject() throws Exception {
+ Logger log = mock(Logger.class);
+ Injector i = DIBootstrap.createInjector(new DbSyncModule(), new ToolsModule(log), new DbImportModule());
+ DbImportConfiguration params = mock(DbImportConfiguration.class);
+
+ URL projectURL = new URL(getPackageURL(), "dbimport/cayenne-testProject2.map.xml");
+ File projectFile = new File(projectURL.toURI());
+ projectFile.delete();
+ assertFalse(projectFile.exists());
+ when(params.getCayenneProject()).thenReturn(projectFile);
+
+ DefaultDbImportAction action = (DefaultDbImportAction) i.getInstance(DbImportAction.class);
+
+ URL dataMapURL = new URL(getPackageURL(), "dbimport/testSaveLoaded2.map.xml");
+
+ File dataMapFile = new File(dataMapURL.toURI());
+ dataMapFile.delete();
+ assertFalse(dataMapFile.exists());
+
+ DataMap map = new DataMap("testSaveLoaded2");
+ map.setConfigurationSource(new URLResource(dataMapURL));
+
+ action.saveLoaded(map, params);
+
+ assertTrue(dataMapFile.isFile());
+ assertTrue(projectFile.isFile());
+
+ String dataMapContents = Util.stringFromFile(dataMapFile);
+ assertTrue("Has no project version saved", dataMapContents.contains("project-version=\""));
+
+ String projectContents = Util.stringFromFile(projectFile);
+ assertTrue("Has no project version saved", projectContents.contains("project-version=\""));
+ assertTrue("Has no datamap in project", projectContents.contains("<map name=\"testSaveLoaded2\"/>"));
+ }
+
+ @Test
+ public void testSaveLoadedWithNonEmptyProject() throws Exception {
+ Logger log = mock(Logger.class);
+ Injector i = DIBootstrap.createInjector(new DbSyncModule(), new ToolsModule(log), new DbImportModule());
+ DbImportConfiguration params = mock(DbImportConfiguration.class);
+
+ URL projectURL = new URL(getPackageURL(), "dbimport/cayenne-testProject3.map.xml");
+ File projectFile = new File(projectURL.toURI());
+ projectFile.delete();
+ assertFalse(projectFile.exists());
+
+ Files.write(projectFile.toPath(), ("<?xml version=\"1.0\" encoding=\"utf-8\"?>\n" +
+ "<domain xmlns=\"http://cayenne.apache.org/schema/10/domain\"\n" +
+ "\t xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"\n" +
+ "\t xsi:schemaLocation=\"http://cayenne.apache.org/schema/10/domain http://cayenne.apache.org/schema/10/domain.xsd\"\n" +
+ "\t project-version=\"10\">\n" +
+ "</domain>").getBytes(Charset.forName("UTF-8")));
+ assertTrue(projectFile.isFile());
+
+ when(params.getCayenneProject()).thenReturn(projectFile);
+
+ DefaultDbImportAction action = (DefaultDbImportAction) i.getInstance(DbImportAction.class);
+
+ URL dataMapURL = new URL(getPackageURL(), "dbimport/testSaveLoaded3.map.xml");
+
+ File dataMapFile = new File(dataMapURL.toURI());
+ dataMapFile.delete();
+ assertFalse(dataMapFile.exists());
+
+ DataMap map = new DataMap("testSaveLoaded3");
+ map.setConfigurationSource(new URLResource(dataMapURL));
+
+ action.saveLoaded(map, params);
+
+ assertTrue(dataMapFile.isFile());
+ assertTrue(projectFile.isFile());
+
+ String dataMapContents = Util.stringFromFile(dataMapFile);
+ assertTrue("Has no project version saved", dataMapContents.contains("project-version=\""));
+
+ String projectContents = Util.stringFromFile(projectFile);
+ assertTrue("Has no project version saved", projectContents.contains("project-version=\""));
+ assertTrue("Has no datamap in project", projectContents.contains("<map name=\"testSaveLoaded3\"/>"));
+ }
+
+ @Test
+ public void testSaveLoadedWithNonEmptyProjectAndNonEmptyDataMap() throws Exception {
+ Logger log = mock(Logger.class);
+ Injector i = DIBootstrap.createInjector(new DbSyncModule(), new ToolsModule(log), new DbImportModule());
+ DbImportConfiguration params = mock(DbImportConfiguration.class);
+
+ URL projectURL = new URL(getPackageURL(), "dbimport/cayenne-testProject4.map.xml");
+ File projectFile = new File(projectURL.toURI());
+ projectFile.delete();
+ assertFalse(projectFile.exists());
+
+ Files.write(projectFile.toPath(), ("<?xml version=\"1.0\" encoding=\"utf-8\"?>\n" +
+ "<domain xmlns=\"http://cayenne.apache.org/schema/10/domain\"\n" +
+ "\t xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"\n" +
+ "\t xsi:schemaLocation=\"http://cayenne.apache.org/schema/10/domain http://cayenne.apache.org/schema/10/domain.xsd\"\n" +
+ "\t project-version=\"10\">\n" +
+ "\t<map name=\"testSaveLoaded4\"/>\n" +
+ "</domain>").getBytes(Charset.forName("UTF-8")));
+ assertTrue(projectFile.isFile());
+
+ when(params.getCayenneProject()).thenReturn(projectFile);
+
+ DefaultDbImportAction action = (DefaultDbImportAction) i.getInstance(DbImportAction.class);
+
+ URL dataMapURL = new URL(getPackageURL(), "dbimport/testSaveLoaded4.map.xml");
+
+ File dataMapFile = new File(dataMapURL.toURI());
+ dataMapFile.delete();
+ assertFalse(dataMapFile.exists());
+
+ Files.write(dataMapFile.toPath(), ("<?xml version=\"1.0\" encoding=\"utf-8\"?>\n" +
+ "<data-map xmlns=\"http://cayenne.apache.org/schema/10/modelMap\"\n" +
+ "\t xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"\n" +
+ "\t xsi:schemaLocation=\"http://cayenne.apache.org/schema/10/modelMap http://cayenne.apache.org/schema/10/modelMap.xsd\"\n" +
+ "\t project-version=\"10\">\n" +
+ "\t<db-entity name=\"test\">\n" +
+ "\t\t<db-attribute name=\"test\" type=\"INT\"/>\n" +
+ "\t</db-entity>\n" +
+ "</data-map>").getBytes(Charset.forName("UTF-8")));
+ assertTrue(dataMapFile.isFile());
+
+ DataMap map = new DataMap("testSaveLoaded4");
+ map.setConfigurationSource(new URLResource(dataMapURL));
+
+ action.saveLoaded(map, params);
+
+ assertTrue(dataMapFile.isFile());
+ assertTrue(projectFile.isFile());
+
+ String dataMapContents = Util.stringFromFile(dataMapFile);
+ assertTrue("Has no project version saved", dataMapContents.contains("project-version=\""));
+ assertFalse(dataMapContents.contains("<db-entity"));
+
+ String projectContents = Util.stringFromFile(projectFile);
+ assertTrue("Has no project version saved", projectContents.contains("project-version=\""));
+ assertEquals("Has no or too many datamaps in project", 1, Util.countMatches(projectContents, "<map name=\"testSaveLoaded4\"/>"));
+ }
+
+ @Test
public void testMergeTokensSorting() {
LinkedList<MergerToken> tokens = new LinkedList<MergerToken>();
tokens.add(new AddColumnToModel(null, null));
http://git-wip-us.apache.org/repos/asf/cayenne/blob/c4b11004/cayenne-gradle-plugin/src/main/java/org/apache/cayenne/tools/DbImportTask.java
----------------------------------------------------------------------
diff --git a/cayenne-gradle-plugin/src/main/java/org/apache/cayenne/tools/DbImportTask.java b/cayenne-gradle-plugin/src/main/java/org/apache/cayenne/tools/DbImportTask.java
index c640439..e5a9bd1 100644
--- a/cayenne-gradle-plugin/src/main/java/org/apache/cayenne/tools/DbImportTask.java
+++ b/cayenne-gradle-plugin/src/main/java/org/apache/cayenne/tools/DbImportTask.java
@@ -62,6 +62,9 @@ public class DbImportTask extends BaseCayenneTask {
@Internal
private ReverseEngineering reverseEngineering;
+ @Internal
+ private File cayenneProject;
+
public DbImportTask() {
// this task should be executed every invocation, so it is never up to date.
getOutputs().upToDateWhen(new Spec<Task>() {
@@ -127,6 +130,7 @@ public class DbImportTask extends BaseCayenneTask {
config.setUsername(dataSource.getUsername());
config.setUsePrimitives(reverseEngineering.isUsePrimitives());
config.setUseJava7Types(reverseEngineering.isUseJava7Types());
+ config.setCayenneProject(cayenneProject);
return config;
}
@@ -167,4 +171,22 @@ public class DbImportTask extends BaseCayenneTask {
public void adapter(String adapter) {
setAdapter(adapter);
}
+
+ @OutputFile
+ @Optional
+ public File getCayenneProject() {
+ return cayenneProject;
+ }
+
+ public void setCayenneProject(File cayenneProject) {
+ this.cayenneProject = cayenneProject;
+ }
+
+ public void cayenneProject(File cayenneProject) {
+ this.cayenneProject = cayenneProject;
+ }
+
+ public void cayenneProject(String cayenneProjectFileName) {
+ this.cayenneProject = getProject().file(cayenneProjectFileName);
+ }
}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/cayenne/blob/c4b11004/cayenne-gradle-plugin/src/test/java/org/apache/cayenne/tools/DbImportIT.java
----------------------------------------------------------------------
diff --git a/cayenne-gradle-plugin/src/test/java/org/apache/cayenne/tools/DbImportIT.java b/cayenne-gradle-plugin/src/test/java/org/apache/cayenne/tools/DbImportIT.java
index 00ecbe5..1fa16a7 100644
--- a/cayenne-gradle-plugin/src/test/java/org/apache/cayenne/tools/DbImportIT.java
+++ b/cayenne-gradle-plugin/src/test/java/org/apache/cayenne/tools/DbImportIT.java
@@ -114,9 +114,43 @@ public class DbImportIT extends BaseTaskIT {
assertTrue(result.getOutput().contains("Table: SCHEMA_01.TEST2"));
}
+ @Test
+ public void withProjectTaskSuccess() throws Exception {
+ String dbUrl = prepareDerbyDatabase("test_project_db");
+ File dataMap = new File(projectDir.getAbsolutePath() + "/datamap.map.xml");
+ assertFalse(dataMap.exists());
+ File project = new File(projectDir.getAbsolutePath() + "/cayenne-project.xml");
+ assertFalse(project.exists());
+
+ GradleRunner runner = createRunner("dbimport_with_project", "cdbimport", "--info", "-PdbUrl=" + dbUrl);
+
+ BuildResult result = runner.build();
+
+ assertNotNull(result.task(":cdbimport"));
+ assertEquals(TaskOutcome.SUCCESS, result.task(":cdbimport").getOutcome());
+
+ assertTrue(dataMap.isFile());
+ assertTrue(project.isFile());
+
+ // Check few lines from reverse engineering output
+ assertTrue(result.getOutput().contains("Table: APP.PAINTING"));
+ assertTrue(result.getOutput().contains("Db Relationship : toOne (EXHIBIT.GALLERY_ID, GALLERY.GALLERY_ID)"));
+ assertTrue(result.getOutput().contains("Db Relationship : toMany (GALLERY.GALLERY_ID, PAINTING.GALLERY_ID)"));
+ assertTrue(result.getOutput().contains("Create Table ARTIST"));
+ assertFalse(result.getOutput().contains("Create Table PAINTING1"));
+ assertTrue(result.getOutput().contains("Skip relation: '.APP.ARTIST.ARTIST_ID <- .APP.PAINTING1.ARTIST_ID # 1'"));
+ assertTrue(result.getOutput().contains("Migration Complete Successfully."));
+ }
+
private String prepareDerbyDatabase(String sqlFile) throws Exception {
URL sqlUrl = Objects.requireNonNull(ResourceUtil.getResource(getClass(), sqlFile + ".sql"));
String dbUrl = "jdbc:derby:" + projectDir.getAbsolutePath() + "/build/" + sqlFile;
+
+ // Try to open connection, it may fail at first time, so ignore it
+ try (Connection unused = DriverManager.getConnection(dbUrl + ";create=true")) {
+ } catch (SQLException ignore) {
+ }
+
try (Connection connection = DriverManager.getConnection(dbUrl + ";create=true")) {
try (Statement stmt = connection.createStatement()) {
for (String sql : SQLReader.statements(sqlUrl, ";")) {
http://git-wip-us.apache.org/repos/asf/cayenne/blob/c4b11004/cayenne-gradle-plugin/src/test/resources/org/apache/cayenne/tools/dbimport_with_project.gradle
----------------------------------------------------------------------
diff --git a/cayenne-gradle-plugin/src/test/resources/org/apache/cayenne/tools/dbimport_with_project.gradle b/cayenne-gradle-plugin/src/test/resources/org/apache/cayenne/tools/dbimport_with_project.gradle
new file mode 100644
index 0000000..d99dd49
--- /dev/null
+++ b/cayenne-gradle-plugin/src/test/resources/org/apache/cayenne/tools/dbimport_with_project.gradle
@@ -0,0 +1,40 @@
+/*****************************************************************
+ * 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.
+ ****************************************************************/
+
+plugins {
+ id 'org.apache.cayenne'
+}
+
+cdbimport {
+ map 'datamap.map.xml'
+ cayenneProject 'cayenne-project.xml'
+
+ adapter 'org.apache.cayenne.dba.derby.DerbyAdapter'
+
+ dataSource {
+ username 'sa'
+ password ''
+ url dbUrl
+ driver 'org.apache.derby.jdbc.EmbeddedDriver'
+ }
+
+ dbImport {
+ excludeTable 'PAINTING1'
+ }
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/cayenne/blob/c4b11004/cayenne-gradle-plugin/src/test/resources/org/apache/cayenne/tools/test_project_db.sql
----------------------------------------------------------------------
diff --git a/cayenne-gradle-plugin/src/test/resources/org/apache/cayenne/tools/test_project_db.sql b/cayenne-gradle-plugin/src/test/resources/org/apache/cayenne/tools/test_project_db.sql
new file mode 100644
index 0000000..82c8d79
--- /dev/null
+++ b/cayenne-gradle-plugin/src/test/resources/org/apache/cayenne/tools/test_project_db.sql
@@ -0,0 +1,53 @@
+-- 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.
+
+-- Test Schema for dbimport task test
+
+CREATE TABLE ARTIST (ARTIST_ID BIGINT NOT NULL, ARTIST_NAME CHAR (254) NOT NULL, DATE_OF_BIRTH DATE , PRIMARY KEY (ARTIST_ID));
+CREATE TABLE NULL_TEST (ID INTEGER NOT NULL GENERATED BY DEFAULT AS IDENTITY, NAME VARCHAR (100), PRIMARY KEY (ID));
+CREATE TABLE ARTIST_CT (ARTIST_ID INTEGER NOT NULL, ARTIST_NAME CHAR (254) NOT NULL, DATE_OF_BIRTH DATE , PRIMARY KEY (ARTIST_ID));
+CREATE TABLE GENERATED_COLUMN (GENERATED_COLUMN INTEGER NOT NULL GENERATED BY DEFAULT AS IDENTITY, NAME VARCHAR (250), PRIMARY KEY (GENERATED_COLUMN));
+CREATE TABLE GALLERY (GALLERY_ID INTEGER NOT NULL, GALLERY_NAME VARCHAR (100) NOT NULL, PRIMARY KEY (GALLERY_ID));
+CREATE TABLE PAINTING1 (ARTIST_ID BIGINT , ESTIMATED_PRICE DECIMAL (10, 2), GALLERY_ID INTEGER , PAINTING_ID INTEGER NOT NULL, PAINTING_TITLE VARCHAR (255) NOT NULL, PRIMARY KEY (PAINTING_ID));
+CREATE TABLE ARTGROUP (GROUP_ID INTEGER NOT NULL, NAME VARCHAR (100) NOT NULL, PARENT_GROUP_ID INTEGER , PRIMARY KEY (GROUP_ID));
+CREATE TABLE EXHIBIT (CLOSING_DATE TIMESTAMP NOT NULL, EXHIBIT_ID INTEGER NOT NULL, GALLERY_ID INTEGER NOT NULL, OPENING_DATE TIMESTAMP NOT NULL, PRIMARY KEY (EXHIBIT_ID));
+CREATE TABLE ARTIST_GROUP (ARTIST_ID BIGINT NOT NULL, GROUP_ID INTEGER NOT NULL, PRIMARY KEY (ARTIST_ID, GROUP_ID));
+CREATE TABLE PAINTING (ARTIST_ID BIGINT , ESTIMATED_PRICE DECIMAL (10, 2), GALLERY_ID INTEGER , PAINTING_DESCRIPTION VARCHAR (255), PAINTING_ID INTEGER NOT NULL, PAINTING_TITLE VARCHAR (255) NOT NULL, PRIMARY KEY (PAINTING_ID));
+CREATE TABLE ARTIST_EXHIBIT (ARTIST_ID BIGINT NOT NULL, EXHIBIT_ID INTEGER NOT NULL, PRIMARY KEY (ARTIST_ID, EXHIBIT_ID));
+CREATE TABLE PAINTING_INFO (IMAGE_BLOB LONG VARCHAR FOR BIT DATA , PAINTING_ID INTEGER NOT NULL, TEXT_REVIEW LONG VARCHAR , PRIMARY KEY (PAINTING_ID));
+
+ALTER TABLE PAINTING1 ADD FOREIGN KEY (ARTIST_ID) REFERENCES ARTIST (ARTIST_ID);
+ALTER TABLE ARTGROUP ADD FOREIGN KEY (PARENT_GROUP_ID) REFERENCES ARTGROUP (GROUP_ID);
+ALTER TABLE EXHIBIT ADD FOREIGN KEY (GALLERY_ID) REFERENCES GALLERY (GALLERY_ID);
+ALTER TABLE ARTIST_GROUP ADD FOREIGN KEY (ARTIST_ID) REFERENCES ARTIST (ARTIST_ID);
+ALTER TABLE ARTIST_GROUP ADD FOREIGN KEY (GROUP_ID) REFERENCES ARTGROUP (GROUP_ID);
+ALTER TABLE PAINTING ADD FOREIGN KEY (ARTIST_ID) REFERENCES ARTIST (ARTIST_ID);
+ALTER TABLE PAINTING ADD FOREIGN KEY (GALLERY_ID) REFERENCES GALLERY (GALLERY_ID);
+ALTER TABLE ARTIST_EXHIBIT ADD FOREIGN KEY (ARTIST_ID) REFERENCES ARTIST (ARTIST_ID);
+ALTER TABLE ARTIST_EXHIBIT ADD FOREIGN KEY (EXHIBIT_ID) REFERENCES EXHIBIT (EXHIBIT_ID);
+ALTER TABLE PAINTING_INFO ADD FOREIGN KEY (PAINTING_ID) REFERENCES PAINTING (PAINTING_ID);
+
+CREATE SEQUENCE PK_ARTGROUP AS BIGINT START WITH 200 INCREMENT BY 20 NO MAXVALUE NO CYCLE;
+CREATE SEQUENCE PK_ARTIST AS BIGINT START WITH 200 INCREMENT BY 20 NO MAXVALUE NO CYCLE;
+CREATE SEQUENCE PK_ARTIST_CT AS BIGINT START WITH 200 INCREMENT BY 20 NO MAXVALUE NO CYCLE;
+CREATE SEQUENCE PK_ARTIST_GROUP AS BIGINT START WITH 200 INCREMENT BY 20 NO MAXVALUE NO CYCLE;
+CREATE SEQUENCE PK_EXHIBIT AS BIGINT START WITH 200 INCREMENT BY 20 NO MAXVALUE NO CYCLE;
+CREATE SEQUENCE PK_GALLERY AS BIGINT START WITH 200 INCREMENT BY 20 NO MAXVALUE NO CYCLE;
+CREATE SEQUENCE PK_GENERATED_COLUMN AS BIGINT START WITH 200 INCREMENT BY 20 NO MAXVALUE NO CYCLE;
+CREATE SEQUENCE PK_NULL_TEST AS BIGINT START WITH 200 INCREMENT BY 20 NO MAXVALUE NO CYCLE;
+CREATE SEQUENCE PK_PAINTING AS BIGINT START WITH 200 INCREMENT BY 20 NO MAXVALUE NO CYCLE;
+CREATE SEQUENCE PK_PAINTING1 AS BIGINT START WITH 200 INCREMENT BY 20 NO MAXVALUE NO CYCLE;
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/cayenne/blob/c4b11004/docs/doc/src/main/resources/RELEASE-NOTES.txt
----------------------------------------------------------------------
diff --git a/docs/doc/src/main/resources/RELEASE-NOTES.txt b/docs/doc/src/main/resources/RELEASE-NOTES.txt
index 5fba36f..5b61a78 100644
--- a/docs/doc/src/main/resources/RELEASE-NOTES.txt
+++ b/docs/doc/src/main/resources/RELEASE-NOTES.txt
@@ -18,6 +18,7 @@ CAY-2377 Cleanup deprecated code.
CAY-2391 cdbimport: add option to skip user-defined relationships
CAY-2393 Add sqlserver-docker profile to automate tests on SQLServer
CAY-2394 Upgrade to Apache Velocity 2.0
+CAY-2395 cdbimport: add option to create project file
CAY-2396 Upgrade maven-assembly-plugin to 3.1.0
Bug Fixes:
http://git-wip-us.apache.org/repos/asf/cayenne/blob/c4b11004/maven-plugins/cayenne-maven-plugin/src/main/java/org/apache/cayenne/tools/DbImporterMojo.java
----------------------------------------------------------------------
diff --git a/maven-plugins/cayenne-maven-plugin/src/main/java/org/apache/cayenne/tools/DbImporterMojo.java b/maven-plugins/cayenne-maven-plugin/src/main/java/org/apache/cayenne/tools/DbImporterMojo.java
index ab04c83..e6422c5 100644
--- a/maven-plugins/cayenne-maven-plugin/src/main/java/org/apache/cayenne/tools/DbImporterMojo.java
+++ b/maven-plugins/cayenne-maven-plugin/src/main/java/org/apache/cayenne/tools/DbImporterMojo.java
@@ -71,6 +71,14 @@ public class DbImporterMojo extends AbstractMojo {
private File map;
/**
+ * Project XML file to use. If set cayenneProject will be created or updated after DB importing.
+ * This is optional parameter.
+ * @since 4.1
+ */
+ @Parameter
+ private File cayenneProject;
+
+ /**
* An object that contains reverse engineering rules.
*/
@Parameter(name = "dbimport", property = "dbimport", alias = "dbImport")
@@ -129,6 +137,7 @@ public class DbImporterMojo extends AbstractMojo {
config.setStripFromTableNames(dbImportConfig.getStripFromTableNames());
config.setTableTypes(dbImportConfig.getTableTypes());
config.setTargetDataMap(map);
+ config.setCayenneProject(cayenneProject);
config.setUrl(dataSource.getUrl());
config.setUsername(dataSource.getUsername());
config.setUsePrimitives(dbImportConfig.isUsePrimitives());
http://git-wip-us.apache.org/repos/asf/cayenne/blob/c4b11004/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/dialog/db/load/ModelerDbImportAction.java
----------------------------------------------------------------------
diff --git a/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/dialog/db/load/ModelerDbImportAction.java b/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/dialog/db/load/ModelerDbImportAction.java
index 5e60bc4..b98313f 100644
--- a/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/dialog/db/load/ModelerDbImportAction.java
+++ b/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/dialog/db/load/ModelerDbImportAction.java
@@ -18,6 +18,7 @@
****************************************************************/
package org.apache.cayenne.modeler.dialog.db.load;
+import org.apache.cayenne.configuration.DataChannelDescriptorLoader;
import org.apache.cayenne.configuration.DataMapLoader;
import org.apache.cayenne.configuration.server.DataSourceFactory;
import org.apache.cayenne.configuration.server.DbAdapterFactory;
@@ -41,8 +42,9 @@ public class ModelerDbImportAction extends DefaultDbImportAction {
@Inject DataSourceFactory dataSourceFactory,
@Inject DbAdapterFactory adapterFactory,
@Inject DataMapLoader mapLoader,
- @Inject MergerTokenFactoryProvider mergerTokenFactoryProvider) {
- super(logger, projectSaver, dataSourceFactory, adapterFactory, mapLoader, mergerTokenFactoryProvider);
+ @Inject MergerTokenFactoryProvider mergerTokenFactoryProvider,
+ @Inject DataChannelDescriptorLoader dataChannelDescriptorLoader) {
+ super(logger, projectSaver, dataSourceFactory, adapterFactory, mapLoader, mergerTokenFactoryProvider, dataChannelDescriptorLoader);
}
@Override