You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@cassandra.apache.org by jb...@apache.org on 2011/07/22 03:59:10 UTC

svn commit: r1149432 - in /cassandra/drivers/java: src/org/apache/cassandra/cql/jdbc/ test/org/apache/cassandra/cql/ test/org/apache/cassandra/cql/jdbc/

Author: jbellis
Date: Fri Jul 22 01:59:09 2011
New Revision: 1149432

URL: http://svn.apache.org/viewvc?rev=1149432&view=rev
Log:
clean up Connection and CassandraConnection
patch by Rick Shaw and jbellis for CASSANDRA-2924

Removed:
    cassandra/drivers/java/src/org/apache/cassandra/cql/jdbc/Connection.java
    cassandra/drivers/java/src/org/apache/cassandra/cql/jdbc/ConnectionPool.java
Modified:
    cassandra/drivers/java/src/org/apache/cassandra/cql/jdbc/CResultSet.java
    cassandra/drivers/java/src/org/apache/cassandra/cql/jdbc/CassandraConnection.java
    cassandra/drivers/java/src/org/apache/cassandra/cql/jdbc/CassandraDriver.java
    cassandra/drivers/java/src/org/apache/cassandra/cql/jdbc/CassandraPreparedStatement.java
    cassandra/drivers/java/src/org/apache/cassandra/cql/jdbc/CassandraStatement.java
    cassandra/drivers/java/src/org/apache/cassandra/cql/jdbc/Utils.java
    cassandra/drivers/java/test/org/apache/cassandra/cql/JdbcDriverTest.java
    cassandra/drivers/java/test/org/apache/cassandra/cql/jdbc/PreparedStatementTest.java

Modified: cassandra/drivers/java/src/org/apache/cassandra/cql/jdbc/CResultSet.java
URL: http://svn.apache.org/viewvc/cassandra/drivers/java/src/org/apache/cassandra/cql/jdbc/CResultSet.java?rev=1149432&r1=1149431&r2=1149432&view=diff
==============================================================================
--- cassandra/drivers/java/src/org/apache/cassandra/cql/jdbc/CResultSet.java (original)
+++ cassandra/drivers/java/src/org/apache/cassandra/cql/jdbc/CResultSet.java Fri Jul 22 01:59:09 2011
@@ -38,51 +38,75 @@ import org.apache.cassandra.utils.ByteBu
 
 public class CResultSet extends AbstractResultSet implements CassandraResultSet
 {
+    public static final int DEFAULT_TYPE = ResultSet.TYPE_FORWARD_ONLY;
+    public static final int DEFAULT_CONCURRENCY = ResultSet.CONCUR_READ_ONLY;
+    public static final int DEFAULT_HOLDABILITY = ResultSet.HOLD_CURSORS_OVER_COMMIT;
+
     private final ColumnDecoder decoder;
     private final String keyspace;
-    
+
     private final String columnFamily;
-    
-    /** The r set iter. */
+
+    /**
+     * The r set iter.
+     */
     private Iterator<CqlRow> rSetIter;
-    
+
     int rowNumber = 0;
     // the current row key when iterating through results.
     private byte[] curRowKey = null;
-    
+
     private TypedColumn typedCurRowKey = null;
-    
-    /** The values. */
+
+    /**
+     * The values.
+     */
     private List<TypedColumn> values = new ArrayList<TypedColumn>();
-    
-    /** The value map. */
+
+    /**
+     * The value map.
+     */
     private Map<String, TypedColumn> valueMap = new HashMap<String, TypedColumn>();
-    
-    /** The index map. */
+
+    /**
+     * The index map.
+     */
     private Map<String, Integer> indexMap = new HashMap<String, Integer>();
-    
+
     private final CResultSetMetaData meta;
-    
+
     private final Statement statement;
-    
+
     private int resultSetType;
-    
+
     private int fetchDirection;
-    
+
     private int fetchSize;
 
     private boolean wasNull;
 
     /**
+     * no argument constructor.
+     */
+    CResultSet()
+    {
+        keyspace = null;
+        columnFamily = null;
+        decoder = null;
+        statement = null;
+        meta = new CResultSetMetaData();
+    }
+
+    /**
      * Instantiates a new cassandra result set.
      */
-    CResultSet(Statement statement,CqlResult resultSet, ColumnDecoder decoder, String keyspace, String columnFamily) throws SQLException
+    CResultSet(Statement statement, CqlResult resultSet, ColumnDecoder decoder, String keyspace, String columnFamily) throws SQLException
     {
         this.statement = statement;
         this.resultSetType = statement.getResultSetType();
         this.fetchDirection = statement.getFetchDirection();
         this.fetchSize = statement.getFetchSize();
-        
+
         this.decoder = decoder;
         this.keyspace = keyspace;
         this.columnFamily = columnFamily;
@@ -92,23 +116,24 @@ public class CResultSet extends Abstract
 
     public boolean absolute(int arg0) throws SQLException
     {
-        throw new SQLFeatureNotSupportedException (NOT_SUPPORTED);
+        throw new SQLFeatureNotSupportedException(NOT_SUPPORTED);
     }
 
     public void afterLast() throws SQLException
     {
-        throw new SQLFeatureNotSupportedException (NOT_SUPPORTED);
+        throw new SQLFeatureNotSupportedException(NOT_SUPPORTED);
     }
 
     public void beforeFirst() throws SQLException
     {
-        throw new SQLFeatureNotSupportedException (NOT_SUPPORTED);
+        throw new SQLFeatureNotSupportedException(NOT_SUPPORTED);
     }
-    
+
     private final void checkIndex(int index) throws SQLException
     {
         // 1 <= index <= size()
-        if (index < 1 || index > values.size()) throw new SQLSyntaxErrorException(String.format(MUST_BE_POSITIVE, String.valueOf(index)));
+        if (index < 1 || index > values.size())
+            throw new SQLSyntaxErrorException(String.format(MUST_BE_POSITIVE, String.valueOf(index)));
     }
 
     private final void checkName(String name) throws SQLException
@@ -143,29 +168,29 @@ public class CResultSet extends Abstract
 
     public boolean first() throws SQLException
     {
-        throw new SQLFeatureNotSupportedException (NOT_SUPPORTED);
+        throw new SQLFeatureNotSupportedException(NOT_SUPPORTED);
     }
 
     // Big Decimal (awaiting a new AbstractType implementation)
-    
+
     public BigDecimal getBigDecimal(int arg0) throws SQLException
     {
-        throw new SQLFeatureNotSupportedException (NOT_SUPPORTED);
+        throw new SQLFeatureNotSupportedException(NOT_SUPPORTED);
     }
-    
+
     public BigDecimal getBigDecimal(int arg0, int arg1) throws SQLException
     {
-        throw new SQLFeatureNotSupportedException (NOT_SUPPORTED);
+        throw new SQLFeatureNotSupportedException(NOT_SUPPORTED);
     }
 
     public BigDecimal getBigDecimal(String arg0) throws SQLException
     {
-        throw new SQLFeatureNotSupportedException (NOT_SUPPORTED);
+        throw new SQLFeatureNotSupportedException(NOT_SUPPORTED);
     }
 
     public BigDecimal getBigDecimal(String arg0, int arg1) throws SQLException
     {
-        throw new SQLFeatureNotSupportedException (NOT_SUPPORTED);
+        throw new SQLFeatureNotSupportedException(NOT_SUPPORTED);
     }
 
     public BigInteger getBigInteger(int index) throws SQLException
@@ -179,7 +204,7 @@ public class CResultSet extends Abstract
         checkName(name);
         return getBigInteger(valueMap.get(name));
     }
-    
+
     private BigInteger getBigInteger(TypedColumn column) throws SQLException
     {
         checkNotClosed();
@@ -201,13 +226,13 @@ public class CResultSet extends Abstract
             throw new SQLSyntaxErrorException(e);
         }
 
-        throw new SQLSyntaxErrorException(String.format(NOT_TRANSLATABLE, value.getClass().getSimpleName(),"BigInteger"));
+        throw new SQLSyntaxErrorException(String.format(NOT_TRANSLATABLE, value.getClass().getSimpleName(), "BigInteger"));
     }
 
     public boolean getBoolean(int index) throws SQLException
     {
         checkIndex(index);
-        return getBoolean(values.get(index-1));
+        return getBoolean(values.get(index - 1));
     }
 
     public boolean getBoolean(String name) throws SQLException
@@ -237,7 +262,7 @@ public class CResultSet extends Abstract
             throw new SQLSyntaxErrorException(String.format(NOT_BOOLEAN, str));
         }
 
-        throw new SQLSyntaxErrorException(String.format(NOT_TRANSLATABLE, value.getClass().getSimpleName(),"Boolean"));
+        throw new SQLSyntaxErrorException(String.format(NOT_TRANSLATABLE, value.getClass().getSimpleName(), "Boolean"));
     }
 
     public byte getByte(int index) throws SQLException
@@ -273,7 +298,7 @@ public class CResultSet extends Abstract
             throw new SQLSyntaxErrorException(e);
         }
 
-        throw new SQLSyntaxErrorException(String.format(NOT_TRANSLATABLE, value.getClass().getSimpleName(),"Byte"));
+        throw new SQLSyntaxErrorException(String.format(NOT_TRANSLATABLE, value.getClass().getSimpleName(), "Byte"));
     }
 
     public byte[] getBytes(int index) throws SQLException
@@ -293,7 +318,7 @@ public class CResultSet extends Abstract
         wasNull = value == null;
         return value == null ? null : ByteBufferUtil.clone(value).array();
     }
-    
+
     public TypedColumn getColumn(int index) throws SQLException
     {
         checkIndex(index);
@@ -317,7 +342,7 @@ public class CResultSet extends Abstract
     public Date getDate(int index) throws SQLException
     {
         checkIndex(index);
-        return getDate(values.get(index-1));
+        return getDate(values.get(index - 1));
     }
 
     public Date getDate(int index, Calendar calendar) throws SQLException
@@ -340,34 +365,34 @@ public class CResultSet extends Abstract
         return getDate(name);
     }
 
-    private Date getDate(TypedColumn column)  throws SQLException
+    private Date getDate(TypedColumn column) throws SQLException
     {
         checkNotClosed();
         Object value = column.getValue();
-        wasNull = value==null;
-        
+        wasNull = value == null;
+
         if (wasNull) return null;
-        
-        if (value instanceof Long ) return new Date((Long)value);
-                
-        if (value instanceof java.util.Date ) return new Date(((java.util.Date) value).getTime());
-        
+
+        if (value instanceof Long) return new Date((Long) value);
+
+        if (value instanceof java.util.Date) return new Date(((java.util.Date) value).getTime());
+
         try
         {
             if (value instanceof String) return Date.valueOf((String) value);
         }
         catch (IllegalArgumentException e)
         {
-           throw new SQLSyntaxErrorException(e);
+            throw new SQLSyntaxErrorException(e);
         }
-        
-        throw new SQLSyntaxErrorException(String.format(NOT_TRANSLATABLE, value.getClass().getSimpleName(),"SQL Date"));
+
+        throw new SQLSyntaxErrorException(String.format(NOT_TRANSLATABLE, value.getClass().getSimpleName(), "SQL Date"));
     }
 
     public double getDouble(int index) throws SQLException
     {
         checkIndex(index);
-        return getDouble(values.get(index-1));
+        return getDouble(values.get(index - 1));
     }
 
     public double getDouble(String name) throws SQLException
@@ -398,10 +423,10 @@ public class CResultSet extends Abstract
         }
         catch (NumberFormatException e)
         {
-           throw new SQLSyntaxErrorException(e);
+            throw new SQLSyntaxErrorException(e);
         }
 
-        throw new SQLSyntaxErrorException(String.format(NOT_TRANSLATABLE, value.getClass().getSimpleName(),"Double"));
+        throw new SQLSyntaxErrorException(String.format(NOT_TRANSLATABLE, value.getClass().getSimpleName(), "Double"));
     }
 
     public int getFetchDirection() throws SQLException
@@ -409,7 +434,7 @@ public class CResultSet extends Abstract
         checkNotClosed();
         return fetchDirection;
     }
-    
+
     public int getFetchSize() throws SQLException
     {
         checkNotClosed();
@@ -427,7 +452,7 @@ public class CResultSet extends Abstract
         checkName(name);
         return getFloat(valueMap.get(name));
     }
-    
+
     private final Float getFloat(TypedColumn column) throws SQLException
     {
         checkNotClosed();
@@ -458,7 +483,7 @@ public class CResultSet extends Abstract
 
     public int getHoldability() throws SQLException
     {
-        checkNotClosed();        
+        checkNotClosed();
         return statement.getResultSetHoldability();
     }
 
@@ -496,7 +521,7 @@ public class CResultSet extends Abstract
             throw new SQLSyntaxErrorException(e);
         }
 
-        throw new SQLSyntaxErrorException(String.format(NOT_TRANSLATABLE, value.getClass().getSimpleName(),"int"));
+        throw new SQLSyntaxErrorException(String.format(NOT_TRANSLATABLE, value.getClass().getSimpleName(), "int"));
     }
 
     public byte[] getKey() throws SQLException
@@ -537,7 +562,7 @@ public class CResultSet extends Abstract
             throw new SQLSyntaxErrorException(e);
         }
 
-        throw new SQLSyntaxErrorException(String.format(NOT_TRANSLATABLE, value.getClass().getSimpleName(),"Long"));
+        throw new SQLSyntaxErrorException(String.format(NOT_TRANSLATABLE, value.getClass().getSimpleName(), "Long"));
     }
 
     public ResultSetMetaData getMetaData() throws SQLException
@@ -576,7 +601,7 @@ public class CResultSet extends Abstract
     // RowId (shall we just store the raw bytes as it is kept in C* ? Probably...
     public RowId getRowId(String arg0) throws SQLException
     {
-        throw new SQLFeatureNotSupportedException (NOT_SUPPORTED);
+        throw new SQLFeatureNotSupportedException(NOT_SUPPORTED);
     }
 
     public short getShort(int index) throws SQLException
@@ -612,12 +637,12 @@ public class CResultSet extends Abstract
             throw new SQLSyntaxErrorException(e);
         }
 
-        throw new SQLSyntaxErrorException(String.format(NOT_TRANSLATABLE, value.getClass().getSimpleName(),"Short"));
+        throw new SQLSyntaxErrorException(String.format(NOT_TRANSLATABLE, value.getClass().getSimpleName(), "Short"));
     }
 
     public Statement getStatement() throws SQLException
     {
-        checkNotClosed();        
+        checkNotClosed();
         return statement;
     }
 
@@ -644,9 +669,9 @@ public class CResultSet extends Abstract
     public Time getTime(int index) throws SQLException
     {
         checkIndex(index);
-        return getTime(values.get(index-1));
+        return getTime(values.get(index - 1));
     }
-    
+
     public Time getTime(int index, Calendar calendar) throws SQLException
     {
         checkIndex(index);
@@ -666,7 +691,7 @@ public class CResultSet extends Abstract
         // silently ignore the Calendar argument; its a hint we do not need
         return getTime(name);
     }
-    
+
     private Time getTime(TypedColumn column) throws SQLException
     {
         checkNotClosed();
@@ -747,7 +772,7 @@ public class CResultSet extends Abstract
         return resultSetType;
     }
 
-    public TypedColumn getTypedKey()throws SQLException
+    public TypedColumn getTypedKey() throws SQLException
     {
         return typedCurRowKey;
     }
@@ -755,18 +780,18 @@ public class CResultSet extends Abstract
     // URL (awaiting some clarifications as to how it is stored in C* ... just a validated Sting in URL format?
     public URL getURL(int arg0) throws SQLException
     {
-        throw new SQLFeatureNotSupportedException (NOT_SUPPORTED);
+        throw new SQLFeatureNotSupportedException(NOT_SUPPORTED);
     }
 
     public URL getURL(String arg0) throws SQLException
     {
-        throw new SQLFeatureNotSupportedException (NOT_SUPPORTED);
+        throw new SQLFeatureNotSupportedException(NOT_SUPPORTED);
     }
 
     // These Methods are planned to be  implemented soon; but not right now...
     // Each set of methods has a more detailed set of issues that should be considered fully...
-    
-    
+
+
     public SQLWarning getWarnings() throws SQLException
     {
         checkNotClosed();
@@ -786,7 +811,7 @@ public class CResultSet extends Abstract
         checkNotClosed();
         return rowNumber == 0;
     }
-    
+
     public boolean isClosed() throws SQLException
     {
         return valueMap == null;
@@ -811,10 +836,10 @@ public class CResultSet extends Abstract
 
     // Navigation between rows within the returned set of rows
     // Need to use a list iterator so next() needs completely re-thought
-    
+
     public boolean last() throws SQLException
     {
-        throw new SQLFeatureNotSupportedException (NOT_SUPPORTED);
+        throw new SQLFeatureNotSupportedException(NOT_SUPPORTED);
     }
 
     public synchronized boolean next() throws SQLException
@@ -836,7 +861,7 @@ public class CResultSet extends Abstract
 
                 TypedColumn c = decoder.makeCol(keyspace, columnFamily, col);
                 String columnName = decoder.colNameAsString(keyspace, columnFamily, col.name);
-                values.add(c); 
+                values.add(c);
                 indexMap.put(columnName, values.size()); // one greater than 0 based index of a list
                 valueMap.put(columnName, c);
             }
@@ -851,12 +876,12 @@ public class CResultSet extends Abstract
 
     public boolean previous() throws SQLException
     {
-        throw new SQLFeatureNotSupportedException (NOT_SUPPORTED);
+        throw new SQLFeatureNotSupportedException(NOT_SUPPORTED);
     }
 
     public boolean relative(int arg0) throws SQLException
     {
-        throw new SQLFeatureNotSupportedException (NOT_SUPPORTED);
+        throw new SQLFeatureNotSupportedException(NOT_SUPPORTED);
     }
 
     public void setFetchDirection(int direction) throws SQLException
@@ -865,23 +890,24 @@ public class CResultSet extends Abstract
 
         if (direction == FETCH_FORWARD || direction == FETCH_REVERSE || direction == FETCH_UNKNOWN)
         {
-            if ((getType() == TYPE_FORWARD_ONLY) && (direction != FETCH_FORWARD)) throw new SQLSyntaxErrorException("attempt to set an illegal direction : " + direction);
+            if ((getType() == TYPE_FORWARD_ONLY) && (direction != FETCH_FORWARD))
+                throw new SQLSyntaxErrorException("attempt to set an illegal direction : " + direction);
             fetchDirection = direction;
         }
         throw new SQLSyntaxErrorException(String.format(BAD_FETCH_DIR, direction));
     }
 
-     public void setFetchSize(int size) throws SQLException
+    public void setFetchSize(int size) throws SQLException
     {
         checkNotClosed();
-        if (size < 0 ) throw new SQLException(String.format(BAD_FETCH_SIZE, size));
+        if (size < 0) throw new SQLException(String.format(BAD_FETCH_SIZE, size));
         fetchSize = size;
     }
 
     public <T> T unwrap(Class<T> iface) throws SQLException
     {
         if (iface.equals(CassandraResultSet.class)) return (T) this;
-        
+
         throw new SQLFeatureNotSupportedException(String.format(NO_INTERFACE, iface.getSimpleName()));
     }
 
@@ -889,6 +915,7 @@ public class CResultSet extends Abstract
     {
         return wasNull;
     }
+
     /**
      * RSMD implementation.  The metadata returned refers to the column
      * values, not the column names.
@@ -915,7 +942,7 @@ public class CResultSet extends Abstract
         public int getColumnDisplaySize(int column) throws SQLException
         {
             checkIndex(column);
-            return values.get(column-1).getValueString().length();
+            return values.get(column - 1).getValueString().length();
         }
 
         public String getColumnLabel(int column) throws SQLException
@@ -927,33 +954,33 @@ public class CResultSet extends Abstract
         public String getColumnName(int column) throws SQLException
         {
             checkIndex(column);
-            return values.get(column-1).getNameString();
+            return values.get(column - 1).getNameString();
         }
 
         public int getColumnType(int column) throws SQLException
         {
             checkIndex(column);
-            return values.get(column-1).getValueType().getJdbcType();
+            return values.get(column - 1).getValueType().getJdbcType();
         }
 
         // Spec says "database specific type name". For Cassandra this means the abstract type.
         public String getColumnTypeName(int column) throws SQLException
         {
             checkIndex(column);
-            return values.get(column-1).getValueType().getClass().getSimpleName();
+            return values.get(column - 1).getValueType().getClass().getSimpleName();
         }
 
         public int getPrecision(int column) throws SQLException
         {
             checkIndex(column);
-            TypedColumn col = values.get(column-1);
+            TypedColumn col = values.get(column - 1);
             return col.getValueType().getPrecision(col.getValue());
         }
 
         public int getScale(int column) throws SQLException
         {
             checkIndex(column);
-            TypedColumn tc = values.get(column-1);
+            TypedColumn tc = values.get(column - 1);
             return tc.getValueType().getScale(tc.getValue());
         }
 
@@ -972,20 +999,20 @@ public class CResultSet extends Abstract
         public boolean isAutoIncrement(int column) throws SQLException
         {
             checkIndex(column);
-            return values.get(column-1).getValueType() instanceof CounterColumnType; // todo: check Value is correct.
+            return values.get(column - 1).getValueType() instanceof CounterColumnType; // todo: check Value is correct.
         }
 
         public boolean isCaseSensitive(int column) throws SQLException
         {
             checkIndex(column);
-            TypedColumn tc = values.get(column-1);
+            TypedColumn tc = values.get(column - 1);
             return tc.getValueType().isCaseSensitive();
         }
 
         public boolean isCurrency(int column) throws SQLException
         {
             checkIndex(column);
-            TypedColumn tc = values.get(column-1);
+            TypedColumn tc = values.get(column - 1);
             return tc.getValueType().isCurrency();
         }
 
@@ -995,7 +1022,9 @@ public class CResultSet extends Abstract
             return isWritable(column);
         }
 
-        /** absence is the equivalent of null in Cassandra */
+        /**
+         * absence is the equivalent of null in Cassandra
+         */
         public int isNullable(int column) throws SQLException
         {
             checkIndex(column);
@@ -1017,7 +1046,7 @@ public class CResultSet extends Abstract
         public boolean isSigned(int column) throws SQLException
         {
             checkIndex(column);
-            TypedColumn tc = values.get(column-1);
+            TypedColumn tc = values.get(column - 1);
             return tc.getValueType().isSigned();
         }
 

Modified: cassandra/drivers/java/src/org/apache/cassandra/cql/jdbc/CassandraConnection.java
URL: http://svn.apache.org/viewvc/cassandra/drivers/java/src/org/apache/cassandra/cql/jdbc/CassandraConnection.java?rev=1149432&r1=1149431&r2=1149432&view=diff
==============================================================================
--- cassandra/drivers/java/src/org/apache/cassandra/cql/jdbc/CassandraConnection.java (original)
+++ cassandra/drivers/java/src/org/apache/cassandra/cql/jdbc/CassandraConnection.java Fri Jul 22 01:59:09 2011
@@ -20,14 +20,22 @@
  */
 package org.apache.cassandra.cql.jdbc;
 
-import static org.apache.cassandra.cql.jdbc.Utils.*;
+import static org.apache.cassandra.cql.jdbc.Utils.ALWAYS_AUTOCOMMIT;
+import static org.apache.cassandra.cql.jdbc.Utils.BAD_TIMEOUT;
+import static org.apache.cassandra.cql.jdbc.Utils.NO_INTERFACE;
+import static org.apache.cassandra.cql.jdbc.Utils.NO_TRANSACTIONS;
+import static org.apache.cassandra.cql.jdbc.Utils.SCHEMA_MISMATCH;
+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.WAS_CLOSED_CON;
+import static org.apache.cassandra.cql.jdbc.Utils.determineCurrentKeyspace;
 
-import java.net.URI;
-import java.net.URISyntaxException;
 import java.sql.Connection;
 import java.sql.DatabaseMetaData;
 import java.sql.PreparedStatement;
-import java.sql.ResultSet;
 import java.sql.SQLClientInfoException;
 import java.sql.SQLException;
 import java.sql.SQLFeatureNotSupportedException;
@@ -40,73 +48,113 @@ import java.sql.SQLTransientConnectionEx
 import java.sql.SQLWarning;
 import java.sql.Statement;
 import java.util.ArrayList;
+import java.util.HashMap;
 import java.util.List;
+import java.util.Map;
 import java.util.Properties;
 
 import org.apache.cassandra.thrift.AuthenticationException;
+import org.apache.cassandra.thrift.AuthenticationRequest;
 import org.apache.cassandra.thrift.AuthorizationException;
+import org.apache.cassandra.thrift.Cassandra;
+import org.apache.cassandra.thrift.Compression;
+import org.apache.cassandra.thrift.CqlResult;
 import org.apache.cassandra.thrift.InvalidRequestException;
 import org.apache.cassandra.thrift.SchemaDisagreementException;
 import org.apache.cassandra.thrift.TimedOutException;
 import org.apache.cassandra.thrift.UnavailableException;
 import org.apache.thrift.TException;
+import org.apache.thrift.protocol.TBinaryProtocol;
+import org.apache.thrift.protocol.TProtocol;
+import org.apache.thrift.transport.TFramedTransport;
+import org.apache.thrift.transport.TSocket;
+import org.apache.thrift.transport.TTransport;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
 
 /**
  * Implementation class for {@link Connection}.
  */
 class CassandraConnection extends AbstractCassandraConnection implements Connection
 {
+
+    private static final Logger logger = LoggerFactory.getLogger(CassandraConnection.class);
+
+    public static final int DB_MAJOR_VERSION = 0;
+    public static final int DB_MINOR_VERSION = 8;
+    public static final String DB_PRODUCT_NAME = "Cassandra";
+
+    public static Compression defaultCompression = Compression.GZIP;
+
     private final boolean autoCommit = true;
-    
+
     private final int transactionIsolation = Connection.TRANSACTION_NONE;
-    
-    /** Client Info Properties (currently unused) */
+
+    /**
+     * Client Info Properties (currently unused)
+     */
     private Properties clientInfo = new Properties();
-    
-    /** List of all Statements that have been created by this connection */
+
+    /**
+     * List of all Statements that have been created by this connection
+     */
     private List<Statement> statements;
-    
-    /** The Cassandra connection to the Thrift transport. */
-    private org.apache.cassandra.cql.jdbc.Connection cassandraCon;
-    
+
+    private Cassandra.Client client;
+    private TTransport transport;
+
+    protected long timeOfLastFailure = 0;
+    protected int numFailures = 0;
+
+    String currentKeyspace;
+    ColumnDecoder decoder;
+
+
     /**
      * Instantiates a new CassandraConnection.
      */
-    public CassandraConnection(String url,Properties props) throws SQLException
+    public CassandraConnection(Properties props) throws SQLException
     {
         statements = new ArrayList<Statement>();
         clientInfo = new Properties();
         try
         {
-            String rawUri = url.substring(PROTOCOL.length());
-            URI uri = new URI(rawUri);
+            String host = props.getProperty(TAG_SERVER_NAME);
+            int port = Integer.parseInt(props.getProperty(TAG_PORT_NUMBER));
+            String keyspace = props.getProperty(TAG_DATABASE_NAME);
+            String username = props.getProperty(TAG_USER);
+            String password = props.getProperty(TAG_PASSWORD);
+
+            TSocket socket = new TSocket(host, port);
+            transport = new TFramedTransport(socket);
+            TProtocol protocol = new TBinaryProtocol(transport);
+            client = new Cassandra.Client(protocol);
+            socket.open();
+            decoder = new ColumnDecoder(client.describe_keyspaces());
+
+            if (username != null)
+            {
+                Map<String, String> credentials = new HashMap<String, String>();
+                credentials.put("username", username);
+                if (password != null) credentials.put("password", password);
+                AuthenticationRequest areq = new AuthenticationRequest(credentials);
+                client.login(areq);
+
+            }
+
+            logger.info("Connected to {}:{}", host, port);
 
-            String host = uri.getHost() == null ? "localhost" : uri.getHost();
-            int port = (uri.getPort() == -1) ? 9160 : uri.getPort();
-            String keyspace = (uri.getPath().length() == 0) ? null : uri.getPath().substring(1);
-            String userInfo = uri.getUserInfo();
-            String[] s = new String[0];
-
-            if ((userInfo != null) && (!userInfo.isEmpty()))
-                s = userInfo.split(":");
-
-            // use user and password from the properties file( which takes precedence over url values)
-            String username = props.getProperty("user", (s.length > 0) ? s[0] : null);
-            String password = props.getProperty("password", (s.length > 1) ? s[1] : null);
 
-            cassandraCon = new org.apache.cassandra.cql.jdbc.Connection(host, port, username, password);
-            final String useQ = "USE " + keyspace;
             if (keyspace != null)
-                cassandraCon.execute(useQ);
+            {
+                execute("USE " + keyspace);
+            }
         }
         catch (SchemaDisagreementException e)
         {
             throw new SQLRecoverableException(SCHEMA_MISMATCH);
         }
-        catch (URISyntaxException e)
-        {
-            throw new SQLNonTransientConnectionException(e);
-        }
         catch (InvalidRequestException e)
         {
             throw new SQLSyntaxErrorException(e);
@@ -132,12 +180,12 @@ class CassandraConnection extends Abstra
             throw new SQLInvalidAuthorizationSpecException(e);
         }
     }
-    
+
     private final void checkNotClosed() throws SQLException
     {
         if (isClosed()) throw new SQLNonTransientConnectionException(WAS_CLOSED_CON);
     }
-    
+
     public void clearWarnings() throws SQLException
     {
         // This implementation does not support the collection of warnings so clearing is a no-op
@@ -150,11 +198,12 @@ class CassandraConnection extends Abstra
      */
     public synchronized void close() throws SQLException
     {
-        if (cassandraCon != null)
+        if (isConnected())
         {
             // spec says to close all statements associated with this connection upon close
             for (Statement statement : statements) statement.close();
-            cassandraCon.close();
+            // then disconnect from the transport                
+            disconnect();
         }
     }
 
@@ -167,21 +216,21 @@ class CassandraConnection extends Abstra
     public Statement createStatement() throws SQLException
     {
         checkNotClosed();
-        statements.add(new CassandraStatement(this.cassandraCon));
+        statements.add(new CassandraStatement(this));
         return statements.get(statements.size() - 1);
     }
 
     public Statement createStatement(int resultSetType, int resultSetConcurrency) throws SQLException
     {
         checkNotClosed();
-        statements.add(new CassandraStatement(this.cassandraCon, null, resultSetType, resultSetConcurrency));
+        statements.add(new CassandraStatement(this, null, resultSetType, resultSetConcurrency));
         return statements.get(statements.size() - 1);
     }
 
     public Statement createStatement(int resultSetType, int resultSetConcurrency, int resultSetHoldability) throws SQLException
     {
         checkNotClosed();
-        statements.add(new CassandraStatement(this.cassandraCon, null, resultSetType, resultSetConcurrency, resultSetHoldability));
+        statements.add(new CassandraStatement(this, null, resultSetType, resultSetConcurrency, resultSetHoldability));
         return statements.get(statements.size() - 1);
     }
 
@@ -204,7 +253,7 @@ class CassandraConnection extends Abstra
         checkNotClosed();
         return clientInfo;
     }
-    
+
     public String getClientInfo(String label) throws SQLException
     {
         checkNotClosed();
@@ -215,9 +264,9 @@ class CassandraConnection extends Abstra
     {
         checkNotClosed();
         // the rationale is there are really no commits in Cassandra so no boundary...
-        return ResultSet.HOLD_CURSORS_OVER_COMMIT;
+        return CResultSet.DEFAULT_HOLDABILITY;
     }
-    
+
     public DatabaseMetaData getMetaData() throws SQLException
     {
         checkNotClosed();
@@ -240,9 +289,8 @@ class CassandraConnection extends Abstra
 
     public synchronized boolean isClosed() throws SQLException
     {
-        if (cassandraCon == null) return true;
 
-        return !cassandraCon.isOpen();
+        return !isConnected();
     }
 
     public boolean isReadOnly() throws SQLException
@@ -276,8 +324,8 @@ class CassandraConnection extends Abstra
     public PreparedStatement prepareStatement(String sql) throws SQLException
     {
         checkNotClosed();
-        statements.add(new CassandraPreparedStatement(this.cassandraCon, sql));
-        return (PreparedStatement)statements.get(statements.size() - 1);
+        statements.add(new CassandraPreparedStatement(this, sql));
+        return (PreparedStatement) statements.get(statements.size() - 1);
     }
 
     public PreparedStatement prepareStatement(String arg0, int arg1, int arg2) throws SQLException
@@ -327,7 +375,7 @@ class CassandraConnection extends Abstra
         // the rationale is there are no holdability to set in this implementation...
         // so we are "silently ignoring" the request
     }
-    
+
     public void setReadOnly(boolean arg0) throws SQLException
     {
         checkNotClosed();
@@ -345,4 +393,64 @@ class CassandraConnection extends Abstra
     {
         throw new SQLFeatureNotSupportedException(String.format(NO_INTERFACE, iface.getSimpleName()));
     }
+
+    /**
+     * Execute a CQL query.
+     *
+     * @param queryStr    a CQL query string
+     * @param compression query compression to use
+     * @return the query results encoded as a CqlResult structure
+     * @throws InvalidRequestException     on poorly constructed or illegal requests
+     * @throws UnavailableException        when not all required replicas could be created/read
+     * @throws TimedOutException           when a cluster operation timed out
+     * @throws SchemaDisagreementException when the client side and server side are at different versions of schema (Thrift)
+     * @throws TException                  when there is a error in Thrift processing
+     */
+    public CqlResult execute(String queryStr, Compression compression) throws InvalidRequestException, UnavailableException, TimedOutException, SchemaDisagreementException, TException
+    {
+        currentKeyspace = determineCurrentKeyspace(queryStr, currentKeyspace);
+
+        try
+        {
+            return client.execute_cql_query(Utils.compressQuery(queryStr, compression), compression);
+        }
+        catch (TException error)
+        {
+            numFailures++;
+            timeOfLastFailure = System.currentTimeMillis();
+            throw error;
+        }
+    }
+
+    /**
+     * Execute a CQL query using the default compression methodology.
+     *
+     * @param queryStr a CQL query string
+     * @return the query results encoded as a CqlResult structure
+     * @throws InvalidRequestException     on poorly constructed or illegal requests
+     * @throws UnavailableException        when not all required replicas could be created/read
+     * @throws TimedOutException           when a cluster operation timed out
+     * @throws SchemaDisagreementException when the client side and server side are at different versions of schema (Thrift)
+     * @throws TException                  when there is a error in Thrift processing
+     */
+    public CqlResult execute(String queryStr) throws InvalidRequestException, UnavailableException, TimedOutException, SchemaDisagreementException, TException
+    {
+        return execute(queryStr, defaultCompression);
+    }
+
+    /**
+     * Shutdown the remote connection
+     */
+    public void disconnect()
+    {
+        transport.close();
+    }
+
+    /**
+     * Connection state.
+     */
+    public boolean isConnected()
+    {
+        return transport.isOpen();
+    }
 }

Modified: cassandra/drivers/java/src/org/apache/cassandra/cql/jdbc/CassandraDriver.java
URL: http://svn.apache.org/viewvc/cassandra/drivers/java/src/org/apache/cassandra/cql/jdbc/CassandraDriver.java?rev=1149432&r1=1149431&r2=1149432&view=diff
==============================================================================
--- cassandra/drivers/java/src/org/apache/cassandra/cql/jdbc/CassandraDriver.java (original)
+++ cassandra/drivers/java/src/org/apache/cassandra/cql/jdbc/CassandraDriver.java Fri Jul 22 01:59:09 2011
@@ -20,29 +20,34 @@
  */
 package org.apache.cassandra.cql.jdbc;
 
-import static org.apache.cassandra.cql.jdbc.Utils.*;
+import static org.apache.cassandra.cql.jdbc.Utils.PROTOCOL;
+import static org.apache.cassandra.cql.jdbc.Utils.TAG_PASSWORD;
+import static org.apache.cassandra.cql.jdbc.Utils.TAG_USER;
 
 import java.sql.Connection;
 import java.sql.Driver;
 import java.sql.DriverManager;
 import java.sql.DriverPropertyInfo;
 import java.sql.SQLException;
-import java.sql.SQLNonTransientConnectionException;
 import java.util.Properties;
 
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
 /**
-  * The Class CassandraDriver.
-  */
- public class CassandraDriver implements Driver
+ * The Class CassandraDriver.
+ */
+public class CassandraDriver implements Driver
 {
-    
-    /** The Constant MAJOR_VERSION. */
-    private static final int MAJOR_VERSION = 1;
-    
-    /** The Constant MINOR_VERSION. */
-    private static final int MINOR_VERSION = 0;
+    public static final int DVR_MAJOR_VERSION = 1;
+
+    public static final int DVR_MINOR_VERSION = 0;
+
+    public static final int DVR_PATCH_VERSION = 4;
 
-//    private static final Logger logger = LoggerFactory.getLogger(CassandraDriver.class); 
+    public static final String DVR_NAME = "Cassandra JDBC Driver";
+
+    private static final Logger logger = LoggerFactory.getLogger(CassandraDriver.class);
 
     static
     {
@@ -54,10 +59,10 @@ import java.util.Properties;
         }
         catch (SQLException e)
         {
-            throw new DriverResolverException(e.getMessage());
+            throw new RuntimeException(e.getMessage());
         }
     }
-    
+
     /**
      * Method to validate whether provided connection url matches with pattern or not.
      */
@@ -71,9 +76,18 @@ import java.util.Properties;
      */
     public Connection connect(String url, Properties props) throws SQLException
     {
+        Properties finalProps;
         if (acceptsURL(url))
         {
-            return new CassandraConnection(url, props);
+            // parse the URL into a set of Properties
+            finalProps = Utils.parseURL(url);
+
+            // override any matching values in finalProps with values from props
+            finalProps.putAll(props);
+
+            if (logger.isDebugEnabled()) logger.debug("Final Properties to Connection: {}", finalProps);
+
+            return new CassandraConnection(finalProps);
         }
         else
         {
@@ -86,7 +100,7 @@ import java.util.Properties;
      */
     public int getMajorVersion()
     {
-        return MAJOR_VERSION;
+        return DVR_MAJOR_VERSION;
     }
 
     /**
@@ -94,15 +108,25 @@ import java.util.Properties;
      */
     public int getMinorVersion()
     {
-        return MINOR_VERSION;
+        return DVR_MINOR_VERSION;
     }
 
     /**
      * Returns default driver property info object.
      */
-    public DriverPropertyInfo[] getPropertyInfo(String arg0, Properties arg1) throws SQLException
+    public DriverPropertyInfo[] getPropertyInfo(String url, Properties props) throws SQLException
     {
-        return new DriverPropertyInfo[0];
+        if (props == null) props = new Properties();
+
+        DriverPropertyInfo[] info = new DriverPropertyInfo[2];
+
+        info[0] = new DriverPropertyInfo(TAG_USER, props.getProperty(TAG_USER));
+        info[0].description = "The 'user' property";
+
+        info[1] = new DriverPropertyInfo(TAG_PASSWORD, props.getProperty(TAG_PASSWORD));
+        info[1].description = "The 'password' property";
+
+        return info;
     }
 
     /**

Modified: cassandra/drivers/java/src/org/apache/cassandra/cql/jdbc/CassandraPreparedStatement.java
URL: http://svn.apache.org/viewvc/cassandra/drivers/java/src/org/apache/cassandra/cql/jdbc/CassandraPreparedStatement.java?rev=1149432&r1=1149431&r2=1149432&view=diff
==============================================================================
--- cassandra/drivers/java/src/org/apache/cassandra/cql/jdbc/CassandraPreparedStatement.java (original)
+++ cassandra/drivers/java/src/org/apache/cassandra/cql/jdbc/CassandraPreparedStatement.java Fri Jul 22 01:59:09 2011
@@ -20,6 +20,11 @@ package org.apache.cassandra.cql.jdbc;
  * 
  */
 
+import static org.apache.cassandra.cql.jdbc.Utils.determineCurrentKeyspace;
+import static org.apache.cassandra.cql.jdbc.Utils.determineCurrentColumnFamily;
+import static org.apache.cassandra.cql.jdbc.Utils.NO_CF;
+import static org.apache.cassandra.cql.jdbc.Utils.NO_COMPARATOR;
+import static org.apache.cassandra.cql.jdbc.Utils.NO_VALIDATOR;
 
 import org.apache.cassandra.db.marshal.*;
 
@@ -40,8 +45,10 @@ import java.sql.Ref;
 import java.sql.ResultSet;
 import java.sql.ResultSetMetaData;
 import java.sql.RowId;
+import java.sql.SQLDataException;
 import java.sql.SQLException;
 import java.sql.SQLFeatureNotSupportedException;
+import java.sql.SQLTransientException;
 import java.sql.SQLXML;
 import java.sql.Time;
 import java.sql.Timestamp;
@@ -55,31 +62,31 @@ import java.util.regex.Pattern;
 
 public class CassandraPreparedStatement extends CassandraStatement implements PreparedStatement
 {
-//    private static final Pattern Parameterizable = Pattern.compile("(SELECT|DELETE|UPDATE)\\s+.*", Pattern.CASE_INSENSITIVE);
+    //    private static final Pattern Parameterizable = Pattern.compile("(SELECT|DELETE|UPDATE)\\s+.*", Pattern.CASE_INSENSITIVE);
     private static final Pattern Select = Pattern.compile("SELECT[\\s+FIRST\\s+\\d+]?[\\s+REVERSED]?\\s+(.*)WHERE\\s+(.*)", Pattern.CASE_INSENSITIVE);
     private static final Pattern Update = Pattern.compile("UPDATE\\s+\\w+.*\\s+SET\\s+(.*)\\s+WHERE KEY(.*)", Pattern.CASE_INSENSITIVE);
     private static final Pattern Delete = Pattern.compile("DELETE\\s+(.*)\\s+FROM\\s+\\w+\\s+WHERE KEY(.*)", Pattern.CASE_INSENSITIVE);
-    
+
     // current set of bound variables.
     private final Map<Integer, Object> variables = new HashMap<Integer, Object>();
-    
+
     // for batching. These are the queries that have been batched and not executed.
     private final List<String> queries = new ArrayList<String>();
-    
-    CassandraPreparedStatement(Connection con, String cql) throws SQLException
+
+    CassandraPreparedStatement(CassandraConnection con, String cql) throws SQLException
     {
         super(con, cql);
     }
-    
+
     // impl specific methods start here.
 
     // double quotes strings (in parameters)
-    private static String makeCqlString(String s) 
+    private static String makeCqlString(String s)
     {
         // escape any single-quotes with double single-quotes.
         return s.replaceAll("\'", "\'\'");
     }
-    
+
     // null type means just call param.toString() and quote it (default for keys).
     private static String applySimpleBindings(String q, AbstractType type, ParameterIterator params) throws SQLException
     {
@@ -113,11 +120,11 @@ public class CassandraPreparedStatement 
             }
             else
                 sb.append(c);
-                
+
         }
         return sb.toString();
     }
-    
+
     private static String applyDualBindings(String q, AbstractType ltype, AbstractType rtype, ParameterIterator params) throws SQLException
     {
         StringBuffer sb = new StringBuffer();
@@ -131,7 +138,7 @@ public class CassandraPreparedStatement 
                 left = false;
             if (c == ',' && !between)
                 left = true;
-            
+
             if (c == '?' && !between)
             {
                 try
@@ -153,10 +160,12 @@ public class CassandraPreparedStatement 
         }
         return sb.toString();
     }
-    
-    /** applies current bindings to produce a string that can be sent to the server. */
+
+    /**
+     * applies current bindings to produce a string that can be sent to the server.
+     */
     public synchronized String makeCql() throws SQLException
-    { 
+    {
         // break cql up
         Matcher m;
         m = Delete.matcher(cql);
@@ -168,77 +177,79 @@ public class CassandraPreparedStatement 
         m = Select.matcher(cql);
         if (m.matches())
             return makeSelect(m.end(1));
-        
+
         // if we made it this far, cql is not parameterizable. this isn't bad, there is just nothing to be done.
         return cql;
     }
-    
+
     // subs parameters into a delete statement.
     private String makeDelete(int pivot) throws SQLException
-    { 
-        String keyspace = connection.getKeyspace(cql);
-        String columnFamily = connection.getColumnFamily(cql);
+    {
+        String keyspace = determineCurrentKeyspace(cql, connection.currentKeyspace);
+        String columnFamily = determineCurrentColumnFamily(cql);
+        if (columnFamily == null) throw new SQLTransientException(NO_CF);
+
         ParameterIterator params = new ParameterIterator();
         String left = cql.substring(0, pivot);
         AbstractType leftType = connection.decoder.getComparator(keyspace, columnFamily);
-        if (leftType == null)
-            throw new SQLException("Could not find comparator for " + keyspace + "." + columnFamily);
+        if (leftType == null) throw new SQLDataException(String.format(NO_COMPARATOR, keyspace, columnFamily));
         left = applySimpleBindings(left, leftType, params);
+
         String right = cql.substring(pivot);
         AbstractType keyVald = connection.decoder.getKeyValidator(keyspace, columnFamily);
-        if (keyVald == null)
-            throw new SQLException("Could not find key validator for " + keyspace + "." + columnFamily);
+        if (keyVald == null) throw new SQLDataException(String.format(NO_VALIDATOR, keyspace, columnFamily));
         right = applySimpleBindings(right, keyVald, params);
         return left + right;
     }
-    
+
     // subs parameters into a select statement.
     private String makeSelect(int pivot) throws SQLException
-    { 
-        String keyspace = connection.getKeyspace(cql);
-        String columnFamily = connection.getColumnFamily(cql);
+    {
+        String keyspace = determineCurrentKeyspace(cql, connection.currentKeyspace);
+        String columnFamily = determineCurrentColumnFamily(cql);
+        if (columnFamily == null) throw new SQLTransientException(NO_CF);
+
         ParameterIterator params = new ParameterIterator();
         String left = cql.substring(0, pivot);
         AbstractType leftType = connection.decoder.getComparator(keyspace, columnFamily);
-        if (leftType == null)
-            throw new SQLException("Could not find comparator for " + keyspace + "." + columnFamily);
+        if (leftType == null) throw new SQLDataException(String.format(NO_COMPARATOR, keyspace, columnFamily));
         left = applySimpleBindings(left, leftType, params);
+
         String right = cql.substring(pivot);
         AbstractType keyVald = connection.decoder.getKeyValidator(keyspace, columnFamily);
-        if (keyVald == null)
-            throw new SQLException("Could not find key validator for " + keyspace + "." + columnFamily);
+        if (keyVald == null) throw new SQLDataException(String.format(NO_VALIDATOR, keyspace, columnFamily));
         right = applySimpleBindings(right, keyVald, params);
         return left + right;
     }
-    
+
     // subs parameters into an update statement.
     private String makeUpdate(int pivot) throws SQLException
     {
         // this one is a little bit different. left contains key=value pairs. we use the comparator for the left side,
         // the validator for the right side.  right side is treated as a key.
-        String keyspace = connection.getKeyspace(cql);
-        String columnFamily = connection.getColumnFamily(cql);
+        String keyspace = determineCurrentKeyspace(cql, connection.currentKeyspace);
+        String columnFamily = determineCurrentColumnFamily(cql);
+        if (columnFamily == null) throw new SQLTransientException(NO_CF);
+
         ParameterIterator params = new ParameterIterator();
         String left = cql.substring(0, pivot);
         AbstractType leftComp = connection.decoder.getComparator(keyspace, columnFamily);
-        if (leftComp == null)
-            throw new SQLException("Could not find comparator for " + keyspace + "." + columnFamily);
+        if (leftComp == null) throw new SQLDataException(String.format(NO_COMPARATOR, keyspace, columnFamily));
+
         AbstractType leftVald = connection.decoder.getComparator(keyspace, columnFamily);
-        if (leftVald == null)
-            throw new SQLException("Could not find validator for " + keyspace + "." + columnFamily);
+        if (leftVald == null) throw new SQLDataException(String.format(NO_VALIDATOR, keyspace, columnFamily));
         left = applyDualBindings(left, leftComp, leftVald, params);
+
         String right = cql.substring(pivot);
         AbstractType keyVald = connection.decoder.getKeyValidator(keyspace, columnFamily);
-        if (keyVald == null)
-            throw new SQLException("Could not find key validator for " + keyspace + "." + columnFamily);
+        if (keyVald == null) throw new SQLDataException(String.format(NO_VALIDATOR, keyspace, columnFamily));
         right = applySimpleBindings(right, keyVald, params);
-        return left + right; 
+        return left + right;
     }
-    
-    
-    
+
+
     // standard API methods follow.
-    
+
     public void addBatch() throws SQLException
     {
         queries.add(makeCql());
@@ -253,12 +264,12 @@ public class CassandraPreparedStatement 
     {
         return this.cql != null && super.execute(makeCql());
     }
-    
+
     public ResultSet executeQuery() throws SQLException
     {
         return this.cql != null ? super.executeQuery(makeCql()) : null;
     }
-    
+
     public int executeUpdate() throws SQLException
     {
         String q = makeCql();
@@ -273,13 +284,13 @@ public class CassandraPreparedStatement 
     {
         // todo: current impl of RSMD relies on knowing the results. implementing this will require refactoring CRSMD into 
         // two classes: the first will be an implementation whose methods don't rely on knowing the results, the second
-        // will implement the full CRSMD interfae and extend or compose the first.
+        // will implement the full CRSMD interface and extend or compose the first.
         throw new SQLFeatureNotSupportedException("PreparedStatement.getMetaData() hasn't been implemented yet.");
     }
 
     public void setByte(int parameterIndex, byte x) throws SQLException
     {
-        setObject(parameterIndex, new byte[]{x});
+        setObject(parameterIndex, new byte[]{ x });
     }
 
     public void setBytes(int parameterIndex, byte[] x) throws SQLException
@@ -316,11 +327,11 @@ public class CassandraPreparedStatement 
     {
         setObject(parameterIndex, x);
     }
-    
-    
+
+
     // everything below here is not implemented and will let you know about it.
-    
-    
+
+
     public ParameterMetaData getParameterMetaData() throws SQLException
     {
         throw new SQLFeatureNotSupportedException("PreparedStatement.getParameterMetaData() hasn't been implemented yet.");
@@ -328,77 +339,77 @@ public class CassandraPreparedStatement 
 
     public void setArray(int parameterIndex, Array x) throws SQLException
     {
-        throw new SQLFeatureNotSupportedException("method not supported");
+        throw new SQLFeatureNotSupportedException(NOT_SUPPORTED);
     }
 
     public void setAsciiStream(int parameterIndex, InputStream x) throws SQLException
     {
-        throw new SQLFeatureNotSupportedException("method not supported");
+        throw new SQLFeatureNotSupportedException(NOT_SUPPORTED);
     }
 
     public void setAsciiStream(int parameterIndex, InputStream x, int length) throws SQLException
     {
-        throw new SQLFeatureNotSupportedException("method not supported");
+        throw new SQLFeatureNotSupportedException(NOT_SUPPORTED);
     }
 
     public void setAsciiStream(int parameterIndex, InputStream x, long length) throws SQLException
     {
-        throw new SQLFeatureNotSupportedException("method not supported");
+        throw new SQLFeatureNotSupportedException(NOT_SUPPORTED);
     }
 
     public void setBigDecimal(int parameterIndex, BigDecimal x) throws SQLException
     {
-        throw new SQLFeatureNotSupportedException("method not supported");
+        throw new SQLFeatureNotSupportedException(NOT_SUPPORTED);
     }
 
     public void setBinaryStream(int parameterIndex, InputStream x) throws SQLException
     {
-        throw new SQLFeatureNotSupportedException("method not supported");
+        throw new SQLFeatureNotSupportedException(NOT_SUPPORTED);
     }
 
     public void setBinaryStream(int parameterIndex, InputStream x, int length) throws SQLException
     {
-        throw new SQLFeatureNotSupportedException("method not supported");
+        throw new SQLFeatureNotSupportedException(NOT_SUPPORTED);
     }
 
     public void setBinaryStream(int parameterIndex, InputStream x, long length) throws SQLException
     {
-        throw new SQLFeatureNotSupportedException("method not supported");
+        throw new SQLFeatureNotSupportedException(NOT_SUPPORTED);
     }
 
     public void setBlob(int parameterIndex, Blob x) throws SQLException
     {
-        throw new SQLFeatureNotSupportedException("method not supported");
+        throw new SQLFeatureNotSupportedException(NOT_SUPPORTED);
     }
 
     public void setBlob(int parameterIndex, InputStream inputStream) throws SQLException
     {
-        throw new SQLFeatureNotSupportedException("method not supported");
+        throw new SQLFeatureNotSupportedException(NOT_SUPPORTED);
     }
 
     public void setBlob(int parameterIndex, InputStream inputStream, long length) throws SQLException
     {
-        throw new SQLFeatureNotSupportedException("method not supported");
+        throw new SQLFeatureNotSupportedException(NOT_SUPPORTED);
     }
 
     public void setBoolean(int parameterIndex, boolean x) throws SQLException
     {
-        throw new SQLFeatureNotSupportedException("method not supported");
+        throw new SQLFeatureNotSupportedException(NOT_SUPPORTED);
     }
 
     public void setCharacterStream(int parameterIndex, Reader reader) throws SQLException
     {
-        throw new SQLFeatureNotSupportedException("method not supported");
+        throw new SQLFeatureNotSupportedException(NOT_SUPPORTED);
     }
 
     public void setCharacterStream(int parameterIndex, Reader reader, int length) throws SQLException
     {
-        throw new SQLFeatureNotSupportedException("method not supported");
+        throw new SQLFeatureNotSupportedException(NOT_SUPPORTED);
     }
 
     public void setCharacterStream(int parameterIndex, Reader reader, long length) throws SQLException
     {
-        throw new SQLFeatureNotSupportedException("method not supported");
+        throw new SQLFeatureNotSupportedException(NOT_SUPPORTED);
     }
 
     public void setClob(int parameterIndex, Clob x) throws SQLException
@@ -408,142 +419,141 @@ public class CassandraPreparedStatement 
 
     public void setClob(int parameterIndex, Reader reader) throws SQLException
     {
-        throw new SQLFeatureNotSupportedException("method not supported");
+        throw new SQLFeatureNotSupportedException(NOT_SUPPORTED);
     }
 
     public void setClob(int parameterIndex, Reader reader, long length) throws SQLException
     {
-        throw new SQLFeatureNotSupportedException("method not supported");
+        throw new SQLFeatureNotSupportedException(NOT_SUPPORTED);
     }
 
     public void setDate(int parameterIndex, Date x) throws SQLException
     {
-        throw new SQLFeatureNotSupportedException("method not supported");
+        throw new SQLFeatureNotSupportedException(NOT_SUPPORTED);
     }
 
     public void setDate(int parameterIndex, Date x, Calendar cal) throws SQLException
     {
-        throw new SQLFeatureNotSupportedException("method not supported");
+        throw new SQLFeatureNotSupportedException(NOT_SUPPORTED);
     }
 
     public void setDouble(int parameterIndex, double x) throws SQLException
     {
-        throw new SQLFeatureNotSupportedException("method not supported");
+        throw new SQLFeatureNotSupportedException(NOT_SUPPORTED);
     }
 
     public void setFloat(int parameterIndex, float x) throws SQLException
     {
-        throw new SQLFeatureNotSupportedException("method not supported");
+        throw new SQLFeatureNotSupportedException(NOT_SUPPORTED);
     }
-    
+
     public void setNCharacterStream(int parameterIndex, Reader value) throws SQLException
     {
-        throw new SQLFeatureNotSupportedException("method not supported");
+        throw new SQLFeatureNotSupportedException(NOT_SUPPORTED);
     }
 
     public void setNCharacterStream(int parameterIndex, Reader value, long length) throws SQLException
     {
-        throw new SQLFeatureNotSupportedException("method not supported");
+        throw new SQLFeatureNotSupportedException(NOT_SUPPORTED);
     }
 
     public void setNClob(int parameterIndex, NClob value) throws SQLException
     {
-        throw new SQLFeatureNotSupportedException("method not supported");
+        throw new SQLFeatureNotSupportedException(NOT_SUPPORTED);
     }
 
     public void setNClob(int parameterIndex, Reader reader) throws SQLException
     {
-        throw new SQLFeatureNotSupportedException("method not supported");
+        throw new SQLFeatureNotSupportedException(NOT_SUPPORTED);
     }
 
     public void setNClob(int parameterIndex, Reader reader, long length) throws SQLException
     {
-        throw new SQLFeatureNotSupportedException("method not supported");
+        throw new SQLFeatureNotSupportedException(NOT_SUPPORTED);
     }
-    
+
     public void setNull(int parameterIndex, int sqlType) throws SQLException
     {
-        throw new SQLFeatureNotSupportedException("method not supported");
+        throw new SQLFeatureNotSupportedException(NOT_SUPPORTED);
     }
 
     public void setNull(int parameterIndex, int sqlType, String typeName) throws SQLException
     {
-        throw new SQLFeatureNotSupportedException("method not supported");
+        throw new SQLFeatureNotSupportedException(NOT_SUPPORTED);
     }
-    
+
     public void setObject(int parameterIndex, Object x, int targetSqlType) throws SQLException
     {
-        throw new SQLFeatureNotSupportedException("method not supported");
+        throw new SQLFeatureNotSupportedException(NOT_SUPPORTED);
     }
 
     public void setObject(int parameterIndex, Object x, int targetSqlType, int scaleOrLength) throws SQLException
     {
-        throw new SQLFeatureNotSupportedException("method not supported");
+        throw new SQLFeatureNotSupportedException(NOT_SUPPORTED);
     }
 
     public void setRef(int parameterIndex, Ref x) throws SQLException
     {
-        throw new SQLFeatureNotSupportedException("method not supported");
+        throw new SQLFeatureNotSupportedException(NOT_SUPPORTED);
     }
 
     public void setRowId(int parameterIndex, RowId x) throws SQLException
     {
-        throw new SQLFeatureNotSupportedException("method not supported");
+        throw new SQLFeatureNotSupportedException(NOT_SUPPORTED);
     }
 
     public void setSQLXML(int parameterIndex, SQLXML xmlObject) throws SQLException
     {
-        throw new SQLFeatureNotSupportedException("method not supported");
+        throw new SQLFeatureNotSupportedException(NOT_SUPPORTED);
     }
-    
+
     public void setTime(int parameterIndex, Time x) throws SQLException
     {
-        throw new SQLFeatureNotSupportedException("method not supported");
+        throw new SQLFeatureNotSupportedException(NOT_SUPPORTED);
     }
 
     public void setTime(int parameterIndex, Time x, Calendar cal) throws SQLException
     {
-        throw new SQLFeatureNotSupportedException("method not supported");
+        throw new SQLFeatureNotSupportedException(NOT_SUPPORTED);
     }
 
     public void setTimestamp(int parameterIndex, Timestamp x) throws SQLException
     {
-        throw new SQLFeatureNotSupportedException("method not supported");
+        throw new SQLFeatureNotSupportedException(NOT_SUPPORTED);
     }
 
     public void setTimestamp(int parameterIndex, Timestamp x, Calendar cal) throws SQLException
     {
-        throw new SQLFeatureNotSupportedException("method not supported");
+        throw new SQLFeatureNotSupportedException(NOT_SUPPORTED);
     }
 
     public void setURL(int parameterIndex, URL x) throws SQLException
     {
-        throw new SQLFeatureNotSupportedException("method not supported");
+        throw new SQLFeatureNotSupportedException(NOT_SUPPORTED);
     }
 
     public void setUnicodeStream(int parameterIndex, InputStream x, int length) throws SQLException
     {
-        throw new SQLFeatureNotSupportedException("method not supported");
+        throw new SQLFeatureNotSupportedException(NOT_SUPPORTED);
     }
-    
-    
+
+
     // done with API methods.
-    
-    
-    
+
+
     // provides a way to iterate through the parameters. it will blow up if it discovers any missing parameters.
     // not thread-safe.
     private class ParameterIterator
     {
         private Map<Integer, Object> params = new HashMap<Integer, Object>(variables);
         private int index = 1;
-        
+
         // throws SQLException if a parameter is not specified.
         private Object nextParam() throws SQLException
         {
             Object p = params.get(index++);
             if (p == null)
-                throw new SQLException("No parameter bound to " + (index-1));
+                throw new SQLException("No parameter bound to " + (index - 1));
             return p;
         }
 

Modified: cassandra/drivers/java/src/org/apache/cassandra/cql/jdbc/CassandraStatement.java
URL: http://svn.apache.org/viewvc/cassandra/drivers/java/src/org/apache/cassandra/cql/jdbc/CassandraStatement.java?rev=1149432&r1=1149431&r2=1149432&view=diff
==============================================================================
--- cassandra/drivers/java/src/org/apache/cassandra/cql/jdbc/CassandraStatement.java (original)
+++ cassandra/drivers/java/src/org/apache/cassandra/cql/jdbc/CassandraStatement.java Fri Jul 22 01:59:09 2011
@@ -50,72 +50,77 @@ class CassandraStatement extends Abstrac
 {
     protected static final Pattern UpdatePattern = Pattern.compile("UPDATE .*", Pattern.CASE_INSENSITIVE);
 
-    /** The connection. */
-    protected org.apache.cassandra.cql.jdbc.Connection connection;
-    
-    /** The cql. */
+    /**
+     * The connection.
+     */
+    protected CassandraConnection connection;
+
+    /**
+     * The cql.
+     */
     protected String cql;
-    
+
     protected int fetchDirection = ResultSet.FETCH_FORWARD;
-    
+
     protected int fetchSize = 0;
 
     protected int maxFieldSize = 0;
 
     protected int maxRows = 0;
-    
-    protected int resultSetType = ResultSet.TYPE_FORWARD_ONLY;
-    
-    protected int resultSetConcurrency = ResultSet.TYPE_FORWARD_ONLY;
-    
-    protected int resultSetHoldability = ResultSet.HOLD_CURSORS_OVER_COMMIT;
-    
+
+    protected int resultSetType = CResultSet.DEFAULT_TYPE;
+
+    protected int resultSetConcurrency = CResultSet.DEFAULT_CONCURRENCY;
+
+    protected int resultSetHoldability = CResultSet.DEFAULT_HOLDABILITY;
+
     protected ResultSet currentResultSet = null;
-    
+
     protected int updateCount = -1;
-    
+
     protected boolean escapeProcessing = true;
 
-    CassandraStatement(org.apache.cassandra.cql.jdbc.Connection con)  throws SQLException
+    CassandraStatement(CassandraConnection con) throws SQLException
     {
         this(con, null);
     }
 
-    CassandraStatement(org.apache.cassandra.cql.jdbc.Connection con, String cql)  throws SQLException
+    CassandraStatement(CassandraConnection con, String cql) throws SQLException
     {
         this.connection = con;
         this.cql = cql;
     }
 
-    CassandraStatement(org.apache.cassandra.cql.jdbc.Connection con, String cql, int resultSetType, int resultSetConcurrency) throws SQLException
+    CassandraStatement(CassandraConnection con, String cql, int resultSetType, int resultSetConcurrency) throws SQLException
     {
-        this(con,cql,resultSetType,resultSetConcurrency, ResultSet.HOLD_CURSORS_OVER_COMMIT);
+        this(con, cql, resultSetType, resultSetConcurrency, ResultSet.HOLD_CURSORS_OVER_COMMIT);
     }
-    
-    CassandraStatement(org.apache.cassandra.cql.jdbc.Connection con, String cql, int resultSetType, int resultSetConcurrency,
+
+    CassandraStatement(CassandraConnection con, String cql, int resultSetType, int resultSetConcurrency,
                        int resultSetHoldability) throws SQLException
     {
         this.connection = con;
         this.cql = cql;
 
-        if (!(resultSetType == ResultSet.TYPE_FORWARD_ONLY 
-           || resultSetType == ResultSet.TYPE_SCROLL_INSENSITIVE 
-           || resultSetType == ResultSet.TYPE_SCROLL_SENSITIVE)) throw new SQLSyntaxErrorException(BAD_TYPE_RSET);
+        if (!(resultSetType == ResultSet.TYPE_FORWARD_ONLY
+              || resultSetType == ResultSet.TYPE_SCROLL_INSENSITIVE
+              || resultSetType == ResultSet.TYPE_SCROLL_SENSITIVE)) throw new SQLSyntaxErrorException(BAD_TYPE_RSET);
         this.resultSetType = resultSetType;
 
         if (!(resultSetConcurrency == ResultSet.CONCUR_READ_ONLY
-           || resultSetConcurrency == ResultSet.CONCUR_UPDATABLE )) throw new SQLSyntaxErrorException(BAD_TYPE_RSET);
+              || resultSetConcurrency == ResultSet.CONCUR_UPDATABLE)) throw new SQLSyntaxErrorException(BAD_TYPE_RSET);
         this.resultSetConcurrency = resultSetConcurrency;
 
 
-        if (!(resultSetHoldability == ResultSet.HOLD_CURSORS_OVER_COMMIT 
-           || resultSetHoldability == ResultSet.CLOSE_CURSORS_AT_COMMIT)) throw new SQLSyntaxErrorException(BAD_HOLD_RSET);
+        if (!(resultSetHoldability == ResultSet.HOLD_CURSORS_OVER_COMMIT
+              || resultSetHoldability == ResultSet.CLOSE_CURSORS_AT_COMMIT))
+            throw new SQLSyntaxErrorException(BAD_HOLD_RSET);
         this.resultSetHoldability = resultSetHoldability;
     }
-    
+
     public void addBatch(String arg0) throws SQLException
     {
-        checkNotClosed();        
+        checkNotClosed();
         throw new SQLFeatureNotSupportedException(NO_BATCH);
     }
 
@@ -123,10 +128,10 @@ class CassandraStatement extends Abstrac
     {
         if (isClosed()) throw new SQLRecoverableException(WAS_CLOSED_STMT);
     }
-    
+
     public void clearBatch() throws SQLException
     {
-        checkNotClosed();        
+        checkNotClosed();
         throw new SQLFeatureNotSupportedException(NO_BATCH);
     }
 
@@ -149,11 +154,13 @@ class CassandraStatement extends Abstrac
         {
             resetResults();
             CqlResult rSet = connection.execute(sql);
-            
-            switch(rSet.getType())
+            String keyspace = connection.currentKeyspace;
+            String columnfamily = determineCurrentColumnFamily(sql);
+
+            switch (rSet.getType())
             {
                 case ROWS:
-                    currentResultSet = new CResultSet(this,rSet, connection.decoder, connection.curKeyspace, connection.curColumnFamily);
+                    currentResultSet = new CResultSet(this, rSet, connection.decoder, keyspace, columnfamily);
                     break;
                 case INT:
                     updateCount = rSet.getNum();
@@ -162,7 +169,7 @@ class CassandraStatement extends Abstrac
                     updateCount = 0;
                     break;
             }
-        } 
+        }
         catch (InvalidRequestException e)
         {
             throw new SQLSyntaxErrorException(e.getWhy());
@@ -183,24 +190,25 @@ class CassandraStatement extends Abstrac
         {
             throw new SQLNonTransientConnectionException(e.getMessage());
         }
-        
+
     }
 
-     public boolean execute(String query) throws SQLException
+    public boolean execute(String query) throws SQLException
     {
         checkNotClosed();
         doExecute(query);
-        return !(currentResultSet==null);
+        return !(currentResultSet == null);
     }
+
     public boolean execute(String sql, int autoGeneratedKeys) throws SQLException
     {
         checkNotClosed();
-        
-        if (!(autoGeneratedKeys==RETURN_GENERATED_KEYS || autoGeneratedKeys==NO_GENERATED_KEYS))
-        throw new SQLSyntaxErrorException(BAD_AUTO_GEN);
-        
-        if (autoGeneratedKeys==RETURN_GENERATED_KEYS) throw new SQLFeatureNotSupportedException(NO_GEN_KEYS);
-        
+
+        if (!(autoGeneratedKeys == RETURN_GENERATED_KEYS || autoGeneratedKeys == NO_GENERATED_KEYS))
+            throw new SQLSyntaxErrorException(BAD_AUTO_GEN);
+
+        if (autoGeneratedKeys == RETURN_GENERATED_KEYS) throw new SQLFeatureNotSupportedException(NO_GEN_KEYS);
+
         return execute(sql);
     }
 
@@ -221,7 +229,7 @@ class CassandraStatement extends Abstrac
         checkNotClosed();
         if (!UpdatePattern.matcher(query).matches())
             throw new SQLSyntaxErrorException("Not an update statement.");
- 
+
         doExecute(query);
         return updateCount;
     }
@@ -229,9 +237,10 @@ class CassandraStatement extends Abstrac
     public int executeUpdate(String sql, int autoGeneratedKeys) throws SQLException
     {
         checkNotClosed();
-        
-        if (!(autoGeneratedKeys==RETURN_GENERATED_KEYS || autoGeneratedKeys==NO_GENERATED_KEYS)) throw new SQLFeatureNotSupportedException(BAD_AUTO_GEN);
-        
+
+        if (!(autoGeneratedKeys == RETURN_GENERATED_KEYS || autoGeneratedKeys == NO_GENERATED_KEYS))
+            throw new SQLFeatureNotSupportedException(BAD_AUTO_GEN);
+
         return executeUpdate(sql);
     }
 
@@ -240,7 +249,7 @@ class CassandraStatement extends Abstrac
         checkNotClosed();
         return (Connection) connection;
     }
-    
+
     public int getFetchDirection() throws SQLException
     {
         checkNotClosed();
@@ -258,7 +267,7 @@ class CassandraStatement extends Abstrac
         checkNotClosed();
         return maxFieldSize;
     }
-    
+
     public int getMaxRows() throws SQLException
     {
         checkNotClosed();
@@ -272,24 +281,24 @@ class CassandraStatement extends Abstrac
         // in the current Cassandra implementation there are never MORE results
         return false;
     }
-    
+
     public boolean getMoreResults(int current) throws SQLException
     {
         checkNotClosed();
-        
+
         switch (current)
         {
-            case CLOSE_CURRENT_RESULT: 
+            case CLOSE_CURRENT_RESULT:
                 resetResults();
                 break;
-                
-            case CLOSE_ALL_RESULTS: 
-            case KEEP_CURRENT_RESULT: 
+
+            case CLOSE_ALL_RESULTS:
+            case KEEP_CURRENT_RESULT:
                 throw new SQLFeatureNotSupportedException(NO_MULTIPLE);
-                
-            default: 
+
+            default:
                 throw new SQLSyntaxErrorException(String.format(BAD_KEEP_RSET, current));
-       }
+        }
         // in the current Cassandra implementation there are never MORE results
         return false;
     }
@@ -299,13 +308,13 @@ class CassandraStatement extends Abstrac
         // the Cassandra implementation does not support timeouts on queries
         return 0;
     }
-    
+
     public ResultSet getResultSet() throws SQLException
     {
         checkNotClosed();
         return currentResultSet;
     }
-    
+
     public int getResultSetConcurrency() throws SQLException
     {
         checkNotClosed();
@@ -317,14 +326,14 @@ class CassandraStatement extends Abstrac
         checkNotClosed();
         // the Cassandra implementations does not support commits so this is the closest match
         return ResultSet.HOLD_CURSORS_OVER_COMMIT;
-    }    
-    
+    }
+
     public int getResultSetType() throws SQLException
     {
         checkNotClosed();
         return ResultSet.TYPE_FORWARD_ONLY;
     }
-    
+
     public int getUpdateCount() throws SQLException
     {
         checkNotClosed();
@@ -339,7 +348,7 @@ class CassandraStatement extends Abstrac
 
     public boolean isClosed() throws SQLException
     {
-        return connection==null;
+        return connection == null;
     }
 
     public boolean isPoolable() throws SQLException
@@ -352,13 +361,13 @@ class CassandraStatement extends Abstrac
     {
         return false;
     }
-    
+
     private final void resetResults()
     {
         currentResultSet = null;
         updateCount = -1;
     }
-    
+
     public void setEscapeProcessing(boolean enable) throws SQLException
     {
         checkNotClosed();
@@ -372,18 +381,18 @@ class CassandraStatement extends Abstrac
 
         if (direction == ResultSet.FETCH_FORWARD || direction == ResultSet.FETCH_REVERSE || direction == ResultSet.FETCH_UNKNOWN)
         {
-            if ((getResultSetType() == ResultSet.TYPE_FORWARD_ONLY) && (direction != ResultSet.FETCH_FORWARD)) 
+            if ((getResultSetType() == ResultSet.TYPE_FORWARD_ONLY) && (direction != ResultSet.FETCH_FORWARD))
                 throw new SQLSyntaxErrorException(String.format(BAD_FETCH_DIR, direction));
             fetchDirection = direction;
         }
         throw new SQLSyntaxErrorException(String.format(BAD_FETCH_DIR, direction));
     }
-    
-    
+
+
     public void setFetchSize(int size) throws SQLException
     {
         checkNotClosed();
-        if (size < 0 ) throw new SQLSyntaxErrorException(String.format(BAD_FETCH_SIZE, size));
+        if (size < 0) throw new SQLSyntaxErrorException(String.format(BAD_FETCH_SIZE, size));
         fetchSize = size;
     }
 
@@ -392,7 +401,7 @@ class CassandraStatement extends Abstrac
         checkNotClosed();
         // silently ignore this setting. always use default 0 (unlimited)
     }
-    
+
     public void setMaxRows(int arg0) throws SQLException
     {
         checkNotClosed();
@@ -410,7 +419,7 @@ class CassandraStatement extends Abstrac
         checkNotClosed();
         // silently ignore any attempt to set this away from the current default (0)
     }
-    
+
     public <T> T unwrap(Class<T> iface) throws SQLException
     {
         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=1149432&r1=1149431&r2=1149432&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 Fri Jul 22 01:59:09 2011
@@ -22,30 +22,61 @@
 package org.apache.cassandra.cql.jdbc;
 
 import java.io.ByteArrayOutputStream;
+import java.net.URI;
+import java.net.URISyntaxException;
 import java.nio.ByteBuffer;
+import java.sql.SQLException;
+import java.sql.SQLNonTransientConnectionException;
+import java.sql.SQLSyntaxErrorException;
+import java.util.Properties;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
 import java.util.zip.Deflater;
 
-import com.google.common.base.Charsets;
 import org.apache.cassandra.thrift.Compression;
+
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
+import com.google.common.base.Charsets;
+
+/**
+ * A set of static utility methods used by the JDBC Suite, and various default values and error message strings
+ * that can be shared across classes.
+ */
 class Utils
 {
-    protected static final String PROTOCOL = "jdbc:cassandra:";
+    private static final Pattern KEYSPACE_PATTERN = Pattern.compile("USE (\\w+);?", Pattern.CASE_INSENSITIVE | Pattern.MULTILINE);
+    private static final Pattern SELECT_PATTERN = Pattern.compile("(?:SELECT|DELETE)\\s+.+\\s+FROM\\s+(\\w+).*", Pattern.CASE_INSENSITIVE | Pattern.MULTILINE);
+    private static final Pattern UPDATE_PATTERN = Pattern.compile("UPDATE\\s+(\\w+)\\s+.*", Pattern.CASE_INSENSITIVE);
+
+    public static final String PROTOCOL = "jdbc:cassandra:";
+    public static final String DEFAULT_HOST = "localhost";
+    public static final int DEFAULT_PORT = 9160;
+
+    public static final String TAG_DESCRIPTION = "description";
+    public static final String TAG_USER = "user";
+    public static final String TAG_PASSWORD = "password";
+    public static final String TAG_DATABASE_NAME = "databaseName";
+    public static final String TAG_SERVER_NAME = "serverName";
+    public static final String TAG_PORT_NUMBER = "portNumber";
+
     protected static final String WAS_CLOSED_CON = "method was called on a closed Connection";
     protected static final String WAS_CLOSED_STMT = "method was called on a closed Statement";
     protected static final String WAS_CLOSED_RSLT = "method was called on a closed ResultSet";
     protected static final String NO_INTERFACE = "no object was found that matched the provided interface: %s";
     protected static final String NO_TRANSACTIONS = "the Cassandra implementation does not support transactions";
-    protected static final String NO_SERVER  = "no Cassandra server is available";
+    protected static final String NO_SERVER = "no Cassandra server is available";
     protected static final String ALWAYS_AUTOCOMMIT = "the Cassandra implementation is always in auto-commit mode";
     protected static final String BAD_TIMEOUT = "the timeout value was less than zero";
-    protected static final String SCHEMA_MISMATCH  = "schema does not match across nodes, (try again later)";
+    protected static final String SCHEMA_MISMATCH = "schema does not match across nodes, (try again later)";
     protected static final String NOT_SUPPORTED = "the Cassandra implementation does not support this method";
     protected static final String NO_GEN_KEYS = "the Cassandra implementation does not currently support returning generated  keys";
     protected static final String NO_BATCH = "the Cassandra implementation does not currently support this batch in Statement";
     protected static final String NO_MULTIPLE = "the Cassandra implementation does not currently support multiple open Result Sets";
+    protected static final String NO_VALIDATOR = "Could not find key validator for: %s.%s";
+    protected static final String NO_COMPARATOR = "Could not find key comparator for: %s.%s";
+    protected static final String NO_CF = "no column family reference could be extracted from the provided CQL statement";
     protected static final String BAD_KEEP_RSET = "the argument for keeping the current result set : %s is not a valid value";
     protected static final String BAD_TYPE_RSET = "the argument for result set type : %s is not a valid value";
     protected static final String BAD_CONCUR_RSET = "the argument for result set concurrency : %s is not a valid value";
@@ -57,30 +88,123 @@ class Utils
     protected static final String VALID_LABELS = "name provided was not in the list of valid column labels: %s";
     protected static final String NOT_TRANSLATABLE = "column was stored in %s format which is not translatable to %s";
     protected static final String NOT_BOOLEAN = "string value was neither 'true' nor 'false' :  %s";
+    protected static final String HOST_IN_URL = "Connection url must specify a host, e.g., jdbc:cassandra://localhost:9170/Keyspace1";
+    protected static final String HOST_REQUIRED = "a 'host' name is required to build a Connection";
+    protected static final String BAD_KEYSPACE = "Keyspace names must be composed of alphanumerics and underscores (parsed: '%s')";
+    protected static final String URI_IS_SIMPLE = "Connection url may only include host, port, and keyspace, e.g., jdbc:cassandra://localhost:9170/Keyspace1";
 
-    
     protected static final Logger logger = LoggerFactory.getLogger(Utils.class);
-    
+
+    /**
+     * Use the Compression object method to deflate the query string
+     *
+     * @param queryStr An un-compressed CQL query string
+     * @param compression The compression object
+     * @return A compressed string
+     */
     public static ByteBuffer compressQuery(String queryStr, Compression compression)
     {
         byte[] data = queryStr.getBytes(Charsets.UTF_8);
         Deflater compressor = new Deflater();
         compressor.setInput(data);
         compressor.finish();
-        
+
         ByteArrayOutputStream byteArray = new ByteArrayOutputStream();
         byte[] buffer = new byte[1024];
-        
+
         while (!compressor.finished())
         {
             int size = compressor.deflate(buffer);
             byteArray.write(buffer, 0, size);
         }
-        
-        logger.trace("Compressed query statement {} bytes in length to {} bytes",
-                     data.length,
-                     byteArray.size());
-        
+
+        logger.trace("Compressed query statement {} bytes in length to {} bytes", data.length, byteArray.size());
+
         return ByteBuffer.wrap(byteArray.toByteArray());
     }
+
+    /**
+     * Parse a URL for the Cassandra JDBC Driver
+     * <p/>
+     * The URL must start with the Protocol: "jdbc:cassandra:"
+     * The URI part(the "Subname") must contain a host and an optional port and optional keyspace name
+     * ie. "//localhost:9160/Test1"
+     *
+     * @param url The full JDBC URL to be parsed
+     * @return A list of properties that were parsed from the Subname
+     * @throws SQLException
+     */
+    public static final Properties parseURL(String url) throws SQLException
+    {
+        Properties props = new Properties();
+
+        if (!(url == null))
+        {
+            props.setProperty(TAG_PORT_NUMBER, "" + DEFAULT_PORT);
+            String rawUri = url.substring(PROTOCOL.length());
+            URI uri = null;
+            try
+            {
+                uri = new URI(rawUri);
+            }
+            catch (URISyntaxException e)
+            {
+                throw new SQLSyntaxErrorException(e);
+            }
+
+            String host = uri.getHost();
+            if (host == null) throw new SQLNonTransientConnectionException(HOST_IN_URL);
+            props.setProperty(TAG_SERVER_NAME, host);
+
+            int port = uri.getPort() >= 0 ? uri.getPort() : DEFAULT_PORT;
+            props.setProperty(TAG_PORT_NUMBER, "" + port);
+
+            String keyspace = uri.getPath();
+            if ((keyspace != null) && (!keyspace.isEmpty()))
+            {
+                if (keyspace.startsWith("/")) keyspace = keyspace.substring(1);
+                if (!keyspace.matches("[a-zA-Z]\\w+"))
+                    throw new SQLNonTransientConnectionException(String.format(BAD_KEYSPACE, keyspace));
+                props.setProperty(TAG_DATABASE_NAME, keyspace);
+            }
+
+            if (uri.getUserInfo() != null)
+                throw new SQLNonTransientConnectionException(URI_IS_SIMPLE);
+        }
+
+        if (logger.isTraceEnabled()) logger.trace("URL : '{}' parses to: {}", url, props);
+
+        return props;
+    }
+
+    /**
+     * 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
+     * @param current The current keyspace stored as state in the connection
+     * @return the provided keyspace name or the keyspace from the contents of the CQL string
+     */
+    public static String determineCurrentKeyspace(String cql, String current)
+    {
+        String ks = current;
+        Matcher isKeyspace = KEYSPACE_PATTERN.matcher(cql);
+        if (isKeyspace.matches()) ks = isKeyspace.group(1);
+        return ks;
+    }
+
+    /**
+     * Determine the current column family by inspecting the CQL to find a CF reference.
+     *
+     * @param cql A CQL query string
+     * @return The column family name from the contents of the CQL string or null in none was found
+     */
+    public static String determineCurrentColumnFamily(String cql)
+    {
+        String cf = null;
+        Matcher isSelect = SELECT_PATTERN.matcher(cql);
+        if (isSelect.matches()) cf = isSelect.group(1);
+        Matcher isUpdate = UPDATE_PATTERN.matcher(cql);
+        if (isUpdate.matches()) cf = isUpdate.group(1);
+        return cf;
+    }
 }

Modified: cassandra/drivers/java/test/org/apache/cassandra/cql/JdbcDriverTest.java
URL: http://svn.apache.org/viewvc/cassandra/drivers/java/test/org/apache/cassandra/cql/JdbcDriverTest.java?rev=1149432&r1=1149431&r2=1149432&view=diff
==============================================================================
--- cassandra/drivers/java/test/org/apache/cassandra/cql/JdbcDriverTest.java (original)
+++ cassandra/drivers/java/test/org/apache/cassandra/cql/JdbcDriverTest.java Fri Jul 22 01:59:09 2011
@@ -59,7 +59,7 @@ public class JdbcDriverTest extends Embe
     {
         startCassandraServer();
         Class.forName("org.apache.cassandra.cql.jdbc.CassandraDriver");
-        con = DriverManager.getConnection("jdbc:cassandra://root:root@localhost:9170/Keyspace1");
+        con = DriverManager.getConnection("jdbc:cassandra://localhost:9170/Keyspace1");
         String[] inserts = 
         {
             String.format("UPDATE Standard1 SET '%s' = '%s', '%s' = '%s' WHERE KEY = '%s'", first, firstrec, last, lastrec, jsmith),    
@@ -82,7 +82,7 @@ public class JdbcDriverTest extends Embe
             }
         }
     }
-    
+
     private static void expectedMetaData(ResultSetMetaData md, int col, String colClass, String table, String schema,
                                   String label, int type, String typeName, boolean signed, boolean caseSensitive) throws SQLException
     {
@@ -106,7 +106,25 @@ public class JdbcDriverTest extends Embe
         assertEquals(valuSigned, md.isSigned(col));
         assertEquals(valuCaseSense, md.isCaseSensitive(col));
     }
-    
+
+    @Test(expected=SQLNonTransientConnectionException.class)
+    public void testNoHost() throws SQLException
+    {
+        DriverManager.getConnection("jdbc:cassandra:localhost");
+    }
+
+    @Test(expected=SQLNonTransientConnectionException.class)
+    public void testBadKeyspace() throws SQLException
+    {
+        DriverManager.getConnection("jdbc:cassandra://localhost/Keysp@ce");
+    }
+
+    @Test(expected=SQLNonTransientConnectionException.class)
+    public void testBadUserinfo() throws SQLException
+    {
+        DriverManager.getConnection("jdbc:cassandra://root;root@localhost");
+    }
+
     @Test
     public void testNonDefaultColumnValidators() throws SQLException
     {

Modified: cassandra/drivers/java/test/org/apache/cassandra/cql/jdbc/PreparedStatementTest.java
URL: http://svn.apache.org/viewvc/cassandra/drivers/java/test/org/apache/cassandra/cql/jdbc/PreparedStatementTest.java?rev=1149432&r1=1149431&r2=1149432&view=diff
==============================================================================
--- cassandra/drivers/java/test/org/apache/cassandra/cql/jdbc/PreparedStatementTest.java (original)
+++ cassandra/drivers/java/test/org/apache/cassandra/cql/jdbc/PreparedStatementTest.java Fri Jul 22 01:59:09 2011
@@ -44,7 +44,7 @@ public class PreparedStatementTest exten
     {
         startCassandraServer();
         Class.forName("org.apache.cassandra.cql.jdbc.CassandraDriver");
-        con = DriverManager.getConnection("jdbc:cassandra://root:root@localhost:9170/Keyspace1");
+        con = DriverManager.getConnection("jdbc:cassandra://localhost:9170/Keyspace1");
     }
     
     @Test
@@ -291,7 +291,7 @@ public class PreparedStatementTest exten
     @Test
     public void testInteger() throws SQLException
     {
-        PreparedStatement stmt = con.prepareStatement("update JdbcInteger set ?=?, ?=? where key = ?");
+รท        PreparedStatement stmt = con.prepareStatement("update JdbcInteger set ?=?, ?=? where key = ?");
         for (int i = 0; i < 5; i++)
         {
             byte[] key = Integer.toString(i).getBytes();