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);
+    }
+}


Reply via email to