From e84f3aae926401e7216684c59b58441e007f82a9 Mon Sep 17 00:00:00 2001
From: vran <vran_dev@foxmail.com>
Date: Sat, 12 Mar 2022 12:39:21 +0800
Subject: [PATCH] feat: support database, schema config

---
 .../api/validator/DatabaseTypeValidator.java        | 13 +++++++------
 .../document/converter/DocumentPojoConverter.java   |  1 +
 .../document/data/DatabaseDocumentResponse.java     |  2 ++
 .../data/DatabaseDocumentSimpleResponse.java        |  2 ++
 .../domain/document/service/DocumentService.java    |  2 +-
 .../domain/project/data/ProjectCreateRequest.java   |  3 +++
 .../domain/project/data/ProjectDetailResponse.java  |  2 ++
 .../domain/project/data/ProjectListCondition.java   |  6 ++++++
 .../domain/project/data/ProjectSimpleResponse.java  |  2 ++
 .../project/data/ProjectTestConnectionRequest.java  |  3 +++
 .../domain/project/data/ProjectUpdateRequest.java   |  3 +++
 .../core/domain/project/service/ProjectService.java |  1 +
 .../connection/CustomDatabaseConnectionFactory.java |  3 ++-
 .../connection/DatabaseConnectionFactory.java       |  4 +++-
 .../connection/DatabaseConnectionService.java       |  7 +++++--
 .../connection/MysqlDatabaseConnectionFactory.java  |  2 +-
 .../PostgresqlDatabaseConnectionFactory.java        |  2 +-
 .../src/main/java/com/databasir/core/Databasir.java |  3 ++-
 .../com/databasir/core/meta/data/DatabaseMeta.java  |  5 +++++
 .../core/meta/repository/condition/Condition.java   |  2 ++
 .../impl/jdbc/JdbcDatabaseMetaRepository.java       |  1 +
 .../impl/jdbc/JdbcTableMetaRepository.java          |  2 +-
 22 files changed, 56 insertions(+), 15 deletions(-)

diff --git a/api/src/main/java/com/databasir/api/validator/DatabaseTypeValidator.java b/api/src/main/java/com/databasir/api/validator/DatabaseTypeValidator.java
index f6fcbf5..de5c249 100644
--- a/api/src/main/java/com/databasir/api/validator/DatabaseTypeValidator.java
+++ b/api/src/main/java/com/databasir/api/validator/DatabaseTypeValidator.java
@@ -1,23 +1,24 @@
 package com.databasir.api.validator;
 
-import com.databasir.core.domain.DomainErrors;
 import org.springframework.stereotype.Component;
 
+import static com.databasir.core.domain.DomainErrors.INVALID_DATABASE_TYPE_URL_PATTERN;
+
 @Component
 public class DatabaseTypeValidator {
 
     public void isValidUrlPattern(String urlPattern) {
         if (urlPattern == null) {
-            throw DomainErrors.INVALID_DATABASE_TYPE_URL_PATTERN.exception("url pattern 不能为空");
+            throw INVALID_DATABASE_TYPE_URL_PATTERN.exception("url pattern 不能为空");
         }
         if (!urlPattern.contains("{{jdbc.protocol}}")) {
-            throw DomainErrors.INVALID_DATABASE_TYPE_URL_PATTERN.exception("必须包含变量{{jdbc.protocol}}");
+            throw INVALID_DATABASE_TYPE_URL_PATTERN.exception("必须包含变量{{jdbc.protocol}}");
         }
         if (!urlPattern.contains("{{db.url}}")) {
-            throw DomainErrors.INVALID_DATABASE_TYPE_URL_PATTERN.exception("必须包含变量{{db.url}}不能为空");
+            throw INVALID_DATABASE_TYPE_URL_PATTERN.exception("必须包含变量{{db.url}}不能为空");
         }
-        if (!urlPattern.contains("{{db.name}}")) {
-            throw DomainErrors.INVALID_DATABASE_TYPE_URL_PATTERN.exception("必须包含变量{{db.name}}不能为空");
+        if (!urlPattern.contains("{{db.schema}}") && !urlPattern.contains("{{db.name}}")) {
+            throw INVALID_DATABASE_TYPE_URL_PATTERN.exception("{{db.schema}} 和 {{db.name}} 至少设置一个");
         }
     }
 }
diff --git a/core/src/main/java/com/databasir/core/domain/document/converter/DocumentPojoConverter.java b/core/src/main/java/com/databasir/core/domain/document/converter/DocumentPojoConverter.java
index fac7df8..5b3de08 100644
--- a/core/src/main/java/com/databasir/core/domain/document/converter/DocumentPojoConverter.java
+++ b/core/src/main/java/com/databasir/core/domain/document/converter/DocumentPojoConverter.java
@@ -16,6 +16,7 @@ import java.util.stream.Collectors;
 public interface DocumentPojoConverter extends BaseConverter {
 
     @Mapping(target = "databaseName", source = "meta.databaseName")
+    @Mapping(target = "schemaName", source = "meta.schemaName")
     @Mapping(target = "isArchive", constant = "false")
     DatabaseDocumentPojo toDatabasePojo(Integer projectId,
                                         com.databasir.core.meta.data.DatabaseMeta meta,
diff --git a/core/src/main/java/com/databasir/core/domain/document/data/DatabaseDocumentResponse.java b/core/src/main/java/com/databasir/core/domain/document/data/DatabaseDocumentResponse.java
index e7d446e..ba8fafb 100644
--- a/core/src/main/java/com/databasir/core/domain/document/data/DatabaseDocumentResponse.java
+++ b/core/src/main/java/com/databasir/core/domain/document/data/DatabaseDocumentResponse.java
@@ -19,6 +19,8 @@ public class DatabaseDocumentResponse {
 
     private String databaseName;
 
+    private String schemaName;
+
     private String productName;
 
     private String productVersion;
diff --git a/core/src/main/java/com/databasir/core/domain/document/data/DatabaseDocumentSimpleResponse.java b/core/src/main/java/com/databasir/core/domain/document/data/DatabaseDocumentSimpleResponse.java
index 9be02e4..ab10038 100644
--- a/core/src/main/java/com/databasir/core/domain/document/data/DatabaseDocumentSimpleResponse.java
+++ b/core/src/main/java/com/databasir/core/domain/document/data/DatabaseDocumentSimpleResponse.java
@@ -13,6 +13,8 @@ public class DatabaseDocumentSimpleResponse {
 
     private String databaseName;
 
+    private String schemaName;
+
     private String productName;
 
     private String productVersion;
diff --git a/core/src/main/java/com/databasir/core/domain/document/service/DocumentService.java b/core/src/main/java/com/databasir/core/domain/document/service/DocumentService.java
index 8aa21d2..a446f87 100644
--- a/core/src/main/java/com/databasir/core/domain/document/service/DocumentService.java
+++ b/core/src/main/java/com/databasir/core/domain/document/service/DocumentService.java
@@ -89,7 +89,7 @@ public class DocumentService {
         databasirConfig.setIgnoreTableNameRegex(jsonConverter.fromJson(rule.getIgnoreTableNameRegexArray()));
         databasirConfig.setIgnoreTableColumnNameRegex(jsonConverter.fromJson(rule.getIgnoreColumnNameRegexArray()));
         return Databasir.of(databasirConfig)
-                .get(jdbcConnection, dataSource.getDatabaseName())
+                .get(jdbcConnection, dataSource.getDatabaseName(), dataSource.getSchemaName())
                 .orElseThrow(DomainErrors.DATABASE_META_NOT_FOUND::exception);
     }
 
diff --git a/core/src/main/java/com/databasir/core/domain/project/data/ProjectCreateRequest.java b/core/src/main/java/com/databasir/core/domain/project/data/ProjectCreateRequest.java
index f2d0ee0..45e6214 100644
--- a/core/src/main/java/com/databasir/core/domain/project/data/ProjectCreateRequest.java
+++ b/core/src/main/java/com/databasir/core/domain/project/data/ProjectCreateRequest.java
@@ -40,6 +40,9 @@ public class ProjectCreateRequest {
         @NotBlank
         private String databaseName;
 
+        @NotBlank
+        private String schemaName;
+
         @NotBlank
         private String databaseType;
 
diff --git a/core/src/main/java/com/databasir/core/domain/project/data/ProjectDetailResponse.java b/core/src/main/java/com/databasir/core/domain/project/data/ProjectDetailResponse.java
index 5776654..08c418c 100644
--- a/core/src/main/java/com/databasir/core/domain/project/data/ProjectDetailResponse.java
+++ b/core/src/main/java/com/databasir/core/domain/project/data/ProjectDetailResponse.java
@@ -34,6 +34,8 @@ public class ProjectDetailResponse {
 
         private String databaseName;
 
+        private String schemaName;
+
         private String databaseType;
 
         private List<DataSourcePropertyValue> properties = new ArrayList<>();
diff --git a/core/src/main/java/com/databasir/core/domain/project/data/ProjectListCondition.java b/core/src/main/java/com/databasir/core/domain/project/data/ProjectListCondition.java
index cbf1fc0..5050738 100644
--- a/core/src/main/java/com/databasir/core/domain/project/data/ProjectListCondition.java
+++ b/core/src/main/java/com/databasir/core/domain/project/data/ProjectListCondition.java
@@ -15,6 +15,8 @@ public class ProjectListCondition {
 
     private String databaseNameContains;
 
+    private String schemaNameContains;
+
     private String databaseType;
 
     private Integer groupId;
@@ -29,6 +31,10 @@ public class ProjectListCondition {
             Condition condition = Tables.DATA_SOURCE.DATABASE_NAME.contains(databaseNameContains);
             conditions.add(condition);
         }
+        if (schemaNameContains != null) {
+            Condition condition = Tables.DATA_SOURCE.SCHEMA_NAME.contains(schemaNameContains);
+            conditions.add(condition);
+        }
         if (databaseType != null) {
             Condition condition = Tables.DATA_SOURCE.DATABASE_TYPE.eq(databaseType);
             conditions.add(condition);
diff --git a/core/src/main/java/com/databasir/core/domain/project/data/ProjectSimpleResponse.java b/core/src/main/java/com/databasir/core/domain/project/data/ProjectSimpleResponse.java
index 4aedc43..50a54c7 100644
--- a/core/src/main/java/com/databasir/core/domain/project/data/ProjectSimpleResponse.java
+++ b/core/src/main/java/com/databasir/core/domain/project/data/ProjectSimpleResponse.java
@@ -15,6 +15,8 @@ public class ProjectSimpleResponse {
 
     private String databaseName;
 
+    private String schemaName;
+
     private String databaseType;
 
     private Boolean isAutoSync;
diff --git a/core/src/main/java/com/databasir/core/domain/project/data/ProjectTestConnectionRequest.java b/core/src/main/java/com/databasir/core/domain/project/data/ProjectTestConnectionRequest.java
index 81030ac..a2001d7 100644
--- a/core/src/main/java/com/databasir/core/domain/project/data/ProjectTestConnectionRequest.java
+++ b/core/src/main/java/com/databasir/core/domain/project/data/ProjectTestConnectionRequest.java
@@ -22,6 +22,9 @@ public class ProjectTestConnectionRequest {
     @NotBlank
     private String databaseName;
 
+    @NotBlank
+    private String schemaName;
+
     @NotBlank
     private String databaseType;
 
diff --git a/core/src/main/java/com/databasir/core/domain/project/data/ProjectUpdateRequest.java b/core/src/main/java/com/databasir/core/domain/project/data/ProjectUpdateRequest.java
index fb88995..715ce6b 100644
--- a/core/src/main/java/com/databasir/core/domain/project/data/ProjectUpdateRequest.java
+++ b/core/src/main/java/com/databasir/core/domain/project/data/ProjectUpdateRequest.java
@@ -39,6 +39,9 @@ public class ProjectUpdateRequest {
         @NotBlank
         private String databaseName;
 
+        @NotBlank
+        private String schemaName;
+
         @NotBlank
         private String databaseType;
 
diff --git a/core/src/main/java/com/databasir/core/domain/project/service/ProjectService.java b/core/src/main/java/com/databasir/core/domain/project/service/ProjectService.java
index 3eac60f..7e85452 100644
--- a/core/src/main/java/com/databasir/core/domain/project/service/ProjectService.java
+++ b/core/src/main/java/com/databasir/core/domain/project/service/ProjectService.java
@@ -169,6 +169,7 @@ public class ProjectService {
                 password,
                 request.getUrl(),
                 request.getDatabaseName(),
+                request.getSchemaName(),
                 request.getDatabaseType(),
                 properties);
     }
diff --git a/core/src/main/java/com/databasir/core/infrastructure/connection/CustomDatabaseConnectionFactory.java b/core/src/main/java/com/databasir/core/infrastructure/connection/CustomDatabaseConnectionFactory.java
index b850c64..e61a1e8 100644
--- a/core/src/main/java/com/databasir/core/infrastructure/connection/CustomDatabaseConnectionFactory.java
+++ b/core/src/main/java/com/databasir/core/infrastructure/connection/CustomDatabaseConnectionFactory.java
@@ -78,7 +78,8 @@ public class CustomDatabaseConnectionFactory implements DatabaseConnectionFactor
         String urlPattern = type.getUrlPattern();
         String jdbcUrl = urlPattern.replace("{{jdbc.protocol}}", type.getJdbcProtocol())
                 .replace("{{db.url}}", context.getUrl())
-                .replace("{{db.name}}", context.getSchema());
+                .replace("{{db.name}}", context.getDatabaseName())
+                .replace("{{db.schema}}", context.getSchemaName());
         Properties info = new Properties();
         info.put("user", context.getUsername());
         info.put("password", context.getPassword());
diff --git a/core/src/main/java/com/databasir/core/infrastructure/connection/DatabaseConnectionFactory.java b/core/src/main/java/com/databasir/core/infrastructure/connection/DatabaseConnectionFactory.java
index 87daeca..99c3be9 100644
--- a/core/src/main/java/com/databasir/core/infrastructure/connection/DatabaseConnectionFactory.java
+++ b/core/src/main/java/com/databasir/core/infrastructure/connection/DatabaseConnectionFactory.java
@@ -25,7 +25,9 @@ public interface DatabaseConnectionFactory {
 
         private String url;
 
-        private String schema;
+        private String databaseName;
+
+        private String schemaName;
 
         private Properties properties;
     }
diff --git a/core/src/main/java/com/databasir/core/infrastructure/connection/DatabaseConnectionService.java b/core/src/main/java/com/databasir/core/infrastructure/connection/DatabaseConnectionService.java
index f89e578..d1234c8 100644
--- a/core/src/main/java/com/databasir/core/infrastructure/connection/DatabaseConnectionService.java
+++ b/core/src/main/java/com/databasir/core/infrastructure/connection/DatabaseConnectionService.java
@@ -36,7 +36,8 @@ public class DatabaseConnectionService {
                     .username(username)
                     .password(password)
                     .url(url)
-                    .schema(dataSource.getDatabaseName())
+                    .databaseName(dataSource.getDatabaseName())
+                    .schemaName(dataSource.getSchemaName())
                     .properties(info)
                     .databaseType(dataSource.getDatabaseType())
                     .build();
@@ -54,6 +55,7 @@ public class DatabaseConnectionService {
                                String password,
                                String url,
                                String databaseName,
+                               String schemaName,
                                String databaseType,
                                Properties properties) {
         try {
@@ -61,7 +63,8 @@ public class DatabaseConnectionService {
                     .username(username)
                     .password(password)
                     .url(url)
-                    .schema(databaseName)
+                    .databaseName(databaseName)
+                    .schemaName(schemaName)
                     .properties(properties)
                     .databaseType(databaseType)
                     .build();
diff --git a/core/src/main/java/com/databasir/core/infrastructure/connection/MysqlDatabaseConnectionFactory.java b/core/src/main/java/com/databasir/core/infrastructure/connection/MysqlDatabaseConnectionFactory.java
index 851e839..cf8a667 100644
--- a/core/src/main/java/com/databasir/core/infrastructure/connection/MysqlDatabaseConnectionFactory.java
+++ b/core/src/main/java/com/databasir/core/infrastructure/connection/MysqlDatabaseConnectionFactory.java
@@ -29,7 +29,7 @@ public class MysqlDatabaseConnectionFactory implements DatabaseConnectionFactory
         info.put("user", context.getUsername());
         info.put("password", context.getPassword());
         info.putAll(context.getProperties());
-        String jdbcUrl = "jdbc:mysql://" + context.getUrl() + "/" + context.getSchema();
+        String jdbcUrl = "jdbc:mysql://" + context.getUrl() + "/" + context.getDatabaseName();
         return DriverManager.getConnection(jdbcUrl, info);
     }
 
diff --git a/core/src/main/java/com/databasir/core/infrastructure/connection/PostgresqlDatabaseConnectionFactory.java b/core/src/main/java/com/databasir/core/infrastructure/connection/PostgresqlDatabaseConnectionFactory.java
index ca43484..d22abe8 100644
--- a/core/src/main/java/com/databasir/core/infrastructure/connection/PostgresqlDatabaseConnectionFactory.java
+++ b/core/src/main/java/com/databasir/core/infrastructure/connection/PostgresqlDatabaseConnectionFactory.java
@@ -29,7 +29,7 @@ public class PostgresqlDatabaseConnectionFactory implements DatabaseConnectionFa
         info.put("user", context.getUsername());
         info.put("password", context.getPassword());
         info.putAll(context.getProperties());
-        String jdbcUrl = "jdbc:postgresql://" + context.getUrl() + "/" + context.getSchema();
+        String jdbcUrl = "jdbc:postgresql://" + context.getUrl() + "/" + context.getDatabaseName();
         return DriverManager.getConnection(jdbcUrl, info);
     }
 }
diff --git a/plugin/src/main/java/com/databasir/core/Databasir.java b/plugin/src/main/java/com/databasir/core/Databasir.java
index 046c535..a30bb38 100644
--- a/plugin/src/main/java/com/databasir/core/Databasir.java
+++ b/plugin/src/main/java/com/databasir/core/Databasir.java
@@ -20,9 +20,10 @@ public class Databasir {
 
     private final DatabasirConfig config;
 
-    public Optional<DatabaseMeta> get(Connection connection, String databaseName) {
+    public Optional<DatabaseMeta> get(Connection connection, String databaseName, String schemaName) {
         Condition condition = Condition.builder()
                 .databaseName(databaseName)
+                .schemaName(schemaName)
                 .ignoreTableNameRegex(config.getIgnoreTableNameRegex())
                 .ignoreTableColumnNameRegex(config.getIgnoreTableColumnNameRegex())
                 .build();
diff --git a/plugin/src/main/java/com/databasir/core/meta/data/DatabaseMeta.java b/plugin/src/main/java/com/databasir/core/meta/data/DatabaseMeta.java
index 331ea15..13091fa 100644
--- a/plugin/src/main/java/com/databasir/core/meta/data/DatabaseMeta.java
+++ b/plugin/src/main/java/com/databasir/core/meta/data/DatabaseMeta.java
@@ -35,6 +35,11 @@ public class DatabaseMeta {
      */
     private String databaseName;
 
+    /**
+     * schema_name
+     */
+    private String schemaName;
+
     @Builder.Default
     private List<TableMeta> tables = Collections.emptyList();
 
diff --git a/plugin/src/main/java/com/databasir/core/meta/repository/condition/Condition.java b/plugin/src/main/java/com/databasir/core/meta/repository/condition/Condition.java
index 9e83edb..0d962fa 100644
--- a/plugin/src/main/java/com/databasir/core/meta/repository/condition/Condition.java
+++ b/plugin/src/main/java/com/databasir/core/meta/repository/condition/Condition.java
@@ -16,6 +16,8 @@ public class Condition {
     @NonNull
     private String databaseName;
 
+    private String schemaName;
+
     @Builder.Default
     private Collection<String> ignoreTableNameRegex = Collections.emptyList();
 
diff --git a/plugin/src/main/java/com/databasir/core/meta/repository/impl/jdbc/JdbcDatabaseMetaRepository.java b/plugin/src/main/java/com/databasir/core/meta/repository/impl/jdbc/JdbcDatabaseMetaRepository.java
index dfe20e4..ebce9ab 100644
--- a/plugin/src/main/java/com/databasir/core/meta/repository/impl/jdbc/JdbcDatabaseMetaRepository.java
+++ b/plugin/src/main/java/com/databasir/core/meta/repository/impl/jdbc/JdbcDatabaseMetaRepository.java
@@ -33,6 +33,7 @@ public class JdbcDatabaseMetaRepository implements DatabaseMetaRepository {
                             .productName(metaData.getDatabaseProductName())
                             .productVersion(metaData.getDatabaseProductVersion())
                             .databaseName(catalogName)
+                            .schemaName(condition.getSchemaName())
                             .tables(tableDocs)
                             .build();
                     return Optional.of(meta);
diff --git a/plugin/src/main/java/com/databasir/core/meta/repository/impl/jdbc/JdbcTableMetaRepository.java b/plugin/src/main/java/com/databasir/core/meta/repository/impl/jdbc/JdbcTableMetaRepository.java
index 8c107ab..fe96cad 100644
--- a/plugin/src/main/java/com/databasir/core/meta/repository/impl/jdbc/JdbcTableMetaRepository.java
+++ b/plugin/src/main/java/com/databasir/core/meta/repository/impl/jdbc/JdbcTableMetaRepository.java
@@ -40,7 +40,7 @@ public class JdbcTableMetaRepository implements TableMetaRepository {
         List<TableMeta> tableMetas = new ArrayList<>();
         String databaseName = condition.getDatabaseName();
         ResultSet tablesResult = connection.getMetaData()
-                .getTables(databaseName, null, null, new String[]{"TABLE"});
+                .getTables(databaseName, condition.getSchemaName(), null, new String[]{"TABLE"});
         while (tablesResult.next()) {
             String tableName = tablesResult.getString("TABLE_NAME");
             if (condition.tableIsIgnored(tableName)) {