Author: gdusbabek
Date: Thu Mar 17 15:13:33 2011
New Revision: 1082524

URL: http://svn.apache.org/viewvc?rev=1082524&view=rev
Log:
implement a real ResultSetMetaData

Added:
    
cassandra/trunk/drivers/java/src/org/apache/cassandra/cql/jdbc/CassandraResultSetMetaData.java
    
cassandra/trunk/drivers/java/src/org/apache/cassandra/cql/jdbc/ColumnMetaData.java
Removed:
    
cassandra/trunk/drivers/java/src/org/apache/cassandra/cql/jdbc/RowMetaData.java
Modified:
    
cassandra/trunk/drivers/java/src/org/apache/cassandra/cql/jdbc/CassandraResultSet.java
    
cassandra/trunk/drivers/java/src/org/apache/cassandra/cql/jdbc/ColumnDecoder.java
    
cassandra/trunk/drivers/java/src/org/apache/cassandra/cql/jdbc/TypedColumn.java
    
cassandra/trunk/drivers/java/test/org/apache/cassandra/cql/JdbcDriverTest.java
    
cassandra/trunk/src/java/org/apache/cassandra/db/marshal/AbstractCommutativeType.java
    cassandra/trunk/src/java/org/apache/cassandra/db/marshal/AbstractType.java
    cassandra/trunk/src/java/org/apache/cassandra/db/marshal/AsciiType.java
    cassandra/trunk/src/java/org/apache/cassandra/db/marshal/BytesType.java
    cassandra/trunk/src/java/org/apache/cassandra/db/marshal/IntegerType.java
    
cassandra/trunk/src/java/org/apache/cassandra/db/marshal/LexicalUUIDType.java
    
cassandra/trunk/src/java/org/apache/cassandra/db/marshal/LocalByPartionerType.java
    cassandra/trunk/src/java/org/apache/cassandra/db/marshal/LongType.java
    cassandra/trunk/src/java/org/apache/cassandra/db/marshal/TimeUUIDType.java
    cassandra/trunk/src/java/org/apache/cassandra/db/marshal/UTF8Type.java

Modified: 
cassandra/trunk/drivers/java/src/org/apache/cassandra/cql/jdbc/CassandraResultSet.java
URL: 
http://svn.apache.org/viewvc/cassandra/trunk/drivers/java/src/org/apache/cassandra/cql/jdbc/CassandraResultSet.java?rev=1082524&r1=1082523&r2=1082524&view=diff
==============================================================================
--- 
cassandra/trunk/drivers/java/src/org/apache/cassandra/cql/jdbc/CassandraResultSet.java
 (original)
+++ 
cassandra/trunk/drivers/java/src/org/apache/cassandra/cql/jdbc/CassandraResultSet.java
 Thu Mar 17 15:13:33 2011
@@ -36,18 +36,26 @@ import java.sql.ResultSet;
 import java.sql.ResultSetMetaData;
 import java.sql.RowId;
 import java.sql.SQLException;
+import java.sql.SQLFeatureNotSupportedException;
 import java.sql.SQLWarning;
 import java.sql.SQLXML;
 import java.sql.Statement;
 import java.sql.Time;
 import java.sql.Timestamp;
+import java.sql.Types;
 import java.util.ArrayList;
 import java.util.Calendar;
 import java.util.Iterator;
 import java.util.List;
 import java.util.Map;
+import java.util.UUID;
 import java.util.WeakHashMap;
 
+import org.apache.cassandra.db.marshal.AbstractType;
+import org.apache.cassandra.db.marshal.BytesType;
+import org.apache.cassandra.db.marshal.CounterColumnType;
+import org.apache.cassandra.db.marshal.IntegerType;
+import org.apache.cassandra.db.marshal.LongType;
 import org.apache.cassandra.thrift.Column;
 import org.apache.cassandra.thrift.CqlResult;
 import org.apache.cassandra.thrift.CqlRow;
@@ -76,6 +84,8 @@ class CassandraResultSet<N, V> implement
     
     /** The value map. */
     private Map<String, Object> valueMap = new WeakHashMap<String, Object>();
+    
+    private final RsMetaData meta;
 
     /**
      * Instantiates a new cassandra result set.
@@ -89,6 +99,7 @@ class CassandraResultSet<N, V> implement
         this.keyspace = keyspace;
         this.columnFamily = columnFamily;
         rSetIter = rSet.getRowsIterator();
+        meta = new RsMetaData();
     }
 
     /**
@@ -98,7 +109,7 @@ class CassandraResultSet<N, V> implement
      */
     public boolean isWrapperFor(Class<?> iface) throws SQLException
     {
-        throw new UnsupportedOperationException("method not supported");
+        return false;
     }
 
     /**
@@ -579,7 +590,7 @@ class CassandraResultSet<N, V> implement
      */
     public ResultSetMetaData getMetaData() throws SQLException
     {
-        throw new UnsupportedOperationException("method not supported");
+        return meta;
     }
 
     /**
@@ -1032,11 +1043,7 @@ class CassandraResultSet<N, V> implement
      */
     public <T> T unwrap(Class<T> iface) throws SQLException
     {
-        // exposes the current row only.
-        if (iface.equals(RowMetaData.class))
-            return (T)new CassandraRowMetaData(this);
-        else
-            throw new SQLException("Unsupported unwrap interface: " + 
iface.getSimpleName());
+        throw new SQLException("Unsupported unwrap interface: " + 
iface.getSimpleName());
     }
     
     /**
@@ -1999,55 +2006,331 @@ class CassandraResultSet<N, V> implement
     {
         throw new UnsupportedOperationException("method not supported");
     }
-
-    private class CassandraRowMetaData<N, V> implements RowMetaData<N, V>
+    
+    /**
+     * RSMD implementation. Except where explicitly noted the metadata 
returned refers to the column 
+     * values, not the column names. There is an additional interface that 
describes column name 
+     * meta information.
+     */
+    private class RsMetaData implements CassandraResultSetMetaData, 
ResultSetMetaData
     {
-        private final List<TypedColumn<N, V>> cols;
-        private final byte[] key;
-        private final Class colClass;
-        private final Class valClass;
+        public byte[] getKey()
+        {
+            return curRowKey;
+        }
+
+        public boolean isNameCaseSensitive(int column) throws SQLException
+        {
+            checkIndex(column);
+            if (values.get(column).getNameType() instanceof ColumnMetaData)
+                return 
((ColumnMetaData)values.get(column).getNameType()).isCaseSensitive();
+            else 
+                return 
values.get(column).getNameType().getType().equals(String.class);
+        }
         
-        private CassandraRowMetaData(CassandraResultSet rs) {
-            cols = new ArrayList<TypedColumn<N, V>>(rs.values);
-            assert rs.values.size() > 0;
-            colClass = rs.values.get(0).getClass();
-            valClass = rs.values.get(0).getClass();
-            key = curRowKey;
+        public boolean isValueCaseSensitive(int column) throws SQLException
+        {
+            checkIndex(column);
+            if (values.get(column).getValueType() instanceof ColumnMetaData)
+                return 
((ColumnMetaData)values.get(column).getValueType()).isCaseSensitive();
+            else 
+                return 
values.get(column).getValueType().getType().equals(String.class);
         }
 
-        public int getColumnCount()
+        public boolean isNameCurrency(int column) throws SQLException
         {
-            return cols.size();
+            checkIndex(column);
+            if (values.get(column).getNameType() instanceof ColumnMetaData)
+                return 
((ColumnMetaData)values.get(column).getNameType()).isCurrency();
+            else
+                return false;
+        }
+        
+        public boolean isValueCurrency(int column) throws SQLException
+        {
+            checkIndex(column);
+            if (values.get(column).getValueType() instanceof ColumnMetaData)
+                return 
((ColumnMetaData)values.get(column).getValueType()).isCurrency();
+            else
+                return false;
         }
 
-        public N getColumnName(int index)
+        public boolean isNameSigned(int column) throws SQLException
+        {
+            checkIndex(column);
+            TypedColumn col = values.get(column);
+            if (col.getNameType() == IntegerType.instance || col.getNameType() 
== LongType.instance)
+                return true;
+            else if (col.getNameType() instanceof ColumnMetaData) 
+                return ((ColumnMetaData)col.getNameType()).isSigned();
+            else
+                return false;
+        }
+        
+        public boolean isValueSigned(int column) throws SQLException
         {
-            return cols.get(index).getName();
+            checkIndex(column);
+            TypedColumn col = values.get(column);
+            if (col.getValueType() == IntegerType.instance || 
col.getValueType() == LongType.instance)
+                return true;
+            else if (col.getValueType() instanceof ColumnMetaData) 
+                return ((ColumnMetaData)col.getValueType()).isSigned();
+            else
+                return false;
         }
 
-        public V getColumnValue(int index)
+        public int getNameDisplaySize(int column) throws SQLException
         {
-            return cols.get(index).getValue();
+            return getColumnName(column).length();
         }
 
-        public Class getColumnNameClass()
+        public int getValueDisplaySize(int column) throws SQLException
         {
-            return colClass;
+            checkIndex(column);
+            return values.get(column).getValueString().length();
         }
 
-        public Class getColumnValueClass()
+        public int getNamePrecision(int column) throws SQLException
+        {
+            checkIndex(column);
+            TypedColumn col = values.get(column);
+            if (col.getNameType() instanceof ColumnMetaData)
+                return ((ColumnMetaData)col.getNameType()).getPrecision();
+            else if (col.getNameType().getType().equals(String.class))
+                return col.getNameString().length();
+            else if (col.getNameType() == BytesType.instance)
+                return col.getNameString().length();
+            else if (col.getNameType().getType().equals(UUID.class))
+                return 36; // xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx
+            else if (col.getNameType() == LongType.instance)
+                return 19; // number of digits in 2**63-1.
+            else 
+                return 0;
+        }
+        
+        public int getValuePrecision(int column) throws SQLException
         {
-            return valClass;
+            checkIndex(column);
+            TypedColumn col = values.get(column);
+            if (col.getValueType() instanceof ColumnMetaData)
+                return ((ColumnMetaData)col.getValueType()).getPrecision();
+            else if (col.getValueType().getType().equals(String.class))
+                return col.getValueString().length();
+            else if (col.getValueType() == BytesType.instance)
+                return col.getValueString().length();
+            else if (col.getValueType().getType().equals(UUID.class))
+                return 36; // xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx
+            else if (col.getValueType() == LongType.instance)
+                return 19; // number of digits in 2**63-1.
+            else 
+                return 0;
         }
 
-        public TypedColumn getColumn(int index)
+        public int getNameScale(int column) throws SQLException
         {
-            return cols.get(index);
+            checkIndex(column);
+            if (values.get(column).getValueType() instanceof ColumnMetaData)
+                return 
((ColumnMetaData)values.get(column).getNameType()).getScale();
+            else
+                return 0;
+        }
+        
+        public int getValueScale(int column) throws SQLException
+        {
+            checkIndex(column);
+            if (values.get(column).getValueType() instanceof ColumnMetaData)
+                return 
((ColumnMetaData)values.get(column).getValueType()).getScale();
+            else
+                return 0;
         }
 
-        public byte[] getKey()
+        public int getNameType(int column) throws SQLException
+        {
+            checkIndex(column);
+            return getJdbcType(values.get(column).getNameType());
+        }
+        
+        public int getValueType(int column) throws SQLException
         {
-            return key;
+            checkIndex(column);
+            return getJdbcType(values.get(column).getValueType());
+        }
+        
+        private int getJdbcType(AbstractType type) throws SQLException
+        {
+            
+            if (type instanceof ColumnMetaData)
+                return ((ColumnMetaData)type).getType();
+            else if (type == IntegerType.instance)
+                return Types.BIGINT;
+            else if (type.getType().equals(Long.class))
+                return Types.BIGINT; // not the best fit.
+            else if (type.getType().equals(String.class))
+                return Types.VARCHAR;
+            else if (type.getType().equals(UUID.class))
+                return Types.TIMESTAMP;
+            else if (type == BytesType.instance)
+                return Types.BINARY;
+            else
+                throw new SQLException("Uninterpretable JDBC type " + 
type.getClass().getName());
+        }
+
+        public String getNameTypeName(int column) throws SQLException
+        {
+            checkIndex(column);
+            return values.get(column).getNameType().getClass().getSimpleName();
+        }
+        
+        public String getValueTypeName(int column) throws SQLException
+        {
+            checkIndex(column);
+            return 
values.get(column).getValueType().getClass().getSimpleName();
+        }
+
+        public String getNameClassName(int column) throws SQLException
+        {
+            checkIndex(column);
+            return values.get(column).getNameType().getType().getName();
+        }
+
+        public String getValueClassName(int column) throws SQLException
+        {
+            checkIndex(column);
+            return values.get(column).getValueType().getType().getName();
+        }
+        
+        //
+        // ResultSetMetaData
+        //
+        
+        private void checkIndex(int i) throws SQLException
+        {
+            if (i >= values.size())
+                throw new SQLException("Invalid column index " + i);
+        }
+        
+        public int getColumnCount() throws SQLException
+        {
+            return values.size();
+        }
+
+        public boolean isAutoIncrement(int column) throws SQLException
+        {
+            checkIndex(column);
+            return values.get(column).getValueType() instanceof 
CounterColumnType; // todo: check Value is correct.
+        }
+
+        public boolean isCaseSensitive(int column) throws SQLException
+        {
+            return isValueCaseSensitive(column);
+        }
+
+        public boolean isSearchable(int column) throws SQLException
+        {
+            return false;
+        }
+
+        public boolean isCurrency(int column) throws SQLException
+        {
+            return isValueCurrency(column);
+        }
+
+        public int isNullable(int column) throws SQLException
+        {
+            // no such thing as null in cassandra.
+            return ResultSetMetaData.columnNullableUnknown;
+        }
+
+        public boolean isSigned(int column) throws SQLException
+        {
+            return isValueSigned(column);
+        }
+
+        public int getColumnDisplaySize(int column) throws SQLException
+        {
+            return getValueDisplaySize(column);
+        }
+
+        public String getColumnLabel(int column) throws SQLException
+        {
+            return getColumnName(column);
+        }
+
+        public String getColumnName(int column) throws SQLException
+        {
+            checkIndex(column);
+            return values.get(column).getNameString();
+        }
+
+        public String getSchemaName(int column) throws SQLException
+        {
+            return keyspace;
+        }
+
+        public int getPrecision(int column) throws SQLException
+        {
+            return getValuePrecision(column);
+        }
+
+        public int getScale(int column) throws SQLException
+        {
+            return getValueScale(column);
+        }
+
+        public String getTableName(int column) throws SQLException
+        {
+            return columnFamily;
+        }
+
+        public String getCatalogName(int column) throws SQLException
+        {
+            throw new SQLFeatureNotSupportedException("Cassandra has no 
catalogs");
+        }
+
+        public int getColumnType(int column) throws SQLException
+        {
+            return getValueType(column);
+        }
+
+        // todo: spec says "database specific type name". this means the 
abstract type.
+        public String getColumnTypeName(int column) throws SQLException
+        {
+            return getValueTypeName(column);
+        }
+
+        public boolean isReadOnly(int column) throws SQLException
+        {
+            return column == 0;
+        }
+
+        public boolean isWritable(int column) throws SQLException
+        {
+            return column > 0;
+        }
+
+        public boolean isDefinitelyWritable(int column) throws SQLException
+        {
+            return isWritable(column);
+        }
+
+        public String getColumnClassName(int column) throws SQLException
+        {
+            return getValueClassName(column);
+        }
+
+        // todo: once the kinks are worked out, allow unwrapping as 
CassandraResultSetMetaData.
+        public <T> T unwrap(Class<T> iface) throws SQLException
+        {
+//            if (iface.equals(CassandraResultSetMetaData.class))
+//                return (T)this;
+//            else
+                throw new SQLFeatureNotSupportedException("No wrappers");
+        }
+
+        public boolean isWrapperFor(Class<?> iface) throws SQLException
+        {
+//            return CassandraResultSetMetaData.class.isAssignableFrom(iface);
+            return false;
         }
     }
 }

Added: 
cassandra/trunk/drivers/java/src/org/apache/cassandra/cql/jdbc/CassandraResultSetMetaData.java
URL: 
http://svn.apache.org/viewvc/cassandra/trunk/drivers/java/src/org/apache/cassandra/cql/jdbc/CassandraResultSetMetaData.java?rev=1082524&view=auto
==============================================================================
--- 
cassandra/trunk/drivers/java/src/org/apache/cassandra/cql/jdbc/CassandraResultSetMetaData.java
 (added)
+++ 
cassandra/trunk/drivers/java/src/org/apache/cassandra/cql/jdbc/CassandraResultSetMetaData.java
 Thu Mar 17 15:13:33 2011
@@ -0,0 +1,35 @@
+package org.apache.cassandra.cql.jdbc;
+
+import java.sql.SQLException;
+
+/**
+ * ResultSetMetaData give lots of nice detailed type inforamtion about column 
values.
+ * This interface aims to do the same thing but distinguishes column names and 
values.
+ */
+interface CassandraResultSetMetaData
+{
+    /** exposes row key */
+    public byte[] getKey();
+    
+    // the rest of these methods have similar calls in 
java.sql.ResultSetMetaData.
+    
+    public boolean isNameCaseSensitive(int column) throws SQLException;
+    public boolean isNameCurrency(int column) throws SQLException;
+    public boolean isNameSigned(int column) throws SQLException;
+    public int getNameDisplaySize(int column) throws SQLException;
+    public int getNamePrecision(int column) throws SQLException;
+    public int getNameScale(int column) throws SQLException;
+    public int getNameType(int column) throws SQLException;
+    public String getNameTypeName(int column) throws SQLException;
+    public String getNameClassName(int column) throws SQLException;
+    
+    public boolean isValueCaseSensitive(int column) throws SQLException;
+    public boolean isValueCurrency(int column) throws SQLException;
+    public boolean isValueSigned(int column) throws SQLException;
+    public int getValueDisplaySize(int column) throws SQLException;
+    public int getValuePrecision(int column) throws SQLException;
+    public int getValueScale(int column) throws SQLException;
+    public int getValueType(int column) throws SQLException;
+    public String getValueTypeName(int column) throws SQLException;
+    public String getValueClassName(int column) throws SQLException;
+}

Modified: 
cassandra/trunk/drivers/java/src/org/apache/cassandra/cql/jdbc/ColumnDecoder.java
URL: 
http://svn.apache.org/viewvc/cassandra/trunk/drivers/java/src/org/apache/cassandra/cql/jdbc/ColumnDecoder.java?rev=1082524&r1=1082523&r2=1082524&view=diff
==============================================================================
--- 
cassandra/trunk/drivers/java/src/org/apache/cassandra/cql/jdbc/ColumnDecoder.java
 (original)
+++ 
cassandra/trunk/drivers/java/src/org/apache/cassandra/cql/jdbc/ColumnDecoder.java
 Thu Mar 17 15:13:33 2011
@@ -127,7 +127,6 @@ class ColumnDecoder 
         CfDef cfDef = cfDefs.get(String.format("%s.%s", keyspace, 
columnFamily));
         AbstractType comparator = getComparator(keyspace, columnFamily, 
Specifier.Comparator, cfDef);
         AbstractType validator = getComparator(keyspace, columnFamily, 
Specifier.Validator, null);
-        // todo: generate less garbage.
-        return new TypedColumn(comparator.compose(ByteBuffer.wrap(name)), 
validator.compose(ByteBuffer.wrap(value)));
+        return new TypedColumn(comparator, name, validator, value);
     }
 }

Added: 
cassandra/trunk/drivers/java/src/org/apache/cassandra/cql/jdbc/ColumnMetaData.java
URL: 
http://svn.apache.org/viewvc/cassandra/trunk/drivers/java/src/org/apache/cassandra/cql/jdbc/ColumnMetaData.java?rev=1082524&view=auto
==============================================================================
--- 
cassandra/trunk/drivers/java/src/org/apache/cassandra/cql/jdbc/ColumnMetaData.java
 (added)
+++ 
cassandra/trunk/drivers/java/src/org/apache/cassandra/cql/jdbc/ColumnMetaData.java
 Thu Mar 17 15:13:33 2011
@@ -0,0 +1,16 @@
+package org.apache.cassandra.cql.jdbc;
+
+/**
+ * This interface lets AbstractTypes derived outside of the cassandra project 
answer JDBC questions
+ * relating to type.  Only bother implmenting this on your AbstractTypes if 
you're going to use JDBC
+ * and ResultSetMetaData.
+ */
+public interface ColumnMetaData
+{
+    public boolean isSigned();
+    public boolean isCaseSensitive();
+    public boolean isCurrency();
+    public int getPrecision();
+    public int getScale();
+    public int getType();
+}

Modified: 
cassandra/trunk/drivers/java/src/org/apache/cassandra/cql/jdbc/TypedColumn.java
URL: 
http://svn.apache.org/viewvc/cassandra/trunk/drivers/java/src/org/apache/cassandra/cql/jdbc/TypedColumn.java?rev=1082524&r1=1082523&r2=1082524&view=diff
==============================================================================
--- 
cassandra/trunk/drivers/java/src/org/apache/cassandra/cql/jdbc/TypedColumn.java 
(original)
+++ 
cassandra/trunk/drivers/java/src/org/apache/cassandra/cql/jdbc/TypedColumn.java 
Thu Mar 17 15:13:33 2011
@@ -1,14 +1,28 @@
 package org.apache.cassandra.cql.jdbc;
 
+import org.apache.cassandra.db.marshal.AbstractType;
+
+import java.nio.ByteBuffer;
+
 class TypedColumn<N, V>
 {
-    public final N name;
-    public final V value;
+    private final N name;
+    private final V value;
+    private final AbstractType<N> nameType;
+    private final AbstractType<V> valueType;
+    private final String nameString;
+    private final String valueString;
     
-    public TypedColumn(N name, V value)
+    public TypedColumn(AbstractType<N> comparator, byte[] name, 
AbstractType<V> validator, byte[] value)
     {
-        this.name = name;
-        this.value = value;
+        ByteBuffer bbName = ByteBuffer.wrap(name);
+        ByteBuffer bbValue = ByteBuffer.wrap(value);
+        this.name = comparator.compose(bbName);
+        this.value = validator.compose(bbValue);
+        nameType = comparator;
+        valueType = validator;
+        nameString = comparator.getString(bbName);
+        valueString = validator.getString(bbValue);
     }
     
     public N getName()
@@ -20,4 +34,24 @@ class TypedColumn<N, V>
     {
         return value;
     }
+    
+    public AbstractType<N> getNameType()
+    {
+        return nameType;
+    }
+    
+    public AbstractType<V> getValueType()
+    {
+        return valueType;
+    }
+    
+    public String getNameString()
+    {
+        return nameString;
+    }
+    
+    public String getValueString()
+    {
+        return valueString;
+    }
 }

Modified: 
cassandra/trunk/drivers/java/test/org/apache/cassandra/cql/JdbcDriverTest.java
URL: 
http://svn.apache.org/viewvc/cassandra/trunk/drivers/java/test/org/apache/cassandra/cql/JdbcDriverTest.java?rev=1082524&r1=1082523&r2=1082524&view=diff
==============================================================================
--- 
cassandra/trunk/drivers/java/test/org/apache/cassandra/cql/JdbcDriverTest.java 
(original)
+++ 
cassandra/trunk/drivers/java/test/org/apache/cassandra/cql/JdbcDriverTest.java 
Thu Mar 17 15:13:33 2011
@@ -29,11 +29,17 @@ import java.sql.Connection;
 import java.sql.DriverManager;
 import java.sql.PreparedStatement;
 import java.sql.ResultSet;
+import java.sql.ResultSetMetaData;
 import java.sql.SQLException;
 import java.sql.Statement;
+import java.sql.Types;
 import java.util.Arrays;
 
-import org.apache.cassandra.cql.jdbc.RowMetaData;
+import org.apache.cassandra.db.marshal.AsciiType;
+import org.apache.cassandra.db.marshal.BytesType;
+import org.apache.cassandra.db.marshal.IntegerType;
+import org.apache.cassandra.db.marshal.LongType;
+import org.apache.cassandra.db.marshal.UTF8Type;
 import org.apache.cassandra.utils.FBUtilities;
 import org.junit.AfterClass;
 import org.junit.BeforeClass;
@@ -71,6 +77,20 @@ public class JdbcDriverTest extends Embe
             executeNoResults(con, q);
     }
     
+    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
+    {
+        assert colClass.equals(md.getColumnClassName(col)); // full class name 
of type<T>
+        assert table.equals(md.getTableName(col));
+        assert schema.equals(md.getSchemaName(col));
+        assert label.equals(md.getColumnLabel(col)) : "expected " + label + " 
got " + md.getColumnLabel(col);
+        assert label.equals(md.getColumnName(col));
+        assert type == md.getColumnType(col);
+        assert typeName.equals(md.getColumnTypeName(col)) : "expected " + 
typeName + " got " + md.getColumnTypeName(col); // simple name of abstract type.
+        assert md.isSigned(col) == signed;
+        assert md.isCaseSensitive(col) == caseSensitive;
+    }
+    
     @Test 
     public void testIntegerMetadata() throws SQLException
     {
@@ -80,12 +100,11 @@ public class JdbcDriverTest extends Embe
         assert rs.next();
         assert rs.getInt("1") == 111;
         assert rs.getInt("2") == 222;
-        RowMetaData<BigInteger, BigInteger> rd = rs.unwrap(RowMetaData.class);
-        assert rd.getColumnCount() == 2;
-        assert rd.getColumnName(0).equals(new BigInteger("1"));
-        assert rd.getColumnValue(0).equals(new BigInteger("111"));
-        assert rd.getColumnName(1).equals(new BigInteger("2"));
-        assert rd.getColumnValue(1).equals(new BigInteger("222"));
+        
+        ResultSetMetaData md = rs.getMetaData();
+        assert md.getColumnCount() == 2;
+        expectedMetaData(md, 0, BigInteger.class.getName(), "JdbcInteger", 
"Keyspace1", "1", Types.BIGINT, IntegerType.class.getSimpleName(), true, false);
+        expectedMetaData(md, 1, BigInteger.class.getName(), "JdbcInteger", 
"Keyspace1", "2", Types.BIGINT, IntegerType.class.getSimpleName(), true, false);
     }
     
     @Test
@@ -97,16 +116,11 @@ public class JdbcDriverTest extends Embe
         assert rs.next();
         assert rs.getLong("1") == 111;
         assert rs.getLong("2") == 222;
-        RowMetaData<Long, Long> rd = rs.unwrap(RowMetaData.class);
-        assert rd.getColumnCount() == 2;
-        assert rd.getColumnName(0).equals(new Long("1"));
-        assert rd.getColumnValue(0).equals(new Long("111"));
-        assert rd.getColumnName(1).equals(new Long("2"));
-        assert rd.getColumnValue(1).equals(new Long("222"));
-        assert rd.getColumnName(0) == 1L;
-        assert rd.getColumnValue(0) == 111L;
-        assert rd.getColumnName(1) == 2L;
-        assert rd.getColumnValue(1) == 222L;
+        
+        ResultSetMetaData md = rs.getMetaData();
+        assert md.getColumnCount() == 2;
+        expectedMetaData(md, 0, Long.class.getName(), "JdbcLong", "Keyspace1", 
"1", Types.BIGINT, LongType.class.getSimpleName(), true, false);
+        expectedMetaData(md, 1, Long.class.getName(), "JdbcLong", "Keyspace1", 
"2", Types.BIGINT, LongType.class.getSimpleName(), true, false);
     }
     
     @Test
@@ -122,13 +136,16 @@ public class JdbcDriverTest extends Embe
             assert rs.next();
             assert rs.getString("a").equals("aa");
             assert rs.getString("b").equals("bb");
-            RowMetaData<String, String> rd = rs.unwrap(RowMetaData.class);
-            assert rd.getColumnCount() == 2;
-            assert rd.getColumnName(0).equals("a");
-            assert rd.getColumnValue(0).equals("aa");
-            assert rd.getColumnName(1).equals("b");
-            assert rd.getColumnValue(1).equals("bb");
         }
+        
+        ResultSetMetaData md = rs0.getMetaData();
+        assert md.getColumnCount() == 2;
+        expectedMetaData(md, 0, String.class.getName(), "JdbcAscii", 
"Keyspace1", "a", Types.VARCHAR, AsciiType.class.getSimpleName(), false, true);
+        expectedMetaData(md, 1, String.class.getName(), "JdbcAscii", 
"Keyspace1", "b", Types.VARCHAR, AsciiType.class.getSimpleName(), false, true);
+        md = rs1.getMetaData();
+        assert md.getColumnCount() == 2;
+        expectedMetaData(md, 0, String.class.getName(), "JdbcUtf8", 
"Keyspace1", "a", Types.VARCHAR, UTF8Type.class.getSimpleName(), false, true);
+        expectedMetaData(md, 1, String.class.getName(), "JdbcUtf8", 
"Keyspace1", "b", Types.VARCHAR, UTF8Type.class.getSimpleName(), false, true);
     }
     
     @Test
@@ -154,11 +171,10 @@ public class JdbcDriverTest extends Embe
         assert Arrays.equals(bb, rs.getBytes(1));
         assert Arrays.equals(aa, rs.getBytes(FBUtilities.bytesToHex(a)));
         assert Arrays.equals(bb, rs.getBytes(FBUtilities.bytesToHex(b)));
-        RowMetaData<ByteBuffer, ByteBuffer> rd = rs.unwrap(RowMetaData.class);
-        assert rd.getColumnName(0).equals(ByteBuffer.wrap(a));
-        assert rd.getColumnName(1).equals(ByteBuffer.wrap(b));
-        assert rd.getColumnValue(0).equals(ByteBuffer.wrap(aa));
-        assert rd.getColumnValue(1).equals(ByteBuffer.wrap(bb));
+        ResultSetMetaData md = rs.getMetaData();
+        assert md.getColumnCount() == 2;
+        expectedMetaData(md, 0, ByteBuffer.class.getName(), "JdbcBytes", 
"Keyspace1", FBUtilities.bytesToHex(a), Types.BINARY, 
BytesType.class.getSimpleName(), false, false);
+        expectedMetaData(md, 1, ByteBuffer.class.getName(), "JdbcBytes", 
"Keyspace1", FBUtilities.bytesToHex(b), Types.BINARY, 
BytesType.class.getSimpleName(), false, false);
     }
     
     /** Method to test statement. */

Modified: 
cassandra/trunk/src/java/org/apache/cassandra/db/marshal/AbstractCommutativeType.java
URL: 
http://svn.apache.org/viewvc/cassandra/trunk/src/java/org/apache/cassandra/db/marshal/AbstractCommutativeType.java?rev=1082524&r1=1082523&r2=1082524&view=diff
==============================================================================
--- 
cassandra/trunk/src/java/org/apache/cassandra/db/marshal/AbstractCommutativeType.java
 (original)
+++ 
cassandra/trunk/src/java/org/apache/cassandra/db/marshal/AbstractCommutativeType.java
 Thu Mar 17 15:13:33 2011
@@ -41,4 +41,9 @@ public abstract class AbstractCommutativ
      * create commutative column
      */
     public abstract Column createColumn(ByteBuffer name, ByteBuffer value, 
long timestamp);
+
+    public Class<Long> getType()
+    {
+        return Long.class;
+    }
 }

Modified: 
cassandra/trunk/src/java/org/apache/cassandra/db/marshal/AbstractType.java
URL: 
http://svn.apache.org/viewvc/cassandra/trunk/src/java/org/apache/cassandra/db/marshal/AbstractType.java?rev=1082524&r1=1082523&r2=1082524&view=diff
==============================================================================
--- cassandra/trunk/src/java/org/apache/cassandra/db/marshal/AbstractType.java 
(original)
+++ cassandra/trunk/src/java/org/apache/cassandra/db/marshal/AbstractType.java 
Thu Mar 17 15:13:33 2011
@@ -139,4 +139,7 @@ public abstract class AbstractType<T> im
     {
         return false;
     }
+    
+    /** returns the class this AbstractType represents. */
+    public abstract Class<T> getType();
 }

Modified: 
cassandra/trunk/src/java/org/apache/cassandra/db/marshal/AsciiType.java
URL: 
http://svn.apache.org/viewvc/cassandra/trunk/src/java/org/apache/cassandra/db/marshal/AsciiType.java?rev=1082524&r1=1082523&r2=1082524&view=diff
==============================================================================
--- cassandra/trunk/src/java/org/apache/cassandra/db/marshal/AsciiType.java 
(original)
+++ cassandra/trunk/src/java/org/apache/cassandra/db/marshal/AsciiType.java Thu 
Mar 17 15:13:33 2011
@@ -72,4 +72,9 @@ public class AsciiType extends AbstractT
                 throw new MarshalException("Invalid byte for ascii: " + 
Byte.toString(b));
         }
     }
+
+    public Class<String> getType()
+    {
+        return String.class;
+    }
 }

Modified: 
cassandra/trunk/src/java/org/apache/cassandra/db/marshal/BytesType.java
URL: 
http://svn.apache.org/viewvc/cassandra/trunk/src/java/org/apache/cassandra/db/marshal/BytesType.java?rev=1082524&r1=1082523&r2=1082524&view=diff
==============================================================================
--- cassandra/trunk/src/java/org/apache/cassandra/db/marshal/BytesType.java 
(original)
+++ cassandra/trunk/src/java/org/apache/cassandra/db/marshal/BytesType.java Thu 
Mar 17 15:13:33 2011
@@ -40,9 +40,7 @@ public class BytesType extends AbstractT
     public int compare(ByteBuffer o1, ByteBuffer o2)
     {
         return BytesType.bytesCompare(o1, o2);
- 
     }
-
     
     public static int bytesCompare(ByteBuffer o1, ByteBuffer o2)
     {
@@ -75,4 +73,9 @@ public class BytesType extends AbstractT
     {
         // all bytes are legal.
     }
+
+    public Class<ByteBuffer> getType()
+    {
+        return ByteBuffer.class;
+    }
 }

Modified: 
cassandra/trunk/src/java/org/apache/cassandra/db/marshal/IntegerType.java
URL: 
http://svn.apache.org/viewvc/cassandra/trunk/src/java/org/apache/cassandra/db/marshal/IntegerType.java?rev=1082524&r1=1082523&r2=1082524&view=diff
==============================================================================
--- cassandra/trunk/src/java/org/apache/cassandra/db/marshal/IntegerType.java 
(original)
+++ cassandra/trunk/src/java/org/apache/cassandra/db/marshal/IntegerType.java 
Thu Mar 17 15:13:33 2011
@@ -150,4 +150,9 @@ public final class IntegerType extends A
     {
         // no invalid integers.
     }
+
+    public Class<BigInteger> getType()
+    {
+        return BigInteger.class;
+    }
 }

Modified: 
cassandra/trunk/src/java/org/apache/cassandra/db/marshal/LexicalUUIDType.java
URL: 
http://svn.apache.org/viewvc/cassandra/trunk/src/java/org/apache/cassandra/db/marshal/LexicalUUIDType.java?rev=1082524&r1=1082523&r2=1082524&view=diff
==============================================================================
--- 
cassandra/trunk/src/java/org/apache/cassandra/db/marshal/LexicalUUIDType.java 
(original)
+++ 
cassandra/trunk/src/java/org/apache/cassandra/db/marshal/LexicalUUIDType.java 
Thu Mar 17 15:13:33 2011
@@ -82,4 +82,9 @@ public class LexicalUUIDType extends Abs
             throw new MarshalException(String.format("LexicalUUID should be 16 
or 0 bytes (%d)", bytes.remaining()));
         // not sure what the version should be for this.
     }
+
+    public Class<UUID> getType()
+    {
+        return UUID.class;
+    }
 }

Modified: 
cassandra/trunk/src/java/org/apache/cassandra/db/marshal/LocalByPartionerType.java
URL: 
http://svn.apache.org/viewvc/cassandra/trunk/src/java/org/apache/cassandra/db/marshal/LocalByPartionerType.java?rev=1082524&r1=1082523&r2=1082524&view=diff
==============================================================================
--- 
cassandra/trunk/src/java/org/apache/cassandra/db/marshal/LocalByPartionerType.java
 (original)
+++ 
cassandra/trunk/src/java/org/apache/cassandra/db/marshal/LocalByPartionerType.java
 Thu Mar 17 15:13:33 2011
@@ -62,4 +62,9 @@ public class LocalByPartionerType<T exte
     {
         throw new IllegalStateException("You shouldn't be validating this.");
     }
+
+    public Class<ByteBuffer> getType()
+    {
+        return ByteBuffer.class;
+    }
 }

Modified: cassandra/trunk/src/java/org/apache/cassandra/db/marshal/LongType.java
URL: 
http://svn.apache.org/viewvc/cassandra/trunk/src/java/org/apache/cassandra/db/marshal/LongType.java?rev=1082524&r1=1082523&r2=1082524&view=diff
==============================================================================
--- cassandra/trunk/src/java/org/apache/cassandra/db/marshal/LongType.java 
(original)
+++ cassandra/trunk/src/java/org/apache/cassandra/db/marshal/LongType.java Thu 
Mar 17 15:13:33 2011
@@ -91,4 +91,9 @@ public class LongType extends AbstractTy
         if (bytes.remaining() != 8 && bytes.remaining() != 0)
             throw new MarshalException(String.format("Expected 8 or 0 byte 
long (%d)", bytes.remaining()));
     }
+
+    public Class<Long> getType()
+    {
+        return Long.class;
+    }
 }

Modified: 
cassandra/trunk/src/java/org/apache/cassandra/db/marshal/TimeUUIDType.java
URL: 
http://svn.apache.org/viewvc/cassandra/trunk/src/java/org/apache/cassandra/db/marshal/TimeUUIDType.java?rev=1082524&r1=1082523&r2=1082524&view=diff
==============================================================================
--- cassandra/trunk/src/java/org/apache/cassandra/db/marshal/TimeUUIDType.java 
(original)
+++ cassandra/trunk/src/java/org/apache/cassandra/db/marshal/TimeUUIDType.java 
Thu Mar 17 15:13:33 2011
@@ -185,4 +185,9 @@ public class TimeUUIDType extends Abstra
                 throw new MarshalException("Invalid version for TimeUUID 
type.");
         }
     }
+
+    public Class<UUID> getType()
+    {
+        return UUID.class;
+    }
 }

Modified: cassandra/trunk/src/java/org/apache/cassandra/db/marshal/UTF8Type.java
URL: 
http://svn.apache.org/viewvc/cassandra/trunk/src/java/org/apache/cassandra/db/marshal/UTF8Type.java?rev=1082524&r1=1082523&r2=1082524&view=diff
==============================================================================
--- cassandra/trunk/src/java/org/apache/cassandra/db/marshal/UTF8Type.java 
(original)
+++ cassandra/trunk/src/java/org/apache/cassandra/db/marshal/UTF8Type.java Thu 
Mar 17 15:13:33 2011
@@ -182,4 +182,9 @@ public class UTF8Type extends AbstractTy
             return state == State.START;
         }
     }
+
+    public Class<String> getType()
+    {
+        return String.class;
+    }
 }


Reply via email to