4 new revisions:
Revision: fe2e2825021f
Author: paul cannon <p...@riptano.com>
Date: Mon Nov 7 12:27:00 2011
Log: put correct type in row descriptions...
http://code.google.com/a/apache-extras.org/p/cassandra-dbapi2/source/detail?r=fe2e2825021f
Revision: 20e9cdd17004
Author: paul cannon <p...@riptano.com>
Date: Mon Nov 7 12:30:25 2011
Log: catch ImportError when importing uuid...
http://code.google.com/a/apache-extras.org/p/cassandra-dbapi2/source/detail?r=20e9cdd17004
Revision: 711bcee73e29
Author: paul cannon <p...@riptano.com>
Date: Mon Nov 7 12:32:03 2011
Log: unmarshal boolean, date, decimal, float, & double
http://code.google.com/a/apache-extras.org/p/cassandra-dbapi2/source/detail?r=711bcee73e29
Revision: fa6011c86af9
Author: paul cannon <p...@riptano.com>
Date: Mon Nov 7 12:32:57 2011
Log: add unmarshalling tests for all types
http://code.google.com/a/apache-extras.org/p/cassandra-dbapi2/source/detail?r=fa6011c86af9
==============================================================================
Revision: fe2e2825021f
Author: paul cannon <p...@riptano.com>
Date: Mon Nov 7 12:27:00 2011
Log: put correct type in row descriptions
the type shown in a row description should be the type of the
corresponding data, not the type of the column name.
also, don't look up unmarshaller twice when decoding values.
http://code.google.com/a/apache-extras.org/p/cassandra-dbapi2/source/detail?r=fe2e2825021f
Modified:
/cql/decoders.py
=======================================
--- /cql/decoders.py Tue Sep 6 09:21:29 2011
+++ /cql/decoders.py Mon Nov 7 12:27:00 2011
@@ -32,7 +32,8 @@
name = column.name
comparator = schema.name_types.get(name,
schema.default_name_type)
unmarshal = unmarshallers.get(comparator, unmarshal_noop)
- description.append((unmarshal(name), comparator, None, None,
None, None, True))
+ validator = schema.value_types.get(name,
schema.default_value_type)
+ description.append((unmarshal(name), validator, None, None,
None, None, True))
return description
def decode_row(self, row):
@@ -46,6 +47,6 @@
name = column.name
validator = schema.value_types.get(name,
schema.default_value_type)
unmarshal = unmarshallers.get(validator, unmarshal_noop)
- values.append(unmarshallers.get(validator,
unmarshal_noop)(column.value))
+ values.append(unmarshal(column.value))
return values
==============================================================================
Revision: 20e9cdd17004
Author: paul cannon <p...@riptano.com>
Date: Mon Nov 7 12:30:25 2011
Log: catch ImportError when importing uuid
since python2.4 doesn't have it, and the rest of this code looks like
it's meant to support python2.4.
http://code.google.com/a/apache-extras.org/p/cassandra-dbapi2/source/detail?r=20e9cdd17004
Modified:
/cql/marshal.py
=======================================
--- /cql/marshal.py Fri Sep 9 10:07:55 2011
+++ /cql/marshal.py Mon Nov 7 12:30:25 2011
@@ -17,7 +17,7 @@
import re
import struct
-from uuid import UUID
+from decimal import Decimal
import cql
@@ -30,6 +30,13 @@
else:
_have_struct = False
+try:
+ from uuid import UUID # new in Python 2.5
+except ImportError:
+ class UUID:
+ def __init__(self, bytes):
+ self.bytes = bytes
+
_param_re =
re.compile(r"(?<!strategy_options)(?<!\\)(:[a-zA-Z_][a-zA-Z0-9_]*)", re.M)
BYTES_TYPE = "org.apache.cassandra.db.marshal.BytesType"
==============================================================================
Revision: 711bcee73e29
Author: paul cannon <p...@riptano.com>
Date: Mon Nov 7 12:32:03 2011
Log: unmarshal boolean, date, decimal, float, & double
http://code.google.com/a/apache-extras.org/p/cassandra-dbapi2/source/detail?r=711bcee73e29
Modified:
/cql/marshal.py
=======================================
--- /cql/marshal.py Mon Nov 7 12:30:25 2011
+++ /cql/marshal.py Mon Nov 7 12:32:03 2011
@@ -27,6 +27,8 @@
_have_struct = True
_long_packer = struct.Struct('>q')
_int32_packer = struct.Struct('>i')
+ _float_packer = struct.Struct('>f')
+ _double_packer = struct.Struct('>d')
else:
_have_struct = False
@@ -41,10 +43,15 @@
BYTES_TYPE = "org.apache.cassandra.db.marshal.BytesType"
ASCII_TYPE = "org.apache.cassandra.db.marshal.AsciiType"
+BOOLEAN_TYPE = "org.apache.cassandra.db.marshal.BooleanType"
+DATE_TYPE = "org.apache.cassandra.db.marshal.DateType"
+DECIMAL_TYPE = "org.apache.cassandra.db.marshal.DecimalType"
UTF8_TYPE = "org.apache.cassandra.db.marshal.UTF8Type"
INT32_TYPE = "org.apache.cassandra.db.marshal.Int32Type"
INTEGER_TYPE = "org.apache.cassandra.db.marshal.IntegerType"
LONG_TYPE = "org.apache.cassandra.db.marshal.LongType"
+FLOAT_TYPE = "org.apache.cassandra.db.marshal.FloatType"
+DOUBLE_TYPE = "org.apache.cassandra.db.marshal.DoubleType"
UUID_TYPE = "org.apache.cassandra.db.marshal.UUIDType"
LEXICAL_UUID_TYPE = "org.apache.cassandra.db.marshal.LexicalType"
TIME_UUID_TYPE = "org.apache.cassandra.db.marshal.TimeUUIDType"
@@ -70,35 +77,91 @@
def unmarshal_noop(bytestr):
return bytestr
+def unmarshal_bool(bytestr):
+ if not bytestr:
+ return None
+ return bool(ord(bytestr[0]))
+
def unmarshal_utf8(bytestr):
return bytestr.decode("utf8")
if _have_struct:
def unmarshal_int32(bytestr):
+ if not bytestr:
+ return None
return _int32_packer.unpack(bytestr)[0]
else:
def unmarshal_int32(bytestr):
+ if not bytestr:
+ return None
return struct.unpack(">i", bytestr)[0]
def unmarshal_int(bytestr):
+ if not bytestr:
+ return None
return decode_bigint(bytestr)
if _have_struct:
def unmarshal_long(bytestr):
+ if not bytestr:
+ return None
return _long_packer.unpack(bytestr)[0]
else:
def unmarshal_long(bytestr):
+ if not bytestr:
+ return None
return struct.unpack(">q", bytestr)[0]
+if _have_struct:
+ def unmarshal_float(bytestr):
+ if not bytestr:
+ return None
+ return _float_packer.unpack(bytestr)[0]
+else:
+ def unmarshal_long(bytestr):
+ if not bytestr:
+ return None
+ return struct.unpack(">f", bytestr)[0]
+
+if _have_struct:
+ def unmarshal_double(bytestr):
+ if not bytestr:
+ return None
+ return _double_packer.unpack(bytestr)[0]
+else:
+ def unmarshal_long(bytestr):
+ if not bytestr:
+ return None
+ return struct.unpack(">d", bytestr)[0]
+
+def unmarshal_date(bytestr):
+ if not bytestr:
+ return None
+ return unmarshal_long(bytestr) / 1000.0
+
+def unmarshal_decimal(bytestr):
+ if not bytestr:
+ return None
+ scale = unmarshal_int32(bytestr[:4])
+ unscaled = decode_bigint(bytestr[4:])
+ return Decimal('%de%d' % (unscaled, -scale))
+
def unmarshal_uuid(bytestr):
+ if not bytestr:
+ return None
return UUID(bytes=bytestr)
unmarshallers = {BYTES_TYPE: unmarshal_noop,
ASCII_TYPE: unmarshal_noop,
+ BOOLEAN_TYPE: unmarshal_bool,
+ DATE_TYPE: unmarshal_date,
+ DECIMAL_TYPE: unmarshal_decimal,
UTF8_TYPE: unmarshal_utf8,
INT32_TYPE: unmarshal_int32,
INTEGER_TYPE: unmarshal_int,
LONG_TYPE: unmarshal_long,
+ FLOAT_TYPE: unmarshal_float,
+ DOUBLE_TYPE: unmarshal_double,
UUID_TYPE: unmarshal_uuid,
LEXICAL_UUID_TYPE: unmarshal_uuid,
TIME_UUID_TYPE: unmarshal_uuid,
==============================================================================
Revision: fa6011c86af9
Author: paul cannon <p...@riptano.com>
Date: Mon Nov 7 12:32:57 2011
Log: add unmarshalling tests for all types
http://code.google.com/a/apache-extras.org/p/cassandra-dbapi2/source/detail?r=fa6011c86af9
Added:
/test/test_unmarshalling.py
=======================================
--- /dev/null
+++ /test/test_unmarshalling.py Mon Nov 7 12:32:57 2011
@@ -0,0 +1,77 @@
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+import unittest
+from decimal import Decimal
+from uuid import UUID
+import cql
+from cql.marshal import unmarshallers, unmarshal_noop
+
+demarshal_me = (
+ ('lorem ipsum dolor sit amet', 'AsciiType', 'lorem ipsum dolor sit
amet'),
+ ('', 'AsciiType', ''),
+ ('\x01', 'BooleanType', True),
+ ('\x00', 'BooleanType', False),
+ ('', 'BooleanType', None),
+ ('\xff\xfe\xfd\xfc\xfb', 'BytesType', '\xff\xfe\xfd\xfc\xfb'),
+ ('', 'BytesType', ''),
+ ('\x7f\xff\xff\xff\xff\xff\xff\xff', 'CounterColumnType',
9223372036854775807),
+ ('\x80\x00\x00\x00\x00\x00\x00\x00', 'CounterColumnType',
-9223372036854775808),
+ ('', 'CounterColumnType', None),
+ ('\x00\x00\x013\x7fb\xeey', 'DateType', 1320692149.881),
+ ('', 'DateType', None),
+ ('\x00\x00\x00\r\nJ\x04"^\x91\x04\x8a\xb1\x18\xfe', 'DecimalType',
Decimal('1243878957943.1234124191998')),
+ ('\x00\x00\x00\x06\xe5\xde]\x98Y', 'DecimalType',
Decimal('-112233.441191')),
+ ('\x00\x00\x00\x14\x00\xfa\xce', 'DecimalType',
Decimal('0.00000000000000064206')),
+ ('\x00\x00\x00\x14\xff\x052', 'DecimalType',
Decimal('-0.00000000000000064206')),
+ ('\xff\xff\xff\x9c\x00\xfa\xce', 'DecimalType', Decimal('64206e100')),
+ ('', 'DecimalType', None),
+ ('@\xd2\xfa\x08\x00\x00\x00\x00', 'DoubleType', 19432.125),
+ ('\xc0\xd2\xfa\x08\x00\x00\x00\x00', 'DoubleType', -19432.125),
+ ('\x7f\xef\x00\x00\x00\x00\x00\x00', 'DoubleType',
1.7415152243978685e+308),
+ ('', 'DoubleType', None),
+ ('F\x97\xd0@', 'FloatType', 19432.125),
+ ('\xc6\x97\xd0@', 'FloatType', -19432.125),
+ ('\xc6\x97\xd0@', 'FloatType', -19432.125),
+ ('\x7f\x7f\x00\x00', 'FloatType',
338953138925153547590470800371487866880.0),
+ ('', 'FloatType', None),
+ ('\x7f\x50\x00\x00', 'Int32Type', 2135949312),
+ ('\xff\xfd\xcb\x91', 'Int32Type', -144495),
+ ('', 'Int32Type', None),
+ ('f\x1e\xfd\xf2\xe3\xb1\x9f|\x04_\x15', 'IntegerType',
123456789123456789123456789),
+ ('', 'IntegerType', None),
+ ('\x7f\xff\xff\xff\xff\xff\xff\xff', 'LongType', 9223372036854775807),
+ ('\x80\x00\x00\x00\x00\x00\x00\x00', 'LongType', -9223372036854775808),
+ ('', 'LongType', None),
+ ('\xe3\x81\xbe\xe3\x81\x97\xe3\x81\xa6', 'UTF8Type',
u'\u307e\u3057\u3066'),
+ ('\xe3\x81\xbe\xe3\x81\x97\xe3\x81\xa6' * 1000, 'UTF8Type',
u'\u307e\u3057\u3066' * 1000),
+ ('', 'UTF8Type', u''),
+ ('\xff' * 16, 'UUIDType',
UUID('ffffffff-ffff-ffff-ffff-ffffffffffff')),
+ ('I\x15~\xfc\xef<\x9d\xe3\x16\x98\xaf\x80\x1f\xb4\x0b*', 'UUIDType',
UUID('49157efc-ef3c-9de3-1698-af801fb40b2a')),
+ ('', 'UUIDType', None),
+)
+
+class TestUnmarshal(unittest.TestCase):
+ def test_unmarshalling(self):
+ for serializedval, valtype, marshaledval in demarshal_me:
+ unmarshaller = unmarshallers.get(valtype, unmarshal_noop)
+ whatwegot = unmarshaller(serializedval)
+ self.assertEqual(whatwegot, marshaledval,
+ msg='Unmarshaller for %s (%s) failed:
unmarshal(%r) got %r instead of %r'
+ % (valtype, unmarshaller, serializedval,
whatwegot, marshaledval))
+ self.assertEqual(type(whatwegot), type(marshaledval),
+ msg='Unmarshaller for %s (%s) gave wrong type
(%s instead of %s)'
+ % (valtype, unmarshaller,
type(whatwegot), type(marshaledval)))