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 0000000000000000000000000000000000000000..ce6d8c58b2199d5cc15fa7042e089383c30c6e20 --- /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 0000000000000000000000000000000000000000..b1a77c8ac7359192ed1c40ddfe79fb29aa1a596e --- /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 2d032e65d8c7508776cc8bafc31965c82905e756..79a9d730868bfe5d3fa01d679a4abfe9ee7811f0 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 353bc84752597b1fd0728f35f45b15cb46fc0ae2..70db6bba13a8b52b9f707400b80d1302542dbc34 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 Binary files a/src/connector/python/windows/python2/dist/taos-1.4.11-py3-none-any.whl and /dev/null differ 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 Binary files a/src/connector/python/windows/python2/dist/taos-1.4.11.tar.gz and /dev/null differ 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 Binary files /dev/null and b/src/connector/python/windows/python2/dist/taos-1.4.15-py2-none-any.whl differ 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 Binary files /dev/null and b/src/connector/python/windows/python2/dist/taos-1.4.15.tar.gz differ diff --git a/src/connector/python/windows/python2/setup.py b/src/connector/python/windows/python2/setup.py index d31cd3752562f943dd93849aefa92f49abce03e4..cace06f443b113b1efef4e15133eee96bbef91d3 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 0000000000000000000000000000000000000000..9673ab6c5cd27eaa998b6e537bee90e72aeffc8d --- /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 52b5647c6a690b8cd70c432ee323287be078c04d..23a38056c07fbfca16754614dc0389d6893893ff 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 d3f5a12faa99758192ecc4ed3fc22c9249232e86..8b137891791fe96927ad78e64b0aad7bded08bdc 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 bb442feabdde9fc9c6e9bfca85ca25a1ba0e42ab..6b5f0c008b9a67f85944b090fb33fc84bfcaaf7b 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 508a35f1dd1ed6df5e0c4cfe6545a964f722d7a0..4894488bc8d4e594c11a8be61fbea278ca2588fa 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 0000000000000000000000000000000000000000..526329d657c72b9fec2751651d513cfb36a448a1 --- /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 0000000000000000000000000000000000000000..ba24209552600d6ee75258f929eeff829dd7b675 --- /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 0000000000000000000000000000000000000000..a994bceaf61894ac0bf9a719a574d00a09c584a5 --- /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 0000000000000000000000000000000000000000..933efbde228334ac3d039c3a614dc45064d86366 --- /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 0000000000000000000000000000000000000000..f1c22bdb512224ac712b78b15ec00207587e65c5 --- /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 0000000000000000000000000000000000000000..24508a72ed78bb6231187bb6de34d57182e31b22 --- /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 1a73558b2dd4d7b0e6f74950009a63d7d96f0247..0000000000000000000000000000000000000000 --- 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 0000000000000000000000000000000000000000..191327092b8e08799979cfa2ff7e7818af513c7f --- /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