Преглед изворни кода

支持过滤条件设置系统参数表达式,如:$getdate()$

Signed-off-by: AE86 <836391306@qq.com>
AE86 пре 1 година
родитељ
комит
99f0c7f899

+ 2 - 0
dbsyncer-common/src/main/java/org/dbsyncer/common/util/StringUtil.java

@@ -12,6 +12,8 @@ public abstract class StringUtil {
 
     public static final String SPACE = " ";
 
+    public static final String SINGLE_QUOTATION = "'";
+
     public static final String FORWARD_SLASH = "/";
 
     public static boolean equals(CharSequence cs1, CharSequence cs2) {

+ 28 - 5
dbsyncer-connector/src/main/java/org/dbsyncer/connector/database/AbstractDatabaseConnector.java

@@ -43,12 +43,19 @@ import java.util.Iterator;
 import java.util.List;
 import java.util.Map;
 import java.util.Set;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
 import java.util.stream.Collectors;
 
 public abstract class AbstractDatabaseConnector extends AbstractConnector implements Connector<DatabaseConnectorMapper, DatabaseConfig>, Database {
 
     private final Logger logger = LoggerFactory.getLogger(getClass());
 
+    /**
+     * 系统函数表达式$select max(update_time)$
+     */
+    private final String SYS_EXPRESSION = "^[$].*[$]$";
+
     @Override
     public ConnectorMapper connect(DatabaseConfig config) {
         try {
@@ -375,14 +382,14 @@ public abstract class AbstractDatabaseConnector extends AbstractConnector implem
         StringBuilder sql = new StringBuilder();
 
         // 拼接并且SQL
-        String addSql = getFilterSql(fieldMap, OperationEnum.AND.getName(), filter);
+        String addSql = buildFilterSql(fieldMap, OperationEnum.AND.getName(), filter);
         // 如果Add条件存在
         if (StringUtil.isNotBlank(addSql)) {
             sql.append(addSql);
         }
 
         // 拼接或者SQL
-        String orSql = getFilterSql(fieldMap, OperationEnum.OR.getName(), filter);
+        String orSql = buildFilterSql(fieldMap, OperationEnum.OR.getName(), filter);
         // 如果Or条件和Add条件都存在
         if (StringUtil.isNotBlank(orSql) && StringUtil.isNotBlank(addSql)) {
             sql.append(" OR ");
@@ -454,7 +461,7 @@ public abstract class AbstractDatabaseConnector extends AbstractConnector implem
      * @param filter
      * @return
      */
-    private String getFilterSql(Map<String, Field> fieldMap, String queryOperator, List<Filter> filter) {
+    private String buildFilterSql(Map<String, Field> fieldMap, String queryOperator, List<Filter> filter) {
         List<Filter> list = filter.stream().filter(f -> StringUtil.equals(f.getOperation(), queryOperator)).collect(Collectors.toList());
         if (CollectionUtils.isEmpty(list)) {
             return "";
@@ -476,8 +483,7 @@ public abstract class AbstractDatabaseConnector extends AbstractConnector implem
             sql.append(quotation);
             sql.append(" ").append(c.getFilter()).append(" ");
             // 如果使用了函数则不加引号
-            String filterValueQuotation = buildSqlFilterWithQuotation(c.getValue());
-            sql.append(filterValueQuotation).append(c.getValue()).append(filterValueQuotation);
+            sql.append(buildFilterValue(c.getValue()));
             if (i < end) {
                 sql.append(" ").append(queryOperator).append(" ");
             }
@@ -486,6 +492,23 @@ public abstract class AbstractDatabaseConnector extends AbstractConnector implem
         return sql.toString();
     }
 
+    /**
+     * 获取条件值引号(如包含系统表达式则排除引号)
+     *
+     * @param value
+     * @return
+     */
+    protected String buildFilterValue(String value) {
+        if (StringUtil.isNotBlank(value)) {
+            // 系统函数表达式 $select max(update_time)$
+            Matcher matcher = Pattern.compile(SYS_EXPRESSION).matcher(value);
+            if (matcher.find()) {
+                return StringUtil.substring(value, 1, value.length() - 1);
+            }
+        }
+        return new StringBuilder(StringUtil.SINGLE_QUOTATION).append(value).append(StringUtil.SINGLE_QUOTATION).toString();
+    }
+
     /**
      * 生成SQL
      *

+ 0 - 11
dbsyncer-connector/src/main/java/org/dbsyncer/connector/database/Database.java

@@ -2,7 +2,6 @@ package org.dbsyncer.connector.database;
 
 import org.dbsyncer.common.util.StringUtil;
 import org.dbsyncer.connector.ConnectorException;
-import org.dbsyncer.connector.config.DatabaseConfig;
 import org.dbsyncer.connector.config.ReaderConfig;
 import org.dbsyncer.connector.model.Field;
 import org.dbsyncer.connector.model.PageSql;
@@ -20,16 +19,6 @@ public interface Database {
         return StringUtil.EMPTY;
     }
 
-    /**
-     * 获取条件值引号
-     *
-     * @param value
-     * @return
-     */
-    default String buildSqlFilterWithQuotation(String value) {
-        return "'";
-    }
-
     /**
      * 获取表名称(可自定义处理系统关键字,函数名)
      *

+ 9 - 3
dbsyncer-connector/src/main/java/org/dbsyncer/connector/oracle/OracleConnector.java

@@ -102,17 +102,23 @@ public final class OracleConnector extends AbstractDatabaseConnector {
         return true;
     }
 
+    /**
+     * TODO 待废弃 推荐使用系统参数表达式$xxx$
+     *
+     * @param value
+     * @return
+     */
     @Override
-    public String buildSqlFilterWithQuotation(String value) {
+    public String buildFilterValue(String value) {
         if (StringUtil.isNotBlank(value)) {
             String val = value.toLowerCase();
             // 支持Oracle系统函数, Example: to_char(sysdate, 'YYYY-MM-DD HH24:MI:SS')
             Matcher matcher = Pattern.compile(SYS_EXPRESSION).matcher(val);
             if (matcher.find()) {
-                return StringUtil.EMPTY;
+                return value;
             }
         }
-        return super.buildSqlFilterWithQuotation(value);
+        return super.buildFilterValue(value);
     }
 
     @Override

+ 11 - 7
dbsyncer-connector/src/main/java/org/dbsyncer/connector/sqlserver/SqlServerConnector.java

@@ -58,13 +58,20 @@ public final class SqlServerConnector extends AbstractDatabaseConnector {
         return new Object[] {(pageIndex - 1) * pageSize + 1, pageIndex * pageSize};
     }
 
+    /**
+     * TODO 待废弃 推荐使用系统参数表达式$xxx$
+     *
+     * @param value
+     * @return
+     */
+    @Deprecated
     @Override
-    public String buildSqlFilterWithQuotation(String value) {
+    public String buildFilterValue(String value) {
         // 支持SqlServer系统函数, Example: (select CONVERT(varchar(10),GETDATE(),120))
         if (containsKeyword(SYS_EXPRESSION, value)) {
-            return StringUtil.EMPTY;
+            return value;
         }
-        return super.buildSqlFilterWithQuotation(value);
+        return super.buildFilterValue(value);
     }
 
     @Override
@@ -118,10 +125,7 @@ public final class SqlServerConnector extends AbstractDatabaseConnector {
      * @return
      */
     private boolean containsKeyword(String val) {
-        if (StringUtil.isNotBlank(val)) {
-            return SYS_FIELDS.contains(val.toLowerCase());
-        }
-        return false;
+        return StringUtil.isNotBlank(val) && SYS_FIELDS.contains(val.toLowerCase());
     }
 
     /**