CQL_DATATYPE_TO_DATATYPE;
final int protocolId;
diff --git a/src/main/java/com/ing/data/cassandra/jdbc/SessionHolder.java b/src/main/java/com/ing/data/cassandra/jdbc/SessionHolder.java
index 0757788..bf1241c 100644
--- a/src/main/java/com/ing/data/cassandra/jdbc/SessionHolder.java
+++ b/src/main/java/com/ing/data/cassandra/jdbc/SessionHolder.java
@@ -234,7 +234,9 @@ private Session createSession(final Properties properties) throws SQLException {
}
// The DefaultLoadBalancingPolicy requires to specify a local data center.
- builder.withLocalDatacenter(localDatacenter);
+ if (!localDatacenter.trim().isEmpty()) {
+ builder.withLocalDatacenter(localDatacenter);
+ }
if (loadBalancingPolicy.length() > 0) {
// if a custom load balancing policy has been given in the JDBC URL, parse it and add it to the cluster
// builder.
diff --git a/src/main/java/com/ing/data/cassandra/jdbc/TypesMap.java b/src/main/java/com/ing/data/cassandra/jdbc/TypesMap.java
index 8cb1f82..09f6133 100644
--- a/src/main/java/com/ing/data/cassandra/jdbc/TypesMap.java
+++ b/src/main/java/com/ing/data/cassandra/jdbc/TypesMap.java
@@ -72,6 +72,7 @@ public final class TypesMap {
TYPES_MAP.put("org.apache.cassandra.db.marshal.uuid", JdbcUUID.INSTANCE);
TYPES_MAP.put("org.apache.cassandra.db.marshal.varchar", JdbcUTF8.INSTANCE);
TYPES_MAP.put("org.apache.cassandra.db.marshal.varint", JdbcInteger.INSTANCE);
+ TYPES_MAP.put("org.apache.cassandra.db.marshal.jsonb", JdbcUTF8.INSTANCE);
}
private TypesMap() {
diff --git a/src/main/java/com/ing/data/cassandra/jdbc/Utils.java b/src/main/java/com/ing/data/cassandra/jdbc/Utils.java
index 795e5d7..67037aa 100644
--- a/src/main/java/com/ing/data/cassandra/jdbc/Utils.java
+++ b/src/main/java/com/ing/data/cassandra/jdbc/Utils.java
@@ -185,6 +185,7 @@ public final class Utils {
protected static final String FORWARD_ONLY = "Can not position cursor with a type of TYPE_FORWARD_ONLY.";
protected static final String MALFORMED_URL = "The string '%s' is not a valid URL.";
protected static final String SSL_CONFIG_FAILED = "Unable to configure SSL: %s.";
+ protected static boolean hasPort = false;
static final Logger LOG = LoggerFactory.getLogger(Utils.class);
@@ -192,6 +193,38 @@ private Utils() {
// Private constructor to hide the public one.
}
+ public static boolean isIPv6(String hostsStr) {
+ Pattern validIpv6Pattern = Pattern.compile("([0-9a-f]{1,4}:){7}([0-9a-f]){1,4}", 2);
+ Pattern validIpv6WithPortPattern = Pattern.compile("([0-9a-f]{1,4}:){8}([0-9a-f]){1,4}", 2);
+ String[] hosts = hostsStr.split("--");
+ int n = hosts.length;
+ boolean value = false;
+
+ Matcher m2;
+ for (int i = 0; i < n - 1; ++i) {
+ m2 = validIpv6Pattern.matcher(hosts[i]);
+ value = m2.matches();
+ if (!value) {
+ break;
+ }
+ }
+
+ m2 = validIpv6WithPortPattern.matcher(hosts[n - 1]);
+ Matcher m3;
+ boolean value2;
+ if (m2.matches()) {
+ hasPort = true;
+ m3 = validIpv6Pattern.matcher(hosts[n - 1].substring(0, hosts[n - 1].lastIndexOf(":")));
+ value2 = m3.matches();
+ } else {
+ hasPort = false;
+ m3 = validIpv6Pattern.matcher(hosts[n - 1]);
+ value2 = m3.matches();
+ }
+
+ return value && value2;
+ }
+
/**
* Parses a URL for the Cassandra JDBC Driver.
*
@@ -212,6 +245,8 @@ public static Properties parseURL(final String url) throws SQLException {
final Properties props = new Properties();
if (url != null) {
+ int port = DEFAULT_PORT;
+ String host;
props.setProperty(TAG_PORT_NUMBER, String.valueOf(DEFAULT_PORT));
boolean isDbaasConnection = false;
int uriStartIndex = PROTOCOL.length();
@@ -228,13 +263,30 @@ public static Properties parseURL(final String url) throws SQLException {
}
if (!isDbaasConnection) {
- final String host = uri.getHost();
+ host = uri.getHost();
+ String[] hostsStr = rawUri.split("/");
if (host == null) {
- throw new SQLNonTransientConnectionException(HOST_IN_URL);
+ if (!hostsStr[2].contains("--")) {
+ throw new SQLNonTransientConnectionException("Connection url must specify a host, e.g. jdbc:cassandra://localhost:9042/keyspace");
+ }
+
+ boolean ipv6 = isIPv6(hostsStr[2]);
+ if (!ipv6) {
+ if (hostsStr[2].contains(":")) {
+ host = hostsStr[2].substring(0, hostsStr[2].indexOf(58));
+ port = Integer.parseInt(hostsStr[2].substring(hostsStr[2].indexOf(58) + 1));
+ } else {
+ host = hostsStr[2];
+ }
+ } else if (hasPort) {
+ host = hostsStr[2].substring(0, hostsStr[2].lastIndexOf(58));
+ port = Integer.parseInt(hostsStr[2].substring(hostsStr[2].lastIndexOf(58) + 1));
+ } else {
+ host = hostsStr[2];
+ }
}
props.setProperty(TAG_SERVER_NAME, host);
- int port = DEFAULT_PORT;
if (uri.getPort() >= 0) {
port = uri.getPort();
}
@@ -333,7 +385,10 @@ public static String createSubName(final Properties props) throws SQLException {
keyspace = StringUtils.prependIfMissing(keyspace, "/");
}
- final String host = props.getProperty(TAG_SERVER_NAME);
+ String host = props.getProperty(TAG_SERVER_NAME);
+ if (host.contains("--")) {
+ host = host.split("--")[0];
+ }
if (host == null) {
throw new SQLNonTransientConnectionException(HOST_REQUIRED);
}
diff --git a/src/test/java/com/ing/data/cassandra/jdbc/utils/AnotherFakeLoadBalancingPolicy.java b/src/test/java/com/ing/data/cassandra/jdbc/utils/AnotherFakeLoadBalancingPolicy.java
index 08735b6..0e80833 100644
--- a/src/test/java/com/ing/data/cassandra/jdbc/utils/AnotherFakeLoadBalancingPolicy.java
+++ b/src/test/java/com/ing/data/cassandra/jdbc/utils/AnotherFakeLoadBalancingPolicy.java
@@ -18,7 +18,7 @@
import com.datastax.oss.driver.api.core.metadata.Node;
import com.datastax.oss.driver.api.core.session.Request;
import com.datastax.oss.driver.api.core.session.Session;
-import com.datastax.oss.driver.internal.core.util.collection.SimpleQueryPlan;
+import com.datastax.oss.driver.internal.core.util.collection.QueryPlan;
import edu.umd.cs.findbugs.annotations.NonNull;
import edu.umd.cs.findbugs.annotations.Nullable;
@@ -43,7 +43,7 @@ public void init(@NonNull final Map nodes, @NonNull final DistanceRe
@Override
public Queue newQueryPlan(@Nullable final Request request, @Nullable final Session session) {
// Do nothing. For testing purpose only.
- return new SimpleQueryPlan(mock(Node.class));
+ return new QueryPlan(mock(Node.class));
}
@Override
diff --git a/src/test/java/com/ing/data/cassandra/jdbc/utils/FakeLoadBalancingPolicy.java b/src/test/java/com/ing/data/cassandra/jdbc/utils/FakeLoadBalancingPolicy.java
index 8e61a3a..76fd46f 100644
--- a/src/test/java/com/ing/data/cassandra/jdbc/utils/FakeLoadBalancingPolicy.java
+++ b/src/test/java/com/ing/data/cassandra/jdbc/utils/FakeLoadBalancingPolicy.java
@@ -18,7 +18,7 @@
import com.datastax.oss.driver.api.core.metadata.Node;
import com.datastax.oss.driver.api.core.session.Request;
import com.datastax.oss.driver.api.core.session.Session;
-import com.datastax.oss.driver.internal.core.util.collection.SimpleQueryPlan;
+import com.datastax.oss.driver.internal.core.util.collection.QueryPlan;
import edu.umd.cs.findbugs.annotations.NonNull;
import edu.umd.cs.findbugs.annotations.Nullable;
@@ -43,7 +43,7 @@ public void init(@NonNull final Map nodes, @NonNull final DistanceRe
@Override
public Queue newQueryPlan(@Nullable final Request request, @Nullable final Session session) {
// Do nothing. For testing purpose only.
- return new SimpleQueryPlan(mock(Node.class));
+ return new QueryPlan(mock(Node.class));
}
@Override
diff --git a/src/test/java/com/ing/data/cassandra/jdbc/utils/JSONBTest.java b/src/test/java/com/ing/data/cassandra/jdbc/utils/JSONBTest.java
new file mode 100644
index 0000000..f1b0cdd
--- /dev/null
+++ b/src/test/java/com/ing/data/cassandra/jdbc/utils/JSONBTest.java
@@ -0,0 +1,46 @@
+package com.ing.data.cassandra.jdbc.utils;
+
+import java.sql.*;
+
+public class JSONBTest {
+ private static final String urlWithoutAuth = "jdbc:cassandra://127.0.0.1/system?localdatacenter=datacenter1";
+ public static void main(String args[]) throws ClassNotFoundException, SQLException {
+// Class.forName("com.wisecoders.dbschema.cassandra.JdbcDriver");
+ /*
+ create keyspace test;
+ create table test.jsontable (id int primary key, col1 text, col2 varchar, details jsonb);
+ insert into test.jsontable (id, col1, col2, details) values (1, 'abc', 'xyz', '{ "name": "Macbeth", "author": { "first_name": "William", "last_name": "Shakespeare" }, "year": 1623, "editors": ["John", "Elizabeth", "Jeff"] }');
+ */
+ Class.forName("com.ing.data.cassandra.jdbc.CassandraDriver");
+ Connection con = DriverManager.getConnection( urlWithoutAuth, "yugabyte", "yugabyte");
+ Statement stmt = con.createStatement();
+ stmt.execute("SELECT id, col1, col2, details FROM test.jsontable");
+ ResultSet rs = stmt.getResultSet();
+ while(rs.next()){
+ System.out.println("getInt(1): " + rs.getInt(1));
+// System.out.println(rs.getObject(2));
+// System.out.println(rs.getObject(3));
+ System.out.println("getObject(4): " + rs.getObject(4));
+ System.out.println("getObject('details'): " + rs.getObject("details"));
+ ResultSetMetaData rmd = rs.getMetaData();
+ System.out.println("colName: " + rmd.getColumnName(1));
+ System.out.println("colType: " + rmd.getColumnType(1));
+ System.out.println("colTypeName: " + rmd.getColumnTypeName(1));
+ System.out.println("getLong(1): " + rs.getLong(1));
+//
+// System.out.println(rmd.getColumnName(2));
+// System.out.println(rmd.getColumnType(2));
+// System.out.println(rmd.getColumnTypeName(2));
+//
+// System.out.println(rmd.getColumnName(3));
+// System.out.println(rmd.getColumnType(3));
+// System.out.println(rmd.getColumnTypeName(3));
+
+ System.out.println("colName: " + rmd.getColumnName(4));
+ System.out.println("colType: " + rmd.getColumnType(4));
+ System.out.println("colTypeName: " + rmd.getColumnTypeName(4));
+ }
+ System.out.println("executed query");
+ con.close();
+ }
+}