http://git-wip-us.apache.org/repos/asf/phoenix/blob/14b57801/python/phoenixdb/phoenixdb/types.py
----------------------------------------------------------------------
diff --git a/python/phoenixdb/phoenixdb/types.py 
b/python/phoenixdb/phoenixdb/types.py
new file mode 100644
index 0000000..f41355a
--- /dev/null
+++ b/python/phoenixdb/phoenixdb/types.py
@@ -0,0 +1,202 @@
+# 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 sys
+import time
+import datetime
+from decimal import Decimal
+from phoenixdb.avatica.proto import common_pb2
+
+__all__ = [
+    'Date', 'Time', 'Timestamp', 'DateFromTicks', 'TimeFromTicks', 
'TimestampFromTicks',
+    'Binary', 'STRING', 'BINARY', 'NUMBER', 'DATETIME', 'ROWID', 'BOOLEAN',
+    'JAVA_CLASSES', 'JAVA_CLASSES_MAP', 'TypeHelper',
+]
+
+
+def Date(year, month, day):
+    """Constructs an object holding a date value."""
+    return datetime.date(year, month, day)
+
+
+def Time(hour, minute, second):
+    """Constructs an object holding a time value."""
+    return datetime.time(hour, minute, second)
+
+
+def Timestamp(year, month, day, hour, minute, second):
+    """Constructs an object holding a datetime/timestamp value."""
+    return datetime.datetime(year, month, day, hour, minute, second)
+
+
+def DateFromTicks(ticks):
+    """Constructs an object holding a date value from the given UNIX 
timestamp."""
+    return Date(*time.localtime(ticks)[:3])
+
+
+def TimeFromTicks(ticks):
+    """Constructs an object holding a time value from the given UNIX 
timestamp."""
+    return Time(*time.localtime(ticks)[3:6])
+
+
+def TimestampFromTicks(ticks):
+    """Constructs an object holding a datetime/timestamp value from the given 
UNIX timestamp."""
+    return Timestamp(*time.localtime(ticks)[:6])
+
+
+def Binary(value):
+    """Constructs an object capable of holding a binary (long) string value."""
+    return bytes(value)
+
+
+def time_from_java_sql_time(n):
+    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 ColumnType(object):
+
+    def __init__(self, eq_types):
+        self.eq_types = tuple(eq_types)
+        self.eq_types_set = set(eq_types)
+
+    def __eq__(self, other):
+        return other in self.eq_types_set
+
+    def __cmp__(self, other):
+        if other in self.eq_types_set:
+            return 0
+        if other < self.eq_types:
+            return 1
+        else:
+            return -1
+
+
+STRING = ColumnType(['VARCHAR', 'CHAR'])
+"""Type object that can be used to describe string-based columns."""
+
+BINARY = ColumnType(['BINARY', 'VARBINARY'])
+"""Type object that can be used to describe (long) binary columns."""
+
+NUMBER = ColumnType([
+    'INTEGER', 'UNSIGNED_INT', 'BIGINT', 'UNSIGNED_LONG', 'TINYINT', 
'UNSIGNED_TINYINT',
+    'SMALLINT', 'UNSIGNED_SMALLINT', 'FLOAT', 'UNSIGNED_FLOAT', 'DOUBLE', 
'UNSIGNED_DOUBLE', 'DECIMAL'
+])
+"""Type object that can be used to describe numeric columns."""
+
+DATETIME = ColumnType(['TIME', 'DATE', 'TIMESTAMP', 'UNSIGNED_TIME', 
'UNSIGNED_DATE', 'UNSIGNED_TIMESTAMP'])
+"""Type object that can be used to describe date/time columns."""
+
+ROWID = ColumnType([])
+"""Only implemented for DB API 2.0 compatibility, not used."""
+
+BOOLEAN = ColumnType(['BOOLEAN'])
+"""Type object that can be used to describe boolean columns. This is a 
phoenixdb-specific extension."""
+
+
+# XXX ARRAY
+
+if sys.version_info[0] < 3:
+    _long = long  # noqa: F821
+else:
+    _long = int
+
+JAVA_CLASSES = {
+    'bool_value': [
+        ('java.lang.Boolean', common_pb2.BOOLEAN, None, None),
+    ],
+    'string_value': [
+        ('java.lang.Character', common_pb2.CHARACTER, None, None),
+        ('java.lang.String', common_pb2.STRING, None, None),
+        ('java.math.BigDecimal', common_pb2.BIG_DECIMAL, str, Decimal),
+    ],
+    'number_value': [
+        ('java.lang.Integer', common_pb2.INTEGER, None, int),
+        ('java.lang.Short', common_pb2.SHORT, None, int),
+        ('java.lang.Long', common_pb2.LONG, None, _long),
+        ('java.lang.Byte', common_pb2.BYTE, None, int),
+        ('java.sql.Time', common_pb2.JAVA_SQL_TIME, time_to_java_sql_time, 
time_from_java_sql_time),
+        ('java.sql.Date', common_pb2.JAVA_SQL_DATE, date_to_java_sql_date, 
date_from_java_sql_date),
+        ('java.sql.Timestamp', common_pb2.JAVA_SQL_TIMESTAMP, 
datetime_to_java_sql_timestamp, datetime_from_java_sql_timestamp),
+    ],
+    'bytes_value': [
+        ('[B', common_pb2.BYTE_STRING, Binary, None),
+    ],
+    'double_value': [
+        # if common_pb2.FLOAT is used, incorrect values are sent
+        ('java.lang.Float', common_pb2.DOUBLE, float, float),
+        ('java.lang.Double', common_pb2.DOUBLE, float, float),
+    ]
+}
+"""Groups of Java classes."""
+
+JAVA_CLASSES_MAP = dict((v[0], (k, v[1], v[2], v[3])) for k in JAVA_CLASSES 
for v in JAVA_CLASSES[k])
+"""Flips the available types to allow for faster lookup by Java class.
+
+This mapping should be structured as:
+    {
+        'java.math.BigDecimal': ('string_value', common_pb2.BIG_DECIMAL, str, 
Decimal),),
+        ...
+        '<java class>': (<field_name>, <Rep enum>, <mutate_to function>, 
<cast_from function>),
+    }
+"""
+
+
+class TypeHelper(object):
+    @staticmethod
+    def from_class(klass):
+        """Retrieves a Rep and functions to cast to/from based on the Java 
class.
+
+        :param klass:
+            The string of the Java class for the column or parameter.
+
+        :returns: tuple ``(field_name, rep, mutate_to, cast_from)``
+            WHERE
+            ``field_name`` is the attribute in ``common_pb2.TypedValue``
+            ``rep`` is the common_pb2.Rep enum
+            ``mutate_to`` is the function to cast values into Phoenix values, 
if any
+            ``cast_from`` is the function to cast from the Phoenix value to 
the Python value, if any
+
+        :raises:
+            NotImplementedError
+        """
+        if klass not in JAVA_CLASSES_MAP:
+            raise NotImplementedError('type {} is not supported'.format(klass))
+
+        return JAVA_CLASSES_MAP[klass]

http://git-wip-us.apache.org/repos/asf/phoenix/blob/14b57801/python/phoenixdb/requirements.txt
----------------------------------------------------------------------
diff --git a/python/phoenixdb/requirements.txt 
b/python/phoenixdb/requirements.txt
new file mode 100644
index 0000000..e6be902
--- /dev/null
+++ b/python/phoenixdb/requirements.txt
@@ -0,0 +1,25 @@
+#
+# 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.
+#
+-e git+https://bitbucket.org/lalinsky/python-sqlline.git#egg=sqlline
+nose
+protobuf>=3.0.0
+sphinx
+flake8
+requests
+../requests-kerberos

http://git-wip-us.apache.org/repos/asf/phoenix/blob/14b57801/python/phoenixdb/setup.cfg
----------------------------------------------------------------------
diff --git a/python/phoenixdb/setup.cfg b/python/phoenixdb/setup.cfg
new file mode 100644
index 0000000..ebc28c2
--- /dev/null
+++ b/python/phoenixdb/setup.cfg
@@ -0,0 +1,34 @@
+# 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.
+
+[nosetests]
+verbosity=2
+testmatch=^test_.+
+where=phoenixdb/tests
+
+[build_sphinx]
+source-dir = doc
+build-dir = doc/build
+all_files = 1
+
+[upload_sphinx]
+upload-dir = doc/build/html
+
+[flake8]
+max-line-length = 140
+exclude =
+  e,e3,env,venv,doc,build,dist,.tox,.idea,
+  ./phoenixdb/tests/dbapi20.py,
+  ./phoenixdb/avatica/proto/*_pb2.py

http://git-wip-us.apache.org/repos/asf/phoenix/blob/14b57801/python/phoenixdb/setup.py
----------------------------------------------------------------------
diff --git a/python/phoenixdb/setup.py b/python/phoenixdb/setup.py
new file mode 100644
index 0000000..994286a
--- /dev/null
+++ b/python/phoenixdb/setup.py
@@ -0,0 +1,69 @@
+#
+# 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.
+#
+from setuptools import setup, find_packages
+
+cmdclass = {}
+
+try:
+    from sphinx.setup_command import BuildDoc
+    cmdclass['build_sphinx'] = BuildDoc
+except ImportError:
+    pass
+
+
+def readme():
+    with open('README.rst') as f:
+        return f.read()
+
+
+version = "0.7"
+
+setup(
+    name="phoenixdb",
+    version=version,
+    description="Phoenix database adapter for Python",
+    long_description=readme(),
+    author="Lukas Lalinsky",
+    author_email="lu...@oxygene.sk",
+    url="https://bitbucket.org/lalinsky/python-phoenixdb";,
+    license="Apache 2",
+    packages=find_packages(),
+    include_package_data=True,
+    cmdclass=cmdclass,
+    command_options={
+        'build_sphinx': {
+            'version': ('setup.py', version),
+            'release': ('setup.py', version),
+        },
+    },
+    classifiers=[
+        'Programming Language :: Python',
+        'Programming Language :: Python :: 2',
+        'Programming Language :: Python :: 2.7',
+        'Programming Language :: Python :: 3',
+        'Programming Language :: Python :: 3.4',
+        'Programming Language :: Python :: 3.5',
+        'Programming Language :: Python :: 3.6',
+    ],
+    install_requires=[
+        'protobuf>=3.0.0',
+        'requests',
+        'requests-kerberos'
+    ]
+)

http://git-wip-us.apache.org/repos/asf/phoenix/blob/14b57801/python/phoenixdb/tests/__init__.py
----------------------------------------------------------------------
diff --git a/python/phoenixdb/tests/__init__.py 
b/python/phoenixdb/tests/__init__.py
deleted file mode 100644
index ec9a79b..0000000
--- a/python/phoenixdb/tests/__init__.py
+++ /dev/null
@@ -1,44 +0,0 @@
-# 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 os
-import unittest
-import phoenixdb
-
-TEST_DB_URL = os.environ.get('PHOENIXDB_TEST_DB_URL')
-
-
-@unittest.skipIf(TEST_DB_URL is None, "these tests require the 
PHOENIXDB_TEST_DB_URL environment variable set to a clean database")
-class DatabaseTestCase(unittest.TestCase):
-
-    def setUp(self):
-        self.conn = phoenixdb.connect(TEST_DB_URL, autocommit=True)
-        self.cleanup_tables = []
-
-    def tearDown(self):
-        self.doCleanups()
-        self.conn.close()
-
-    def addTableCleanup(self, name):
-        def dropTable():
-            with self.conn.cursor() as cursor:
-                cursor.execute("DROP TABLE IF EXISTS {}".format(name))
-        self.addCleanup(dropTable)
-
-    def createTable(self, name, columns):
-        with self.conn.cursor() as cursor:
-            cursor.execute("DROP TABLE IF EXISTS {}".format(name))
-            cursor.execute("CREATE TABLE {} ({})".format(name, columns))
-            self.addTableCleanup(name)

http://git-wip-us.apache.org/repos/asf/phoenix/blob/14b57801/python/phoenixdb/tests/dbapi20.py
----------------------------------------------------------------------
diff --git a/python/phoenixdb/tests/dbapi20.py 
b/python/phoenixdb/tests/dbapi20.py
deleted file mode 100644
index f176400..0000000
--- a/python/phoenixdb/tests/dbapi20.py
+++ /dev/null
@@ -1,857 +0,0 @@
-#!/usr/bin/env python
-
-# 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.
-
-''' Python DB API 2.0 driver compliance unit test suite. 
-    
-    This software is Public Domain and may be used without restrictions.
-
- "Now we have booze and barflies entering the discussion, plus rumours of
-  DBAs on drugs... and I won't tell you what flashes through my mind each
-  time I read the subject line with 'Anal Compliance' in it.  All around
-  this is turning out to be a thoroughly unwholesome unit test."
-
-    -- Ian Bicking
-'''
-
-__version__ = '1.14.3'
-
-import unittest
-import time
-import sys
-
-if sys.version[0] >= '3': #python 3.x
-    _BaseException = Exception
-    def _failUnless(self, expr, msg=None):
-        self.assertTrue(expr, msg)
-else:                   #python 2.x
-    from exceptions import StandardError as _BaseException
-    def _failUnless(self, expr, msg=None):
-        self.failUnless(expr, msg)  ## deprecated since Python 2.6
-
-def str2bytes(sval):
-    if sys.version_info < (3,0) and isinstance(sval, str):
-        sval = sval.decode("latin1")
-    return sval.encode("latin1") #python 3 make unicode into bytes
-
-class DatabaseAPI20Test(unittest.TestCase):
-    ''' Test a database self.driver for DB API 2.0 compatibility.
-        This implementation tests Gadfly, but the TestCase
-        is structured so that other self.drivers can subclass this 
-        test case to ensure compiliance with the DB-API. It is 
-        expected that this TestCase may be expanded in the future
-        if ambiguities or edge conditions are discovered.
-
-        The 'Optional Extensions' are not yet being tested.
-
-        self.drivers should subclass this test, overriding setUp, tearDown,
-        self.driver, connect_args and connect_kw_args. Class specification
-        should be as follows:
-
-        import dbapi20 
-        class mytest(dbapi20.DatabaseAPI20Test):
-           [...] 
-
-        Don't 'import DatabaseAPI20Test from dbapi20', or you will
-        confuse the unit tester - just 'import dbapi20'.
-    '''
-
-    # The self.driver module. This should be the module where the 'connect'
-    # method is to be found
-    driver = None
-    connect_args = () # List of arguments to pass to connect
-    connect_kw_args = {} # Keyword arguments for connect
-    table_prefix = 'dbapi20test_' # If you need to specify a prefix for tables
-
-    ddl1 = 'create table %sbooze (name varchar(20))' % table_prefix
-    ddl2 = 'create table %sbarflys (name varchar(20), drink varchar(30))' % 
table_prefix
-    xddl1 = 'drop table %sbooze' % table_prefix
-    xddl2 = 'drop table %sbarflys' % table_prefix
-    insert = 'insert'
-
-    lowerfunc = 'lower' # Name of stored procedure to convert string->lowercase
-        
-    # Some drivers may need to override these helpers, for example adding
-    # a 'commit' after the execute.
-    def executeDDL1(self,cursor):
-        cursor.execute(self.ddl1)
-
-    def executeDDL2(self,cursor):
-        cursor.execute(self.ddl2)
-
-    def setUp(self):
-        ''' self.drivers should override this method to perform required setup
-            if any is necessary, such as creating the database.
-        '''
-        pass
-
-    def tearDown(self):
-        ''' self.drivers should override this method to perform required 
cleanup
-            if any is necessary, such as deleting the test database.
-            The default drops the tables that may be created.
-        '''
-        try:
-            con = self._connect()
-            try:
-                cur = con.cursor()
-                for ddl in (self.xddl1,self.xddl2):
-                    try:
-                        cur.execute(ddl)
-                        con.commit()
-                    except self.driver.Error:
-                        # Assume table didn't exist. Other tests will check if
-                        # execute is busted.
-                        pass
-            finally:
-                con.close()
-        except _BaseException:
-            pass
-
-    def _connect(self):
-        try:
-             r = self.driver.connect(
-                *self.connect_args,**self.connect_kw_args
-                )
-        except AttributeError:
-            self.fail("No connect method found in self.driver module")
-        return r
-
-    def test_connect(self):
-        con = self._connect()
-        con.close()
-
-    def test_apilevel(self):
-        try:
-            # Must exist
-            apilevel = self.driver.apilevel
-            # Must equal 2.0
-            self.assertEqual(apilevel,'2.0')
-        except AttributeError:
-            self.fail("Driver doesn't define apilevel")
-
-    def test_threadsafety(self):
-        try:
-            # Must exist
-            threadsafety = self.driver.threadsafety
-            # Must be a valid value
-            _failUnless(self, threadsafety in (0,1,2,3))
-        except AttributeError:
-            self.fail("Driver doesn't define threadsafety")
-
-    def test_paramstyle(self):
-        try:
-            # Must exist
-            paramstyle = self.driver.paramstyle
-            # Must be a valid value
-            _failUnless(self, paramstyle in (
-                'qmark','numeric','named','format','pyformat'
-                ))
-        except AttributeError:
-            self.fail("Driver doesn't define paramstyle")
-
-    def test_Exceptions(self):
-        # Make sure required exceptions exist, and are in the
-        # defined heirarchy.
-        if sys.version[0] == '3': #under Python 3 StardardError no longer 
exists
-            self.assertTrue(issubclass(self.driver.Warning,Exception))
-            self.assertTrue(issubclass(self.driver.Error,Exception))
-        else:
-            self.failUnless(issubclass(self.driver.Warning,StandardError))
-            self.failUnless(issubclass(self.driver.Error,StandardError))
-
-        _failUnless(self,
-            issubclass(self.driver.InterfaceError,self.driver.Error)
-            )
-        _failUnless(self,
-            issubclass(self.driver.DatabaseError,self.driver.Error)
-            )
-        _failUnless(self,
-            issubclass(self.driver.OperationalError,self.driver.Error)
-            )
-        _failUnless(self,
-            issubclass(self.driver.IntegrityError,self.driver.Error)
-            )
-        _failUnless(self,
-            issubclass(self.driver.InternalError,self.driver.Error)
-            )
-        _failUnless(self,
-            issubclass(self.driver.ProgrammingError,self.driver.Error)
-            )
-        _failUnless(self,
-            issubclass(self.driver.NotSupportedError,self.driver.Error)
-            )
-
-    def test_ExceptionsAsConnectionAttributes(self):
-        # OPTIONAL EXTENSION
-        # Test for the optional DB API 2.0 extension, where the exceptions
-        # are exposed as attributes on the Connection object
-        # I figure this optional extension will be implemented by any
-        # driver author who is using this test suite, so it is enabled
-        # by default.
-        con = self._connect()
-        drv = self.driver
-        _failUnless(self,con.Warning is drv.Warning)
-        _failUnless(self,con.Error is drv.Error)
-        _failUnless(self,con.InterfaceError is drv.InterfaceError)
-        _failUnless(self,con.DatabaseError is drv.DatabaseError)
-        _failUnless(self,con.OperationalError is drv.OperationalError)
-        _failUnless(self,con.IntegrityError is drv.IntegrityError)
-        _failUnless(self,con.InternalError is drv.InternalError)
-        _failUnless(self,con.ProgrammingError is drv.ProgrammingError)
-        _failUnless(self,con.NotSupportedError is drv.NotSupportedError)
-
-
-    def test_commit(self):
-        con = self._connect()
-        try:
-            # Commit must work, even if it doesn't do anything
-            con.commit()
-        finally:
-            con.close()
-
-    def test_rollback(self):
-        con = self._connect()
-        # If rollback is defined, it should either work or throw
-        # the documented exception
-        if hasattr(con,'rollback'):
-            try:
-                con.rollback()
-            except self.driver.NotSupportedError:
-                pass
-    
-    def test_cursor(self):
-        con = self._connect()
-        try:
-            cur = con.cursor()
-        finally:
-            con.close()
-
-    def test_cursor_isolation(self):
-        con = self._connect()
-        try:
-            # Make sure cursors created from the same connection have
-            # the documented transaction isolation level
-            cur1 = con.cursor()
-            cur2 = con.cursor()
-            self.executeDDL1(cur1)
-            cur1.execute("%s into %sbooze values ('Victoria Bitter')" % (
-                self.insert, self.table_prefix
-                ))
-            cur2.execute("select name from %sbooze" % self.table_prefix)
-            booze = cur2.fetchall()
-            self.assertEqual(len(booze),1)
-            self.assertEqual(len(booze[0]),1)
-            self.assertEqual(booze[0][0],'Victoria Bitter')
-        finally:
-            con.close()
-
-    def test_description(self):
-        con = self._connect()
-        try:
-            cur = con.cursor()
-            self.executeDDL1(cur)
-            self.assertEqual(cur.description,None,
-                'cursor.description should be none after executing a '
-                'statement that can return no rows (such as DDL)'
-                )
-            cur.execute('select name from %sbooze' % self.table_prefix)
-            self.assertEqual(len(cur.description),1,
-                'cursor.description describes too many columns'
-                )
-            self.assertEqual(len(cur.description[0]),7,
-                'cursor.description[x] tuples must have 7 elements'
-                )
-            self.assertEqual(cur.description[0][0].lower(),'name',
-                'cursor.description[x][0] must return column name'
-                )
-            self.assertEqual(cur.description[0][1],self.driver.STRING,
-                'cursor.description[x][1] must return column type. Got %r'
-                    % cur.description[0][1]
-                )
-
-            # Make sure self.description gets reset
-            self.executeDDL2(cur)
-            self.assertEqual(cur.description,None,
-                'cursor.description not being set to None when executing '
-                'no-result statements (eg. DDL)'
-                )
-        finally:
-            con.close()
-
-    def test_rowcount(self):
-        con = self._connect()
-        try:
-            cur = con.cursor()
-            self.executeDDL1(cur)
-            _failUnless(self,cur.rowcount in (-1,0),   # Bug #543885
-                'cursor.rowcount should be -1 or 0 after executing no-result '
-                'statements'
-                )
-            cur.execute("%s into %sbooze values ('Victoria Bitter')" % (
-                self.insert, self.table_prefix
-                ))
-            _failUnless(self,cur.rowcount in (-1,1),
-                'cursor.rowcount should == number or rows inserted, or '
-                'set to -1 after executing an insert statement'
-                )
-            cur.execute("select name from %sbooze" % self.table_prefix)
-            _failUnless(self,cur.rowcount in (-1,1),
-                'cursor.rowcount should == number of rows returned, or '
-                'set to -1 after executing a select statement'
-                )
-            self.executeDDL2(cur)
-            _failUnless(self,cur.rowcount in (-1,0),   # Bug #543885
-                'cursor.rowcount should be -1 or 0 after executing no-result '
-                'statements'
-                )
-        finally:
-            con.close()
-
-    lower_func = 'lower'
-    def test_callproc(self):
-        con = self._connect()
-        try:
-            cur = con.cursor()
-            if self.lower_func and hasattr(cur,'callproc'):
-                r = cur.callproc(self.lower_func,('FOO',))
-                self.assertEqual(len(r),1)
-                self.assertEqual(r[0],'FOO')
-                r = cur.fetchall()
-                self.assertEqual(len(r),1,'callproc produced no result set')
-                self.assertEqual(len(r[0]),1,
-                    'callproc produced invalid result set'
-                    )
-                self.assertEqual(r[0][0],'foo',
-                    'callproc produced invalid results'
-                    )
-        finally:
-            con.close()
-
-    def test_close(self):
-        con = self._connect()
-        try:
-            cur = con.cursor()
-        finally:
-            con.close()
-
-        # cursor.execute should raise an Error if called after connection
-        # closed
-        self.assertRaises(self.driver.Error,self.executeDDL1,cur)
-
-        # connection.commit should raise an Error if called after connection'
-        # closed.'
-        self.assertRaises(self.driver.Error,con.commit)
-
-    def test_non_idempotent_close(self):
-        con = self._connect()
-        con.close()
-        # connection.close should raise an Error if called more than once
-        #!!! reasonable persons differ about the usefulness of this test and 
this feature !!!
-        self.assertRaises(self.driver.Error,con.close)
-
-    def test_execute(self):
-        con = self._connect()
-        try:
-            cur = con.cursor()
-            self._paraminsert(cur)
-        finally:
-            con.close()
-
-    def _paraminsert(self,cur):
-        self.executeDDL2(cur)
-        cur.execute("%s into %sbarflys values ('Victoria Bitter', 'thi%%s :may 
ca%%(u)se? troub:1e')" % (
-            self.insert, self.table_prefix
-            ))
-        _failUnless(self,cur.rowcount in (-1,1))
-
-        if self.driver.paramstyle == 'qmark':
-            cur.execute(
-                "%s into %sbarflys values (?, 'thi%%s :may ca%%(u)se? 
troub:1e')" % (self.insert, self.table_prefix),
-                ("Cooper's",)
-                )
-        elif self.driver.paramstyle == 'numeric':
-            cur.execute(
-                "%s into %sbarflys values (:1, 'thi%%s :may ca%%(u)se? 
troub:1e')" % (self.insert, self.table_prefix),
-                ("Cooper's",)
-                )
-        elif self.driver.paramstyle == 'named':
-            cur.execute(
-                "%s into %sbarflys values (:beer, 'thi%%s :may ca%%(u)se? 
troub:1e')" % (self.insert, self.table_prefix),
-                {'beer':"Cooper's"}
-                )
-        elif self.driver.paramstyle == 'format':
-            cur.execute(
-                "%s into %sbarflys values (%%s, 'thi%%%%s :may ca%%%%(u)se? 
troub:1e')" % (self.insert, self.table_prefix),
-                ("Cooper's",)
-                )
-        elif self.driver.paramstyle == 'pyformat':
-            cur.execute(
-                "%s into %sbarflys values (%%(beer)s, 'thi%%%%s :may 
ca%%%%(u)se? troub:1e')" % (self.insert, self.table_prefix),
-                {'beer':"Cooper's"}
-                )
-        else:
-            self.fail('Invalid paramstyle')
-        _failUnless(self,cur.rowcount in (-1,1))
-
-        cur.execute('select name, drink from %sbarflys' % self.table_prefix)
-        res = cur.fetchall()
-        self.assertEqual(len(res),2,'cursor.fetchall returned too few rows')
-        beers = [res[0][0],res[1][0]]
-        beers.sort()
-        self.assertEqual(beers[0],"Cooper's",
-            'cursor.fetchall retrieved incorrect data, or data inserted '
-            'incorrectly'
-            )
-        self.assertEqual(beers[1],"Victoria Bitter",
-            'cursor.fetchall retrieved incorrect data, or data inserted '
-            'incorrectly'
-            )
-        trouble = "thi%s :may ca%(u)se? troub:1e"
-        self.assertEqual(res[0][1], trouble,
-            'cursor.fetchall retrieved incorrect data, or data inserted '
-            'incorrectly. Got=%s, Expected=%s' % (repr(res[0][1]), 
repr(trouble)))      
-        self.assertEqual(res[1][1], trouble,
-            'cursor.fetchall retrieved incorrect data, or data inserted '
-            'incorrectly. Got=%s, Expected=%s' % (repr(res[1][1]), 
repr(trouble)
-            ))
-        
-    def test_executemany(self):
-        con = self._connect()
-        try:
-            cur = con.cursor()
-            self.executeDDL1(cur)
-            largs = [ ("Cooper's",) , ("Boag's",) ]
-            margs = [ {'beer': "Cooper's"}, {'beer': "Boag's"} ]
-            if self.driver.paramstyle == 'qmark':
-                cur.executemany(
-                    '%s into %sbooze values (?)' % (self.insert, 
self.table_prefix),
-                    largs
-                    )
-            elif self.driver.paramstyle == 'numeric':
-                cur.executemany(
-                    '%s into %sbooze values (:1)' % (self.insert, 
self.table_prefix),
-                    largs
-                    )
-            elif self.driver.paramstyle == 'named':
-                cur.executemany(
-                    '%s into %sbooze values (:beer)' % (self.insert, 
self.table_prefix),
-                    margs
-                    )
-            elif self.driver.paramstyle == 'format':
-                cur.executemany(
-                    '%s into %sbooze values (%%s)' % (self.insert, 
self.table_prefix),
-                    largs
-                    )
-            elif self.driver.paramstyle == 'pyformat':
-                cur.executemany(
-                    '%s into %sbooze values (%%(beer)s)' % (
-                        self.insert, self.table_prefix
-                        ),
-                    margs
-                    )
-            else:
-                self.fail('Unknown paramstyle')
-            _failUnless(self,cur.rowcount in (-1,2),
-                'insert using cursor.executemany set cursor.rowcount to '
-                'incorrect value %r' % cur.rowcount
-                )
-            cur.execute('select name from %sbooze' % self.table_prefix)
-            res = cur.fetchall()
-            self.assertEqual(len(res),2,
-                'cursor.fetchall retrieved incorrect number of rows'
-                )
-            beers = [res[0][0],res[1][0]]
-            beers.sort()
-            self.assertEqual(beers[0],"Boag's",'incorrect data retrieved')
-            self.assertEqual(beers[1],"Cooper's",'incorrect data retrieved')
-        finally:
-            con.close()
-
-    def test_fetchone(self):
-        con = self._connect()
-        try:
-            cur = con.cursor()
-
-            # cursor.fetchone should raise an Error if called before
-            # executing a select-type query
-            self.assertRaises(self.driver.Error,cur.fetchone)
-
-            # cursor.fetchone should raise an Error if called after
-            # executing a query that cannnot return rows
-            self.executeDDL1(cur)
-            self.assertRaises(self.driver.Error,cur.fetchone)
-
-            cur.execute('select name from %sbooze' % self.table_prefix)
-            self.assertEqual(cur.fetchone(),None,
-                'cursor.fetchone should return None if a query retrieves '
-                'no rows'
-                )
-            _failUnless(self,cur.rowcount in (-1,0))
-
-            # cursor.fetchone should raise an Error if called after
-            # executing a query that cannnot return rows
-            cur.execute("%s into %sbooze values ('Victoria Bitter')" % (
-                self.insert, self.table_prefix
-                ))
-            self.assertRaises(self.driver.Error,cur.fetchone)
-
-            cur.execute('select name from %sbooze' % self.table_prefix)
-            r = cur.fetchone()
-            self.assertEqual(len(r),1,
-                'cursor.fetchone should have retrieved a single row'
-                )
-            self.assertEqual(r[0],'Victoria Bitter',
-                'cursor.fetchone retrieved incorrect data'
-                )
-            self.assertEqual(cur.fetchone(),None,
-                'cursor.fetchone should return None if no more rows available'
-                )
-            _failUnless(self,cur.rowcount in (-1,1))
-        finally:
-            con.close()
-
-    samples = [
-        'Carlton Cold',
-        'Carlton Draft',
-        'Mountain Goat',
-        'Redback',
-        'Victoria Bitter',
-        'XXXX'
-        ]
-
-    def _populate(self):
-        ''' Return a list of sql commands to setup the DB for the fetch
-            tests.
-        '''
-        populate = [
-            "%s into %sbooze values ('%s')" % (self.insert, self.table_prefix, 
s)
-                for s in self.samples
-            ]
-        return populate
-
-    def test_fetchmany(self):
-        con = self._connect()
-        try:
-            cur = con.cursor()
-
-            # cursor.fetchmany should raise an Error if called without
-            #issuing a query
-            self.assertRaises(self.driver.Error,cur.fetchmany,4)
-
-            self.executeDDL1(cur)
-            for sql in self._populate():
-                cur.execute(sql)
-
-            cur.execute('select name from %sbooze' % self.table_prefix)
-            r = cur.fetchmany()
-            self.assertEqual(len(r),1,
-                'cursor.fetchmany retrieved incorrect number of rows, '
-                'default of arraysize is one.'
-                )
-            cur.arraysize=10
-            r = cur.fetchmany(3) # Should get 3 rows
-            self.assertEqual(len(r),3,
-                'cursor.fetchmany retrieved incorrect number of rows'
-                )
-            r = cur.fetchmany(4) # Should get 2 more
-            self.assertEqual(len(r),2,
-                'cursor.fetchmany retrieved incorrect number of rows'
-                )
-            r = cur.fetchmany(4) # Should be an empty sequence
-            self.assertEqual(len(r),0,
-                'cursor.fetchmany should return an empty sequence after '
-                'results are exhausted'
-            )
-            _failUnless(self,cur.rowcount in (-1,6))
-
-            # Same as above, using cursor.arraysize
-            cur.arraysize=4
-            cur.execute('select name from %sbooze' % self.table_prefix)
-            r = cur.fetchmany() # Should get 4 rows
-            self.assertEqual(len(r),4,
-                'cursor.arraysize not being honoured by fetchmany'
-                )
-            r = cur.fetchmany() # Should get 2 more
-            self.assertEqual(len(r),2)
-            r = cur.fetchmany() # Should be an empty sequence
-            self.assertEqual(len(r),0)
-            _failUnless(self,cur.rowcount in (-1,6))
-
-            cur.arraysize=6
-            cur.execute('select name from %sbooze' % self.table_prefix)
-            rows = cur.fetchmany() # Should get all rows
-            _failUnless(self,cur.rowcount in (-1,6))
-            self.assertEqual(len(rows),6)
-            self.assertEqual(len(rows),6)
-            rows = [r[0] for r in rows]
-            rows.sort()
-          
-            # Make sure we get the right data back out
-            for i in range(0,6):
-                self.assertEqual(rows[i],self.samples[i],
-                    'incorrect data retrieved by cursor.fetchmany'
-                    )
-
-            rows = cur.fetchmany() # Should return an empty list
-            self.assertEqual(len(rows),0,
-                'cursor.fetchmany should return an empty sequence if '
-                'called after the whole result set has been fetched'
-                )
-            _failUnless(self,cur.rowcount in (-1,6))
-
-            self.executeDDL2(cur)
-            cur.execute('select name from %sbarflys' % self.table_prefix)
-            r = cur.fetchmany() # Should get empty sequence
-            self.assertEqual(len(r),0,
-                'cursor.fetchmany should return an empty sequence if '
-                'query retrieved no rows'
-                )
-            _failUnless(self,cur.rowcount in (-1,0))
-
-        finally:
-            con.close()
-
-    def test_fetchall(self):
-        con = self._connect()
-        try:
-            cur = con.cursor()
-            # cursor.fetchall should raise an Error if called
-            # without executing a query that may return rows (such
-            # as a select)
-            self.assertRaises(self.driver.Error, cur.fetchall)
-
-            self.executeDDL1(cur)
-            for sql in self._populate():
-                cur.execute(sql)
-
-            # cursor.fetchall should raise an Error if called
-            # after executing a a statement that cannot return rows
-            self.assertRaises(self.driver.Error,cur.fetchall)
-
-            cur.execute('select name from %sbooze' % self.table_prefix)
-            rows = cur.fetchall()
-            _failUnless(self,cur.rowcount in (-1,len(self.samples)))
-            self.assertEqual(len(rows),len(self.samples),
-                'cursor.fetchall did not retrieve all rows'
-                )
-            rows = [r[0] for r in rows]
-            rows.sort()
-            for i in range(0,len(self.samples)):
-                self.assertEqual(rows[i],self.samples[i],
-                'cursor.fetchall retrieved incorrect rows'
-                )
-            rows = cur.fetchall()
-            self.assertEqual(
-                len(rows),0,
-                'cursor.fetchall should return an empty list if called '
-                'after the whole result set has been fetched'
-                )
-            _failUnless(self,cur.rowcount in (-1,len(self.samples)))
-
-            self.executeDDL2(cur)
-            cur.execute('select name from %sbarflys' % self.table_prefix)
-            rows = cur.fetchall()
-            _failUnless(self,cur.rowcount in (-1,0))
-            self.assertEqual(len(rows),0,
-                'cursor.fetchall should return an empty list if '
-                'a select query returns no rows'
-                )
-            
-        finally:
-            con.close()
-    
-    def test_mixedfetch(self):
-        con = self._connect()
-        try:
-            cur = con.cursor()
-            self.executeDDL1(cur)
-            for sql in self._populate():
-                cur.execute(sql)
-
-            cur.execute('select name from %sbooze' % self.table_prefix)
-            rows1  = cur.fetchone()
-            rows23 = cur.fetchmany(2)
-            rows4  = cur.fetchone()
-            rows56 = cur.fetchall()
-            _failUnless(self,cur.rowcount in (-1,6))
-            self.assertEqual(len(rows23),2,
-                'fetchmany returned incorrect number of rows'
-                )
-            self.assertEqual(len(rows56),2,
-                'fetchall returned incorrect number of rows'
-                )
-
-            rows = [rows1[0]]
-            rows.extend([rows23[0][0],rows23[1][0]])
-            rows.append(rows4[0])
-            rows.extend([rows56[0][0],rows56[1][0]])
-            rows.sort()
-            for i in range(0,len(self.samples)):
-                self.assertEqual(rows[i],self.samples[i],
-                    'incorrect data retrieved or inserted'
-                    )
-        finally:
-            con.close()
-
-    def help_nextset_setUp(self,cur):
-        ''' Should create a procedure called deleteme
-            that returns two result sets, first the 
-           number of rows in booze then "name from booze"
-        '''
-        raise NotImplementedError('Helper not implemented')
-        #sql="""
-        #    create procedure deleteme as
-        #    begin
-        #        select count(*) from booze
-        #        select name from booze
-        #    end
-        #"""
-        #cur.execute(sql)
-
-    def help_nextset_tearDown(self,cur):
-        'If cleaning up is needed after nextSetTest'
-        raise NotImplementedError('Helper not implemented')
-        #cur.execute("drop procedure deleteme")
-
-    def test_nextset(self):
-        con = self._connect()
-        try:
-            cur = con.cursor()
-            if not hasattr(cur,'nextset'):
-                return
-
-            try:
-                self.executeDDL1(cur)
-                sql=self._populate()
-                for sql in self._populate():
-                    cur.execute(sql)
-
-                self.help_nextset_setUp(cur)
-
-                cur.callproc('deleteme')
-                numberofrows=cur.fetchone()
-                assert numberofrows[0]== len(self.samples)
-                assert cur.nextset()
-                names=cur.fetchall()
-                assert len(names) == len(self.samples)
-                s=cur.nextset()
-                assert s == None,'No more return sets, should return None'
-            finally:
-                self.help_nextset_tearDown(cur)
-
-        finally:
-            con.close()
-
-    def test_nextset(self):
-        raise NotImplementedError('Drivers need to override this test')
-
-    def test_arraysize(self):
-        # Not much here - rest of the tests for this are in test_fetchmany
-        con = self._connect()
-        try:
-            cur = con.cursor()
-            _failUnless(self,hasattr(cur,'arraysize'),
-                'cursor.arraysize must be defined'
-                )
-        finally:
-            con.close()
-
-    def test_setinputsizes(self):
-        con = self._connect()
-        try:
-            cur = con.cursor()
-            cur.setinputsizes( (25,) )
-            self._paraminsert(cur) # Make sure cursor still works
-        finally:
-            con.close()
-
-    def test_setoutputsize_basic(self):
-        # Basic test is to make sure setoutputsize doesn't blow up
-        con = self._connect()
-        try:
-            cur = con.cursor()
-            cur.setoutputsize(1000)
-            cur.setoutputsize(2000,0)
-            self._paraminsert(cur) # Make sure the cursor still works
-        finally:
-            con.close()
-
-    def test_setoutputsize(self):
-        # Real test for setoutputsize is driver dependant
-        raise NotImplementedError('Driver needed to override this test')
-
-    def test_None(self):
-        con = self._connect()
-        try:
-            cur = con.cursor()
-            self.executeDDL1(cur)
-            cur.execute("%s into %sbarflys values ('a', NULL)" % (self.insert, 
self.table_prefix))
-            cur.execute('select drink from %sbarflys' % self.table_prefix)
-            r = cur.fetchall()
-            self.assertEqual(len(r),1)
-            self.assertEqual(len(r[0]),1)
-            self.assertEqual(r[0][0],None,'NULL value not returned as None')
-        finally:
-            con.close()
-
-    def test_Date(self):
-        d1 = self.driver.Date(2002,12,25)
-        d2 = self.driver.DateFromTicks(time.mktime((2002,12,25,0,0,0,0,0,0)))
-        # Can we assume this? API doesn't specify, but it seems implied
-        # self.assertEqual(str(d1),str(d2))
-
-    def test_Time(self):
-        t1 = self.driver.Time(13,45,30)
-        t2 = self.driver.TimeFromTicks(time.mktime((2001,1,1,13,45,30,0,0,0)))
-        # Can we assume this? API doesn't specify, but it seems implied
-        # self.assertEqual(str(t1),str(t2))
-
-    def test_Timestamp(self):
-        t1 = self.driver.Timestamp(2002,12,25,13,45,30)
-        t2 = self.driver.TimestampFromTicks(
-            time.mktime((2002,12,25,13,45,30,0,0,0))
-            )
-        # Can we assume this? API doesn't specify, but it seems implied
-        # self.assertEqual(str(t1),str(t2))
-
-    def test_Binary(self):
-        b = self.driver.Binary(str2bytes('Something'))
-        b = self.driver.Binary(str2bytes(''))
-
-    def test_STRING(self):
-        _failUnless(self, hasattr(self.driver,'STRING'),
-            'module.STRING must be defined'
-            )
-
-    def test_BINARY(self):
-        _failUnless(self, hasattr(self.driver,'BINARY'),
-            'module.BINARY must be defined.'
-            )
-
-    def test_NUMBER(self):
-        _failUnless(self, hasattr(self.driver,'NUMBER'),
-            'module.NUMBER must be defined.'
-            )
-
-    def test_DATETIME(self):
-        _failUnless(self, hasattr(self.driver,'DATETIME'),
-            'module.DATETIME must be defined.'
-            )
-
-    def test_ROWID(self):
-        _failUnless(self, hasattr(self.driver,'ROWID'),
-            'module.ROWID must be defined.'
-            )

http://git-wip-us.apache.org/repos/asf/phoenix/blob/14b57801/python/phoenixdb/tests/test_avatica.py
----------------------------------------------------------------------
diff --git a/python/phoenixdb/tests/test_avatica.py 
b/python/phoenixdb/tests/test_avatica.py
deleted file mode 100644
index 6152814..0000000
--- a/python/phoenixdb/tests/test_avatica.py
+++ /dev/null
@@ -1,25 +0,0 @@
-# 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 phoenixdb.avatica.client import parse_url, urlparse
-
-
-class ParseUrlTest(unittest.TestCase):
-
-    def test_parse_url(self):
-        self.assertEqual(urlparse.urlparse('http://localhost:8765/'), 
parse_url('localhost'))
-        self.assertEqual(urlparse.urlparse('http://localhost:2222/'), 
parse_url('localhost:2222'))
-        self.assertEqual(urlparse.urlparse('http://localhost:2222/'), 
parse_url('http://localhost:2222/'))

http://git-wip-us.apache.org/repos/asf/phoenix/blob/14b57801/python/phoenixdb/tests/test_connection.py
----------------------------------------------------------------------
diff --git a/python/phoenixdb/tests/test_connection.py 
b/python/phoenixdb/tests/test_connection.py
deleted file mode 100644
index 2deacf5..0000000
--- a/python/phoenixdb/tests/test_connection.py
+++ /dev/null
@@ -1,42 +0,0 @@
-# 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
-import phoenixdb
-from phoenixdb.tests import TEST_DB_URL
-
-
-@unittest.skipIf(TEST_DB_URL is None, "these tests require the 
PHOENIXDB_TEST_DB_URL environment variable set to a clean database")
-class PhoenixConnectionTest(unittest.TestCase):
-
-    def _connect(self, connect_kw_args):
-        try:
-            r = phoenixdb.connect(TEST_DB_URL, **connect_kw_args)
-        except AttributeError:
-            self.fail("Failed to connect")
-        return r
-
-    def test_connection_credentials(self):
-        connect_kw_args = {'user': 'SCOTT', 'password': 'TIGER', 'readonly': 
'True'}
-        con = self._connect(connect_kw_args)
-        try:
-            self.assertEqual(
-                con._connection_args, {'user': 'SCOTT', 'password': 'TIGER'},
-                'Should have extract user and password')
-            self.assertEqual(
-                con._filtered_args, {'readonly': 'True'},
-                'Should have not extracted foo')
-        finally:
-            con.close()

http://git-wip-us.apache.org/repos/asf/phoenix/blob/14b57801/python/phoenixdb/tests/test_db.py
----------------------------------------------------------------------
diff --git a/python/phoenixdb/tests/test_db.py 
b/python/phoenixdb/tests/test_db.py
deleted file mode 100644
index 2fb1a2a..0000000
--- a/python/phoenixdb/tests/test_db.py
+++ /dev/null
@@ -1,99 +0,0 @@
-# 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
-import phoenixdb
-import phoenixdb.cursor
-from phoenixdb.errors import InternalError
-from phoenixdb.tests import TEST_DB_URL
-
-
-@unittest.skipIf(TEST_DB_URL is None, "these tests require the 
PHOENIXDB_TEST_DB_URL environment variable set to a clean database")
-class PhoenixDatabaseTest(unittest.TestCase):
-
-    def test_select_literal(self):
-        db = phoenixdb.connect(TEST_DB_URL, autocommit=True)
-        self.addCleanup(db.close)
-
-        with db.cursor() as cursor:
-            cursor.execute("DROP TABLE IF EXISTS test")
-            cursor.execute("CREATE TABLE test (id INTEGER PRIMARY KEY, text 
VARCHAR)")
-            cursor.executemany("UPSERT INTO test VALUES (?, ?)", [[i, 'text 
{}'.format(i)] for i in range(10)])
-
-        with db.cursor() as cursor:
-            cursor.itersize = 4
-            cursor.execute("SELECT * FROM test WHERE id>1 ORDER BY id")
-            self.assertEqual(cursor.fetchall(), [[i, 'text {}'.format(i)] for 
i in range(2, 10)])
-
-    def test_select_parameter(self):
-        db = phoenixdb.connect(TEST_DB_URL, autocommit=True)
-        self.addCleanup(db.close)
-
-        with db.cursor() as cursor:
-            cursor.execute("DROP TABLE IF EXISTS test")
-            cursor.execute("CREATE TABLE test (id INTEGER PRIMARY KEY, text 
VARCHAR)")
-            cursor.executemany("UPSERT INTO test VALUES (?, ?)", [[i, 'text 
{}'.format(i)] for i in range(10)])
-
-        with db.cursor() as cursor:
-            cursor.itersize = 4
-            cursor.execute("SELECT * FROM test WHERE id>? ORDER BY id", [1])
-            self.assertEqual(cursor.fetchall(), [[i, 'text {}'.format(i)] for 
i in range(2, 10)])
-
-    def _check_dict_cursor(self, cursor):
-        cursor.execute("DROP TABLE IF EXISTS test")
-        cursor.execute("CREATE TABLE test (id INTEGER PRIMARY KEY, text 
VARCHAR)")
-        cursor.execute("UPSERT INTO test VALUES (?, ?)", [1, 'text 1'])
-        cursor.execute("SELECT * FROM test ORDER BY id")
-        self.assertEqual(cursor.fetchall(), [{'ID': 1, 'TEXT': 'text 1'}])
-
-    def test_dict_cursor_default_parameter(self):
-        db = phoenixdb.connect(TEST_DB_URL, autocommit=True, 
cursor_factory=phoenixdb.cursor.DictCursor)
-        self.addCleanup(db.close)
-
-        with db.cursor() as cursor:
-            self._check_dict_cursor(cursor)
-
-    def test_dict_cursor_default_attribute(self):
-        db = phoenixdb.connect(TEST_DB_URL, autocommit=True)
-        db.cursor_factory = phoenixdb.cursor.DictCursor
-        self.addCleanup(db.close)
-
-        with db.cursor() as cursor:
-            self._check_dict_cursor(cursor)
-
-    def test_dict_cursor(self):
-        db = phoenixdb.connect(TEST_DB_URL, autocommit=True)
-        self.addCleanup(db.close)
-
-        with db.cursor(cursor_factory=phoenixdb.cursor.DictCursor) as cursor:
-            self._check_dict_cursor(cursor)
-
-    def test_schema(self):
-        db = phoenixdb.connect(TEST_DB_URL, autocommit=True)
-        self.addCleanup(db.close)
-
-        with db.cursor() as cursor:
-            try:
-                cursor.execute("CREATE SCHEMA IF NOT EXISTS test_schema")
-            except InternalError as e:
-                if "phoenix.schema.isNamespaceMappingEnabled" in e.message:
-                    self.skipTest(e.message)
-                raise
-
-            cursor.execute("DROP TABLE IF EXISTS test_schema.test")
-            cursor.execute("CREATE TABLE test_schema.test (id INTEGER PRIMARY 
KEY, text VARCHAR)")
-            cursor.execute("UPSERT INTO test_schema.test VALUES (?, ?)", [1, 
'text 1'])
-            cursor.execute("SELECT * FROM test_schema.test ORDER BY id")
-            self.assertEqual(cursor.fetchall(), [[1, 'text 1']])

http://git-wip-us.apache.org/repos/asf/phoenix/blob/14b57801/python/phoenixdb/tests/test_dbapi20.py
----------------------------------------------------------------------
diff --git a/python/phoenixdb/tests/test_dbapi20.py 
b/python/phoenixdb/tests/test_dbapi20.py
deleted file mode 100644
index 0e5c2e4..0000000
--- a/python/phoenixdb/tests/test_dbapi20.py
+++ /dev/null
@@ -1,122 +0,0 @@
-# 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
-import phoenixdb
-from . import dbapi20
-from phoenixdb.tests import TEST_DB_URL
-
-
-@unittest.skipIf(TEST_DB_URL is None, "these tests require the 
PHOENIXDB_TEST_DB_URL environment variable set to a clean database")
-class PhoenixDatabaseAPI20Test(dbapi20.DatabaseAPI20Test):
-    driver = phoenixdb
-    connect_args = (TEST_DB_URL, )
-
-    ddl1 = 'create table %sbooze (name varchar(20) primary key)' % 
dbapi20.DatabaseAPI20Test.table_prefix
-    ddl2 = 'create table %sbarflys (name varchar(20) primary key, drink 
varchar(30))' % dbapi20.DatabaseAPI20Test.table_prefix
-    insert = 'upsert'
-
-    def test_nextset(self):
-        pass
-
-    def test_setoutputsize(self):
-        pass
-
-    def _connect(self):
-        con = dbapi20.DatabaseAPI20Test._connect(self)
-        con.autocommit = True
-        return con
-
-    def test_None(self):
-        con = self._connect()
-        try:
-            cur = con.cursor()
-            self.executeDDL2(cur)
-            cur.execute("%s into %sbarflys values ('a', NULL)" % (self.insert, 
self.table_prefix))
-            cur.execute('select drink from %sbarflys' % self.table_prefix)
-            r = cur.fetchall()
-            self.assertEqual(len(r), 1)
-            self.assertEqual(len(r[0]), 1)
-            self.assertEqual(r[0][0], None, 'NULL value not returned as None')
-        finally:
-            con.close()
-
-    def test_autocommit(self):
-        con = dbapi20.DatabaseAPI20Test._connect(self)
-        self.assertFalse(con.autocommit)
-        con.autocommit = True
-        self.assertTrue(con.autocommit)
-        con.autocommit = False
-        self.assertFalse(con.autocommit)
-        con.close()
-
-    def test_readonly(self):
-        con = dbapi20.DatabaseAPI20Test._connect(self)
-        self.assertFalse(con.readonly)
-        con.readonly = True
-        self.assertTrue(con.readonly)
-        con.readonly = False
-        self.assertFalse(con.readonly)
-        con.close()
-
-    def test_iter(self):
-        # https://www.python.org/dev/peps/pep-0249/#iter
-        con = self._connect()
-        try:
-            cur = con.cursor()
-            if hasattr(cur, '__iter__'):
-                self.assertIs(cur, iter(cur))
-        finally:
-            con.close()
-
-    def test_next(self):
-        # https://www.python.org/dev/peps/pep-0249/#next
-        con = self._connect()
-        try:
-            cur = con.cursor()
-            if not hasattr(cur, 'next'):
-                return
-
-            # cursor.next should raise an Error if called before
-            # executing a select-type query
-            self.assertRaises(self.driver.Error, cur.next)
-
-            # cursor.next should raise an Error if called after
-            # executing a query that cannnot return rows
-            self.executeDDL1(cur)
-            self.assertRaises(self.driver.Error, cur.next)
-
-            # cursor.next should return None if a query retrieves '
-            # no rows
-            cur.execute('select name from %sbooze' % self.table_prefix)
-            self.assertRaises(StopIteration, cur.next)
-            self.failUnless(cur.rowcount in (-1, 0))
-
-            # cursor.next should raise an Error if called after
-            # executing a query that cannnot return rows
-            cur.execute("%s into %sbooze values ('Victoria Bitter')" % (
-                self.insert, self.table_prefix
-                ))
-            self.assertRaises(self.driver.Error, cur.next)
-
-            cur.execute('select name from %sbooze' % self.table_prefix)
-            r = cur.next()
-            self.assertEqual(len(r), 1, 'cursor.next should have retrieved a 
row with one column')
-            self.assertEqual(r[0], 'Victoria Bitter', 'cursor.next retrieved 
incorrect data')
-            # cursor.next should raise StopIteration if no more rows available
-            self.assertRaises(StopIteration, cur.next)
-            self.failUnless(cur.rowcount in (-1, 1))
-        finally:
-            con.close()

http://git-wip-us.apache.org/repos/asf/phoenix/blob/14b57801/python/phoenixdb/tests/test_errors.py
----------------------------------------------------------------------
diff --git a/python/phoenixdb/tests/test_errors.py 
b/python/phoenixdb/tests/test_errors.py
deleted file mode 100644
index 191ccb1..0000000
--- a/python/phoenixdb/tests/test_errors.py
+++ /dev/null
@@ -1,60 +0,0 @@
-# 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.
-
-from phoenixdb.tests import DatabaseTestCase
-
-
-class ProgrammingErrorTest(DatabaseTestCase):
-
-    def test_invalid_sql(self):
-        with self.conn.cursor() as cursor:
-            with self.assertRaises(self.conn.ProgrammingError) as cm:
-                cursor.execute("UPS")
-            self.assertEqual("Syntax error. Encountered \"UPS\" at line 1, 
column 1.", cm.exception.message)
-            self.assertEqual(601, cm.exception.code)
-            self.assertEqual("42P00", cm.exception.sqlstate)
-
-
-class IntegrityErrorTest(DatabaseTestCase):
-
-    def test_null_in_pk(self):
-        self.createTable("phoenixdb_test_tbl1", "id integer primary key")
-        with self.conn.cursor() as cursor:
-            with self.assertRaises(self.conn.IntegrityError) as cm:
-                cursor.execute("UPSERT INTO phoenixdb_test_tbl1 VALUES (NULL)")
-            self.assertEqual("Constraint violation. PHOENIXDB_TEST_TBL1.ID may 
not be null", cm.exception.message)
-            self.assertEqual(218, cm.exception.code)
-            self.assertIn(cm.exception.sqlstate, ("22018", "23018"))
-
-
-class DataErrorTest(DatabaseTestCase):
-
-    def test_number_outside_of_range(self):
-        self.createTable("phoenixdb_test_tbl1", "id tinyint primary key")
-        with self.conn.cursor() as cursor:
-            with self.assertRaises(self.conn.DataError) as cm:
-                cursor.execute("UPSERT INTO phoenixdb_test_tbl1 VALUES 
(10000)")
-            self.assertEqual("Type mismatch. TINYINT and INTEGER for 10000", 
cm.exception.message)
-            self.assertEqual(203, cm.exception.code)
-            self.assertEqual("22005", cm.exception.sqlstate)
-
-    def test_division_by_zero(self):
-        self.createTable("phoenixdb_test_tbl1", "id integer primary key")
-        with self.conn.cursor() as cursor:
-            with self.assertRaises(self.conn.DataError) as cm:
-                cursor.execute("UPSERT INTO phoenixdb_test_tbl1 VALUES (2/0)")
-            self.assertEqual("Divide by zero.", cm.exception.message)
-            self.assertEqual(202, cm.exception.code)
-            self.assertEqual("22012", cm.exception.sqlstate)

http://git-wip-us.apache.org/repos/asf/phoenix/blob/14b57801/python/phoenixdb/tests/test_types.py
----------------------------------------------------------------------
diff --git a/python/phoenixdb/tests/test_types.py 
b/python/phoenixdb/tests/test_types.py
deleted file mode 100644
index 2cef0f2..0000000
--- a/python/phoenixdb/tests/test_types.py
+++ /dev/null
@@ -1,327 +0,0 @@
-# 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 sys
-import unittest
-import datetime
-import phoenixdb
-from decimal import Decimal
-from phoenixdb.tests import DatabaseTestCase
-
-
-class TypesTest(DatabaseTestCase):
-
-    def checkIntType(self, type_name, min_value, max_value):
-        self.createTable("phoenixdb_test_tbl1", "id integer primary key, val 
{}".format(type_name))
-        with self.conn.cursor() as cursor:
-            cursor.execute("UPSERT INTO phoenixdb_test_tbl1 VALUES (1, 1)")
-            cursor.execute("UPSERT INTO phoenixdb_test_tbl1 VALUES (2, NULL)")
-            cursor.execute("UPSERT INTO phoenixdb_test_tbl1 VALUES (3, ?)", 
[1])
-            cursor.execute("UPSERT INTO phoenixdb_test_tbl1 VALUES (4, ?)", 
[None])
-            cursor.execute("UPSERT INTO phoenixdb_test_tbl1 VALUES (5, ?)", 
[min_value])
-            cursor.execute("UPSERT INTO phoenixdb_test_tbl1 VALUES (6, ?)", 
[max_value])
-            cursor.execute("SELECT id, val FROM phoenixdb_test_tbl1 ORDER BY 
id")
-            self.assertEqual(cursor.description[1].type_code, phoenixdb.NUMBER)
-            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])
-
-    def test_integer(self):
-        self.checkIntType("integer", -2147483648, 2147483647)
-
-    def test_unsigned_int(self):
-        self.checkIntType("unsigned_int", 0, 2147483647)
-
-    def test_bigint(self):
-        self.checkIntType("bigint", -9223372036854775808, 9223372036854775807)
-
-    def test_unsigned_long(self):
-        self.checkIntType("unsigned_long", 0, 9223372036854775807)
-
-    def test_tinyint(self):
-        self.checkIntType("tinyint", -128, 127)
-
-    def test_unsigned_tinyint(self):
-        self.checkIntType("unsigned_tinyint", 0, 127)
-
-    def test_smallint(self):
-        self.checkIntType("smallint", -32768, 32767)
-
-    def test_unsigned_smallint(self):
-        self.checkIntType("unsigned_smallint", 0, 32767)
-
-    def checkFloatType(self, type_name, min_value, max_value):
-        self.createTable("phoenixdb_test_tbl1", "id integer primary key, val 
{}".format(type_name))
-        with self.conn.cursor() as cursor:
-            cursor.execute("UPSERT INTO phoenixdb_test_tbl1 VALUES (1, 1)")
-            cursor.execute("UPSERT INTO phoenixdb_test_tbl1 VALUES (2, NULL)")
-            cursor.execute("UPSERT INTO phoenixdb_test_tbl1 VALUES (3, ?)", 
[1])
-            cursor.execute("UPSERT INTO phoenixdb_test_tbl1 VALUES (4, ?)", 
[None])
-            cursor.execute("UPSERT INTO phoenixdb_test_tbl1 VALUES (5, ?)", 
[min_value])
-            cursor.execute("UPSERT INTO phoenixdb_test_tbl1 VALUES (6, ?)", 
[max_value])
-            cursor.execute("SELECT id, val FROM phoenixdb_test_tbl1 ORDER BY 
id")
-            self.assertEqual(cursor.description[1].type_code, phoenixdb.NUMBER)
-            rows = cursor.fetchall()
-            self.assertEqual([r[0] for r in rows], [1, 2, 3, 4, 5, 6])
-            self.assertEqual(rows[0][1], 1.0)
-            self.assertEqual(rows[1][1], None)
-            self.assertEqual(rows[2][1], 1.0)
-            self.assertEqual(rows[3][1], None)
-            self.assertAlmostEqual(rows[4][1], min_value)
-            self.assertAlmostEqual(rows[5][1], max_value)
-
-    def test_float(self):
-        self.checkFloatType("float", -3.4028234663852886e+38, 
3.4028234663852886e+38)
-
-    def test_unsigned_float(self):
-        self.checkFloatType("unsigned_float", 0, 3.4028234663852886e+38)
-
-    def test_double(self):
-        self.checkFloatType("double", -1.7976931348623158E+308, 
1.7976931348623158E+308)
-
-    def test_unsigned_double(self):
-        self.checkFloatType("unsigned_double", 0, 1.7976931348623158E+308)
-
-    def test_decimal(self):
-        self.createTable("phoenixdb_test_tbl1", "id integer primary key, val 
decimal(8,3)")
-        with self.conn.cursor() as cursor:
-            cursor.execute("UPSERT INTO phoenixdb_test_tbl1 VALUES (1, 
33333.333)")
-            cursor.execute("UPSERT INTO phoenixdb_test_tbl1 VALUES (2, NULL)")
-            cursor.execute("UPSERT INTO phoenixdb_test_tbl1 VALUES (3, ?)", 
[33333.333])
-            cursor.execute("UPSERT INTO phoenixdb_test_tbl1 VALUES (4, ?)", 
[Decimal('33333.333')])
-            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.description[1].type_code, phoenixdb.NUMBER)
-            rows = cursor.fetchall()
-            self.assertEqual([r[0] for r in rows], [1, 2, 3, 4, 5])
-            self.assertEqual(rows[0][1], Decimal('33333.333'))
-            self.assertEqual(rows[1][1], None)
-            self.assertEqual(rows[2][1], Decimal('33333.333'))
-            self.assertEqual(rows[3][1], Decimal('33333.333'))
-            self.assertEqual(rows[4][1], None)
-            self.assertRaises(
-                self.conn.DatabaseError, cursor.execute,
-                "UPSERT INTO phoenixdb_test_tbl1 VALUES (100, ?)", 
[Decimal('1234567890')])
-            self.assertRaises(
-                self.conn.DatabaseError, cursor.execute,
-                "UPSERT INTO phoenixdb_test_tbl1 VALUES (101, ?)", 
[Decimal('123456.789')])
-
-    def test_boolean(self):
-        self.createTable("phoenixdb_test_tbl1", "id integer primary key, val 
boolean")
-        with self.conn.cursor() as cursor:
-            cursor.execute("UPSERT INTO phoenixdb_test_tbl1 VALUES (1, TRUE)")
-            cursor.execute("UPSERT INTO phoenixdb_test_tbl1 VALUES (2, FALSE)")
-            cursor.execute("UPSERT INTO phoenixdb_test_tbl1 VALUES (3, NULL)")
-            cursor.execute("UPSERT INTO phoenixdb_test_tbl1 VALUES (4, ?)", 
[True])
-            cursor.execute("UPSERT INTO phoenixdb_test_tbl1 VALUES (5, ?)", 
[False])
-            cursor.execute("UPSERT INTO phoenixdb_test_tbl1 VALUES (6, ?)", 
[None])
-            cursor.execute("SELECT id, val FROM phoenixdb_test_tbl1 ORDER BY 
id")
-            self.assertEqual(cursor.description[1].type_code, 
phoenixdb.BOOLEAN)
-            self.assertEqual(cursor.fetchall(), [[1, True], [2, False], [3, 
None], [4, True], [5, False], [6, None]])
-
-    def test_time(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, 
'1970-01-01 12:01:02')")
-            cursor.execute("UPSERT INTO phoenixdb_test_tbl1 VALUES (2, NULL)")
-            cursor.execute("UPSERT INTO phoenixdb_test_tbl1 VALUES (3, ?)", 
[phoenixdb.Time(12, 1, 2)])
-            cursor.execute("UPSERT INTO phoenixdb_test_tbl1 VALUES (4, ?)", 
[datetime.time(12, 1, 2)])
-            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.time(12, 1, 2)],
-                [2, None],
-                [3, datetime.time(12, 1, 2)],
-                [4, datetime.time(12, 1, 2)],
-                [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)],
-            ])
-
-    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:
-            cursor.execute("UPSERT INTO phoenixdb_test_tbl1 VALUES (1, 'abc')")
-            cursor.execute("UPSERT INTO phoenixdb_test_tbl1 VALUES (2, NULL)")
-            cursor.execute("UPSERT INTO phoenixdb_test_tbl1 VALUES (3, ?)", 
['abc'])
-            cursor.execute("UPSERT INTO phoenixdb_test_tbl1 VALUES (4, ?)", 
[None])
-            cursor.execute("UPSERT INTO phoenixdb_test_tbl1 VALUES (5, '')")
-            cursor.execute("UPSERT INTO phoenixdb_test_tbl1 VALUES (6, ?)", 
[''])
-            cursor.execute("SELECT id, val FROM phoenixdb_test_tbl1 ORDER BY 
id")
-            self.assertEqual(cursor.fetchall(), [[1, 'abc'], [2, None], [3, 
'abc'], [4, None], [5, None], [6, None]])
-
-    def test_varchar_very_long(self):
-        self.createTable("phoenixdb_test_tbl1", "id integer primary key, val 
varchar")
-        with self.conn.cursor() as cursor:
-            value = '1234567890' * 1000
-            cursor.execute("UPSERT INTO phoenixdb_test_tbl1 VALUES (1, ?)", 
[value])
-            cursor.execute("SELECT id, val FROM phoenixdb_test_tbl1 ORDER BY 
id")
-            self.assertEqual(cursor.fetchall(), [[1, value]])
-
-    def test_varchar_limited(self):
-        self.createTable("phoenixdb_test_tbl1", "id integer primary key, val 
varchar(2)")
-        with self.conn.cursor() as cursor:
-            cursor.execute("UPSERT INTO phoenixdb_test_tbl1 VALUES (1, 'ab')")
-            cursor.execute("UPSERT INTO phoenixdb_test_tbl1 VALUES (2, NULL)")
-            cursor.execute("UPSERT INTO phoenixdb_test_tbl1 VALUES (3, ?)", 
['ab'])
-            cursor.execute("UPSERT INTO phoenixdb_test_tbl1 VALUES (4, ?)", 
[None])
-            cursor.execute("UPSERT INTO phoenixdb_test_tbl1 VALUES (5, '')")
-            cursor.execute("UPSERT INTO phoenixdb_test_tbl1 VALUES (6, ?)", 
[''])
-            cursor.execute("SELECT id, val FROM phoenixdb_test_tbl1 ORDER BY 
id")
-            self.assertEqual(cursor.fetchall(), [[1, 'ab'], [2, None], [3, 
'ab'], [4, None], [5, None], [6, None]])
-            self.assertRaises(self.conn.DataError, cursor.execute, "UPSERT 
INTO phoenixdb_test_tbl1 VALUES (100, 'abc')")
-
-    def test_char_null(self):
-        self.createTable("phoenixdb_test_tbl1", "id integer primary key, val 
char(2)")
-        with self.conn.cursor() as cursor:
-            cursor.execute("UPSERT INTO phoenixdb_test_tbl1 VALUES (2, NULL)")
-            cursor.execute("UPSERT INTO phoenixdb_test_tbl1 VALUES (4, ?)", 
[None])
-            cursor.execute("UPSERT INTO phoenixdb_test_tbl1 VALUES (5, '')")
-            cursor.execute("UPSERT INTO phoenixdb_test_tbl1 VALUES (6, ?)", 
[''])
-            cursor.execute("SELECT id, val FROM phoenixdb_test_tbl1 ORDER BY 
id")
-            self.assertEqual(cursor.fetchall(), [[2, None], [4, None], [5, 
None], [6, None]])
-            self.assertRaises(self.conn.DataError, cursor.execute, "UPSERT 
INTO phoenixdb_test_tbl1 VALUES (100, 'abc')")
-
-    def test_char(self):
-        self.createTable("phoenixdb_test_tbl1", "id integer primary key, val 
char(2)")
-        with self.conn.cursor() as cursor:
-            cursor.execute("UPSERT INTO phoenixdb_test_tbl1 VALUES (1, 'ab')")
-            cursor.execute("UPSERT INTO phoenixdb_test_tbl1 VALUES (2, ?)", 
['ab'])
-            cursor.execute("UPSERT INTO phoenixdb_test_tbl1 VALUES (3, 'a')")
-            cursor.execute("UPSERT INTO phoenixdb_test_tbl1 VALUES (4, ?)", 
['b'])
-            cursor.execute("SELECT id, val FROM phoenixdb_test_tbl1 ORDER BY 
id")
-            self.assertEqual(cursor.fetchall(), [[1, 'ab'], [2, 'ab'], [3, 
'a'], [4, 'b']])
-            self.assertRaises(self.conn.DataError, cursor.execute, "UPSERT 
INTO phoenixdb_test_tbl1 VALUES (100, 'abc')")
-
-    def test_binary(self):
-        self.createTable("phoenixdb_test_tbl1", "id integer primary key, val 
binary(2)")
-        with self.conn.cursor() as cursor:
-            cursor.execute("UPSERT INTO phoenixdb_test_tbl1 VALUES (1, 'ab')")
-            cursor.execute("UPSERT INTO phoenixdb_test_tbl1 VALUES (2, ?)", 
[phoenixdb.Binary(b'ab')])
-            cursor.execute("UPSERT INTO phoenixdb_test_tbl1 VALUES (3, 
'\x01\x00')")
-            cursor.execute("UPSERT INTO phoenixdb_test_tbl1 VALUES (4, ?)", 
[phoenixdb.Binary(b'\x01\x00')])
-            cursor.execute("SELECT id, val FROM phoenixdb_test_tbl1 ORDER BY 
id")
-            self.assertEqual(cursor.fetchall(), [
-                [1, b'ab'],
-                [2, b'ab'],
-                [3, b'\x01\x00'],
-                [4, b'\x01\x00'],
-            ])
-
-    def test_binary_all_bytes(self):
-        self.createTable("phoenixdb_test_tbl1", "id integer primary key, val 
binary(256)")
-        with self.conn.cursor() as cursor:
-            if sys.version_info[0] < 3:
-                value = ''.join(map(chr, range(256)))
-            else:
-                value = bytes(range(256))
-            cursor.execute("UPSERT INTO phoenixdb_test_tbl1 VALUES (1, ?)", 
[phoenixdb.Binary(value)])
-            cursor.execute("SELECT id, val FROM phoenixdb_test_tbl1 ORDER BY 
id")
-            self.assertEqual(cursor.fetchall(), [[1, value]])
-
-    @unittest.skip("https://issues.apache.org/jira/browse/CALCITE-1050 
https://issues.apache.org/jira/browse/PHOENIX-2585";)
-    def test_array(self):
-        self.createTable("phoenixdb_test_tbl1", "id integer primary key, val 
integer[]")
-        with self.conn.cursor() as cursor:
-            cursor.execute("UPSERT INTO phoenixdb_test_tbl1 VALUES (1, 
ARRAY[1, 2])")
-            cursor.execute("UPSERT INTO phoenixdb_test_tbl1 VALUES (2, ?)", 
[[2, 3]])
-            cursor.execute("SELECT id, val FROM phoenixdb_test_tbl1 ORDER BY 
id")
-            self.assertEqual(cursor.fetchall(), [
-                [1, [1, 2]],
-                [2, [2, 3]],
-            ])

http://git-wip-us.apache.org/repos/asf/phoenix/blob/14b57801/python/phoenixdb/tox.ini
----------------------------------------------------------------------
diff --git a/python/phoenixdb/tox.ini b/python/phoenixdb/tox.ini
new file mode 100644
index 0000000..908696a
--- /dev/null
+++ b/python/phoenixdb/tox.ini
@@ -0,0 +1,24 @@
+# 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.
+
+[tox]
+envlist = py27,py35,py36
+
+[testenv]
+passenv = PHOENIXDB_TEST_DB_URL
+commands =
+  flake8
+  nosetests -v
+deps = -rrequirements.txt

Reply via email to