5 new revisions:

Revision: 946e3f9ce790
Author:   Rick Shaw <wfs...@gmail.com>
Date:     Sun Nov 18 21:22:15 2012
Log:      Support new CQL3 Thrift calls in CassandraConnection
http://code.google.com/a/apache-extras.org/p/cassandra-jdbc/source/detail?r=946e3f9ce790

Revision: 4bb83b3eefa2
Author:   Rick Shaw <wfs...@gmail.com>
Date:     Sun Nov 18 21:30:11 2012
Log: Fix Issue #49, Better handling of Null in PreparedStatement setters...
http://code.google.com/a/apache-extras.org/p/cassandra-jdbc/source/detail?r=4bb83b3eefa2

Revision: c217c201eca0
Author:   Rick Shaw <wfs...@gmail.com>
Date:     Sun Nov 18 21:41:37 2012
Log:      Completed Enhancement Issue #51, Support for Collections
http://code.google.com/a/apache-extras.org/p/cassandra-jdbc/source/detail?r=c217c201eca0

Revision: 052ad46f5f4b
Author:   Palmer Cox <palmer...@gmail.com>
Date:     Sun Nov 18 21:45:28 2012
Log:      Fixed Issue #50, JDBC Suite does not compile under JDK 7
http://code.google.com/a/apache-extras.org/p/cassandra-jdbc/source/detail?r=052ad46f5f4b

Revision: e548427cee85
Author:   Rick Shaw <wfs...@gmail.com>
Date:     Sun Nov 18 21:48:14 2012
Log:      Update project POM to use C* Beta2
http://code.google.com/a/apache-extras.org/p/cassandra-jdbc/source/detail?r=e548427cee85

==============================================================================
Revision: 946e3f9ce790
Author:   Rick Shaw <wfs...@gmail.com>
Date:     Sun Nov 18 21:22:15 2012
Log:      Support new CQL3 Thrift calls in CassandraConnection
http://code.google.com/a/apache-extras.org/p/cassandra-jdbc/source/detail?r=946e3f9ce790

Modified:
 /src/main/java/org/apache/cassandra/cql/jdbc/CassandraConnection.java

=======================================
--- /src/main/java/org/apache/cassandra/cql/jdbc/CassandraConnection.java Sun Oct 14 10:02:03 2012 +++ /src/main/java/org/apache/cassandra/cql/jdbc/CassandraConnection.java Sun Nov 18 21:22:15 2012
@@ -56,7 +56,7 @@
     public static final int DB_MAJOR_VERSION = 1;
     public static final int DB_MINOR_VERSION = 2;
     public static final String DB_PRODUCT_NAME = "Cassandra";
-    public static final String DEFAULT_CQL_VERSION = "2.0.0";
+    public static final String DEFAULT_CQL_VERSION = "3.0.0";

     public static Compression defaultCompression = Compression.GZIP;

@@ -444,7 +444,8 @@

         try
         {
- return client.execute_cql_query(Utils.compressQuery(queryStr, compression), compression); + if (majorCqlVersion==3) return client.execute_cql3_query(Utils.compressQuery(queryStr, compression), compression, ConsistencyLevel.ONE); + else return client.execute_cql_query(Utils.compressQuery(queryStr, compression), compression);
         }
         catch (TException error)
         {
@@ -476,7 +477,8 @@
     {
         try
         {
-            return client.execute_prepared_cql_query(itemId, values);
+ if (majorCqlVersion==3) return client.execute_prepared_cql3_query(itemId, values, ConsistencyLevel.ONE); + else return client.execute_prepared_cql_query(itemId, values);
         }
         catch (TException error)
         {
@@ -490,7 +492,8 @@
     {
         try
         {
- return client.prepare_cql_query(Utils.compressQuery(queryStr, compression), compression); + if (majorCqlVersion==3) return client.prepare_cql3_query(Utils.compressQuery(queryStr, compression), compression); + else return client.prepare_cql_query(Utils.compressQuery(queryStr, compression), compression);
         }
         catch (TException error)
         {

==============================================================================
Revision: 4bb83b3eefa2
Author:   Rick Shaw <wfs...@gmail.com>
Date:     Sun Nov 18 21:30:11 2012
Log: Fix Issue #49, Better handling of Null in PreparedStatement setters
o Handle nulls in value argument of setters of object types like String
  as if it was a setNull by inserting an empty ByteBuffer
http://code.google.com/a/apache-extras.org/p/cassandra-jdbc/source/detail?r=4bb83b3eefa2

Modified:
/src/main/java/org/apache/cassandra/cql/jdbc/CassandraPreparedStatement.java

=======================================
--- /src/main/java/org/apache/cassandra/cql/jdbc/CassandraPreparedStatement.java Sun Oct 14 10:02:03 2012 +++ /src/main/java/org/apache/cassandra/cql/jdbc/CassandraPreparedStatement.java Sun Nov 18 21:30:11 2012
@@ -1,23 +1,23 @@
 /*
  *
  * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
+ * or more contributor license agreements. See the NOTICE file
  * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
+ * regarding copyright ownership. The ASF licenses this file
  * to you under the Apache License, Version 2.0 (the
  * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
+ * with the License. You may obtain a copy of the License at
  *
- *   http://www.apache.org/licenses/LICENSE-2.0
+ * http://www.apache.org/licenses/LICENSE-2.0
  *
  * Unless required by applicable law or agreed to in writing,
  * software distributed under the License is distributed on an
  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
+ * KIND, either express or implied. See the License for the
  * specific language governing permissions and limitations
  * under the License.
- *
  */
+
 package org.apache.cassandra.cql.jdbc;

 import static org.apache.cassandra.cql.jdbc.Utils.NO_RESULTSET;
@@ -65,25 +65,25 @@
class CassandraPreparedStatement extends CassandraStatement implements PreparedStatement
 {
private static final Logger LOG = LoggerFactory.getLogger(CassandraPreparedStatement.class);
-
+
/** the key token passed back from server-side to identify the prepared statement */
     private int itemId;
-
- /** the count of bound variable markers (?) encountered in the parse o the CQL server-side */
+
+ /** the count of bound variable markers (?) encountered in the parse o the CQL server-side */
     private int count;
-
-    /** a Map of the current bound values encountered in setXXX methods */
- private Map<Integer,ByteBuffer> bindValues = new LinkedHashMap<Integer,ByteBuffer>();

-
+    /** a Map of the current bound values encountered in setXXX methods */
+ private Map<Integer, ByteBuffer> bindValues = new LinkedHashMap<Integer, ByteBuffer>();
+
+
CassandraPreparedStatement(CassandraConnection con, String cql) throws SQLException
     {
         super(con, cql);
-        if (LOG.isTraceEnabled()) LOG.trace("CQL: "+ this.cql);
+        if (LOG.isTraceEnabled()) LOG.trace("CQL: " + this.cql);
         try
         {
             CqlPreparedResult result = con.prepare(cql);
-
+
             itemId = result.itemId;
             count = result.count;
         }
@@ -91,52 +91,54 @@
         {
             throw new SQLSyntaxErrorException(e);
         }
-         catch (TException e)
+        catch (TException e)
         {
             throw new SQLNonTransientConnectionException(e);
         }
     }
-
+
     String getCql()
     {
-       return cql;
+        return cql;
     }

     private final void checkIndex(int index) throws SQLException
     {
- if (index > count ) throw new SQLRecoverableException(String.format("the column index : %d is greater than the count of bound variable markers in the CQL: %d", index,count)); - if (index < 1 ) throw new SQLRecoverableException(String.format("the column index must be a positive number : %d", index)); + if (index > count) throw new SQLRecoverableException(String.format("the column index : %d is greater than the count of bound variable markers in the CQL: %d",
+            index,
+            count));
+ if (index < 1) throw new SQLRecoverableException(String.format("the column index must be a positive number : %d", index));
     }
-
+
     private List<ByteBuffer> getBindValues() throws SQLException
     {
         List<ByteBuffer> values = new ArrayList<ByteBuffer>();
-//        System.out.println("bindValues.size() = "+bindValues.size());
-//        System.out.println("count             = "+count);
-        if (bindValues.size() != count )
- throw new SQLRecoverableException(String.format("the number of bound variables: %d must match the count of bound variable markers in the CQL: %d", bindValues.size(),count));
+        if (bindValues.size() != count) throw new SQLRecoverableException(
+ String.format("the number of bound variables: %d must match the count of bound variable markers in the CQL: %d",
+            bindValues.size(),
+            count));

-        for (int i = 1; i <= count ; i++)
+        for (int i = 1; i <= count; i++)
         {
             ByteBuffer value = bindValues.get(i);
- if (value==null) throw new SQLRecoverableException(String.format("the bound value for index: %d was not set", i));
-           values.add(value);
+ if (value == null) throw new SQLRecoverableException(String.format("the bound value for index: %d was not set", i));
+            values.add(value);
         }
         return values;
     }

-
+
     public void close()
     {
         connection.removeStatement(this);
-
+
         connection = null;
     }
-
+
     private void doExecute() throws SQLException
     {
-        if (LOG.isTraceEnabled()) LOG.trace("CQL: "+ cql);
-       try
+        if (LOG.isTraceEnabled()) LOG.trace("CQL: " + cql);
+        try
         {
             resetResults();
             CqlResult result = connection.execute(itemId, getBindValues());
@@ -156,7 +158,7 @@
         }
         catch (InvalidRequestException e)
         {
-            throw new SQLSyntaxErrorException(e.getWhy()+"\n'"+cql+"'",e);
+ throw new SQLSyntaxErrorException(e.getWhy() + "\n'" + cql + "'", e);
         }
         catch (UnavailableException e)
         {
@@ -175,7 +177,7 @@
             throw new SQLNonTransientConnectionException(e);
         }
     }
-
+
     public void addBatch() throws SQLException
     {
         throw new SQLFeatureNotSupportedException(NOT_SUPPORTED);
@@ -212,7 +214,7 @@
         doExecute();
if (currentResultSet != null) throw new SQLNonTransientException(NO_UPDATE_COUNT);
         return updateCount;
-     }
+    }


     public ResultSetMetaData getMetaData() throws SQLException
@@ -231,7 +233,7 @@
     {
         checkNotClosed();
         checkIndex(parameterIndex);
- bindValues.put(parameterIndex, JdbcDecimal.instance.decompose(decimal)); + bindValues.put(parameterIndex, decimal == null ? ByteBufferUtil.EMPTY_BYTE_BUFFER : JdbcDecimal.instance.decompose(decimal));
     }


@@ -255,7 +257,7 @@
     {
         checkNotClosed();
         checkIndex(parameterIndex);
-        bindValues.put(parameterIndex, ByteBuffer.wrap(bytes));
+ bindValues.put(parameterIndex, bytes == null ? ByteBufferUtil.EMPTY_BYTE_BUFFER : ByteBuffer.wrap(bytes));
     }


@@ -264,14 +266,14 @@
         checkNotClosed();
         checkIndex(parameterIndex);
// date type data is handled as an 8 byte Long value of milliseconds since the epoch (handled in decompose() )
-        bindValues.put(parameterIndex, JdbcDate.instance.decompose(value));
+ bindValues.put(parameterIndex, value == null ? ByteBufferUtil.EMPTY_BYTE_BUFFER : JdbcDate.instance.decompose(value));
     }


public void setDate(int parameterIndex, Date date, Calendar cal) throws SQLException
     {
// silently ignore the calendar argument it is not useful for the Cassandra implementation
-        setDate(parameterIndex,date);
+        setDate(parameterIndex, date);
     }


@@ -310,7 +312,7 @@
public void setNString(int parameterIndex, String value) throws SQLException
     {
         // treat like a String
-        setString(parameterIndex,value);
+        setString(parameterIndex, value);
     }


@@ -326,30 +328,30 @@
public void setNull(int parameterIndex, int sqlType, String typeName) throws SQLException
     {
// silently ignore type and type name for cassandra... just store an empty BB
-        setNull(parameterIndex,sqlType);
+        setNull(parameterIndex, sqlType);
     }


public void setObject(int parameterIndex, Object object) throws SQLException
     {
         // For now all objects are forced to String type
-        setObject(parameterIndex,object,Types.VARCHAR,0);
+        setObject(parameterIndex, object, Types.VARCHAR, 0);
     }
-
+
public void setObject(int parameterIndex, Object object, int targetSqlType) throws SQLException
     {
-        setObject(parameterIndex,object,targetSqlType,0);
+        setObject(parameterIndex, object, targetSqlType, 0);
     }

public final void setObject(int parameterIndex, Object object, int targetSqlType, int scaleOrLength) throws SQLException
     {
         checkNotClosed();
         checkIndex(parameterIndex);
-
+
ByteBuffer variable = HandleObjects.makeBytes(object, targetSqlType, scaleOrLength);
-
- if (variable==null) throw new SQLNonTransientException("Problem mapping object to JDBC Type");
-
+
+ if (variable == null) throw new SQLNonTransientException("Problem mapping object to JDBC Type");
+
         bindValues.put(parameterIndex, variable);
     }

@@ -373,7 +375,7 @@
     {
         checkNotClosed();
         checkIndex(parameterIndex);
-        bindValues.put(parameterIndex, ByteBufferUtil.bytes(value));
+ bindValues.put(parameterIndex, value == null ? ByteBufferUtil.EMPTY_BYTE_BUFFER : ByteBufferUtil.bytes(value));
     }


@@ -382,14 +384,15 @@
         checkNotClosed();
         checkIndex(parameterIndex);
// time type data is handled as an 8 byte Long value of milliseconds since the epoch - bindValues.put(parameterIndex, JdbcLong.instance.decompose(Long.valueOf(value.getTime())));
+        bindValues.put(parameterIndex,
+ value == null ? ByteBufferUtil.EMPTY_BYTE_BUFFER : JdbcLong.instance.decompose(Long.valueOf(value.getTime())));
     }


public void setTime(int parameterIndex, Time value, Calendar cal) throws SQLException
     {
// silently ignore the calendar argument it is not useful for the Cassandra implementation
-        setTime(parameterIndex,value);
+        setTime(parameterIndex, value);
     }


@@ -398,14 +401,15 @@
         checkNotClosed();
         checkIndex(parameterIndex);
// timestamp type data is handled as an 8 byte Long value of milliseconds since the epoch. Nanos are not supported and are ignored - bindValues.put(parameterIndex, JdbcLong.instance.decompose(Long.valueOf(value.getTime())));
+        bindValues.put(parameterIndex,
+ value == null ? ByteBufferUtil.EMPTY_BYTE_BUFFER : JdbcLong.instance.decompose(Long.valueOf(value.getTime())));
     }


public void setTimestamp(int parameterIndex, Timestamp value, Calendar cal) throws SQLException
     {
// silently ignore the calendar argument it is not useful for the Cassandra implementation
-        setTimestamp(parameterIndex,value);
+        setTimestamp(parameterIndex, value);
     }


@@ -415,6 +419,6 @@
         checkIndex(parameterIndex);
         // URl type data is handled as an string
         String url = value.toString();
-        bindValues.put(parameterIndex, ByteBufferUtil.bytes(url));
+ bindValues.put(parameterIndex, value == null ? ByteBufferUtil.EMPTY_BYTE_BUFFER : ByteBufferUtil.bytes(url));
     }
 }

==============================================================================
Revision: c217c201eca0
Author:   Rick Shaw <wfs...@gmail.com>
Date:     Sun Nov 18 21:41:37 2012
Log:      Completed Enhancement Issue #51, Support for Collections
http://code.google.com/a/apache-extras.org/p/cassandra-jdbc/source/detail?r=c217c201eca0

Modified:
 /src/main/java/org/apache/cassandra/cql/jdbc/CassandraResultSet.java
 /src/main/java/org/apache/cassandra/cql/jdbc/HandleObjects.java
 /src/test/java/org/apache/cassandra/cql/jdbc/CollectionsTest.java

=======================================
--- /src/main/java/org/apache/cassandra/cql/jdbc/CassandraResultSet.java Sun Nov 4 19:51:06 2012 +++ /src/main/java/org/apache/cassandra/cql/jdbc/CassandraResultSet.java Sun Nov 18 21:41:37 2012
@@ -1084,7 +1084,8 @@
         }

TypedColumn tc = new TypedColumn(column, comparator, validator, keyType, type);
-        logger.debug("tc = "+tc);
+
+        if (logger.isTraceEnabled()) logger.trace("tc = "+tc);

         return tc;
     }
=======================================
--- /src/main/java/org/apache/cassandra/cql/jdbc/HandleObjects.java Thu Feb 2 07:47:12 2012 +++ /src/main/java/org/apache/cassandra/cql/jdbc/HandleObjects.java Sun Nov 18 21:41:37 2012
@@ -28,16 +28,25 @@
 import java.io.ObjectOutputStream;
 import java.math.BigDecimal;
 import java.math.BigInteger;
+import java.net.Inet4Address;
+import java.net.Inet6Address;
 import java.net.URL;
 import java.nio.ByteBuffer;
 import java.sql.Date;
 import java.sql.RowId;
 import java.sql.SQLException;
 import java.sql.SQLNonTransientException;
+import java.sql.SQLRecoverableException;
 import java.sql.Time;
 import java.sql.Timestamp;
 import java.sql.Types;
 import java.text.ParseException;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.UUID;

 import org.apache.cassandra.utils.ByteBufferUtil;
 import org.apache.commons.lang.time.DateUtils;
@@ -51,6 +60,33 @@
private static final String BAD_MAPPING = "encountered object of class: %s, but only '%s' is supported to map to %s";

private static final String STR_BOOL_NUMERIC = "String, Boolean, or a Numeric class";
+
+ private final static Map<Class<?>, AbstractJdbcType<?>> map = new HashMap<Class<?>, AbstractJdbcType<?>>();
+
+    static
+    {
+        map.put(Boolean.class, JdbcBoolean.instance);
+        map.put(Byte[].class, JdbcBytes.instance);
+        map.put(java.util.Date.class, JdbcDate.instance);
+        map.put(BigDecimal.class, JdbcDecimal.instance);
+        map.put(Double.class, JdbcDouble.instance);
+        map.put(Float.class, JdbcFloat.instance);
+        map.put(Integer.class, JdbcInt32.instance);
+        map.put(Inet4Address.class, JdbcInetAddress.instance);
+        map.put(Inet6Address.class, JdbcInetAddress.instance);
+        map.put(BigInteger.class, JdbcInteger.instance);
+        map.put(Long.class, JdbcLong.instance);
+        map.put(String.class, JdbcUTF8.instance);
+        map.put(UUID.class, JdbcUUID.instance);
+    }
+
+ private static AbstractJdbcType<?> getType(Class<?> elementClass) throws SQLException
+    {
+        AbstractJdbcType<?> type = map.get(elementClass);
+ if (type==null) throw new SQLRecoverableException(String.format("unsupported Collection elemement type: '%s' for CQL", elementClass));
+        return type;
+    }
+

     private static Long fromString(String source) throws SQLException
     {
@@ -210,12 +246,85 @@
         else return null; // this should not happen
     }

+
+ private static final Class<?> getCollectionElementType(Object maybeCollection)
+    {
+        Collection trial = (Collection) maybeCollection;
+        if (trial.isEmpty()) return null;
+        else return trial.iterator().next().getClass();
+    }
+
+    private static final Class<?> getKeyElementType(Object maybeMap)
+    {
+        return getCollectionElementType(((Map) maybeMap).keySet());
+    }
+
+    private static final Class<?> getValueElementType(Object maybeMap)
+    {
+        return getCollectionElementType(((Map) maybeMap).values());
+    }
+
+ private static final <X> ByteBuffer makeByteBuffer4List(AbstractJdbcType<?> instanceType, List<X> value)
+    {
+ return ListMaker.getInstance(instanceType).decompose(value.getClass().cast(value));
+    }
+
+ private static final <X> ByteBuffer makeByteBuffer4Set(AbstractJdbcType<?> instanceType, Set<X> value)
+    {
+ return SetMaker.getInstance(instanceType).decompose(value.getClass().cast(value));
+    }
+
+ private static final <K,V> ByteBuffer makeByteBuffer4Map(AbstractJdbcType<?> keyInstanceType, AbstractJdbcType<?> valueInstanceType, Map<K,V> value)
+    {
+ return MapMaker.getInstance(keyInstanceType,valueInstanceType).decompose(value.getClass().cast(value));
+    }
+
+ private static final <X> ByteBuffer handleAsList(Class<? extends Object> objectClass, Object object) throws SQLException
+    {
+ if (!List.class.isAssignableFrom(objectClass)) return ByteBuffer.wrap(new byte[0]);
+
+        Class<?> elementClass = getCollectionElementType(object);
+
+        AbstractJdbcType<?> instanceType = getType(elementClass);
+
+ ByteBuffer bb = makeByteBuffer4List(instanceType, (List<X>) object.getClass().cast(object));
+
+        return bb;
+    }
+
+ private static final <X> ByteBuffer handleAsSet(Class<? extends Object> objectClass, Object object) throws SQLException
+    {
+ if (!Set.class.isAssignableFrom(objectClass)) return ByteBuffer.wrap(new byte[0]);
+
+        Class<?> elementClass = getCollectionElementType(object);
+
+        AbstractJdbcType<?> instanceType = getType(elementClass);
+
+ ByteBuffer bb = makeByteBuffer4Set(instanceType, (Set<X>) object.getClass().cast(object));
+
+        return bb;
+    }
+
+ private static final <K,V> ByteBuffer handleAsMap(Class<? extends Object> objectClass, Object object) throws SQLException
+    {
+ if (!Map.class.isAssignableFrom(objectClass)) return ByteBuffer.wrap(new byte[0]);

+        Class<?> keyElementClass = getKeyElementType(object);
+        Class<?> valueElementClass = getValueElementType(object);
+
+        AbstractJdbcType<?> keyInstanceType = getType(keyElementClass);
+        AbstractJdbcType<?> valueInstanceType = getType(valueElementClass);
+
+ ByteBuffer bb = makeByteBuffer4Map(keyInstanceType,valueInstanceType, (Map<K,V>) object.getClass().cast(object));
+
+        return bb;
+    }

- public static final ByteBuffer makeBytes(Object object, int targetSqlType, int scaleOrLength) throws SQLException + public static final ByteBuffer makeBytes(Object object, int baseType, int scaleOrLength) throws SQLException
     {
         Class<? extends Object> objectClass = object.getClass();
-
+ boolean isCollection = (Collection.class.isAssignableFrom(objectClass));
+        int targetSqlType = isCollection ? Types.OTHER : baseType;
         // Type check first
         switch (targetSqlType)
         {
@@ -311,6 +420,14 @@
             case Types.JAVA_OBJECT:
                 break;

+            case Types.OTHER:
+                // Only Collection classes for transformation to OTHER
+                if (!( List.class.isAssignableFrom(object.getClass())
+                    || Set.class.isAssignableFrom(object.getClass())
+                    || Map.class.isAssignableFrom(object.getClass())))
+ throw makeBadMapping(objectClass,STR_BOOL_NUMERIC,"OTHER");
+                break;
+
             case Types.ROWID:
if (objectClass != RowId.class) throw makeBadMapping(objectClass,"a RowId type","ROWID");
                 break;
@@ -383,6 +500,22 @@

             case Types.JAVA_OBJECT:
                 return javaObject(object);
+
+            case Types.OTHER:
+                if ( List.class.isAssignableFrom(objectClass))
+                {
+                  return handleAsList(objectClass, object);
+                }
+                else if ( Set.class.isAssignableFrom(objectClass))
+                {
+                    return handleAsSet(objectClass, object);
+                }
+                else if ( Map.class.isAssignableFrom(objectClass))
+                {
+                    return handleAsMap(objectClass, object);
+                }
+                else return null;
+

             case Types.ROWID:
                 byte[] bytes = ((RowId) object).getBytes();
=======================================
--- /src/test/java/org/apache/cassandra/cql/jdbc/CollectionsTest.java Sun Nov 4 19:51:06 2012 +++ /src/test/java/org/apache/cassandra/cql/jdbc/CollectionsTest.java Sun Nov 18 21:41:37 2012
@@ -23,6 +23,9 @@
 import static org.junit.Assert.*;

 import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.LinkedHashMap;
 import java.util.LinkedHashSet;
 import java.util.List;
 import java.util.Set;
@@ -30,6 +33,7 @@
 import java.sql.PreparedStatement;
 import java.sql.ResultSet;
 import java.sql.Statement;
+import java.sql.Types;
 import java.util.Map;

 import org.apache.cassandra.cql.ConnectionDetails;
@@ -70,7 +74,7 @@

         con = DriverManager.getConnection(URL);

-        LOG.debug("URL         = '{}'", URL);
+        if (LOG.isDebugEnabled()) LOG.debug("URL         = '{}'", URL);

         Statement stmt = con.createStatement();

@@ -88,9 +92,9 @@
         {/* Exception on DROP is OK */}

         // Create KeySpace
- String createKS = String.format("CREATE KEYSPACE %s WITH replication = { 'class' : 'SimpleStrategy', 'replication_factor' : 1 }",KEYSPACE); + String createKS = String.format("CREATE KEYSPACE %s WITH replication = { 'class' : 'SimpleStrategy', 'replication_factor' : 1 };",KEYSPACE); // String createKS = String.format("CREATE KEYSPACE %s WITH strategy_class = SimpleStrategy AND strategy_options:replication_factor = 1;",KEYSPACE);
-        LOG.debug("createKS    = '{}'", createKS);
+ if (LOG.isDebugEnabled()) LOG.debug("createKS = '{}'", createKS);

         stmt = con.createStatement();
         stmt.execute("USE " + SYSTEM);
@@ -100,7 +104,7 @@

         // Create the target Table (CF)
String createTable = "CREATE TABLE testcollection (" + " k int PRIMARY KEY," + " L list<bigint>," + " M map<double, boolean>," + " S set<text>" + ") ;";
-        LOG.debug("createTable = '{}'", createTable);
+ if (LOG.isDebugEnabled()) LOG.debug("createTable = '{}'", createTable);

         stmt.execute(createTable);
         stmt.close();
@@ -109,7 +113,7 @@
         // open it up again to see the new TABLE
URL = String.format("jdbc:cassandra://%s:%d/%s?version=%s", HOST, PORT, KEYSPACE, CQLV3);
         con = DriverManager.getConnection(URL);
-        LOG.debug("URL         = '{}'", URL);
+        if (LOG.isDebugEnabled()) LOG.debug("URL         = '{}'", URL);

         Statement statement = con.createStatement();

@@ -121,7 +125,7 @@
         statement.executeUpdate(update2);


- LOG.debug("Unit Test: 'CollectionsTest' initialization complete.\n\n"); + if (LOG.isDebugEnabled()) LOG.debug("Unit Test: 'CollectionsTest' initialization complete.\n\n");
     }

     /**
@@ -136,7 +140,7 @@
     @Test
     public void testReadList() throws Exception
     {
-        if (LOG.isDebugEnabled()) LOG.debug("Test: 'testReadList'.\n");
+        if (LOG.isDebugEnabled()) LOG.debug("Test: 'testReadList'\n");

         Statement statement = con.createStatement();

@@ -146,7 +150,7 @@
         assertEquals(1, result.getInt("k"));

         Object myObj = result.getObject("l");
-        LOG.debug("l           = '{}'", myObj);
+        if (LOG.isDebugEnabled()) LOG.debug("l           = '{}'\n", myObj);
         List<Long> myList = (List<Long>) myObj;
         assertEquals(3, myList.size());
         assertTrue(12345L == myList.get(2));
@@ -155,14 +159,12 @@
         myList = (List<Long>) extras(result).getList("l");
         statement.close();
         assertTrue(3L == myList.get(1));
-
-        if (LOG.isDebugEnabled()) LOG.debug("\n");
     }

     @Test
     public void testUpdateList() throws Exception
     {
-        if (LOG.isDebugEnabled()) LOG.debug("Test: 'testUpdateList'.\n");
+        if (LOG.isDebugEnabled()) LOG.debug("Test: 'testUpdateList'\n");

         Statement statement = con.createStatement();

@@ -178,7 +180,7 @@
         assertEquals(6, myList.size());
         assertTrue(12345L == myList.get(2));

-        LOG.debug("l           = '{}'", myObj);
+        if (LOG.isDebugEnabled()) LOG.debug("l           = '{}'", myObj);

String update2 = "UPDATE testcollection SET L = [98,99,100] + L WHERE k = 1;";
         statement.executeUpdate(update2);
@@ -188,7 +190,7 @@
         myList = (List<Long>) myObj;
         assertTrue(100L == myList.get(0));

-        LOG.debug("l           = '{}'", myObj);
+        if (LOG.isDebugEnabled()) LOG.debug("l           = '{}'", myObj);

String update3 = "UPDATE testcollection SET L[0] = 2000 WHERE k = 1;";
         statement.executeUpdate(update3);
@@ -197,28 +199,30 @@
         myObj = result.getObject("l");
         myList = (List<Long>) myObj;

-        LOG.debug("l           = '{}'", myObj);
+        if (LOG.isDebugEnabled()) LOG.debug("l           = '{}'", myObj);

// String update4 = "UPDATE testcollection SET L = L + ? WHERE k = 1;";
-//
-//        PreparedStatement prepared = con.prepareStatement(update4);
-//        prepared.setLong(1, 8888L);
-//        prepared.executeUpdate();
-//
-// result = prepared.executeQuery("SELECT * FROM testcollection WHERE k = 1;");
-//        result.next();
-//        myObj = result.getObject("l");
-//        myList = (List<Long>) myObj;
-//
-//        LOG.debug("l           = '{}'", myObj);
+        String update4 = "UPDATE testcollection SET L =  ? WHERE k = 1;";
+
+        PreparedStatement prepared = con.prepareStatement(update4);
+        List<Long> myNewList = new ArrayList<Long>();
+        myNewList.add(8888L);
+        myNewList.add(9999L);
+        prepared.setObject(1, myNewList, Types.OTHER);
+        prepared.execute();

-        if (LOG.isDebugEnabled()) LOG.debug("\n");
+ result = prepared.executeQuery("SELECT * FROM testcollection WHERE k = 1;");
+        result.next();
+        myObj = result.getObject("l");
+        myList = (List<Long>) myObj;
+
+        if (LOG.isDebugEnabled()) LOG.debug("l (prepared)= '{}'\n", myObj);
     }

     @Test
     public void testReadSet() throws Exception
     {
-        if (LOG.isDebugEnabled()) LOG.debug("Test: 'testReadSet'.\n");
+        if (LOG.isDebugEnabled()) LOG.debug("Test: 'testReadSet'\n");

         Statement statement = con.createStatement();

@@ -229,19 +233,17 @@
         assertEquals(1, result.getInt("k"));

         Object myObj = result.getObject("s");
-        LOG.debug("s           = '{}'", myObj);
+        if (LOG.isDebugEnabled()) LOG.debug("s           = '{}'\n", myObj);
         Set<String> mySet = (Set<String>) myObj;
         assertEquals(3, mySet.size());
         assertTrue(mySet.contains("white"));
         assertTrue(myObj instanceof LinkedHashSet);
-
-        if (LOG.isDebugEnabled()) LOG.debug("\n");
     }

     @Test
     public void testUpdateSet() throws Exception
     {
-        if (LOG.isDebugEnabled()) LOG.debug("Test: 'testUpdateSet'.\n");
+        if (LOG.isDebugEnabled()) LOG.debug("Test: 'testUpdateSet'\n");

         Statement statement = con.createStatement();

@@ -258,7 +260,7 @@
         assertEquals(5, mySet.size());
         assertTrue(mySet.contains("white"));

-        LOG.debug("l           = '{}'", myObj);
+        if (LOG.isDebugEnabled()) LOG.debug("s           = '{}'", myObj);

         // remove an item from the set
String update2 = "UPDATE testcollection SET S = S - {'red'} WHERE k = 1;";
@@ -275,9 +277,100 @@
         assertTrue(mySet.contains("white"));
         assertFalse(mySet.contains("red"));

-        LOG.debug("s           = '{}'", myObj);
+        if (LOG.isDebugEnabled()) LOG.debug("s           = '{}'", myObj);
+
+        String update4 = "UPDATE testcollection SET S =  ? WHERE k = 1;";
+
+        PreparedStatement prepared = con.prepareStatement(update4);
+        Set<String> myNewSet = new HashSet<String>();
+        myNewSet.add("black");
+        myNewSet.add("blue");
+        prepared.setObject(1, myNewSet, Types.OTHER);
+        prepared.execute();
+
+ result = prepared.executeQuery("SELECT * FROM testcollection WHERE k = 1;");
+        result.next();
+        myObj = result.getObject("s");
+        mySet = (Set<String>) myObj;
+
+        if (LOG.isDebugEnabled()) LOG.debug("s (prepared)= '{}'\n", myObj);
+    }
+
+    @Test
+    public void testReadMap() throws Exception
+    {
+        if (LOG.isDebugEnabled()) LOG.debug("Test: 'testReadMap'\n");
+
+        Statement statement = con.createStatement();
+
+
+ ResultSet result = statement.executeQuery("SELECT * FROM testcollection WHERE k = 1;");
+        result.next();
+
+        assertEquals(1, result.getInt("k"));
+
+        Object myObj = result.getObject("m");
+        if (LOG.isDebugEnabled()) LOG.debug("m           = '{}'\n", myObj);
+        Map<Double,Boolean> myMap = (Map<Double,Boolean>) myObj;
+        assertEquals(3, myMap.size());
+        assertTrue(myMap.keySet().contains(2.0));
+        assertTrue(myObj instanceof HashMap);
+    }
+
+    @Test
+    public void testUpdateMap() throws Exception
+    {
+        if (LOG.isDebugEnabled()) LOG.debug("Test: 'testUpdateMap'\n");
+
+        Statement statement = con.createStatement();
+
+        // add some items to the set
+ String update1 = "UPDATE testcollection SET M = M + {1.0: 'true', 3.0: 'false', 5.0: 'false'} WHERE k = 1;";
+        statement.executeUpdate(update1);
+
+ ResultSet result = statement.executeQuery("SELECT * FROM testcollection WHERE k = 1;");
+        result.next();
+
+        assertEquals(1, result.getInt("k"));
+        Object myObj = result.getObject("m");
+        Map<Double,Boolean> myMap = (Map<Double,Boolean>) myObj;
+        assertEquals(6, myMap.size());
+        assertTrue(myMap.keySet().contains(5.0));
+
+        if (LOG.isDebugEnabled()) LOG.debug("m           = '{}'", myObj);
+
+        // remove an item from the map
+        String update2 = "DELETE M[6.0] FROM testcollection WHERE k = 1;";
+        statement.executeUpdate(update2);
+
+ result = statement.executeQuery("SELECT * FROM testcollection WHERE k = 1;");
+        result.next();
+
+        assertEquals(1, result.getInt("k"));
+
+        myObj = result.getObject("m");
+        myMap = (Map<Double,Boolean>) myObj;
+        assertEquals(5, myMap.size());
+        assertTrue(myMap.keySet().contains(5.0));
+        assertFalse(myMap.keySet().contains(6.0));
+
+        if (LOG.isDebugEnabled()) LOG.debug("m           = '{}'", myObj);
+
+        String update4 = "UPDATE testcollection SET M =  ? WHERE k = 1;";
+
+        PreparedStatement prepared = con.prepareStatement(update4);
+ Map<Double,Boolean> myNewMap = new LinkedHashMap<Double,Boolean> ();
+        myNewMap.put(10.0, false);
+        myNewMap.put(12.0, true);
+        prepared.setObject(1, myNewMap, Types.OTHER);
+        prepared.execute();

-        if (LOG.isDebugEnabled()) LOG.debug("\n");
+ result = prepared.executeQuery("SELECT * FROM testcollection WHERE k = 1;");
+        result.next();
+        myObj = result.getObject("m");
+        myMap = (Map<Double,Boolean>) myObj;
+
+        if (LOG.isDebugEnabled()) LOG.debug("m (prepared)= '{}'\n", myObj);
     }



==============================================================================
Revision: 052ad46f5f4b
Author:   Palmer Cox <palmer...@gmail.com>
Date:     Sun Nov 18 21:45:28 2012
Log:      Fixed Issue #50, JDBC Suite does not compile under JDK 7
http://code.google.com/a/apache-extras.org/p/cassandra-jdbc/source/detail?r=052ad46f5f4b

Modified:
 /src/main/java/org/apache/cassandra/cql/jdbc/PooledCassandraDataSource.java

=======================================
--- /src/main/java/org/apache/cassandra/cql/jdbc/PooledCassandraDataSource.java Fri Oct 5 07:11:15 2012 +++ /src/main/java/org/apache/cassandra/cql/jdbc/PooledCassandraDataSource.java Sun Nov 18 21:45:28 2012
@@ -177,4 +177,11 @@
                return connectionPoolDataSource.unwrap(arg0);
        }

+ // Method not annotated with @Override since getParentLogger() is a new method + // in the CommonDataSource interface starting with JDK7 and this annotation
+       // would cause compilation errors with JDK6.
+ public java.util.logging.Logger getParentLogger() throws SQLFeatureNotSupportedException
+    {
+        return connectionPoolDataSource.getParentLogger();
+    }
 }

==============================================================================
Revision: e548427cee85
Author:   Rick Shaw <wfs...@gmail.com>
Date:     Sun Nov 18 21:48:14 2012
Log:      Update project POM to use C* Beta2
http://code.google.com/a/apache-extras.org/p/cassandra-jdbc/source/detail?r=e548427cee85

Modified:
 /pom.xml

=======================================
--- /pom.xml    Thu Oct 18 07:30:06 2012
+++ /pom.xml    Sun Nov 18 21:48:14 2012
@@ -105,12 +105,12 @@
     <dependency>
       <groupId>org.apache.cassandra</groupId>
       <artifactId>cassandra-clientutil</artifactId>
-      <version>1.2.0-beta1</version>
+      <version>1.2.0-beta2</version>
     </dependency>
     <dependency>
       <groupId>org.apache.cassandra</groupId>
       <artifactId>cassandra-thrift</artifactId>
-      <version>1.2.0-beta1</version>
+      <version>1.2.0-beta2</version>
       <exclusions>
         <exclusion>
           <groupId>javax.servlet</groupId>
@@ -131,7 +131,7 @@
     <dependency>
       <groupId>org.slf4j</groupId>
       <artifactId>slf4j-log4j12</artifactId>
-      <version>1.6.1</version>
+      <version>1.7.2</version>
       <scope>test</scope>
     </dependency>
     <dependency>

Reply via email to