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/06/18 21:19:13 UTC

svn commit: r1137231 [2/3] - in /cassandra/drivers/java: ./ src/org/apache/cassandra/cql/jdbc/

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=1137231&r1=1137230&r2=1137231&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 Sat Jun 18 19:19:13 2011
@@ -20,8 +20,8 @@
  */
 package org.apache.cassandra.cql.jdbc;
 
-import java.io.InputStream;
-import java.io.Reader;
+import static org.apache.cassandra.cql.jdbc.Utils.*;
+
 import java.math.BigDecimal;
 import java.math.BigInteger;
 import java.net.URL;
@@ -40,14 +40,16 @@ public class CResultSet extends Abstract
 {
     private final ColumnDecoder decoder;
     private final String keyspace;
+    
     private final String columnFamily;
     
     /** The r set iter. */
     private Iterator<CqlRow> rSetIter;
-    int rowNumber = 0;
     
+    int rowNumber = 0;
     // the current row key when iterating through results.
     private byte[] curRowKey = null;
+    
     private TypedColumn typedCurRowKey = null;
     
     /** The values. */
@@ -56,17 +58,31 @@ public class CResultSet extends Abstract
     /** The value map. */
     private Map<String, TypedColumn> valueMap = new HashMap<String, TypedColumn>();
     
+    /** 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;
 
     /**
      * Instantiates a new cassandra result set.
-     *
-     * @param resultSet the result set
      */
-    CResultSet(CqlResult resultSet, ColumnDecoder decoder, String keyspace, String columnFamily)
+    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;
@@ -74,24 +90,42 @@ public class CResultSet extends Abstract
         meta = new CResultSetMetaData();
     }
 
-    public byte[] getKey()
+    public boolean absolute(int arg0) throws SQLException
     {
-        return curRowKey;
+        throw new SQLFeatureNotSupportedException (NOT_SUPPORTED);
     }
 
-    public TypedColumn getTypedKey()
+    public void afterLast() throws SQLException
     {
-        return typedCurRowKey;
+        throw new SQLFeatureNotSupportedException (NOT_SUPPORTED);
     }
 
-    public TypedColumn getColumn(int i)
+    public void beforeFirst() throws SQLException
+    {
+        throw new SQLFeatureNotSupportedException (NOT_SUPPORTED);
+    }
+    
+    private final void checkIndex(int index) throws SQLException
     {
-        return values.get(i);
+        // 1 <= index <= size()
+        if (index < 1 || index > values.size()) throw new SQLSyntaxErrorException(String.format(MUST_BE_POSITIVE, String.valueOf(index)));
     }
 
-    public TypedColumn getColumn(String name)
+    private final void checkName(String name) throws SQLException
     {
-        return valueMap.get(name);
+        if (valueMap.get(name) == null) throw new SQLSyntaxErrorException(String.format(VALID_LABELS, name));
+    }
+
+    private final void checkNotClosed() throws SQLException
+    {
+        if (isClosed()) throw new SQLRecoverableException(WAS_CLOSED_RSLT);
+    }
+
+    public void clearWarnings() throws SQLException
+    {
+        // This implementation does not support the collection of warnings so clearing is a no-op
+        // but it is still an exception to call this on a closed connection.
+        checkNotClosed();
     }
 
     public void close() throws SQLException
@@ -100,11 +134,146 @@ public class CResultSet extends Abstract
         values = null;
     }
 
-    private byte[] getBytes(TypedColumn column)
+    public int findColumn(String name) throws SQLException
     {
-        ByteBuffer value = (ByteBuffer) column.getValue();
+        checkNotClosed();
+        checkName(name);
+        return indexMap.get(name).intValue();
+    }
+
+    public boolean first() throws SQLException
+    {
+        throw new SQLFeatureNotSupportedException (NOT_SUPPORTED);
+    }
+
+    // Big Decimal (awaiting a new AbstractType implementation)
+    
+    public BigDecimal getBigDecimal(int arg0) throws SQLException
+    {
+        throw new SQLFeatureNotSupportedException (NOT_SUPPORTED);
+    }
+    
+    public BigDecimal getBigDecimal(int arg0, int arg1) throws SQLException
+    {
+        throw new SQLFeatureNotSupportedException (NOT_SUPPORTED);
+    }
+
+    public BigDecimal getBigDecimal(String arg0) throws SQLException
+    {
+        throw new SQLFeatureNotSupportedException (NOT_SUPPORTED);
+    }
+
+    public BigDecimal getBigDecimal(String arg0, int arg1) throws SQLException
+    {
+        throw new SQLFeatureNotSupportedException (NOT_SUPPORTED);
+    }
+
+    public BigInteger getBigInteger(int index) throws SQLException
+    {
+        checkIndex(index);
+        return getBigInteger(values.get(index - 1));
+    }
+
+    public BigInteger getBigInteger(String name) throws SQLException
+    {
+        checkName(name);
+        return getBigInteger(valueMap.get(name));
+    }
+    
+    private BigInteger getBigInteger(TypedColumn column) throws SQLException
+    {
+        checkNotClosed();
+        Object value = column.getValue();
         wasNull = value == null;
-        return value == null ? null : ByteBufferUtil.clone(value).array();
+
+        if (wasNull) return null;
+
+        if (value instanceof Long) return BigInteger.valueOf((Long) value);
+
+        if (value instanceof BigInteger) return (BigInteger) value;
+
+        try
+        {
+            if (value instanceof String) return (new BigInteger((String) value));
+        }
+        catch (NumberFormatException e)
+        {
+            throw new SQLSyntaxErrorException(e);
+        }
+
+        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));
+    }
+
+    public boolean getBoolean(String name) throws SQLException
+    {
+        checkName(name);
+        return getBoolean(valueMap.get(name));
+    }
+
+    private final Boolean getBoolean(TypedColumn column) throws SQLException
+    {
+        checkNotClosed();
+        Object value = column.getValue();
+        wasNull = value == null;
+
+        if (wasNull) return null;
+
+        if (value instanceof Long) return Boolean.valueOf(((Long) value) == 0 ? false : true);
+
+        if (value instanceof BigInteger) return Boolean.valueOf(((BigInteger) value).intValue() == 0 ? false : true);
+
+        if (value instanceof String)
+        {
+            String str = (String) value;
+            if (str.equalsIgnoreCase("true")) return true;
+            if (str.equalsIgnoreCase("false")) return false;
+
+            throw new SQLSyntaxErrorException(String.format(NOT_BOOLEAN, str));
+        }
+
+        throw new SQLSyntaxErrorException(String.format(NOT_TRANSLATABLE, value.getClass().getSimpleName(),"Boolean"));
+    }
+
+    public byte getByte(int index) throws SQLException
+    {
+        checkIndex(index);
+        return getByte(values.get(index - 1));
+    }
+
+    public byte getByte(String name) throws SQLException
+    {
+        checkName(name);
+        return getByte(valueMap.get(name));
+    }
+
+    private final Byte getByte(TypedColumn column) throws SQLException
+    {
+        checkNotClosed();
+        Object value = column.getValue();
+        wasNull = value == null;
+
+        if (wasNull) return null;
+
+        if (value instanceof Long) return ((Long) value).byteValue();
+
+        if (value instanceof BigInteger) return ((BigInteger) value).byteValue();
+
+        try
+        {
+            if (value instanceof String) return (new Byte((String) value));
+        }
+        catch (NumberFormatException e)
+        {
+            throw new SQLSyntaxErrorException(e);
+        }
+
+        throw new SQLSyntaxErrorException(String.format(NOT_TRANSLATABLE, value.getClass().getSimpleName(),"Byte"));
     }
 
     public byte[] getBytes(int index) throws SQLException
@@ -117,230 +286,507 @@ public class CResultSet extends Abstract
         return getBytes(valueMap.get(name));
     }
 
-    public Date getDate(int arg0) throws SQLException
+    private byte[] getBytes(TypedColumn column) throws SQLException
+    {
+        checkNotClosed();
+        ByteBuffer value = (ByteBuffer) column.getValue();
+        wasNull = value == null;
+        return value == null ? null : ByteBufferUtil.clone(value).array();
+    }
+    
+    public TypedColumn getColumn(int index) throws SQLException
     {
-        throw new UnsupportedOperationException("method not supported");
+        checkIndex(index);
+        checkNotClosed();
+        return values.get(index);
     }
 
-    public Date getDate(String arg0) throws SQLException
+    public TypedColumn getColumn(String name) throws SQLException
     {
-        throw new UnsupportedOperationException("method not supported");
+        checkName(name);
+        checkNotClosed();
+        return valueMap.get(name);
     }
 
-    public Date getDate(int arg0, Calendar arg1) throws SQLException
+    public int getConcurrency() throws SQLException
     {
-        throw new UnsupportedOperationException("method not supported");
+        checkNotClosed();
+        return statement.getResultSetConcurrency();
     }
 
-    public Date getDate(String arg0, Calendar arg1) throws SQLException
+    public Date getDate(int index) throws SQLException
     {
-        throw new UnsupportedOperationException("method not supported");
+        checkIndex(index);
+        return getDate(values.get(index-1));
     }
 
-    public double getDouble(int arg0) throws SQLException
+    public Date getDate(int index, Calendar calendar) throws SQLException
     {
-        throw new UnsupportedOperationException("method not supported");
+        checkIndex(index);
+        // silently ignore the Calendar argument; its a hint we do not need
+        return getDate(index);
     }
 
-    public double getDouble(String arg0) throws SQLException
+    public Date getDate(String name) throws SQLException
     {
-        throw new UnsupportedOperationException("method not supported");
+        checkName(name);
+        return getDate(valueMap.get(name));
     }
 
-    public float getFloat(int arg0) throws SQLException
+    public Date getDate(String name, Calendar calendar) throws SQLException
     {
-        throw new UnsupportedOperationException("method not supported");
+        checkName(name);
+        // silently ignore the Calendar argument; its a hint we do not need
+        return getDate(name);
     }
 
-    public float getFloat(String arg0) throws SQLException
+    private Date getDate(TypedColumn column)  throws SQLException
     {
-        throw new UnsupportedOperationException("method not supported");
+        checkNotClosed();
+        Object value = column.getValue();
+        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());
+        
+        try
+        {
+            if (value instanceof String) return Date.valueOf((String) value);
+        }
+        catch (IllegalArgumentException e)
+        {
+           throw new SQLSyntaxErrorException(e);
+        }
+        
+        throw new SQLSyntaxErrorException(String.format(NOT_TRANSLATABLE, value.getClass().getSimpleName(),"SQL Date"));
     }
 
-    public boolean getBoolean(int arg0) throws SQLException
+    public double getDouble(int index) throws SQLException
     {
-        throw new UnsupportedOperationException("method not supported");
+        checkIndex(index);
+        return getDouble(values.get(index-1));
     }
 
-    public boolean getBoolean(String arg0) throws SQLException
+    public double getDouble(String name) throws SQLException
     {
-        throw new UnsupportedOperationException("method not supported");
+        checkName(name);
+        return getDouble(valueMap.get(name));
     }
 
-    private BigInteger getBigInteger(TypedColumn column)
+    private final Double getDouble(TypedColumn column) throws SQLException
     {
-        BigInteger value = (BigInteger) column.getValue();
+        checkNotClosed();
+        Object value = column.getValue();
         wasNull = value == null;
-        return value;
+
+        if (wasNull) return null;
+
+        if (value instanceof Long) return new Double((Long) value);
+
+        if (value instanceof BigInteger) return new Double(((BigInteger) value).doubleValue());
+
+        if (value instanceof Double) return ((Double) value);
+
+        if (value instanceof Float) return ((Float) value).doubleValue();
+
+        try
+        {
+            if (value instanceof String) return new Double((String) value);
+        }
+        catch (NumberFormatException e)
+        {
+           throw new SQLSyntaxErrorException(e);
+        }
+
+        throw new SQLSyntaxErrorException(String.format(NOT_TRANSLATABLE, value.getClass().getSimpleName(),"Double"));
     }
 
-    public BigInteger getBigInteger(int i)
+    public int getFetchDirection() throws SQLException
+    {
+        checkNotClosed();
+        return fetchDirection;
+    }
+    
+    public int getFetchSize() throws SQLException
     {
-        return getBigInteger(values.get(i - 1));
+        checkNotClosed();
+        return fetchSize;
     }
 
-    public BigInteger getBigInteger(String name)
+    public float getFloat(int index) throws SQLException
     {
-        return getBigInteger(valueMap.get(name));
+        checkIndex(index);
+        return getFloat(values.get(index - 1));
     }
 
-    private int getInt(TypedColumn column) throws SQLException
+    public float getFloat(String name) throws SQLException
     {
-        // bit of a hack, this, but asking for getInt seems so common that we should accomodate it
-        if (column.getValue() instanceof BigInteger)
-        {
-            wasNull = false;
-            return getBigInteger(column).intValue();
-        }
-        else if (column.getValue() instanceof Long)
+        checkName(name);
+        return getFloat(valueMap.get(name));
+    }
+    
+    private final Float getFloat(TypedColumn column) throws SQLException
+    {
+        checkNotClosed();
+        Object value = column.getValue();
+        wasNull = value == null;
+
+        if (wasNull) return null;
+
+        if (value instanceof Long) return new Float((Long) value);
+
+        if (value instanceof BigInteger) return new Float(((BigInteger) value).floatValue());
+
+        if (value instanceof Float) return ((Float) value);
+
+        if (value instanceof Double) return ((Double) value).floatValue();
+
+        try
         {
-            wasNull = false;
-            return getLong(column).intValue();
+            if (value instanceof String) return new Float((String) value);
         }
-        else if (column.getValue() == null)
+        catch (NumberFormatException e)
         {
-            wasNull = true;
-            return 0;
+            throw new SQLException(e);
         }
-        throw new SQLException("Non-integer value " + column.getValue());
+
+        throw new SQLSyntaxErrorException(String.format(NOT_TRANSLATABLE, value.getClass().getSimpleName(), "Float"));
+    }
+
+    public int getHoldability() throws SQLException
+    {
+        checkNotClosed();        
+        return statement.getResultSetHoldability();
     }
 
     public int getInt(int index) throws SQLException
     {
+        checkIndex(index);
         return getInt(values.get(index - 1));
     }
 
     public int getInt(String name) throws SQLException
     {
+        checkName(name);
         return getInt(valueMap.get(name));
     }
 
-    private Long getLong(TypedColumn column)
+    private int getInt(TypedColumn column) throws SQLException
     {
-        Long value = (Long) column.getValue();
+        checkNotClosed();
+        Object value = column.getValue();
         wasNull = value == null;
-        return value == null ? 0 : value;
+
+        if (wasNull) return 0;
+
+        // bit of a hack, this, but asking for getInt seems so common that we should accommodate it
+        if (value instanceof BigInteger) return ((BigInteger) value).intValue();
+
+        if (value instanceof Long) return ((Long) value).intValue();
+
+        try
+        {
+            if (value instanceof String) return (Integer.parseInt((String) value));
+        }
+        catch (NumberFormatException e)
+        {
+            throw new SQLSyntaxErrorException(e);
+        }
+
+        throw new SQLSyntaxErrorException(String.format(NOT_TRANSLATABLE, value.getClass().getSimpleName(),"int"));
+    }
+
+    public byte[] getKey() throws SQLException
+    {
+        return curRowKey;
     }
 
     public long getLong(int index) throws SQLException
     {
+        checkIndex(index);
         return getLong(values.get(index - 1));
     }
 
     public long getLong(String name) throws SQLException
     {
+        checkName(name);
         return getLong(valueMap.get(name));
     }
 
-    public ResultSetMetaData getMetaData() throws SQLException
+    private Long getLong(TypedColumn column) throws SQLException
     {
-        return meta;
+        checkNotClosed();
+        Object value = column.getValue();
+        wasNull = value == null;
+
+        if (wasNull) return null;
+
+        if (value instanceof BigInteger) return getBigInteger(column).longValue();
+
+        if (value instanceof Long) return (Long) value;
+
+        try
+        {
+            if (value instanceof String) return (Long.parseLong((String) value));
+        }
+        catch (NumberFormatException e)
+        {
+            throw new SQLSyntaxErrorException(e);
+        }
+
+        throw new SQLSyntaxErrorException(String.format(NOT_TRANSLATABLE, value.getClass().getSimpleName(),"Long"));
     }
 
-    private Object getObject(TypedColumn column)
+    public ResultSetMetaData getMetaData() throws SQLException
     {
-        Object value = column.getValue();
-        wasNull = value == null;
-        return value;
+        checkNotClosed();
+        return meta;
     }
 
     public Object getObject(int index) throws SQLException
     {
+        checkIndex(index);
         return getObject(values.get(index - 1));
     }
 
     public Object getObject(String name) throws SQLException
     {
+        checkName(name);
         return getObject(valueMap.get(name));
     }
 
-    public Object getObject(int arg0, Map<String, Class<?>> arg1) throws SQLException
-    {
-        throw new UnsupportedOperationException("method not supported");
-    }
 
-    public Object getObject(String arg0, Map<String, Class<?>> arg1) throws SQLException
+    private Object getObject(TypedColumn column) throws SQLException
     {
-        throw new UnsupportedOperationException("method not supported");
+        checkNotClosed();
+        Object value = column.getValue();
+        wasNull = value == null;
+        return (wasNull) ? null : value;
     }
 
     public int getRow() throws SQLException
     {
+        checkNotClosed();
         return rowNumber;
     }
 
-    private String getString(TypedColumn column)
+    // 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);
+    }
+
+    public short getShort(int index) throws SQLException
     {
-        String value = (String) column.getValue();
+        checkIndex(index);
+        return getShort(values.get(index - 1));
+    }
+
+    public short getShort(String name) throws SQLException
+    {
+        checkName(name);
+        return getShort(valueMap.get(name));
+    }
+
+    private final Short getShort(TypedColumn column) throws SQLException
+    {
+        checkNotClosed();
+        Object value = column.getValue();
         wasNull = value == null;
-        return value == null ? null : value;
+
+        if (wasNull) return null;
+
+        if (value instanceof Long) return ((Long) value).shortValue();
+
+        if (value instanceof BigInteger) return ((BigInteger) value).shortValue();
+
+        try
+        {
+            if (value instanceof String) return (new Short((String) value));
+        }
+        catch (NumberFormatException e)
+        {
+            throw new SQLSyntaxErrorException(e);
+        }
+
+        throw new SQLSyntaxErrorException(String.format(NOT_TRANSLATABLE, value.getClass().getSimpleName(),"Short"));
+    }
+
+    public Statement getStatement() throws SQLException
+    {
+        checkNotClosed();        
+        return statement;
     }
 
     public String getString(int index) throws SQLException
     {
+        checkIndex(index);
         return getString(values.get(index - 1));
     }
 
     public String getString(String name) throws SQLException
     {
+        checkName(name);
         return getString(valueMap.get(name));
     }
 
-    public Time getTime(int arg0) throws SQLException
+    private String getString(TypedColumn column) throws SQLException
     {
-        throw new UnsupportedOperationException("method not supported");
+        checkNotClosed();
+        Object value = column.getValue();
+        wasNull = value == null;
+        return (wasNull) ? null : value.toString();
     }
 
-    public Time getTime(String arg0) throws SQLException
+    public Time getTime(int index) throws SQLException
+    {
+        checkIndex(index);
+        return getTime(values.get(index-1));
+    }
+    
+    public Time getTime(int index, Calendar calendar) throws SQLException
     {
-        throw new UnsupportedOperationException("method not supported");
+        checkIndex(index);
+        // silently ignore the Calendar argument; its a hint we do not need
+        return getTime(index);
     }
 
-    public Time getTime(int arg0, Calendar arg1) throws SQLException
+    public Time getTime(String name) throws SQLException
     {
-        throw new UnsupportedOperationException("method not supported");
+        checkName(name);
+        return getTime(valueMap.get(name));
     }
 
-    public Time getTime(String arg0, Calendar arg1) throws SQLException
+    public Time getTime(String name, Calendar calendar) throws SQLException
     {
-        throw new UnsupportedOperationException("method not supported");
+        checkName(name);
+        // silently ignore the Calendar argument; its a hint we do not need
+        return getTime(name);
     }
+    
+    private Time getTime(TypedColumn column) throws SQLException
+    {
+        checkNotClosed();
+        Object value = column.getValue();
+        wasNull = value == null;
+
+        if (wasNull) return null;
+
+        if (value instanceof Long) return new Time((Long) value);
+
+        if (value instanceof java.util.Date) return new Time(((java.util.Date) value).getTime());
+
+        try
+        {
+            if (value instanceof String) return Time.valueOf((String) value);
+        }
+        catch (IllegalArgumentException e)
+        {
+            throw new SQLSyntaxErrorException(e);
+        }
 
-    public Timestamp getTimestamp(int arg0) throws SQLException
+        throw new SQLSyntaxErrorException(String.format(NOT_TRANSLATABLE, value.getClass().getSimpleName(), "SQL Time"));
+    }
+
+    public Timestamp getTimestamp(int index) throws SQLException
+    {
+        checkIndex(index);
+        return getTimestamp(values.get(index - 1));
+    }
+
+    public Timestamp getTimestamp(int index, Calendar calendar) throws SQLException
     {
-        throw new UnsupportedOperationException("method not supported");
+        checkIndex(index);
+        // silently ignore the Calendar argument; its a hint we do not need
+        return getTimestamp(index);
     }
 
-    public Timestamp getTimestamp(String arg0) throws SQLException
+    public Timestamp getTimestamp(String name) throws SQLException
     {
-        throw new UnsupportedOperationException("method not supported");
+        checkName(name);
+        return getTimestamp(valueMap.get(name));
     }
 
-    public Timestamp getTimestamp(int arg0, Calendar arg1) throws SQLException
+    public Timestamp getTimestamp(String name, Calendar calendar) throws SQLException
     {
-        throw new UnsupportedOperationException("method not supported");
+        checkName(name);
+        // silently ignore the Calendar argument; its a hint we do not need
+        return getTimestamp(name);
     }
 
-    public Timestamp getTimestamp(String arg0, Calendar arg1) throws SQLException
+    private Timestamp getTimestamp(TypedColumn column) throws SQLException
     {
-        throw new UnsupportedOperationException("method not supported");
+        checkNotClosed();
+        Object value = column.getValue();
+        wasNull = value == null;
+
+        if (wasNull) return null;
+
+        if (value instanceof Long) return new Timestamp((Long) value);
+
+        if (value instanceof java.util.Date) return new Timestamp(((java.util.Date) value).getTime());
+
+        try
+        {
+            if (value instanceof String) return Timestamp.valueOf((String) value);
+        }
+        catch (IllegalArgumentException e)
+        {
+            throw new SQLSyntaxErrorException(e);
+        }
+
+        throw new SQLSyntaxErrorException(String.format(NOT_TRANSLATABLE, value.getClass().getSimpleName(), "SQL Timestamp"));
     }
 
     public int getType() throws SQLException
     {
-        return ResultSet.TYPE_FORWARD_ONLY;
+        checkNotClosed();
+        return resultSetType;
+    }
+
+    public TypedColumn getTypedKey()throws SQLException
+    {
+        return typedCurRowKey;
+    }
+
+    // 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);
     }
 
+    public URL getURL(String arg0) throws SQLException
+    {
+        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();
+        // the rationale is there are no warnings to return in this implementation...
+        return null;
+    }
+
+
     public boolean isAfterLast() throws SQLException
     {
+        checkNotClosed();
         return rowNumber == Integer.MAX_VALUE;
     }
 
     public boolean isBeforeFirst() throws SQLException
     {
+        checkNotClosed();
         return rowNumber == 0;
     }
-
+    
     public boolean isClosed() throws SQLException
     {
         return valueMap == null;
@@ -348,29 +794,27 @@ public class CResultSet extends Abstract
 
     public boolean isFirst() throws SQLException
     {
+        checkNotClosed();
         return rowNumber == 1;
     }
 
     public boolean isLast() throws SQLException
     {
+        checkNotClosed();
         return !rSetIter.hasNext();
     }
 
-    public boolean last() throws SQLException
+    public boolean isWrapperFor(Class<?> iface) throws SQLException
     {
-        throw new UnsupportedOperationException("method not supported");
+        return CassandraResultSet.class.isAssignableFrom(iface);
     }
 
-    public <T> T unwrap(Class<T> iface) throws SQLException
-    {
-        if (iface.equals(CassandraResultSet.class))
-            return (T) this;
-        throw new SQLException("Unsupported unwrap interface: " + iface.getSimpleName());
-    }
+    // Navigation between rows within the returned set of rows
+    // Need to use a list iterator so next() needs completely re-thought
     
-    public boolean isWrapperFor(Class<?> iface) throws SQLException
+    public boolean last() throws SQLException
     {
-        return CassandraResultSet.class.isAssignableFrom(iface);
+        throw new SQLFeatureNotSupportedException (NOT_SUPPORTED);
     }
 
     public synchronized boolean next() throws SQLException
@@ -386,17 +830,18 @@ public class CResultSet extends Abstract
             rowNumber++;
             curRowKey = row.getKey();
             typedCurRowKey = decoder.makeKeyColumn(keyspace, columnFamily, curRowKey);
-
             List<Column> cols = row.getColumns();
             for (Column col : cols)
             {
 
                 TypedColumn c = decoder.makeCol(keyspace, columnFamily, col);
-                values.add(c);
-                valueMap.put(decoder.colNameAsString(keyspace, columnFamily, col.name), c);
+                String columnName = decoder.colNameAsString(keyspace, columnFamily, col.name);
+                values.add(c); 
+                indexMap.put(columnName, values.size()); // one greater than 0 based index of a list
+                valueMap.put(columnName, c);
             }
             return !(values.isEmpty() && valueMap.isEmpty());
-        } 
+        }
         else
         {
             rowNumber = Integer.MAX_VALUE;
@@ -404,165 +849,192 @@ public class CResultSet extends Abstract
         }
     }
 
+    public boolean previous() throws SQLException
+    {
+        throw new SQLFeatureNotSupportedException (NOT_SUPPORTED);
+    }
+
+    public boolean relative(int arg0) throws SQLException
+    {
+        throw new SQLFeatureNotSupportedException (NOT_SUPPORTED);
+    }
+
+    public void setFetchDirection(int direction) throws SQLException
+    {
+        checkNotClosed();
+
+        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);
+            fetchDirection = direction;
+        }
+        throw new SQLSyntaxErrorException(String.format(BAD_FETCH_DIR, direction));
+    }
+
+     public void setFetchSize(int size) throws SQLException
+    {
+        checkNotClosed();
+        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()));
+    }
+
     public boolean wasNull() throws SQLException
     {
         return wasNull;
     }
-    
     /**
      * RSMD implementation.  The metadata returned refers to the column
      * values, not the column names.
      */
     class CResultSetMetaData implements ResultSetMetaData
     {
-        private void checkIndex(int i) throws SQLException
-        {
-            if (i >= values.size())
-                throw new SQLException("Invalid column index " + i);
-        }
-        
-        public int getColumnCount() throws SQLException
+        public String getCatalogName(int column) throws SQLException
         {
-            return values.size();
+            checkIndex(column);
+            return "";
         }
 
-        public boolean isAutoIncrement(int column) throws SQLException
+        public String getColumnClassName(int column) throws SQLException
         {
-            column--;
             checkIndex(column);
-            return values.get(column).getValueType() instanceof CounterColumnType; // todo: check Value is correct.
+            return values.get(column - 1).getValueType().getType().getName();
         }
 
-        public boolean isCaseSensitive(int column) throws SQLException
+        public int getColumnCount() throws SQLException
         {
-            column--;
-            checkIndex(column);
-            TypedColumn tc = values.get(column);
-            return tc.getValueType().isCaseSensitive();
+            return values.size();
         }
 
-        public boolean isSearchable(int column) throws SQLException
+        public int getColumnDisplaySize(int column) throws SQLException
         {
-            return false;
+            checkIndex(column);
+            return values.get(column-1).getValueString().length();
         }
 
-        public boolean isCurrency(int column) throws SQLException
+        public String getColumnLabel(int column) throws SQLException
         {
-            column--;
             checkIndex(column);
-            TypedColumn tc = values.get(column);
-            return tc.getValueType().isCurrency();
+            return getColumnName(column);
         }
 
-        /** absence is the equivalent of null in Cassandra */
-        public int isNullable(int column) throws SQLException
+        public String getColumnName(int column) throws SQLException
         {
-            return ResultSetMetaData.columnNullable;
+            checkIndex(column);
+            return values.get(column-1).getNameString();
         }
 
-        public boolean isSigned(int column) throws SQLException
+        public int getColumnType(int column) throws SQLException
         {
-            column--;
             checkIndex(column);
-            TypedColumn tc = values.get(column);
-            return tc.getValueType().isSigned();
+            return values.get(column-1).getValueType().getJdbcType();
         }
 
-        public int getColumnDisplaySize(int column) throws SQLException
+        // Spec says "database specific type name". For Cassandra this means the abstract type.
+        public String getColumnTypeName(int column) throws SQLException
         {
-            column--;
             checkIndex(column);
-            return values.get(column).getValueString().length();
+            return values.get(column-1).getValueType().getClass().getSimpleName();
         }
 
-        public String getColumnLabel(int column) throws SQLException
+        public int getPrecision(int column) throws SQLException
         {
-            return getColumnName(column);
+            checkIndex(column);
+            TypedColumn col = values.get(column-1);
+            return col.getValueType().getPrecision(col.getValue());
         }
 
-        public String getColumnName(int column) throws SQLException
+        public int getScale(int column) throws SQLException
         {
-            column--;
             checkIndex(column);
-            return values.get(column).getNameString();
+            TypedColumn tc = values.get(column-1);
+            return tc.getValueType().getScale(tc.getValue());
         }
 
         public String getSchemaName(int column) throws SQLException
         {
+            checkIndex(column);
             return keyspace;
         }
 
-        public int getPrecision(int column) throws SQLException
+        public String getTableName(int column) throws SQLException
         {
-            column--;
             checkIndex(column);
-            TypedColumn col = values.get(column);
-            return col.getValueType().getPrecision(col.getValue());
+            return columnFamily;
         }
 
-        public int getScale(int column) throws SQLException
+        public boolean isAutoIncrement(int column) throws SQLException
         {
-            column--;
             checkIndex(column);
-            TypedColumn tc = values.get(column);
-            return tc.getValueType().getScale(tc.getValue());
+            return values.get(column-1).getValueType() instanceof CounterColumnType; // todo: check Value is correct.
         }
 
-        public String getTableName(int column) throws SQLException
+        public boolean isCaseSensitive(int column) throws SQLException
         {
-            return columnFamily;
+            checkIndex(column);
+            TypedColumn tc = values.get(column-1);
+            return tc.getValueType().isCaseSensitive();
         }
 
-        public String getCatalogName(int column) throws SQLException
+        public boolean isCurrency(int column) throws SQLException
         {
-            throw new SQLFeatureNotSupportedException("Cassandra has no catalogs");
+            checkIndex(column);
+            TypedColumn tc = values.get(column-1);
+            return tc.getValueType().isCurrency();
         }
 
-        public int getColumnType(int column) throws SQLException
+        public boolean isDefinitelyWritable(int column) throws SQLException
         {
-            column--;
             checkIndex(column);
-            return values.get(column).getValueType().getJdbcType();
+            return isWritable(column);
         }
 
-        // todo: spec says "database specific type name". this means the abstract type.
-        public String getColumnTypeName(int column) throws SQLException
+        /** absence is the equivalent of null in Cassandra */
+        public int isNullable(int column) throws SQLException
         {
-            column--;
             checkIndex(column);
-            return values.get(column).getValueType().getClass().getSimpleName();
+            return ResultSetMetaData.columnNullable;
         }
 
         public boolean isReadOnly(int column) throws SQLException
         {
+            checkIndex(column);
             return column == 0;
         }
 
-        public boolean isWritable(int column) throws SQLException
+        public boolean isSearchable(int column) throws SQLException
         {
-            return column > 0;
+            checkIndex(column);
+            return false;
         }
 
-        public boolean isDefinitelyWritable(int column) throws SQLException
+        public boolean isSigned(int column) throws SQLException
         {
-            return isWritable(column);
+            checkIndex(column);
+            TypedColumn tc = values.get(column-1);
+            return tc.getValueType().isSigned();
         }
 
-        public String getColumnClassName(int column) throws SQLException
+        public boolean isWrapperFor(Class<?> iface) throws SQLException
         {
-            column--;
-            checkIndex(column);
-            return values.get(column).getValueType().getType().getName();
+            return false;
         }
 
-        public <T> T unwrap(Class<T> iface) throws SQLException
+        public boolean isWritable(int column) throws SQLException
         {
-            throw new SQLException("No wrapping implemented");
+            checkIndex(column);
+            return column > 0;
         }
 
-        public boolean isWrapperFor(Class<?> iface) throws SQLException
+        public <T> T unwrap(Class<T> iface) throws SQLException
         {
-            return false;
+            throw new SQLFeatureNotSupportedException(String.format(NO_INTERFACE, iface.getSimpleName()));
         }
     }
 }

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=1137231&r1=1137230&r2=1137231&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 Sat Jun 18 19:19:13 2011
@@ -20,24 +20,27 @@
  */
 package org.apache.cassandra.cql.jdbc;
 
-import java.sql.Array;
-import java.sql.Blob;
-import java.sql.CallableStatement;
-import java.sql.Clob;
+import static org.apache.cassandra.cql.jdbc.Utils.*;
+
+import java.net.URI;
+import java.net.URISyntaxException;
 import java.sql.Connection;
 import java.sql.DatabaseMetaData;
-import java.sql.NClob;
 import java.sql.PreparedStatement;
 import java.sql.ResultSet;
 import java.sql.SQLClientInfoException;
 import java.sql.SQLException;
 import java.sql.SQLFeatureNotSupportedException;
+import java.sql.SQLInvalidAuthorizationSpecException;
+import java.sql.SQLNonTransientConnectionException;
+import java.sql.SQLRecoverableException;
+import java.sql.SQLSyntaxErrorException;
+import java.sql.SQLTimeoutException;
+import java.sql.SQLTransientConnectionException;
 import java.sql.SQLWarning;
-import java.sql.SQLXML;
-import java.sql.Savepoint;
 import java.sql.Statement;
-import java.sql.Struct;
-import java.util.Map;
+import java.util.ArrayList;
+import java.util.List;
 import java.util.Properties;
 
 import org.apache.cassandra.thrift.AuthenticationException;
@@ -47,672 +50,297 @@ import org.apache.cassandra.thrift.Schem
 import org.apache.cassandra.thrift.TimedOutException;
 import org.apache.cassandra.thrift.UnavailableException;
 import org.apache.thrift.TException;
-import org.apache.thrift.transport.TTransportException;
 
 /**
  * Implementation class for {@link Connection}.
  */
-class CassandraConnection implements Connection
+class CassandraConnection extends AbstractCassandraConnection implements Connection
 {
+    private final boolean autoCommit = true;
+    
+    private final int transactionIsolation = Connection.TRANSACTION_NONE;
+    
+    /** Client Info Properties (currently unused) */
     private Properties clientInfo = new Properties();
-
-    /**
-     * The cassandra con.
-     */
+    
+    /** 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;
-
+    
     /**
-     * Instantiates a new cassandra connection.
-     *
-     * @param url the url
+     * Instantiates a new CassandraConnection.
      */
-    public CassandraConnection(String url)
+    public CassandraConnection(String url,Properties props) throws SQLException
     {
+        statements = new ArrayList<Statement>();
+        clientInfo = new Properties();
         try
         {
-            final int splitIndex = url.indexOf('@');
-            final String usr_pwd = url.substring(0, splitIndex);
-            final String host_port = url.substring(splitIndex + 1);
-            final int usr_colonIdx = usr_pwd.lastIndexOf(':');
-            final int usr_backwardIdx = usr_pwd.indexOf('/');
-            final String userName = usr_pwd.substring(usr_colonIdx + 1, usr_backwardIdx);
-            final String password = usr_pwd.substring(usr_backwardIdx + 1);
-            final int host_colonIdx = host_port.indexOf(':');
-            final String hostName = host_port.substring(0, host_colonIdx);
-            final int host_backwardIdx = host_port.indexOf('/');
-            final String port = host_port.substring(host_colonIdx + 1, host_backwardIdx);
-            final String keyspace = host_port.substring(host_backwardIdx + 1);
-            cassandraCon = new org.apache.cassandra.cql.jdbc.Connection(hostName, Integer.valueOf(port), userName, password);
+            String rawUri = url.substring(PROTOCOL.length());
+            URI uri = new URI(rawUri);
+            
+            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;
-            cassandraCon.execute(useQ);
-        }
-        catch (NumberFormatException e)
-        {
-            throw new DriverResolverException(e.getMessage());
+            if (keyspace!=null) cassandraCon.execute(useQ);
         }
-        catch (TTransportException e)
+        catch (SchemaDisagreementException e)
         {
-            throw new DriverResolverException(e.getMessage());
+            throw new SQLRecoverableException(SCHEMA_MISMATCH);
         }
-        catch (AuthenticationException e)
+        catch (URISyntaxException e)
         {
-            throw new DriverResolverException(e.getMessage());
+            throw new SQLNonTransientConnectionException(e);
         }
-        catch (AuthorizationException e)
+        catch (InvalidRequestException e)
         {
-            throw new DriverResolverException(e.getMessage());
+            throw new SQLSyntaxErrorException(e);
         }
-        catch (TException e)
+        catch (UnavailableException e)
         {
-            throw new DriverResolverException(e.getMessage());
+            throw new SQLNonTransientConnectionException(e);
         }
-        catch (InvalidRequestException e)
+        catch (TimedOutException e)
         {
-            throw new DriverResolverException(e.getMessage());
+            throw new SQLTransientConnectionException(e);
         }
-        catch (UnavailableException e)
+        catch (TException e)
         {
-            throw new DriverResolverException(e.getMessage());
+            throw new SQLNonTransientConnectionException(e);
         }
-        catch (TimedOutException e)
+        catch (AuthenticationException e)
         {
-            throw new DriverResolverException(e.getMessage());
+            throw new SQLInvalidAuthorizationSpecException(e);
         }
-        catch (SchemaDisagreementException e)
+        catch (AuthorizationException e)
         {
-            throw new DriverResolverException("schema does not match across nodes, (try again later).");
+            throw new SQLInvalidAuthorizationSpecException(e);
         }
-
     }
-
-    /**
-     * @param arg0
-     * @return
-     * @throws SQLException
-     */
-    public boolean isWrapperFor(Class<?> arg0) throws SQLException
+    
+    private final void checkNotClosed() throws SQLException
     {
-        throw new SQLException("no object is found that implements this interface");
+        if (isClosed()) throw new SQLNonTransientConnectionException(WAS_CLOSED_CON);
     }
-
-
-    /**
-     * @param <T>
-     * @param arg0
-     * @return
-     * @throws SQLException
-     */
-    public <T> T unwrap(Class<T> arg0) throws SQLException
-    {
-        throw new SQLException("no object is found that implements this interface");
-    }
-
-
-    /**
-     * @throws SQLException
-     */
+    
     public void clearWarnings() throws SQLException
     {
         // This implementation does not support the collection of warnings so clearing is a no-op
         // but it is still an exception to call this on a closed connection.
-        if (isClosed())
-            throw new SQLException("this method was called on a closed Connection");
+        checkNotClosed();
     }
 
     /**
      * On close of connection.
-     *
-     * @throws SQLException the sQL exception
      */
-    public void close() throws SQLException
+    public synchronized void close() throws SQLException
     {
         if (cassandraCon != null)
         {
+            // spec says to close all statements associated with this connection upon close
+            for (Statement statement : statements) statement.close();
             cassandraCon.close();
         }
     }
 
-
-    /**
-     * @throws SQLException
-     */
     public void commit() throws SQLException
     {
-        throw new SQLException("The Cassandra Implementation is always in auto-commit mode.");
-    }
-
-
-    /**
-     * @param arg0
-     * @param arg1
-     * @return
-     * @throws SQLException
-     */
-    public Array createArrayOf(String arg0, Object[] arg1) throws SQLException
-    {
-        throw new SQLFeatureNotSupportedException("the Cassandra Implementation does not support this method");
-    }
-
-
-    /**
-     * @return
-     * @throws SQLException
-     */
-    public Blob createBlob() throws SQLException
-    {
-        throw new SQLFeatureNotSupportedException("the Cassandra Implementation does not support this method");
+        checkNotClosed();
+        throw new SQLFeatureNotSupportedException(ALWAYS_AUTOCOMMIT);
     }
 
-
-    /**
-     * @return
-     * @throws SQLException
-     */
-    public Clob createClob() throws SQLException
-    {
-        throw new SQLFeatureNotSupportedException("the Cassandra Implementation does not support this method");
-    }
-
-
-    /**
-     * @return
-     * @throws SQLException
-     */
-    public NClob createNClob() throws SQLException
-    {
-        throw new SQLFeatureNotSupportedException("the Cassandra Implementation does not support this method");
-    }
-
-
-    /**
-     * @return
-     * @throws SQLException
-     */
-    public SQLXML createSQLXML() throws SQLException
-    {
-        throw new SQLFeatureNotSupportedException("the Cassandra Implementation does not support this method");
-    }
-
-
-    /**
-     * @return
-     * @throws SQLException
-     */
     public Statement createStatement() throws SQLException
     {
-        return new CassandraStatement(this.cassandraCon);
-    }
-
-
-    /**
-     * @param arg0
-     * @param arg1
-     * @return
-     * @throws SQLException
-     */
-    public Statement createStatement(int arg0, int arg1) throws SQLException
-    {
-        throw new SQLFeatureNotSupportedException("the Cassandra Implementation does not support this method");
+        checkNotClosed();
+        statements.add(new CassandraStatement(this.cassandraCon));
+        return statements.get(statements.size() - 1);
     }
 
-
-    /**
-     * @param arg0
-     * @param arg1
-     * @param arg2
-     * @return
-     * @throws SQLException
-     */
-    public Statement createStatement(int arg0, int arg1, int arg2) throws SQLException
+    public Statement createStatement(int resultSetType, int resultSetConcurrency) throws SQLException
     {
-        throw new SQLFeatureNotSupportedException("the Cassandra Implementation does not support this method");
+        checkNotClosed();
+        statements.add(new CassandraStatement(this.cassandraCon, null, resultSetType, resultSetConcurrency));
+        return statements.get(statements.size() - 1);
     }
 
-
-    /**
-     * @param arg0
-     * @param arg1
-     * @return
-     * @throws SQLException
-     */
-    public Struct createStruct(String arg0, Object[] arg1) throws SQLException
+    public Statement createStatement(int resultSetType, int resultSetConcurrency, int resultSetHoldability) throws SQLException
     {
-        throw new SQLFeatureNotSupportedException("the Cassandra Implementation does not support this method");
+        checkNotClosed();
+        statements.add(new CassandraStatement(this.cassandraCon, null, resultSetType, resultSetConcurrency, resultSetHoldability));
+        return statements.get(statements.size() - 1);
     }
 
-
-    /**
-     * @return
-     * @throws SQLException
-     */
     public boolean getAutoCommit() throws SQLException
     {
-        return true;
+        checkNotClosed();
+        return autoCommit;
     }
 
-
-    /**
-     * @return
-     * @throws SQLException
-     */
     public String getCatalog() throws SQLException
     {
         // This implementation does not support the catalog names so null is always returned if the connection is open.
         // but it is still an exception to call this on a closed connection.
-        if (isClosed())
-            throw new SQLException("this method was called on a closed Connection");
-
+        checkNotClosed();
         return null;
     }
 
-
-    /**
-     * @return
-     * @throws SQLException
-     */
     public Properties getClientInfo() throws SQLException
     {
-        if (isClosed())
-            throw new SQLException("this method was called on a closed Connection");
-
+        checkNotClosed();
         return clientInfo;
     }
-
-
-    /**
-     * @param label
-     * @return
-     * @throws SQLException
-     */
+    
     public String getClientInfo(String label) throws SQLException
     {
-        if (isClosed())
-            throw new SQLException("this method was called on a closed Connection");
-
+        checkNotClosed();
         return clientInfo.getProperty(label);
     }
 
-
-    /**
-     * @return
-     * @throws SQLException
-     */
     public int getHoldability() throws SQLException
     {
-        if (isClosed())
-            throw new SQLException("this method was called on a closed Connection");
-
+        checkNotClosed();
         // the rationale is there are really no commits in Cassandra so no boundary...
         return ResultSet.HOLD_CURSORS_OVER_COMMIT;
     }
-
-
-    /**
-     * @return
-     * @throws SQLException
-     */
+    
     public DatabaseMetaData getMetaData() throws SQLException
     {
-        if (isClosed())
-            throw new SQLException("this method was called on a closed Connection");
-
+        checkNotClosed();
         // the rationale is there is no DatabaseMetaData to return but if there was we would return it...
         return null;
     }
 
-
-    /**
-     * @return
-     * @throws SQLException
-     */
     public int getTransactionIsolation() throws SQLException
     {
-        if (isClosed())
-            throw new SQLException("this method was called on a closed Connection");
-
-        return Connection.TRANSACTION_NONE;
+        checkNotClosed();
+        return transactionIsolation;
     }
 
-
-    /**
-     * @return
-     * @throws SQLException
-     */
-    public Map<String, Class<?>> getTypeMap() throws SQLException
-    {
-        throw new SQLFeatureNotSupportedException("the Cassandra Implementation does not support this method");
-    }
-
-
-    /**
-     * @return
-     * @throws SQLException
-     */
     public SQLWarning getWarnings() throws SQLException
     {
-        if (isClosed())
-            throw new SQLException("this method was called on a closed Connection");
-
+        checkNotClosed();
         // the rationale is there are no warnings to return in this implementation...
         return null;
     }
 
-
-    /**
-     * @return
-     * @throws SQLException
-     */
-    public boolean isClosed() throws SQLException
+    public synchronized boolean isClosed() throws SQLException
     {
-        if (cassandraCon == null)
-            return true;
+        if (cassandraCon == null) return true;
 
         return !cassandraCon.isOpen();
     }
 
-
-    /**
-     * @return
-     * @throws SQLException
-     */
     public boolean isReadOnly() throws SQLException
     {
+        checkNotClosed();
         return false;
     }
 
-
-    /**
-     * @param timeout
-     * @return
-     * @throws SQLException
-     */
     public boolean isValid(int timeout) throws SQLException
     {
-
-        if (timeout < 0)
-            throw new SQLException("the timeout value was less than zero");
+        checkNotClosed();
+        if (timeout < 0) throw new SQLTimeoutException(BAD_TIMEOUT);
 
         // this needs to be more robust. Some query needs to be made to verify connection is really up.
         return !isClosed();
     }
 
+    public boolean isWrapperFor(Class<?> arg0) throws SQLException
+    {
+        return false;
+    }
 
-    /**
-     * @param sql
-     * @return
-     * @throws SQLException
-     */
     public String nativeSQL(String sql) throws SQLException
     {
-        if (isClosed())
-            throw new SQLException("this method was called on a closed Connection");
-
+        checkNotClosed();
         // the rationale is there are no distinction between grammars in this implementation...
         // so we are just return the input argument
         return sql;
     }
 
-
-    /**
-     * @param arg0
-     * @return
-     * @throws SQLException
-     */
-    public CallableStatement prepareCall(String arg0) throws SQLException
-    {
-        throw new SQLFeatureNotSupportedException("the Cassandra Implementation does not support this method");
-    }
-
-
-    /**
-     * @param arg0
-     * @param arg1
-     * @param arg2
-     * @return
-     * @throws SQLException
-     */
-    public CallableStatement prepareCall(String arg0, int arg1, int arg2) throws SQLException
-    {
-        throw new SQLFeatureNotSupportedException("the Cassandra Implementation does not support this method");
-    }
-
-
-    /**
-     * @param arg0
-     * @param arg1
-     * @param arg2
-     * @param arg3
-     * @return
-     * @throws SQLException
-     */
-    public CallableStatement prepareCall(String arg0, int arg1, int arg2, int arg3) throws SQLException
-    {
-        throw new SQLFeatureNotSupportedException("the Cassandra Implementation does not support this method");
-    }
-
-
-    /**
-     * @param sql
-     * @return
-     * @throws SQLException
-     */
     public PreparedStatement prepareStatement(String sql) throws SQLException
     {
-        return new CassandraPreparedStatement(this.cassandraCon, sql);
-    }
-
-
-    /**
-     * @param arg0
-     * @param arg1
-     * @return
-     * @throws SQLException
-     */
-    public PreparedStatement prepareStatement(String arg0, int arg1) throws SQLException
-    {
-        throw new SQLFeatureNotSupportedException("the Cassandra Implementation does not support this method");
+        checkNotClosed();
+        statements.add(new CassandraPreparedStatement(this.cassandraCon, sql));
+        return (PreparedStatement)statements.get(statements.size() - 1);
     }
 
-
-    /**
-     * @param arg0
-     * @param arg1
-     * @return
-     * @throws SQLException
-     */
-    public PreparedStatement prepareStatement(String arg0, int[] arg1) throws SQLException
-    {
-        throw new SQLFeatureNotSupportedException("the Cassandra Implementation does not support this method");
-    }
-
-
-    /**
-     * @param arg0
-     * @param arg1
-     * @return
-     * @throws SQLException
-     */
-    public PreparedStatement prepareStatement(String arg0, String[] arg1) throws SQLException
-    {
-        throw new SQLFeatureNotSupportedException("the Cassandra Implementation does not support this method");
-    }
-
-
-    /**
-     * @param arg0
-     * @param arg1
-     * @param arg2
-     * @return
-     * @throws SQLException
-     */
     public PreparedStatement prepareStatement(String arg0, int arg1, int arg2) throws SQLException
     {
-        throw new SQLFeatureNotSupportedException("the Cassandra Implementation does not support this method");
+        throw new SQLFeatureNotSupportedException(NOT_SUPPORTED);
     }
 
-
-    /**
-     * @param arg0
-     * @param arg1
-     * @param arg2
-     * @param arg3
-     * @return
-     * @throws SQLException
-     */
     public PreparedStatement prepareStatement(String arg0, int arg1, int arg2, int arg3) throws SQLException
     {
-        throw new SQLFeatureNotSupportedException("the Cassandra Implementation does not support this method");
+        throw new SQLFeatureNotSupportedException(NOT_SUPPORTED);
     }
 
-
-    /**
-     * @param arg0
-     * @throws SQLException
-     */
-    public void releaseSavepoint(Savepoint arg0) throws SQLException
-    {
-        throw new SQLFeatureNotSupportedException("the Cassandra Implementation does not support this method");
-    }
-
-
-    /**
-     * @throws SQLException
-     */
     public void rollback() throws SQLException
     {
-        throw new SQLException("the Cassandra Implementation is always in auto-commit mode");
-    }
-
-
-    /**
-     * @param arg0
-     * @throws SQLException
-     */
-    public void rollback(Savepoint arg0) throws SQLException
-    {
-        throw new SQLFeatureNotSupportedException("the Cassandra Implementation does not support this method");
+        checkNotClosed();
+        throw new SQLFeatureNotSupportedException(ALWAYS_AUTOCOMMIT);
     }
 
-
-    /**
-     * @param autoCommit
-     * @throws SQLException
-     */
     public void setAutoCommit(boolean autoCommit) throws SQLException
     {
-        if (!autoCommit)
-            throw new SQLException("the Cassandra Implementation is always in auto-commit mode");
+        checkNotClosed();
+        if (!autoCommit) throw new SQLFeatureNotSupportedException(ALWAYS_AUTOCOMMIT);
     }
 
-
-    /**
-     * @param arg0
-     * @throws SQLException
-     */
     public void setCatalog(String arg0) throws SQLException
     {
-        if (isClosed())
-            throw new SQLException("this method was called on a closed Connection");
-
+        checkNotClosed();
         // the rationale is there are no catalog name to set in this implementation...
         // so we are "silently ignoring" the request
     }
 
-
-    /**
-     * @param props
-     * @throws SQLClientInfoException
-     */
     public void setClientInfo(Properties props) throws SQLClientInfoException
     {
-        // this needs to be revisited when and if we actually start to use the clientInfo properties
-        if (props != null)
-            clientInfo = props;
+        // we don't use them but we will happily collect them for now...
+        if (props != null) clientInfo = props;
     }
 
-
-    /**
-     * @param key
-     * @param value
-     * @throws SQLClientInfoException
-     */
     public void setClientInfo(String key, String value) throws SQLClientInfoException
     {
-        // this needs to be revisited when and if we actually start to use the clientInfo properties
+        // we don't use them but we will happily collect them for now...
         clientInfo.setProperty(key, value);
     }
 
-
-    /**
-     * @param arg0
-     * @throws SQLException
-     */
     public void setHoldability(int arg0) throws SQLException
     {
-        if (isClosed())
-            throw new SQLException("this method was called on a closed Connection");
-
+        checkNotClosed();
         // the rationale is there are no holdability to set in this implementation...
         // so we are "silently ignoring" the request
     }
-
-
-    /**
-     * @param arg0
-     * @throws SQLException
-     */
+    
     public void setReadOnly(boolean arg0) throws SQLException
     {
-        if (isClosed())
-            throw new SQLException("this method was called on a closed Connection");
-
+        checkNotClosed();
         // the rationale is all connections are read/write in the Cassandra implementation...
         // so we are "silently ignoring" the request
     }
 
-
-    /**
-     * @return
-     * @throws SQLException
-     */
-    public Savepoint setSavepoint() throws SQLException
-    {
-        throw new UnsupportedOperationException("method not supported");
-    }
-
-
-    /**
-     * @param arg0
-     * @return
-     * @throws SQLException
-     */
-    public Savepoint setSavepoint(String arg0) throws SQLException
-    {
-        throw new SQLFeatureNotSupportedException("the Cassandra Implementation does not support this method");
-    }
-
-
-    /**
-     * @param level
-     * @throws SQLException
-     */
     public void setTransactionIsolation(int level) throws SQLException
     {
-        if (isClosed())
-            throw new SQLException("this method was called on a closed Connection");
-
-        if (level != Connection.TRANSACTION_NONE)
-            throw new SQLException("the Cassandra Inplementation does not support transactions");
+        checkNotClosed();
+        if (level != Connection.TRANSACTION_NONE) throw new SQLFeatureNotSupportedException(NO_TRANSACTIONS);
     }
 
-
-    /**
-     * @param arg0
-     * @throws SQLException
-     */
-    public void setTypeMap(Map<String, Class<?>> arg0) throws SQLException
+    public <T> T unwrap(Class<T> iface) throws SQLException
     {
-        throw new SQLFeatureNotSupportedException("the Cassandra Implementation does not support this method");
+        throw new SQLFeatureNotSupportedException(String.format(NO_INTERFACE, iface.getSimpleName()));
     }
-
 }

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=1137231&r1=1137230&r2=1137231&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 Sat Jun 18 19:19:13 2011
@@ -25,6 +25,7 @@ import java.sql.Driver;
 import java.sql.DriverManager;
 import java.sql.DriverPropertyInfo;
 import java.sql.SQLException;
+import java.sql.SQLNonTransientConnectionException;
 import java.util.Properties;
 
 /**
@@ -38,9 +39,11 @@ import java.util.Properties;
     
     /** The Constant MINOR_VERSION. */
     private static final int MINOR_VERSION = 0;
+    
+    private static final String BAD_URL = "Invalid connection url: '%s'. it should start with 'jdbc:cassandra:'";
 
     /** The ACCEPT s_ url. */
-    private static String ACCEPTS_URL = "jdbc:cassandra";
+    public static final String ACCEPTS_URL = "jdbc:cassandra:";
     
 //    private static final Logger logger = LoggerFactory.getLogger(CassandraDriver.class); 
 
@@ -57,14 +60,9 @@ import java.util.Properties;
             throw new DriverResolverException(e.getMessage());
         }
     }
-
     
     /**
      * Method to validate whether provided connection url matches with pattern or not.
-     *
-     * @param url  connection url.
-     * @return true, if successful
-     * @throws SQLException the sQL exception
      */
     public boolean acceptsURL(String url) throws SQLException
     {
@@ -73,27 +71,21 @@ import java.util.Properties;
 
     /**
      * Method to return connection instance for given connection url and connection props.
-     *
-     * @param url               connection url.
-     * @param props          connection properties.
-     * @return connection connection instance.
-     * @throws SQLException the sQL exception
      */
     public Connection connect(String url, Properties props) throws SQLException
     {
         if (acceptsURL(url))
         {
-            return new CassandraConnection(url);
+            return new CassandraConnection(url, props);
         }
         else
         {
-            throw new InvalidUrlException("Invalid connection url:" + url + ". should start with jdbc:cassandra");
+            throw new SQLNonTransientConnectionException(String.format(BAD_URL, url));
         }
     }
 
     /**
      * Returns default major version.
-     * @return MAJOR_VERSION major version.
      */
     public int getMajorVersion()
     {
@@ -102,7 +94,6 @@ import java.util.Properties;
 
     /**
      * Returns default minor version.
-     * @return MINOR_VERSION minor version.
      */
     public int getMinorVersion()
     {
@@ -111,24 +102,17 @@ import java.util.Properties;
 
     /**
      * Returns default driver property info object.
-     *
-     * @param arg0 the arg0
-     * @param arg1 the arg1
-     * @return driverPropertyInfo
-     * @throws SQLException the sQL exception
      */
     public DriverPropertyInfo[] getPropertyInfo(String arg0, Properties arg1) throws SQLException
     {
         return new DriverPropertyInfo[0];
     }
 
-   /**
-    * Returns true, if it is jdbc compliant.    
-    * @return value true, if it is jdbc compliant.
-    */
+    /**
+     * Returns true, if it is jdbc compliant.
+     */
     public boolean jdbcCompliant()
     {
         return false;
     }
-
 }

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=1137231&r1=1137230&r2=1137231&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 Sat Jun 18 19:19:13 2011
@@ -66,7 +66,7 @@ public class CassandraPreparedStatement 
     // 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)
+    CassandraPreparedStatement(Connection con, String cql) throws SQLException
     {
         super(con, cql);
     }

Modified: cassandra/drivers/java/src/org/apache/cassandra/cql/jdbc/CassandraResultSet.java
URL: http://svn.apache.org/viewvc/cassandra/drivers/java/src/org/apache/cassandra/cql/jdbc/CassandraResultSet.java?rev=1137231&r1=1137230&r2=1137231&view=diff
==============================================================================
--- cassandra/drivers/java/src/org/apache/cassandra/cql/jdbc/CassandraResultSet.java (original)
+++ cassandra/drivers/java/src/org/apache/cassandra/cql/jdbc/CassandraResultSet.java Sat Jun 18 19:19:13 2011
@@ -20,25 +20,26 @@ package org.apache.cassandra.cql.jdbc;
  * 
  */
 
-
 import java.math.BigInteger;
 import java.sql.ResultSet;
+import java.sql.SQLException;
 
 public interface CassandraResultSet extends ResultSet
 {
     /**
      * @return the current row key
      */
-    public byte[] getKey();
-    public TypedColumn getTypedKey();
+    public byte[] getKey()throws SQLException;;
+    
+    public TypedColumn getTypedKey()throws SQLException;;
 
     /** @return a BigInteger value for the given column offset*/
-    public BigInteger getBigInteger(int i);
+    public BigInteger getBigInteger(int i) throws SQLException;
     /** @return a BigInteger value for the given column name */
-    public BigInteger getBigInteger(String name);
+    public BigInteger getBigInteger(String name) throws SQLException;
 
     /** @return the raw column data for the given column offset */
-    public TypedColumn getColumn(int i);
+    public TypedColumn getColumn(int i) throws SQLException;
     /** @return the raw column data for the given column name */
-    public TypedColumn getColumn(String name);
+    public TypedColumn getColumn(String name) throws SQLException;
 }