Commit 827e3191 authored by Lukáš Lalinský's avatar Lukáš Lalinský

DATE/TIME/TIMESTAMP support

parent 08970884
......@@ -30,20 +30,34 @@ ColumnDescription = collections.namedtuple('ColumnDescription', 'name type_code
def time_from_java_sql_time(n):
microsecond = 1000 * (n % 1000)
n /= 1000
second = n % 60
n /= 60
minute = n % 60
n /= 60
hour = n % 24
return datetime.time(hour, minute, second, microsecond)
dt = datetime.datetime(1970, 1, 1) + datetime.timedelta(milliseconds=n)
return dt.time()
def time_to_java_sql_time(t):
return ((t.hour * 60 + t.minute) * 60 + t.second) * 1000 + t.microsecond / 1000
def date_from_java_sql_date(n):
return datetime.date(1970, 1, 1) + datetime.timedelta(days=n)
def date_to_java_sql_date(d):
if isinstance(d, datetime.datetime):
d = d.date()
td = d - datetime.date(1970, 1, 1)
return td.days
def datetime_from_java_sql_timestamp(n):
return datetime.datetime(1970, 1, 1) + datetime.timedelta(milliseconds=n)
def datetime_to_java_sql_timestamp(d):
td = d - datetime.datetime(1970, 1, 1)
return td.microseconds / 1000 + (td.seconds + td.days * 24 * 3600) * 1000
class Cursor(object):
"""Database cursor for executing queries and iterating over results.
......@@ -155,6 +169,10 @@ class Cursor(object):
self._column_data_types.append((i, float))
elif column['columnClassName'] == 'java.sql.Time':
self._column_data_types.append((i, time_from_java_sql_time))
elif column['columnClassName'] == 'java.sql.Date':
self._column_data_types.append((i, date_from_java_sql_date))
elif column['columnClassName'] == 'java.sql.Timestamp':
self._column_data_types.append((i, datetime_from_java_sql_timestamp))
elif column['type']['name'] == 'BINARY':
self._column_data_types.append((i, base64.b64decode))
for parameter in signature['parameters']:
......@@ -178,6 +196,10 @@ class Cursor(object):
self._parameter_data_types.append(('STRING', None))
elif parameter['className'] == 'java.sql.Time':
self._parameter_data_types.append(('JAVA_SQL_TIME', time_to_java_sql_time))
elif parameter['className'] == 'java.sql.Date':
self._parameter_data_types.append(('JAVA_SQL_DATE', date_to_java_sql_date))
elif parameter['className'] == 'java.sql.Timestamp':
self._parameter_data_types.append(('JAVA_SQL_TIMESTAMP', datetime_to_java_sql_timestamp))
elif parameter['className'] == '[B':
self._parameter_data_types.append(('BYTE_STRING', Binary))
else:
......
......@@ -22,6 +22,7 @@ class TypesTest(DatabaseTestCase):
self.assertEqual(cursor.fetchall(), [[1, 1], [2, None], [3, 1], [4, None], [5, min_value], [6, max_value]])
self.assertRaises(self.conn.DatabaseError, cursor.execute, "UPSERT INTO phoenixdb_test_tbl1 VALUES (100, {})".format(min_value - 1))
self.assertRaises(self.conn.DatabaseError, cursor.execute, "UPSERT INTO phoenixdb_test_tbl1 VALUES (100, {})".format(max_value + 1))
# XXX The server silently truncates the values
#self.assertRaises(self.conn.DatabaseError, cursor.execute, "UPSERT INTO phoenixdb_test_tbl1 VALUES (100, ?)", [min_value - 1])
#self.assertRaises(self.conn.DatabaseError, cursor.execute, "UPSERT INTO phoenixdb_test_tbl1 VALUES (100, ?)", [max_value + 1])
......@@ -115,6 +116,7 @@ class TypesTest(DatabaseTestCase):
self.assertEqual(cursor.fetchall(), [[1, True], [2, False], [3, None], [4, True], [5, False], [6, None]])
def test_time(self):
# XXX We should be able to read/write full date with time, not just time
self.createTable("phoenixdb_test_tbl1", "id integer primary key, val time")
with self.conn.cursor() as cursor:
cursor.execute("UPSERT INTO phoenixdb_test_tbl1 VALUES (1, '1970-01-01 12:01:02')")
......@@ -131,6 +133,82 @@ class TypesTest(DatabaseTestCase):
[5, None],
])
@unittest.skip("https://issues.apache.org/jira/browse/CALCITE-797")
def test_time_full(self):
self.createTable("phoenixdb_test_tbl1", "id integer primary key, val time")
with self.conn.cursor() as cursor:
cursor.execute("UPSERT INTO phoenixdb_test_tbl1 VALUES (1, '2015-07-12 13:01:02.123')")
cursor.execute("UPSERT INTO phoenixdb_test_tbl1 VALUES (2, ?)", [datetime.datetime(2015, 7, 12, 13, 1, 2, 123000)])
cursor.execute("SELECT id, val FROM phoenixdb_test_tbl1 ORDER BY id")
self.assertEqual(cursor.fetchall(), [
[1, datetime.datetime(2015, 7, 12, 13, 1, 2, 123000)],
[2, datetime.datetime(2015, 7, 12, 13, 1, 2, 123000)],
])
def test_date(self):
self.createTable("phoenixdb_test_tbl1", "id integer primary key, val date")
with self.conn.cursor() as cursor:
cursor.execute("UPSERT INTO phoenixdb_test_tbl1 VALUES (1, '2015-07-12 00:00:00')")
cursor.execute("UPSERT INTO phoenixdb_test_tbl1 VALUES (3, ?)", [phoenixdb.Date(2015, 7, 12)])
cursor.execute("UPSERT INTO phoenixdb_test_tbl1 VALUES (4, ?)", [datetime.date(2015, 7, 12)])
cursor.execute("SELECT id, val FROM phoenixdb_test_tbl1 ORDER BY id")
self.assertEqual(cursor.fetchall(), [
[1, datetime.date(2015, 7, 12)],
[3, datetime.date(2015, 7, 12)],
[4, datetime.date(2015, 7, 12)],
])
@unittest.skip("https://issues.apache.org/jira/browse/CALCITE-798")
def test_date_full(self):
self.createTable("phoenixdb_test_tbl1", "id integer primary key, val date")
with self.conn.cursor() as cursor:
cursor.execute("UPSERT INTO phoenixdb_test_tbl1 VALUES (1, '2015-07-12 13:01:02.123')")
cursor.execute("UPSERT INTO phoenixdb_test_tbl1 VALUES (2, ?)", [datetime.datetime(2015, 7, 12, 13, 1, 2, 123000)])
cursor.execute("SELECT id, val FROM phoenixdb_test_tbl1 ORDER BY id")
self.assertEqual(cursor.fetchall(), [
[1, datetime.datetime(2015, 7, 12, 13, 1, 2, 123000)],
[2, datetime.datetime(2015, 7, 12, 13, 1, 2, 123000)],
])
@unittest.skip("broken")
def test_date_null(self):
self.createTable("phoenixdb_test_tbl1", "id integer primary key, val date")
with self.conn.cursor() as cursor:
cursor.execute("UPSERT INTO phoenixdb_test_tbl1 VALUES (1, NULL)")
cursor.execute("UPSERT INTO phoenixdb_test_tbl1 VALUES (2, ?)", [None])
cursor.execute("SELECT id, val FROM phoenixdb_test_tbl1 ORDER BY id") # raises NullPointerException on the server
self.assertEqual(cursor.fetchall(), [
[1, None],
[2, None],
])
def test_timestamp(self):
self.createTable("phoenixdb_test_tbl1", "id integer primary key, val timestamp")
with self.conn.cursor() as cursor:
cursor.execute("UPSERT INTO phoenixdb_test_tbl1 VALUES (1, '2015-07-12 13:01:02.123')")
cursor.execute("UPSERT INTO phoenixdb_test_tbl1 VALUES (2, NULL)")
cursor.execute("UPSERT INTO phoenixdb_test_tbl1 VALUES (3, ?)", [phoenixdb.Timestamp(2015, 7, 12, 13, 1, 2)])
cursor.execute("UPSERT INTO phoenixdb_test_tbl1 VALUES (4, ?)", [datetime.datetime(2015, 7, 12, 13, 1, 2, 123000)])
cursor.execute("UPSERT INTO phoenixdb_test_tbl1 VALUES (5, ?)", [None])
cursor.execute("SELECT id, val FROM phoenixdb_test_tbl1 ORDER BY id")
self.assertEqual(cursor.fetchall(), [
[1, datetime.datetime(2015, 7, 12, 13, 1, 2, 123000)],
[2, None],
[3, datetime.datetime(2015, 7, 12, 13, 1, 2)],
[4, datetime.datetime(2015, 7, 12, 13, 1, 2, 123000)],
[5, None],
])
@unittest.skip("https://issues.apache.org/jira/browse/CALCITE-796")
def test_timestamp_full(self):
self.createTable("phoenixdb_test_tbl1", "id integer primary key, val timestamp")
with self.conn.cursor() as cursor:
cursor.execute("UPSERT INTO phoenixdb_test_tbl1 VALUES (1, '2015-07-12 13:01:02.123456789')")
cursor.execute("SELECT id, val FROM phoenixdb_test_tbl1 ORDER BY id")
self.assertEqual(cursor.fetchall(), [
[1, datetime.datetime(2015, 7, 12, 13, 1, 2, 123456789)],
])
def test_varchar(self):
self.createTable("phoenixdb_test_tbl1", "id integer primary key, val varchar")
with self.conn.cursor() as cursor:
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment