Author: jbellis
Date: Tue Aug 2 16:32:51 2011
New Revision: 1153182
URL: http://svn.apache.org/viewvc?rev=1153182&view=rev
Log:
add simple DataSource implementation
Added:
cassandra/drivers/java/src/org/apache/cassandra/cql/jdbc/CassandraDataSource.java
cassandra/drivers/java/test/org/apache/cassandra/cql/jdbc/DataSourceTest.java
Modified:
cassandra/drivers/java/src/org/apache/cassandra/cql/jdbc/Utils.java
Added:
cassandra/drivers/java/src/org/apache/cassandra/cql/jdbc/CassandraDataSource.java
URL:
http://svn.apache.org/viewvc/cassandra/drivers/java/src/org/apache/cassandra/cql/jdbc/CassandraDataSource.java?rev=1153182&view=auto
==============================================================================
---
cassandra/drivers/java/src/org/apache/cassandra/cql/jdbc/CassandraDataSource.java
(added)
+++
cassandra/drivers/java/src/org/apache/cassandra/cql/jdbc/CassandraDataSource.java
Tue Aug 2 16:32:51 2011
@@ -0,0 +1,168 @@
+
+package org.apache.cassandra.cql.jdbc;
+
+import static org.apache.cassandra.cql.jdbc.Utils.HOST_REQUIRED;
+import static org.apache.cassandra.cql.jdbc.Utils.NO_INTERFACE;
+import static org.apache.cassandra.cql.jdbc.Utils.PROTOCOL;
+import static org.apache.cassandra.cql.jdbc.Utils.TAG_SERVER_NAME;
+import static org.apache.cassandra.cql.jdbc.Utils.TAG_DATABASE_NAME;
+import static org.apache.cassandra.cql.jdbc.Utils.TAG_PASSWORD;
+import static org.apache.cassandra.cql.jdbc.Utils.TAG_PORT_NUMBER;
+import static org.apache.cassandra.cql.jdbc.Utils.TAG_USER;
+import static org.apache.cassandra.cql.jdbc.Utils.createSubName;
+
+import java.io.PrintWriter;
+import java.sql.Connection;
+import java.sql.DriverManager;
+import java.sql.SQLException;
+import java.sql.SQLFeatureNotSupportedException;
+import java.sql.SQLNonTransientConnectionException;
+import java.util.Properties;
+
+import javax.sql.DataSource;
+
+public class CassandraDataSource implements DataSource
+{
+
+ static
+ {
+ try
+ {
+ Class.forName("org.apache.cassandra.cql.jdbc.CassandraDriver");
+ }
+ catch (ClassNotFoundException e)
+ {
+ throw new RuntimeException(e);
+ }
+ }
+
+ protected static final String description = "Cassandra Data Source";
+
+ protected String serverName;
+
+ protected int portNumber = 9160;
+
+ protected String databaseName;
+
+ protected String user;
+
+ protected String password;
+
+ public CassandraDataSource(String host, int port, String keyspace, String
user, String password)
+ {
+ if (host != null) setServerName(host);
+ if (port != -1) setPortNumber(port);
+ setDatabaseName(keyspace);
+ setUser(user);
+ setPassword(password);
+ }
+
+ public String getDescription()
+ {
+ return description;
+ }
+
+ public String getServerName()
+ {
+ return serverName;
+ }
+
+ public void setServerName(String serverName)
+ {
+ this.serverName = serverName;
+ }
+
+ public int getPortNumber()
+ {
+ return portNumber;
+ }
+
+ public void setPortNumber(int portNumber)
+ {
+ this.portNumber = portNumber;
+ }
+
+ public String getDatabaseName()
+ {
+ return databaseName;
+ }
+
+ public void setDatabaseName(String databaseName)
+ {
+ this.databaseName = databaseName;
+ }
+
+ public String getUser()
+ {
+ return user;
+ }
+
+ public void setUser(String user)
+ {
+ this.user = user;
+ }
+
+ public String getPassword()
+ {
+ return password;
+ }
+
+ public void setPassword(String password)
+ {
+ this.password = password;
+ }
+
+ public Connection getConnection() throws SQLException
+ {
+ return getConnection(null, null);
+ }
+
+ public Connection getConnection(String user, String password) throws
SQLException
+ {
+ Properties props = new Properties();
+
+ this.user = user;
+ this.password = password;
+
+ if (this.serverName!=null) props.setProperty(TAG_SERVER_NAME,
this.serverName);
+ else throw new SQLNonTransientConnectionException(HOST_REQUIRED);
+ props.setProperty(TAG_PORT_NUMBER, ""+this.portNumber);
+ if (this.databaseName!=null) props.setProperty(TAG_DATABASE_NAME,
this.databaseName);
+ if (user!=null) props.setProperty(TAG_USER, user);
+ if (password!=null) props.setProperty(TAG_PASSWORD, password);
+
+ String url = PROTOCOL+createSubName(props);
+ return DriverManager.getConnection(url, props);
+ }
+
+ public int getLoginTimeout() throws SQLException
+ {
+ return DriverManager.getLoginTimeout();
+ }
+
+ public PrintWriter getLogWriter() throws SQLException
+ {
+ return DriverManager.getLogWriter();
+ }
+
+ public void setLoginTimeout(int timeout) throws SQLException
+ {
+ DriverManager.setLoginTimeout(timeout);
+ }
+
+ public void setLogWriter(PrintWriter writer) throws SQLException
+ {
+ DriverManager.setLogWriter(writer);
+ }
+
+ public boolean isWrapperFor(Class<?> iface) throws SQLException
+ {
+ return iface.isAssignableFrom(getClass());
+ }
+
+ public <T> T unwrap(Class<T> iface) throws SQLException
+ {
+ if (iface.isAssignableFrom(getClass())) return iface.cast(this);
+ throw new SQLFeatureNotSupportedException(String.format(NO_INTERFACE,
iface.getSimpleName()));
+ }
+}
Modified: cassandra/drivers/java/src/org/apache/cassandra/cql/jdbc/Utils.java
URL:
http://svn.apache.org/viewvc/cassandra/drivers/java/src/org/apache/cassandra/cql/jdbc/Utils.java?rev=1153182&r1=1153181&r2=1153182&view=diff
==============================================================================
--- cassandra/drivers/java/src/org/apache/cassandra/cql/jdbc/Utils.java
(original)
+++ cassandra/drivers/java/src/org/apache/cassandra/cql/jdbc/Utils.java Tue Aug
2 16:32:51 2011
@@ -178,6 +178,48 @@ class Utils
}
/**
+ * Create a "Subname" portion of a JDBC URL from properties.
+ *
+ * @param props A Properties file containing all the properties to be
considered.
+ * @return A constructed "Subname" portion of a JDBC URL in the form of a
CLI (ie: //myhost:9160/Test1 )
+ * @throws SQLException
+ */
+ public static final String createSubName(Properties props)throws
SQLException
+ {
+ // make keyspace always start with a "/" for URI
+ String keyspace = props.getProperty(TAG_DATABASE_NAME);
+
+ // if keyspace is null then do not bother ...
+ if (keyspace != null)
+ if (!keyspace.startsWith("/")) keyspace = "/" + keyspace;
+
+ String host = props.getProperty(TAG_SERVER_NAME);
+ if (host==null)throw new
SQLNonTransientConnectionException(HOST_REQUIRED);
+
+ // construct a valid URI from parts...
+ URI uri;
+ try
+ {
+ uri = new URI(
+ null,
+ null,
+ host,
+ props.getProperty(TAG_PORT_NUMBER)==null ? DEFAULT_PORT :
Integer.parseInt(props.getProperty(TAG_PORT_NUMBER)),
+ keyspace,
+ null,
+ null);
+ }
+ catch (Exception e)
+ {
+ throw new SQLNonTransientConnectionException(e);
+ }
+
+ if (logger.isTraceEnabled()) logger.trace("Subname : '{}' created from
: {}",uri.toString(), props);
+
+ return uri.toString();
+ }
+
+ /**
* Determine the current keyspace by inspecting the CQL string to see if a
USE statement is provided; which would change the keyspace.
*
* @param cql A CQL query string
Added:
cassandra/drivers/java/test/org/apache/cassandra/cql/jdbc/DataSourceTest.java
URL:
http://svn.apache.org/viewvc/cassandra/drivers/java/test/org/apache/cassandra/cql/jdbc/DataSourceTest.java?rev=1153182&view=auto
==============================================================================
---
cassandra/drivers/java/test/org/apache/cassandra/cql/jdbc/DataSourceTest.java
(added)
+++
cassandra/drivers/java/test/org/apache/cassandra/cql/jdbc/DataSourceTest.java
Tue Aug 2 16:32:51 2011
@@ -0,0 +1,111 @@
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ */
+package org.apache.cassandra.cql.jdbc;
+
+import static org.junit.Assert.*;
+
+import java.io.PrintWriter;
+import java.sql.SQLFeatureNotSupportedException;
+
+import javax.sql.DataSource;
+
+import org.apache.cassandra.cql.EmbeddedServiceBase;
+import org.junit.BeforeClass;
+import org.junit.Test;
+
+public class DataSourceTest extends EmbeddedServiceBase
+{
+ private static final String HOST = "localhost";
+ private static final int PORT = 9170;
+ private static final String KEYSPACE = "Test";
+ private static final String USER = "JohnDoe";
+ private static final String PASSWORD = "secret";
+
+
+ @BeforeClass
+ public static void setUpBeforeClass() throws Exception
+ {
+ startCassandraServer();
+ }
+
+ @Test
+ public void testConstructor() throws Exception
+ {
+ CassandraDataSource cds = new
CassandraDataSource(HOST,PORT,KEYSPACE,USER,PASSWORD);
+ assertEquals(HOST,cds.getServerName());
+ assertEquals(PORT,cds.getPortNumber());
+ assertEquals(KEYSPACE,cds.getDatabaseName());
+ assertEquals(USER,cds.getUser());
+ assertEquals(PASSWORD,cds.getPassword());
+
+ DataSource ds = new
CassandraDataSource(HOST,PORT,KEYSPACE,USER,PASSWORD);
+ assertNotNull(ds);
+
+ PrintWriter pw = new PrintWriter(System.err);
+
+ // null username and password
+ java.sql.Connection cnx = ds.getConnection(null, null);
+ assertFalse(cnx.isClosed());
+ ds.setLoginTimeout(5);
+ assertEquals(5, ds.getLoginTimeout());
+ ds.setLogWriter(pw);
+ assertNotNull(ds.getLogWriter());
+
+ // no username and password
+ cnx = ds.getConnection();
+ assertFalse(cnx.isClosed());
+ ds.setLoginTimeout(5);
+ assertEquals(5, ds.getLoginTimeout());
+ ds.setLogWriter(pw);
+ assertNotNull(ds.getLogWriter());
+ }
+
+
+ @Test
+ public void testIsWrapperFor() throws Exception
+ {
+ DataSource ds = new
CassandraDataSource(HOST,PORT,KEYSPACE,USER,PASSWORD);
+
+ boolean isIt = false;
+
+ // it is a wrapper for DataSource
+ isIt = ds.isWrapperFor(DataSource.class);
+ assertTrue(isIt);
+
+ // it is not a wrapper for this test class
+ isIt = ds.isWrapperFor(this.getClass());
+ assertFalse(isIt);
+ }
+
+ @Test(expected=SQLFeatureNotSupportedException.class)
+ public void testUnwrap() throws Exception
+ {
+ DataSource ds = new
CassandraDataSource(HOST,PORT,KEYSPACE,USER,PASSWORD);
+
+ // it is a wrapper for DataSource
+ DataSource newds = ds.unwrap(DataSource.class);
+ assertNotNull(newds);
+
+ // it is not a wrapper for this test class
+ newds = (DataSource) ds.unwrap(this.getClass());
+ assertNotNull(newds);
+ }
+}