1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64
|
from uuid import UUID
from .base import FormatColumn
from .. import errors
from ..writer import MAX_UINT64
class UUIDColumn(FormatColumn):
ch_type = 'UUID'
py_types = (str, UUID)
format = 'Q'
# UUID is stored by two uint64 numbers.
def write_items(self, items, buf):
n_items = len(items)
uint_64_pairs = [None] * 2 * n_items
for i, x in enumerate(items):
i2 = 2 * i
uint_64_pairs[i2] = (x >> 64) & MAX_UINT64
uint_64_pairs[i2 + 1] = x & MAX_UINT64
s = self.make_struct(2 * n_items)
buf.write(s.pack(*uint_64_pairs))
def read_items(self, n_items, buf):
# TODO: cythonize
s = self.make_struct(2 * n_items)
items = s.unpack(buf.read(s.size))
uint_128_items = [None] * n_items
for i in range(n_items):
i2 = 2 * i
uint_128_items[i] = (items[i2] << 64) + items[i2 + 1]
return tuple(uint_128_items)
def after_read_items(self, items, nulls_map=None):
if nulls_map is None:
return tuple(UUID(int=item) for item in items)
else:
return tuple(
(None if is_null else UUID(int=items[i]))
for i, is_null in enumerate(nulls_map)
)
def before_write_items(self, items, nulls_map=None):
null_value = self.null_value
for i, item in enumerate(items):
if nulls_map and nulls_map[i]:
items[i] = null_value
continue
try:
if not isinstance(item, UUID):
item = UUID(item)
except ValueError:
raise errors.CannotParseUuidError(
"Cannot parse uuid '{}'".format(item)
)
items[i] = item.int
|