fix(jdbc): apply url params to connection url

This commit is contained in:
t8y2 2026-06-03 15:59:25 +08:00
parent 175d1def0d
commit 5bd94ba201
2 changed files with 56 additions and 1 deletions

View File

@ -197,7 +197,7 @@ public final class DbxJdbcPlugin {
}
private static Connection openConnection(JsonNode connection) throws SQLException {
String url = jdbcUrlWithPasswordKey(optionalText(connection, "connection_string"), optionalText(connection, "password"));
String url = jdbcUrl(connection);
if (url == null) {
throw new IllegalArgumentException("JDBC URL is required.");
}
@ -585,6 +585,7 @@ public final class DbxJdbcPlugin {
private static String connectionKey(JsonNode connection) {
return optionalText(connection, "connection_string")
+ "|" + optionalText(connection, "url_params")
+ "|" + optionalText(connection, "username")
+ "|" + optionalText(connection, "password")
+ "|" + connection.path("sysdba").asBoolean(false);
@ -616,6 +617,11 @@ public final class DbxJdbcPlugin {
return appendJdbcUrlParam(url, "key", password);
}
static String jdbcUrl(JsonNode connection) {
String url = appendJdbcUrlParams(optionalText(connection, "connection_string"), optionalText(connection, "url_params"));
return jdbcUrlWithPasswordKey(url, optionalText(connection, "password"));
}
private static boolean isSqliteUrl(String url) {
return url.regionMatches(true, 0, "jdbc:sqlite:", 0, 12);
}
@ -646,6 +652,25 @@ public final class DbxJdbcPlugin {
return base + separator + key + "=" + encodedValue + fragment;
}
static String appendJdbcUrlParams(String url, String urlParams) {
if (url == null || urlParams == null || urlParams.isBlank()) {
return url;
}
String params = urlParams.trim();
while (params.startsWith("?") || params.startsWith("&")) {
params = params.substring(1).trim();
}
if (params.isEmpty()) {
return url;
}
int fragmentStart = url.indexOf('#');
String base = fragmentStart < 0 ? url : url.substring(0, fragmentStart);
String fragment = fragmentStart < 0 ? "" : url.substring(fragmentStart);
String separator = base.contains("?") ? (base.endsWith("?") || base.endsWith("&") ? "" : "&") : "?";
return base + separator + params + fragment;
}
private static String oracleEffectiveSchema(Connection conn, String schema) throws SQLException {
if (schema != null && !schema.isBlank()) {
return oracleResolveOwner(conn, schema);

View File

@ -122,6 +122,36 @@ final class DbxJdbcPluginTest {
assertEquals("45", properties.getProperty("connectTimeout"));
}
@Test
void jdbcUrlAppendsConnectionUrlParams() throws Exception {
JsonNode connection = MAPPER.readTree("""
{
"connection_string": "jdbc:kingbase8://db.example.com:54321/demo",
"url_params": "useUnicode=true&characterEncoding=UTF-8"
}
""");
assertEquals(
"jdbc:kingbase8://db.example.com:54321/demo?useUnicode=true&characterEncoding=UTF-8",
DbxJdbcPlugin.jdbcUrl(connection)
);
}
@Test
void jdbcUrlAppendsConnectionUrlParamsBeforeFragment() throws Exception {
JsonNode connection = MAPPER.readTree("""
{
"connection_string": "jdbc:example://db/demo?ssl=true#section",
"url_params": "?characterEncoding=UTF-8"
}
""");
assertEquals(
"jdbc:example://db/demo?ssl=true&characterEncoding=UTF-8#section",
DbxJdbcPlugin.jdbcUrl(connection)
);
}
@Test
void oracleSysdbaIsMappedToInternalLogonProperty() throws Exception {
Method method = DbxJdbcPlugin.class.getDeclaredMethod("applyOracleProperties", JsonNode.class, Properties.class);