Skip to content

Commit

Permalink
finalize issue #62
Browse files Browse the repository at this point in the history
  • Loading branch information
gijzelaerr committed Jun 30, 2020
1 parent 9fd961c commit 3f84b16
Show file tree
Hide file tree
Showing 3 changed files with 22 additions and 16 deletions.
19 changes: 8 additions & 11 deletions monetdbe/_cffi.py
Original file line number Diff line number Diff line change
Expand Up @@ -95,9 +95,9 @@ def check_error(msg: ffi.CData) -> None:
lib.monetdbe_double: ("double", py_float, np.dtype(np.float), np.finfo(np.float).min),
lib.monetdbe_str: ("str", make_string, np.dtype('=O'), None),
lib.monetdbe_blob: ("blob", make_blob, np.dtype('=O'), None),
lib.monetdbe_date: ("date", py_date, np.dtype('datetime64[D]'), None),
lib.monetdbe_time: ("time", py_time, np.dtype('datetime64[ns]'), None),
lib.monetdbe_timestamp: ("timestamp", py_timestamp, np.dtype('datetime64[ns]'), None),
lib.monetdbe_date: ("date", py_date, np.dtype('=O'), None), # np.dtype('datetime64[D]')
lib.monetdbe_time: ("time", py_time, np.dtype('=O'), None), # np.dtype('datetime64[ns]')
lib.monetdbe_timestamp: ("timestamp", py_timestamp, np.dtype('=O'), None), # np.dtype('datetime64[ns]')
}


Expand Down Expand Up @@ -268,14 +268,11 @@ def result_fetch_numpy(self, monetdbe_result: ffi.CData):
cast_string, cast_function, numpy_type, monetdbe_null = type_map[rcol.type]

if numpy_type.char == 'O':
lib.PyUnicode_FromString(rcol.data)
char_value = ffi.cast("char *", rcol.data)
data = ffi.string(char_value)
data.decode('utf-8')

buffer_size = monetdbe_result.nrows * numpy_type.itemsize
c_buffer = ffi.buffer(rcol.data, buffer_size)
np_col: np.ndarray = np.frombuffer(c_buffer, dtype=numpy_type)
np_col: np.ndarray = np.array([extract(rcol, r) for r in range(monetdbe_result.nrows)])
else:
buffer_size = monetdbe_result.nrows * numpy_type.itemsize
c_buffer = ffi.buffer(rcol.data, buffer_size)
np_col = np.frombuffer(c_buffer, dtype=numpy_type)

if monetdbe_null:
mask = np_col == monetdbe_null
Expand Down
9 changes: 8 additions & 1 deletion monetdbe/monetize.py
Original file line number Diff line number Diff line change
Expand Up @@ -50,13 +50,20 @@ def monet_memoryview(data: memoryview) -> str:
return "'%s'" % data.tobytes().hex()


def monet_float(data: float) -> str:
if data != data: # yes this is how you can check if a float is a NaN
return 'NULL'
else:
return str(data)


mapping: List[Tuple[Type, Callable]] = [
(str, monet_escape),
(bytes, monet_bytes),
(memoryview, monet_memoryview),
(int, str),
(complex, str),
(float, str),
(float, monet_float),
(decimal.Decimal, str),
(datetime.datetime, monet_escape),
(datetime.time, monet_escape),
Expand Down
10 changes: 6 additions & 4 deletions tests/test_dataframe.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
from datetime import datetime
from typing import List, Any
from unittest import TestCase

from math import isnan
from pandas import DataFrame

from monetdbe import connect, Timestamp
Expand All @@ -17,9 +17,10 @@ def _connect(values: List[Any], type: str) -> DataFrame:

class TestDataFrame(TestCase):
def test_timestamp(self):
now = datetime.now().replace(microsecond=0) # monetdb doesn't support microseconds
values = [
datetime.now(),
Timestamp(2004, 2, 14, 7, 15, 0, 510241),
now,
Timestamp(2004, 2, 14, 7, 15, 0, 510000),
]
df = _connect(values, 'timestamp')
self.assertEqual(values, list(df['d']))
Expand All @@ -32,7 +33,8 @@ def test_int(self):
def test_float(self):
values = [5.0, 10.0, -100.0, float('nan')]
df = _connect(values, 'float')
self.assertEqual(values, list(df['d']))
self.assertEqual(values[:-1], list(df['d'])[:-1])
self.assertTrue(isnan(df['d'].iloc[-1]))

def test_char(self):
values = ['a', 'i', 'é']
Expand Down

0 comments on commit 3f84b16

Please sign in to comment.