cassandra-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From gdusba...@apache.org
Subject svn commit: r1086965 - in /cassandra/trunk/drivers/java: src/org/apache/cassandra/cql/jdbc/ test/org/apache/cassandra/cql/ test/org/apache/cassandra/cql/jdbc/
Date Wed, 30 Mar 2011 14:30:44 GMT
Author: gdusbabek
Date: Wed Mar 30 14:30:43 2011
New Revision: 1086965

URL: http://svn.apache.org/viewvc?rev=1086965&view=rev
Log:
JDBC PreparedStatements + some tests

Added:
    cassandra/trunk/drivers/java/src/org/apache/cassandra/cql/jdbc/CassandraPreparedStatement.java
    cassandra/trunk/drivers/java/test/org/apache/cassandra/cql/jdbc/
    cassandra/trunk/drivers/java/test/org/apache/cassandra/cql/jdbc/PreparedStatementTest.java
Modified:
    cassandra/trunk/drivers/java/src/org/apache/cassandra/cql/jdbc/CassandraConnection.java
    cassandra/trunk/drivers/java/src/org/apache/cassandra/cql/jdbc/CassandraResultSet.java
    cassandra/trunk/drivers/java/src/org/apache/cassandra/cql/jdbc/CassandraStatement.java
    cassandra/trunk/drivers/java/src/org/apache/cassandra/cql/jdbc/ColumnDecoder.java
    cassandra/trunk/drivers/java/src/org/apache/cassandra/cql/jdbc/ColumnMetaData.java
    cassandra/trunk/drivers/java/src/org/apache/cassandra/cql/jdbc/Connection.java
    cassandra/trunk/drivers/java/src/org/apache/cassandra/cql/jdbc/Utils.java
    cassandra/trunk/drivers/java/test/org/apache/cassandra/cql/EmbeddedServiceBase.java
    cassandra/trunk/drivers/java/test/org/apache/cassandra/cql/JdbcDriverTest.java

Modified: cassandra/trunk/drivers/java/src/org/apache/cassandra/cql/jdbc/CassandraConnection.java
URL: http://svn.apache.org/viewvc/cassandra/trunk/drivers/java/src/org/apache/cassandra/cql/jdbc/CassandraConnection.java?rev=1086965&r1=1086964&r2=1086965&view=diff
==============================================================================
--- cassandra/trunk/drivers/java/src/org/apache/cassandra/cql/jdbc/CassandraConnection.java (original)
+++ cassandra/trunk/drivers/java/src/org/apache/cassandra/cql/jdbc/CassandraConnection.java Wed Mar 30 14:30:43 2011
@@ -453,7 +453,7 @@ class CassandraConnection implements Con
      */
     public PreparedStatement prepareStatement(String sql) throws SQLException
     {
-        return new CassandraStatement(this.cassandraCon, sql);
+        return new CassandraPreparedStatement(this.cassandraCon, sql);
     }
 
 

Added: cassandra/trunk/drivers/java/src/org/apache/cassandra/cql/jdbc/CassandraPreparedStatement.java
URL: http://svn.apache.org/viewvc/cassandra/trunk/drivers/java/src/org/apache/cassandra/cql/jdbc/CassandraPreparedStatement.java?rev=1086965&view=auto
==============================================================================
--- cassandra/trunk/drivers/java/src/org/apache/cassandra/cql/jdbc/CassandraPreparedStatement.java (added)
+++ cassandra/trunk/drivers/java/src/org/apache/cassandra/cql/jdbc/CassandraPreparedStatement.java Wed Mar 30 14:30:43 2011
@@ -0,0 +1,548 @@
+package org.apache.cassandra.cql.jdbc;
+
+import org.apache.cassandra.db.marshal.AbstractType;
+import org.apache.cassandra.db.marshal.AsciiType;
+import org.apache.cassandra.db.marshal.BytesType;
+import org.apache.cassandra.db.marshal.LexicalUUIDType;
+import org.apache.cassandra.db.marshal.TimeUUIDType;
+import org.apache.cassandra.db.marshal.UTF8Type;
+
+import java.io.InputStream;
+import java.io.Reader;
+import java.math.BigDecimal;
+import java.math.BigInteger;
+import java.net.URL;
+import java.nio.ByteBuffer;
+import java.sql.Array;
+import java.sql.Blob;
+import java.sql.Clob;
+import java.sql.Date;
+import java.sql.NClob;
+import java.sql.ParameterMetaData;
+import java.sql.PreparedStatement;
+import java.sql.Ref;
+import java.sql.ResultSet;
+import java.sql.ResultSetMetaData;
+import java.sql.RowId;
+import java.sql.SQLException;
+import java.sql.SQLFeatureNotSupportedException;
+import java.sql.SQLXML;
+import java.sql.Time;
+import java.sql.Timestamp;
+import java.util.ArrayList;
+import java.util.Calendar;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+public class CassandraPreparedStatement extends CassandraStatement implements PreparedStatement
+{
+//    private static final Pattern Parameterizable = Pattern.compile("(SELECT|DELETE|UPDATE)\\s+.*", Pattern.CASE_INSENSITIVE);
+    private static final Pattern Select = Pattern.compile("SELECT[\\s+FIRST\\s+\\d+]?[\\s+REVERSED]?\\s+(.*)WHERE\\s+(.*)", Pattern.CASE_INSENSITIVE);
+    private static final Pattern Update = Pattern.compile("UPDATE\\s+\\w+.*\\s+SET\\s+(.*)\\s+WHERE KEY(.*)", Pattern.CASE_INSENSITIVE);
+    private static final Pattern Delete = Pattern.compile("DELETE\\s+(.*)\\s+FROM\\s+\\w+\\s+WHERE KEY(.*)", Pattern.CASE_INSENSITIVE);
+    
+    // current set of bound variables.
+    private final Map<Integer, Object> variables = new HashMap<Integer, Object>();
+    
+    // for batching. These are the queries that have been batched and not executed.
+    private final List<String> queries = new ArrayList<String>();
+    
+    CassandraPreparedStatement(Connection con, String cql)
+    {
+        super(con, cql);
+    }
+    
+    // impl specific methods start here.
+    
+    // determines which types need to be quoted.
+    private static boolean needsQuotes(AbstractType type) 
+    {
+        if (type instanceof ColumnMetaData)
+            return ((ColumnMetaData)type).needsQuotes();
+        else
+            return type == BytesType.instance ||
+                   type == AsciiType.instance ||
+                   type == UTF8Type.instance ||
+                   type == LexicalUUIDType.instance ||
+                   type == TimeUUIDType.instance;
+    }
+    
+    // double quotes strings (in parameters)
+    private static String makeCqlString(String s) 
+    {
+        // escape any single-quotes with double single-quotes.
+        return s.replaceAll("\'", "\'\'");
+    }
+    
+    // null type means just call param.toString() and quote it (default for keys).
+    private static String applySimpleBindings(String q, AbstractType type, ParameterIterator params) throws SQLException
+    {
+        assert type != null;
+        // we need to keep track of whether or not we are between quotes and ignore any question marks within them
+        // so that they are not substituted.  
+        StringBuffer sb = new StringBuffer();
+        boolean between = false;
+        for (char c : q.toCharArray())
+        {
+            if (c == '\'')
+                between = !between;
+            if (between)
+                sb.append(c);
+            else if (c == '?') // !between if we got here.
+            {
+                try
+                {
+                    // perform substitution!
+                    Object param = params.nextParam();
+                    String stringParam = type == null ? param.toString() : type.toString(param);
+                    stringParam = makeCqlString(stringParam);
+                    if (type == null || needsQuotes(type))
+                        stringParam = "'" + stringParam + "'";
+                    sb.append(stringParam);
+                }
+                catch (ClassCastException ex)
+                {
+                    throw new SQLException("Mismatched types: " + ex.getLocalizedMessage());
+                }
+            }
+            else
+                sb.append(c);
+                
+        }
+        return sb.toString();
+    }
+    
+    private static String applyDualBindings(String q, AbstractType ltype, AbstractType rtype, ParameterIterator params) throws SQLException
+    {
+        StringBuffer sb = new StringBuffer();
+        boolean between = false;
+        boolean left = true; // we always start on the left-hand side of a statement. we switch state if we reach a comma and we are not between.
+        for (char c : q.toCharArray())
+        {
+            if (c == '\'')
+                between = !between;
+            if (c == '=' && !between)
+                left = false;
+            if (c == ',' && !between)
+                left = true;
+            
+            if (c == '?' && !between)
+            {
+                try
+                {
+                    Object param = params.nextParam();
+                    AbstractType type = left ? ltype : rtype;
+                    String stringParam = makeCqlString(type.toString(param));
+                    if (needsQuotes(type))
+                        stringParam = "'" + stringParam + "'";
+                    sb.append(stringParam);
+                }
+                catch (ClassCastException ex)
+                {
+                    throw new SQLException("Mismatched types: " + ex.getLocalizedMessage());
+                }
+            }
+            else
+                sb.append(c);
+        }
+        return sb.toString();
+    }
+    
+    /** applies current bindings to produce a string that can be sent to the server. */
+    public synchronized String makeCql() throws SQLException
+    { 
+        // break cql up
+        Matcher m;
+        m = Delete.matcher(cql);
+        if (m.matches())
+            return makeDelete(m.end(1));
+        m = Update.matcher(cql);
+        if (m.matches())
+            return makeUpdate(m.end(1));
+        m = Select.matcher(cql);
+        if (m.matches())
+            return makeSelect(m.end(1));
+        
+        // if we made it this far, cql is not parameterizable. this isn't bad, there is just nothing to be done.
+        return cql;
+    }
+    
+    // subs parameters into a delete statement.
+    private String makeDelete(int pivot) throws SQLException
+    { 
+        String keyspace = connection.getKeyspace(cql);
+        String columnFamily = connection.getColumnFamily(cql);
+        ParameterIterator params = new ParameterIterator();
+        String left = cql.substring(0, pivot);
+        AbstractType leftType = connection.decoder.getComparator(keyspace, columnFamily, ColumnDecoder.Specifier.Comparator, null);
+        if (leftType == null)
+            throw new SQLException("Could not find comparator for " + keyspace + "." + columnFamily);
+        left = applySimpleBindings(left, leftType, params);
+        String right = cql.substring(pivot);
+        AbstractType keyVald = connection.decoder.getComparator(keyspace, columnFamily, ColumnDecoder.Specifier.Key, null);
+        if (keyVald == null)
+            throw new SQLException("Could not find key validator for " + keyspace + "." + columnFamily);
+        right = applySimpleBindings(right, keyVald, params);
+        return left + right;
+    }
+    
+    // subs parameters into a select statement.
+    private String makeSelect(int pivot) throws SQLException
+    { 
+        String keyspace = connection.getKeyspace(cql);
+        String columnFamily = connection.getColumnFamily(cql);
+        ParameterIterator params = new ParameterIterator();
+        String left = cql.substring(0, pivot);
+        AbstractType leftType = connection.decoder.getComparator(keyspace, columnFamily, ColumnDecoder.Specifier.Comparator, null);
+        if (leftType == null)
+            throw new SQLException("Could not find comparator for " + keyspace + "." + columnFamily);
+        left = applySimpleBindings(left, leftType, params);
+        String right = cql.substring(pivot);
+        AbstractType keyVald = connection.decoder.getComparator(keyspace, columnFamily, ColumnDecoder.Specifier.Key, null);
+        if (keyVald == null)
+            throw new SQLException("Could not find key validator for " + keyspace + "." + columnFamily);
+        right = applySimpleBindings(right, keyVald, params);
+        return left + right;
+    }
+    
+    // subs parameters into an update statement.
+    private String makeUpdate(int pivot) throws SQLException
+    {
+        // this one is a little bit different. left contains key=value pairs. we use the comparator for the left side,
+        // the validator for the right side.  right side is treated as a key.
+        String keyspace = connection.getKeyspace(cql);
+        String columnFamily = connection.getColumnFamily(cql);
+        ParameterIterator params = new ParameterIterator();
+        String left = cql.substring(0, pivot);
+        AbstractType leftComp = connection.decoder.getComparator(keyspace, columnFamily, ColumnDecoder.Specifier.Comparator, null);
+        if (leftComp == null)
+            throw new SQLException("Could not find comparator for " + keyspace + "." + columnFamily);
+        AbstractType leftVald = connection.decoder.getComparator(keyspace, columnFamily, ColumnDecoder.Specifier.Validator, null);
+        if (leftVald == null)
+            throw new SQLException("Could not find validator for " + keyspace + "." + columnFamily);
+        left = applyDualBindings(left, leftComp, leftVald, params);
+        String right = cql.substring(pivot);
+        AbstractType keyVald = connection.decoder.getComparator(keyspace, columnFamily, ColumnDecoder.Specifier.Key, null);
+        if (keyVald == null)
+            throw new SQLException("Could not find key validator for " + keyspace + "." + columnFamily);
+        right = applySimpleBindings(right, keyVald, params);
+        return left + right; 
+    }
+    
+    
+    
+    // standard API methods follow.
+    
+    public void addBatch() throws SQLException
+    {
+        queries.add(makeCql());
+    }
+
+    public synchronized void clearParameters() throws SQLException
+    {
+        variables.clear();
+    }
+
+    public boolean execute() throws SQLException
+    {
+        return this.cql != null && super.execute(makeCql());
+    }
+    
+    public ResultSet executeQuery() throws SQLException
+    {
+        return this.cql != null ? super.executeQuery(makeCql()) : null;
+    }
+    
+    public int executeUpdate() throws SQLException
+    {
+        String q = makeCql();
+        if (!UpdatePattern.matcher(q).matches())
+            throw new SQLException("Not an update statement.");
+        super.execute(q);
+        // we don't know how many rows were updated.
+        return 0;
+    }
+
+    public ResultSetMetaData getMetaData() throws SQLException
+    {
+        // todo: current impl of RSMD relies on knowing the results. implementing this will require refactoring CRSMD into 
+        // two classes: the first will be an implementation whose methods don't rely on knowing the results, the second
+        // will implement the full CRSMD interfae and extend or compose the first.
+        throw new SQLFeatureNotSupportedException("PreparedStatement.getMetaData() hasn't been implemented yet.");
+    }
+
+    public void setByte(int parameterIndex, byte x) throws SQLException
+    {
+        setObject(parameterIndex, new byte[]{x});
+    }
+
+    public void setBytes(int parameterIndex, byte[] x) throws SQLException
+    {
+        setObject(parameterIndex, ByteBuffer.wrap(x));
+    }
+
+    public void setInt(int parameterIndex, int x) throws SQLException
+    {
+        setObject(parameterIndex, new BigInteger(Integer.toString(x)));
+    }
+
+    public void setLong(int parameterIndex, long x) throws SQLException
+    {
+        setObject(parameterIndex, x);
+    }
+
+    public void setNString(int parameterIndex, String value) throws SQLException
+    {
+        setString(parameterIndex, value);
+    }
+
+    public void setObject(int parameterIndex, Object x) throws SQLException
+    {
+        variables.put(parameterIndex, x);
+    }
+
+    public void setShort(int parameterIndex, short x) throws SQLException
+    {
+        setInt(parameterIndex, x);
+    }
+
+    public void setString(int parameterIndex, String x) throws SQLException
+    {
+        setObject(parameterIndex, x);
+    }
+    
+    
+    // everything below here is not implemented and will let you know about it.
+    
+    
+    public ParameterMetaData getParameterMetaData() throws SQLException
+    {
+        throw new SQLFeatureNotSupportedException("PreparedStatement.getParameterMetaData() hasn't been implemented yet.");
+    }
+
+    public void setArray(int parameterIndex, Array x) throws SQLException
+    {
+        throw new SQLFeatureNotSupportedException("method not supported");
+    }
+
+    public void setAsciiStream(int parameterIndex, InputStream x) throws SQLException
+    {
+        throw new SQLFeatureNotSupportedException("method not supported");
+    }
+
+    public void setAsciiStream(int parameterIndex, InputStream x, int length) throws SQLException
+    {
+        throw new SQLFeatureNotSupportedException("method not supported");
+    }
+
+    public void setAsciiStream(int parameterIndex, InputStream x, long length) throws SQLException
+    {
+        throw new SQLFeatureNotSupportedException("method not supported");
+    }
+
+    public void setBigDecimal(int parameterIndex, BigDecimal x) throws SQLException
+    {
+        throw new SQLFeatureNotSupportedException("method not supported");
+    }
+
+    public void setBinaryStream(int parameterIndex, InputStream x) throws SQLException
+    {
+        throw new SQLFeatureNotSupportedException("method not supported");
+    }
+
+    public void setBinaryStream(int parameterIndex, InputStream x, int length) throws SQLException
+    {
+        throw new SQLFeatureNotSupportedException("method not supported");
+    }
+
+    public void setBinaryStream(int parameterIndex, InputStream x, long length) throws SQLException
+    {
+        throw new SQLFeatureNotSupportedException("method not supported");
+    }
+
+    public void setBlob(int parameterIndex, Blob x) throws SQLException
+    {
+        throw new SQLFeatureNotSupportedException("method not supported");
+    }
+
+    public void setBlob(int parameterIndex, InputStream inputStream) throws SQLException
+    {
+        throw new SQLFeatureNotSupportedException("method not supported");
+    }
+
+    public void setBlob(int parameterIndex, InputStream inputStream, long length) throws SQLException
+    {
+        throw new SQLFeatureNotSupportedException("method not supported");
+    }
+
+    public void setBoolean(int parameterIndex, boolean x) throws SQLException
+    {
+        throw new SQLFeatureNotSupportedException("method not supported");
+    }
+
+    public void setCharacterStream(int parameterIndex, Reader reader) throws SQLException
+    {
+        throw new SQLFeatureNotSupportedException("method not supported");
+    }
+
+    public void setCharacterStream(int parameterIndex, Reader reader, int length) throws SQLException
+    {
+        throw new SQLFeatureNotSupportedException("method not supported");
+    }
+
+    public void setCharacterStream(int parameterIndex, Reader reader, long length) throws SQLException
+    {
+        throw new SQLFeatureNotSupportedException("method not supported");
+    }
+
+    public void setClob(int parameterIndex, Clob x) throws SQLException
+    {
+        throw new SQLFeatureNotSupportedException("method not supported");
+    }
+
+    public void setClob(int parameterIndex, Reader reader) throws SQLException
+    {
+        throw new SQLFeatureNotSupportedException("method not supported");
+    }
+
+    public void setClob(int parameterIndex, Reader reader, long length) throws SQLException
+    {
+        throw new SQLFeatureNotSupportedException("method not supported");
+    }
+
+    public void setDate(int parameterIndex, Date x) throws SQLException
+    {
+        throw new SQLFeatureNotSupportedException("method not supported");
+    }
+
+    public void setDate(int parameterIndex, Date x, Calendar cal) throws SQLException
+    {
+        throw new SQLFeatureNotSupportedException("method not supported");
+    }
+
+    public void setDouble(int parameterIndex, double x) throws SQLException
+    {
+        throw new SQLFeatureNotSupportedException("method not supported");
+    }
+
+    public void setFloat(int parameterIndex, float x) throws SQLException
+    {
+        throw new SQLFeatureNotSupportedException("method not supported");
+    }
+    
+    public void setNCharacterStream(int parameterIndex, Reader value) throws SQLException
+    {
+        throw new SQLFeatureNotSupportedException("method not supported");
+    }
+
+    public void setNCharacterStream(int parameterIndex, Reader value, long length) throws SQLException
+    {
+        throw new SQLFeatureNotSupportedException("method not supported");
+    }
+
+    public void setNClob(int parameterIndex, NClob value) throws SQLException
+    {
+        throw new SQLFeatureNotSupportedException("method not supported");
+    }
+
+    public void setNClob(int parameterIndex, Reader reader) throws SQLException
+    {
+        throw new SQLFeatureNotSupportedException("method not supported");
+    }
+
+    public void setNClob(int parameterIndex, Reader reader, long length) throws SQLException
+    {
+        throw new SQLFeatureNotSupportedException("method not supported");
+    }
+    
+    public void setNull(int parameterIndex, int sqlType) throws SQLException
+    {
+        throw new SQLFeatureNotSupportedException("method not supported");
+    }
+
+    public void setNull(int parameterIndex, int sqlType, String typeName) throws SQLException
+    {
+        throw new SQLFeatureNotSupportedException("method not supported");
+    }
+    
+    public void setObject(int parameterIndex, Object x, int targetSqlType) throws SQLException
+    {
+        throw new SQLFeatureNotSupportedException("method not supported");
+    }
+
+    public void setObject(int parameterIndex, Object x, int targetSqlType, int scaleOrLength) throws SQLException
+    {
+        throw new SQLFeatureNotSupportedException("method not supported");
+    }
+
+    public void setRef(int parameterIndex, Ref x) throws SQLException
+    {
+        throw new SQLFeatureNotSupportedException("method not supported");
+    }
+
+    public void setRowId(int parameterIndex, RowId x) throws SQLException
+    {
+        throw new SQLFeatureNotSupportedException("method not supported");
+    }
+
+    public void setSQLXML(int parameterIndex, SQLXML xmlObject) throws SQLException
+    {
+        throw new SQLFeatureNotSupportedException("method not supported");
+    }
+    
+    public void setTime(int parameterIndex, Time x) throws SQLException
+    {
+        throw new SQLFeatureNotSupportedException("method not supported");
+    }
+
+    public void setTime(int parameterIndex, Time x, Calendar cal) throws SQLException
+    {
+        throw new SQLFeatureNotSupportedException("method not supported");
+    }
+
+    public void setTimestamp(int parameterIndex, Timestamp x) throws SQLException
+    {
+        throw new SQLFeatureNotSupportedException("method not supported");
+    }
+
+    public void setTimestamp(int parameterIndex, Timestamp x, Calendar cal) throws SQLException
+    {
+        throw new SQLFeatureNotSupportedException("method not supported");
+    }
+
+    public void setURL(int parameterIndex, URL x) throws SQLException
+    {
+        throw new SQLFeatureNotSupportedException("method not supported");
+    }
+
+    public void setUnicodeStream(int parameterIndex, InputStream x, int length) throws SQLException
+    {
+        throw new SQLFeatureNotSupportedException("method not supported");
+    }
+    
+    
+    // done with API methods.
+    
+    
+    
+    // provides a way to iterate through the parameters. it will blow up if it discovers any missing parameters.
+    // not thread-safe.
+    private class ParameterIterator
+    {
+        private Map<Integer, Object> params = new HashMap<Integer, Object>(variables);
+        private int index = 1;
+        
+        // throws SQLException if a parameter is not specified.
+        private Object nextParam() throws SQLException
+        {
+            Object p = params.get(index++);
+            if (p == null)
+                throw new SQLException("No parameter bound to " + (index-1));
+            return p;
+        }
+
+    }
+}

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=1086965&r1=1086964&r2=1086965&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 Wed Mar 30 14:30:43 2011
@@ -42,7 +42,6 @@ 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;
@@ -54,12 +53,12 @@ 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;
 
+// todo: get by index is off by one.
 /**
  * The Class CassandraResultSet.
  */
@@ -2068,26 +2067,14 @@ class CassandraResultSet implements Resu
         {
             column--;
             checkIndex(column);
-            TypedColumn col = values.get(column);
-            if (nameType == IntegerType.instance || nameType == LongType.instance)
-                return true;
-            else if (nameType instanceof ColumnMetaData) 
-                return ((ColumnMetaData)nameType).isSigned();
-            else
-                return false;
+            return Utils.isTypeSigned(nameType);
         }
         
         public boolean isValueSigned(int column) throws SQLException
         {
             column--;
             checkIndex(column);
-            TypedColumn col = values.get(column);
-            if (valueType == IntegerType.instance || valueType == LongType.instance)
-                return true;
-            else if (valueType instanceof ColumnMetaData) 
-                return ((ColumnMetaData)valueType).isSigned();
-            else
-                return false;
+            return Utils.isTypeSigned(valueType);
         }
 
         public int getNameDisplaySize(int column) throws SQLException
@@ -2144,55 +2131,30 @@ class CassandraResultSet implements Resu
         {
             column--;
             checkIndex(column);
-            if (valueType instanceof ColumnMetaData)
-                return ((ColumnMetaData)nameType).getScale();
-            else
-                return 0;
+            return Utils.getTypeScale(nameType);
         }
         
         public int getValueScale(int column) throws SQLException
         {
             column--;
             checkIndex(column);
-            if (valueType instanceof ColumnMetaData)
-                return ((ColumnMetaData)valueType).getScale();
-            else
-                return 0;
+            return Utils.getTypeScale(valueType);
         }
 
         public int getNameType(int column) throws SQLException
         {
             column--;
             checkIndex(column);
-            return getJdbcType(nameType);
+            return Utils.getJdbcType(nameType);
         }
         
         public int getValueType(int column) throws SQLException
         {
             column--;
             checkIndex(column);
-            return getJdbcType(valueType);
+            return Utils.getJdbcType(valueType);
         }
         
-        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
         {
             column--;

Modified: cassandra/trunk/drivers/java/src/org/apache/cassandra/cql/jdbc/CassandraStatement.java
URL: http://svn.apache.org/viewvc/cassandra/trunk/drivers/java/src/org/apache/cassandra/cql/jdbc/CassandraStatement.java?rev=1086965&r1=1086964&r2=1086965&view=diff
==============================================================================
--- cassandra/trunk/drivers/java/src/org/apache/cassandra/cql/jdbc/CassandraStatement.java (original)
+++ cassandra/trunk/drivers/java/src/org/apache/cassandra/cql/jdbc/CassandraStatement.java Wed Mar 30 14:30:43 2011
@@ -20,28 +20,12 @@
  */
 package org.apache.cassandra.cql.jdbc;
 
-import java.io.InputStream;
-import java.io.Reader;
-import java.math.BigDecimal;
-import java.net.URL;
-import java.sql.Array;
-import java.sql.Blob;
-import java.sql.Clob;
 import java.sql.Connection;
-import java.sql.Date;
-import java.sql.NClob;
-import java.sql.ParameterMetaData;
 import java.sql.PreparedStatement;
-import java.sql.Ref;
 import java.sql.ResultSet;
-import java.sql.ResultSetMetaData;
-import java.sql.RowId;
 import java.sql.SQLException;
 import java.sql.SQLWarning;
-import java.sql.SQLXML;
-import java.sql.Time;
-import java.sql.Timestamp;
-import java.util.Calendar;
+import java.sql.Statement;
 import java.util.regex.Pattern;
 
 import org.apache.cassandra.thrift.CqlResult;
@@ -56,15 +40,15 @@ import org.apache.thrift.TException;
  * Cassandra statement: implementation class for {@link PreparedStatement}.
  */
 
-class CassandraStatement implements PreparedStatement
+class CassandraStatement implements Statement
 {
-    private static final Pattern UpdatePattern = Pattern.compile("UPDATE .*", Pattern.CASE_INSENSITIVE);
+    protected static final Pattern UpdatePattern = Pattern.compile("UPDATE .*", Pattern.CASE_INSENSITIVE);
     
     /** The connection. */
-    private org.apache.cassandra.cql.jdbc.Connection connection;
+    protected final org.apache.cassandra.cql.jdbc.Connection connection;
     
     /** The cql. */
-    private String cql;
+    protected final String cql;
 
     /**
      * Constructor using fields.
@@ -72,7 +56,7 @@ class CassandraStatement implements Prep
      */
     CassandraStatement(org.apache.cassandra.cql.jdbc.Connection con)
     {
-        this.connection = con;
+        this(con, null);
     }
 
     /**
@@ -607,663 +591,4 @@ class CassandraStatement implements Prep
         throw new UnsupportedOperationException("method not supported");
 
     }
-
-    
-    /**
-     * @throws SQLException
-     */
-    public void addBatch() throws SQLException
-    {
-        throw new UnsupportedOperationException("method not supported");
-
-    }
-
-    
-    /**
-     * @throws SQLException
-     */
-    public void clearParameters() throws SQLException
-    {
-        throw new UnsupportedOperationException("method not supported");
-
-    }
-
-    
-    /**
-     * @return
-     * @throws SQLException
-     */
-    public boolean execute() throws SQLException
-    {
-        return this.cql != null ? execute(cql) : false;
-    }
-
-    
-    /**
-     * @return
-     * @throws SQLException
-     */
-    public ResultSet executeQuery() throws SQLException
-    {
-        return this.cql != null ? executeQuery(cql) : null;
-    }
-
-    
-    /**
-     * @return
-     * @throws SQLException
-     */
-    public int executeUpdate() throws SQLException
-    {
-        return 0;
-    }
-
-    
-    /**
-     * @return
-     * @throws SQLException
-     */
-    public ResultSetMetaData getMetaData() throws SQLException
-    {
-        return null;
-    }
-
-    
-    /**
-     * @return
-     * @throws SQLException
-     */
-    public ParameterMetaData getParameterMetaData() throws SQLException
-    {
-        return null;
-    }
-
-    
-    /**
-     * @param parameterIndex
-     * @param x
-     * @throws SQLException
-     */
-    public void setArray(int parameterIndex, Array x) throws SQLException
-    {
-    }
-
-    
-    /**
-     * @param parameterIndex
-     * @param x
-     * @throws SQLException
-     */
-    public void setAsciiStream(int parameterIndex, InputStream x) throws SQLException
-    {
-        throw new UnsupportedOperationException("method not supported");
-
-    }
-
-    
-    /**
-     * @param parameterIndex
-     * @param x
-     * @param length
-     * @throws SQLException
-     */
-    public void setAsciiStream(int parameterIndex, InputStream x, int length) throws SQLException
-    {
-        throw new UnsupportedOperationException("method not supported");
-
-    }
-
-    
-    /**
-     * @param parameterIndex
-     * @param x
-     * @param length
-     * @throws SQLException
-     */
-    public void setAsciiStream(int parameterIndex, InputStream x, long length) throws SQLException
-    {
-        throw new UnsupportedOperationException("method not supported");
-
-    }
-
-    
-    /**
-     * @param parameterIndex
-     * @param x
-     * @throws SQLException
-     */
-    public void setBigDecimal(int parameterIndex, BigDecimal x) throws SQLException
-    {
-        throw new UnsupportedOperationException("method not supported");
-
-    }
-
-    
-    /**
-     * @param parameterIndex
-     * @param x
-     * @throws SQLException
-     */
-    public void setBinaryStream(int parameterIndex, InputStream x) throws SQLException
-    {
-        throw new UnsupportedOperationException("method not supported");
-
-    }
-
-    
-    /**
-     * @param parameterIndex
-     * @param x
-     * @param length
-     * @throws SQLException
-     */
-    public void setBinaryStream(int parameterIndex, InputStream x, int length) throws SQLException
-    {
-        throw new UnsupportedOperationException("method not supported");
-
-    }
-
-    
-    /**
-     * @param parameterIndex
-     * @param x
-     * @param length
-     * @throws SQLException
-     */
-    public void setBinaryStream(int parameterIndex, InputStream x, long length) throws SQLException
-    {
-        throw new UnsupportedOperationException("method not supported");
-
-    }
-
-    
-    /**
-     * @param parameterIndex
-     * @param x
-     * @throws SQLException
-     */
-    public void setBlob(int parameterIndex, Blob x) throws SQLException
-    {
-        throw new UnsupportedOperationException("method not supported");
-
-    }
-
-    
-    /**
-     * @param parameterIndex
-     * @param inputStream
-     * @throws SQLException
-     */
-    public void setBlob(int parameterIndex, InputStream inputStream) throws SQLException
-    {
-        throw new UnsupportedOperationException("method not supported");
-
-    }
-
-    
-    /**
-     * @param parameterIndex
-     * @param inputStream
-     * @param length
-     * @throws SQLException
-     */
-    public void setBlob(int parameterIndex, InputStream inputStream, long length) throws SQLException
-    {
-        throw new UnsupportedOperationException("method not supported");
-
-    }
-
-    
-    /**
-     * @param parameterIndex
-     * @param x
-     * @throws SQLException
-     */
-    public void setBoolean(int parameterIndex, boolean x) throws SQLException
-    {
-        throw new UnsupportedOperationException("method not supported");
-
-    }
-
-    
-    /**
-     * @param parameterIndex
-     * @param x
-     * @throws SQLException
-     */
-    public void setByte(int parameterIndex, byte x) throws SQLException
-    {
-        throw new UnsupportedOperationException("method not supported");
-
-    }
-
-    
-    /**
-     * @param parameterIndex
-     * @param x
-     * @throws SQLException
-     */
-    public void setBytes(int parameterIndex, byte[] x) throws SQLException
-    {
-        throw new UnsupportedOperationException("method not supported");
-
-    }
-
-    
-    /**
-     * @param parameterIndex
-     * @param reader
-     * @throws SQLException
-     */
-    public void setCharacterStream(int parameterIndex, Reader reader) throws SQLException
-    {
-        throw new UnsupportedOperationException("method not supported");
-
-    }
-
-    
-    /**
-     * @param parameterIndex
-     * @param reader
-     * @param length
-     * @throws SQLException
-     */
-    public void setCharacterStream(int parameterIndex, Reader reader, int length) throws SQLException
-    {
-        throw new UnsupportedOperationException("method not supported");
-
-    }
-
-    
-    /**
-     * @param parameterIndex
-     * @param reader
-     * @param length
-     * @throws SQLException
-     */
-    public void setCharacterStream(int parameterIndex, Reader reader, long length) throws SQLException
-    {
-        throw new UnsupportedOperationException("method not supported");
-
-    }
-
-    
-    /**
-     * @param parameterIndex
-     * @param x
-     * @throws SQLException
-     */
-    public void setClob(int parameterIndex, Clob x) throws SQLException
-    {
-        throw new UnsupportedOperationException("method not supported");
-
-    }
-
-    
-    /**
-     * @param parameterIndex
-     * @param reader
-     * @throws SQLException
-     */
-    public void setClob(int parameterIndex, Reader reader) throws SQLException
-    {
-        throw new UnsupportedOperationException("method not supported");
-
-    }
-
-    
-    /**
-     * @param parameterIndex
-     * @param reader
-     * @param length
-     * @throws SQLException
-     */
-    public void setClob(int parameterIndex, Reader reader, long length) throws SQLException
-    {
-        throw new UnsupportedOperationException("method not supported");
-
-    }
-
-    
-    /**
-     * @param parameterIndex
-     * @param x
-     * @throws SQLException
-     */
-    public void setDate(int parameterIndex, Date x) throws SQLException
-    {
-        throw new UnsupportedOperationException("method not supported");
-
-    }
-
-    
-    /**
-     * @param parameterIndex
-     * @param x
-     * @param cal
-     * @throws SQLException
-     */
-    public void setDate(int parameterIndex, Date x, Calendar cal) throws SQLException
-    {
-        throw new UnsupportedOperationException("method not supported");
-
-    }
-
-    
-    /**
-     * @param parameterIndex
-     * @param x
-     * @throws SQLException
-     */
-    public void setDouble(int parameterIndex, double x) throws SQLException
-    {
-        throw new UnsupportedOperationException("method not supported");
-
-    }
-
-    
-    /**
-     * @param parameterIndex
-     * @param x
-     * @throws SQLException
-     */
-    public void setFloat(int parameterIndex, float x) throws SQLException
-    {
-        throw new UnsupportedOperationException("method not supported");
-
-    }
-
-    
-    /**
-     * @param parameterIndex
-     * @param x
-     * @throws SQLException
-     */
-    public void setInt(int parameterIndex, int x) throws SQLException
-    {
-        throw new UnsupportedOperationException("method not supported");
-
-    }
-
-    
-    /**
-     * @param parameterIndex
-     * @param x
-     * @throws SQLException
-     */
-    public void setLong(int parameterIndex, long x) throws SQLException
-    {
-        throw new UnsupportedOperationException("method not supported");
-
-    }
-
-    
-    /**
-     * @param parameterIndex
-     * @param value
-     * @throws SQLException
-     */
-    public void setNCharacterStream(int parameterIndex, Reader value) throws SQLException
-    {
-        throw new UnsupportedOperationException("method not supported");
-
-    }
-
-    
-    /**
-     * @param parameterIndex
-     * @param value
-     * @param length
-     * @throws SQLException
-     */
-    public void setNCharacterStream(int parameterIndex, Reader value, long length) throws SQLException
-    {
-        throw new UnsupportedOperationException("method not supported");
-
-    }
-
-    
-    /**
-     * @param parameterIndex
-     * @param value
-     * @throws SQLException
-     */
-    public void setNClob(int parameterIndex, NClob value) throws SQLException
-    {
-        throw new UnsupportedOperationException("method not supported");
-
-    }
-
-    
-    /**
-     * @param parameterIndex
-     * @param reader
-     * @throws SQLException
-     */
-    public void setNClob(int parameterIndex, Reader reader) throws SQLException
-    {
-        throw new UnsupportedOperationException("method not supported");
-
-    }
-
-    
-    /**
-     * @param parameterIndex
-     * @param reader
-     * @param length
-     * @throws SQLException
-     */
-    public void setNClob(int parameterIndex, Reader reader, long length) throws SQLException
-    {
-        throw new UnsupportedOperationException("method not supported");
-
-    }
-
-    
-    /**
-     * @param parameterIndex
-     * @param value
-     * @throws SQLException
-     */
-    public void setNString(int parameterIndex, String value) throws SQLException
-    {
-        throw new UnsupportedOperationException("method not supported");
-
-    }
-
-    
-    /**
-     * @param parameterIndex
-     * @param sqlType
-     * @throws SQLException
-     */
-    public void setNull(int parameterIndex, int sqlType) throws SQLException
-    {
-        throw new UnsupportedOperationException("method not supported");
-
-    }
-
-    
-    /**
-     * @param parameterIndex
-     * @param sqlType
-     * @param typeName
-     * @throws SQLException
-     */
-    public void setNull(int parameterIndex, int sqlType, String typeName) throws SQLException
-    {
-        throw new UnsupportedOperationException("method not supported");
-
-    }
-
-    
-    /**
-     * @param parameterIndex
-     * @param x
-     * @throws SQLException
-     */
-    public void setObject(int parameterIndex, Object x) throws SQLException
-    {
-        throw new UnsupportedOperationException("method not supported");
-
-    }
-
-    
-    /**
-     * @param parameterIndex
-     * @param x
-     * @param targetSqlType
-     * @throws SQLException
-     */
-    public void setObject(int parameterIndex, Object x, int targetSqlType) throws SQLException
-    {
-        throw new UnsupportedOperationException("method not supported");
-
-    }
-
-    
-    /**
-     * @param parameterIndex
-     * @param x
-     * @param targetSqlType
-     * @param scaleOrLength
-     * @throws SQLException
-     */
-    public void setObject(int parameterIndex, Object x, int targetSqlType, int scaleOrLength) throws SQLException
-    {
-        throw new UnsupportedOperationException("method not supported");
-
-    }
-
-    
-    /**
-     * @param parameterIndex
-     * @param x
-     * @throws SQLException
-     */
-    public void setRef(int parameterIndex, Ref x) throws SQLException
-    {
-        throw new UnsupportedOperationException("method not supported");
-
-    }
-
-    
-    /**
-     * @param parameterIndex
-     * @param x
-     * @throws SQLException
-     */
-    public void setRowId(int parameterIndex, RowId x) throws SQLException
-    {
-        throw new UnsupportedOperationException("method not supported");
-
-    }
-
-    
-    /**
-     * @param parameterIndex
-     * @param xmlObject
-     * @throws SQLException
-     */
-    public void setSQLXML(int parameterIndex, SQLXML xmlObject) throws SQLException
-    {
-        throw new UnsupportedOperationException("method not supported");
-
-    }
-
-    
-    /**
-     * @param parameterIndex
-     * @param x
-     * @throws SQLException
-     */
-    public void setShort(int parameterIndex, short x) throws SQLException
-    {
-        throw new UnsupportedOperationException("method not supported");
-
-    }
-
-    
-    /**
-     * @param parameterIndex
-     * @param x
-     * @throws SQLException
-     */
-    public void setString(int parameterIndex, String x) throws SQLException
-    {
-        throw new UnsupportedOperationException("method not supported");
-
-    }
-
-    
-    /**
-     * @param parameterIndex
-     * @param x
-     * @throws SQLException
-     */
-    public void setTime(int parameterIndex, Time x) throws SQLException
-    {
-        throw new UnsupportedOperationException("method not supported");
-
-    }
-
-    
-    /**
-     * @param parameterIndex
-     * @param x
-     * @param cal
-     * @throws SQLException
-     */
-    public void setTime(int parameterIndex, Time x, Calendar cal) throws SQLException
-    {
-        throw new UnsupportedOperationException("method not supported");
-
-    }
-
-    
-    /**
-     * @param parameterIndex
-     * @param x
-     * @throws SQLException
-     */
-    public void setTimestamp(int parameterIndex, Timestamp x) throws SQLException
-    {
-        throw new UnsupportedOperationException("method not supported");
-    }
-
-    
-    /**
-     * @param parameterIndex
-     * @param x
-     * @param cal
-     * @throws SQLException
-     */
-    public void setTimestamp(int parameterIndex, Timestamp x, Calendar cal) throws SQLException
-    {
-        throw new UnsupportedOperationException("method not supported");
-    }
-
-    
-    /**
-     * @param parameterIndex
-     * @param x
-     * @throws SQLException
-     */
-    public void setURL(int parameterIndex, URL x) throws SQLException
-    {
-        throw new UnsupportedOperationException("method not supported");
-    }
-
-    
-    /**
-     * @param parameterIndex
-     * @param x
-     * @param length
-     * @throws SQLException
-     */
-    public void setUnicodeStream(int parameterIndex, InputStream x, int length) throws SQLException
-    {
-        throw new UnsupportedOperationException("method not supported");
-    }
-
 }

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=1086965&r1=1086964&r2=1086965&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 Wed Mar 30 14:30:43 2011
@@ -45,7 +45,8 @@ class ColumnDecoder 
     enum Specifier
     {
         Comparator,
-        Validator
+        Validator,
+        Key
     }
     
     private Map<String, CfDef> cfDefs = new HashMap<String, CfDef>();
@@ -79,10 +80,16 @@ class ColumnDecoder 
         {
             if (def == null)
                 def = cfDefs.get(String.format("%s.%s", keyspace, columnFamily));
+            if (def == null)
+                // no point in proceeding. these values are bad.
+                return null;
             try 
             {
                 switch (specifier)
                 {
+                    case Key:
+                        comparator = FBUtilities.getComparator(def.getKey_validation_class());
+                        break;
                     case Validator:
                         comparator = FBUtilities.getComparator(def.getDefault_validation_class());
                         break;

Modified: 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=1086965&r1=1086964&r2=1086965&view=diff
==============================================================================
--- cassandra/trunk/drivers/java/src/org/apache/cassandra/cql/jdbc/ColumnMetaData.java (original)
+++ cassandra/trunk/drivers/java/src/org/apache/cassandra/cql/jdbc/ColumnMetaData.java Wed Mar 30 14:30:43 2011
@@ -34,4 +34,5 @@ public interface ColumnMetaData
     public int getPrecision();
     public int getScale();
     public int getType();
+    public boolean needsQuotes();
 }

Modified: cassandra/trunk/drivers/java/src/org/apache/cassandra/cql/jdbc/Connection.java
URL: http://svn.apache.org/viewvc/cassandra/trunk/drivers/java/src/org/apache/cassandra/cql/jdbc/Connection.java?rev=1086965&r1=1086964&r2=1086965&view=diff
==============================================================================
--- cassandra/trunk/drivers/java/src/org/apache/cassandra/cql/jdbc/Connection.java (original)
+++ cassandra/trunk/drivers/java/src/org/apache/cassandra/cql/jdbc/Connection.java Wed Mar 30 14:30:43 2011
@@ -50,7 +50,8 @@ import org.slf4j.LoggerFactory;
 class Connection
 {
     private static final Pattern KeyspacePattern = Pattern.compile("USE (\\w+);?", Pattern.CASE_INSENSITIVE | Pattern.MULTILINE);
-    private static final Pattern SelectPattern = Pattern.compile("SELECT\\s+.+\\s+FROM\\s+(\\w+).*", Pattern.CASE_INSENSITIVE | Pattern.MULTILINE);
+    private static final Pattern SelectPattern = Pattern.compile("(?:SELECT|DELETE)\\s+.+\\s+FROM\\s+(\\w+).*", Pattern.CASE_INSENSITIVE | Pattern.MULTILINE);
+    private static final Pattern UpdatePatter = Pattern.compile("UPDATE\\s+(\\w+)\\s+.*", Pattern.CASE_INSENSITIVE);
     
     public static Compression defaultCompression = Compression.GZIP;
     public final String hostName;
@@ -140,12 +141,8 @@ class Connection
         if (decoder == null)
             decoder = new ColumnDecoder(client.describe_keyspaces());
         
-        Matcher isKeyspace = KeyspacePattern.matcher(queryStr);
-        if (isKeyspace.matches())
-            curKeyspace = isKeyspace.group(1);
-        Matcher isSelect = SelectPattern.matcher(queryStr);
-        if (isSelect.matches())
-            curColumnFamily = isSelect.group(1);
+        curKeyspace = getKeyspace(queryStr);
+        curColumnFamily = getColumnFamily(queryStr);
         try
         {
             return client.execute_cql_query(Utils.compressQuery(queryStr, compress), compress);
@@ -158,6 +155,27 @@ class Connection
         }
     }
     
+    String getKeyspace(String query)
+    {
+        String ks = curKeyspace;
+        Matcher isKeyspace = KeyspacePattern.matcher(query);
+        if (isKeyspace.matches())
+            ks = isKeyspace.group(1);
+        return ks;
+    }
+    
+    String getColumnFamily(String query) 
+    {
+        String cf = curColumnFamily;
+        Matcher isSelect = SelectPattern.matcher(query);
+        if (isSelect.matches())
+            cf = isSelect.group(1);
+        Matcher isUpdate = UpdatePatter.matcher(query);
+        if (isUpdate.matches())
+            cf = isUpdate.group(1);   
+        return cf;
+    }
+    
     /** Shutdown the remote connection */
     public void close()
     {
@@ -169,4 +187,16 @@ class Connection
     {
         return transport.isOpen();
     }
+    
+    class QueryMetadata
+    {
+        public final String keyspace;
+        public final String columnFamily;
+        
+        QueryMetadata(String keyspace, String columnFamily)
+        {
+            this.keyspace = keyspace;
+            this.columnFamily = columnFamily;
+        }
+    }
 }

Modified: cassandra/trunk/drivers/java/src/org/apache/cassandra/cql/jdbc/Utils.java
URL: http://svn.apache.org/viewvc/cassandra/trunk/drivers/java/src/org/apache/cassandra/cql/jdbc/Utils.java?rev=1086965&r1=1086964&r2=1086965&view=diff
==============================================================================
--- cassandra/trunk/drivers/java/src/org/apache/cassandra/cql/jdbc/Utils.java (original)
+++ cassandra/trunk/drivers/java/src/org/apache/cassandra/cql/jdbc/Utils.java Wed Mar 30 14:30:43 2011
@@ -23,8 +23,15 @@ package org.apache.cassandra.cql.jdbc;
 
 import java.io.ByteArrayOutputStream;
 import java.nio.ByteBuffer;
+import java.sql.SQLException;
+import java.sql.Types;
+import java.util.UUID;
 import java.util.zip.Deflater;
 
+import org.apache.cassandra.db.marshal.AbstractType;
+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.thrift.Compression;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
@@ -55,4 +62,40 @@ class Utils
         
         return ByteBuffer.wrap(byteArray.toByteArray());
     }
+    
+    static 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());
+    }
+    
+    static boolean isTypeSigned(AbstractType type)
+    {
+        if (type == IntegerType.instance || type == LongType.instance)
+            return true;
+        else if (type instanceof ColumnMetaData) 
+            return ((ColumnMetaData)type).isSigned();
+        else
+            return false;
+    }
+    
+    static int getTypeScale(AbstractType type) 
+    {
+        if (type instanceof ColumnMetaData)
+            return ((ColumnMetaData)type).getScale();
+        else
+            return 0;
+    }
 }

Modified: cassandra/trunk/drivers/java/test/org/apache/cassandra/cql/EmbeddedServiceBase.java
URL: http://svn.apache.org/viewvc/cassandra/trunk/drivers/java/test/org/apache/cassandra/cql/EmbeddedServiceBase.java?rev=1086965&r1=1086964&r2=1086965&view=diff
==============================================================================
--- cassandra/trunk/drivers/java/test/org/apache/cassandra/cql/EmbeddedServiceBase.java (original)
+++ cassandra/trunk/drivers/java/test/org/apache/cassandra/cql/EmbeddedServiceBase.java Wed Mar 30 14:30:43 2011
@@ -25,12 +25,14 @@ import java.io.IOException;
 import java.net.Socket;
 import java.net.UnknownHostException;
 
+import org.apache.cassandra.CleanupHelper;
 import org.apache.cassandra.SchemaLoader;
 import org.apache.cassandra.config.CFMetaData;
 import org.apache.cassandra.config.ConfigurationException;
 import org.apache.cassandra.config.DatabaseDescriptor;
 import org.apache.cassandra.config.KSMetaData;
 import org.apache.cassandra.service.EmbeddedCassandraService;
+import org.junit.BeforeClass;
 
 /**
  * The abstract BaseClass.
@@ -41,13 +43,19 @@ public abstract class EmbeddedServiceBas
     /** The embedded server cassandra. */
     private static EmbeddedCassandraService cassandra;
     
+    @BeforeClass 
+    public static void cleanUpOldStuff() throws IOException
+    {
+        CleanupHelper.cleanupAndLeaveDirs();
+    }
+    
     /**
      * Start cassandra server.
      * @throws ConfigurationException 
      *
      * @throws Exception the exception
      */
-    static void startCassandraServer() throws IOException, ConfigurationException
+    public static void startCassandraServer() throws IOException, ConfigurationException
     {
         if (!checkIfServerRunning())
         {

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=1086965&r1=1086964&r2=1086965&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 Wed Mar 30 14:30:43 2011
@@ -244,16 +244,25 @@ public class JdbcDriverTest extends Embe
                     ByteBuffer.class.getName(), Types.BINARY, BytesType.class.getSimpleName(), false, false);
     }
     
-    /** Method to test statement. */
     @Test
-    public void testWithStatement() throws SQLException
+    public void testWithStatementBytesType() throws SQLException
     {
         Statement stmt = con.createStatement();
         
         String selectQ = String.format("SELECT '%s', '%s' FROM Standard1 WHERE KEY='%s'", first, last, jsmith);
         checkResultSet(stmt.executeQuery(selectQ), "Bytes", 1, first, last);
         
-        selectQ = "SELECT 1, 2 FROM JdbcInteger WHERE KEY='" + jsmith + "'";
+        selectQ = String.format("SELECT '%s', '%s' FROM JdbcBytes WHERE KEY='%s'", first, last, jsmith);
+        checkResultSet(stmt.executeQuery(selectQ), "Bytes", 1, first, last);
+    }
+    
+    /** Method to test statement. */
+    @Test
+    public void testWithStatement() throws SQLException
+    {
+        Statement stmt = con.createStatement();
+        
+        String selectQ = "SELECT 1, 2 FROM JdbcInteger WHERE KEY='" + jsmith + "'";
         checkResultSet(stmt.executeQuery(selectQ), "Int", 1, "1", "2");
         
         selectQ = "SELECT 3, 4 FROM JdbcInteger WHERE KEY='" + jsmith + "'";
@@ -274,6 +283,16 @@ public class JdbcDriverTest extends Embe
         selectQ = "SELECT 'first', 'last' FROM JdbcUtf8 WHERE KEY='" + jsmith + "'";
         checkResultSet(stmt.executeQuery(selectQ), "String", 1, "first", "last");
     }
+    
+    @Test
+    public void testWithPreparedStatementBytesType() throws SQLException
+    {
+        String selectQ = String.format("SELECT '%s', '%s' FROM Standard1 WHERE KEY='%s'", first, last, jsmith);
+        checkResultSet(executePreparedStatementWithResults(con, selectQ), "Bytes", 1, first, last);
+        
+        selectQ = String.format("SELECT '%s', '%s' FROM JdbcBytes WHERE KEY='%s'", first, last, jsmith);
+        checkResultSet(executePreparedStatementWithResults(con, selectQ), "Bytes", 1, first, last);
+    }
 
    /** Method to test with prepared statement.*/
    @Test
@@ -385,8 +404,10 @@ public class JdbcDriverTest extends Embe
         }
         
         // Cleanup backup links
-        for (String fname : new File("build/test/cassandra/data/Keyspace1/backups").list())
-            new File("build/test/cassandra/data/Keyspace1/backups" + File.separator + fname).delete();
+        File backups = new File("build/test/cassandra/data/Keyspace1/backups");
+        if (backups.exists())
+            for (String fname : backups.list())
+                new File("build/test/cassandra/data/Keyspace1/backups" + File.separator + fname).delete();
     }
     
     // todo: check expected values as well.

Added: cassandra/trunk/drivers/java/test/org/apache/cassandra/cql/jdbc/PreparedStatementTest.java
URL: http://svn.apache.org/viewvc/cassandra/trunk/drivers/java/test/org/apache/cassandra/cql/jdbc/PreparedStatementTest.java?rev=1086965&view=auto
==============================================================================
--- cassandra/trunk/drivers/java/test/org/apache/cassandra/cql/jdbc/PreparedStatementTest.java (added)
+++ cassandra/trunk/drivers/java/test/org/apache/cassandra/cql/jdbc/PreparedStatementTest.java Wed Mar 30 14:30:43 2011
@@ -0,0 +1,346 @@
+package org.apache.cassandra.cql.jdbc;
+
+import org.apache.cassandra.cql.EmbeddedServiceBase;
+import org.apache.cassandra.utils.FBUtilities;
+import org.junit.BeforeClass;
+import org.junit.Test;
+
+import java.sql.DriverManager;
+import java.sql.PreparedStatement;
+import java.sql.ResultSet;
+import java.sql.SQLException;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+
+
+public class PreparedStatementTest extends EmbeddedServiceBase
+{ 
+    private static java.sql.Connection con = null;
+    
+    @BeforeClass
+    public static void waxOn() throws Exception
+    {
+        startCassandraServer();
+        Class.forName("org.apache.cassandra.cql.jdbc.CassandraDriver");
+        con = DriverManager.getConnection("jdbc:cassandra:root/root@localhost:9170/Keyspace1");
+    }
+    
+    @Test
+    public void testBytes() throws SQLException
+    {
+        // insert
+        PreparedStatement stmt = con.prepareStatement("update JdbcBytes set ?=?, ?=? where key=?");
+        for (int i = 0; i < 5; i++)
+        {
+            byte[] key = Integer.toString(i).getBytes();
+            stmt.setBytes(1, FBUtilities.toByteArray(i));
+            stmt.setBytes(2, FBUtilities.toByteArray((i+1)*10));
+            stmt.setBytes(3, FBUtilities.toByteArray(i+100));
+            stmt.setBytes(4, FBUtilities.toByteArray((i+1)*10+1));
+            stmt.setBytes(5, key);
+            stmt.executeUpdate();
+        }
+        
+        // verify
+        stmt = con.prepareStatement("select ?, ? from JdbcBytes where key=?");
+        for (int i = 0; i < 5; i++)
+        {
+            byte[] key = Integer.toString(i).getBytes();
+            stmt.setBytes(1, FBUtilities.toByteArray(i));
+            stmt.setBytes(2, FBUtilities.toByteArray(i+100));
+            stmt.setBytes(3, key);
+            ResultSet rs = stmt.executeQuery();
+            assert rs.next();
+            assert Arrays.equals(rs.getBytes(FBUtilities.bytesToHex(FBUtilities.toByteArray(i))), FBUtilities.toByteArray((i+1)*10));
+            assert Arrays.equals(rs.getBytes(FBUtilities.bytesToHex(FBUtilities.toByteArray(i+100))), FBUtilities.toByteArray((i+1)*10+1));
+            assert !rs.next();
+            rs.close();
+        }
+        
+        // delete
+        stmt = con.prepareStatement("delete ?, ? from JdbcBytes where key=?");
+        for (int i = 0; i < 5; i++)
+        {
+            byte[] key = Integer.toString(i).getBytes();
+            stmt.setBytes(1, FBUtilities.toByteArray(i));
+            stmt.setBytes(2, FBUtilities.toByteArray(i+100));
+            stmt.setBytes(3, key);
+            stmt.execute();
+        }
+        
+        // verify
+        stmt = con.prepareStatement("select ?, ? from JdbcBytes where key=?");
+        for (int i = 0; i < 5; i++)
+        {
+            byte[] key = Integer.toString(i).getBytes();
+            stmt.setBytes(1, FBUtilities.toByteArray(i));
+            stmt.setBytes(2, FBUtilities.toByteArray(i+100));
+            stmt.setBytes(3, key);
+            ResultSet rs = stmt.executeQuery();
+            assert !rs.next();
+            rs.close();
+        }
+    }
+    
+    @Test
+    public void testUtf8() throws SQLException
+    {
+        // insert.
+        PreparedStatement stmt = con.prepareStatement("update JdbcUtf8 set ?=?, ?=? where key = ?");
+        for (int i = 0; i < 5; i++)
+        {
+            byte[] key = Integer.toString(i).getBytes();
+            stmt.setString(1, "1\u6543\u3435\u6554");
+            stmt.setString(2, "abc\u6543\u3435\u6554");
+            stmt.setString(3, "2\u6543\u3435\u6554");
+            stmt.setString(4, "def\u6543\u3435\u6554");
+            stmt.setBytes(5, key);
+            stmt.executeUpdate();
+        }
+        
+        // verify
+        stmt = con.prepareStatement("select ?, ? from JdbcUtf8 where key=?");
+        for (int i = 0; i < 5; i++)
+        {
+            byte[] key = Integer.toString(i).getBytes();
+            stmt.setString(1, "1\u6543\u3435\u6554");
+            stmt.setString(2, "2\u6543\u3435\u6554");
+            stmt.setBytes(3, key);
+            ResultSet rs = stmt.executeQuery();
+            assert rs.next();
+            assert rs.getString("1\u6543\u3435\u6554").equals("abc\u6543\u3435\u6554");
+            assert rs.getString("2\u6543\u3435\u6554").equals("def\u6543\u3435\u6554");
+            assert !rs.next();
+            rs.close();
+        }
+        
+        // delete
+        stmt = con.prepareStatement("delete ?, ? from JdbcUtf8 where key=?");
+        for (int i = 0; i < 5; i++)
+        {
+            byte[] key = Integer.toString(i).getBytes();
+            stmt.setString(1, "1\u6543\u3435\u6554");
+            stmt.setString(2, "2\u6543\u3435\u6554");
+            stmt.setBytes(3, key);
+            stmt.execute();
+        }
+        
+        // verify
+        stmt = con.prepareStatement("select ?, ? from JdbcUtf8 where key=?");
+        for (int i = 0; i < 5; i++)
+        {
+            byte[] key = Integer.toString(i).getBytes();
+            stmt.setString(1, "1\u6543\u3435\u6554");
+            stmt.setString(2, "2\u6543\u3435\u6554");
+            stmt.setBytes(3, key);
+            ResultSet rs = stmt.executeQuery();
+            assert !rs.next();
+            rs.close();
+        }
+    }
+    
+    @Test
+    public void testAscii() throws SQLException
+    {
+        // insert.
+        PreparedStatement stmt = con.prepareStatement("update JdbcAscii set ?=?, ?=? where key = ?");
+        for (int i = 0; i < 5; i++)
+        {
+            byte[] key = Integer.toString(i).getBytes();
+            stmt.setString(1, "1");
+            stmt.setString(2, "abc");
+            stmt.setString(3, "2");
+            stmt.setString(4, "def");
+            stmt.setBytes(5, key);
+            stmt.executeUpdate();
+        }
+        
+        // verify
+        stmt = con.prepareStatement("select ?, ? from JdbcAscii where key=?");
+        for (int i = 0; i < 5; i++)
+        {
+            byte[] key = Integer.toString(i).getBytes();
+            stmt.setString(1, "1");
+            stmt.setString(2, "2");
+            stmt.setBytes(3, key);
+            ResultSet rs = stmt.executeQuery();
+            assert rs.next();
+            assert rs.getString("1").equals("abc");
+            assert rs.getString("2").equals("def");
+            assert !rs.next();
+            rs.close();
+        }
+        
+        // delete
+        stmt = con.prepareStatement("delete ?, ? from JdbcAscii where key=?");
+        for (int i = 0; i < 5; i++)
+        {
+            byte[] key = Integer.toString(i).getBytes();
+            stmt.setString(1, "1");
+            stmt.setString(2, "2");
+            stmt.setBytes(3, key);
+            stmt.execute();
+        }
+        
+        // verify
+        stmt = con.prepareStatement("select ?, ? from JdbcAscii where key=?");
+        for (int i = 0; i < 5; i++)
+        {
+            byte[] key = Integer.toString(i).getBytes();
+            stmt.setString(1, "1");
+            stmt.setString(2, "2");
+            stmt.setBytes(3, key);
+            ResultSet rs = stmt.executeQuery();
+            assert !rs.next();
+            rs.close();
+        }
+    }
+    
+    @Test
+    public void testLong() throws SQLException
+    {
+        PreparedStatement stmt = con.prepareStatement("update JdbcLong set ?=?, ?=? where key = ?");
+        for (int i = 0; i < 5; i++)
+        {
+            byte[] key = Integer.toString(i).getBytes();
+            stmt.setLong(1, 1);
+            stmt.setLong(2, (i+1)*10);
+            stmt.setLong(3, 2);
+            stmt.setLong(4, (i+1)*10+1);
+            stmt.setBytes(5, key);
+            stmt.executeUpdate();
+        }
+        stmt.close();
+        
+        // verify.
+        stmt = con.prepareStatement("select ?, ? from JdbcLong where key = ?");
+        for (int i = 0; i < 5; i++)
+        {
+            byte[] key = Integer.toString(i).getBytes();
+            stmt.setLong(1, 1);
+            stmt.setLong(2, 2);
+            stmt.setBytes(3, key);
+            ResultSet rs = stmt.executeQuery();
+            assert rs.next();
+            assert rs.getLong("1") == (i+1)*10;
+            assert rs.getLong("2") == (i+1)*10+1;
+            assert !rs.next();
+            rs.close();
+        }
+        
+        // delete
+        stmt = con.prepareStatement("delete ?, ? from JdbcLong where key = ?");
+        for (int i = 0; i < 5; i++)
+        {
+            byte[] key = Integer.toString(i).getBytes();
+            stmt.setLong(1, 1);
+            stmt.setLong(2, 2);
+            stmt.setBytes(3, key);
+            stmt.execute();
+        }
+        
+        // verify.
+        stmt = con.prepareStatement("select ?, ? from JdbcLong where key = ?");
+        for (int i = 0; i < 5; i++)
+        {
+            byte[] key = Integer.toString(i).getBytes();
+            stmt.setLong(1, 1);
+            stmt.setLong(2, 2);
+            stmt.setBytes(3, key);
+            ResultSet rs = stmt.executeQuery();
+            assert !rs.next();
+            rs.close();
+        }
+    }
+    
+    @Test
+    public void testInteger() throws SQLException
+    {
+        PreparedStatement stmt = con.prepareStatement("update JdbcInteger set ?=?, ?=? where key = ?");
+        for (int i = 0; i < 5; i++)
+        {
+            byte[] key = Integer.toString(i).getBytes();
+            stmt.setInt(1, 1);
+            stmt.setInt(2, (i+1)*10);
+            stmt.setInt(3, 2);
+            stmt.setInt(4, (i+1)*10+1);
+            stmt.setBytes(5, key);
+            stmt.executeUpdate();
+        }
+        stmt.close();
+        
+        // verify.
+        stmt = con.prepareStatement("select ?, ? from JdbcInteger where key = ?");
+        for (int i = 0; i < 5; i++)
+        {
+            byte[] key = Integer.toString(i).getBytes();
+            stmt.setInt(1, 1);
+            stmt.setInt(2, 2);
+            stmt.setBytes(3, key);
+            ResultSet rs = stmt.executeQuery();
+            assert rs.next();
+            assert rs.getInt("1") == (i+1)*10;
+            assert rs.getInt("2") == (i+1)*10+1;
+            assert !rs.next();
+            rs.close();
+        }
+        
+        // delete
+        stmt = con.prepareStatement("delete ?, ? from JdbcInteger where key = ?");
+        for (int i = 0; i < 5; i++)
+        {
+            byte[] key = Integer.toString(i).getBytes();
+            stmt.setInt(1, 1);
+            stmt.setInt(2, 2);
+            stmt.setBytes(3, key);
+            stmt.execute();
+        }
+        
+        // verify.
+        stmt = con.prepareStatement("select ?, ? from JdbcInteger where key = ?");
+        for (int i = 0; i < 5; i++)
+        {
+            byte[] key = Integer.toString(i).getBytes();
+            stmt.setInt(1, 1);
+            stmt.setInt(2, 2);
+            stmt.setBytes(3, key);
+            ResultSet rs = stmt.executeQuery();
+            assert !rs.next();
+            rs.close();
+        }
+    }
+    
+    @Test
+    public void testParamSubstitution() throws SQLException
+    {
+        byte[] key = "key".getBytes();
+        String q = "SELECT 'fo??est', ?, ? from JdbcUtf8 WHERE KEY = ?";
+        CassandraPreparedStatement stmt = (CassandraPreparedStatement)con.prepareStatement(q);
+        stmt.setString(1, "pathological param: ?'make it?? '' sto'p?'");
+        stmt.setString(2, "simple");
+        stmt.setBytes(3, key);
+        String qq = stmt.makeCql();
+        assert qq.equals("SELECT 'fo??est', 'pathological param: ?''make it?? '''' sto''p?''', 'simple' from JdbcUtf8 WHERE KEY = '6b6579'");
+        
+        q = "UPDATE JdbcUtf8 USING CONSISTENCY ONE SET 'fru??us'=?, ?='gr''d?', ?=?, ?=? WHERE key=?";
+        stmt = (CassandraPreparedStatement)con.prepareStatement(q);
+        stmt.setString(1, "o?e");
+        stmt.setString(2, "tw'o");
+        stmt.setString(3, "thr'?'ee");
+        stmt.setString(4, "fo''?'ur");
+        stmt.setString(5, "five");
+        stmt.setString(6, "six");
+        stmt.setBytes(7, key);
+        qq = stmt.makeCql();
+        assert qq.equals("UPDATE JdbcUtf8 USING CONSISTENCY ONE SET 'fru??us'='o?e', 'tw''o'='gr''d?', 'thr''?''ee'='fo''''?''ur', 'five'='six' WHERE key='6b6579'");
+        
+        q = "DELETE ?, ? FROM JdbcUtf8 WHERE KEY=?";
+        stmt = (CassandraPreparedStatement)con.prepareStatement(q);
+        stmt.setString(1, "on'?'");
+        stmt.setString(2, "two");
+        stmt.setBytes(3, key);
+        qq = stmt.makeCql();
+        assert qq.equals("DELETE 'on''?''', 'two' FROM JdbcUtf8 WHERE KEY='6b6579'");
+    }
+}



Mime
View raw message