From 8b226b5b7903f5f8320e882bf526c8b753f13dbf Mon Sep 17 00:00:00 2001 From: slguan Date: Wed, 31 Jul 2019 10:03:30 +0800 Subject: [PATCH] Fix the issue #222 --- .../linux/python2/taos.egg-info/PKG-INFO | 13 + .../linux/python3/taos.egg-info/PKG-INFO | 13 + src/connector/python/windows/python2/LICENSE | 24 +- .../python/windows/python2/README.md | 2 +- .../python2/dist/taos-1.4.11-py3-none-any.whl | Bin 4515 -> 0 bytes .../windows/python2/dist/taos-1.4.11.tar.gz | Bin 3966 -> 0 bytes .../python2/dist/taos-1.4.15-py2-none-any.whl | Bin 0 -> 9164 bytes .../windows/python2/dist/taos-1.4.15.tar.gz | Bin 0 -> 7021 bytes src/connector/python/windows/python2/setup.py | 40 +- .../windows/python2/taos.egg-info/PKG-INFO | 13 + .../windows/python2/taos.egg-info/SOURCES.txt | 19 +- .../taos.egg-info/dependency_links.txt | 2 +- .../python2/taos.egg-info/top_level.txt | 2 +- .../python/windows/python2/taos/__init__.py | 28 +- .../python/windows/python2/taos/cinterface.py | 354 ++++++++++++++++ .../python/windows/python2/taos/connection.py | 80 ++++ .../python/windows/python2/taos/constants.py | 33 ++ .../python/windows/python2/taos/cursor.py | 178 ++++++++ .../python/windows/python2/taos/dbapi.py | 38 ++ .../python/windows/python2/taos/error.py | 57 +++ .../python/windows/python2/taos/pytdengine.py | 391 ------------------ .../windows/python3/taos.egg-info/PKG-INFO | 13 + 22 files changed, 863 insertions(+), 437 deletions(-) create mode 100644 src/connector/python/linux/python2/taos.egg-info/PKG-INFO create mode 100644 src/connector/python/linux/python3/taos.egg-info/PKG-INFO delete mode 100644 src/connector/python/windows/python2/dist/taos-1.4.11-py3-none-any.whl delete mode 100644 src/connector/python/windows/python2/dist/taos-1.4.11.tar.gz create mode 100644 src/connector/python/windows/python2/dist/taos-1.4.15-py2-none-any.whl create mode 100644 src/connector/python/windows/python2/dist/taos-1.4.15.tar.gz create mode 100644 src/connector/python/windows/python2/taos.egg-info/PKG-INFO create mode 100644 src/connector/python/windows/python2/taos/cinterface.py create mode 100644 src/connector/python/windows/python2/taos/connection.py create mode 100644 src/connector/python/windows/python2/taos/constants.py create mode 100644 src/connector/python/windows/python2/taos/cursor.py create mode 100644 src/connector/python/windows/python2/taos/dbapi.py create mode 100644 src/connector/python/windows/python2/taos/error.py delete mode 100644 src/connector/python/windows/python2/taos/pytdengine.py create mode 100644 src/connector/python/windows/python3/taos.egg-info/PKG-INFO diff --git a/src/connector/python/linux/python2/taos.egg-info/PKG-INFO b/src/connector/python/linux/python2/taos.egg-info/PKG-INFO new file mode 100644 index 0000000000..ce6d8c58b2 --- /dev/null +++ b/src/connector/python/linux/python2/taos.egg-info/PKG-INFO @@ -0,0 +1,13 @@ +Metadata-Version: 2.1 +Name: taos +Version: 1.4.15 +Summary: TDengine python client package +Home-page: https://github.com/pypa/sampleproject +Author: Taosdata Inc. +Author-email: support@taosdata.com +License: UNKNOWN +Description: # TDengine python client interface +Platform: UNKNOWN +Classifier: Programming Language :: Python :: 2 +Classifier: Operating System :: Linux +Description-Content-Type: text/markdown diff --git a/src/connector/python/linux/python3/taos.egg-info/PKG-INFO b/src/connector/python/linux/python3/taos.egg-info/PKG-INFO new file mode 100644 index 0000000000..b1a77c8ac7 --- /dev/null +++ b/src/connector/python/linux/python3/taos.egg-info/PKG-INFO @@ -0,0 +1,13 @@ +Metadata-Version: 2.1 +Name: taos +Version: 1.4.15 +Summary: TDengine python client package +Home-page: https://github.com/pypa/sampleproject +Author: Taosdata Inc. +Author-email: support@taosdata.com +License: UNKNOWN +Description: # TDengine python client interface +Platform: UNKNOWN +Classifier: Programming Language :: Python :: 3 +Classifier: Operating System :: Linux +Description-Content-Type: text/markdown diff --git a/src/connector/python/windows/python2/LICENSE b/src/connector/python/windows/python2/LICENSE index 2d032e65d8..79a9d73086 100644 --- a/src/connector/python/windows/python2/LICENSE +++ b/src/connector/python/windows/python2/LICENSE @@ -1,12 +1,12 @@ - Copyright (c) 2019 TAOS Data, Inc. - -This program is free software: you can use, redistribute, and/or modify -it under the terms of the GNU Affero General Public License, version 3 -or later ("AGPL"), as published by the Free Software Foundation. - -This program is distributed in the hope that it will be useful, but WITHOUT -ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -FITNESS FOR A PARTICULAR PURPOSE. - -You should have received a copy of the GNU Affero General Public License -along with this program. If not, see . + Copyright (c) 2019 TAOS Data, Inc. + +This program is free software: you can use, redistribute, and/or modify +it under the terms of the GNU Affero General Public License, version 3 +or later ("AGPL"), as published by the Free Software Foundation. + +This program is distributed in the hope that it will be useful, but WITHOUT +ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +FITNESS FOR A PARTICULAR PURPOSE. + +You should have received a copy of the GNU Affero General Public License +along with this program. If not, see . diff --git a/src/connector/python/windows/python2/README.md b/src/connector/python/windows/python2/README.md index 353bc84752..70db6bba13 100644 --- a/src/connector/python/windows/python2/README.md +++ b/src/connector/python/windows/python2/README.md @@ -1 +1 @@ -# TDengine python client interface +# TDengine python client interface \ No newline at end of file diff --git a/src/connector/python/windows/python2/dist/taos-1.4.11-py3-none-any.whl b/src/connector/python/windows/python2/dist/taos-1.4.11-py3-none-any.whl deleted file mode 100644 index efe772206da6af5de1680507e89e070ef7aaf770..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 4515 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 diff --git a/src/connector/python/windows/python2/dist/taos-1.4.11.tar.gz b/src/connector/python/windows/python2/dist/taos-1.4.11.tar.gz deleted file mode 100644 index 984228e3bb00bca2a0a735a440b4feb8cc306b79..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 3966 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 Yr72BmN>iHBls|U)FH_;G@c?)L0Mj7M%m4rY diff --git a/src/connector/python/windows/python2/dist/taos-1.4.15-py2-none-any.whl b/src/connector/python/windows/python2/dist/taos-1.4.15-py2-none-any.whl new file mode 100644 index 0000000000000000000000000000000000000000..6e97d3a5e40a62e80b633ab7e728839b4299b506 GIT binary patch literal 9164 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 EAD9U-YXATM literal 0 HcmV?d00001 diff --git a/src/connector/python/windows/python2/dist/taos-1.4.15.tar.gz b/src/connector/python/windows/python2/dist/taos-1.4.15.tar.gz new file mode 100644 index 0000000000000000000000000000000000000000..dcc20602426b475eaa88cd9aa9877a53cd72a62e GIT binary patch literal 7021 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 L&7L3w0LTCU|B>eQ literal 0 HcmV?d00001 diff --git a/src/connector/python/windows/python2/setup.py b/src/connector/python/windows/python2/setup.py index d31cd37525..cace06f443 100644 --- a/src/connector/python/windows/python2/setup.py +++ b/src/connector/python/windows/python2/setup.py @@ -1,20 +1,20 @@ -import setuptools - -with open("README.md", "r") as fh: - long_description = fh.read() - -setuptools.setup( - name="taos", - version="1.4.11", - author="Taosdata Inc.", - author_email="support@taosdata.com", - description="TDengine python client package", - long_description=long_description, - long_description_content_type="text/markdown", - url="https://github.com/pypa/sampleproject", - packages=setuptools.find_packages(), - classifiers=[ - "Programming Language :: Python :: 2", - "Operating System :: Windows", - ], -) +import setuptools + +with open("README.md", "r") as fh: + long_description = fh.read() + +setuptools.setup( + name="taos", + version="1.4.15", + author="Taosdata Inc.", + author_email="support@taosdata.com", + description="TDengine python client package", + long_description=long_description, + long_description_content_type="text/markdown", + url="https://github.com/pypa/sampleproject", + packages=setuptools.find_packages(), + classifiers=[ + "Programming Language :: Python :: 2", + "Operating System :: Windows", + ], +) diff --git a/src/connector/python/windows/python2/taos.egg-info/PKG-INFO b/src/connector/python/windows/python2/taos.egg-info/PKG-INFO new file mode 100644 index 0000000000..9673ab6c5c --- /dev/null +++ b/src/connector/python/windows/python2/taos.egg-info/PKG-INFO @@ -0,0 +1,13 @@ +Metadata-Version: 2.1 +Name: taos +Version: 1.4.15 +Summary: TDengine python client package +Home-page: https://github.com/pypa/sampleproject +Author: Taosdata Inc. +Author-email: support@taosdata.com +License: UNKNOWN +Description: # TDengine python client interface +Platform: UNKNOWN +Classifier: Programming Language :: Python :: 2 +Classifier: Operating System :: Windows +Description-Content-Type: text/markdown diff --git a/src/connector/python/windows/python2/taos.egg-info/SOURCES.txt b/src/connector/python/windows/python2/taos.egg-info/SOURCES.txt index 52b5647c6a..23a38056c0 100644 --- a/src/connector/python/windows/python2/taos.egg-info/SOURCES.txt +++ b/src/connector/python/windows/python2/taos.egg-info/SOURCES.txt @@ -1,8 +1,13 @@ -README.md -setup.py -taos/__init__.py -taos/pytdengine.py -taos.egg-info/PKG-INFO -taos.egg-info/SOURCES.txt -taos.egg-info/dependency_links.txt +README.md +setup.py +taos/__init__.py +taos/cinterface.py +taos/connection.py +taos/constants.py +taos/cursor.py +taos/dbapi.py +taos/error.py +taos.egg-info/PKG-INFO +taos.egg-info/SOURCES.txt +taos.egg-info/dependency_links.txt taos.egg-info/top_level.txt \ No newline at end of file diff --git a/src/connector/python/windows/python2/taos.egg-info/dependency_links.txt b/src/connector/python/windows/python2/taos.egg-info/dependency_links.txt index d3f5a12faa..8b13789179 100644 --- a/src/connector/python/windows/python2/taos.egg-info/dependency_links.txt +++ b/src/connector/python/windows/python2/taos.egg-info/dependency_links.txt @@ -1 +1 @@ - + diff --git a/src/connector/python/windows/python2/taos.egg-info/top_level.txt b/src/connector/python/windows/python2/taos.egg-info/top_level.txt index bb442feabd..6b5f0c008b 100644 --- a/src/connector/python/windows/python2/taos.egg-info/top_level.txt +++ b/src/connector/python/windows/python2/taos.egg-info/top_level.txt @@ -1 +1 @@ -taos +taos diff --git a/src/connector/python/windows/python2/taos/__init__.py b/src/connector/python/windows/python2/taos/__init__.py index 508a35f1dd..4894488bc8 100644 --- a/src/connector/python/windows/python2/taos/__init__.py +++ b/src/connector/python/windows/python2/taos/__init__.py @@ -1,4 +1,24 @@ -from .pytdengine import TaosCursor -from .pytdengine import TaosConnection -from .pytdengine import connector -# from .pytdengine import TaosClass + +from .connection import TDengineConnection +from .cursor import TDengineCursor + +# Globals +apilevel = '2.0' +threadsafety = 0 +paramstyle = 'pyformat' + +__all__ = ['connection', 'cursor'] + +def connect(*args, **kwargs): + """ Function to return a TDengine connector object + + Current supporting keyword parameters: + @dsn: Data source name as string + @user: Username as string(optional) + @password: Password as string(optional) + @host: Hostname(optional) + @database: Database name(optional) + + @rtype: TDengineConnector + """ + return TDengineConnection(*args, **kwargs) \ No newline at end of file diff --git a/src/connector/python/windows/python2/taos/cinterface.py b/src/connector/python/windows/python2/taos/cinterface.py new file mode 100644 index 0000000000..526329d657 --- /dev/null +++ b/src/connector/python/windows/python2/taos/cinterface.py @@ -0,0 +1,354 @@ +import ctypes +from .constants import FieldType +from .error import * +import math +import datetime + +def _convert_millisecond_to_datetime(milli): + return datetime.datetime.fromtimestamp(milli/1000.0) + +def _convert_microsecond_to_datetime(micro): + return datetime.datetime.fromtimestamp(micro/1000000.0) + +def _crow_timestamp_to_python(data, num_of_rows, nbytes=None, micro=False): + """Function to convert C bool row to python row + """ + _timstamp_converter = _convert_millisecond_to_datetime + if micro: + _timstamp_converter = _convert_microsecond_to_datetime + + if num_of_rows > 0: + return list(map(_timstamp_converter, ctypes.cast(data, ctypes.POINTER(ctypes.c_longlong))[:abs(num_of_rows)][::-1])) + else: + return list(map(_timstamp_converter, ctypes.cast(data, ctypes.POINTER(ctypes.c_longlong))[:abs(num_of_rows)])) + +def _crow_bool_to_python(data, num_of_rows, nbytes=None, micro=False): + """Function to convert C bool row to python row + """ + if num_of_rows > 0: + return [ None if ele == FieldType.C_BOOL_NULL else bool(ele) for ele in ctypes.cast(data, ctypes.POINTER(ctypes.c_byte))[:abs(num_of_rows)][::-1] ] + else: + return [ None if ele == FieldType.C_BOOL_NULL else bool(ele) for ele in ctypes.cast(data, ctypes.POINTER(ctypes.c_bool))[:abs(num_of_rows)] ] + +def _crow_tinyint_to_python(data, num_of_rows, nbytes=None, micro=False): + """Function to convert C tinyint row to python row + """ + if num_of_rows > 0: + return [ None if ele == FieldType.C_TINYINT_NULL else ele for ele in ctypes.cast(data, ctypes.POINTER(ctypes.c_byte))[:abs(num_of_rows)][::-1] ] + else: + return [ None if ele == FieldType.C_TINYINT_NULL else ele for ele in ctypes.cast(data, ctypes.POINTER(ctypes.c_byte))[:abs(num_of_rows)] ] + +def _crow_smallint_to_python(data, num_of_rows, nbytes=None, micro=False): + """Function to convert C smallint row to python row + """ + if num_of_rows > 0: + return [ None if ele == FieldType.C_SMALLINT_NULL else ele for ele in ctypes.cast(data, ctypes.POINTER(ctypes.c_short))[:abs(num_of_rows)][::-1]] + else: + return [ None if ele == FieldType.C_SMALLINT_NULL else ele for ele in ctypes.cast(data, ctypes.POINTER(ctypes.c_short))[:abs(num_of_rows)] ] + +def _crow_int_to_python(data, num_of_rows, nbytes=None, micro=False): + """Function to convert C int row to python row + """ + if num_of_rows > 0: + return [ None if ele == FieldType.C_INT_NULL else ele for ele in ctypes.cast(data, ctypes.POINTER(ctypes.c_int))[:abs(num_of_rows)][::-1] ] + else: + return [ None if ele == FieldType.C_INT_NULL else ele for ele in ctypes.cast(data, ctypes.POINTER(ctypes.c_int))[:abs(num_of_rows)] ] + +def _crow_bigint_to_python(data, num_of_rows, nbytes=None, micro=False): + """Function to convert C bigint row to python row + """ + if num_of_rows > 0: + return [ None if ele == FieldType.C_BIGINT_NULL else ele for ele in ctypes.cast(data, ctypes.POINTER(ctypes.c_longlong))[:abs(num_of_rows)][::-1] ] + else: + return [ None if ele == FieldType.C_BIGINT_NULL else ele for ele in ctypes.cast(data, ctypes.POINTER(ctypes.c_longlong))[:abs(num_of_rows)] ] + +def _crow_float_to_python(data, num_of_rows, nbytes=None, micro=False): + """Function to convert C float row to python row + """ + if num_of_rows > 0: + return [ None if math.isnan(ele) else ele for ele in ctypes.cast(data, ctypes.POINTER(ctypes.c_float))[:abs(num_of_rows)][::-1] ] + else: + return [ None if math.isnan(ele) else ele for ele in ctypes.cast(data, ctypes.POINTER(ctypes.c_float))[:abs(num_of_rows)] ] + +def _crow_double_to_python(data, num_of_rows, nbytes=None, micro=False): + """Function to convert C double row to python row + """ + if num_of_rows > 0: + return [ None if math.isnan(ele) else ele for ele in ctypes.cast(data, ctypes.POINTER(ctypes.c_double))[:abs(num_of_rows)][::-1] ] + else: + return [ None if math.isnan(ele) else ele for ele in ctypes.cast(data, ctypes.POINTER(ctypes.c_double))[:abs(num_of_rows)] ] + +def _crow_binary_to_python(data, num_of_rows, nbytes=None, micro=False): + """Function to convert C binary row to python row + """ + if num_of_rows > 0: + return [ None if ele.value[0:1] == FieldType.C_BINARY_NULL else ele.value.decode('utf-8') for ele in (ctypes.cast(data, ctypes.POINTER(ctypes.c_char * nbytes)))[:abs(num_of_rows)][::-1]] + else: + return [ None if ele.value[0:1] == FieldType.C_BINARY_NULL else ele.value.decode('utf-8') for ele in (ctypes.cast(data, ctypes.POINTER(ctypes.c_char * nbytes)))[:abs(num_of_rows)]] + +def _crow_nchar_to_python(data, num_of_rows, nbytes=None, micro=False): + """Function to convert C nchar row to python row + """ + assert(nbytes is not None) + + res = [] + + for i in range(abs(num_of_rows)): + try: + if num_of_rows >= 0: + res.append( (ctypes.cast(data+nbytes*(abs(num_of_rows - i -1)), ctypes.POINTER(ctypes.c_wchar * (nbytes//4))))[0].value ) + else: + res.append( (ctypes.cast(data+nbytes*i, ctypes.POINTER(ctypes.c_wchar * (nbytes//4))))[0].value ) + except ValueError: + res.append(None) + + return res + # if num_of_rows > 0: + # for i in range(abs(num_of_rows)): + # try: + # res.append( (ctypes.cast(data+nbytes*i, ctypes.POINTER(ctypes.c_wchar * (nbytes//4))))[0].value ) + # except ValueError: + # res.append(None) + # return res + # # return [ele.value for ele in (ctypes.cast(data, ctypes.POINTER(ctypes.c_wchar * (nbytes//4))))[:abs(num_of_rows)][::-1]] + # else: + # return [ele.value for ele in (ctypes.cast(data, ctypes.POINTER(ctypes.c_wchar * (nbytes//4))))[:abs(num_of_rows)]] + +_CONVERT_FUNC = { + FieldType.C_BOOL: _crow_bool_to_python, + FieldType.C_TINYINT : _crow_tinyint_to_python, + FieldType.C_SMALLINT : _crow_smallint_to_python, + FieldType.C_INT : _crow_int_to_python, + FieldType.C_BIGINT : _crow_bigint_to_python, + FieldType.C_FLOAT : _crow_float_to_python, + FieldType.C_DOUBLE : _crow_double_to_python, + FieldType.C_BINARY: _crow_binary_to_python, + FieldType.C_TIMESTAMP : _crow_timestamp_to_python, + FieldType.C_NCHAR : _crow_nchar_to_python +} + +# Corresponding TAOS_FIELD structure in C +class TaosField(ctypes.Structure): + _fields_ = [('name', ctypes.c_char * 64), + ('bytes', ctypes.c_short), + ('type', ctypes.c_char)] + +# C interface class +class CTaosInterface(object): + + libtaos = ctypes.windll.LoadLibrary('taos') + + libtaos.taos_fetch_fields.restype = ctypes.POINTER(TaosField) + libtaos.taos_init.restype = None + libtaos.taos_connect.restype = ctypes.c_void_p + libtaos.taos_use_result.restype = ctypes.c_void_p + libtaos.taos_fetch_row.restype = ctypes.POINTER(ctypes.c_void_p) + libtaos.taos_errstr.restype = ctypes.c_char_p + + def __init__(self, config=None): + ''' + Function to initialize the class + @host : str, hostname to connect + @user : str, username to connect to server + @password : str, password to connect to server + @db : str, default db to use when log in + @config : str, config directory + + @rtype : None + ''' + if config is None: + self._config = ctypes.c_char_p(None) + else: + try: + self._config = ctypes.c_char_p(config.encode('utf-8')) + except AttributeError: + raise AttributeError("config is expected as a str") + + if config != None: + CTaosInterface.libtaos.taos_options(3, self._config) + + CTaosInterface.libtaos.taos_init() + + @property + def config(self): + """ Get current config + """ + return self._config + + def connect(self, host=None, user="root", password="taosdata", db=None, port=0): + ''' + Function to connect to server + + @rtype: c_void_p, TDengine handle + ''' + # host + try: + _host = ctypes.c_char_p(host.encode( + "utf-8")) if host != None else ctypes.c_char_p(None) + except AttributeError: + raise AttributeError("host is expected as a str") + + # user + try: + _user = ctypes.c_char_p(user.encode("utf-8")) + except AttributeError: + raise AttributeError("user is expected as a str") + + # password + try: + _password = ctypes.c_char_p(password.encode("utf-8")) + except AttributeError: + raise AttributeError("password is expected as a str") + + # db + try: + _db = ctypes.c_char_p( + db.encode("utf-8")) if db != None else ctypes.c_char_p(None) + except AttributeError: + raise AttributeError("db is expected as a str") + + # port + try: + _port = ctypes.c_int(port) + except TypeError: + raise TypeError("port is expected as an int") + + connection = ctypes.c_void_p(CTaosInterface.libtaos.taos_connect( + _host, _user, _password, _db, _port)) + + if connection.value == None: + print('connect to TDengine failed') + # sys.exit(1) + else: + print('connect to TDengine success') + + return connection + + @staticmethod + def close(connection): + '''Close the TDengine handle + ''' + CTaosInterface.libtaos.taos_close(connection) + print('connection is closed') + + @staticmethod + def query(connection, sql): + '''Run SQL + + @sql: str, sql string to run + + @rtype: 0 on success and -1 on failure + ''' + try: + return CTaosInterface.libtaos.taos_query(connection, ctypes.c_char_p(sql.encode('utf-8'))) + except AttributeError: + raise AttributeError("sql is expected as a string") + finally: + CTaosInterface.libtaos.close(connection) + + @staticmethod + def affectedRows(connection): + """The affected rows after runing query + """ + return CTaosInterface.libtaos.taos_affected_rows(connection) + + @staticmethod + def useResult(connection): + '''Use result after calling self.query + ''' + result = ctypes.c_void_p(CTaosInterface.libtaos.taos_use_result(connection)) + fields = [] + pfields = CTaosInterface.fetchFields(result) + for i in range(CTaosInterface.fieldsCount(connection)): + fields.append({'name': pfields[i].name.decode('utf-8'), + 'bytes': pfields[i].bytes, + 'type': ord(pfields[i].type)}) + + return result, fields + + @staticmethod + def fetchBlock(result, fields): + pblock = ctypes.c_void_p(0) + num_of_rows = CTaosInterface.libtaos.taos_fetch_block( + result, ctypes.byref(pblock)) + + if num_of_rows == 0: + return None, 0 + + blocks = [None] * len(fields) + isMicro = (CTaosInterface.libtaos.taos_result_precision(result) == FieldType.C_TIMESTAMP_MICRO) + for i in range(len(fields)): + data = ctypes.cast(pblock, ctypes.POINTER(ctypes.c_void_p))[i] + + if fields[i]['type'] not in _CONVERT_FUNC: + raise DatabaseError("Invalid data type returned from database") + + blocks[i] = _CONVERT_FUNC[fields[i]['type']](data, num_of_rows, fields[i]['bytes'], isMicro) + + return blocks, abs(num_of_rows) + + @staticmethod + def freeResult(result): + CTaosInterface.libtaos.taos_free_result(result) + result.value = None + + @staticmethod + def fieldsCount(connection): + return CTaosInterface.libtaos.taos_field_count(connection) + + @staticmethod + def fetchFields(result): + return CTaosInterface.libtaos.taos_fetch_fields(result) + + # @staticmethod + # def fetchRow(result, fields): + # l = [] + # row = CTaosInterface.libtaos.taos_fetch_row(result) + # if not row: + # return None + + # for i in range(len(fields)): + # l.append(CTaosInterface.getDataValue( + # row[i], fields[i]['type'], fields[i]['bytes'])) + + # return tuple(l) + + # @staticmethod + # def getDataValue(data, dtype, byte): + # ''' + # ''' + # if not data: + # return None + + # if (dtype == CTaosInterface.TSDB_DATA_TYPE_BOOL): + # return ctypes.cast(data, ctypes.POINTER(ctypes.c_bool))[0] + # elif (dtype == CTaosInterface.TSDB_DATA_TYPE_TINYINT): + # return ctypes.cast(data, ctypes.POINTER(ctypes.c_byte))[0] + # elif (dtype == CTaosInterface.TSDB_DATA_TYPE_SMALLINT): + # return ctypes.cast(data, ctypes.POINTER(ctypes.c_short))[0] + # elif (dtype == CTaosInterface.TSDB_DATA_TYPE_INT): + # return ctypes.cast(data, ctypes.POINTER(ctypes.c_int))[0] + # elif (dtype == CTaosInterface.TSDB_DATA_TYPE_BIGINT): + # return ctypes.cast(data, ctypes.POINTER(ctypes.c_long))[0] + # elif (dtype == CTaosInterface.TSDB_DATA_TYPE_FLOAT): + # return ctypes.cast(data, ctypes.POINTER(ctypes.c_float))[0] + # elif (dtype == CTaosInterface.TSDB_DATA_TYPE_DOUBLE): + # return ctypes.cast(data, ctypes.POINTER(ctypes.c_double))[0] + # elif (dtype == CTaosInterface.TSDB_DATA_TYPE_BINARY): + # return (ctypes.cast(data, ctypes.POINTER(ctypes.c_char))[0:byte]).rstrip('\x00') + # elif (dtype == CTaosInterface.TSDB_DATA_TYPE_TIMESTAMP): + # return ctypes.cast(data, ctypes.POINTER(ctypes.c_long))[0] + # elif (dtype == CTaosInterface.TSDB_DATA_TYPE_NCHAR): + # return (ctypes.cast(data, ctypes.c_char_p).value).rstrip('\x00') + + @staticmethod + def errno(connection): + """Return the error number. + """ + return CTaosInterface.libtaos.taos_errno(connection) + + @staticmethod + def errStr(connection): + """Return the error styring + """ + return CTaosInterface.libtaos.taos_errstr(connection) \ No newline at end of file diff --git a/src/connector/python/windows/python2/taos/connection.py b/src/connector/python/windows/python2/taos/connection.py new file mode 100644 index 0000000000..ba24209552 --- /dev/null +++ b/src/connector/python/windows/python2/taos/connection.py @@ -0,0 +1,80 @@ +# from .cursor import TDengineCursor +from .cursor import TDengineCursor +from .cinterface import CTaosInterface + +class TDengineConnection(object): + """ TDengine connection object + """ + def __init__(self, *args, **kwargs): + self._conn = None + self._host = None + self._user = "root" + self._password = "taosdata" + self._database = None + self._port = 0 + self._config = None + self._chandle = None + + self.config(**kwargs) + + def config(self, **kwargs): + # host + if 'host' in kwargs: + self._host = kwargs['host'] + + # user + if 'user' in kwargs: + self._user = kwargs['user'] + + # password + if 'password' in kwargs: + self._password = kwargs['password'] + + # database + if 'database' in kwargs: + self._database = kwargs['database'] + + # port + if 'port' in kwargs: + self._port = kwargs['port'] + + # config + if 'config' in kwargs: + self._config = kwargs['config'] + + self._chandle = CTaosInterface(self._config) + self._conn = self._chandle.connect(self._host, self._user, self._password, self._database, self._port) + + def close(self): + """Close current connection. + """ + return CTaosInterface.close(self._conn) + + def cursor(self): + """Return a new Cursor object using the connection. + """ + return TDengineCursor(self) + + def commit(self): + """Commit any pending transaction to the database. + + Since TDengine do not support transactions, the implement is void functionality. + """ + pass + + def rollback(self): + """Void functionality + """ + pass + + def clear_result_set(self): + """Clear unused result set on this connection. + """ + result = self._chandle.useResult(self._conn)[0] + if result: + self._chandle.freeResult(result) + +if __name__ == "__main__": + conn = TDengineConnection(host='192.168.1.107') + conn.close() + print("Hello world") \ No newline at end of file diff --git a/src/connector/python/windows/python2/taos/constants.py b/src/connector/python/windows/python2/taos/constants.py new file mode 100644 index 0000000000..a994bceaf6 --- /dev/null +++ b/src/connector/python/windows/python2/taos/constants.py @@ -0,0 +1,33 @@ +"""Constants in TDengine python +""" + +from .dbapi import * + +class FieldType(object): + """TDengine Field Types + """ + # type_code + C_NULL = 0 + C_BOOL = 1 + C_TINYINT = 2 + C_SMALLINT = 3 + C_INT = 4 + C_BIGINT = 5 + C_FLOAT = 6 + C_DOUBLE = 7 + C_BINARY = 8 + C_TIMESTAMP = 9 + C_NCHAR = 10 + # NULL value definition + # NOTE: These values should change according to C definition in tsdb.h + C_BOOL_NULL = 0x02 + C_TINYINT_NULL = -128 + C_SMALLINT_NULL = -32768 + C_INT_NULL = -2147483648 + C_BIGINT_NULL = -9223372036854775808 + C_FLOAT_NULL = float('nan') + C_DOUBLE_NULL = float('nan') + C_BINARY_NULL = bytearray([int('0xff', 16)]) + # Time precision definition + C_TIMESTAMP_MILLI = 0 + C_TIMESTAMP_MICRO = 1 diff --git a/src/connector/python/windows/python2/taos/cursor.py b/src/connector/python/windows/python2/taos/cursor.py new file mode 100644 index 0000000000..933efbde22 --- /dev/null +++ b/src/connector/python/windows/python2/taos/cursor.py @@ -0,0 +1,178 @@ +from .cinterface import CTaosInterface +from .error import * + +class TDengineCursor(object): + """Database cursor which is used to manage the context of a fetch operation. + + Attributes: + .description: Read-only attribute consists of 7-item sequences: + + > name (mondatory) + > type_code (mondatory) + > display_size + > internal_size + > precision + > scale + > null_ok + + This attribute will be None for operations that do not return rows or + if the cursor has not had an operation invoked via the .execute*() method yet. + + .rowcount:This read-only attribute specifies the number of rows that the last + .execute*() produced (for DQL statements like SELECT) or affected + """ + + def __init__(self, connection=None): + self._description = None + self._rowcount = -1 + self._connection = None + self._result = None + self._fields = None + self._block = None + self._block_rows = -1 + self._block_iter = 0 + + if connection is not None: + self._connection = connection + + def __iter__(self): + return self + + def next(self): + if self._result is None or self._fields is None: + raise OperationalError("Invalid use of fetch iterator") + + if self._block_rows <= self._block_iter: + block, self._block_rows = CTaosInterface.fetchBlock(self._result, self._fields) + if self._block_rows == 0: + raise StopIteration + self._block = list(map(tuple, zip(*block))) + self._block_iter = 0 + + data = self._block[self._block_iter] + self._block_iter += 1 + + return data + + @property + def description(self): + """Return the description of the object. + """ + return self._description + + @property + def rowcount(self): + """Return the rowcount of the object + """ + return self._rowcount + + def callproc(self, procname, *args): + """Call a stored database procedure with the given name. + + Void functionality since no stored procedures. + """ + pass + + def close(self): + """Close the cursor. + """ + if self._connection is None: + return False + + self._connection.clear_result_set() + self._reset_result() + self._connection = None + + return True + + def execute(self, operation, params=None): + """Prepare and execute a database operation (query or command). + """ + if not operation: + return None + + if not self._connection: + # TODO : change the exception raised here + raise ProgrammingError("Cursor is not connected") + + self._connection.clear_result_set() + self._reset_result() + + stmt = operation + if params is not None: + pass + + res = CTaosInterface.query(self._connection._conn, stmt) + if res == 0: + if CTaosInterface.fieldsCount(self._connection._conn) == 0: + return CTaosInterface.affectedRows(self._connection._conn) + else: + self._result, self._fields = CTaosInterface.useResult(self._connection._conn) + return self._handle_result() + else: + raise ProgrammingError(CTaosInterface.errStr(self._connection._conn)) + + def executemany(self, operation, seq_of_parameters): + """Prepare a database operation (query or command) and then execute it against all parameter sequences or mappings found in the sequence seq_of_parameters. + """ + pass + + def fetchone(self): + """Fetch the next row of a query result set, returning a single sequence, or None when no more data is available. + """ + pass + + def fetchmany(self): + pass + + def fetchall(self): + """Fetch all (remaining) rows of a query result, returning them as a sequence of sequences (e.g. a list of tuples). Note that the cursor's arraysize attribute can affect the performance of this operation. + """ + if self._result is None or self._fields is None: + raise OperationalError("Invalid use of fetchall") + + buffer = [[] for i in range(len(self._fields))] + self._rowcount = 0 + while True: + block, num_of_fields = CTaosInterface.fetchBlock(self._result, self._fields) + if num_of_fields == 0: break + self._rowcount += num_of_fields + for i in range(len(self._fields)): + buffer[i].extend(block[i]) + + self._connection.clear_result_set() + + return list(map(tuple, zip(*buffer))) + + + + def nextset(self): + """ + """ + pass + + def setinputsize(self, sizes): + pass + + def setutputsize(self, size, column=None): + pass + + def _reset_result(self): + """Reset the result to unused version. + """ + self._description = None + self._rowcount = -1 + self._result = None + self._fields = None + self._block = None + self._block_rows = -1 + self._block_iter = 0 + + def _handle_result(self): + """Handle the return result from query. + """ + self._description = [] + for ele in self._fields: + self._description.append((ele['name'], ele['type'], None, None, None, None, False)) + + return self._result \ No newline at end of file diff --git a/src/connector/python/windows/python2/taos/dbapi.py b/src/connector/python/windows/python2/taos/dbapi.py new file mode 100644 index 0000000000..f1c22bdb51 --- /dev/null +++ b/src/connector/python/windows/python2/taos/dbapi.py @@ -0,0 +1,38 @@ +"""Type Objects and Constructors. +""" + +import time +import datetime + +class DBAPITypeObject(object): + def __init__(self, *values): + self.values = values + + def __com__(self, other): + if other in self.values: + return 0 + if other < self.values: + return 1 + else: + return -1 + +Date = datetime.date +Time = datetime.time +Timestamp = datetime.datetime + +def DataFromTicks(ticks): + return Date(*time.localtime(ticks)[:3]) + +def TimeFromTicks(ticks): + return Time(*time.localtime(ticks)[3:6]) + +def TimestampFromTicks(ticks): + return Timestamp(*time.localtime(ticks)[:6]) + +Binary = bytes + +# STRING = DBAPITypeObject(*constants.FieldType.get_string_types()) +# BINARY = DBAPITypeObject(*constants.FieldType.get_binary_types()) +# NUMBER = BAPITypeObject(*constants.FieldType.get_number_types()) +# DATETIME = DBAPITypeObject(*constants.FieldType.get_timestamp_types()) +# ROWID = DBAPITypeObject() \ No newline at end of file diff --git a/src/connector/python/windows/python2/taos/error.py b/src/connector/python/windows/python2/taos/error.py new file mode 100644 index 0000000000..24508a72ed --- /dev/null +++ b/src/connector/python/windows/python2/taos/error.py @@ -0,0 +1,57 @@ +"""Python exceptions +""" + +class Error(Exception): + def __init__(self, msg=None, errno=None): + self.msg = msg + self._full_msg = self.msg + self.errno = errno + + def __str__(self): + return self._full_msg + +class Warning(Exception): + """Exception raised for important warnings like data truncations while inserting. + """ + pass + +class InterfaceError(Error): + """Exception raised for errors that are related to the database interface rather than the database itself. + """ + pass + +class DatabaseError(Error): + """Exception raised for errors that are related to the database. + """ + pass + +class DataError(DatabaseError): + """Exception raised for errors that are due to problems with the processed data like division by zero, numeric value out of range. + """ + pass + +class OperationalError(DatabaseError): + """Exception raised for errors that are related to the database's operation and not necessarily under the control of the programmer + """ + pass + + +class IntegrityError(DatabaseError): + """Exception raised when the relational integrity of the database is affected. + """ + pass + +class InternalError(DatabaseError): + """Exception raised when the database encounters an internal error. + """ + pass + +class ProgrammingError(DatabaseError): + """Exception raised for programming errors. + """ + pass + +class NotSupportedError(DatabaseError): + """Exception raised in case a method or database API was used which is not supported by the database,. + """ + pass \ No newline at end of file diff --git a/src/connector/python/windows/python2/taos/pytdengine.py b/src/connector/python/windows/python2/taos/pytdengine.py deleted file mode 100644 index 1a73558b2d..0000000000 --- a/src/connector/python/windows/python2/taos/pytdengine.py +++ /dev/null @@ -1,391 +0,0 @@ -import ctypes -import numpy as np -import pandas as pd - -class TaosField(ctypes.Structure): - _fields_ = [('name' , ctypes.c_char * 64), - ('bytes' , ctypes.c_short), - ('type' , ctypes.c_char)] - -class TaosClass(object): - ''' - ''' - TSDB_DATA_TYPE_NULL = 0 - TSDB_DATA_TYPE_BOOL = 1 - TSDB_DATA_TYPE_TINYINT = 2 - TSDB_DATA_TYPE_SMALLINT = 3 - TSDB_DATA_TYPE_INT = 4 - TSDB_DATA_TYPE_BIGINT = 5 - TSDB_DATA_TYPE_FLOAT = 6 - TSDB_DATA_TYPE_DOUBLE = 7 - TSDB_DATA_TYPE_BINARY = 8 - TSDB_DATA_TYPE_TIMESTAMP = 9 - TSDB_DATA_TYPE_NCHAR = 10 - - libtaos = ctypes.windll.LoadLibrary('taos') - - libtaos.taos_fetch_fields.restype = ctypes.POINTER(TaosField) - libtaos.taos_init.restype = None - libtaos.taos_connect.restype = ctypes.c_void_p - libtaos.taos_use_result.restype = ctypes.c_void_p - libtaos.taos_fetch_row.restype = ctypes.POINTER(ctypes.c_void_p) - libtaos.taos_errstr.restype = ctypes.c_char_p - - def __init__(self, host=None, user='root', password='taosdata', db=None, port=0, config=None): - ''' - Function to initialize the class - @host : str, hostname to connect - @user : str, username to connect to server - @password : str, password to connect to server - @db : str, default db to use when log in - @config : str, config directory - - @rtype : None - ''' - self.host = ctypes.c_char_p(host) - self.user = ctypes.c_char_p(user) - self.password = ctypes.c_char_p(password) - self.db = ctypes.c_char_p(db) - self.config = ctypes.c_char_p(config) - self.port = ctypes.c_int(port) - - if config != None: - TaosClass.libtaos.taos_options(2, self.config) - - TaosClass.libtaos.taos_init() - - def connect(self): - ''' - Function to connect to server - - @rtype: c_void_p, TDengine handle - ''' - connection = ctypes.c_void_p(TaosClass.libtaos.taos_connect(self.host, self.user, self.password, self.db, self.port)) - - if connection.value == None: - print('connect to TDengine failed') - # sys.exit(1) - else: - print('connect to TDengine success') - - return connection - - @staticmethod - def close(connection): - ''' - Close the TDengine handle - ''' - TaosClass.libtaos.taos_close(connection) - print('connection is closed') - - @staticmethod - def fetchBlock(result, fields): - pblock = ctypes.c_void_p(0) - num_of_rows = TaosClass.libtaos.taos_fetch_block(result, ctypes.byref(pblock)) - - if num_of_rows == 0: - return None, 0 - - blocks = [None] * len(fields) - for i in range(len(fields)): - data = ctypes.cast(pblock, ctypes.POINTER(ctypes.c_void_p))[i] - - if (fields[i]['type'] == TaosClass.TSDB_DATA_TYPE_BOOL): - if num_of_rows > 0: - blocks[i] = ctypes.cast(data, ctypes.POINTER(ctypes.c_bool))[:abs(num_of_rows)][::-1] - else: - blocks[i] = ctypes.cast(data, ctypes.POINTER(ctypes.c_bool))[:abs(num_of_rows)] - elif (fields[i]['type'] == TaosClass.TSDB_DATA_TYPE_TINYINT): - if num_of_rows > 0: - blocks[i] = ctypes.cast(data, ctypes.POINTER(ctypes.c_byte))[:abs(num_of_rows)][::-1] - else: - blocks[i] = ctypes.cast(data, ctypes.POINTER(ctypes.c_byte))[:abs(num_of_rows)] - elif (fields[i]['type'] == TaosClass.TSDB_DATA_TYPE_SMALLINT): - if num_of_rows > 0: - blocks[i] = ctypes.cast(data, ctypes.POINTER(ctypes.c_short))[:abs(num_of_rows)][::-1] - else: - blocks[i] = ctypes.cast(data, ctypes.POINTER(ctypes.c_short))[:abs(num_of_rows)] - elif (fields[i]['type'] == TaosClass.TSDB_DATA_TYPE_INT): - if num_of_rows > 0: - blocks[i] = ctypes.cast(data, ctypes.POINTER(ctypes.c_int))[:abs(num_of_rows)][::-1] - else: - blocks[i] = ctypes.cast(data, ctypes.POINTER(ctypes.c_int))[:abs(num_of_rows)] - elif (fields[i]['type'] == TaosClass.TSDB_DATA_TYPE_BIGINT): - if num_of_rows > 0: - blocks[i] = ctypes.cast(data, ctypes.POINTER(ctypes.c_longlong))[:abs(num_of_rows)][::-1] - else: - blocks[i] = ctypes.cast(data, ctypes.POINTER(ctypes.c_longlong))[:abs(num_of_rows)] - elif (fields[i]['type'] == TaosClass.TSDB_DATA_TYPE_FLOAT): - if num_of_rows > 0: - blocks[i] = ctypes.cast(data, ctypes.POINTER(ctypes.c_float))[:abs(num_of_rows)][::-1] - else: - blocks[i] = ctypes.cast(data, ctypes.POINTER(ctypes.c_float))[:abs(num_of_rows)] - elif (fields[i]['type'] == TaosClass.TSDB_DATA_TYPE_DOUBLE): - if num_of_rows > 0: - blocks[i] = ctypes.cast(data, ctypes.POINTER(ctypes.c_double))[:abs(num_of_rows)][::-1] - else: - blocks[i] = ctypes.cast(data, ctypes.POINTER(ctypes.c_double))[:abs(num_of_rows)] - elif (fields[i]['type'] == TaosClass.TSDB_DATA_TYPE_TIMESTAMP): - if num_of_rows > 0: - blocks[i] = ctypes.cast(data, ctypes.POINTER(ctypes.c_longlong))[:abs(num_of_rows)][::-1] - else: - blocks[i] = ctypes.cast(data, ctypes.POINTER(ctypes.c_longlong))[:abs(num_of_rows)] - # TODO : Make it more efficient - elif (fields[i]['type'] == TaosClass.TSDB_DATA_TYPE_BINARY): - if num_of_rows > 0: - blocks[i] = [ele.value for ele in (ctypes.cast(data, ctypes.POINTER(ctypes.c_char * fields[i]['bytes'])))[:abs(num_of_rows)][::-1]] - else: - blocks[i] = [ele.value for ele in (ctypes.cast(data, ctypes.POINTER(ctypes.c_char * fields[i]['bytes'])))[:abs(num_of_rows)]] - elif (fields[i]['type'] == TaosClass.TSDB_DATA_TYPE_NCHAR): - if num_of_rows > 0: - blocks[i] = [ele.value for ele in (ctypes.cast(data, ctypes.POINTER(ctypes.c_wchar * (fields[i]['bytes']/4))))[:abs(num_of_rows)][::-1]] - else: - blocks[i] = [ele.value for ele in (ctypes.cast(data, ctypes.POINTER(ctypes.c_wchar * (fields[i]['bytes']/4))))[:abs(num_of_rows)]] - - return blocks, abs(num_of_rows) - - @staticmethod - def query(connection, sql): - ''' - Run SQL - - @sql: str, sql string to run - - @rtype: 0 on success and -1 on failure - ''' - return TaosClass.libtaos.taos_query(connection, ctypes.c_char_p(sql)) - - @staticmethod - def useResult(connection): - ''' - Use result after calling self.query - ''' - result = ctypes.c_void_p(TaosClass.libtaos.taos_use_result(connection)) - fields = [] - pfields = TaosClass.fetchFields(result) - for i in range(TaosClass.fieldsCount(connection)): - fields.append({'name': pfields[i].name, 'bytes':pfields[i].bytes, 'type': ord(pfields[i].type)}) - - return result, fields - - @staticmethod - def freeResult(result): - TaosClass.libtaos.taos_free_result(result) - result.value = None - - @staticmethod - def fieldsCount(connection): - return TaosClass.libtaos.taos_field_count(connection) - - @staticmethod - def fetchFields(result): - return TaosClass.libtaos.taos_fetch_fields(result) - - @staticmethod - def fetchRow(result, fields): - l = [] - row = TaosClass.libtaos.taos_fetch_row(result) - if not row: return None - - for i in range(len(fields)): - l.append(TaosClass.getDataValue(row[i], fields[i]['type'], fields[i]['bytes'])) - - return tuple(l) - - @staticmethod - def getDataValue(data, dtype, byte): - ''' - ''' - if not data: return None - - if (dtype == TaosClass.TSDB_DATA_TYPE_BOOL): - return ctypes.cast(data, ctypes.POINTER(ctypes.c_bool))[0] - elif (dtype == TaosClass.TSDB_DATA_TYPE_TINYINT): - return ctypes.cast(data, ctypes.POINTER(ctypes.c_byte))[0] - elif (dtype == TaosClass.TSDB_DATA_TYPE_SMALLINT): - return ctypes.cast(data, ctypes.POINTER(ctypes.c_short))[0] - elif (dtype == TaosClass.TSDB_DATA_TYPE_INT): - return ctypes.cast(data, ctypes.POINTER(ctypes.c_int))[0] - elif (dtype == TaosClass.TSDB_DATA_TYPE_BIGINT): - return ctypes.cast(data, ctypes.POINTER(ctypes.c_long))[0] - elif (dtype == TaosClass.TSDB_DATA_TYPE_FLOAT): - return ctypes.cast(data, ctypes.POINTER(ctypes.c_float))[0] - elif (dtype == TaosClass.TSDB_DATA_TYPE_DOUBLE): - return ctypes.cast(data, ctypes.POINTER(ctypes.c_double))[0] - elif (dtype == TaosClass.TSDB_DATA_TYPE_BINARY): - return (ctypes.cast(data, ctypes.POINTER(ctypes.c_char))[0:byte]).rstrip('\x00') - elif (dtype == TaosClass.TSDB_DATA_TYPE_TIMESTAMP): - return ctypes.cast(data, ctypes.POINTER(ctypes.c_long))[0] - elif (dtype == TaosClass.TSDB_DATA_TYPE_NCHAR): - return (ctypes.cast(data, ctypes.c_char_p).value).rstrip('\x00') - - @staticmethod - def affectedRows(connection): - return TaosClass.libtaos.taos_affected_rows(connection) - - @staticmethod - def errno(connection): - return TaosClass.libtaos.taos_errno(connection) - - @staticmethod - def errStr(connection): - return TaosClass.libtaos.taos_errstr(connection) - - -class TaosCursor(): - ''' - Object in TDengine python client which the same as a connection to TDengine server. - ''' - def __init__(self, connection): - self.connection = connection - # self.buffered = buffered; - self.result = ctypes.c_void_p(0) - self.fields = [] - - self.buffer = None - self.iter = 0 - - # def __iter__(self): - # self.iter = 0 - # return self - # - # def next(self): - # if self.buffered: - # if self.iter >= len(self.buffer[0]): - # raise StopIteration - # else: - # return tuple(row[self.iter] for row in self.buffer) - # else: - # if self.iter >= len(self.buffer[0]): - # self.buffer, num_of_fields = TaosClass.fetchBlock(self.result, self.fields) - # if num_of_fields == 0: - # raise StopIteration - # else: - # self.iter = 1 - # return tuple(row[self.iter-1] for row in self.buffer) - # else: - # self.iter += 1 - # l = tuple(row[self.iter-1] for row in self.buffer) - - def fetchall(self, format=list): - ''' - Fetch data after run commands like 'show/select/describe' TaosCursor.execute. - - @format: list -> return a list of list, default and the fastest - dict -> return a dictionary with the name of each column as the key - numpy.array->return an array - pandas.DataFrame->return data as the form of pandas.DataFram - - @rtype: depends on the format - ''' - if TaosClass.fieldsCount(self.connection) != 0: - # select or show command - self.result, self.fields = TaosClass.useResult(self.connection) - self.iter = 0 - # if self.buffered: - self.buffer = [[] for i in range(len(self.fields))] - while True: - block, num_of_fields = TaosClass.fetchBlock(self.result, self.fields) - if num_of_fields == 0: break; - for i in range(len(self.fields)): - self.buffer[i].extend(block[i]) - self.freeResult() - - if format == list: - return self.buffer - elif format == dict: - return dict(zip(self.columns(), self.buffer)) - elif format == np.array: - return [np.asarray(self.buffer[i]) for i in range(len(self.columns()))] - elif format == pd.DataFrame: - l = [np.asarray(self.buffer[i]) for i in range(len(self.columns()))] - return pd.DataFrame.from_records(dict(zip(self.columns(), l))) - else: - return None - else: - return None - - def execute(self, sql): - ''' - run sql command - - @rtype: int, 0 for succeed and others for failure - ''' - # release previous result - self.freeResult() - - res = TaosClass.query(self.connection, sql) - if res != 0: return res - else: return 0 - - def freeResult(self): - if self.result.value != None: - TaosClass.freeResult(self.result) - - def columns(self): - ''' - return the column names when query using TaosCursor.execute. - - @rtype: list of str - ''' - return [self.fields[col]['name'] for col in range(len(self.fields))] - - def error(self): - ''' - return error string of if execute is wrong - - @rtype: str - ''' - return TaosClass.errStr(self.connection) - - def close(self): - self.freeResult() - TaosClass.close(self.connection) - self.connection.value = None - -class TaosConnection: - ''' - TDengine connection object - ''' - def __init__(self, host=None, user='root', passwd='taosdata', database=None, port=0, config=None): - ''' - @host : IP address of the TDengine server host - @user : user name to log in - @password : password used to log in - @database : database to use when logging in - @port : port number - @config : configuration directory - ''' - self.taos = TaosClass(host, user, passwd, database, port, config) - self.cursors = [] - - def cursor(self): - ''' - Generate a TaosCursor object, each object is the same as a connection to TDengine - - @rtype: TaosCursor - ''' - self.cursors.append(TaosCursor(self.taos.connect())) - return self.cursors[-1] - - def close(self): - ''' - Close the connection - ''' - for cur in self.cursors: - cur.close() - -def connector(host=None, user='root', passwd='taosdata', database=None, port=0, config=None): - ''' - Function to create a TaosConnection object - - @host : str, ipaddr of the TDengine server - @user : str, username used to login - @passwd : str, password used to login - @database : str, database to use when connect, if database is not None and not exists on server, it will result in a connection failure - @port : port number - @config : configuration directory - - @rtype : TaosConnection object - ''' - return TaosConnection(host, user, passwd, database, port, config) diff --git a/src/connector/python/windows/python3/taos.egg-info/PKG-INFO b/src/connector/python/windows/python3/taos.egg-info/PKG-INFO new file mode 100644 index 0000000000..191327092b --- /dev/null +++ b/src/connector/python/windows/python3/taos.egg-info/PKG-INFO @@ -0,0 +1,13 @@ +Metadata-Version: 2.1 +Name: taos +Version: 1.4.15 +Summary: TDengine python client package +Home-page: https://github.com/pypa/sampleproject +Author: Hongze Cheng +Author-email: hzcheng@taosdata.com +License: UNKNOWN +Description: # TDengine python client interface +Platform: UNKNOWN +Classifier: Programming Language :: Python :: 3 +Classifier: Operating System :: Windows +Description-Content-Type: text/markdown -- GitLab