Merge remote-tracking branch 'origin/master' into ttl
This commit is contained in:
		| @@ -256,6 +256,10 @@ class Integer(Column): | |||||||
|         return self.validate(value) |         return self.validate(value) | ||||||
|  |  | ||||||
|  |  | ||||||
|  | class BigInt(Integer): | ||||||
|  |     db_type = 'bigint' | ||||||
|  |  | ||||||
|  |  | ||||||
| class VarInt(Column): | class VarInt(Column): | ||||||
|     db_type = 'varint' |     db_type = 'varint' | ||||||
|  |  | ||||||
| @@ -332,11 +336,9 @@ class DateTime(Column): | |||||||
|             else: |             else: | ||||||
|                 raise ValidationError("'{}' is not a datetime object".format(value)) |                 raise ValidationError("'{}' is not a datetime object".format(value)) | ||||||
|         epoch = datetime(1970, 1, 1, tzinfo=value.tzinfo) |         epoch = datetime(1970, 1, 1, tzinfo=value.tzinfo) | ||||||
|         offset = 0 |         offset = epoch.tzinfo.utcoffset(epoch).total_seconds() if epoch.tzinfo else 0 | ||||||
|         if epoch.tzinfo: |  | ||||||
|             offset_delta = epoch.tzinfo.utcoffset(epoch) |         return long(((value - epoch).total_seconds() - offset) * 1000) | ||||||
|             offset = offset_delta.days*24*3600 + offset_delta.seconds |  | ||||||
|         return long(((value  - epoch).total_seconds() - offset) * 1000) |  | ||||||
|  |  | ||||||
|  |  | ||||||
| class Date(Column): | class Date(Column): | ||||||
| @@ -406,12 +408,7 @@ class TimeUUID(UUID): | |||||||
|         global _last_timestamp |         global _last_timestamp | ||||||
|  |  | ||||||
|         epoch = datetime(1970, 1, 1, tzinfo=dt.tzinfo) |         epoch = datetime(1970, 1, 1, tzinfo=dt.tzinfo) | ||||||
|  |         offset = epoch.tzinfo.utcoffset(epoch).total_seconds() if epoch.tzinfo else 0 | ||||||
|         offset = 0 |  | ||||||
|         if epoch.tzinfo: |  | ||||||
|             offset_delta = epoch.tzinfo.utcoffset(epoch) |  | ||||||
|             offset = offset_delta.days*24*3600 + offset_delta.seconds |  | ||||||
|  |  | ||||||
|         timestamp = (dt  - epoch).total_seconds() - offset |         timestamp = (dt  - epoch).total_seconds() - offset | ||||||
|  |  | ||||||
|         node = None |         node = None | ||||||
|   | |||||||
| @@ -54,8 +54,10 @@ class MinTimeUUID(BaseQueryFunction): | |||||||
|         super(MinTimeUUID, self).__init__(value) |         super(MinTimeUUID, self).__init__(value) | ||||||
|  |  | ||||||
|     def get_value(self): |     def get_value(self): | ||||||
|         epoch = datetime(1970, 1, 1) |         epoch = datetime(1970, 1, 1, tzinfo=self.value.tzinfo) | ||||||
|         return long((self.value - epoch).total_seconds() * 1000) |         offset = epoch.tzinfo.utcoffset(epoch).total_seconds() if epoch.tzinfo else 0 | ||||||
|  |  | ||||||
|  |         return long(((self.value - epoch).total_seconds() - offset) * 1000) | ||||||
|  |  | ||||||
|     def get_dict(self, column): |     def get_dict(self, column): | ||||||
|         return {self.identifier: self.get_value()} |         return {self.identifier: self.get_value()} | ||||||
| @@ -79,8 +81,10 @@ class MaxTimeUUID(BaseQueryFunction): | |||||||
|         super(MaxTimeUUID, self).__init__(value) |         super(MaxTimeUUID, self).__init__(value) | ||||||
|  |  | ||||||
|     def get_value(self): |     def get_value(self): | ||||||
|         epoch = datetime(1970, 1, 1) |         epoch = datetime(1970, 1, 1, tzinfo=self.value.tzinfo) | ||||||
|         return long((self.value - epoch).total_seconds() * 1000) |         offset = epoch.tzinfo.utcoffset(epoch).total_seconds() if epoch.tzinfo else 0 | ||||||
|  |  | ||||||
|  |         return long(((self.value - epoch).total_seconds() - offset) * 1000) | ||||||
|  |  | ||||||
|     def get_dict(self, column): |     def get_dict(self, column): | ||||||
|         return {self.identifier: self.get_value()} |         return {self.identifier: self.get_value()} | ||||||
|   | |||||||
| @@ -15,6 +15,7 @@ from cqlengine.columns import Bytes | |||||||
| from cqlengine.columns import Ascii | from cqlengine.columns import Ascii | ||||||
| from cqlengine.columns import Text | from cqlengine.columns import Text | ||||||
| from cqlengine.columns import Integer | from cqlengine.columns import Integer | ||||||
|  | from cqlengine.columns import BigInt | ||||||
| from cqlengine.columns import VarInt | from cqlengine.columns import VarInt | ||||||
| from cqlengine.columns import DateTime | from cqlengine.columns import DateTime | ||||||
| from cqlengine.columns import Date | from cqlengine.columns import Date | ||||||
| @@ -180,6 +181,16 @@ class TestInteger(BaseCassEngTestCase): | |||||||
|         it = self.IntegerTest() |         it = self.IntegerTest() | ||||||
|         it.validate() |         it.validate() | ||||||
|  |  | ||||||
|  | class TestBigInt(BaseCassEngTestCase): | ||||||
|  |     class BigIntTest(Model): | ||||||
|  |         test_id = UUID(primary_key=True, default=lambda:uuid4()) | ||||||
|  |         value   = BigInt(default=0, required=True) | ||||||
|  |  | ||||||
|  |     def test_default_zero_fields_validate(self): | ||||||
|  |         """ Tests that bigint columns with a default value of 0 validate """ | ||||||
|  |         it = self.BigIntTest() | ||||||
|  |         it.validate() | ||||||
|  |  | ||||||
| class TestText(BaseCassEngTestCase): | class TestText(BaseCassEngTestCase): | ||||||
|  |  | ||||||
|     def test_min_length(self): |     def test_min_length(self): | ||||||
|   | |||||||
| @@ -95,6 +95,12 @@ class TestInteger(BaseColumnIOTest): | |||||||
|     pkey_val = 5 |     pkey_val = 5 | ||||||
|     data_val = 6 |     data_val = 6 | ||||||
|  |  | ||||||
|  | class TestBigInt(BaseColumnIOTest): | ||||||
|  |  | ||||||
|  |     column = columns.BigInt | ||||||
|  |     pkey_val = 6 | ||||||
|  |     data_val = pow(2, 63) - 1 | ||||||
|  |  | ||||||
| class TestDateTime(BaseColumnIOTest): | class TestDateTime(BaseColumnIOTest): | ||||||
|  |  | ||||||
|     column = columns.DateTime |     column = columns.DateTime | ||||||
|   | |||||||
| @@ -11,6 +11,25 @@ from cqlengine.management import delete_table | |||||||
| from cqlengine.models import Model | from cqlengine.models import Model | ||||||
| from cqlengine import columns | from cqlengine import columns | ||||||
| from cqlengine import query | from cqlengine import query | ||||||
|  | from datetime import timedelta | ||||||
|  | from datetime import tzinfo | ||||||
|  |  | ||||||
|  |  | ||||||
|  | class TzOffset(tzinfo): | ||||||
|  |     """Minimal implementation of a timezone offset to help testing with timezone | ||||||
|  |     aware datetimes. | ||||||
|  |     """ | ||||||
|  |     def __init__(self, offset): | ||||||
|  |         self._offset = timedelta(hours=offset) | ||||||
|  |  | ||||||
|  |     def utcoffset(self, dt): | ||||||
|  |         return self._offset | ||||||
|  |  | ||||||
|  |     def tzname(self, dt): | ||||||
|  |         return 'TzOffset: {}'.format(self._offset.hours) | ||||||
|  |  | ||||||
|  |     def dst(self, dt): | ||||||
|  |         return timedelta(0) | ||||||
|  |  | ||||||
| class TestModel(Model): | class TestModel(Model): | ||||||
|     test_id = columns.Integer(primary_key=True) |     test_id = columns.Integer(primary_key=True) | ||||||
| @@ -515,6 +534,49 @@ class TestMinMaxTimeUUIDFunctions(BaseCassEngTestCase): | |||||||
|         super(TestMinMaxTimeUUIDFunctions, cls).tearDownClass() |         super(TestMinMaxTimeUUIDFunctions, cls).tearDownClass() | ||||||
|         delete_table(TimeUUIDQueryModel) |         delete_table(TimeUUIDQueryModel) | ||||||
|  |  | ||||||
|  |     def test_tzaware_datetime_support(self): | ||||||
|  |         """Test that using timezone aware datetime instances works with the | ||||||
|  |         MinTimeUUID/MaxTimeUUID functions. | ||||||
|  |         """ | ||||||
|  |         pk = uuid4() | ||||||
|  |         midpoint_utc = datetime.utcnow().replace(tzinfo=TzOffset(0)) | ||||||
|  |         midpoint_helsinki = midpoint_utc.astimezone(TzOffset(3)) | ||||||
|  |  | ||||||
|  |         # Assert pre-condition that we have the same logical point in time | ||||||
|  |         assert midpoint_utc.utctimetuple() == midpoint_helsinki.utctimetuple() | ||||||
|  |         assert midpoint_utc.timetuple() != midpoint_helsinki.timetuple() | ||||||
|  |  | ||||||
|  |         TimeUUIDQueryModel.create( | ||||||
|  |             partition=pk, | ||||||
|  |             time=columns.TimeUUID.from_datetime(midpoint_utc - timedelta(minutes=1)), | ||||||
|  |             data='1') | ||||||
|  |  | ||||||
|  |         TimeUUIDQueryModel.create( | ||||||
|  |             partition=pk, | ||||||
|  |             time=columns.TimeUUID.from_datetime(midpoint_utc), | ||||||
|  |             data='2') | ||||||
|  |  | ||||||
|  |         TimeUUIDQueryModel.create( | ||||||
|  |             partition=pk, | ||||||
|  |             time=columns.TimeUUID.from_datetime(midpoint_utc + timedelta(minutes=1)), | ||||||
|  |             data='3') | ||||||
|  |  | ||||||
|  |         assert ['1', '2'] == [o.data for o in TimeUUIDQueryModel.filter( | ||||||
|  |             TimeUUIDQueryModel.partition == pk, | ||||||
|  |             TimeUUIDQueryModel.time <= functions.MaxTimeUUID(midpoint_utc))] | ||||||
|  |  | ||||||
|  |         assert ['1', '2'] == [o.data for o in TimeUUIDQueryModel.filter( | ||||||
|  |             TimeUUIDQueryModel.partition == pk, | ||||||
|  |             TimeUUIDQueryModel.time <= functions.MaxTimeUUID(midpoint_helsinki))] | ||||||
|  |  | ||||||
|  |         assert ['2', '3'] == [o.data for o in TimeUUIDQueryModel.filter( | ||||||
|  |             TimeUUIDQueryModel.partition == pk, | ||||||
|  |             TimeUUIDQueryModel.time >= functions.MinTimeUUID(midpoint_utc))] | ||||||
|  |  | ||||||
|  |         assert ['2', '3'] == [o.data for o in TimeUUIDQueryModel.filter( | ||||||
|  |             TimeUUIDQueryModel.partition == pk, | ||||||
|  |             TimeUUIDQueryModel.time >= functions.MinTimeUUID(midpoint_helsinki))] | ||||||
|  |  | ||||||
|     def test_success_case(self): |     def test_success_case(self): | ||||||
|         """ Test that the min and max time uuid functions work as expected """ |         """ Test that the min and max time uuid functions work as expected """ | ||||||
|         pk = uuid4() |         pk = uuid4() | ||||||
|   | |||||||
| @@ -38,10 +38,16 @@ Columns | |||||||
|  |  | ||||||
| .. class:: Integer() | .. class:: Integer() | ||||||
|  |  | ||||||
|     Stores an integer value :: |     Stores a 32-bit signed integer value :: | ||||||
|  |  | ||||||
|         columns.Integer() |         columns.Integer() | ||||||
|  |  | ||||||
|  | .. class:: BigInt() | ||||||
|  |  | ||||||
|  |     Stores a 64-bit signed long value :: | ||||||
|  |  | ||||||
|  |         columns.BigInt() | ||||||
|  |  | ||||||
| .. class:: VarInt() | .. class:: VarInt() | ||||||
|  |  | ||||||
|     Stores an arbitrary-precision integer :: |     Stores an arbitrary-precision integer :: | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user
	 Jon Haddad
					Jon Haddad