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

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


The following commit(s) were added to refs/heads/master by this push:
     new b8cd91dd940 URLArgumentLine to support multiple expressions on the one 
line (#32817)
b8cd91dd940 is described below

commit b8cd91dd940b09866951d3b49d95d2db60ae3d19
Author: malonglei <[email protected]>
AuthorDate: Thu Sep 12 12:56:05 2024 +0800

    URLArgumentLine to support multiple expressions on the one line (#32817)
    
    * URLArgumentLine to support multiple expressions on the one line
    
    * URLArgumentLine to support multiple expressions on the one line
    
    * URLArgumentLine to support multiple expressions on the one line
    
    * add multiple dynamic placeholders document
---
 .../jdbc-driver/known-implementation/_index.cn.md  | 33 +++++++++++++++++++
 .../jdbc-driver/known-implementation/_index.en.md  | 33 +++++++++++++++++++
 .../infra/url/core/arg/URLArgumentLine.java        | 38 ++++++++++++----------
 .../infra/url/core/arg/URLArgumentLineTest.java    | 24 ++++++++++++++
 4 files changed, 111 insertions(+), 17 deletions(-)

diff --git 
a/docs/document/content/user-manual/shardingsphere-jdbc/yaml-config/jdbc-driver/known-implementation/_index.cn.md
 
b/docs/document/content/user-manual/shardingsphere-jdbc/yaml-config/jdbc-driver/known-implementation/_index.cn.md
index 3156c0990ab..85dd493a0cc 100644
--- 
a/docs/document/content/user-manual/shardingsphere-jdbc/yaml-config/jdbc-driver/known-implementation/_index.cn.md
+++ 
b/docs/document/content/user-manual/shardingsphere-jdbc/yaml-config/jdbc-driver/known-implementation/_index.cn.md
@@ -175,6 +175,39 @@ public class ExampleUtils {
 - `jdbc:shardingsphere:classpath:config.yaml?placeholder-type=system_props`
 - 
`jdbc:shardingsphere:absolutepath:/path/to/config.yaml?placeholder-type=system_props`
 
+### 多个动态占位符
+
+在配置 YAML 属性值的时候,如果 YAML 属性值的部分需要动态替换,可以通过配置多个动态占位符的方式来实现
+
+假设存在以下一组环境变量或系统属性,
+
+1. 存在环境变量或系统属性 `FIXTURE_HOST` 为 `127.0.0.1`。
+2. 存在环境变量或系统属性 `FIXTURE_PORT` 为 `3306`。
+3. 存在环境变量或系统属性 `FIXTURE_DATABASE` 为 `test`。
+4. 存在环境变量或系统属性 `FIXTURE_USERNAME` 为 `sa`。
+
+则对于以下 YAML 文件的截取片段,
+
+```yaml
+ds_1:
+  dataSourceClassName: com.zaxxer.hikari.HikariDataSource
+  driverClassName: $${FIXTURE_DRIVER_CLASS_NAME::com.mysql.cj.jdbc.Driver}
+  jdbcUrl: 
jdbc:mysql://$${FIXTURE_HOST::}:$${FIXTURE_PORT::}/$${FIXTURE_DATABASE::}?useUnicode=true&characterEncoding=UTF-8
+  username: $${FIXTURE_USERNAME::}
+  password: $${FIXTURE_PASSWORD::}
+```
+
+此 YAML 截取片段将被解析为,
+
+```yaml
+ds_1:
+  dataSourceClassName: com.zaxxer.hikari.HikariDataSource
+  driverClassName: com.mysql.cj.jdbc.Driver
+  jdbcUrl: 
jdbc:mysql://127.0.0.1:3306/test?useUnicode=true&characterEncoding=UTF-8
+  username: sa
+  password:
+```
+
 ## 其他实现
 
 具体可参考 https://github.com/apache/shardingsphere-plugin 。
diff --git 
a/docs/document/content/user-manual/shardingsphere-jdbc/yaml-config/jdbc-driver/known-implementation/_index.en.md
 
b/docs/document/content/user-manual/shardingsphere-jdbc/yaml-config/jdbc-driver/known-implementation/_index.en.md
index a46fc6ade51..71f45f804f5 100644
--- 
a/docs/document/content/user-manual/shardingsphere-jdbc/yaml-config/jdbc-driver/known-implementation/_index.en.md
+++ 
b/docs/document/content/user-manual/shardingsphere-jdbc/yaml-config/jdbc-driver/known-implementation/_index.en.md
@@ -193,6 +193,39 @@ Example:
 - `jdbc:shardingsphere:classpath:config.yaml?placeholder-type=system_props`
 - 
`jdbc:shardingsphere:absolutepath:/path/to/config.yaml?placeholder-type=system_props`
 
+### multiple dynamic placeholders
+
+When configuring the value of a YAML attribute, if part of the value of the 
YAML attribute needs to be replaced dynamically, you can implement this by 
configuring multiple dynamic placeholders.
+
+Assume the following set of environment variables or system properties exists,
+
+1. The existing environment variable or system property `FIXTURE_HOST` is 
`127.0.0.1`。
+2. The existing environment variable or system property `FIXTURE_PORT` is 
`3306`。
+3. The existing environment variable or system property `FIXTURE_DATABASE` is 
`test`。
+4. The existing environment variable or system property `FIXTURE_USERNAME` is 
`sa`。
+
+Then for the intercepted fragment of the following YAML file,
+
+```yaml
+ds_1:
+  dataSourceClassName: com.zaxxer.hikari.HikariDataSource
+  driverClassName: $${FIXTURE_DRIVER_CLASS_NAME::com.mysql.cj.jdbc.Driver}
+  jdbcUrl: 
jdbc:mysql://$${FIXTURE_HOST::}:$${FIXTURE_PORT::}/$${FIXTURE_DATABASE::}?useUnicode=true&characterEncoding=UTF-8
+  username: $${FIXTURE_USERNAME::}
+  password: $${FIXTURE_PASSWORD::}
+```
+
+This YAML snippet will be parsed as,
+
+```yaml
+ds_1:
+  dataSourceClassName: com.zaxxer.hikari.HikariDataSource
+  driverClassName: com.mysql.cj.jdbc.Driver
+  jdbcUrl: 
jdbc:mysql://127.0.0.1:3306/test?useUnicode=true&characterEncoding=UTF-8
+  username: sa
+  password:
+```
+
 ## Other implementations
 
 For details, please refer to https://github.com/apache/shardingsphere-plugin.
diff --git 
a/infra/url/core/src/main/java/org/apache/shardingsphere/infra/url/core/arg/URLArgumentLine.java
 
b/infra/url/core/src/main/java/org/apache/shardingsphere/infra/url/core/arg/URLArgumentLine.java
index 3d339a6cfee..fcbd8b1763e 100644
--- 
a/infra/url/core/src/main/java/org/apache/shardingsphere/infra/url/core/arg/URLArgumentLine.java
+++ 
b/infra/url/core/src/main/java/org/apache/shardingsphere/infra/url/core/arg/URLArgumentLine.java
@@ -31,13 +31,7 @@ import java.util.regex.Pattern;
 @RequiredArgsConstructor(access = AccessLevel.PRIVATE)
 public final class URLArgumentLine {
     
-    private static final Pattern PLACEHOLDER_PATTERN = 
Pattern.compile("\\$\\$\\{(.+::.*)}$");
-    
-    private static final String KV_SEPARATOR = "::";
-    
-    private final String argName;
-    
-    private final String argDefaultValue;
+    private static final Pattern PLACEHOLDER_PATTERN = 
Pattern.compile("\\$\\$\\{(.*?)::(.*?)}");
     
     private final Matcher placeholderMatcher;
     
@@ -52,8 +46,7 @@ public final class URLArgumentLine {
         if (!matcher.find()) {
             return Optional.empty();
         }
-        String[] parsedArg = matcher.group(1).split(KV_SEPARATOR, 2);
-        return Optional.of(new URLArgumentLine(parsedArg[0], parsedArg[1], 
matcher));
+        return Optional.of(new URLArgumentLine(matcher));
     }
     
     /**
@@ -63,18 +56,29 @@ public final class URLArgumentLine {
      * @return replaced argument
      */
     public String replaceArgument(final URLArgumentPlaceholderType type) {
-        String argumentValue = getArgumentValue(type);
-        if (!Strings.isNullOrEmpty(argumentValue)) {
-            return placeholderMatcher.replaceAll(argumentValue);
+        placeholderMatcher.reset();
+        StringBuffer result = new StringBuffer();
+        while (placeholderMatcher.find()) {
+            String variableName = placeholderMatcher.group(1);
+            String defaultValue = placeholderMatcher.group(2);
+            String argumentValue = getArgumentValue(variableName, type);
+            if (Strings.isNullOrEmpty(argumentValue)) {
+                argumentValue = defaultValue;
+            }
+            placeholderMatcher.appendReplacement(result, argumentValue);
         }
-        if (!argDefaultValue.isEmpty()) {
-            return placeholderMatcher.replaceAll(argDefaultValue);
+        placeholderMatcher.appendTail(result);
+        return rightTrim(result);
+    }
+    
+    private String rightTrim(final StringBuffer result) {
+        while (result.length() > 0 && 
Character.isWhitespace(result.charAt(result.length() - 1))) {
+            result.deleteCharAt(result.length() - 1);
         }
-        String modifiedLineWithSpace = placeholderMatcher.replaceAll("");
-        return modifiedLineWithSpace.substring(0, 
modifiedLineWithSpace.length() - 1);
+        return result.toString();
     }
     
-    private String getArgumentValue(final URLArgumentPlaceholderType type) {
+    private String getArgumentValue(final String argName, final 
URLArgumentPlaceholderType type) {
         if (URLArgumentPlaceholderType.ENVIRONMENT == type) {
             return System.getenv(argName);
         }
diff --git 
a/infra/url/core/src/test/java/org/apache/shardingsphere/infra/url/core/arg/URLArgumentLineTest.java
 
b/infra/url/core/src/test/java/org/apache/shardingsphere/infra/url/core/arg/URLArgumentLineTest.java
index acd0505683c..898b7f4f084 100644
--- 
a/infra/url/core/src/test/java/org/apache/shardingsphere/infra/url/core/arg/URLArgumentLineTest.java
+++ 
b/infra/url/core/src/test/java/org/apache/shardingsphere/infra/url/core/arg/URLArgumentLineTest.java
@@ -30,6 +30,10 @@ class URLArgumentLineTest {
     
     private final String line = "key=$${value::default_value}";
     
+    private final String lineMultiple1 = 
"key1=$${value1::default_value1}:key2=$${value2::default_value2}:tail";
+    
+    private final String lineMultiple2 = 
"key1=$${value1::}:key2=$${value2::}:tail";
+    
     @Test
     void assertParseWithInvalidPattern() {
         assertFalse(URLArgumentLine.parse("invalid").isPresent());
@@ -38,22 +42,42 @@ class URLArgumentLineTest {
     @Test
     void assertReplaceArgumentWithNone() {
         Optional<URLArgumentLine> argLine = URLArgumentLine.parse(line);
+        Optional<URLArgumentLine> argLineMultiple1 = 
URLArgumentLine.parse(lineMultiple1);
+        Optional<URLArgumentLine> argLineMultiple2 = 
URLArgumentLine.parse(lineMultiple2);
         assertTrue(argLine.isPresent());
+        assertTrue(argLineMultiple1.isPresent());
+        assertTrue(argLineMultiple2.isPresent());
         
assertThat(argLine.get().replaceArgument(URLArgumentPlaceholderType.NONE), 
is("key=default_value"));
+        
assertThat(argLineMultiple1.get().replaceArgument(URLArgumentPlaceholderType.NONE),
 is("key1=default_value1:key2=default_value2:tail"));
+        
assertThat(argLineMultiple2.get().replaceArgument(URLArgumentPlaceholderType.NONE),
 is("key1=:key2=:tail"));
     }
     
     @Test
     void assertReplaceArgumentWithEnvironment() {
         Optional<URLArgumentLine> argLine = URLArgumentLine.parse(line);
+        Optional<URLArgumentLine> argLineMultiple1 = 
URLArgumentLine.parse(lineMultiple1);
+        Optional<URLArgumentLine> argLineMultiple2 = 
URLArgumentLine.parse(lineMultiple2);
         assertTrue(argLine.isPresent());
+        assertTrue(argLineMultiple1.isPresent());
+        assertTrue(argLineMultiple2.isPresent());
         
assertThat(argLine.get().replaceArgument(URLArgumentPlaceholderType.ENVIRONMENT),
 is("key=default_value"));
+        
assertThat(argLineMultiple1.get().replaceArgument(URLArgumentPlaceholderType.ENVIRONMENT),
 is("key1=default_value1:key2=default_value2:tail"));
+        
assertThat(argLineMultiple2.get().replaceArgument(URLArgumentPlaceholderType.ENVIRONMENT),
 is("key1=:key2=:tail"));
     }
     
     @Test
     void assertReplaceArgumentWithSystemProperty() {
         System.setProperty("value", "props_value");
+        System.setProperty("value1", "props_value1");
+        System.setProperty("value2", "props_value2");
         Optional<URLArgumentLine> argLine = URLArgumentLine.parse(line);
+        Optional<URLArgumentLine> argLineMultiple1 = 
URLArgumentLine.parse(lineMultiple1);
+        Optional<URLArgumentLine> argLineMultiple2 = 
URLArgumentLine.parse(lineMultiple2);
         assertTrue(argLine.isPresent());
+        assertTrue(argLineMultiple1.isPresent());
+        assertTrue(argLineMultiple2.isPresent());
         
assertThat(argLine.get().replaceArgument(URLArgumentPlaceholderType.SYSTEM_PROPS),
 is("key=props_value"));
+        
assertThat(argLineMultiple1.get().replaceArgument(URLArgumentPlaceholderType.SYSTEM_PROPS),
 is("key1=props_value1:key2=props_value2:tail"));
+        
assertThat(argLineMultiple2.get().replaceArgument(URLArgumentPlaceholderType.SYSTEM_PROPS),
 is("key1=props_value1:key2=props_value2:tail"));
     }
 }

Reply via email to