You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@cassandra.apache.org by ca...@codespot.com on 2012/08/20 01:52:46 UTC

[cassandra-dbapi2] 2 new revisions pushed by pcannon@gmail.com on 2012-08-19 23:52 GMT

2 new revisions:

Revision: 602d5138da97
Author:   paul cannon <pa...@datastax.com>
Date:     Sun Aug 19 15:13:16 2012
Log:      fix generation of unknown casstype objects...
http://code.google.com/a/apache-extras.org/p/cassandra-dbapi2/source/detail?r=602d5138da97

Revision: 1ac7beb124c7
Author:   paul cannon <pa...@datastax.com>
Date:     Sun Aug 19 16:50:44 2012
Log:      better support for more complex casstype strings...
http://code.google.com/a/apache-extras.org/p/cassandra-dbapi2/source/detail?r=1ac7beb124c7

==============================================================================
Revision: 602d5138da97
Author:   paul cannon <pa...@datastax.com>
Date:     Sun Aug 19 15:13:16 2012
Log:      fix generation of unknown casstype objects

since class names have to be bytes, not unicode

http://code.google.com/a/apache-extras.org/p/cassandra-dbapi2/source/detail?r=602d5138da97

Modified:
  /cql/cqltypes.py

=======================================
--- /cql/cqltypes.py	Sun Aug 19 14:09:48 2012
+++ /cql/cqltypes.py	Sun Aug 19 15:13:16 2012
@@ -136,7 +136,7 @@
          if cls.num_subtypes != 'UNKNOWN' and len(subtypes) !=  
cls.num_subtypes:
              raise ValueError("%s types require %d subtypes (%d given)"
                               % (cls.typename, cls.num_subtypes,  
len(subtypes)))
-        newname = cls.cass_parameterized_type_with(subtypes)
+        newname = cls.cass_parameterized_type_with(subtypes).encode('utf8')
          return type(newname, (cls,), {'subtypes': subtypes, 'cassname':  
cls.cassname})

      @classmethod
@@ -157,7 +157,7 @@
      num_subtypes = 'UNKNOWN'

  def mkUnrecognizedType(casstypename):
-    return CassandraTypeType(casstypename,
+    return CassandraTypeType(casstypename.encode('utf8'),
                               (_UnrecognizedType,),
                               {'typename': "'%s'" % casstypename})


==============================================================================
Revision: 1ac7beb124c7
Author:   paul cannon <pa...@datastax.com>
Date:     Sun Aug 19 16:50:44 2012
Log:      better support for more complex casstype strings

such as "CompositeType" and "ColumnToCollectionType". it looks like yes,
this driver does need to be able to parse arbitrarily complex type
strings, so add parsing.

http://code.google.com/a/apache-extras.org/p/cassandra-dbapi2/source/detail?r=1ac7beb124c7

Modified:
  /cql/cqltypes.py

=======================================
--- /cql/cqltypes.py	Sun Aug 19 15:13:16 2012
+++ /cql/cqltypes.py	Sun Aug 19 16:50:44 2012
@@ -22,6 +22,7 @@
  from decimal import Decimal
  import time
  import calendar
+import re

  try:
      from cStringIO import StringIO
@@ -50,23 +51,50 @@
              _cqltypes[cls.typename] = cls
          return cls

-def lookup_casstype(casstype):
-    args = ()
+casstype_scanner = re.Scanner((
+    (r'[()]', lambda s,t: t),
+    (r'[a-zA-Z0-9_.:]+', lambda s,t: t),
+    (r'[\s,]', None),
+))
+
+def lookup_casstype_simple(casstype):
      shortname = trim_if_startswith(casstype, apache_cassandra_type_prefix)
-    if '(' in shortname:
-        # do we need to support arbitrary nesting? if so, this is where
-        # we need to tokenize and parse
-        assert shortname.endswith(')'), shortname
-        shortname, args = shortname[:-1].split('(', 1)
-        args = [lookup_casstype(s.strip()) for s in args.split(',')]
      try:
          typeclass = _casstypes[shortname]
      except KeyError:
          typeclass = mkUnrecognizedType(casstype)
-    if args:
-        typeclass = typeclass.apply_parameters(*args)
      return typeclass

+def parse_casstype_args(typestring):
+    tokens, remainder = casstype_scanner.scan(typestring)
+    if remainder:
+        raise ValueError("weird characters %r at end" % remainder)
+    args = [[]]
+    for tok in tokens:
+        if tok == '(':
+            args.append([])
+        elif tok == ')':
+            arglist = args.pop()
+            ctype = args[-1].pop()
+            paramized = ctype.apply_parameters(*arglist)
+            args[-1].append(paramized)
+        else:
+            if ':' in tok:
+                # ignore those column name hex encoding bit; we have the
+                # proper column name from elsewhere
+                tok = tok.rsplit(':', 1)[-1]
+            ctype = lookup_casstype_simple(tok)
+            args[-1].append(ctype)
+    assert len(args) == 1, args
+    assert len(args[0]) == 1, args[0]
+    return args[0][0]
+
+def lookup_casstype(casstype):
+    try:
+        return parse_casstype_args(casstype)
+    except (ValueError, AssertionError, IndexError), e:
+        raise ValueError("Don't know how to parse type string %r: %s" %  
(casstype, e))
+
  def lookup_cqltype(cqltype):
      args = ()
      if cqltype.startswith("'") and cqltype.endswith("'"):
@@ -439,10 +467,18 @@
              buf.write(valbytes)
          return buf.getvalue()

+class CompositeType(_ParameterizedType):
+    typename = "'org.apache.cassandra.db.marshal.CompositeType'"
+    num_subtypes = 'UNKNOWN'
+
+class ColumnToCollectionType(_ParameterizedType):
+    typename = "'org.apache.cassandra.db.marshal.ColumnToCollectionType'"
+    num_subtypes = 1
+
  def is_counter_type(t):
      if isinstance(t, basestring):
          t = lookup_casstype(t)
-    return t.typename == 'counter'
+    return issubclass(t, CounterColumnType)

  cql_type_to_apache_class = dict([(c, t.cassname) for (c, t) in  
_cqltypes.items()])
  apache_class_to_cql_type = dict([(n, t.typename) for (n, t) in  
_casstypes.items()])