This is an automated email from the ASF dual-hosted git repository.

abulatski pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/cayenne.git

commit e14d2c3b15e967ea22ed4fc6c5c1bec5be619702
Author: Arseni Bulatski <ancars...@gmail.com>
AuthorDate: Mon Jul 1 15:17:43 2019 +0300

    CAY-2539 Import procedures with the help of MergerToken
---
 RELEASE-NOTES.txt                                  |   1 +
 .../apache/cayenne/dbsync/merge/DataMapMerger.java |  16 ++-
 .../cayenne/dbsync/merge/ProcedureDictionary.java  |  69 +++++++++++++
 .../cayenne/dbsync/merge/ProcedureMerger.java      | 112 +++++++++++++++++++++
 .../merge/factory/DefaultMergerTokenFactory.java   |  29 +++++-
 .../dbsync/merge/factory/MergerTokenFactory.java   |  13 ++-
 .../dbsync/merge/token/db/AddProcedureToDb.java    |  55 ++++++++++
 .../dbsync/merge/token/db/DropProcedureToDb.java   |  55 ++++++++++
 .../merge/token/model/CreateProcedureToModel.java  |  57 +++++++++++
 .../merge/token/model/DropProcedureToModel.java    |  57 +++++++++++
 .../reverse/dbimport/DefaultDbImportAction.java    |  55 +---------
 .../reverse/dbload/DefaultModelMergeDelegate.java  |  11 ++
 .../dbsync/reverse/dbload/ModelMergeDelegate.java  |   4 +
 .../reverse/dbload/ProxyModelMergeDelegate.java    |  11 ++
 .../cayenne/dbsync/merge/DataMapMergerTest.java    |  28 +++++-
 .../dbsync/merge/builders/DataMapBuilder.java      |  21 +++-
 .../dbsync/merge/builders/ObjectMother.java        |   8 ++
 .../dbsync/merge/builders/ProcedureBuilder.java    |  56 +++++++++++
 .../dbsync/merge/token/TokensReverseTest.java      |  11 +-
 .../apache/cayenne/dba/DefaultQuotingStrategy.java |   2 +-
 .../java/org/apache/cayenne/map/Procedure.java     |  14 +--
 .../apache/cayenne/tools/DbImporterMojoTest.java   |  24 +++++
 .../tools/dbimport/testDropProcedure-pom.xml       |  49 +++++++++
 .../tools/dbimport/testDropProcedure.map.xml       |  32 ++++++
 .../dbimport/testDropProcedure.map.xml-result      |  31 ++++++
 .../cayenne/tools/dbimport/testDropProcedure.sql   |  25 +++++
 .../tools/dbimport/testImportProcedure-pom.xml     |  51 ++++++++++
 .../tools/dbimport/testImportProcedure.map.xml     |  31 ++++++
 .../dbimport/testImportProcedure.map.xml-result    |  35 +++++++
 .../cayenne/tools/dbimport/testImportProcedure.sql |  29 ++++++
 .../tools/dbimport/testSameProcedure-pom.xml       |  51 ++++++++++
 .../tools/dbimport/testSameProcedure.map.xml       |  32 ++++++
 .../dbimport/testSameProcedure.map.xml-result      |  35 +++++++
 .../cayenne/tools/dbimport/testSameProcedure.sql   |  29 ++++++
 .../dialog/db/load/ModelerDbImportAction.java      |  39 +------
 35 files changed, 1064 insertions(+), 114 deletions(-)

diff --git a/RELEASE-NOTES.txt b/RELEASE-NOTES.txt
index 89bf59d..8c995c7 100644
--- a/RELEASE-NOTES.txt
+++ b/RELEASE-NOTES.txt
@@ -23,6 +23,7 @@ CAY-2518 Add method to append having qualifier expression to 
ObjectSelect
 CAY-2520 Split ObjectId into several specialized variants
 CAY-2522 Make ObjectSelect a direct query
 CAY-2525 Deprecate OpenBase adapter
+CAY-2539 Import procedures with the help of MergerToken
 CAY-2540 Modeler: redesign dbRelationship editor dialog
 CAY-2542 Modeler: redesign ObjRelationship editor dialog
 CAY-2543 Move ResultSetMapping generation from metadata to translator
diff --git 
a/cayenne-dbsync/src/main/java/org/apache/cayenne/dbsync/merge/DataMapMerger.java
 
b/cayenne-dbsync/src/main/java/org/apache/cayenne/dbsync/merge/DataMapMerger.java
index 628872c..bc2c8f5 100644
--- 
a/cayenne-dbsync/src/main/java/org/apache/cayenne/dbsync/merge/DataMapMerger.java
+++ 
b/cayenne-dbsync/src/main/java/org/apache/cayenne/dbsync/merge/DataMapMerger.java
@@ -19,6 +19,11 @@
 
 package org.apache.cayenne.dbsync.merge;
 
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+import java.util.Objects;
+
 import org.apache.cayenne.dbsync.merge.factory.MergerTokenFactory;
 import org.apache.cayenne.dbsync.merge.token.EmptyValueForNullProvider;
 import org.apache.cayenne.dbsync.merge.token.MergerToken;
@@ -31,11 +36,6 @@ import org.apache.cayenne.map.DbAttribute;
 import org.apache.cayenne.map.DbEntity;
 import org.apache.cayenne.map.DbRelationship;
 
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.List;
-import java.util.Objects;
-
 /**
  * Synchronization of data base store and Cayenne model.
  */
@@ -62,6 +62,7 @@ public class DataMapMerger implements Merger<DataMap> {
         createDbEntityMerger(original, importedFromDb);
         createRelationshipMerger();
         createAttributeMerger();
+        createProcedureMerger(original ,importedFromDb);
 
         return createTokens();
     }
@@ -102,6 +103,11 @@ public class DataMapMerger implements Merger<DataMap> {
         mergerList.add(dbRelationshipMerger);
     }
 
+    private void createProcedureMerger(DataMap original, DataMap imported) {
+        ProcedureMerger procedureMerger = new ProcedureMerger(tokenFactory, 
original, imported, filters);
+        mergerList.add(procedureMerger);
+    }
+
     public static Builder builder(MergerTokenFactory tokenFactory) {
         return new Builder(tokenFactory);
     }
diff --git 
a/cayenne-dbsync/src/main/java/org/apache/cayenne/dbsync/merge/ProcedureDictionary.java
 
b/cayenne-dbsync/src/main/java/org/apache/cayenne/dbsync/merge/ProcedureDictionary.java
new file mode 100644
index 0000000..6ca374d
--- /dev/null
+++ 
b/cayenne-dbsync/src/main/java/org/apache/cayenne/dbsync/merge/ProcedureDictionary.java
@@ -0,0 +1,69 @@
+/*****************************************************************
+ *   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
+ *
+ *    https://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ ****************************************************************/
+
+package org.apache.cayenne.dbsync.merge;
+
+import java.util.Collection;
+import java.util.LinkedList;
+
+import org.apache.cayenne.dbsync.reverse.filters.FiltersConfig;
+import org.apache.cayenne.dbsync.reverse.filters.PatternFilter;
+import org.apache.cayenne.map.DataMap;
+import org.apache.cayenne.map.Procedure;
+
+/**
+ * @since 4.2
+ */
+public class ProcedureDictionary extends MergerDictionary<Procedure> {
+
+    private final DataMap container;
+
+    private final FiltersConfig filtersConfig;
+
+    ProcedureDictionary(DataMap container, FiltersConfig filtersConfig) {
+        this.container = container;
+        this.filtersConfig = filtersConfig;
+    }
+
+    @Override
+    String getName(Procedure entity) {
+        return entity.getName();
+    }
+
+    @Override
+    Collection<Procedure> getAll() {
+        return filter();
+    }
+
+    private Collection<Procedure> filter() {
+        if(filtersConfig == null) {
+            return container.getProcedures();
+        }
+
+        Collection<Procedure> existingFiltered = new LinkedList<>();
+        for(Procedure procedure : container.getProcedures()) {
+            PatternFilter patternFilter = filtersConfig
+                    .proceduresFilter(procedure.getCatalog(), 
procedure.getSchema());
+            if(patternFilter != null && 
patternFilter.isIncluded(procedure.getName())) {
+                existingFiltered.add(procedure);
+            }
+        }
+        return existingFiltered;
+    }
+}
diff --git 
a/cayenne-dbsync/src/main/java/org/apache/cayenne/dbsync/merge/ProcedureMerger.java
 
b/cayenne-dbsync/src/main/java/org/apache/cayenne/dbsync/merge/ProcedureMerger.java
new file mode 100644
index 0000000..7bc5362
--- /dev/null
+++ 
b/cayenne-dbsync/src/main/java/org/apache/cayenne/dbsync/merge/ProcedureMerger.java
@@ -0,0 +1,112 @@
+/*****************************************************************
+ *   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
+ *
+ *    https://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ ****************************************************************/
+
+package org.apache.cayenne.dbsync.merge;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.List;
+
+import org.apache.cayenne.dbsync.merge.factory.MergerTokenFactory;
+import org.apache.cayenne.dbsync.merge.token.MergerToken;
+import org.apache.cayenne.dbsync.reverse.filters.FiltersConfig;
+import org.apache.cayenne.map.DataMap;
+import org.apache.cayenne.map.Procedure;
+import org.apache.cayenne.map.ProcedureParameter;
+
+/**
+ * @since 4.2
+ */
+public class ProcedureMerger extends AbstractMerger<DataMap, Procedure> {
+
+    private final FiltersConfig filtersConfig;
+    private DataMap originalDataMap;
+    private DataMap importedDataMap;
+
+    ProcedureMerger(MergerTokenFactory tokenFactory, DataMap original, DataMap 
imported,
+                   FiltersConfig filtersConfig) {
+        super(tokenFactory);
+        this.filtersConfig = filtersConfig;
+        originalDataMap = original;
+        importedDataMap = imported;
+    }
+
+    @Override
+    public List<MergerToken> createMergeTokens() {
+        return createMergeTokens(originalDataMap, importedDataMap);
+    }
+
+    @Override
+    MergerDictionaryDiff<Procedure> createDiff(DataMap original, DataMap 
imported) {
+        return new MergerDictionaryDiff.Builder<Procedure>()
+                .originalDictionary(new ProcedureDictionary(original, 
filtersConfig))
+                .importedDictionary(new ProcedureDictionary(imported, 
filtersConfig))
+                .build();
+    }
+
+    @Override
+    Collection<MergerToken> createTokensForMissingOriginal(Procedure imported) 
{
+        return 
Collections.singletonList(getTokenFactory().createDropProcedureToDb(imported));
+    }
+
+    @Override
+    Collection<MergerToken> createTokensForMissingImported(Procedure original) 
{
+        return 
Collections.singletonList(getTokenFactory().createAddProcedureToDb(original));
+    }
+
+    @Override
+    Collection<MergerToken> createTokensForSame(MergerDiffPair<Procedure> 
same) {
+        Procedure original = same.getOriginal();
+        Procedure imported = same.getImported();
+        if(needToCreateTokens(original, imported)) {
+            List<MergerToken> tokens = new ArrayList<>();
+            tokens.add(getTokenFactory().createAddProcedureToDb(original));
+            tokens.add(getTokenFactory().createDropProcedureToDb(imported));
+            return tokens;
+        }
+        return null;
+    }
+
+    private boolean needToCreateTokens(Procedure original, Procedure imported) 
{
+        List<ProcedureParameter> originalParams = original.getCallParameters();
+        List<ProcedureParameter> importedParams = imported.getCallParameters();
+        if(originalParams.size() != importedParams.size()) {
+            return true;
+        }
+        for(ProcedureParameter oP : originalParams) {
+            boolean found = false;
+            for(ProcedureParameter iP : importedParams) {
+                if(oP.getName().equals(iP.getName()) &&
+                        oP.getType() == iP.getType() &&
+                        oP.getPrecision() == iP.getPrecision() &&
+                        oP.getMaxLength() == iP.getMaxLength() &&
+                        oP.getDirection() == iP.getDirection()) {
+                    found = true;
+                    break;
+                }
+            }
+            if(!found) {
+                return true;
+            }
+        }
+        return false;
+    }
+
+}
diff --git 
a/cayenne-dbsync/src/main/java/org/apache/cayenne/dbsync/merge/factory/DefaultMergerTokenFactory.java
 
b/cayenne-dbsync/src/main/java/org/apache/cayenne/dbsync/merge/factory/DefaultMergerTokenFactory.java
index a011466..4b9af94 100644
--- 
a/cayenne-dbsync/src/main/java/org/apache/cayenne/dbsync/merge/factory/DefaultMergerTokenFactory.java
+++ 
b/cayenne-dbsync/src/main/java/org/apache/cayenne/dbsync/merge/factory/DefaultMergerTokenFactory.java
@@ -18,12 +18,16 @@
  ****************************************************************/
 package org.apache.cayenne.dbsync.merge.factory;
 
+import java.util.Collection;
+
 import org.apache.cayenne.dbsync.merge.token.MergerToken;
 import org.apache.cayenne.dbsync.merge.token.ValueForNullProvider;
 import org.apache.cayenne.dbsync.merge.token.db.AddColumnToDb;
+import org.apache.cayenne.dbsync.merge.token.db.AddProcedureToDb;
 import org.apache.cayenne.dbsync.merge.token.db.AddRelationshipToDb;
 import org.apache.cayenne.dbsync.merge.token.db.CreateTableToDb;
 import org.apache.cayenne.dbsync.merge.token.db.DropColumnToDb;
+import org.apache.cayenne.dbsync.merge.token.db.DropProcedureToDb;
 import org.apache.cayenne.dbsync.merge.token.db.DropRelationshipToDb;
 import org.apache.cayenne.dbsync.merge.token.db.DropTableToDb;
 import org.apache.cayenne.dbsync.merge.token.db.SetAllowNullToDb;
@@ -34,8 +38,10 @@ import 
org.apache.cayenne.dbsync.merge.token.db.SetPrimaryKeyToDb;
 import org.apache.cayenne.dbsync.merge.token.db.SetValueForNullToDb;
 import org.apache.cayenne.dbsync.merge.token.model.AddColumnToModel;
 import org.apache.cayenne.dbsync.merge.token.model.AddRelationshipToModel;
+import org.apache.cayenne.dbsync.merge.token.model.CreateProcedureToModel;
 import org.apache.cayenne.dbsync.merge.token.model.CreateTableToModel;
 import org.apache.cayenne.dbsync.merge.token.model.DropColumnToModel;
+import org.apache.cayenne.dbsync.merge.token.model.DropProcedureToModel;
 import org.apache.cayenne.dbsync.merge.token.model.DropRelationshipToModel;
 import org.apache.cayenne.dbsync.merge.token.model.DropTableToModel;
 import org.apache.cayenne.dbsync.merge.token.model.SetAllowNullToModel;
@@ -46,8 +52,7 @@ import 
org.apache.cayenne.dbsync.merge.token.model.SetPrimaryKeyToModel;
 import org.apache.cayenne.map.DbAttribute;
 import org.apache.cayenne.map.DbEntity;
 import org.apache.cayenne.map.DbRelationship;
-
-import java.util.Collection;
+import org.apache.cayenne.map.Procedure;
 
 /**
  * @since 4.0
@@ -156,6 +161,26 @@ public class DefaultMergerTokenFactory implements 
MergerTokenFactory {
     }
 
     @Override
+    public MergerToken createAddProcedureToDb(Procedure procedure) {
+        return new AddProcedureToDb(procedure);
+    }
+
+    @Override
+    public MergerToken createAddProcedureToModel(Procedure procedure) {
+        return new CreateProcedureToModel(procedure);
+    }
+
+    @Override
+    public MergerToken createDropProcedureToDb(Procedure procedure) {
+        return new DropProcedureToDb(procedure);
+    }
+
+    @Override
+    public MergerToken createDropProcedureToModel(Procedure procedure) {
+        return new DropProcedureToModel(procedure);
+    }
+
+    @Override
     public MergerToken createSetPrimaryKeyToDb(
             DbEntity entity,
             Collection<DbAttribute> primaryKeyOriginal,
diff --git 
a/cayenne-dbsync/src/main/java/org/apache/cayenne/dbsync/merge/factory/MergerTokenFactory.java
 
b/cayenne-dbsync/src/main/java/org/apache/cayenne/dbsync/merge/factory/MergerTokenFactory.java
index 3b91321..60d9c9d 100644
--- 
a/cayenne-dbsync/src/main/java/org/apache/cayenne/dbsync/merge/factory/MergerTokenFactory.java
+++ 
b/cayenne-dbsync/src/main/java/org/apache/cayenne/dbsync/merge/factory/MergerTokenFactory.java
@@ -18,13 +18,14 @@
  ****************************************************************/
 package org.apache.cayenne.dbsync.merge.factory;
 
+import java.util.Collection;
+
 import org.apache.cayenne.dbsync.merge.token.MergerToken;
 import org.apache.cayenne.dbsync.merge.token.ValueForNullProvider;
 import org.apache.cayenne.map.DbAttribute;
 import org.apache.cayenne.map.DbEntity;
 import org.apache.cayenne.map.DbRelationship;
-
-import java.util.Collection;
+import org.apache.cayenne.map.Procedure;
 
 public interface MergerTokenFactory {
 
@@ -74,6 +75,14 @@ public interface MergerTokenFactory {
 
     MergerToken createDropRelationshipToModel(DbEntity entity, DbRelationship 
rel);
 
+    MergerToken createAddProcedureToDb(Procedure procedure);
+
+    MergerToken createAddProcedureToModel(Procedure procedure);
+
+    MergerToken createDropProcedureToDb(Procedure procedure);
+
+    MergerToken createDropProcedureToModel(Procedure procedure);
+
     MergerToken createSetPrimaryKeyToDb(
             DbEntity entity,
             Collection<DbAttribute> primaryKeyOriginal,
diff --git 
a/cayenne-dbsync/src/main/java/org/apache/cayenne/dbsync/merge/token/db/AddProcedureToDb.java
 
b/cayenne-dbsync/src/main/java/org/apache/cayenne/dbsync/merge/token/db/AddProcedureToDb.java
new file mode 100644
index 0000000..1481888
--- /dev/null
+++ 
b/cayenne-dbsync/src/main/java/org/apache/cayenne/dbsync/merge/token/db/AddProcedureToDb.java
@@ -0,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
+ *
+ *    https://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ ****************************************************************/
+
+package org.apache.cayenne.dbsync.merge.token.db;
+
+import java.util.List;
+
+import org.apache.cayenne.dba.DbAdapter;
+import org.apache.cayenne.dbsync.merge.factory.MergerTokenFactory;
+import org.apache.cayenne.dbsync.merge.token.MergerToken;
+import org.apache.cayenne.map.Procedure;
+
+/**
+ * @since 4.2
+ */
+public class AddProcedureToDb extends AbstractToDbToken {
+
+    private Procedure procedure;
+
+    public AddProcedureToDb(Procedure procedure) {
+        super("Add procedure to db", 120);
+        this.procedure = procedure;
+    }
+
+    @Override
+    public List<String> createSql(DbAdapter adapter) {
+        throw new UnsupportedOperationException("Can't generate SQL for 
procedure");
+    }
+
+    @Override
+    public String getTokenValue() {
+        return procedure.getName();
+    }
+
+    @Override
+    public MergerToken createReverse(MergerTokenFactory factory) {
+        return factory.createDropProcedureToModel(procedure);
+    }
+}
diff --git 
a/cayenne-dbsync/src/main/java/org/apache/cayenne/dbsync/merge/token/db/DropProcedureToDb.java
 
b/cayenne-dbsync/src/main/java/org/apache/cayenne/dbsync/merge/token/db/DropProcedureToDb.java
new file mode 100644
index 0000000..05f5163
--- /dev/null
+++ 
b/cayenne-dbsync/src/main/java/org/apache/cayenne/dbsync/merge/token/db/DropProcedureToDb.java
@@ -0,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
+ *
+ *    https://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ ****************************************************************/
+
+package org.apache.cayenne.dbsync.merge.token.db;
+
+import java.util.List;
+
+import org.apache.cayenne.dba.DbAdapter;
+import org.apache.cayenne.dbsync.merge.factory.MergerTokenFactory;
+import org.apache.cayenne.dbsync.merge.token.MergerToken;
+import org.apache.cayenne.map.Procedure;
+
+/**
+ * @since 4.2
+ */
+public class DropProcedureToDb extends AbstractToDbToken {
+
+    private Procedure procedure;
+
+    public DropProcedureToDb(Procedure procedure) {
+        super("Drop procedure to db", 7);
+        this.procedure = procedure;
+    }
+
+    @Override
+    public List<String> createSql(DbAdapter adapter) {
+        throw new UnsupportedOperationException("Can't drop procedure to db.");
+    }
+
+    @Override
+    public String getTokenValue() {
+        return procedure.getName();
+    }
+
+    @Override
+    public MergerToken createReverse(MergerTokenFactory factory) {
+        return factory.createAddProcedureToModel(procedure);
+    }
+}
diff --git 
a/cayenne-dbsync/src/main/java/org/apache/cayenne/dbsync/merge/token/model/CreateProcedureToModel.java
 
b/cayenne-dbsync/src/main/java/org/apache/cayenne/dbsync/merge/token/model/CreateProcedureToModel.java
new file mode 100644
index 0000000..83c1371
--- /dev/null
+++ 
b/cayenne-dbsync/src/main/java/org/apache/cayenne/dbsync/merge/token/model/CreateProcedureToModel.java
@@ -0,0 +1,57 @@
+/*****************************************************************
+ *   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
+ *
+ *    https://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ ****************************************************************/
+
+package org.apache.cayenne.dbsync.merge.token.model;
+
+import org.apache.cayenne.dbsync.merge.context.MergerContext;
+import org.apache.cayenne.dbsync.merge.factory.MergerTokenFactory;
+import org.apache.cayenne.dbsync.merge.token.MergerToken;
+import org.apache.cayenne.map.DataMap;
+import org.apache.cayenne.map.Procedure;
+
+/**
+ * @since 4.2
+ */
+public class CreateProcedureToModel extends AbstractToModelToken {
+
+    private Procedure procedure;
+
+    public CreateProcedureToModel(Procedure procedure) {
+        super("Add procedure to model", 125);
+        this.procedure = procedure;
+    }
+
+    @Override
+    public String getTokenValue() {
+        return procedure.getName();
+    }
+
+    @Override
+    public MergerToken createReverse(MergerTokenFactory factory) {
+        return factory.createDropProcedureToDb(procedure);
+    }
+
+    @Override
+    public void execute(MergerContext context) {
+        DataMap dataMap = context.getDataMap();
+        dataMap.addProcedure(procedure);
+
+        context.getDelegate().procedureAdded(procedure);
+    }
+}
diff --git 
a/cayenne-dbsync/src/main/java/org/apache/cayenne/dbsync/merge/token/model/DropProcedureToModel.java
 
b/cayenne-dbsync/src/main/java/org/apache/cayenne/dbsync/merge/token/model/DropProcedureToModel.java
new file mode 100644
index 0000000..19bc07b
--- /dev/null
+++ 
b/cayenne-dbsync/src/main/java/org/apache/cayenne/dbsync/merge/token/model/DropProcedureToModel.java
@@ -0,0 +1,57 @@
+/*****************************************************************
+ *   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
+ *
+ *    https://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ ****************************************************************/
+
+package org.apache.cayenne.dbsync.merge.token.model;
+
+import org.apache.cayenne.dbsync.merge.context.MergerContext;
+import org.apache.cayenne.dbsync.merge.factory.MergerTokenFactory;
+import org.apache.cayenne.dbsync.merge.token.MergerToken;
+import org.apache.cayenne.map.Procedure;
+
+/**
+ * @since 4.2
+ */
+public class DropProcedureToModel extends AbstractToModelToken {
+
+    private Procedure procedure;
+
+    public DropProcedureToModel(Procedure procedure) {
+        super("Drop procedure to model", 60);
+        this.procedure = procedure;
+    }
+
+    @Override
+    public String getTokenValue() {
+        return procedure.getName();
+    }
+
+    @Override
+    public MergerToken createReverse(MergerTokenFactory factory) {
+        return factory.createAddProcedureToDb(procedure);
+    }
+
+    @Override
+    public void execute(MergerContext context) {
+        if(procedure == null) {
+            return;
+        }
+        context.getDataMap().removeProcedure(procedure.getName());
+        context.getDelegate().procedureRemoved(procedure);
+    }
+}
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 1728116..2130498 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
@@ -54,14 +54,12 @@ import 
org.apache.cayenne.dbsync.reverse.dbload.ProxyModelMergeDelegate;
 import org.apache.cayenne.dbsync.reverse.filters.CatalogFilter;
 import org.apache.cayenne.dbsync.reverse.filters.FiltersConfig;
 import org.apache.cayenne.dbsync.reverse.filters.FiltersConfigBuilder;
-import org.apache.cayenne.dbsync.reverse.filters.PatternFilter;
 import org.apache.cayenne.di.Inject;
 import org.apache.cayenne.map.DataMap;
 import org.apache.cayenne.map.DbEntity;
 import org.apache.cayenne.map.EntityResolver;
 import org.apache.cayenne.map.ObjEntity;
 import org.apache.cayenne.map.ObjRelationship;
-import org.apache.cayenne.map.Procedure;
 import org.apache.cayenne.project.Project;
 import org.apache.cayenne.project.ProjectSaver;
 import org.apache.cayenne.resource.URLResource;
@@ -153,7 +151,6 @@ public class DefaultDbImportAction implements 
DbImportAction {
 
             syncDataMapProperties(targetDataMap, config);
             applyTokens(targetDataMap, tokens, config);
-            syncProcedures(targetDataMap, sourceDataMap, filters);
 
             saveLoaded(targetDataMap, config);
             this.loadedDataMap = null;
@@ -201,7 +198,7 @@ public class DefaultDbImportAction implements 
DbImportAction {
         }
         this.loadedDataMap = targetDataMap;
 
-        // In that moment our data map fills with sorce map
+        // In that moment our data map fills with source map
         // transform source DataMap before merging
         transformSourceBeforeMerge(sourceDataMap, targetDataMap, config);
 
@@ -219,7 +216,6 @@ public class DefaultDbImportAction implements 
DbImportAction {
 
         hasChanges |= checkDataMapProperties(targetDataMap, config);
         hasChanges |= hasTokensToImport(tokens);
-        hasChanges |= checkIncludedProcedures(sourceDataMap, filters);
         return sourceDataMap;
     }
 
@@ -275,24 +271,6 @@ public class DefaultDbImportAction implements 
DbImportAction {
         return defaultPackage.equals(targetDataMap.getDefaultPackage());
     }
 
-    protected boolean hasChangesForProcedure(Procedure procedure) {
-        PatternFilter proceduresFilter = 
filters.proceduresFilter(procedure.getCatalog(), procedure.getSchema());
-        return proceduresFilter != null && 
proceduresFilter.isIncluded(procedure.getName());
-    }
-
-    protected boolean checkIncludedProcedures(DataMap loadedDataMap, 
FiltersConfig filters) {
-        Collection<Procedure> procedures = loadedDataMap.getProcedures();
-        boolean hasChanges = false;
-        for (Procedure procedure : procedures) {
-            if(!hasChangesForProcedure(procedure)) {
-                continue;
-            }
-            hasChanges = true;
-        }
-        return hasChanges;
-    }
-
-
     private void syncDataMapProperties(DataMap targetDataMap, 
DbImportConfiguration config) {
         String defaultPackage = config.getDefaultPackage();
         if (defaultPackage == null || isBlank(defaultPackage)) {
@@ -384,8 +362,7 @@ public class DefaultDbImportAction implements 
DbImportAction {
         return dataMap;
     }
 
-    private List<MergerToken> reverse(MergerTokenFactory mergerTokenFactory, 
Iterable<MergerToken> mergeTokens)
-            throws IOException {
+    private List<MergerToken> reverse(MergerTokenFactory mergerTokenFactory, 
Iterable<MergerToken> mergeTokens) {
 
         List<MergerToken> tokens = new LinkedList<>();
         for (MergerToken token : mergeTokens) {
@@ -449,38 +426,10 @@ public class DefaultDbImportAction implements 
DbImportAction {
         relationshipsSanity(targetDataMap);
     }
 
-    protected void addMessageToLogs(String message, List<String> messages) {
-        messages.add(message);
-    }
-
     protected void logMessages(List<String> messages) {
         messages.forEach(logger::info);
     }
 
-
-    protected void syncProcedures(DataMap targetDataMap, DataMap 
loadedDataMap, FiltersConfig filters) {
-        Collection<Procedure> procedures = loadedDataMap.getProcedures();
-        List<String> messages = new LinkedList<>();
-
-        for (Procedure procedure : procedures) {
-            PatternFilter proceduresFilter = 
filters.proceduresFilter(procedure.getCatalog(), procedure.getSchema());
-            if (proceduresFilter == null || 
!proceduresFilter.isIncluded(procedure.getName())) {
-                continue;
-            }
-
-            Procedure oldProcedure = 
targetDataMap.getProcedure(procedure.getName());
-            // maybe we need to compare oldProcedure's and procedure's fully 
qualified names?
-            if (oldProcedure != null) {
-                targetDataMap.removeProcedure(procedure.getName());
-                addMessageToLogs("Replace procedure " + procedure.getName(), 
messages);
-            } else {
-                addMessageToLogs("Add new procedure " + procedure.getName(), 
messages);
-            }
-            targetDataMap.addProcedure(procedure);
-        }
-        logMessages(messages);
-    }
-
     /**
      * Save imported data.
      * This can create DataMap and/or Project files.
diff --git 
a/cayenne-dbsync/src/main/java/org/apache/cayenne/dbsync/reverse/dbload/DefaultModelMergeDelegate.java
 
b/cayenne-dbsync/src/main/java/org/apache/cayenne/dbsync/reverse/dbload/DefaultModelMergeDelegate.java
index e0c6f18..689e337 100644
--- 
a/cayenne-dbsync/src/main/java/org/apache/cayenne/dbsync/reverse/dbload/DefaultModelMergeDelegate.java
+++ 
b/cayenne-dbsync/src/main/java/org/apache/cayenne/dbsync/reverse/dbload/DefaultModelMergeDelegate.java
@@ -25,6 +25,7 @@ import org.apache.cayenne.map.DbRelationship;
 import org.apache.cayenne.map.ObjAttribute;
 import org.apache.cayenne.map.ObjEntity;
 import org.apache.cayenne.map.ObjRelationship;
+import org.apache.cayenne.map.Procedure;
 
 /**
  * A default noop implementation of {@link ModelMergeDelegate}.
@@ -87,4 +88,14 @@ public class DefaultModelMergeDelegate implements 
ModelMergeDelegate {
     public void objRelationshipRemoved(ObjRelationship rel) {
     }
 
+    @Override
+    public void procedureAdded(Procedure procedure) {
+
+    }
+
+    @Override
+    public void procedureRemoved(Procedure procedure) {
+
+    }
+
 }
diff --git 
a/cayenne-dbsync/src/main/java/org/apache/cayenne/dbsync/reverse/dbload/ModelMergeDelegate.java
 
b/cayenne-dbsync/src/main/java/org/apache/cayenne/dbsync/reverse/dbload/ModelMergeDelegate.java
index 5f4b663..466d3bb 100644
--- 
a/cayenne-dbsync/src/main/java/org/apache/cayenne/dbsync/reverse/dbload/ModelMergeDelegate.java
+++ 
b/cayenne-dbsync/src/main/java/org/apache/cayenne/dbsync/reverse/dbload/ModelMergeDelegate.java
@@ -27,6 +27,7 @@ import org.apache.cayenne.map.DbRelationship;
 import org.apache.cayenne.map.ObjAttribute;
 import org.apache.cayenne.map.ObjEntity;
 import org.apache.cayenne.map.ObjRelationship;
+import org.apache.cayenne.map.Procedure;
 
 /**
  * A interface used to tell about modifications performed on the model by
@@ -62,4 +63,7 @@ public interface ModelMergeDelegate {
 
     void objRelationshipRemoved(ObjRelationship rel);
 
+    void procedureAdded(Procedure procedure);
+
+    void procedureRemoved(Procedure procedure);
 }
diff --git 
a/cayenne-dbsync/src/main/java/org/apache/cayenne/dbsync/reverse/dbload/ProxyModelMergeDelegate.java
 
b/cayenne-dbsync/src/main/java/org/apache/cayenne/dbsync/reverse/dbload/ProxyModelMergeDelegate.java
index 2f95cc5..0c50580 100644
--- 
a/cayenne-dbsync/src/main/java/org/apache/cayenne/dbsync/reverse/dbload/ProxyModelMergeDelegate.java
+++ 
b/cayenne-dbsync/src/main/java/org/apache/cayenne/dbsync/reverse/dbload/ProxyModelMergeDelegate.java
@@ -25,6 +25,7 @@ import org.apache.cayenne.map.DbRelationship;
 import org.apache.cayenne.map.ObjAttribute;
 import org.apache.cayenne.map.ObjEntity;
 import org.apache.cayenne.map.ObjRelationship;
+import org.apache.cayenne.map.Procedure;
 
 /**
  * @since 4.0
@@ -106,4 +107,14 @@ public class ProxyModelMergeDelegate implements 
ModelMergeDelegate {
     public void objRelationshipRemoved(ObjRelationship rel) {
         delegate.objRelationshipRemoved(rel);
     }
+
+    @Override
+    public void procedureAdded(Procedure procedure) {
+        delegate.procedureAdded(procedure);
+    }
+
+    @Override
+    public void procedureRemoved(Procedure procedure) {
+        delegate.procedureRemoved(procedure);
+    }
 }
diff --git 
a/cayenne-dbsync/src/test/java/org/apache/cayenne/dbsync/merge/DataMapMergerTest.java
 
b/cayenne-dbsync/src/test/java/org/apache/cayenne/dbsync/merge/DataMapMergerTest.java
index c656518..4f14d81 100644
--- 
a/cayenne-dbsync/src/test/java/org/apache/cayenne/dbsync/merge/DataMapMergerTest.java
+++ 
b/cayenne-dbsync/src/test/java/org/apache/cayenne/dbsync/merge/DataMapMergerTest.java
@@ -18,19 +18,23 @@
  ****************************************************************/
 package org.apache.cayenne.dbsync.merge;
 
+import java.util.List;
+
 import org.apache.cayenne.dbsync.merge.builders.DbEntityBuilder;
 import org.apache.cayenne.dbsync.merge.factory.HSQLMergerTokenFactory;
 import org.apache.cayenne.dbsync.merge.token.MergerToken;
 import org.apache.cayenne.dbsync.merge.token.db.SetColumnTypeToDb;
+import org.apache.cayenne.dbsync.reverse.filters.FiltersConfig;
+import org.apache.cayenne.dbsync.reverse.filters.PatternFilter;
 import org.apache.cayenne.map.DataMap;
 import org.apache.cayenne.map.DbEntity;
+import org.apache.cayenne.map.ProcedureParameter;
 import org.junit.Test;
 
-import java.util.List;
-
 import static org.apache.cayenne.dbsync.merge.builders.ObjectMother.dataMap;
 import static org.apache.cayenne.dbsync.merge.builders.ObjectMother.dbAttr;
 import static org.apache.cayenne.dbsync.merge.builders.ObjectMother.dbEntity;
+import static org.apache.cayenne.dbsync.merge.builders.ObjectMother.procedure;
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertNotNull;
 import static org.junit.Assert.assertTrue;
@@ -464,6 +468,26 @@ public class DataMapMergerTest {
         assertEquals(0, dbMerger().createMergeTokens(dataMap1, 
dataMap2).size());
     }
 
+    @Test
+    public void testProcedures() {
+        DataMap dataMap1 = dataMap().with(
+               procedure("proc1")
+                       .callParameters(new ProcedureParameter("test"))
+        ).build();
+
+        DataMap dataMap2 = dataMap().build();
+
+        PatternFilter patternFilter = new PatternFilter();
+        patternFilter.include("proc1");
+        FiltersConfig filtersConfig = FiltersConfig
+                .create(null, null, null, patternFilter);
+        DataMapMerger merger = DataMapMerger
+                .builder(factory())
+                .filters(filtersConfig)
+                .build();
+        assertEquals(1, merger.createMergeTokens(dataMap1, dataMap2).size());
+    }
+
     private DataMapMerger dbMerger() {
         return DataMapMerger.build(factory());
     }
diff --git 
a/cayenne-dbsync/src/test/java/org/apache/cayenne/dbsync/merge/builders/DataMapBuilder.java
 
b/cayenne-dbsync/src/test/java/org/apache/cayenne/dbsync/merge/builders/DataMapBuilder.java
index 3878bee..5a7d518 100644
--- 
a/cayenne-dbsync/src/test/java/org/apache/cayenne/dbsync/merge/builders/DataMapBuilder.java
+++ 
b/cayenne-dbsync/src/test/java/org/apache/cayenne/dbsync/merge/builders/DataMapBuilder.java
@@ -18,12 +18,13 @@
  ****************************************************************/
 package org.apache.cayenne.dbsync.merge.builders;
 
+import java.util.Collections;
+
 import org.apache.cayenne.map.DataMap;
 import org.apache.cayenne.map.DbEntity;
 import org.apache.cayenne.map.EntityResolver;
 import org.apache.cayenne.map.ObjEntity;
-
-import java.util.Collections;
+import org.apache.cayenne.map.Procedure;
 
 /**
  * @since 4.0.
@@ -108,6 +109,22 @@ public class DataMapBuilder extends 
DefaultBuilder<DataMap> {
         return this;
     }
 
+    public DataMapBuilder with(ProcedureBuilder... procedures) {
+        for(ProcedureBuilder builder : procedures) {
+            obj.addProcedure(builder.build());
+        }
+
+        return this;
+    }
+
+    public DataMapBuilder with(Procedure... procedures) {
+        for(Procedure procedure : procedures) {
+            obj.addProcedure(procedure);
+        }
+
+        return this;
+    }
+
     public DataMap build() {
         if (obj.getNamespace() == null) {
             obj.setNamespace(new EntityResolver(Collections.singleton(obj)));
diff --git 
a/cayenne-dbsync/src/test/java/org/apache/cayenne/dbsync/merge/builders/ObjectMother.java
 
b/cayenne-dbsync/src/test/java/org/apache/cayenne/dbsync/merge/builders/ObjectMother.java
index e543a25..51a1af4 100644
--- 
a/cayenne-dbsync/src/test/java/org/apache/cayenne/dbsync/merge/builders/ObjectMother.java
+++ 
b/cayenne-dbsync/src/test/java/org/apache/cayenne/dbsync/merge/builders/ObjectMother.java
@@ -67,4 +67,12 @@ public class ObjectMother {
         return new DbAttributeBuilder();
     }
 
+    public static ProcedureBuilder procedure(String name) {
+        return procedure().name(name);
+    }
+
+    public static ProcedureBuilder procedure() {
+        return new ProcedureBuilder();
+    }
+
 }
diff --git 
a/cayenne-dbsync/src/test/java/org/apache/cayenne/dbsync/merge/builders/ProcedureBuilder.java
 
b/cayenne-dbsync/src/test/java/org/apache/cayenne/dbsync/merge/builders/ProcedureBuilder.java
new file mode 100644
index 0000000..8b75c44
--- /dev/null
+++ 
b/cayenne-dbsync/src/test/java/org/apache/cayenne/dbsync/merge/builders/ProcedureBuilder.java
@@ -0,0 +1,56 @@
+/*****************************************************************
+ *   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
+ *
+ *    https://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ ****************************************************************/
+
+package org.apache.cayenne.dbsync.merge.builders;
+
+import java.util.Arrays;
+
+import org.apache.cayenne.map.Procedure;
+import org.apache.cayenne.map.ProcedureParameter;
+import org.apache.cayenne.util.Util;
+
+public class ProcedureBuilder extends DefaultBuilder<Procedure> {
+
+    public ProcedureBuilder() {
+        super(new Procedure());
+    }
+
+    public ProcedureBuilder name() {
+        return name(getRandomJavaName());
+    }
+
+    public ProcedureBuilder name(String name) {
+        obj.setName(name);
+        return this;
+    }
+
+    public ProcedureBuilder callParameters(ProcedureParameter... 
procedureParameters) {
+        obj.setCallParameters(Arrays.asList(procedureParameters));
+
+        return this;
+    }
+
+    public Procedure build() {
+        if(obj.getName() == null) {
+            obj.setName(Util.capitalized(getRandomJavaName()));
+        }
+
+        return obj;
+    }
+}
diff --git 
a/cayenne-dbsync/src/test/java/org/apache/cayenne/dbsync/merge/token/TokensReverseTest.java
 
b/cayenne-dbsync/src/test/java/org/apache/cayenne/dbsync/merge/token/TokensReverseTest.java
index f221e2e..31d992b 100644
--- 
a/cayenne-dbsync/src/test/java/org/apache/cayenne/dbsync/merge/token/TokensReverseTest.java
+++ 
b/cayenne-dbsync/src/test/java/org/apache/cayenne/dbsync/merge/token/TokensReverseTest.java
@@ -19,17 +19,18 @@
 
 package org.apache.cayenne.dbsync.merge.token;
 
+import java.util.Collections;
+
 import org.apache.cayenne.dbsync.merge.factory.HSQLMergerTokenFactory;
 import org.apache.cayenne.dbsync.merge.factory.MergerTokenFactory;
 import org.apache.cayenne.map.DbAttribute;
 import org.apache.cayenne.map.DbEntity;
 import org.apache.cayenne.map.DbJoin;
 import org.apache.cayenne.map.DbRelationship;
+import org.apache.cayenne.map.Procedure;
 import org.junit.Assert;
 import org.junit.Test;
 
-import java.util.Collections;
-
 import static org.apache.cayenne.dbsync.merge.builders.ObjectMother.dbAttr;
 import static org.apache.cayenne.dbsync.merge.builders.ObjectMother.dbEntity;
 
@@ -45,6 +46,7 @@ public class TokensReverseTest {
         DbRelationship rel = new DbRelationship("rel");
         rel.setSourceEntity(entity);
         rel.addJoin(new DbJoin(rel, attr.getName(), "dontKnow"));
+        Procedure procedure = new Procedure("Test");
 
         testOneToOneReverse(factory().createAddColumnToDb(entity, attr));
         testOneToOneReverse(factory().createAddColumnToModel(entity, attr));
@@ -74,6 +76,11 @@ public class TokensReverseTest {
         testOneToOneReverse(factory().createSetPrimaryKeyToModel(entity, 
Collections.singleton(attr), Collections.singleton(attr2), "PK"));
 
         testOneToOneReverse(factory().createSetValueForNullToDb(entity, attr, 
new DefaultValueForNullProvider()));
+
+        testOneToOneReverse(factory().createDropProcedureToDb(procedure));
+        testOneToOneReverse(factory().createAddProcedureToDb(procedure));
+        testOneToOneReverse(factory().createDropProcedureToModel(procedure));
+        testOneToOneReverse(factory().createAddProcedureToModel(procedure));
     }
 
     private void testOneToOneReverse(MergerToken token) {
diff --git 
a/cayenne-server/src/main/java/org/apache/cayenne/dba/DefaultQuotingStrategy.java
 
b/cayenne-server/src/main/java/org/apache/cayenne/dba/DefaultQuotingStrategy.java
index 0ba17ff..f61a710 100644
--- 
a/cayenne-server/src/main/java/org/apache/cayenne/dba/DefaultQuotingStrategy.java
+++ 
b/cayenne-server/src/main/java/org/apache/cayenne/dba/DefaultQuotingStrategy.java
@@ -25,7 +25,7 @@ import org.apache.cayenne.map.DataMap;
 import org.apache.cayenne.map.DbAttribute;
 import org.apache.cayenne.map.DbEntity;
 import org.apache.cayenne.map.DbJoin;
-import org.apache.cayenne.map.Entity;
+import org.apache.cayenne.map.Procedure;
 
 /**
  * @since 4.0 this is a top-level class.
diff --git a/cayenne-server/src/main/java/org/apache/cayenne/map/Procedure.java 
b/cayenne-server/src/main/java/org/apache/cayenne/map/Procedure.java
index 45b009a..4d77524 100644
--- a/cayenne-server/src/main/java/org/apache/cayenne/map/Procedure.java
+++ b/cayenne-server/src/main/java/org/apache/cayenne/map/Procedure.java
@@ -19,17 +19,17 @@
 
 package org.apache.cayenne.map;
 
+import java.io.Serializable;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+
 import org.apache.cayenne.configuration.ConfigurationNode;
 import org.apache.cayenne.configuration.ConfigurationNodeVisitor;
 import org.apache.cayenne.util.CayenneMapEntry;
 import org.apache.cayenne.util.XMLEncoder;
 import org.apache.cayenne.util.XMLSerializable;
 
-import java.io.Serializable;
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.List;
-
 /**
  * A mapping descriptor for a database stored procedure.
  */
@@ -112,8 +112,8 @@ public class Procedure implements ConfigurationNode, 
CayenneMapEntry, XMLSeriali
     * Utility function to generate fully qualified name for procedure
     */
     public static String generateFullyQualifiedName(String catalog, String 
schema, String name) {
-        return (catalog != null ? catalog + '.' : "")
-                + (schema != null ? schema + '.' : "")
+        return (catalog != null && !catalog.isEmpty() ? catalog + '.' : "")
+                + (schema != null && !schema.isEmpty() ? schema + '.' : "")
                 + name;
     }
 
diff --git 
a/maven-plugins/cayenne-maven-plugin/src/test/java/org/apache/cayenne/tools/DbImporterMojoTest.java
 
b/maven-plugins/cayenne-maven-plugin/src/test/java/org/apache/cayenne/tools/DbImporterMojoTest.java
index f39f629..8dc70ee 100644
--- 
a/maven-plugins/cayenne-maven-plugin/src/test/java/org/apache/cayenne/tools/DbImporterMojoTest.java
+++ 
b/maven-plugins/cayenne-maven-plugin/src/test/java/org/apache/cayenne/tools/DbImporterMojoTest.java
@@ -292,6 +292,21 @@ public class DbImporterMojoTest extends 
AbstractMojoTestCase {
     }
 
     @Test
+    public void testImportProcedure() throws Exception {
+        test("testImportProcedure");
+    }
+
+    @Test
+    public void testDropProcedure() throws Exception {
+        test("testDropProcedure");
+    }
+
+    @Test
+    public void testSameProcedures() throws Exception {
+        test("testSameProcedure");
+    }
+
+    @Test
     public void testFilteringConfig() throws Exception {
         DbImporterMojo cdbImport = getCdbImport("config/pom-01.xml");
 
@@ -423,6 +438,15 @@ public class DbImporterMojoTest extends 
AbstractMojoTestCase {
                     }
                 }
 
+                try(ResultSet procedures = connection.getMetaData()
+                        .getProcedures(null, null,"PROC")) {
+                    while(procedures.next()) {
+                        String schema = 
procedures.getString("PROCEDURE_SCHEM");
+                        String name = procedures.getString("PROCEDURE_NAME");
+                        execute(stmt, "DROP PROCEDURE " + (isBlank(schema) ? 
"" : schema + ".") + name);
+                    }
+                }
+
                 try (ResultSet schemas = 
connection.getMetaData().getSchemas()) {
                     while (schemas.next()) {
                         String schem = schemas.getString("TABLE_SCHEM");
diff --git 
a/maven-plugins/cayenne-maven-plugin/src/test/resources/org/apache/cayenne/tools/dbimport/testDropProcedure-pom.xml
 
b/maven-plugins/cayenne-maven-plugin/src/test/resources/org/apache/cayenne/tools/dbimport/testDropProcedure-pom.xml
new file mode 100644
index 0000000..0a4f58e
--- /dev/null
+++ 
b/maven-plugins/cayenne-maven-plugin/src/test/resources/org/apache/cayenne/tools/dbimport/testDropProcedure-pom.xml
@@ -0,0 +1,49 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+  ~   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
+  ~
+  ~    https://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 xmlns="http://maven.apache.org/POM/4.0.0"; 
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance";
+         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0
+       http://maven.apache.org/xsd/maven-4.0.0.xsd";>
+
+    <name>DbImporterMojo Test1</name>
+    <groupId>org.apache.maven.plugin-testing</groupId>
+    <artifactId>maven-plugin-testing</artifactId>
+    <version>1.0-SNAPSHOT</version>
+
+    <modelVersion>4.0.0</modelVersion>
+    <build>
+        <plugins>
+            <plugin>
+                <artifactId>cayenne-maven-plugin</artifactId>
+                <configuration>
+                    
<map>target/test-classes/org/apache/cayenne/tools/dbimport/testDropProcedure.map.xml</map>
+                    <dataSource>
+                        <driver>org.apache.derby.jdbc.EmbeddedDriver</driver>
+                        
<url>jdbc:derby:memory:DbImporterMojoTest;create=true</url>
+                    </dataSource>
+                    <dbImport>
+                        <includeTable>.*</includeTable>
+                    </dbImport>
+                    <project 
implementation="org.apache.cayenne.stubs.CayenneProjectStub"/>
+                </configuration>
+            </plugin>
+        </plugins>
+    </build>
+
+</project>
\ No newline at end of file
diff --git 
a/maven-plugins/cayenne-maven-plugin/src/test/resources/org/apache/cayenne/tools/dbimport/testDropProcedure.map.xml
 
b/maven-plugins/cayenne-maven-plugin/src/test/resources/org/apache/cayenne/tools/dbimport/testDropProcedure.map.xml
new file mode 100644
index 0000000..9db1d27
--- /dev/null
+++ 
b/maven-plugins/cayenne-maven-plugin/src/test/resources/org/apache/cayenne/tools/dbimport/testDropProcedure.map.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+  ~   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
+  ~
+  ~    https://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.
+  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~-->
+<data-map xmlns="http://cayenne.apache.org/schema/10/modelMap";
+          xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance";
+          xsi:schemaLocation="http://cayenne.apache.org/schema/10/modelMap 
https://cayenne.apache.org/schema/10/modelMap.xsd";
+          project-version="10">
+    <procedure name="PROC" schema="SCHEMA_01"/>
+    <db-entity name="TABLE1" schema="SCHEMA_01">
+        <db-attribute name="ID" type="INTEGER" isPrimaryKey="true" 
isMandatory="true" length="10"/>
+        <db-attribute name="T1_NAME" type="VARCHAR" length="45"/>
+    </db-entity>
+    <obj-entity name="Table1" className="Table1" dbEntityName="TABLE1">
+        <obj-attribute name="t1Name" type="java.lang.String" 
db-attribute-path="T1_NAME"/>
+    </obj-entity>
+</data-map>
\ No newline at end of file
diff --git 
a/maven-plugins/cayenne-maven-plugin/src/test/resources/org/apache/cayenne/tools/dbimport/testDropProcedure.map.xml-result
 
b/maven-plugins/cayenne-maven-plugin/src/test/resources/org/apache/cayenne/tools/dbimport/testDropProcedure.map.xml-result
new file mode 100644
index 0000000..57f4845
--- /dev/null
+++ 
b/maven-plugins/cayenne-maven-plugin/src/test/resources/org/apache/cayenne/tools/dbimport/testDropProcedure.map.xml-result
@@ -0,0 +1,31 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+  ~   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
+  ~
+  ~    https://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.
+  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~-->
+<data-map xmlns="http://cayenne.apache.org/schema/10/modelMap";
+        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance";
+        xsi:schemaLocation="http://cayenne.apache.org/schema/10/modelMap 
https://cayenne.apache.org/schema/10/modelMap.xsd";
+        project-version="10">
+       <db-entity name="TABLE2" schema="SCHEMA_01">
+               <db-attribute name="ID" type="INTEGER" isPrimaryKey="true" 
isMandatory="true" length="10"/>
+               <db-attribute name="T1_NAME" type="VARCHAR" length="45"/>
+       </db-entity>
+       <obj-entity name="Table2" className="Table2" dbEntityName="TABLE2">
+               <obj-attribute name="t1Name" type="java.lang.String" 
db-attribute-path="T1_NAME"/>
+       </obj-entity>
+</data-map>
\ No newline at end of file
diff --git 
a/maven-plugins/cayenne-maven-plugin/src/test/resources/org/apache/cayenne/tools/dbimport/testDropProcedure.sql
 
b/maven-plugins/cayenne-maven-plugin/src/test/resources/org/apache/cayenne/tools/dbimport/testDropProcedure.sql
new file mode 100644
index 0000000..3bb9edf
--- /dev/null
+++ 
b/maven-plugins/cayenne-maven-plugin/src/test/resources/org/apache/cayenne/tools/dbimport/testDropProcedure.sql
@@ -0,0 +1,25 @@
+--  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
+--
+--    https://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.
+
+CREATE SCHEMA schema_01;
+SET SCHEMA schema_01;
+
+CREATE TABLE schema_01.table2 (
+    id INTEGER  NOT NULL,
+    t1_name VARCHAR (45),
+    PRIMARY KEY (id)
+);
\ No newline at end of file
diff --git 
a/maven-plugins/cayenne-maven-plugin/src/test/resources/org/apache/cayenne/tools/dbimport/testImportProcedure-pom.xml
 
b/maven-plugins/cayenne-maven-plugin/src/test/resources/org/apache/cayenne/tools/dbimport/testImportProcedure-pom.xml
new file mode 100644
index 0000000..898872d
--- /dev/null
+++ 
b/maven-plugins/cayenne-maven-plugin/src/test/resources/org/apache/cayenne/tools/dbimport/testImportProcedure-pom.xml
@@ -0,0 +1,51 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+  ~   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
+  ~
+  ~    https://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 xmlns="http://maven.apache.org/POM/4.0.0"; 
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance";
+         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0
+       http://maven.apache.org/xsd/maven-4.0.0.xsd";>
+
+    <name>DbImporterMojo Test1</name>
+    <groupId>org.apache.maven.plugin-testing</groupId>
+    <artifactId>maven-plugin-testing</artifactId>
+    <version>1.0-SNAPSHOT</version>
+
+    <modelVersion>4.0.0</modelVersion>
+    <build>
+        <plugins>
+            <plugin>
+                <artifactId>cayenne-maven-plugin</artifactId>
+                <configuration>
+                    
<map>target/test-classes/org/apache/cayenne/tools/dbimport/testImportProcedure.map.xml</map>
+                    <dataSource>
+                        <driver>org.apache.derby.jdbc.EmbeddedDriver</driver>
+                        
<url>jdbc:derby:memory:DbImporterMojoTest;create=true</url>
+                    </dataSource>
+                    <dbImport>
+                        <includeTable>.*</includeTable>
+                        <includeProcedure>PROC</includeProcedure>
+                    </dbImport>
+                    <project 
implementation="org.apache.cayenne.stubs.CayenneProjectStub"/>
+
+                </configuration>
+            </plugin>
+        </plugins>
+    </build>
+
+</project>
\ No newline at end of file
diff --git 
a/maven-plugins/cayenne-maven-plugin/src/test/resources/org/apache/cayenne/tools/dbimport/testImportProcedure.map.xml
 
b/maven-plugins/cayenne-maven-plugin/src/test/resources/org/apache/cayenne/tools/dbimport/testImportProcedure.map.xml
new file mode 100644
index 0000000..b8fec94
--- /dev/null
+++ 
b/maven-plugins/cayenne-maven-plugin/src/test/resources/org/apache/cayenne/tools/dbimport/testImportProcedure.map.xml
@@ -0,0 +1,31 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+  ~   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
+  ~
+  ~    https://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.
+  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~-->
+<data-map xmlns="http://cayenne.apache.org/schema/10/modelMap";
+          xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance";
+          xsi:schemaLocation="http://cayenne.apache.org/schema/10/modelMap 
https://cayenne.apache.org/schema/10/modelMap.xsd";
+          project-version="10">
+    <db-entity name="TABLE1" schema="SCHEMA_01">
+        <db-attribute name="ID" type="INTEGER" isPrimaryKey="true" 
isMandatory="true" length="10"/>
+        <db-attribute name="T1_NAME" type="VARCHAR" length="45"/>
+    </db-entity>
+    <obj-entity name="Table1" className="Table1" dbEntityName="TABLE1">
+        <obj-attribute name="t1Name" type="java.lang.String" 
db-attribute-path="T1_NAME"/>
+    </obj-entity>
+</data-map>
\ No newline at end of file
diff --git 
a/maven-plugins/cayenne-maven-plugin/src/test/resources/org/apache/cayenne/tools/dbimport/testImportProcedure.map.xml-result
 
b/maven-plugins/cayenne-maven-plugin/src/test/resources/org/apache/cayenne/tools/dbimport/testImportProcedure.map.xml-result
new file mode 100644
index 0000000..6a1d2d9
--- /dev/null
+++ 
b/maven-plugins/cayenne-maven-plugin/src/test/resources/org/apache/cayenne/tools/dbimport/testImportProcedure.map.xml-result
@@ -0,0 +1,35 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+  ~   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
+  ~
+  ~    https://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.
+  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~-->
+<data-map xmlns="http://cayenne.apache.org/schema/10/modelMap";
+        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance";
+        xsi:schemaLocation="http://cayenne.apache.org/schema/10/modelMap 
https://cayenne.apache.org/schema/10/modelMap.xsd";
+        project-version="10">
+       <procedure name="PROC" schema="SCHEMA_01">
+           <procedure-parameter name="TEST" type="INTEGER" length="4" 
direction="in"/>
+       <procedure-parameter name="TOTAL" type="DECIMAL" length="24" 
precision="2" direction="out"/>
+    </procedure>
+       <db-entity name="TABLE2" schema="SCHEMA_01">
+               <db-attribute name="ID" type="INTEGER" isPrimaryKey="true" 
isMandatory="true" length="10"/>
+               <db-attribute name="T1_NAME" type="VARCHAR" length="45"/>
+       </db-entity>
+       <obj-entity name="Table2" className="Table2" dbEntityName="TABLE2">
+               <obj-attribute name="t1Name" type="java.lang.String" 
db-attribute-path="T1_NAME"/>
+       </obj-entity>
+</data-map>
\ No newline at end of file
diff --git 
a/maven-plugins/cayenne-maven-plugin/src/test/resources/org/apache/cayenne/tools/dbimport/testImportProcedure.sql
 
b/maven-plugins/cayenne-maven-plugin/src/test/resources/org/apache/cayenne/tools/dbimport/testImportProcedure.sql
new file mode 100644
index 0000000..55fb31e
--- /dev/null
+++ 
b/maven-plugins/cayenne-maven-plugin/src/test/resources/org/apache/cayenne/tools/dbimport/testImportProcedure.sql
@@ -0,0 +1,29 @@
+--  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
+--
+--    https://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.
+
+CREATE SCHEMA schema_01;
+SET SCHEMA schema_01;
+
+CREATE TABLE schema_01.table2 (
+    id INTEGER  NOT NULL,
+    t1_name VARCHAR (45),
+    PRIMARY KEY (id)
+);
+
+CREATE PROCEDURE PROC(IN test INTEGER, OUT TOTAL DECIMAL(10,2))
+PARAMETER STYLE JAVA READS SQL DATA LANGUAGE JAVA EXTERNAL NAME
+'org.apache.cayenne.test'
\ No newline at end of file
diff --git 
a/maven-plugins/cayenne-maven-plugin/src/test/resources/org/apache/cayenne/tools/dbimport/testSameProcedure-pom.xml
 
b/maven-plugins/cayenne-maven-plugin/src/test/resources/org/apache/cayenne/tools/dbimport/testSameProcedure-pom.xml
new file mode 100644
index 0000000..6f8205d
--- /dev/null
+++ 
b/maven-plugins/cayenne-maven-plugin/src/test/resources/org/apache/cayenne/tools/dbimport/testSameProcedure-pom.xml
@@ -0,0 +1,51 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+  ~   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
+  ~
+  ~    https://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 xmlns="http://maven.apache.org/POM/4.0.0"; 
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance";
+         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0
+       http://maven.apache.org/xsd/maven-4.0.0.xsd";>
+
+    <name>DbImporterMojo Test1</name>
+    <groupId>org.apache.maven.plugin-testing</groupId>
+    <artifactId>maven-plugin-testing</artifactId>
+    <version>1.0-SNAPSHOT</version>
+
+    <modelVersion>4.0.0</modelVersion>
+    <build>
+        <plugins>
+            <plugin>
+                <artifactId>cayenne-maven-plugin</artifactId>
+                <configuration>
+                    
<map>target/test-classes/org/apache/cayenne/tools/dbimport/testSameProcedure.map.xml</map>
+                    <dataSource>
+                        <driver>org.apache.derby.jdbc.EmbeddedDriver</driver>
+                        
<url>jdbc:derby:memory:DbImporterMojoTest;create=true</url>
+                    </dataSource>
+                    <dbImport>
+                        <includeTable>.*</includeTable>
+                        <includeProcedure>PROC</includeProcedure>
+                    </dbImport>
+                    <project 
implementation="org.apache.cayenne.stubs.CayenneProjectStub"/>
+
+                </configuration>
+            </plugin>
+        </plugins>
+    </build>
+
+</project>
\ No newline at end of file
diff --git 
a/maven-plugins/cayenne-maven-plugin/src/test/resources/org/apache/cayenne/tools/dbimport/testSameProcedure.map.xml
 
b/maven-plugins/cayenne-maven-plugin/src/test/resources/org/apache/cayenne/tools/dbimport/testSameProcedure.map.xml
new file mode 100644
index 0000000..9db1d27
--- /dev/null
+++ 
b/maven-plugins/cayenne-maven-plugin/src/test/resources/org/apache/cayenne/tools/dbimport/testSameProcedure.map.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+  ~   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
+  ~
+  ~    https://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.
+  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~-->
+<data-map xmlns="http://cayenne.apache.org/schema/10/modelMap";
+          xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance";
+          xsi:schemaLocation="http://cayenne.apache.org/schema/10/modelMap 
https://cayenne.apache.org/schema/10/modelMap.xsd";
+          project-version="10">
+    <procedure name="PROC" schema="SCHEMA_01"/>
+    <db-entity name="TABLE1" schema="SCHEMA_01">
+        <db-attribute name="ID" type="INTEGER" isPrimaryKey="true" 
isMandatory="true" length="10"/>
+        <db-attribute name="T1_NAME" type="VARCHAR" length="45"/>
+    </db-entity>
+    <obj-entity name="Table1" className="Table1" dbEntityName="TABLE1">
+        <obj-attribute name="t1Name" type="java.lang.String" 
db-attribute-path="T1_NAME"/>
+    </obj-entity>
+</data-map>
\ No newline at end of file
diff --git 
a/maven-plugins/cayenne-maven-plugin/src/test/resources/org/apache/cayenne/tools/dbimport/testSameProcedure.map.xml-result
 
b/maven-plugins/cayenne-maven-plugin/src/test/resources/org/apache/cayenne/tools/dbimport/testSameProcedure.map.xml-result
new file mode 100644
index 0000000..6a1d2d9
--- /dev/null
+++ 
b/maven-plugins/cayenne-maven-plugin/src/test/resources/org/apache/cayenne/tools/dbimport/testSameProcedure.map.xml-result
@@ -0,0 +1,35 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+  ~   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
+  ~
+  ~    https://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.
+  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~-->
+<data-map xmlns="http://cayenne.apache.org/schema/10/modelMap";
+        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance";
+        xsi:schemaLocation="http://cayenne.apache.org/schema/10/modelMap 
https://cayenne.apache.org/schema/10/modelMap.xsd";
+        project-version="10">
+       <procedure name="PROC" schema="SCHEMA_01">
+           <procedure-parameter name="TEST" type="INTEGER" length="4" 
direction="in"/>
+       <procedure-parameter name="TOTAL" type="DECIMAL" length="24" 
precision="2" direction="out"/>
+    </procedure>
+       <db-entity name="TABLE2" schema="SCHEMA_01">
+               <db-attribute name="ID" type="INTEGER" isPrimaryKey="true" 
isMandatory="true" length="10"/>
+               <db-attribute name="T1_NAME" type="VARCHAR" length="45"/>
+       </db-entity>
+       <obj-entity name="Table2" className="Table2" dbEntityName="TABLE2">
+               <obj-attribute name="t1Name" type="java.lang.String" 
db-attribute-path="T1_NAME"/>
+       </obj-entity>
+</data-map>
\ No newline at end of file
diff --git 
a/maven-plugins/cayenne-maven-plugin/src/test/resources/org/apache/cayenne/tools/dbimport/testSameProcedure.sql
 
b/maven-plugins/cayenne-maven-plugin/src/test/resources/org/apache/cayenne/tools/dbimport/testSameProcedure.sql
new file mode 100644
index 0000000..55fb31e
--- /dev/null
+++ 
b/maven-plugins/cayenne-maven-plugin/src/test/resources/org/apache/cayenne/tools/dbimport/testSameProcedure.sql
@@ -0,0 +1,29 @@
+--  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
+--
+--    https://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.
+
+CREATE SCHEMA schema_01;
+SET SCHEMA schema_01;
+
+CREATE TABLE schema_01.table2 (
+    id INTEGER  NOT NULL,
+    t1_name VARCHAR (45),
+    PRIMARY KEY (id)
+);
+
+CREATE PROCEDURE PROC(IN test INTEGER, OUT TOTAL DECIMAL(10,2))
+PARAMETER STYLE JAVA READS SQL DATA LANGUAGE JAVA EXTERNAL NAME
+'org.apache.cayenne.test'
\ No newline at end of file
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 1dd536f..f7b1236 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
@@ -19,8 +19,7 @@
 
 package org.apache.cayenne.modeler.dialog.db.load;
 
-import javax.swing.JDialog;
-import javax.swing.JOptionPane;
+import javax.swing.*;
 import java.awt.event.ComponentAdapter;
 import java.awt.event.ComponentEvent;
 import java.io.IOException;
@@ -37,10 +36,8 @@ import 
org.apache.cayenne.dbsync.merge.factory.MergerTokenFactoryProvider;
 import org.apache.cayenne.dbsync.merge.token.MergerToken;
 import org.apache.cayenne.dbsync.reverse.dbimport.DbImportConfiguration;
 import org.apache.cayenne.dbsync.reverse.dbimport.DefaultDbImportAction;
-import org.apache.cayenne.dbsync.reverse.filters.FiltersConfig;
 import org.apache.cayenne.di.Inject;
 import org.apache.cayenne.map.DataMap;
-import org.apache.cayenne.map.Procedure;
 import org.apache.cayenne.modeler.Application;
 import org.apache.cayenne.modeler.editor.DbImportController;
 import org.apache.cayenne.project.ProjectSaver;
@@ -145,14 +142,6 @@ public class ModelerDbImportAction extends 
DefaultDbImportAction {
     }
 
     @Override
-    protected void addMessageToLogs(String message, List<String> messages) {
-        String formattedMessage = String.format("    %-20s", message);
-        messages.add(formattedMessage);
-        resultDialog.addRowToOutput(formattedMessage, targetMap);
-        hasTokenToMerge = true;
-    }
-
-    @Override
     protected void logMessages(List<String> messages) {
         super.logMessages(messages);
         if (!hasTokenToMerge) {
@@ -170,30 +159,4 @@ public class ModelerDbImportAction extends 
DefaultDbImportAction {
     protected DataMap existingTargetMap(DbImportConfiguration configuration) 
throws IOException {
         return targetMap;
     }
-
-    @Override
-    protected boolean checkIncludedProcedures(DataMap loadedDataMap, 
FiltersConfig filters) {
-        Collection<Procedure> procedures = loadedDataMap.getProcedures();
-        boolean hasProceduresToMerge = false;
-        for (Procedure procedure : procedures) {
-            if(!hasChangesForProcedure(procedure)) {
-               continue;
-            }
-            hasProceduresToMerge = true;
-            Procedure oldProcedure = 
targetMap.getProcedure(procedure.getName());
-
-            String msg = "";
-            if (oldProcedure != null) {
-                msg = "Replace procedure " + procedure.getName();
-            } else {
-                msg = "Create procedure " + procedure.getName();
-            }
-            String formattedMessage = String.format("    %-20s", msg);
-            resultDialog.addRowToOutput(formattedMessage, targetMap);
-        }
-        if(!hasTokenToMerge && !hasProceduresToMerge) {
-            resultDialog.addMsg(targetMap);
-        }
-        return hasProceduresToMerge;
-    }
 }
\ No newline at end of file

Reply via email to