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

svn commit: r1079973 - in /cassandra/trunk/drivers/java: src/org/apache/cassandra/cql/driver/ src/org/apache/cassandra/cql/driver/jdbc/ test/org/apache/cassandra/cql/driver/ test/org/apache/cassandra/cql/driver/jdbc/

Author: gdusbabek
Date: Wed Mar  9 20:22:45 2011
New Revision: 1079973

URL: http://svn.apache.org/viewvc?rev=1079973&view=rev
Log:
first pass at column decoding. patch by gdusbabek, reviewed by eevans. CASSANDRA-2124

Added:
    cassandra/trunk/drivers/java/src/org/apache/cassandra/cql/driver/Col.java
    cassandra/trunk/drivers/java/src/org/apache/cassandra/cql/driver/Results.java
    cassandra/trunk/drivers/java/src/org/apache/cassandra/cql/driver/SchemaDecoder.java
    cassandra/trunk/drivers/java/test/org/apache/cassandra/cql/driver/jdbc/EmbeddedServiceBase.java
      - copied, changed from r1079849, cassandra/trunk/drivers/java/test/org/apache/cassandra/cql/driver/EmbeddedServiceBase.java
Removed:
    cassandra/trunk/drivers/java/test/org/apache/cassandra/cql/driver/EmbeddedServiceBase.java
Modified:
    cassandra/trunk/drivers/java/src/org/apache/cassandra/cql/driver/Connection.java
    cassandra/trunk/drivers/java/src/org/apache/cassandra/cql/driver/jdbc/CassandraResultSet.java
    cassandra/trunk/drivers/java/src/org/apache/cassandra/cql/driver/jdbc/CassandraStatement.java

Added: cassandra/trunk/drivers/java/src/org/apache/cassandra/cql/driver/Col.java
URL: http://svn.apache.org/viewvc/cassandra/trunk/drivers/java/src/org/apache/cassandra/cql/driver/Col.java?rev=1079973&view=auto
==============================================================================
--- cassandra/trunk/drivers/java/src/org/apache/cassandra/cql/driver/Col.java (added)
+++ cassandra/trunk/drivers/java/src/org/apache/cassandra/cql/driver/Col.java Wed Mar  9 20:22:45 2011
@@ -0,0 +1,23 @@
+package org.apache.cassandra.cql.driver;
+
+public class Col<N, V>
+{
+    public final N name;
+    public final V value;
+    
+    public Col(N name, V value)
+    {
+        this.name = name;
+        this.value = value;
+    }
+    
+    public N getName()
+    {
+        return name;
+    }
+    
+    public V getValue()
+    {
+        return value;
+    }
+}

Modified: cassandra/trunk/drivers/java/src/org/apache/cassandra/cql/driver/Connection.java
URL: http://svn.apache.org/viewvc/cassandra/trunk/drivers/java/src/org/apache/cassandra/cql/driver/Connection.java?rev=1079973&r1=1079972&r2=1079973&view=diff
==============================================================================
--- cassandra/trunk/drivers/java/src/org/apache/cassandra/cql/driver/Connection.java (original)
+++ cassandra/trunk/drivers/java/src/org/apache/cassandra/cql/driver/Connection.java Wed Mar  9 20:22:45 2011
@@ -23,6 +23,8 @@ package org.apache.cassandra.cql.driver;
 
 import java.util.HashMap;
 import java.util.Map;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
 
 import org.apache.cassandra.thrift.AuthenticationException;
 import org.apache.cassandra.thrift.AuthenticationRequest;
@@ -46,6 +48,9 @@ import org.slf4j.LoggerFactory;
 /** CQL connection object. */
 public 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);
+    
     public static Compression defaultCompression = Compression.GZIP;
     public final String hostName;
     public final int portNo;
@@ -56,6 +61,11 @@ public class Connection
     private Cassandra.Client client;
     private TTransport transport;
     
+    // todo: encapsulate.
+    public String curKeyspace;
+    public String curColumnFamily;
+    public SchemaDecoder decoder;
+    
     /**
      * Create a new <code>Connection</code> instance.
      * 
@@ -67,7 +77,6 @@ public class Connection
     {
         this.hostName = hostName;
         this.portNo = portNo;
-        
         TSocket socket = new TSocket(hostName, portNo);
         transport = new TFramedTransport(socket);
         TProtocol protocol = new TBinaryProtocol(transport);
@@ -127,6 +136,15 @@ public class Connection
     public CqlResult execute(String queryStr, Compression compress)
     throws InvalidRequestException, UnavailableException, TimedOutException, TException
     {
+        if (decoder == null)
+            decoder = new SchemaDecoder(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);
         try
         {
             return client.execute_cql_query(Utils.compressQuery(queryStr, compress), compress);

Added: cassandra/trunk/drivers/java/src/org/apache/cassandra/cql/driver/Results.java
URL: http://svn.apache.org/viewvc/cassandra/trunk/drivers/java/src/org/apache/cassandra/cql/driver/Results.java?rev=1079973&view=auto
==============================================================================
--- cassandra/trunk/drivers/java/src/org/apache/cassandra/cql/driver/Results.java (added)
+++ cassandra/trunk/drivers/java/src/org/apache/cassandra/cql/driver/Results.java Wed Mar  9 20:22:45 2011
@@ -0,0 +1,21 @@
+package org.apache.cassandra.cql.driver;
+
+
+public class Results
+{
+    private final SchemaDecoder decoder;
+    private final String keyspace;
+    private final String columnFamily;
+    
+    public Results(SchemaDecoder decoder, String keyspace, String columnFamily) 
+    {
+        this.decoder = decoder;
+        this.keyspace = keyspace;
+        this.columnFamily = columnFamily;
+    }
+    
+    public Col makeCol(byte[] name, byte[] value) {
+        return decoder.makeCol(keyspace, columnFamily, name, value);
+    }
+    
+}

Added: cassandra/trunk/drivers/java/src/org/apache/cassandra/cql/driver/SchemaDecoder.java
URL: http://svn.apache.org/viewvc/cassandra/trunk/drivers/java/src/org/apache/cassandra/cql/driver/SchemaDecoder.java?rev=1079973&view=auto
==============================================================================
--- cassandra/trunk/drivers/java/src/org/apache/cassandra/cql/driver/SchemaDecoder.java (added)
+++ cassandra/trunk/drivers/java/src/org/apache/cassandra/cql/driver/SchemaDecoder.java Wed Mar  9 20:22:45 2011
@@ -0,0 +1,110 @@
+package org.apache.cassandra.cql.driver;
+
+import org.apache.cassandra.config.ConfigurationException;
+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.IntegerType;
+import org.apache.cassandra.db.marshal.LexicalUUIDType;
+import org.apache.cassandra.db.marshal.LongType;
+import org.apache.cassandra.db.marshal.TimeUUIDType;
+import org.apache.cassandra.db.marshal.UTF8Type;
+import org.apache.cassandra.thrift.CfDef;
+import org.apache.cassandra.thrift.KsDef;
+import org.apache.cassandra.utils.FBUtilities;
+import org.apache.cassandra.utils.UUIDGen;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.io.UnsupportedEncodingException;
+import java.math.BigInteger;
+import java.nio.ByteBuffer;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+public class SchemaDecoder 
+{
+    private static final Logger logger = LoggerFactory.getLogger(SchemaDecoder.class);
+    private static final String MapFormatString = "%s.%s.%s";
+    
+    enum Specifier
+    {
+        Comparator,
+        Validator
+    }
+    
+    private Map<String, CfDef> cfDefs = new HashMap<String, CfDef>();
+    
+    // cache the comparators for efficiency.
+    private Map<String, AbstractType> comparators = new HashMap<String, AbstractType>();
+    
+    public SchemaDecoder(List<KsDef> defs)
+    {
+        for (KsDef ks : defs) 
+            for (CfDef cf : ks.getCf_defs())
+                cfDefs.put(String.format("%s.%s", ks.getName(), cf.getName()), cf);
+    }
+
+    /**
+     * @param keyspace ALWAYS specify
+     * @param columnFamily ALWAYS specify
+     * @param specifier ALWAYS specify
+     * @param def avoids additional map lookup if specified. null is ok. though.
+     * @return
+     */
+    private AbstractType getComparator(String keyspace, String columnFamily, Specifier specifier, CfDef def) 
+    {
+        // check cache first.
+        String key = String.format(MapFormatString, keyspace, columnFamily, specifier.name());
+        AbstractType comparator = comparators.get(key);
+
+        // make and put in cache.
+        if (comparator == null) 
+        {
+            if (def == null)
+                def = cfDefs.get(String.format("%s.%s", keyspace, columnFamily));
+            try 
+            {
+                switch (specifier)
+                {
+                    case Validator:
+                        comparator = FBUtilities.getComparator(def.getDefault_validation_class());
+                        break;
+                    case Comparator:
+                    default:
+                        comparator = FBUtilities.getComparator(def.getComparator_type());
+                        break;
+                }
+                comparators.put(key, comparator);
+            }
+            catch (ConfigurationException ex)
+            {
+                throw new RuntimeException(ex);
+            }
+        }
+        return comparator;
+    }
+    
+    public String colNameAsString(String keyspace, String columnFamily, String name) 
+    {
+        AbstractType comparator = getComparator(keyspace, columnFamily, Specifier.Comparator, null);
+        ByteBuffer bb = comparator.fromString(name);
+        return comparator.getString(bb);
+    }
+    
+    public String colNameAsString(String keyspace, String columnFamily, byte[] name) 
+    {
+        AbstractType comparator = getComparator(keyspace, columnFamily, Specifier.Comparator, null);
+        return comparator.getString(ByteBuffer.wrap(name));
+    }
+    
+    public Col makeCol(String keyspace, String columnFamily, byte[] name, byte[] value)
+    {
+        CfDef cfDef = cfDefs.get(String.format("%s.%s", keyspace, columnFamily));
+        AbstractType comparator = getComparator(keyspace, columnFamily, Specifier.Comparator, cfDef);
+        AbstractType validator = getComparator(keyspace, columnFamily, Specifier.Validator, null);
+        // todo: generate less garbage.
+        return new Col(comparator.compose(ByteBuffer.wrap(name)), validator.compose(ByteBuffer.wrap(value)));
+    }
+}

Modified: cassandra/trunk/drivers/java/src/org/apache/cassandra/cql/driver/jdbc/CassandraResultSet.java
URL: http://svn.apache.org/viewvc/cassandra/trunk/drivers/java/src/org/apache/cassandra/cql/driver/jdbc/CassandraResultSet.java?rev=1079973&r1=1079972&r2=1079973&view=diff
==============================================================================
--- cassandra/trunk/drivers/java/src/org/apache/cassandra/cql/driver/jdbc/CassandraResultSet.java (original)
+++ cassandra/trunk/drivers/java/src/org/apache/cassandra/cql/driver/jdbc/CassandraResultSet.java Wed Mar  9 20:22:45 2011
@@ -45,6 +45,10 @@ import java.util.Iterator;
 import java.util.List;
 import java.util.Map;
 import java.util.WeakHashMap;
+
+import org.apache.cassandra.cql.driver.Col;
+import org.apache.cassandra.cql.driver.Results;
+import org.apache.cassandra.cql.driver.SchemaDecoder;
 import org.apache.cassandra.thrift.Column;
 import org.apache.cassandra.thrift.CqlResult;
 import org.apache.cassandra.thrift.CqlRow;
@@ -56,16 +60,20 @@ class CassandraResultSet implements Resu
 {
     
     /** The r set. */
-    private CqlResult rSet;
+    private final CqlResult rSet; 
+    
+    private final SchemaDecoder decoder;
+    private final String keyspace;
+    private final String columnFamily;
     
     /** The r set iter. */
     private Iterator<CqlRow> rSetIter;
     
-    /** The row. */
-    private CqlRow row;
+//    /** The row. */
+//    private CqlRow row;
     
     /** The values. */
-    private List<Object> values = new ArrayList<Object>();
+    private List<Col> values = new ArrayList<Col>();
     
     /** The value map. */
     private Map<String, Object> valueMap = new WeakHashMap<String, Object>();
@@ -75,9 +83,12 @@ class CassandraResultSet implements Resu
      *
      * @param resultSet the result set
      */
-    CassandraResultSet(CqlResult resultSet)
+    CassandraResultSet(CqlResult resultSet, SchemaDecoder decoder, String keyspace, String columnFamily)
     {
         this.rSet = resultSet;
+        this.decoder = decoder;
+        this.keyspace = keyspace;
+        this.columnFamily = columnFamily;
         rSetIter = rSet.getRowsIterator();
     }
 
@@ -787,7 +798,7 @@ class CassandraResultSet implements Resu
      */
     public String getString(int index) throws SQLException 
     {
-        return values.get(index) != null ? values.get(index).toString() : null;
+        return values.get(index) != null ? values.get(index).getValue().toString() : null;
     }
 
     /**
@@ -797,7 +808,8 @@ class CassandraResultSet implements Resu
      */
     public String getString(String name) throws SQLException
     {
-        return valueMap.get(name) != null ? valueMap.get(name).toString() : null;
+        String nameAsString = this.decoder.colNameAsString(this.keyspace, this.columnFamily, name);
+        return valueMap.get(nameAsString) != null ? valueMap.get(nameAsString).toString() : null;
     }
 
     /**
@@ -1033,14 +1045,15 @@ class CassandraResultSet implements Resu
         }
         if (rSetIter != null && rSetIter.hasNext())
         {
-            row = rSetIter.next();
+            CqlRow row = rSetIter.next();
             List<Column> cols = row.getColumns();
             for (Column col : cols)
             {
-                String name = new String(col.getName());
-                String value = new String(col.getValue());
-                values.add(value);
-                valueMap.put(name, value);
+                byte[] name = col.getName();
+                byte[] value = col.getValue();
+                Col c = decoder.makeCol(keyspace, columnFamily, name, value);
+                values.add(c);
+                valueMap.put(decoder.colNameAsString(keyspace, columnFamily, name), c.getValue());
             }
             return !(values.isEmpty() && valueMap.isEmpty());
         } 

Modified: cassandra/trunk/drivers/java/src/org/apache/cassandra/cql/driver/jdbc/CassandraStatement.java
URL: http://svn.apache.org/viewvc/cassandra/trunk/drivers/java/src/org/apache/cassandra/cql/driver/jdbc/CassandraStatement.java?rev=1079973&r1=1079972&r2=1079973&view=diff
==============================================================================
--- cassandra/trunk/drivers/java/src/org/apache/cassandra/cql/driver/jdbc/CassandraStatement.java (original)
+++ cassandra/trunk/drivers/java/src/org/apache/cassandra/cql/driver/jdbc/CassandraStatement.java Wed Mar  9 20:22:45 2011
@@ -43,6 +43,7 @@ import java.sql.Time;
 import java.sql.Timestamp;
 import java.util.Calendar;
 
+import org.apache.cassandra.cql.driver.Results;
 import org.apache.cassandra.thrift.CqlResult;
 import org.apache.cassandra.thrift.InvalidRequestException;
 import org.apache.cassandra.thrift.TimedOutException;
@@ -243,7 +244,8 @@ class CassandraStatement implements Prep
         try
         {
             CqlResult rSet = connection.execute(query);
-            return new CassandraResultSet(rSet);
+            // todo: encapsulate.
+            return new CassandraResultSet(rSet, connection.decoder, connection.curKeyspace, connection.curColumnFamily);
         }
         catch (InvalidRequestException e)
         {

Copied: cassandra/trunk/drivers/java/test/org/apache/cassandra/cql/driver/jdbc/EmbeddedServiceBase.java (from r1079849, cassandra/trunk/drivers/java/test/org/apache/cassandra/cql/driver/EmbeddedServiceBase.java)
URL: http://svn.apache.org/viewvc/cassandra/trunk/drivers/java/test/org/apache/cassandra/cql/driver/jdbc/EmbeddedServiceBase.java?p2=cassandra/trunk/drivers/java/test/org/apache/cassandra/cql/driver/jdbc/EmbeddedServiceBase.java&p1=cassandra/trunk/drivers/java/test/org/apache/cassandra/cql/driver/EmbeddedServiceBase.java&r1=1079849&r2=1079973&rev=1079973&view=diff
==============================================================================
    (empty)