diff --git a/clickhouse-data/src/main/java/com/clickhouse/data/ClickHouseUtils.java b/clickhouse-data/src/main/java/com/clickhouse/data/ClickHouseUtils.java index d3f08d4a8..25a648773 100644 --- a/clickhouse-data/src/main/java/com/clickhouse/data/ClickHouseUtils.java +++ b/clickhouse-data/src/main/java/com/clickhouse/data/ClickHouseUtils.java @@ -85,6 +85,25 @@ public final class ClickHouseUtils { public static final String VARIABLE_PREFIX = "{{"; public static final String VARIABLE_SUFFIX = "}}"; + /** + * Parses a boolean value from string. Accepts "true"/"false" and "1"/"0". + * + * @param value string value + * @return parsed boolean, or {@code false} if value is null or unrecognized + */ + public static boolean parseBoolean(String value) { + if (value == null) { + return false; + } + if ("1".equals(value)) { + return true; + } + if ("0".equals(value)) { + return false; + } + return Boolean.parseBoolean(value); + } + private static T findFirstService(Class serviceInterface) { ClickHouseChecker.nonNull(serviceInterface, "serviceInterface"); diff --git a/clickhouse-data/src/test/java/com/clickhouse/data/ClickHouseUtilsTest.java b/clickhouse-data/src/test/java/com/clickhouse/data/ClickHouseUtilsTest.java index d4eb68e80..fd61ef9f3 100644 --- a/clickhouse-data/src/test/java/com/clickhouse/data/ClickHouseUtilsTest.java +++ b/clickhouse-data/src/test/java/com/clickhouse/data/ClickHouseUtilsTest.java @@ -20,6 +20,20 @@ import org.testng.annotations.Test; public class ClickHouseUtilsTest { + @Test(groups = { "unit" }) + public void testParseBoolean() { + Assert.assertFalse(ClickHouseUtils.parseBoolean(null)); + + Assert.assertTrue(ClickHouseUtils.parseBoolean("1")); + Assert.assertFalse(ClickHouseUtils.parseBoolean("0")); + + Assert.assertTrue(ClickHouseUtils.parseBoolean("true")); + Assert.assertFalse(ClickHouseUtils.parseBoolean("false")); + + // unrecognized values should be parsed as false + Assert.assertFalse(ClickHouseUtils.parseBoolean("yes")); + } + @Test(groups = { "unit" }) public void testCreateTempFile() throws IOException { File f = ClickHouseUtils.createTempFile(null, null); diff --git a/client-v2/src/main/java/com/clickhouse/client/api/ClientConfigProperties.java b/client-v2/src/main/java/com/clickhouse/client/api/ClientConfigProperties.java index 5a23f91ba..f207ff7af 100644 --- a/client-v2/src/main/java/com/clickhouse/client/api/ClientConfigProperties.java +++ b/client-v2/src/main/java/com/clickhouse/client/api/ClientConfigProperties.java @@ -9,6 +9,7 @@ import java.util.ArrayList; import java.util.Arrays; +import com.clickhouse.data.ClickHouseUtils; import java.util.Collection; import java.util.Collections; import java.util.HashMap; @@ -270,6 +271,10 @@ public static List valuesFromCommaSeparated(String value) { .collect(Collectors.toList()); } + /** + * Parses a string value into the configured property type. + * Boolean values accept "true"/"false" and "1"/"0". + */ public Object parseValue(String value) { if (value == null) { return null; @@ -280,9 +285,7 @@ public Object parseValue(String value) { } if (valueType.equals(Boolean.class)) { - if (value.equals("1")) return true; - if (value.equals("0")) return false; - return Boolean.parseBoolean(value); + return ClickHouseUtils.parseBoolean(value); } if (valueType.equals(Integer.class)) { diff --git a/client-v2/src/main/java/com/clickhouse/client/api/data_formats/internal/SerializerUtils.java b/client-v2/src/main/java/com/clickhouse/client/api/data_formats/internal/SerializerUtils.java index 54c1e93a8..be8df2603 100644 --- a/client-v2/src/main/java/com/clickhouse/client/api/data_formats/internal/SerializerUtils.java +++ b/client-v2/src/main/java/com/clickhouse/client/api/data_formats/internal/SerializerUtils.java @@ -1,6 +1,7 @@ package com.clickhouse.client.api.data_formats.internal; import com.clickhouse.client.api.Client; +import com.clickhouse.data.ClickHouseUtils; import com.clickhouse.client.api.ClientException; import com.clickhouse.client.api.serde.POJOFieldDeserializer; import com.clickhouse.data.ClickHouseAggregateFunction; @@ -817,7 +818,7 @@ public static boolean convertToBoolean(Object value) { } else if (value instanceof Number) { return ((Number) value).longValue() != 0; } else if (value instanceof String) { - return Boolean.parseBoolean((String) value); + return ClickHouseUtils.parseBoolean((String) value); } else { throw new IllegalArgumentException("Cannot convert " + value + " to Boolean"); } diff --git a/client-v2/src/main/java/com/clickhouse/client/api/data_formats/internal/ValueConverters.java b/client-v2/src/main/java/com/clickhouse/client/api/data_formats/internal/ValueConverters.java index e94283cf9..e6553165c 100644 --- a/client-v2/src/main/java/com/clickhouse/client/api/data_formats/internal/ValueConverters.java +++ b/client-v2/src/main/java/com/clickhouse/client/api/data_formats/internal/ValueConverters.java @@ -5,6 +5,7 @@ import java.math.BigDecimal; import java.math.BigInteger; import java.net.MalformedURLException; +import com.clickhouse.data.ClickHouseUtils; import java.net.URL; import java.sql.Date; import java.sql.Time; @@ -137,7 +138,7 @@ public byte[] convertStringToBytes(Object value) { } public boolean convertStringToBoolean(Object value) { - return Boolean.parseBoolean((String) value); + return ClickHouseUtils.parseBoolean((String) value); } public byte convertStringToByte(Object value) { diff --git a/client-v2/src/test/java/com/clickhouse/client/api/ClientConfigPropertiesTest.java b/client-v2/src/test/java/com/clickhouse/client/api/ClientConfigPropertiesTest.java index f805ee65b..26f94bf81 100644 --- a/client-v2/src/test/java/com/clickhouse/client/api/ClientConfigPropertiesTest.java +++ b/client-v2/src/test/java/com/clickhouse/client/api/ClientConfigPropertiesTest.java @@ -1,5 +1,28 @@ package com.clickhouse.client.api; +import org.testng.Assert; +import org.testng.annotations.Test; + +public class ClientConfigPropertiesTest { + + @Test + public void testBooleanParseValue() { + // HTTP_USE_BASIC_AUTH is defined as Boolean.class + Object v1 = ClientConfigProperties.HTTP_USE_BASIC_AUTH.parseValue("1"); + Assert.assertTrue(v1 instanceof Boolean && (Boolean) v1); + + Object v0 = ClientConfigProperties.HTTP_USE_BASIC_AUTH.parseValue("0"); + Assert.assertTrue(v0 instanceof Boolean && !((Boolean) v0)); + + Object vt = ClientConfigProperties.HTTP_USE_BASIC_AUTH.parseValue("true"); + Assert.assertTrue(vt instanceof Boolean && (Boolean) vt); + + Object vf = ClientConfigProperties.HTTP_USE_BASIC_AUTH.parseValue("false"); + Assert.assertTrue(vf instanceof Boolean && !((Boolean) vf)); + } +} +package com.clickhouse.client.api; + import org.testng.Assert; import org.testng.annotations.Test; diff --git a/client-v2/src/test/java/com/clickhouse/client/api/data_formats/internal/ValueConvertersTest.java b/client-v2/src/test/java/com/clickhouse/client/api/data_formats/internal/ValueConvertersTest.java new file mode 100644 index 000000000..8d89db49a --- /dev/null +++ b/client-v2/src/test/java/com/clickhouse/client/api/data_formats/internal/ValueConvertersTest.java @@ -0,0 +1,16 @@ +package com.clickhouse.client.api.data_formats.internal; + +import org.testng.Assert; +import org.testng.annotations.Test; + +public class ValueConvertersTest { + + @Test + public void testConvertStringToBoolean() { + ValueConverters vc = new ValueConverters(); + Assert.assertTrue(vc.convertStringToBoolean("1")); + Assert.assertFalse(vc.convertStringToBoolean("0")); + Assert.assertTrue(vc.convertStringToBoolean("true")); + Assert.assertFalse(vc.convertStringToBoolean("false")); + } +} diff --git a/jdbc-v2/src/main/java/com/clickhouse/jdbc/internal/JdbcConfiguration.java b/jdbc-v2/src/main/java/com/clickhouse/jdbc/internal/JdbcConfiguration.java index 21d05a552..5ecb2b8ca 100644 --- a/jdbc-v2/src/main/java/com/clickhouse/jdbc/internal/JdbcConfiguration.java +++ b/jdbc-v2/src/main/java/com/clickhouse/jdbc/internal/JdbcConfiguration.java @@ -4,6 +4,7 @@ import com.clickhouse.client.api.ClientConfigProperties; import com.clickhouse.client.api.http.ClickHouseHttpProto; import com.clickhouse.data.ClickHouseDataType; +import com.clickhouse.data.ClickHouseUtils; import com.clickhouse.jdbc.Driver; import com.clickhouse.jdbc.DriverProperties; import com.google.common.collect.ImmutableMap; @@ -80,7 +81,8 @@ public boolean isIgnoreUnsupportedRequests() { */ public JdbcConfiguration(String url, Properties info) throws SQLException { final Properties props = info == null ? new Properties() : info; - this.disableFrameworkDetection = Boolean.parseBoolean(props.getProperty("disable_frameworks_detection", "false")); + this.disableFrameworkDetection = ClickHouseUtils.parseBoolean( + props.getProperty("disable_frameworks_detection", "false")); this.clientProperties = new HashMap<>(); this.driverProperties = new HashMap<>(); @@ -92,8 +94,10 @@ public JdbcConfiguration(String url, Properties info) throws SQLException { initProperties(urlProperties, props); // after initializing all properties - set final connection URL - boolean useSSLInfo = Boolean.parseBoolean(props.getProperty(DriverProperties.SECURE_CONNECTION.getKey(), "false")); - boolean useSSLUrlProperties = Boolean.parseBoolean(urlProperties.getOrDefault(DriverProperties.SECURE_CONNECTION.getKey(), "false")); + boolean useSSLInfo = ClickHouseUtils.parseBoolean( + props.getProperty(DriverProperties.SECURE_CONNECTION.getKey(), "false")); + boolean useSSLUrlProperties = ClickHouseUtils.parseBoolean( + urlProperties.getOrDefault(DriverProperties.SECURE_CONNECTION.getKey(), "false")); boolean useSSL = useSSLInfo || useSSLUrlProperties; String bearerToken = props.getProperty(ClientConfigProperties.BEARERTOKEN_AUTH.getKey(), null); if (bearerToken != null) { @@ -101,7 +105,8 @@ public JdbcConfiguration(String url, Properties info) throws SQLException { } this.connectionUrl = createConnectionURL(tmpConnectionUrl, useSSL); - this.isIgnoreUnsupportedRequests = Boolean.parseBoolean(getDriverProperty(DriverProperties.IGNORE_UNSUPPORTED_VALUES.getKey(), "false")); + this.isIgnoreUnsupportedRequests = ClickHouseUtils.parseBoolean( + getDriverProperty(DriverProperties.IGNORE_UNSUPPORTED_VALUES.getKey(), "false")); } /** @@ -346,7 +351,7 @@ public Supplier getQueryIdGenerator() { public Boolean isSet(DriverProperties driverProp) { String v = driverProperties.getOrDefault(driverProp.getKey(), driverProp.getDefaultValue()); - return Boolean.parseBoolean(v); + return ClickHouseUtils.parseBoolean(v); } public Client.Builder applyClientProperties(Client.Builder builder) { @@ -374,7 +379,7 @@ public boolean isBetaFeatureEnabled(DriverProperties prop) { public boolean isFlagSet(DriverProperties prop) { String value = driverProperties.getOrDefault(prop.getKey(), prop.getDefaultValue()); - return Boolean.parseBoolean(value); + return ClickHouseUtils.parseBoolean(value); } private Map> defaultTypeHintMapping() { diff --git a/jdbc-v2/src/test/java/com/clickhouse/jdbc/internal/JdbcConfigurationTest.java b/jdbc-v2/src/test/java/com/clickhouse/jdbc/internal/JdbcConfigurationTest.java index a5a3e972f..d88030cb2 100644 --- a/jdbc-v2/src/test/java/com/clickhouse/jdbc/internal/JdbcConfigurationTest.java +++ b/jdbc-v2/src/test/java/com/clickhouse/jdbc/internal/JdbcConfigurationTest.java @@ -1,5 +1,24 @@ package com.clickhouse.jdbc.internal; +import com.clickhouse.jdbc.DriverProperties; +import org.testng.Assert; +import org.testng.annotations.Test; + +import java.sql.SQLException; +import java.util.Properties; + +public class JdbcConfigurationTest { + + @Test + public void testIgnoreUnsupportedRequestsParsing() throws SQLException { + Properties props = new Properties(); + props.setProperty(DriverProperties.IGNORE_UNSUPPORTED_VALUES.getKey(), "1"); + JdbcConfiguration cfg = new JdbcConfiguration("jdbc:clickhouse://localhost", props); + Assert.assertTrue(cfg.isIgnoreUnsupportedRequests()); + } +} +package com.clickhouse.jdbc.internal; + import com.clickhouse.client.api.Client; import com.clickhouse.client.api.ClientConfigProperties;