Merge pull request #5202 from taosdata/feature/sangshuduo/TD-2971-python-connector-support-unsigned
[TD-2971] feature: make python connector support unsigned type.
This commit is contained in:
commit
78af455071
|
@ -5,7 +5,7 @@ with open("README.md", "r") as fh:
|
||||||
|
|
||||||
setuptools.setup(
|
setuptools.setup(
|
||||||
name="taos",
|
name="taos",
|
||||||
version="2.0.5",
|
version="2.0.6",
|
||||||
author="Taosdata Inc.",
|
author="Taosdata Inc.",
|
||||||
author_email="support@taosdata.com",
|
author_email="support@taosdata.com",
|
||||||
description="TDengine python client package",
|
description="TDengine python client package",
|
||||||
|
|
|
@ -3,12 +3,12 @@ from .connection import TDengineConnection
|
||||||
from .cursor import TDengineCursor
|
from .cursor import TDengineCursor
|
||||||
|
|
||||||
# Globals
|
# Globals
|
||||||
apilevel = '2.0.3'
|
|
||||||
threadsafety = 0
|
threadsafety = 0
|
||||||
paramstyle = 'pyformat'
|
paramstyle = 'pyformat'
|
||||||
|
|
||||||
__all__ = ['connection', 'cursor']
|
__all__ = ['connection', 'cursor']
|
||||||
|
|
||||||
|
|
||||||
def connect(*args, **kwargs):
|
def connect(*args, **kwargs):
|
||||||
""" Function to return a TDengine connector object
|
""" Function to return a TDengine connector object
|
||||||
|
|
||||||
|
@ -21,4 +21,4 @@ def connect(*args, **kwargs):
|
||||||
|
|
||||||
@rtype: TDengineConnector
|
@rtype: TDengineConnector
|
||||||
"""
|
"""
|
||||||
return TDengineConnection(*args, **kwargs)
|
return TDengineConnection(*args, **kwargs)
|
||||||
|
|
|
@ -4,11 +4,14 @@ from .error import *
|
||||||
import math
|
import math
|
||||||
import datetime
|
import datetime
|
||||||
|
|
||||||
|
|
||||||
def _convert_millisecond_to_datetime(milli):
|
def _convert_millisecond_to_datetime(milli):
|
||||||
return datetime.datetime.fromtimestamp(milli/1000.0)
|
return datetime.datetime.fromtimestamp(milli / 1000.0)
|
||||||
|
|
||||||
|
|
||||||
def _convert_microsecond_to_datetime(micro):
|
def _convert_microsecond_to_datetime(micro):
|
||||||
return datetime.datetime.fromtimestamp(micro/1000000.0)
|
return datetime.datetime.fromtimestamp(micro / 1000000.0)
|
||||||
|
|
||||||
|
|
||||||
def _crow_timestamp_to_python(data, num_of_rows, nbytes=None, micro=False):
|
def _crow_timestamp_to_python(data, num_of_rows, nbytes=None, micro=False):
|
||||||
"""Function to convert C bool row to python row
|
"""Function to convert C bool row to python row
|
||||||
|
@ -18,168 +21,309 @@ def _crow_timestamp_to_python(data, num_of_rows, nbytes=None, micro=False):
|
||||||
_timestamp_converter = _convert_microsecond_to_datetime
|
_timestamp_converter = _convert_microsecond_to_datetime
|
||||||
|
|
||||||
if num_of_rows > 0:
|
if num_of_rows > 0:
|
||||||
return list(map(_timestamp_converter, ctypes.cast(data, ctypes.POINTER(ctypes.c_long))[:abs(num_of_rows)]))
|
return list(map(_timestamp_converter, ctypes.cast(
|
||||||
|
data, ctypes.POINTER(ctypes.c_long))[:abs(num_of_rows)]))
|
||||||
else:
|
else:
|
||||||
return list(map(_timestamp_converter, ctypes.cast(data, ctypes.POINTER(ctypes.c_long))[:abs(num_of_rows)]))
|
return list(map(_timestamp_converter, ctypes.cast(
|
||||||
|
data, ctypes.POINTER(ctypes.c_long))[:abs(num_of_rows)]))
|
||||||
|
|
||||||
|
|
||||||
def _crow_bool_to_python(data, num_of_rows, nbytes=None, micro=False):
|
def _crow_bool_to_python(data, num_of_rows, nbytes=None, micro=False):
|
||||||
"""Function to convert C bool row to python row
|
"""Function to convert C bool row to python row
|
||||||
"""
|
"""
|
||||||
if num_of_rows > 0:
|
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)] ]
|
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)]]
|
||||||
else:
|
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)] ]
|
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):
|
def _crow_tinyint_to_python(data, num_of_rows, nbytes=None, micro=False):
|
||||||
"""Function to convert C tinyint row to python row
|
"""Function to convert C tinyint row to python row
|
||||||
"""
|
"""
|
||||||
if num_of_rows > 0:
|
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)] ]
|
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)]]
|
||||||
else:
|
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)] ]
|
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_tinyint_unsigned_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_UNSIGNED_NULL else ele for ele in ctypes.cast(
|
||||||
|
data, ctypes.POINTER(
|
||||||
|
ctypes.c_byte))[
|
||||||
|
:abs(num_of_rows)]]
|
||||||
|
else:
|
||||||
|
return [
|
||||||
|
None if ele == FieldType.C_TINYINT_UNSIGNED_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):
|
def _crow_smallint_to_python(data, num_of_rows, nbytes=None, micro=False):
|
||||||
"""Function to convert C smallint row to python row
|
"""Function to convert C smallint row to python row
|
||||||
"""
|
"""
|
||||||
if num_of_rows > 0:
|
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)]]
|
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)]]
|
||||||
else:
|
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)] ]
|
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_smallint_unsigned_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_UNSIGNED_NULL else ele for ele in ctypes.cast(
|
||||||
|
data, ctypes.POINTER(
|
||||||
|
ctypes.c_short))[
|
||||||
|
:abs(num_of_rows)]]
|
||||||
|
else:
|
||||||
|
return [
|
||||||
|
None if ele == FieldType.C_SMALLINT_UNSIGNED_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):
|
def _crow_int_to_python(data, num_of_rows, nbytes=None, micro=False):
|
||||||
"""Function to convert C int row to python row
|
"""Function to convert C int row to python row
|
||||||
"""
|
"""
|
||||||
if num_of_rows > 0:
|
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)] ]
|
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)]]
|
||||||
else:
|
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)] ]
|
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_int_unsigned_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_UNSIGNED_NULL else ele for ele in ctypes.cast(
|
||||||
|
data, ctypes.POINTER(
|
||||||
|
ctypes.c_int))[
|
||||||
|
:abs(num_of_rows)]]
|
||||||
|
else:
|
||||||
|
return [
|
||||||
|
None if ele == FieldType.C_INT_UNSIGNED_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):
|
def _crow_bigint_to_python(data, num_of_rows, nbytes=None, micro=False):
|
||||||
"""Function to convert C bigint row to python row
|
"""Function to convert C bigint row to python row
|
||||||
"""
|
"""
|
||||||
if num_of_rows > 0:
|
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_long))[:abs(num_of_rows)] ]
|
return [None if ele == FieldType.C_BIGINT_NULL else ele for ele in ctypes.cast(
|
||||||
|
data, ctypes.POINTER(ctypes.c_long))[:abs(num_of_rows)]]
|
||||||
else:
|
else:
|
||||||
return [ None if ele == FieldType.C_BIGINT_NULL else ele for ele in ctypes.cast(data, ctypes.POINTER(ctypes.c_long))[:abs(num_of_rows)] ]
|
return [None if ele == FieldType.C_BIGINT_NULL else ele for ele in ctypes.cast(
|
||||||
|
data, ctypes.POINTER(ctypes.c_long))[:abs(num_of_rows)]]
|
||||||
|
|
||||||
|
|
||||||
|
def _crow_bigint_unsigned_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_UNSIGNED_NULL else ele for ele in ctypes.cast(
|
||||||
|
data, ctypes.POINTER(
|
||||||
|
ctypes.c_long))[
|
||||||
|
:abs(num_of_rows)]]
|
||||||
|
else:
|
||||||
|
return [
|
||||||
|
None if ele == FieldType.C_BIGINT_UNSIGNED_NULL else ele for ele in ctypes.cast(
|
||||||
|
data, ctypes.POINTER(
|
||||||
|
ctypes.c_long))[
|
||||||
|
:abs(num_of_rows)]]
|
||||||
|
|
||||||
|
|
||||||
def _crow_float_to_python(data, num_of_rows, nbytes=None, micro=False):
|
def _crow_float_to_python(data, num_of_rows, nbytes=None, micro=False):
|
||||||
"""Function to convert C float row to python row
|
"""Function to convert C float row to python row
|
||||||
"""
|
"""
|
||||||
if num_of_rows > 0:
|
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)] ]
|
return [None if math.isnan(ele) else ele for ele in ctypes.cast(
|
||||||
|
data, ctypes.POINTER(ctypes.c_float))[:abs(num_of_rows)]]
|
||||||
else:
|
else:
|
||||||
return [ None if math.isnan(ele) else ele for ele in ctypes.cast(data, ctypes.POINTER(ctypes.c_float))[:abs(num_of_rows)] ]
|
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):
|
def _crow_double_to_python(data, num_of_rows, nbytes=None, micro=False):
|
||||||
"""Function to convert C double row to python row
|
"""Function to convert C double row to python row
|
||||||
"""
|
"""
|
||||||
if num_of_rows > 0:
|
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)] ]
|
return [None if math.isnan(ele) else ele for ele in ctypes.cast(
|
||||||
|
data, ctypes.POINTER(ctypes.c_double))[:abs(num_of_rows)]]
|
||||||
else:
|
else:
|
||||||
return [ None if math.isnan(ele) else ele for ele in ctypes.cast(data, ctypes.POINTER(ctypes.c_double))[:abs(num_of_rows)] ]
|
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):
|
def _crow_binary_to_python(data, num_of_rows, nbytes=None, micro=False):
|
||||||
"""Function to convert C binary row to python row
|
"""Function to convert C binary row to python row
|
||||||
"""
|
"""
|
||||||
assert(nbytes is not None)
|
assert(nbytes is not None)
|
||||||
if num_of_rows > 0:
|
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)]]
|
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)]]
|
||||||
else:
|
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)]]
|
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):
|
def _crow_nchar_to_python(data, num_of_rows, nbytes=None, micro=False):
|
||||||
"""Function to convert C nchar row to python row
|
"""Function to convert C nchar row to python row
|
||||||
"""
|
"""
|
||||||
assert(nbytes is not None)
|
assert(nbytes is not None)
|
||||||
res=[]
|
res = []
|
||||||
for i in range(abs(num_of_rows)):
|
for i in range(abs(num_of_rows)):
|
||||||
try:
|
try:
|
||||||
if num_of_rows >= 0:
|
if num_of_rows >= 0:
|
||||||
tmpstr = ctypes.c_char_p(data)
|
tmpstr = ctypes.c_char_p(data)
|
||||||
res.append( tmpstr.value.decode() )
|
res.append(tmpstr.value.decode())
|
||||||
else:
|
else:
|
||||||
res.append( (ctypes.cast(data+nbytes*i, ctypes.POINTER(ctypes.c_wchar * (nbytes//4))))[0].value )
|
res.append((ctypes.cast(data + nbytes * i,
|
||||||
|
ctypes.POINTER(ctypes.c_wchar * (nbytes // 4))))[0].value)
|
||||||
except ValueError:
|
except ValueError:
|
||||||
res.append(None)
|
res.append(None)
|
||||||
|
|
||||||
return res
|
return res
|
||||||
|
|
||||||
|
|
||||||
def _crow_binary_to_python_block(data, num_of_rows, nbytes=None, micro=False):
|
def _crow_binary_to_python_block(data, num_of_rows, nbytes=None, micro=False):
|
||||||
"""Function to convert C binary row to python row
|
"""Function to convert C binary row to python row
|
||||||
"""
|
"""
|
||||||
assert(nbytes is not None)
|
assert(nbytes is not None)
|
||||||
res=[]
|
res = []
|
||||||
if num_of_rows > 0:
|
if num_of_rows > 0:
|
||||||
for i in range(abs(num_of_rows)):
|
for i in range(abs(num_of_rows)):
|
||||||
try:
|
try:
|
||||||
rbyte=ctypes.cast(data+nbytes*i,ctypes.POINTER(ctypes.c_short))[:1].pop()
|
rbyte = ctypes.cast(
|
||||||
tmpstr = ctypes.c_char_p(data+nbytes*i+2)
|
data + nbytes * i,
|
||||||
res.append( tmpstr.value.decode()[0:rbyte] )
|
ctypes.POINTER(
|
||||||
|
ctypes.c_short))[
|
||||||
|
:1].pop()
|
||||||
|
tmpstr = ctypes.c_char_p(data + nbytes * i + 2)
|
||||||
|
res.append(tmpstr.value.decode()[0:rbyte])
|
||||||
except ValueError:
|
except ValueError:
|
||||||
res.append(None)
|
res.append(None)
|
||||||
else:
|
else:
|
||||||
for i in range(abs(num_of_rows)):
|
for i in range(abs(num_of_rows)):
|
||||||
try:
|
try:
|
||||||
rbyte=ctypes.cast(data+nbytes*i,ctypes.POINTER(ctypes.c_short))[:1].pop()
|
rbyte = ctypes.cast(
|
||||||
tmpstr = ctypes.c_char_p(data+nbytes*i+2)
|
data + nbytes * i,
|
||||||
res.append( tmpstr.value.decode()[0:rbyte] )
|
ctypes.POINTER(
|
||||||
|
ctypes.c_short))[
|
||||||
|
:1].pop()
|
||||||
|
tmpstr = ctypes.c_char_p(data + nbytes * i + 2)
|
||||||
|
res.append(tmpstr.value.decode()[0:rbyte])
|
||||||
except ValueError:
|
except ValueError:
|
||||||
res.append(None)
|
res.append(None)
|
||||||
return res
|
return res
|
||||||
|
|
||||||
|
|
||||||
def _crow_nchar_to_python_block(data, num_of_rows, nbytes=None, micro=False):
|
def _crow_nchar_to_python_block(data, num_of_rows, nbytes=None, micro=False):
|
||||||
"""Function to convert C nchar row to python row
|
"""Function to convert C nchar row to python row
|
||||||
"""
|
"""
|
||||||
assert(nbytes is not None)
|
assert(nbytes is not None)
|
||||||
res=[]
|
res = []
|
||||||
if num_of_rows >= 0:
|
if num_of_rows >= 0:
|
||||||
for i in range(abs(num_of_rows)):
|
for i in range(abs(num_of_rows)):
|
||||||
try:
|
try:
|
||||||
tmpstr = ctypes.c_char_p(data+nbytes*i+2)
|
tmpstr = ctypes.c_char_p(data + nbytes * i + 2)
|
||||||
res.append( tmpstr.value.decode() )
|
res.append(tmpstr.value.decode())
|
||||||
except ValueError:
|
except ValueError:
|
||||||
res.append(None)
|
res.append(None)
|
||||||
else:
|
else:
|
||||||
for i in range(abs(num_of_rows)):
|
for i in range(abs(num_of_rows)):
|
||||||
try:
|
try:
|
||||||
res.append( (ctypes.cast(data+nbytes*i+2, ctypes.POINTER(ctypes.c_wchar * (nbytes//4))))[0].value )
|
res.append((ctypes.cast(data + nbytes * i + 2,
|
||||||
|
ctypes.POINTER(ctypes.c_wchar * (nbytes // 4))))[0].value)
|
||||||
except ValueError:
|
except ValueError:
|
||||||
res.append(None)
|
res.append(None)
|
||||||
return res
|
return res
|
||||||
|
|
||||||
|
|
||||||
_CONVERT_FUNC = {
|
_CONVERT_FUNC = {
|
||||||
FieldType.C_BOOL: _crow_bool_to_python,
|
FieldType.C_BOOL: _crow_bool_to_python,
|
||||||
FieldType.C_TINYINT : _crow_tinyint_to_python,
|
FieldType.C_TINYINT: _crow_tinyint_to_python,
|
||||||
FieldType.C_SMALLINT : _crow_smallint_to_python,
|
FieldType.C_SMALLINT: _crow_smallint_to_python,
|
||||||
FieldType.C_INT : _crow_int_to_python,
|
FieldType.C_INT: _crow_int_to_python,
|
||||||
FieldType.C_BIGINT : _crow_bigint_to_python,
|
FieldType.C_BIGINT: _crow_bigint_to_python,
|
||||||
FieldType.C_FLOAT : _crow_float_to_python,
|
FieldType.C_FLOAT: _crow_float_to_python,
|
||||||
FieldType.C_DOUBLE : _crow_double_to_python,
|
FieldType.C_DOUBLE: _crow_double_to_python,
|
||||||
FieldType.C_BINARY: _crow_binary_to_python,
|
FieldType.C_BINARY: _crow_binary_to_python,
|
||||||
FieldType.C_TIMESTAMP : _crow_timestamp_to_python,
|
FieldType.C_TIMESTAMP: _crow_timestamp_to_python,
|
||||||
FieldType.C_NCHAR : _crow_nchar_to_python
|
FieldType.C_NCHAR: _crow_nchar_to_python,
|
||||||
|
FieldType.C_TINYINT_UNSIGNED: _crow_tinyint_unsigned_to_python,
|
||||||
|
FieldType.C_SMALLINT_UNSIGNED: _crow_smallint_unsigned_to_python,
|
||||||
|
FieldType.C_INT_UNSIGNED: _crow_int_unsigned_to_python,
|
||||||
|
FieldType.C_BIGINT_UNSIGNED: _crow_bigint_unsigned_to_python
|
||||||
}
|
}
|
||||||
|
|
||||||
_CONVERT_FUNC_BLOCK = {
|
_CONVERT_FUNC_BLOCK = {
|
||||||
FieldType.C_BOOL: _crow_bool_to_python,
|
FieldType.C_BOOL: _crow_bool_to_python,
|
||||||
FieldType.C_TINYINT : _crow_tinyint_to_python,
|
FieldType.C_TINYINT: _crow_tinyint_to_python,
|
||||||
FieldType.C_SMALLINT : _crow_smallint_to_python,
|
FieldType.C_SMALLINT: _crow_smallint_to_python,
|
||||||
FieldType.C_INT : _crow_int_to_python,
|
FieldType.C_INT: _crow_int_to_python,
|
||||||
FieldType.C_BIGINT : _crow_bigint_to_python,
|
FieldType.C_BIGINT: _crow_bigint_to_python,
|
||||||
FieldType.C_FLOAT : _crow_float_to_python,
|
FieldType.C_FLOAT: _crow_float_to_python,
|
||||||
FieldType.C_DOUBLE : _crow_double_to_python,
|
FieldType.C_DOUBLE: _crow_double_to_python,
|
||||||
FieldType.C_BINARY: _crow_binary_to_python_block,
|
FieldType.C_BINARY: _crow_binary_to_python_block,
|
||||||
FieldType.C_TIMESTAMP : _crow_timestamp_to_python,
|
FieldType.C_TIMESTAMP: _crow_timestamp_to_python,
|
||||||
FieldType.C_NCHAR : _crow_nchar_to_python_block
|
FieldType.C_NCHAR: _crow_nchar_to_python_block,
|
||||||
|
FieldType.C_TINYINT_UNSIGNED: _crow_tinyint_unsigned_to_python,
|
||||||
|
FieldType.C_SMALLINT_UNSIGNED: _crow_smallint_unsigned_to_python,
|
||||||
|
FieldType.C_INT_UNSIGNED: _crow_int_unsigned_to_python,
|
||||||
|
FieldType.C_BIGINT_UNSIGNED: _crow_bigint_unsigned_to_python
|
||||||
}
|
}
|
||||||
|
|
||||||
# Corresponding TAOS_FIELD structure in C
|
# Corresponding TAOS_FIELD structure in C
|
||||||
|
|
||||||
|
|
||||||
class TaosField(ctypes.Structure):
|
class TaosField(ctypes.Structure):
|
||||||
_fields_ = [('name', ctypes.c_char * 65),
|
_fields_ = [('name', ctypes.c_char * 65),
|
||||||
('type', ctypes.c_char),
|
('type', ctypes.c_char),
|
||||||
('bytes', ctypes.c_short)]
|
('bytes', ctypes.c_short)]
|
||||||
|
|
||||||
# C interface class
|
# C interface class
|
||||||
|
|
||||||
|
|
||||||
class CTaosInterface(object):
|
class CTaosInterface(object):
|
||||||
|
|
||||||
libtaos = ctypes.CDLL('libtaos.so')
|
libtaos = ctypes.CDLL('libtaos.so')
|
||||||
|
@ -216,7 +360,7 @@ class CTaosInterface(object):
|
||||||
except AttributeError:
|
except AttributeError:
|
||||||
raise AttributeError("config is expected as a str")
|
raise AttributeError("config is expected as a str")
|
||||||
|
|
||||||
if config != None:
|
if config is not None:
|
||||||
CTaosInterface.libtaos.taos_options(3, self._config)
|
CTaosInterface.libtaos.taos_options(3, self._config)
|
||||||
|
|
||||||
CTaosInterface.libtaos.taos_init()
|
CTaosInterface.libtaos.taos_init()
|
||||||
|
@ -227,7 +371,13 @@ class CTaosInterface(object):
|
||||||
"""
|
"""
|
||||||
return self._config
|
return self._config
|
||||||
|
|
||||||
def connect(self, host=None, user="root", password="taosdata", db=None, port=0):
|
def connect(
|
||||||
|
self,
|
||||||
|
host=None,
|
||||||
|
user="root",
|
||||||
|
password="taosdata",
|
||||||
|
db=None,
|
||||||
|
port=0):
|
||||||
'''
|
'''
|
||||||
Function to connect to server
|
Function to connect to server
|
||||||
|
|
||||||
|
@ -236,7 +386,7 @@ class CTaosInterface(object):
|
||||||
# host
|
# host
|
||||||
try:
|
try:
|
||||||
_host = ctypes.c_char_p(host.encode(
|
_host = ctypes.c_char_p(host.encode(
|
||||||
"utf-8")) if host != None else ctypes.c_char_p(None)
|
"utf-8")) if host is not None else ctypes.c_char_p(None)
|
||||||
except AttributeError:
|
except AttributeError:
|
||||||
raise AttributeError("host is expected as a str")
|
raise AttributeError("host is expected as a str")
|
||||||
|
|
||||||
|
@ -255,7 +405,7 @@ class CTaosInterface(object):
|
||||||
# db
|
# db
|
||||||
try:
|
try:
|
||||||
_db = ctypes.c_char_p(
|
_db = ctypes.c_char_p(
|
||||||
db.encode("utf-8")) if db != None else ctypes.c_char_p(None)
|
db.encode("utf-8")) if db is not None else ctypes.c_char_p(None)
|
||||||
except AttributeError:
|
except AttributeError:
|
||||||
raise AttributeError("db is expected as a str")
|
raise AttributeError("db is expected as a str")
|
||||||
|
|
||||||
|
@ -268,11 +418,11 @@ class CTaosInterface(object):
|
||||||
connection = ctypes.c_void_p(CTaosInterface.libtaos.taos_connect(
|
connection = ctypes.c_void_p(CTaosInterface.libtaos.taos_connect(
|
||||||
_host, _user, _password, _db, _port))
|
_host, _user, _password, _db, _port))
|
||||||
|
|
||||||
if connection.value == None:
|
if connection.value is None:
|
||||||
print('connect to TDengine failed')
|
print('connect to TDengine failed')
|
||||||
raise ConnectionError("connect to TDengine failed")
|
raise ConnectionError("connect to TDengine failed")
|
||||||
# sys.exit(1)
|
# sys.exit(1)
|
||||||
#else:
|
# else:
|
||||||
# print('connect to TDengine success')
|
# print('connect to TDengine success')
|
||||||
|
|
||||||
return connection
|
return connection
|
||||||
|
@ -293,12 +443,13 @@ class CTaosInterface(object):
|
||||||
@rtype: 0 on success and -1 on failure
|
@rtype: 0 on success and -1 on failure
|
||||||
'''
|
'''
|
||||||
try:
|
try:
|
||||||
return CTaosInterface.libtaos.taos_query(connection, ctypes.c_char_p(sql.encode('utf-8')))
|
return CTaosInterface.libtaos.taos_query(
|
||||||
|
connection, ctypes.c_char_p(sql.encode('utf-8')))
|
||||||
except AttributeError:
|
except AttributeError:
|
||||||
raise AttributeError("sql is expected as a string")
|
raise AttributeError("sql is expected as a string")
|
||||||
# finally:
|
# finally:
|
||||||
# CTaosInterface.libtaos.close(connection)
|
# CTaosInterface.libtaos.close(connection)
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def affectedRows(result):
|
def affectedRows(result):
|
||||||
"""The affected rows after runing query
|
"""The affected rows after runing query
|
||||||
|
@ -308,7 +459,7 @@ class CTaosInterface(object):
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def subscribe(connection, restart, topic, sql, interval):
|
def subscribe(connection, restart, topic, sql, interval):
|
||||||
"""Create a subscription
|
"""Create a subscription
|
||||||
@restart boolean,
|
@restart boolean,
|
||||||
@sql string, sql statement for data query, must be a 'select' statement.
|
@sql string, sql statement for data query, must be a 'select' statement.
|
||||||
@topic string, name of this subscription
|
@topic string, name of this subscription
|
||||||
"""
|
"""
|
||||||
|
@ -360,38 +511,53 @@ class CTaosInterface(object):
|
||||||
result, ctypes.byref(pblock))
|
result, ctypes.byref(pblock))
|
||||||
if num_of_rows == 0:
|
if num_of_rows == 0:
|
||||||
return None, 0
|
return None, 0
|
||||||
isMicro = (CTaosInterface.libtaos.taos_result_precision(result) == FieldType.C_TIMESTAMP_MICRO)
|
isMicro = (CTaosInterface.libtaos.taos_result_precision(
|
||||||
|
result) == FieldType.C_TIMESTAMP_MICRO)
|
||||||
blocks = [None] * len(fields)
|
blocks = [None] * len(fields)
|
||||||
fieldL = CTaosInterface.libtaos.taos_fetch_lengths(result)
|
fieldL = CTaosInterface.libtaos.taos_fetch_lengths(result)
|
||||||
fieldLen = [ele for ele in ctypes.cast(fieldL, ctypes.POINTER(ctypes.c_int))[:len(fields)]]
|
fieldLen = [
|
||||||
|
ele for ele in ctypes.cast(
|
||||||
|
fieldL, ctypes.POINTER(
|
||||||
|
ctypes.c_int))[
|
||||||
|
:len(fields)]]
|
||||||
for i in range(len(fields)):
|
for i in range(len(fields)):
|
||||||
data = ctypes.cast(pblock, ctypes.POINTER(ctypes.c_void_p))[i]
|
data = ctypes.cast(pblock, ctypes.POINTER(ctypes.c_void_p))[i]
|
||||||
if fields[i]['type'] not in _CONVERT_FUNC_BLOCK:
|
if fields[i]['type'] not in _CONVERT_FUNC_BLOCK:
|
||||||
raise DatabaseError("Invalid data type returned from database")
|
raise DatabaseError("Invalid data type returned from database")
|
||||||
blocks[i] = _CONVERT_FUNC_BLOCK[fields[i]['type']](data, num_of_rows, fieldLen[i], isMicro)
|
blocks[i] = _CONVERT_FUNC_BLOCK[fields[i]['type']](
|
||||||
|
data, num_of_rows, fieldLen[i], isMicro)
|
||||||
|
|
||||||
return blocks, abs(num_of_rows)
|
return blocks, abs(num_of_rows)
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def fetchRow(result, fields):
|
def fetchRow(result, fields):
|
||||||
pblock = ctypes.c_void_p(0)
|
pblock = ctypes.c_void_p(0)
|
||||||
pblock = CTaosInterface.libtaos.taos_fetch_row(result)
|
pblock = CTaosInterface.libtaos.taos_fetch_row(result)
|
||||||
if pblock :
|
if pblock:
|
||||||
num_of_rows = 1
|
num_of_rows = 1
|
||||||
isMicro = (CTaosInterface.libtaos.taos_result_precision(result) == FieldType.C_TIMESTAMP_MICRO)
|
isMicro = (CTaosInterface.libtaos.taos_result_precision(
|
||||||
|
result) == FieldType.C_TIMESTAMP_MICRO)
|
||||||
blocks = [None] * len(fields)
|
blocks = [None] * len(fields)
|
||||||
fieldL = CTaosInterface.libtaos.taos_fetch_lengths(result)
|
fieldL = CTaosInterface.libtaos.taos_fetch_lengths(result)
|
||||||
fieldLen = [ele for ele in ctypes.cast(fieldL, ctypes.POINTER(ctypes.c_int))[:len(fields)]]
|
fieldLen = [
|
||||||
|
ele for ele in ctypes.cast(
|
||||||
|
fieldL, ctypes.POINTER(
|
||||||
|
ctypes.c_int))[
|
||||||
|
:len(fields)]]
|
||||||
for i in range(len(fields)):
|
for i in range(len(fields)):
|
||||||
data = ctypes.cast(pblock, ctypes.POINTER(ctypes.c_void_p))[i]
|
data = ctypes.cast(pblock, ctypes.POINTER(ctypes.c_void_p))[i]
|
||||||
if fields[i]['type'] not in _CONVERT_FUNC:
|
if fields[i]['type'] not in _CONVERT_FUNC:
|
||||||
raise DatabaseError("Invalid data type returned from database")
|
raise DatabaseError(
|
||||||
|
"Invalid data type returned from database")
|
||||||
if data is None:
|
if data is None:
|
||||||
blocks[i] = [None]
|
blocks[i] = [None]
|
||||||
else:
|
else:
|
||||||
blocks[i] = _CONVERT_FUNC[fields[i]['type']](data, num_of_rows, fieldLen[i], isMicro)
|
blocks[i] = _CONVERT_FUNC[fields[i]['type']](
|
||||||
|
data, num_of_rows, fieldLen[i], isMicro)
|
||||||
else:
|
else:
|
||||||
return None, 0
|
return None, 0
|
||||||
return blocks, abs(num_of_rows)
|
return blocks, abs(num_of_rows)
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def freeResult(result):
|
def freeResult(result):
|
||||||
CTaosInterface.libtaos.taos_free_result(result)
|
CTaosInterface.libtaos.taos_free_result(result)
|
||||||
|
|
|
@ -2,9 +2,11 @@ from .cursor import TDengineCursor
|
||||||
from .subscription import TDengineSubscription
|
from .subscription import TDengineSubscription
|
||||||
from .cinterface import CTaosInterface
|
from .cinterface import CTaosInterface
|
||||||
|
|
||||||
|
|
||||||
class TDengineConnection(object):
|
class TDengineConnection(object):
|
||||||
""" TDengine connection object
|
""" TDengine connection object
|
||||||
"""
|
"""
|
||||||
|
|
||||||
def __init__(self, *args, **kwargs):
|
def __init__(self, *args, **kwargs):
|
||||||
self._conn = None
|
self._conn = None
|
||||||
self._host = None
|
self._host = None
|
||||||
|
@ -29,7 +31,7 @@ class TDengineConnection(object):
|
||||||
# password
|
# password
|
||||||
if 'password' in kwargs:
|
if 'password' in kwargs:
|
||||||
self._password = kwargs['password']
|
self._password = kwargs['password']
|
||||||
|
|
||||||
# database
|
# database
|
||||||
if 'database' in kwargs:
|
if 'database' in kwargs:
|
||||||
self._database = kwargs['database']
|
self._database = kwargs['database']
|
||||||
|
@ -43,7 +45,12 @@ class TDengineConnection(object):
|
||||||
self._config = kwargs['config']
|
self._config = kwargs['config']
|
||||||
|
|
||||||
self._chandle = CTaosInterface(self._config)
|
self._chandle = CTaosInterface(self._config)
|
||||||
self._conn = self._chandle.connect(self._host, self._user, self._password, self._database, self._port)
|
self._conn = self._chandle.connect(
|
||||||
|
self._host,
|
||||||
|
self._user,
|
||||||
|
self._password,
|
||||||
|
self._database,
|
||||||
|
self._port)
|
||||||
|
|
||||||
def close(self):
|
def close(self):
|
||||||
"""Close current connection.
|
"""Close current connection.
|
||||||
|
@ -55,7 +62,8 @@ class TDengineConnection(object):
|
||||||
"""
|
"""
|
||||||
if self._conn is None:
|
if self._conn is None:
|
||||||
return None
|
return None
|
||||||
sub = CTaosInterface.subscribe(self._conn, restart, topic, sql, interval)
|
sub = CTaosInterface.subscribe(
|
||||||
|
self._conn, restart, topic, sql, interval)
|
||||||
return TDengineSubscription(sub)
|
return TDengineSubscription(sub)
|
||||||
|
|
||||||
def cursor(self):
|
def cursor(self):
|
||||||
|
@ -80,7 +88,8 @@ class TDengineConnection(object):
|
||||||
"""
|
"""
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
conn = TDengineConnection(host='192.168.1.107')
|
conn = TDengineConnection(host='192.168.1.107')
|
||||||
conn.close()
|
conn.close()
|
||||||
print("Hello world")
|
print("Hello world")
|
||||||
|
|
|
@ -3,6 +3,7 @@
|
||||||
|
|
||||||
from .dbapi import *
|
from .dbapi import *
|
||||||
|
|
||||||
|
|
||||||
class FieldType(object):
|
class FieldType(object):
|
||||||
"""TDengine Field Types
|
"""TDengine Field Types
|
||||||
"""
|
"""
|
||||||
|
@ -18,13 +19,21 @@ class FieldType(object):
|
||||||
C_BINARY = 8
|
C_BINARY = 8
|
||||||
C_TIMESTAMP = 9
|
C_TIMESTAMP = 9
|
||||||
C_NCHAR = 10
|
C_NCHAR = 10
|
||||||
|
C_TINYINT_UNSIGNED = 12
|
||||||
|
C_SMALLINT_UNSIGNED = 13
|
||||||
|
C_INT_UNSIGNED = 14
|
||||||
|
C_BIGINT_UNSIGNED = 15
|
||||||
# NULL value definition
|
# NULL value definition
|
||||||
# NOTE: These values should change according to C definition in tsdb.h
|
# NOTE: These values should change according to C definition in tsdb.h
|
||||||
C_BOOL_NULL = 0x02
|
C_BOOL_NULL = 0x02
|
||||||
C_TINYINT_NULL = -128
|
C_TINYINT_NULL = -128
|
||||||
|
C_TINYINT_UNSIGNED_NULL = 255
|
||||||
C_SMALLINT_NULL = -32768
|
C_SMALLINT_NULL = -32768
|
||||||
|
C_SMALLINT_UNSIGNED_NULL = 65535
|
||||||
C_INT_NULL = -2147483648
|
C_INT_NULL = -2147483648
|
||||||
|
C_INT_UNSIGNED_NULL = 4294967295
|
||||||
C_BIGINT_NULL = -9223372036854775808
|
C_BIGINT_NULL = -9223372036854775808
|
||||||
|
C_BIGINT_UNSIGNED_NULL = 18446744073709551615
|
||||||
C_FLOAT_NULL = float('nan')
|
C_FLOAT_NULL = float('nan')
|
||||||
C_DOUBLE_NULL = float('nan')
|
C_DOUBLE_NULL = float('nan')
|
||||||
C_BINARY_NULL = bytearray([int('0xff', 16)])
|
C_BINARY_NULL = bytearray([int('0xff', 16)])
|
||||||
|
|
|
@ -128,8 +128,8 @@ class TDengineCursor(object):
|
||||||
if errno == 0:
|
if errno == 0:
|
||||||
if CTaosInterface.fieldsCount(self._result) == 0:
|
if CTaosInterface.fieldsCount(self._result) == 0:
|
||||||
self._affected_rows += CTaosInterface.affectedRows(
|
self._affected_rows += CTaosInterface.affectedRows(
|
||||||
self._result )
|
self._result)
|
||||||
return CTaosInterface.affectedRows(self._result )
|
return CTaosInterface.affectedRows(self._result)
|
||||||
else:
|
else:
|
||||||
self._fields = CTaosInterface.useResult(
|
self._fields = CTaosInterface.useResult(
|
||||||
self._result)
|
self._result)
|
||||||
|
@ -148,6 +148,7 @@ class TDengineCursor(object):
|
||||||
"""Fetch the next row of a query result set, returning a single sequence, or None when no more data is available.
|
"""Fetch the next row of a query result set, returning a single sequence, or None when no more data is available.
|
||||||
"""
|
"""
|
||||||
pass
|
pass
|
||||||
|
|
||||||
def fetchmany(self):
|
def fetchmany(self):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
@ -158,11 +159,26 @@ class TDengineCursor(object):
|
||||||
if (dataType.upper() == "TINYINT"):
|
if (dataType.upper() == "TINYINT"):
|
||||||
if (self._description[col][1] == FieldType.C_TINYINT):
|
if (self._description[col][1] == FieldType.C_TINYINT):
|
||||||
return True
|
return True
|
||||||
|
if (dataType.upper() == "TINYINT UNSIGNED"):
|
||||||
|
if (self._description[col][1] == FieldType.C_TINYINT_UNSIGNED):
|
||||||
|
return True
|
||||||
|
if (dataType.upper() == "SMALLINT"):
|
||||||
|
if (self._description[col][1] == FieldType.C_SMALLINT):
|
||||||
|
return True
|
||||||
|
if (dataType.upper() == "SMALLINT UNSIGNED"):
|
||||||
|
if (self._description[col][1] == FieldType.C_SMALLINT_UNSIGNED):
|
||||||
|
return True
|
||||||
if (dataType.upper() == "INT"):
|
if (dataType.upper() == "INT"):
|
||||||
if (self._description[col][1] == FieldType.C_INT):
|
if (self._description[col][1] == FieldType.C_INT):
|
||||||
return True
|
return True
|
||||||
|
if (dataType.upper() == "INT UNSIGNED"):
|
||||||
|
if (self._description[col][1] == FieldType.C_INT_UNSIGNED):
|
||||||
|
return True
|
||||||
if (dataType.upper() == "BIGINT"):
|
if (dataType.upper() == "BIGINT"):
|
||||||
if (self._description[col][1] == FieldType.C_INT):
|
if (self._description[col][1] == FieldType.C_BIGINT):
|
||||||
|
return True
|
||||||
|
if (dataType.upper() == "BIGINT UNSIGNED"):
|
||||||
|
if (self._description[col][1] == FieldType.C_BIGINT_UNSIGNED):
|
||||||
return True
|
return True
|
||||||
if (dataType.upper() == "FLOAT"):
|
if (dataType.upper() == "FLOAT"):
|
||||||
if (self._description[col][1] == FieldType.C_FLOAT):
|
if (self._description[col][1] == FieldType.C_FLOAT):
|
||||||
|
@ -191,16 +207,20 @@ class TDengineCursor(object):
|
||||||
buffer = [[] for i in range(len(self._fields))]
|
buffer = [[] for i in range(len(self._fields))]
|
||||||
self._rowcount = 0
|
self._rowcount = 0
|
||||||
while True:
|
while True:
|
||||||
block, num_of_fields = CTaosInterface.fetchRow(self._result, self._fields)
|
block, num_of_fields = CTaosInterface.fetchRow(
|
||||||
|
self._result, self._fields)
|
||||||
errno = CTaosInterface.libtaos.taos_errno(self._result)
|
errno = CTaosInterface.libtaos.taos_errno(self._result)
|
||||||
if errno != 0:
|
if errno != 0:
|
||||||
raise ProgrammingError(CTaosInterface.errStr(self._result), errno)
|
raise ProgrammingError(
|
||||||
|
CTaosInterface.errStr(
|
||||||
|
self._result), errno)
|
||||||
if num_of_fields == 0:
|
if num_of_fields == 0:
|
||||||
break
|
break
|
||||||
self._rowcount += num_of_fields
|
self._rowcount += num_of_fields
|
||||||
for i in range(len(self._fields)):
|
for i in range(len(self._fields)):
|
||||||
buffer[i].extend(block[i])
|
buffer[i].extend(block[i])
|
||||||
return list(map(tuple, zip(*buffer)))
|
return list(map(tuple, zip(*buffer)))
|
||||||
|
|
||||||
def fetchall(self):
|
def fetchall(self):
|
||||||
if self._result is None or self._fields is None:
|
if self._result is None or self._fields is None:
|
||||||
raise OperationalError("Invalid use of fetchall")
|
raise OperationalError("Invalid use of fetchall")
|
||||||
|
@ -208,16 +228,20 @@ class TDengineCursor(object):
|
||||||
buffer = [[] for i in range(len(self._fields))]
|
buffer = [[] for i in range(len(self._fields))]
|
||||||
self._rowcount = 0
|
self._rowcount = 0
|
||||||
while True:
|
while True:
|
||||||
block, num_of_fields = CTaosInterface.fetchBlock(self._result, self._fields)
|
block, num_of_fields = CTaosInterface.fetchBlock(
|
||||||
|
self._result, self._fields)
|
||||||
errno = CTaosInterface.libtaos.taos_errno(self._result)
|
errno = CTaosInterface.libtaos.taos_errno(self._result)
|
||||||
if errno != 0:
|
if errno != 0:
|
||||||
raise ProgrammingError(CTaosInterface.errStr(self._result), errno)
|
raise ProgrammingError(
|
||||||
|
CTaosInterface.errStr(
|
||||||
|
self._result), errno)
|
||||||
if num_of_fields == 0:
|
if num_of_fields == 0:
|
||||||
break
|
break
|
||||||
self._rowcount += num_of_fields
|
self._rowcount += num_of_fields
|
||||||
for i in range(len(self._fields)):
|
for i in range(len(self._fields)):
|
||||||
buffer[i].extend(block[i])
|
buffer[i].extend(block[i])
|
||||||
return list(map(tuple, zip(*buffer)))
|
return list(map(tuple, zip(*buffer)))
|
||||||
|
|
||||||
def nextset(self):
|
def nextset(self):
|
||||||
"""
|
"""
|
||||||
"""
|
"""
|
||||||
|
|
|
@ -4,6 +4,7 @@
|
||||||
import time
|
import time
|
||||||
import datetime
|
import datetime
|
||||||
|
|
||||||
|
|
||||||
class DBAPITypeObject(object):
|
class DBAPITypeObject(object):
|
||||||
def __init__(self, *values):
|
def __init__(self, *values):
|
||||||
self.values = values
|
self.values = values
|
||||||
|
@ -16,23 +17,28 @@ class DBAPITypeObject(object):
|
||||||
else:
|
else:
|
||||||
return -1
|
return -1
|
||||||
|
|
||||||
|
|
||||||
Date = datetime.date
|
Date = datetime.date
|
||||||
Time = datetime.time
|
Time = datetime.time
|
||||||
Timestamp = datetime.datetime
|
Timestamp = datetime.datetime
|
||||||
|
|
||||||
|
|
||||||
def DataFromTicks(ticks):
|
def DataFromTicks(ticks):
|
||||||
return Date(*time.localtime(ticks)[:3])
|
return Date(*time.localtime(ticks)[:3])
|
||||||
|
|
||||||
|
|
||||||
def TimeFromTicks(ticks):
|
def TimeFromTicks(ticks):
|
||||||
return Time(*time.localtime(ticks)[3:6])
|
return Time(*time.localtime(ticks)[3:6])
|
||||||
|
|
||||||
|
|
||||||
def TimestampFromTicks(ticks):
|
def TimestampFromTicks(ticks):
|
||||||
return Timestamp(*time.localtime(ticks)[:6])
|
return Timestamp(*time.localtime(ticks)[:6])
|
||||||
|
|
||||||
|
|
||||||
Binary = bytes
|
Binary = bytes
|
||||||
|
|
||||||
# STRING = DBAPITypeObject(*constants.FieldType.get_string_types())
|
# STRING = DBAPITypeObject(*constants.FieldType.get_string_types())
|
||||||
# BINARY = DBAPITypeObject(*constants.FieldType.get_binary_types())
|
# BINARY = DBAPITypeObject(*constants.FieldType.get_binary_types())
|
||||||
# NUMBER = BAPITypeObject(*constants.FieldType.get_number_types())
|
# NUMBER = BAPITypeObject(*constants.FieldType.get_number_types())
|
||||||
# DATETIME = DBAPITypeObject(*constants.FieldType.get_timestamp_types())
|
# DATETIME = DBAPITypeObject(*constants.FieldType.get_timestamp_types())
|
||||||
# ROWID = DBAPITypeObject()
|
# ROWID = DBAPITypeObject()
|
||||||
|
|
|
@ -1,35 +1,41 @@
|
||||||
"""Python exceptions
|
"""Python exceptions
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
|
||||||
class Error(Exception):
|
class Error(Exception):
|
||||||
def __init__(self, msg=None, errno=None):
|
def __init__(self, msg=None, errno=None):
|
||||||
self.msg = msg
|
self.msg = msg
|
||||||
self._full_msg = self.msg
|
self._full_msg = self.msg
|
||||||
self.errno = errno
|
self.errno = errno
|
||||||
|
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
return self._full_msg
|
return self._full_msg
|
||||||
|
|
||||||
|
|
||||||
class Warning(Exception):
|
class Warning(Exception):
|
||||||
"""Exception raised for important warnings like data truncations while inserting.
|
"""Exception raised for important warnings like data truncations while inserting.
|
||||||
"""
|
"""
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
|
||||||
class InterfaceError(Error):
|
class InterfaceError(Error):
|
||||||
"""Exception raised for errors that are related to the database interface rather than the database itself.
|
"""Exception raised for errors that are related to the database interface rather than the database itself.
|
||||||
"""
|
"""
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
|
||||||
class DatabaseError(Error):
|
class DatabaseError(Error):
|
||||||
"""Exception raised for errors that are related to the database.
|
"""Exception raised for errors that are related to the database.
|
||||||
"""
|
"""
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
|
||||||
class DataError(DatabaseError):
|
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.
|
"""Exception raised for errors that are due to problems with the processed data like division by zero, numeric value out of range.
|
||||||
"""
|
"""
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
|
||||||
class OperationalError(DatabaseError):
|
class OperationalError(DatabaseError):
|
||||||
"""Exception raised for errors that are related to the database's operation and not necessarily under the control of the programmer
|
"""Exception raised for errors that are related to the database's operation and not necessarily under the control of the programmer
|
||||||
"""
|
"""
|
||||||
|
@ -41,17 +47,20 @@ class IntegrityError(DatabaseError):
|
||||||
"""
|
"""
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
|
||||||
class InternalError(DatabaseError):
|
class InternalError(DatabaseError):
|
||||||
"""Exception raised when the database encounters an internal error.
|
"""Exception raised when the database encounters an internal error.
|
||||||
"""
|
"""
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
|
||||||
class ProgrammingError(DatabaseError):
|
class ProgrammingError(DatabaseError):
|
||||||
"""Exception raised for programming errors.
|
"""Exception raised for programming errors.
|
||||||
"""
|
"""
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
|
||||||
class NotSupportedError(DatabaseError):
|
class NotSupportedError(DatabaseError):
|
||||||
"""Exception raised in case a method or database API was used which is not supported by the database,.
|
"""Exception raised in case a method or database API was used which is not supported by the database,.
|
||||||
"""
|
"""
|
||||||
pass
|
pass
|
||||||
|
|
|
@ -1,52 +1,57 @@
|
||||||
from .cinterface import CTaosInterface
|
from .cinterface import CTaosInterface
|
||||||
from .error import *
|
from .error import *
|
||||||
|
|
||||||
|
|
||||||
class TDengineSubscription(object):
|
class TDengineSubscription(object):
|
||||||
"""TDengine subscription object
|
"""TDengine subscription object
|
||||||
"""
|
"""
|
||||||
|
|
||||||
def __init__(self, sub):
|
def __init__(self, sub):
|
||||||
self._sub = sub
|
self._sub = sub
|
||||||
|
|
||||||
|
|
||||||
def consume(self):
|
def consume(self):
|
||||||
"""Consume rows of a subscription
|
"""Consume rows of a subscription
|
||||||
"""
|
"""
|
||||||
if self._sub is None:
|
if self._sub is None:
|
||||||
raise OperationalError("Invalid use of consume")
|
raise OperationalError("Invalid use of consume")
|
||||||
|
|
||||||
result, fields = CTaosInterface.consume(self._sub)
|
result, fields = CTaosInterface.consume(self._sub)
|
||||||
buffer = [[] for i in range(len(fields))]
|
buffer = [[] for i in range(len(fields))]
|
||||||
while True:
|
while True:
|
||||||
block, num_of_fields = CTaosInterface.fetchBlock(result, fields)
|
block, num_of_fields = CTaosInterface.fetchBlock(result, fields)
|
||||||
if num_of_fields == 0: break
|
if num_of_fields == 0:
|
||||||
|
break
|
||||||
for i in range(len(fields)):
|
for i in range(len(fields)):
|
||||||
buffer[i].extend(block[i])
|
buffer[i].extend(block[i])
|
||||||
|
|
||||||
self.fields = fields
|
self.fields = fields
|
||||||
return list(map(tuple, zip(*buffer)))
|
return list(map(tuple, zip(*buffer)))
|
||||||
|
|
||||||
|
def close(self, keepProgress=True):
|
||||||
def close(self, keepProgress = True):
|
|
||||||
"""Close the Subscription.
|
"""Close the Subscription.
|
||||||
"""
|
"""
|
||||||
if self._sub is None:
|
if self._sub is None:
|
||||||
return False
|
return False
|
||||||
|
|
||||||
CTaosInterface.unsubscribe(self._sub, keepProgress)
|
CTaosInterface.unsubscribe(self._sub, keepProgress)
|
||||||
return True
|
return True
|
||||||
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
from .connection import TDengineConnection
|
from .connection import TDengineConnection
|
||||||
conn = TDengineConnection(host="127.0.0.1", user="root", password="taosdata", database="test")
|
conn = TDengineConnection(
|
||||||
|
host="127.0.0.1",
|
||||||
|
user="root",
|
||||||
|
password="taosdata",
|
||||||
|
database="test")
|
||||||
|
|
||||||
# Generate a cursor object to run SQL commands
|
# Generate a cursor object to run SQL commands
|
||||||
sub = conn.subscribe(True, "test", "select * from meters;", 1000)
|
sub = conn.subscribe(True, "test", "select * from meters;", 1000)
|
||||||
|
|
||||||
for i in range(0,10):
|
for i in range(0, 10):
|
||||||
data = sub.consume()
|
data = sub.consume()
|
||||||
for d in data:
|
for d in data:
|
||||||
print(d)
|
print(d)
|
||||||
|
|
||||||
sub.close()
|
sub.close()
|
||||||
conn.close()
|
conn.close()
|
||||||
|
|
|
@ -5,7 +5,7 @@ with open("README.md", "r") as fh:
|
||||||
|
|
||||||
setuptools.setup(
|
setuptools.setup(
|
||||||
name="taos",
|
name="taos",
|
||||||
version="2.0.4",
|
version="2.0.5",
|
||||||
author="Taosdata Inc.",
|
author="Taosdata Inc.",
|
||||||
author_email="support@taosdata.com",
|
author_email="support@taosdata.com",
|
||||||
description="TDengine python client package",
|
description="TDengine python client package",
|
||||||
|
|
|
@ -3,12 +3,12 @@ from .connection import TDengineConnection
|
||||||
from .cursor import TDengineCursor
|
from .cursor import TDengineCursor
|
||||||
|
|
||||||
# Globals
|
# Globals
|
||||||
apilevel = '2.0.3'
|
|
||||||
threadsafety = 0
|
threadsafety = 0
|
||||||
paramstyle = 'pyformat'
|
paramstyle = 'pyformat'
|
||||||
|
|
||||||
__all__ = ['connection', 'cursor']
|
__all__ = ['connection', 'cursor']
|
||||||
|
|
||||||
|
|
||||||
def connect(*args, **kwargs):
|
def connect(*args, **kwargs):
|
||||||
""" Function to return a TDengine connector object
|
""" Function to return a TDengine connector object
|
||||||
|
|
||||||
|
|
|
@ -4,11 +4,14 @@ from .error import *
|
||||||
import math
|
import math
|
||||||
import datetime
|
import datetime
|
||||||
|
|
||||||
|
|
||||||
def _convert_millisecond_to_datetime(milli):
|
def _convert_millisecond_to_datetime(milli):
|
||||||
return datetime.datetime.fromtimestamp(milli/1000.0)
|
return datetime.datetime.fromtimestamp(milli / 1000.0)
|
||||||
|
|
||||||
|
|
||||||
def _convert_microsecond_to_datetime(micro):
|
def _convert_microsecond_to_datetime(micro):
|
||||||
return datetime.datetime.fromtimestamp(micro/1000000.0)
|
return datetime.datetime.fromtimestamp(micro / 1000000.0)
|
||||||
|
|
||||||
|
|
||||||
def _crow_timestamp_to_python(data, num_of_rows, nbytes=None, micro=False):
|
def _crow_timestamp_to_python(data, num_of_rows, nbytes=None, micro=False):
|
||||||
"""Function to convert C bool row to python row
|
"""Function to convert C bool row to python row
|
||||||
|
@ -18,168 +21,309 @@ def _crow_timestamp_to_python(data, num_of_rows, nbytes=None, micro=False):
|
||||||
_timestamp_converter = _convert_microsecond_to_datetime
|
_timestamp_converter = _convert_microsecond_to_datetime
|
||||||
|
|
||||||
if num_of_rows > 0:
|
if num_of_rows > 0:
|
||||||
return list(map(_timestamp_converter, ctypes.cast(data, ctypes.POINTER(ctypes.c_long))[:abs(num_of_rows)]))
|
return list(map(_timestamp_converter, ctypes.cast(
|
||||||
|
data, ctypes.POINTER(ctypes.c_long))[:abs(num_of_rows)]))
|
||||||
else:
|
else:
|
||||||
return list(map(_timestamp_converter, ctypes.cast(data, ctypes.POINTER(ctypes.c_long))[:abs(num_of_rows)]))
|
return list(map(_timestamp_converter, ctypes.cast(
|
||||||
|
data, ctypes.POINTER(ctypes.c_long))[:abs(num_of_rows)]))
|
||||||
|
|
||||||
|
|
||||||
def _crow_bool_to_python(data, num_of_rows, nbytes=None, micro=False):
|
def _crow_bool_to_python(data, num_of_rows, nbytes=None, micro=False):
|
||||||
"""Function to convert C bool row to python row
|
"""Function to convert C bool row to python row
|
||||||
"""
|
"""
|
||||||
if num_of_rows > 0:
|
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)] ]
|
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)]]
|
||||||
else:
|
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)] ]
|
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):
|
def _crow_tinyint_to_python(data, num_of_rows, nbytes=None, micro=False):
|
||||||
"""Function to convert C tinyint row to python row
|
"""Function to convert C tinyint row to python row
|
||||||
"""
|
"""
|
||||||
if num_of_rows > 0:
|
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)] ]
|
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)]]
|
||||||
else:
|
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)] ]
|
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_tinyint_unsigned_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_UNSIGNED_NULL else ele for ele in ctypes.cast(
|
||||||
|
data, ctypes.POINTER(
|
||||||
|
ctypes.c_byte))[
|
||||||
|
:abs(num_of_rows)]]
|
||||||
|
else:
|
||||||
|
return [
|
||||||
|
None if ele == FieldType.C_TINYINT_UNSIGNED_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):
|
def _crow_smallint_to_python(data, num_of_rows, nbytes=None, micro=False):
|
||||||
"""Function to convert C smallint row to python row
|
"""Function to convert C smallint row to python row
|
||||||
"""
|
"""
|
||||||
if num_of_rows > 0:
|
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)]]
|
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)]]
|
||||||
else:
|
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)] ]
|
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_smallint_unsigned_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_UNSIGNED_NULL else ele for ele in ctypes.cast(
|
||||||
|
data, ctypes.POINTER(
|
||||||
|
ctypes.c_short))[
|
||||||
|
:abs(num_of_rows)]]
|
||||||
|
else:
|
||||||
|
return [
|
||||||
|
None if ele == FieldType.C_SMALLINT_UNSIGNED_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):
|
def _crow_int_to_python(data, num_of_rows, nbytes=None, micro=False):
|
||||||
"""Function to convert C int row to python row
|
"""Function to convert C int row to python row
|
||||||
"""
|
"""
|
||||||
if num_of_rows > 0:
|
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)] ]
|
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)]]
|
||||||
else:
|
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)] ]
|
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_int_unsigned_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_UNSIGNED_NULL else ele for ele in ctypes.cast(
|
||||||
|
data, ctypes.POINTER(
|
||||||
|
ctypes.c_int))[
|
||||||
|
:abs(num_of_rows)]]
|
||||||
|
else:
|
||||||
|
return [
|
||||||
|
None if ele == FieldType.C_INT_UNSIGNED_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):
|
def _crow_bigint_to_python(data, num_of_rows, nbytes=None, micro=False):
|
||||||
"""Function to convert C bigint row to python row
|
"""Function to convert C bigint row to python row
|
||||||
"""
|
"""
|
||||||
if num_of_rows > 0:
|
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_long))[:abs(num_of_rows)] ]
|
return [None if ele == FieldType.C_BIGINT_NULL else ele for ele in ctypes.cast(
|
||||||
|
data, ctypes.POINTER(ctypes.c_long))[:abs(num_of_rows)]]
|
||||||
else:
|
else:
|
||||||
return [ None if ele == FieldType.C_BIGINT_NULL else ele for ele in ctypes.cast(data, ctypes.POINTER(ctypes.c_long))[:abs(num_of_rows)] ]
|
return [None if ele == FieldType.C_BIGINT_NULL else ele for ele in ctypes.cast(
|
||||||
|
data, ctypes.POINTER(ctypes.c_long))[:abs(num_of_rows)]]
|
||||||
|
|
||||||
|
|
||||||
|
def _crow_bigint_unsigned_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_UNSIGNED_NULL else ele for ele in ctypes.cast(
|
||||||
|
data, ctypes.POINTER(
|
||||||
|
ctypes.c_long))[
|
||||||
|
:abs(num_of_rows)]]
|
||||||
|
else:
|
||||||
|
return [
|
||||||
|
None if ele == FieldType.C_BIGINT_UNSIGNED_NULL else ele for ele in ctypes.cast(
|
||||||
|
data, ctypes.POINTER(
|
||||||
|
ctypes.c_long))[
|
||||||
|
:abs(num_of_rows)]]
|
||||||
|
|
||||||
|
|
||||||
def _crow_float_to_python(data, num_of_rows, nbytes=None, micro=False):
|
def _crow_float_to_python(data, num_of_rows, nbytes=None, micro=False):
|
||||||
"""Function to convert C float row to python row
|
"""Function to convert C float row to python row
|
||||||
"""
|
"""
|
||||||
if num_of_rows > 0:
|
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)] ]
|
return [None if math.isnan(ele) else ele for ele in ctypes.cast(
|
||||||
|
data, ctypes.POINTER(ctypes.c_float))[:abs(num_of_rows)]]
|
||||||
else:
|
else:
|
||||||
return [ None if math.isnan(ele) else ele for ele in ctypes.cast(data, ctypes.POINTER(ctypes.c_float))[:abs(num_of_rows)] ]
|
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):
|
def _crow_double_to_python(data, num_of_rows, nbytes=None, micro=False):
|
||||||
"""Function to convert C double row to python row
|
"""Function to convert C double row to python row
|
||||||
"""
|
"""
|
||||||
if num_of_rows > 0:
|
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)] ]
|
return [None if math.isnan(ele) else ele for ele in ctypes.cast(
|
||||||
|
data, ctypes.POINTER(ctypes.c_double))[:abs(num_of_rows)]]
|
||||||
else:
|
else:
|
||||||
return [ None if math.isnan(ele) else ele for ele in ctypes.cast(data, ctypes.POINTER(ctypes.c_double))[:abs(num_of_rows)] ]
|
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):
|
def _crow_binary_to_python(data, num_of_rows, nbytes=None, micro=False):
|
||||||
"""Function to convert C binary row to python row
|
"""Function to convert C binary row to python row
|
||||||
"""
|
"""
|
||||||
assert(nbytes is not None)
|
assert(nbytes is not None)
|
||||||
if num_of_rows > 0:
|
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)]]
|
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)]]
|
||||||
else:
|
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)]]
|
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):
|
def _crow_nchar_to_python(data, num_of_rows, nbytes=None, micro=False):
|
||||||
"""Function to convert C nchar row to python row
|
"""Function to convert C nchar row to python row
|
||||||
"""
|
"""
|
||||||
assert(nbytes is not None)
|
assert(nbytes is not None)
|
||||||
res=[]
|
res = []
|
||||||
for i in range(abs(num_of_rows)):
|
for i in range(abs(num_of_rows)):
|
||||||
try:
|
try:
|
||||||
if num_of_rows >= 0:
|
if num_of_rows >= 0:
|
||||||
tmpstr = ctypes.c_char_p(data)
|
tmpstr = ctypes.c_char_p(data)
|
||||||
res.append( tmpstr.value.decode() )
|
res.append(tmpstr.value.decode())
|
||||||
else:
|
else:
|
||||||
res.append( (ctypes.cast(data+nbytes*i, ctypes.POINTER(ctypes.c_wchar * (nbytes//4))))[0].value )
|
res.append((ctypes.cast(data + nbytes * i,
|
||||||
|
ctypes.POINTER(ctypes.c_wchar * (nbytes // 4))))[0].value)
|
||||||
except ValueError:
|
except ValueError:
|
||||||
res.append(None)
|
res.append(None)
|
||||||
|
|
||||||
return res
|
return res
|
||||||
|
|
||||||
|
|
||||||
def _crow_binary_to_python_block(data, num_of_rows, nbytes=None, micro=False):
|
def _crow_binary_to_python_block(data, num_of_rows, nbytes=None, micro=False):
|
||||||
"""Function to convert C binary row to python row
|
"""Function to convert C binary row to python row
|
||||||
"""
|
"""
|
||||||
assert(nbytes is not None)
|
assert(nbytes is not None)
|
||||||
res=[]
|
res = []
|
||||||
if num_of_rows > 0:
|
if num_of_rows > 0:
|
||||||
for i in range(abs(num_of_rows)):
|
for i in range(abs(num_of_rows)):
|
||||||
try:
|
try:
|
||||||
rbyte=ctypes.cast(data+nbytes*i,ctypes.POINTER(ctypes.c_short))[:1].pop()
|
rbyte = ctypes.cast(
|
||||||
tmpstr = ctypes.c_char_p(data+nbytes*i+2)
|
data + nbytes * i,
|
||||||
res.append( tmpstr.value.decode()[0:rbyte] )
|
ctypes.POINTER(
|
||||||
|
ctypes.c_short))[
|
||||||
|
:1].pop()
|
||||||
|
tmpstr = ctypes.c_char_p(data + nbytes * i + 2)
|
||||||
|
res.append(tmpstr.value.decode()[0:rbyte])
|
||||||
except ValueError:
|
except ValueError:
|
||||||
res.append(None)
|
res.append(None)
|
||||||
else:
|
else:
|
||||||
for i in range(abs(num_of_rows)):
|
for i in range(abs(num_of_rows)):
|
||||||
try:
|
try:
|
||||||
rbyte=ctypes.cast(data+nbytes*i,ctypes.POINTER(ctypes.c_short))[:1].pop()
|
rbyte = ctypes.cast(
|
||||||
tmpstr = ctypes.c_char_p(data+nbytes*i+2)
|
data + nbytes * i,
|
||||||
res.append( tmpstr.value.decode()[0:rbyte] )
|
ctypes.POINTER(
|
||||||
|
ctypes.c_short))[
|
||||||
|
:1].pop()
|
||||||
|
tmpstr = ctypes.c_char_p(data + nbytes * i + 2)
|
||||||
|
res.append(tmpstr.value.decode()[0:rbyte])
|
||||||
except ValueError:
|
except ValueError:
|
||||||
res.append(None)
|
res.append(None)
|
||||||
return res
|
return res
|
||||||
|
|
||||||
|
|
||||||
def _crow_nchar_to_python_block(data, num_of_rows, nbytes=None, micro=False):
|
def _crow_nchar_to_python_block(data, num_of_rows, nbytes=None, micro=False):
|
||||||
"""Function to convert C nchar row to python row
|
"""Function to convert C nchar row to python row
|
||||||
"""
|
"""
|
||||||
assert(nbytes is not None)
|
assert(nbytes is not None)
|
||||||
res=[]
|
res = []
|
||||||
if num_of_rows >= 0:
|
if num_of_rows >= 0:
|
||||||
for i in range(abs(num_of_rows)):
|
for i in range(abs(num_of_rows)):
|
||||||
try:
|
try:
|
||||||
tmpstr = ctypes.c_char_p(data+nbytes*i+2)
|
tmpstr = ctypes.c_char_p(data + nbytes * i + 2)
|
||||||
res.append( tmpstr.value.decode() )
|
res.append(tmpstr.value.decode())
|
||||||
except ValueError:
|
except ValueError:
|
||||||
res.append(None)
|
res.append(None)
|
||||||
else:
|
else:
|
||||||
for i in range(abs(num_of_rows)):
|
for i in range(abs(num_of_rows)):
|
||||||
try:
|
try:
|
||||||
res.append( (ctypes.cast(data+nbytes*i+2, ctypes.POINTER(ctypes.c_wchar * (nbytes//4))))[0].value )
|
res.append((ctypes.cast(data + nbytes * i + 2,
|
||||||
|
ctypes.POINTER(ctypes.c_wchar * (nbytes // 4))))[0].value)
|
||||||
except ValueError:
|
except ValueError:
|
||||||
res.append(None)
|
res.append(None)
|
||||||
return res
|
return res
|
||||||
|
|
||||||
|
|
||||||
_CONVERT_FUNC = {
|
_CONVERT_FUNC = {
|
||||||
FieldType.C_BOOL: _crow_bool_to_python,
|
FieldType.C_BOOL: _crow_bool_to_python,
|
||||||
FieldType.C_TINYINT : _crow_tinyint_to_python,
|
FieldType.C_TINYINT: _crow_tinyint_to_python,
|
||||||
FieldType.C_SMALLINT : _crow_smallint_to_python,
|
FieldType.C_SMALLINT: _crow_smallint_to_python,
|
||||||
FieldType.C_INT : _crow_int_to_python,
|
FieldType.C_INT: _crow_int_to_python,
|
||||||
FieldType.C_BIGINT : _crow_bigint_to_python,
|
FieldType.C_BIGINT: _crow_bigint_to_python,
|
||||||
FieldType.C_FLOAT : _crow_float_to_python,
|
FieldType.C_FLOAT: _crow_float_to_python,
|
||||||
FieldType.C_DOUBLE : _crow_double_to_python,
|
FieldType.C_DOUBLE: _crow_double_to_python,
|
||||||
FieldType.C_BINARY: _crow_binary_to_python,
|
FieldType.C_BINARY: _crow_binary_to_python,
|
||||||
FieldType.C_TIMESTAMP : _crow_timestamp_to_python,
|
FieldType.C_TIMESTAMP: _crow_timestamp_to_python,
|
||||||
FieldType.C_NCHAR : _crow_nchar_to_python
|
FieldType.C_NCHAR: _crow_nchar_to_python,
|
||||||
|
FieldType.C_TINYINT_UNSIGNED: _crow_tinyint_unsigned_to_python,
|
||||||
|
FieldType.C_SMALLINT_UNSIGNED: _crow_smallint_unsigned_to_python,
|
||||||
|
FieldType.C_INT_UNSIGNED: _crow_int_unsigned_to_python,
|
||||||
|
FieldType.C_BIGINT_UNSIGNED: _crow_bigint_unsigned_to_python
|
||||||
}
|
}
|
||||||
|
|
||||||
_CONVERT_FUNC_BLOCK = {
|
_CONVERT_FUNC_BLOCK = {
|
||||||
FieldType.C_BOOL: _crow_bool_to_python,
|
FieldType.C_BOOL: _crow_bool_to_python,
|
||||||
FieldType.C_TINYINT : _crow_tinyint_to_python,
|
FieldType.C_TINYINT: _crow_tinyint_to_python,
|
||||||
FieldType.C_SMALLINT : _crow_smallint_to_python,
|
FieldType.C_SMALLINT: _crow_smallint_to_python,
|
||||||
FieldType.C_INT : _crow_int_to_python,
|
FieldType.C_INT: _crow_int_to_python,
|
||||||
FieldType.C_BIGINT : _crow_bigint_to_python,
|
FieldType.C_BIGINT: _crow_bigint_to_python,
|
||||||
FieldType.C_FLOAT : _crow_float_to_python,
|
FieldType.C_FLOAT: _crow_float_to_python,
|
||||||
FieldType.C_DOUBLE : _crow_double_to_python,
|
FieldType.C_DOUBLE: _crow_double_to_python,
|
||||||
FieldType.C_BINARY: _crow_binary_to_python_block,
|
FieldType.C_BINARY: _crow_binary_to_python_block,
|
||||||
FieldType.C_TIMESTAMP : _crow_timestamp_to_python,
|
FieldType.C_TIMESTAMP: _crow_timestamp_to_python,
|
||||||
FieldType.C_NCHAR : _crow_nchar_to_python_block
|
FieldType.C_NCHAR: _crow_nchar_to_python_block,
|
||||||
|
FieldType.C_TINYINT_UNSIGNED: _crow_tinyint_unsigned_to_python,
|
||||||
|
FieldType.C_SMALLINT_UNSIGNED: _crow_smallint_unsigned_to_python,
|
||||||
|
FieldType.C_INT_UNSIGNED: _crow_int_unsigned_to_python,
|
||||||
|
FieldType.C_BIGINT_UNSIGNED: _crow_bigint_unsigned_to_python
|
||||||
}
|
}
|
||||||
|
|
||||||
# Corresponding TAOS_FIELD structure in C
|
# Corresponding TAOS_FIELD structure in C
|
||||||
|
|
||||||
|
|
||||||
class TaosField(ctypes.Structure):
|
class TaosField(ctypes.Structure):
|
||||||
_fields_ = [('name', ctypes.c_char * 65),
|
_fields_ = [('name', ctypes.c_char * 65),
|
||||||
('type', ctypes.c_char),
|
('type', ctypes.c_char),
|
||||||
('bytes', ctypes.c_short)]
|
('bytes', ctypes.c_short)]
|
||||||
|
|
||||||
# C interface class
|
# C interface class
|
||||||
|
|
||||||
|
|
||||||
class CTaosInterface(object):
|
class CTaosInterface(object):
|
||||||
|
|
||||||
libtaos = ctypes.CDLL('libtaos.so')
|
libtaos = ctypes.CDLL('libtaos.so')
|
||||||
|
@ -216,7 +360,7 @@ class CTaosInterface(object):
|
||||||
except AttributeError:
|
except AttributeError:
|
||||||
raise AttributeError("config is expected as a str")
|
raise AttributeError("config is expected as a str")
|
||||||
|
|
||||||
if config != None:
|
if config is not None:
|
||||||
CTaosInterface.libtaos.taos_options(3, self._config)
|
CTaosInterface.libtaos.taos_options(3, self._config)
|
||||||
|
|
||||||
CTaosInterface.libtaos.taos_init()
|
CTaosInterface.libtaos.taos_init()
|
||||||
|
@ -227,7 +371,13 @@ class CTaosInterface(object):
|
||||||
"""
|
"""
|
||||||
return self._config
|
return self._config
|
||||||
|
|
||||||
def connect(self, host=None, user="root", password="taosdata", db=None, port=0):
|
def connect(
|
||||||
|
self,
|
||||||
|
host=None,
|
||||||
|
user="root",
|
||||||
|
password="taosdata",
|
||||||
|
db=None,
|
||||||
|
port=0):
|
||||||
'''
|
'''
|
||||||
Function to connect to server
|
Function to connect to server
|
||||||
|
|
||||||
|
@ -236,7 +386,7 @@ class CTaosInterface(object):
|
||||||
# host
|
# host
|
||||||
try:
|
try:
|
||||||
_host = ctypes.c_char_p(host.encode(
|
_host = ctypes.c_char_p(host.encode(
|
||||||
"utf-8")) if host != None else ctypes.c_char_p(None)
|
"utf-8")) if host is not None else ctypes.c_char_p(None)
|
||||||
except AttributeError:
|
except AttributeError:
|
||||||
raise AttributeError("host is expected as a str")
|
raise AttributeError("host is expected as a str")
|
||||||
|
|
||||||
|
@ -255,7 +405,7 @@ class CTaosInterface(object):
|
||||||
# db
|
# db
|
||||||
try:
|
try:
|
||||||
_db = ctypes.c_char_p(
|
_db = ctypes.c_char_p(
|
||||||
db.encode("utf-8")) if db != None else ctypes.c_char_p(None)
|
db.encode("utf-8")) if db is not None else ctypes.c_char_p(None)
|
||||||
except AttributeError:
|
except AttributeError:
|
||||||
raise AttributeError("db is expected as a str")
|
raise AttributeError("db is expected as a str")
|
||||||
|
|
||||||
|
@ -268,11 +418,11 @@ class CTaosInterface(object):
|
||||||
connection = ctypes.c_void_p(CTaosInterface.libtaos.taos_connect(
|
connection = ctypes.c_void_p(CTaosInterface.libtaos.taos_connect(
|
||||||
_host, _user, _password, _db, _port))
|
_host, _user, _password, _db, _port))
|
||||||
|
|
||||||
if connection.value == None:
|
if connection.value is None:
|
||||||
print('connect to TDengine failed')
|
print('connect to TDengine failed')
|
||||||
raise ConnectionError("connect to TDengine failed")
|
raise ConnectionError("connect to TDengine failed")
|
||||||
# sys.exit(1)
|
# sys.exit(1)
|
||||||
#else:
|
# else:
|
||||||
# print('connect to TDengine success')
|
# print('connect to TDengine success')
|
||||||
|
|
||||||
return connection
|
return connection
|
||||||
|
@ -293,7 +443,8 @@ class CTaosInterface(object):
|
||||||
@rtype: 0 on success and -1 on failure
|
@rtype: 0 on success and -1 on failure
|
||||||
'''
|
'''
|
||||||
try:
|
try:
|
||||||
return CTaosInterface.libtaos.taos_query(connection, ctypes.c_char_p(sql.encode('utf-8')))
|
return CTaosInterface.libtaos.taos_query(
|
||||||
|
connection, ctypes.c_char_p(sql.encode('utf-8')))
|
||||||
except AttributeError:
|
except AttributeError:
|
||||||
raise AttributeError("sql is expected as a string")
|
raise AttributeError("sql is expected as a string")
|
||||||
# finally:
|
# finally:
|
||||||
|
@ -308,7 +459,7 @@ class CTaosInterface(object):
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def subscribe(connection, restart, topic, sql, interval):
|
def subscribe(connection, restart, topic, sql, interval):
|
||||||
"""Create a subscription
|
"""Create a subscription
|
||||||
@restart boolean,
|
@restart boolean,
|
||||||
@sql string, sql statement for data query, must be a 'select' statement.
|
@sql string, sql statement for data query, must be a 'select' statement.
|
||||||
@topic string, name of this subscription
|
@topic string, name of this subscription
|
||||||
"""
|
"""
|
||||||
|
@ -360,35 +511,49 @@ class CTaosInterface(object):
|
||||||
result, ctypes.byref(pblock))
|
result, ctypes.byref(pblock))
|
||||||
if num_of_rows == 0:
|
if num_of_rows == 0:
|
||||||
return None, 0
|
return None, 0
|
||||||
isMicro = (CTaosInterface.libtaos.taos_result_precision(result) == FieldType.C_TIMESTAMP_MICRO)
|
isMicro = (CTaosInterface.libtaos.taos_result_precision(
|
||||||
|
result) == FieldType.C_TIMESTAMP_MICRO)
|
||||||
blocks = [None] * len(fields)
|
blocks = [None] * len(fields)
|
||||||
fieldL = CTaosInterface.libtaos.taos_fetch_lengths(result)
|
fieldL = CTaosInterface.libtaos.taos_fetch_lengths(result)
|
||||||
fieldLen = [ele for ele in ctypes.cast(fieldL, ctypes.POINTER(ctypes.c_int))[:len(fields)]]
|
fieldLen = [
|
||||||
|
ele for ele in ctypes.cast(
|
||||||
|
fieldL, ctypes.POINTER(
|
||||||
|
ctypes.c_int))[
|
||||||
|
:len(fields)]]
|
||||||
for i in range(len(fields)):
|
for i in range(len(fields)):
|
||||||
data = ctypes.cast(pblock, ctypes.POINTER(ctypes.c_void_p))[i]
|
data = ctypes.cast(pblock, ctypes.POINTER(ctypes.c_void_p))[i]
|
||||||
if fields[i]['type'] not in _CONVERT_FUNC_BLOCK:
|
if fields[i]['type'] not in _CONVERT_FUNC_BLOCK:
|
||||||
raise DatabaseError("Invalid data type returned from database")
|
raise DatabaseError("Invalid data type returned from database")
|
||||||
blocks[i] = _CONVERT_FUNC_BLOCK[fields[i]['type']](data, num_of_rows, fieldLen[i], isMicro)
|
blocks[i] = _CONVERT_FUNC_BLOCK[fields[i]['type']](
|
||||||
|
data, num_of_rows, fieldLen[i], isMicro)
|
||||||
|
|
||||||
return blocks, abs(num_of_rows)
|
return blocks, abs(num_of_rows)
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def fetchRow(result, fields):
|
def fetchRow(result, fields):
|
||||||
pblock = ctypes.c_void_p(0)
|
pblock = ctypes.c_void_p(0)
|
||||||
pblock = CTaosInterface.libtaos.taos_fetch_row(result)
|
pblock = CTaosInterface.libtaos.taos_fetch_row(result)
|
||||||
if pblock :
|
if pblock:
|
||||||
num_of_rows = 1
|
num_of_rows = 1
|
||||||
isMicro = (CTaosInterface.libtaos.taos_result_precision(result) == FieldType.C_TIMESTAMP_MICRO)
|
isMicro = (CTaosInterface.libtaos.taos_result_precision(
|
||||||
|
result) == FieldType.C_TIMESTAMP_MICRO)
|
||||||
blocks = [None] * len(fields)
|
blocks = [None] * len(fields)
|
||||||
fieldL = CTaosInterface.libtaos.taos_fetch_lengths(result)
|
fieldL = CTaosInterface.libtaos.taos_fetch_lengths(result)
|
||||||
fieldLen = [ele for ele in ctypes.cast(fieldL, ctypes.POINTER(ctypes.c_int))[:len(fields)]]
|
fieldLen = [
|
||||||
|
ele for ele in ctypes.cast(
|
||||||
|
fieldL, ctypes.POINTER(
|
||||||
|
ctypes.c_int))[
|
||||||
|
:len(fields)]]
|
||||||
for i in range(len(fields)):
|
for i in range(len(fields)):
|
||||||
data = ctypes.cast(pblock, ctypes.POINTER(ctypes.c_void_p))[i]
|
data = ctypes.cast(pblock, ctypes.POINTER(ctypes.c_void_p))[i]
|
||||||
if fields[i]['type'] not in _CONVERT_FUNC:
|
if fields[i]['type'] not in _CONVERT_FUNC:
|
||||||
raise DatabaseError("Invalid data type returned from database")
|
raise DatabaseError(
|
||||||
|
"Invalid data type returned from database")
|
||||||
if data is None:
|
if data is None:
|
||||||
blocks[i] = [None]
|
blocks[i] = [None]
|
||||||
else:
|
else:
|
||||||
blocks[i] = _CONVERT_FUNC[fields[i]['type']](data, num_of_rows, fieldLen[i], isMicro)
|
blocks[i] = _CONVERT_FUNC[fields[i]['type']](
|
||||||
|
data, num_of_rows, fieldLen[i], isMicro)
|
||||||
else:
|
else:
|
||||||
return None, 0
|
return None, 0
|
||||||
return blocks, abs(num_of_rows)
|
return blocks, abs(num_of_rows)
|
||||||
|
|
|
@ -2,9 +2,11 @@ from .cursor import TDengineCursor
|
||||||
from .subscription import TDengineSubscription
|
from .subscription import TDengineSubscription
|
||||||
from .cinterface import CTaosInterface
|
from .cinterface import CTaosInterface
|
||||||
|
|
||||||
|
|
||||||
class TDengineConnection(object):
|
class TDengineConnection(object):
|
||||||
""" TDengine connection object
|
""" TDengine connection object
|
||||||
"""
|
"""
|
||||||
|
|
||||||
def __init__(self, *args, **kwargs):
|
def __init__(self, *args, **kwargs):
|
||||||
self._conn = None
|
self._conn = None
|
||||||
self._host = None
|
self._host = None
|
||||||
|
@ -29,7 +31,7 @@ class TDengineConnection(object):
|
||||||
# password
|
# password
|
||||||
if 'password' in kwargs:
|
if 'password' in kwargs:
|
||||||
self._password = kwargs['password']
|
self._password = kwargs['password']
|
||||||
|
|
||||||
# database
|
# database
|
||||||
if 'database' in kwargs:
|
if 'database' in kwargs:
|
||||||
self._database = kwargs['database']
|
self._database = kwargs['database']
|
||||||
|
@ -43,7 +45,12 @@ class TDengineConnection(object):
|
||||||
self._config = kwargs['config']
|
self._config = kwargs['config']
|
||||||
|
|
||||||
self._chandle = CTaosInterface(self._config)
|
self._chandle = CTaosInterface(self._config)
|
||||||
self._conn = self._chandle.connect(self._host, self._user, self._password, self._database, self._port)
|
self._conn = self._chandle.connect(
|
||||||
|
self._host,
|
||||||
|
self._user,
|
||||||
|
self._password,
|
||||||
|
self._database,
|
||||||
|
self._port)
|
||||||
|
|
||||||
def close(self):
|
def close(self):
|
||||||
"""Close current connection.
|
"""Close current connection.
|
||||||
|
@ -55,7 +62,8 @@ class TDengineConnection(object):
|
||||||
"""
|
"""
|
||||||
if self._conn is None:
|
if self._conn is None:
|
||||||
return None
|
return None
|
||||||
sub = CTaosInterface.subscribe(self._conn, restart, topic, sql, interval)
|
sub = CTaosInterface.subscribe(
|
||||||
|
self._conn, restart, topic, sql, interval)
|
||||||
return TDengineSubscription(sub)
|
return TDengineSubscription(sub)
|
||||||
|
|
||||||
def cursor(self):
|
def cursor(self):
|
||||||
|
@ -80,7 +88,8 @@ class TDengineConnection(object):
|
||||||
"""
|
"""
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
conn = TDengineConnection(host='192.168.1.107')
|
conn = TDengineConnection(host='192.168.1.107')
|
||||||
conn.close()
|
conn.close()
|
||||||
print("Hello world")
|
print("Hello world")
|
||||||
|
|
|
@ -3,6 +3,7 @@
|
||||||
|
|
||||||
from .dbapi import *
|
from .dbapi import *
|
||||||
|
|
||||||
|
|
||||||
class FieldType(object):
|
class FieldType(object):
|
||||||
"""TDengine Field Types
|
"""TDengine Field Types
|
||||||
"""
|
"""
|
||||||
|
@ -18,13 +19,21 @@ class FieldType(object):
|
||||||
C_BINARY = 8
|
C_BINARY = 8
|
||||||
C_TIMESTAMP = 9
|
C_TIMESTAMP = 9
|
||||||
C_NCHAR = 10
|
C_NCHAR = 10
|
||||||
|
C_TINYINT_UNSIGNED = 12
|
||||||
|
C_SMALLINT_UNSIGNED = 13
|
||||||
|
C_INT_UNSIGNED = 14
|
||||||
|
C_BIGINT_UNSIGNED = 15
|
||||||
# NULL value definition
|
# NULL value definition
|
||||||
# NOTE: These values should change according to C definition in tsdb.h
|
# NOTE: These values should change according to C definition in tsdb.h
|
||||||
C_BOOL_NULL = 0x02
|
C_BOOL_NULL = 0x02
|
||||||
C_TINYINT_NULL = -128
|
C_TINYINT_NULL = -128
|
||||||
|
C_TINYINT_UNSIGNED_NULL = 255
|
||||||
C_SMALLINT_NULL = -32768
|
C_SMALLINT_NULL = -32768
|
||||||
|
C_SMALLINT_UNSIGNED_NULL = 65535
|
||||||
C_INT_NULL = -2147483648
|
C_INT_NULL = -2147483648
|
||||||
|
C_INT_UNSIGNED_NULL = 4294967295
|
||||||
C_BIGINT_NULL = -9223372036854775808
|
C_BIGINT_NULL = -9223372036854775808
|
||||||
|
C_BIGINT_UNSIGNED_NULL = 18446744073709551615
|
||||||
C_FLOAT_NULL = float('nan')
|
C_FLOAT_NULL = float('nan')
|
||||||
C_DOUBLE_NULL = float('nan')
|
C_DOUBLE_NULL = float('nan')
|
||||||
C_BINARY_NULL = bytearray([int('0xff', 16)])
|
C_BINARY_NULL = bytearray([int('0xff', 16)])
|
||||||
|
|
|
@ -5,6 +5,7 @@ import threading
|
||||||
|
|
||||||
# querySeqNum = 0
|
# querySeqNum = 0
|
||||||
|
|
||||||
|
|
||||||
class TDengineCursor(object):
|
class TDengineCursor(object):
|
||||||
"""Database cursor which is used to manage the context of a fetch operation.
|
"""Database cursor which is used to manage the context of a fetch operation.
|
||||||
|
|
||||||
|
@ -107,8 +108,8 @@ class TDengineCursor(object):
|
||||||
# if threading.get_ident() != self._threadId:
|
# if threading.get_ident() != self._threadId:
|
||||||
# info ="Cursor execute:Thread ID not match,creater:"+str(self._threadId)+" caller:"+str(threading.get_ident())
|
# info ="Cursor execute:Thread ID not match,creater:"+str(self._threadId)+" caller:"+str(threading.get_ident())
|
||||||
# raise OperationalError(info)
|
# raise OperationalError(info)
|
||||||
# print(info)
|
# print(info)
|
||||||
# return None
|
# return None
|
||||||
|
|
||||||
if not operation:
|
if not operation:
|
||||||
return None
|
return None
|
||||||
|
@ -137,8 +138,8 @@ class TDengineCursor(object):
|
||||||
if errno == 0:
|
if errno == 0:
|
||||||
if CTaosInterface.fieldsCount(self._result) == 0:
|
if CTaosInterface.fieldsCount(self._result) == 0:
|
||||||
self._affected_rows += CTaosInterface.affectedRows(
|
self._affected_rows += CTaosInterface.affectedRows(
|
||||||
self._result )
|
self._result)
|
||||||
return CTaosInterface.affectedRows(self._result )
|
return CTaosInterface.affectedRows(self._result)
|
||||||
else:
|
else:
|
||||||
self._fields = CTaosInterface.useResult(
|
self._fields = CTaosInterface.useResult(
|
||||||
self._result)
|
self._result)
|
||||||
|
@ -168,11 +169,26 @@ class TDengineCursor(object):
|
||||||
if (dataType.upper() == "TINYINT"):
|
if (dataType.upper() == "TINYINT"):
|
||||||
if (self._description[col][1] == FieldType.C_TINYINT):
|
if (self._description[col][1] == FieldType.C_TINYINT):
|
||||||
return True
|
return True
|
||||||
|
if (dataType.upper() == "TINYINT UNSIGNED"):
|
||||||
|
if (self._description[col][1] == FieldType.C_TINYINT_UNSIGNED):
|
||||||
|
return True
|
||||||
|
if (dataType.upper() == "SMALLINT"):
|
||||||
|
if (self._description[col][1] == FieldType.C_SMALLINT):
|
||||||
|
return True
|
||||||
|
if (dataType.upper() == "SMALLINT UNSIGNED"):
|
||||||
|
if (self._description[col][1] == FieldType.C_SMALLINT_UNSIGNED):
|
||||||
|
return True
|
||||||
if (dataType.upper() == "INT"):
|
if (dataType.upper() == "INT"):
|
||||||
if (self._description[col][1] == FieldType.C_INT):
|
if (self._description[col][1] == FieldType.C_INT):
|
||||||
return True
|
return True
|
||||||
|
if (dataType.upper() == "INT UNSIGNED"):
|
||||||
|
if (self._description[col][1] == FieldType.C_INT_UNSIGNED):
|
||||||
|
return True
|
||||||
if (dataType.upper() == "BIGINT"):
|
if (dataType.upper() == "BIGINT"):
|
||||||
if (self._description[col][1] == FieldType.C_INT):
|
if (self._description[col][1] == FieldType.C_BIGINT):
|
||||||
|
return True
|
||||||
|
if (dataType.upper() == "BIGINT UNSIGNED"):
|
||||||
|
if (self._description[col][1] == FieldType.C_BIGINT_UNSIGNED):
|
||||||
return True
|
return True
|
||||||
if (dataType.upper() == "FLOAT"):
|
if (dataType.upper() == "FLOAT"):
|
||||||
if (self._description[col][1] == FieldType.C_FLOAT):
|
if (self._description[col][1] == FieldType.C_FLOAT):
|
||||||
|
@ -201,10 +217,13 @@ class TDengineCursor(object):
|
||||||
buffer = [[] for i in range(len(self._fields))]
|
buffer = [[] for i in range(len(self._fields))]
|
||||||
self._rowcount = 0
|
self._rowcount = 0
|
||||||
while True:
|
while True:
|
||||||
block, num_of_fields = CTaosInterface.fetchRow(self._result, self._fields)
|
block, num_of_fields = CTaosInterface.fetchRow(
|
||||||
|
self._result, self._fields)
|
||||||
errno = CTaosInterface.libtaos.taos_errno(self._result)
|
errno = CTaosInterface.libtaos.taos_errno(self._result)
|
||||||
if errno != 0:
|
if errno != 0:
|
||||||
raise ProgrammingError(CTaosInterface.errStr(self._result), errno)
|
raise ProgrammingError(
|
||||||
|
CTaosInterface.errStr(
|
||||||
|
self._result), errno)
|
||||||
if num_of_fields == 0:
|
if num_of_fields == 0:
|
||||||
break
|
break
|
||||||
self._rowcount += num_of_fields
|
self._rowcount += num_of_fields
|
||||||
|
@ -219,15 +238,20 @@ class TDengineCursor(object):
|
||||||
buffer = [[] for i in range(len(self._fields))]
|
buffer = [[] for i in range(len(self._fields))]
|
||||||
self._rowcount = 0
|
self._rowcount = 0
|
||||||
while True:
|
while True:
|
||||||
block, num_of_fields = CTaosInterface.fetchBlock(self._result, self._fields)
|
block, num_of_fields = CTaosInterface.fetchBlock(
|
||||||
|
self._result, self._fields)
|
||||||
errno = CTaosInterface.libtaos.taos_errno(self._result)
|
errno = CTaosInterface.libtaos.taos_errno(self._result)
|
||||||
if errno != 0:
|
if errno != 0:
|
||||||
raise ProgrammingError(CTaosInterface.errStr(self._result), errno)
|
raise ProgrammingError(
|
||||||
if num_of_fields == 0: break
|
CTaosInterface.errStr(
|
||||||
|
self._result), errno)
|
||||||
|
if num_of_fields == 0:
|
||||||
|
break
|
||||||
self._rowcount += num_of_fields
|
self._rowcount += num_of_fields
|
||||||
for i in range(len(self._fields)):
|
for i in range(len(self._fields)):
|
||||||
buffer[i].extend(block[i])
|
buffer[i].extend(block[i])
|
||||||
return list(map(tuple, zip(*buffer)))
|
return list(map(tuple, zip(*buffer)))
|
||||||
|
|
||||||
def nextset(self):
|
def nextset(self):
|
||||||
"""
|
"""
|
||||||
"""
|
"""
|
||||||
|
@ -259,8 +283,8 @@ class TDengineCursor(object):
|
||||||
# if threading.get_ident() != self._threadId:
|
# if threading.get_ident() != self._threadId:
|
||||||
# info = "Cursor handleresult:Thread ID not match,creater:"+str(self._threadId)+" caller:"+str(threading.get_ident())
|
# info = "Cursor handleresult:Thread ID not match,creater:"+str(self._threadId)+" caller:"+str(threading.get_ident())
|
||||||
# raise OperationalError(info)
|
# raise OperationalError(info)
|
||||||
# print(info)
|
# print(info)
|
||||||
# return None
|
# return None
|
||||||
|
|
||||||
self._description = []
|
self._description = []
|
||||||
for ele in self._fields:
|
for ele in self._fields:
|
||||||
|
@ -268,4 +292,3 @@ class TDengineCursor(object):
|
||||||
(ele['name'], ele['type'], None, None, None, None, False))
|
(ele['name'], ele['type'], None, None, None, None, False))
|
||||||
|
|
||||||
return self._result
|
return self._result
|
||||||
|
|
||||||
|
|
|
@ -4,6 +4,7 @@
|
||||||
import time
|
import time
|
||||||
import datetime
|
import datetime
|
||||||
|
|
||||||
|
|
||||||
class DBAPITypeObject(object):
|
class DBAPITypeObject(object):
|
||||||
def __init__(self, *values):
|
def __init__(self, *values):
|
||||||
self.values = values
|
self.values = values
|
||||||
|
@ -16,23 +17,28 @@ class DBAPITypeObject(object):
|
||||||
else:
|
else:
|
||||||
return -1
|
return -1
|
||||||
|
|
||||||
|
|
||||||
Date = datetime.date
|
Date = datetime.date
|
||||||
Time = datetime.time
|
Time = datetime.time
|
||||||
Timestamp = datetime.datetime
|
Timestamp = datetime.datetime
|
||||||
|
|
||||||
|
|
||||||
def DataFromTicks(ticks):
|
def DataFromTicks(ticks):
|
||||||
return Date(*time.localtime(ticks)[:3])
|
return Date(*time.localtime(ticks)[:3])
|
||||||
|
|
||||||
|
|
||||||
def TimeFromTicks(ticks):
|
def TimeFromTicks(ticks):
|
||||||
return Time(*time.localtime(ticks)[3:6])
|
return Time(*time.localtime(ticks)[3:6])
|
||||||
|
|
||||||
|
|
||||||
def TimestampFromTicks(ticks):
|
def TimestampFromTicks(ticks):
|
||||||
return Timestamp(*time.localtime(ticks)[:6])
|
return Timestamp(*time.localtime(ticks)[:6])
|
||||||
|
|
||||||
|
|
||||||
Binary = bytes
|
Binary = bytes
|
||||||
|
|
||||||
# STRING = DBAPITypeObject(*constants.FieldType.get_string_types())
|
# STRING = DBAPITypeObject(*constants.FieldType.get_string_types())
|
||||||
# BINARY = DBAPITypeObject(*constants.FieldType.get_binary_types())
|
# BINARY = DBAPITypeObject(*constants.FieldType.get_binary_types())
|
||||||
# NUMBER = BAPITypeObject(*constants.FieldType.get_number_types())
|
# NUMBER = BAPITypeObject(*constants.FieldType.get_number_types())
|
||||||
# DATETIME = DBAPITypeObject(*constants.FieldType.get_timestamp_types())
|
# DATETIME = DBAPITypeObject(*constants.FieldType.get_timestamp_types())
|
||||||
# ROWID = DBAPITypeObject()
|
# ROWID = DBAPITypeObject()
|
||||||
|
|
|
@ -1,35 +1,41 @@
|
||||||
"""Python exceptions
|
"""Python exceptions
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
|
||||||
class Error(Exception):
|
class Error(Exception):
|
||||||
def __init__(self, msg=None, errno=None):
|
def __init__(self, msg=None, errno=None):
|
||||||
self.msg = msg
|
self.msg = msg
|
||||||
self._full_msg = self.msg
|
self._full_msg = self.msg
|
||||||
self.errno = errno
|
self.errno = errno
|
||||||
|
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
return self._full_msg
|
return self._full_msg
|
||||||
|
|
||||||
|
|
||||||
class Warning(Exception):
|
class Warning(Exception):
|
||||||
"""Exception raised for important warnings like data truncations while inserting.
|
"""Exception raised for important warnings like data truncations while inserting.
|
||||||
"""
|
"""
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
|
||||||
class InterfaceError(Error):
|
class InterfaceError(Error):
|
||||||
"""Exception raised for errors that are related to the database interface rather than the database itself.
|
"""Exception raised for errors that are related to the database interface rather than the database itself.
|
||||||
"""
|
"""
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
|
||||||
class DatabaseError(Error):
|
class DatabaseError(Error):
|
||||||
"""Exception raised for errors that are related to the database.
|
"""Exception raised for errors that are related to the database.
|
||||||
"""
|
"""
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
|
||||||
class DataError(DatabaseError):
|
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.
|
"""Exception raised for errors that are due to problems with the processed data like division by zero, numeric value out of range.
|
||||||
"""
|
"""
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
|
||||||
class OperationalError(DatabaseError):
|
class OperationalError(DatabaseError):
|
||||||
"""Exception raised for errors that are related to the database's operation and not necessarily under the control of the programmer
|
"""Exception raised for errors that are related to the database's operation and not necessarily under the control of the programmer
|
||||||
"""
|
"""
|
||||||
|
@ -41,17 +47,20 @@ class IntegrityError(DatabaseError):
|
||||||
"""
|
"""
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
|
||||||
class InternalError(DatabaseError):
|
class InternalError(DatabaseError):
|
||||||
"""Exception raised when the database encounters an internal error.
|
"""Exception raised when the database encounters an internal error.
|
||||||
"""
|
"""
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
|
||||||
class ProgrammingError(DatabaseError):
|
class ProgrammingError(DatabaseError):
|
||||||
"""Exception raised for programming errors.
|
"""Exception raised for programming errors.
|
||||||
"""
|
"""
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
|
||||||
class NotSupportedError(DatabaseError):
|
class NotSupportedError(DatabaseError):
|
||||||
"""Exception raised in case a method or database API was used which is not supported by the database,.
|
"""Exception raised in case a method or database API was used which is not supported by the database,.
|
||||||
"""
|
"""
|
||||||
pass
|
pass
|
||||||
|
|
|
@ -1,32 +1,33 @@
|
||||||
from .cinterface import CTaosInterface
|
from .cinterface import CTaosInterface
|
||||||
from .error import *
|
from .error import *
|
||||||
|
|
||||||
|
|
||||||
class TDengineSubscription(object):
|
class TDengineSubscription(object):
|
||||||
"""TDengine subscription object
|
"""TDengine subscription object
|
||||||
"""
|
"""
|
||||||
|
|
||||||
def __init__(self, sub):
|
def __init__(self, sub):
|
||||||
self._sub = sub
|
self._sub = sub
|
||||||
|
|
||||||
|
|
||||||
def consume(self):
|
def consume(self):
|
||||||
"""Consume rows of a subscription
|
"""Consume rows of a subscription
|
||||||
"""
|
"""
|
||||||
if self._sub is None:
|
if self._sub is None:
|
||||||
raise OperationalError("Invalid use of consume")
|
raise OperationalError("Invalid use of consume")
|
||||||
|
|
||||||
result, fields = CTaosInterface.consume(self._sub)
|
result, fields = CTaosInterface.consume(self._sub)
|
||||||
buffer = [[] for i in range(len(fields))]
|
buffer = [[] for i in range(len(fields))]
|
||||||
while True:
|
while True:
|
||||||
block, num_of_fields = CTaosInterface.fetchBlock(result, fields)
|
block, num_of_fields = CTaosInterface.fetchBlock(result, fields)
|
||||||
if num_of_fields == 0: break
|
if num_of_fields == 0:
|
||||||
|
break
|
||||||
for i in range(len(fields)):
|
for i in range(len(fields)):
|
||||||
buffer[i].extend(block[i])
|
buffer[i].extend(block[i])
|
||||||
|
|
||||||
self.fields = fields
|
self.fields = fields
|
||||||
return list(map(tuple, zip(*buffer)))
|
return list(map(tuple, zip(*buffer)))
|
||||||
|
|
||||||
|
def close(self, keepProgress=True):
|
||||||
def close(self, keepProgress = True):
|
|
||||||
"""Close the Subscription.
|
"""Close the Subscription.
|
||||||
"""
|
"""
|
||||||
if self._sub is None:
|
if self._sub is None:
|
||||||
|
@ -38,15 +39,19 @@ class TDengineSubscription(object):
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
from .connection import TDengineConnection
|
from .connection import TDengineConnection
|
||||||
conn = TDengineConnection(host="127.0.0.1", user="root", password="taosdata", database="test")
|
conn = TDengineConnection(
|
||||||
|
host="127.0.0.1",
|
||||||
|
user="root",
|
||||||
|
password="taosdata",
|
||||||
|
database="test")
|
||||||
|
|
||||||
# Generate a cursor object to run SQL commands
|
# Generate a cursor object to run SQL commands
|
||||||
sub = conn.subscribe(True, "test", "select * from meters;", 1000)
|
sub = conn.subscribe(True, "test", "select * from meters;", 1000)
|
||||||
|
|
||||||
for i in range(0,10):
|
for i in range(0, 10):
|
||||||
data = sub.consume()
|
data = sub.consume()
|
||||||
for d in data:
|
for d in data:
|
||||||
print(d)
|
print(d)
|
||||||
|
|
||||||
sub.close()
|
sub.close()
|
||||||
conn.close()
|
conn.close()
|
||||||
|
|
|
@ -5,7 +5,7 @@ with open("README.md", "r") as fh:
|
||||||
|
|
||||||
setuptools.setup(
|
setuptools.setup(
|
||||||
name="taos",
|
name="taos",
|
||||||
version="2.0.4",
|
version="2.0.5",
|
||||||
author="Taosdata Inc.",
|
author="Taosdata Inc.",
|
||||||
author_email="support@taosdata.com",
|
author_email="support@taosdata.com",
|
||||||
description="TDengine python client package",
|
description="TDengine python client package",
|
||||||
|
|
|
@ -3,12 +3,12 @@ from .connection import TDengineConnection
|
||||||
from .cursor import TDengineCursor
|
from .cursor import TDengineCursor
|
||||||
|
|
||||||
# Globals
|
# Globals
|
||||||
apilevel = '2.0.4'
|
|
||||||
threadsafety = 0
|
threadsafety = 0
|
||||||
paramstyle = 'pyformat'
|
paramstyle = 'pyformat'
|
||||||
|
|
||||||
__all__ = ['connection', 'cursor']
|
__all__ = ['connection', 'cursor']
|
||||||
|
|
||||||
|
|
||||||
def connect(*args, **kwargs):
|
def connect(*args, **kwargs):
|
||||||
""" Function to return a TDengine connector object
|
""" Function to return a TDengine connector object
|
||||||
|
|
||||||
|
|
|
@ -4,11 +4,14 @@ from .error import *
|
||||||
import math
|
import math
|
||||||
import datetime
|
import datetime
|
||||||
|
|
||||||
|
|
||||||
def _convert_millisecond_to_datetime(milli):
|
def _convert_millisecond_to_datetime(milli):
|
||||||
return datetime.datetime.fromtimestamp(milli/1000.0)
|
return datetime.datetime.fromtimestamp(milli / 1000.0)
|
||||||
|
|
||||||
|
|
||||||
def _convert_microsecond_to_datetime(micro):
|
def _convert_microsecond_to_datetime(micro):
|
||||||
return datetime.datetime.fromtimestamp(micro/1000000.0)
|
return datetime.datetime.fromtimestamp(micro / 1000000.0)
|
||||||
|
|
||||||
|
|
||||||
def _crow_timestamp_to_python(data, num_of_rows, nbytes=None, micro=False):
|
def _crow_timestamp_to_python(data, num_of_rows, nbytes=None, micro=False):
|
||||||
"""Function to convert C bool row to python row
|
"""Function to convert C bool row to python row
|
||||||
|
@ -18,168 +21,309 @@ def _crow_timestamp_to_python(data, num_of_rows, nbytes=None, micro=False):
|
||||||
_timestamp_converter = _convert_microsecond_to_datetime
|
_timestamp_converter = _convert_microsecond_to_datetime
|
||||||
|
|
||||||
if num_of_rows > 0:
|
if num_of_rows > 0:
|
||||||
return list(map(_timestamp_converter, ctypes.cast(data, ctypes.POINTER(ctypes.c_long))[:abs(num_of_rows)]))
|
return list(map(_timestamp_converter, ctypes.cast(
|
||||||
|
data, ctypes.POINTER(ctypes.c_long))[:abs(num_of_rows)]))
|
||||||
else:
|
else:
|
||||||
return list(map(_timestamp_converter, ctypes.cast(data, ctypes.POINTER(ctypes.c_long))[:abs(num_of_rows)]))
|
return list(map(_timestamp_converter, ctypes.cast(
|
||||||
|
data, ctypes.POINTER(ctypes.c_long))[:abs(num_of_rows)]))
|
||||||
|
|
||||||
|
|
||||||
def _crow_bool_to_python(data, num_of_rows, nbytes=None, micro=False):
|
def _crow_bool_to_python(data, num_of_rows, nbytes=None, micro=False):
|
||||||
"""Function to convert C bool row to python row
|
"""Function to convert C bool row to python row
|
||||||
"""
|
"""
|
||||||
if num_of_rows > 0:
|
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)] ]
|
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)]]
|
||||||
else:
|
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)] ]
|
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):
|
def _crow_tinyint_to_python(data, num_of_rows, nbytes=None, micro=False):
|
||||||
"""Function to convert C tinyint row to python row
|
"""Function to convert C tinyint row to python row
|
||||||
"""
|
"""
|
||||||
if num_of_rows > 0:
|
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)] ]
|
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)]]
|
||||||
else:
|
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)] ]
|
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_tinyint_unsigned_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_UNSIGNED_NULL else ele for ele in ctypes.cast(
|
||||||
|
data, ctypes.POINTER(
|
||||||
|
ctypes.c_byte))[
|
||||||
|
:abs(num_of_rows)]]
|
||||||
|
else:
|
||||||
|
return [
|
||||||
|
None if ele == FieldType.C_TINYINT_UNSIGNED_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):
|
def _crow_smallint_to_python(data, num_of_rows, nbytes=None, micro=False):
|
||||||
"""Function to convert C smallint row to python row
|
"""Function to convert C smallint row to python row
|
||||||
"""
|
"""
|
||||||
if num_of_rows > 0:
|
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)]]
|
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)]]
|
||||||
else:
|
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)] ]
|
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_smallint_unsigned_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_UNSIGNED_NULL else ele for ele in ctypes.cast(
|
||||||
|
data, ctypes.POINTER(
|
||||||
|
ctypes.c_short))[
|
||||||
|
:abs(num_of_rows)]]
|
||||||
|
else:
|
||||||
|
return [
|
||||||
|
None if ele == FieldType.C_SMALLINT_UNSIGNED_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):
|
def _crow_int_to_python(data, num_of_rows, nbytes=None, micro=False):
|
||||||
"""Function to convert C int row to python row
|
"""Function to convert C int row to python row
|
||||||
"""
|
"""
|
||||||
if num_of_rows > 0:
|
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)] ]
|
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)]]
|
||||||
else:
|
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)] ]
|
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_int_unsigned_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_UNSIGNED_NULL else ele for ele in ctypes.cast(
|
||||||
|
data, ctypes.POINTER(
|
||||||
|
ctypes.c_int))[
|
||||||
|
:abs(num_of_rows)]]
|
||||||
|
else:
|
||||||
|
return [
|
||||||
|
None if ele == FieldType.C_INT_UNSIGNED_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):
|
def _crow_bigint_to_python(data, num_of_rows, nbytes=None, micro=False):
|
||||||
"""Function to convert C bigint row to python row
|
"""Function to convert C bigint row to python row
|
||||||
"""
|
"""
|
||||||
if num_of_rows > 0:
|
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_long))[:abs(num_of_rows)] ]
|
return [None if ele == FieldType.C_BIGINT_NULL else ele for ele in ctypes.cast(
|
||||||
|
data, ctypes.POINTER(ctypes.c_long))[:abs(num_of_rows)]]
|
||||||
else:
|
else:
|
||||||
return [ None if ele == FieldType.C_BIGINT_NULL else ele for ele in ctypes.cast(data, ctypes.POINTER(ctypes.c_long))[:abs(num_of_rows)] ]
|
return [None if ele == FieldType.C_BIGINT_NULL else ele for ele in ctypes.cast(
|
||||||
|
data, ctypes.POINTER(ctypes.c_long))[:abs(num_of_rows)]]
|
||||||
|
|
||||||
|
|
||||||
|
def _crow_bigint_unsigned_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_UNSIGNED_NULL else ele for ele in ctypes.cast(
|
||||||
|
data, ctypes.POINTER(
|
||||||
|
ctypes.c_long))[
|
||||||
|
:abs(num_of_rows)]]
|
||||||
|
else:
|
||||||
|
return [
|
||||||
|
None if ele == FieldType.C_BIGINT_UNSIGNED_NULL else ele for ele in ctypes.cast(
|
||||||
|
data, ctypes.POINTER(
|
||||||
|
ctypes.c_long))[
|
||||||
|
:abs(num_of_rows)]]
|
||||||
|
|
||||||
|
|
||||||
def _crow_float_to_python(data, num_of_rows, nbytes=None, micro=False):
|
def _crow_float_to_python(data, num_of_rows, nbytes=None, micro=False):
|
||||||
"""Function to convert C float row to python row
|
"""Function to convert C float row to python row
|
||||||
"""
|
"""
|
||||||
if num_of_rows > 0:
|
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)] ]
|
return [None if math.isnan(ele) else ele for ele in ctypes.cast(
|
||||||
|
data, ctypes.POINTER(ctypes.c_float))[:abs(num_of_rows)]]
|
||||||
else:
|
else:
|
||||||
return [ None if math.isnan(ele) else ele for ele in ctypes.cast(data, ctypes.POINTER(ctypes.c_float))[:abs(num_of_rows)] ]
|
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):
|
def _crow_double_to_python(data, num_of_rows, nbytes=None, micro=False):
|
||||||
"""Function to convert C double row to python row
|
"""Function to convert C double row to python row
|
||||||
"""
|
"""
|
||||||
if num_of_rows > 0:
|
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)] ]
|
return [None if math.isnan(ele) else ele for ele in ctypes.cast(
|
||||||
|
data, ctypes.POINTER(ctypes.c_double))[:abs(num_of_rows)]]
|
||||||
else:
|
else:
|
||||||
return [ None if math.isnan(ele) else ele for ele in ctypes.cast(data, ctypes.POINTER(ctypes.c_double))[:abs(num_of_rows)] ]
|
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):
|
def _crow_binary_to_python(data, num_of_rows, nbytes=None, micro=False):
|
||||||
"""Function to convert C binary row to python row
|
"""Function to convert C binary row to python row
|
||||||
"""
|
"""
|
||||||
assert(nbytes is not None)
|
assert(nbytes is not None)
|
||||||
if num_of_rows > 0:
|
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)]]
|
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)]]
|
||||||
else:
|
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)]]
|
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):
|
def _crow_nchar_to_python(data, num_of_rows, nbytes=None, micro=False):
|
||||||
"""Function to convert C nchar row to python row
|
"""Function to convert C nchar row to python row
|
||||||
"""
|
"""
|
||||||
assert(nbytes is not None)
|
assert(nbytes is not None)
|
||||||
res=[]
|
res = []
|
||||||
for i in range(abs(num_of_rows)):
|
for i in range(abs(num_of_rows)):
|
||||||
try:
|
try:
|
||||||
if num_of_rows >= 0:
|
if num_of_rows >= 0:
|
||||||
tmpstr = ctypes.c_char_p(data)
|
tmpstr = ctypes.c_char_p(data)
|
||||||
res.append( tmpstr.value.decode() )
|
res.append(tmpstr.value.decode())
|
||||||
else:
|
else:
|
||||||
res.append( (ctypes.cast(data+nbytes*i, ctypes.POINTER(ctypes.c_wchar * (nbytes//4))))[0].value )
|
res.append((ctypes.cast(data + nbytes * i,
|
||||||
|
ctypes.POINTER(ctypes.c_wchar * (nbytes // 4))))[0].value)
|
||||||
except ValueError:
|
except ValueError:
|
||||||
res.append(None)
|
res.append(None)
|
||||||
|
|
||||||
return res
|
return res
|
||||||
|
|
||||||
|
|
||||||
def _crow_binary_to_python_block(data, num_of_rows, nbytes=None, micro=False):
|
def _crow_binary_to_python_block(data, num_of_rows, nbytes=None, micro=False):
|
||||||
"""Function to convert C binary row to python row
|
"""Function to convert C binary row to python row
|
||||||
"""
|
"""
|
||||||
assert(nbytes is not None)
|
assert(nbytes is not None)
|
||||||
res=[]
|
res = []
|
||||||
if num_of_rows > 0:
|
if num_of_rows > 0:
|
||||||
for i in range(abs(num_of_rows)):
|
for i in range(abs(num_of_rows)):
|
||||||
try:
|
try:
|
||||||
rbyte=ctypes.cast(data+nbytes*i,ctypes.POINTER(ctypes.c_short))[:1].pop()
|
rbyte = ctypes.cast(
|
||||||
tmpstr = ctypes.c_char_p(data+nbytes*i+2)
|
data + nbytes * i,
|
||||||
res.append( tmpstr.value.decode()[0:rbyte] )
|
ctypes.POINTER(
|
||||||
|
ctypes.c_short))[
|
||||||
|
:1].pop()
|
||||||
|
tmpstr = ctypes.c_char_p(data + nbytes * i + 2)
|
||||||
|
res.append(tmpstr.value.decode()[0:rbyte])
|
||||||
except ValueError:
|
except ValueError:
|
||||||
res.append(None)
|
res.append(None)
|
||||||
else:
|
else:
|
||||||
for i in range(abs(num_of_rows)):
|
for i in range(abs(num_of_rows)):
|
||||||
try:
|
try:
|
||||||
rbyte=ctypes.cast(data+nbytes*i,ctypes.POINTER(ctypes.c_short))[:1].pop()
|
rbyte = ctypes.cast(
|
||||||
tmpstr = ctypes.c_char_p(data+nbytes*i+2)
|
data + nbytes * i,
|
||||||
res.append( tmpstr.value.decode()[0:rbyte] )
|
ctypes.POINTER(
|
||||||
|
ctypes.c_short))[
|
||||||
|
:1].pop()
|
||||||
|
tmpstr = ctypes.c_char_p(data + nbytes * i + 2)
|
||||||
|
res.append(tmpstr.value.decode()[0:rbyte])
|
||||||
except ValueError:
|
except ValueError:
|
||||||
res.append(None)
|
res.append(None)
|
||||||
return res
|
return res
|
||||||
|
|
||||||
|
|
||||||
def _crow_nchar_to_python_block(data, num_of_rows, nbytes=None, micro=False):
|
def _crow_nchar_to_python_block(data, num_of_rows, nbytes=None, micro=False):
|
||||||
"""Function to convert C nchar row to python row
|
"""Function to convert C nchar row to python row
|
||||||
"""
|
"""
|
||||||
assert(nbytes is not None)
|
assert(nbytes is not None)
|
||||||
res=[]
|
res = []
|
||||||
if num_of_rows >= 0:
|
if num_of_rows >= 0:
|
||||||
for i in range(abs(num_of_rows)):
|
for i in range(abs(num_of_rows)):
|
||||||
try:
|
try:
|
||||||
tmpstr = ctypes.c_char_p(data+nbytes*i+2)
|
tmpstr = ctypes.c_char_p(data + nbytes * i + 2)
|
||||||
res.append( tmpstr.value.decode() )
|
res.append(tmpstr.value.decode())
|
||||||
except ValueError:
|
except ValueError:
|
||||||
res.append(None)
|
res.append(None)
|
||||||
else:
|
else:
|
||||||
for i in range(abs(num_of_rows)):
|
for i in range(abs(num_of_rows)):
|
||||||
try:
|
try:
|
||||||
res.append( (ctypes.cast(data+nbytes*i+2, ctypes.POINTER(ctypes.c_wchar * (nbytes//4))))[0].value )
|
res.append((ctypes.cast(data + nbytes * i + 2,
|
||||||
|
ctypes.POINTER(ctypes.c_wchar * (nbytes // 4))))[0].value)
|
||||||
except ValueError:
|
except ValueError:
|
||||||
res.append(None)
|
res.append(None)
|
||||||
return res
|
return res
|
||||||
|
|
||||||
|
|
||||||
_CONVERT_FUNC = {
|
_CONVERT_FUNC = {
|
||||||
FieldType.C_BOOL: _crow_bool_to_python,
|
FieldType.C_BOOL: _crow_bool_to_python,
|
||||||
FieldType.C_TINYINT : _crow_tinyint_to_python,
|
FieldType.C_TINYINT: _crow_tinyint_to_python,
|
||||||
FieldType.C_SMALLINT : _crow_smallint_to_python,
|
FieldType.C_SMALLINT: _crow_smallint_to_python,
|
||||||
FieldType.C_INT : _crow_int_to_python,
|
FieldType.C_INT: _crow_int_to_python,
|
||||||
FieldType.C_BIGINT : _crow_bigint_to_python,
|
FieldType.C_BIGINT: _crow_bigint_to_python,
|
||||||
FieldType.C_FLOAT : _crow_float_to_python,
|
FieldType.C_FLOAT: _crow_float_to_python,
|
||||||
FieldType.C_DOUBLE : _crow_double_to_python,
|
FieldType.C_DOUBLE: _crow_double_to_python,
|
||||||
FieldType.C_BINARY: _crow_binary_to_python,
|
FieldType.C_BINARY: _crow_binary_to_python,
|
||||||
FieldType.C_TIMESTAMP : _crow_timestamp_to_python,
|
FieldType.C_TIMESTAMP: _crow_timestamp_to_python,
|
||||||
FieldType.C_NCHAR : _crow_nchar_to_python
|
FieldType.C_NCHAR: _crow_nchar_to_python,
|
||||||
|
FieldType.C_TINYINT_UNSIGNED: _crow_tinyint_unsigned_to_python,
|
||||||
|
FieldType.C_SMALLINT_UNSIGNED: _crow_smallint_unsigned_to_python,
|
||||||
|
FieldType.C_INT_UNSIGNED: _crow_int_unsigned_to_python,
|
||||||
|
FieldType.C_BIGINT_UNSIGNED: _crow_bigint_unsigned_to_python
|
||||||
}
|
}
|
||||||
|
|
||||||
_CONVERT_FUNC_BLOCK = {
|
_CONVERT_FUNC_BLOCK = {
|
||||||
FieldType.C_BOOL: _crow_bool_to_python,
|
FieldType.C_BOOL: _crow_bool_to_python,
|
||||||
FieldType.C_TINYINT : _crow_tinyint_to_python,
|
FieldType.C_TINYINT: _crow_tinyint_to_python,
|
||||||
FieldType.C_SMALLINT : _crow_smallint_to_python,
|
FieldType.C_SMALLINT: _crow_smallint_to_python,
|
||||||
FieldType.C_INT : _crow_int_to_python,
|
FieldType.C_INT: _crow_int_to_python,
|
||||||
FieldType.C_BIGINT : _crow_bigint_to_python,
|
FieldType.C_BIGINT: _crow_bigint_to_python,
|
||||||
FieldType.C_FLOAT : _crow_float_to_python,
|
FieldType.C_FLOAT: _crow_float_to_python,
|
||||||
FieldType.C_DOUBLE : _crow_double_to_python,
|
FieldType.C_DOUBLE: _crow_double_to_python,
|
||||||
FieldType.C_BINARY: _crow_binary_to_python_block,
|
FieldType.C_BINARY: _crow_binary_to_python_block,
|
||||||
FieldType.C_TIMESTAMP : _crow_timestamp_to_python,
|
FieldType.C_TIMESTAMP: _crow_timestamp_to_python,
|
||||||
FieldType.C_NCHAR : _crow_nchar_to_python_block
|
FieldType.C_NCHAR: _crow_nchar_to_python_block,
|
||||||
|
FieldType.C_TINYINT_UNSIGNED: _crow_tinyint_unsigned_to_python,
|
||||||
|
FieldType.C_SMALLINT_UNSIGNED: _crow_smallint_unsigned_to_python,
|
||||||
|
FieldType.C_INT_UNSIGNED: _crow_int_unsigned_to_python,
|
||||||
|
FieldType.C_BIGINT_UNSIGNED: _crow_bigint_unsigned_to_python
|
||||||
}
|
}
|
||||||
|
|
||||||
# Corresponding TAOS_FIELD structure in C
|
# Corresponding TAOS_FIELD structure in C
|
||||||
|
|
||||||
|
|
||||||
class TaosField(ctypes.Structure):
|
class TaosField(ctypes.Structure):
|
||||||
_fields_ = [('name', ctypes.c_char * 65),
|
_fields_ = [('name', ctypes.c_char * 65),
|
||||||
('type', ctypes.c_char),
|
('type', ctypes.c_char),
|
||||||
('bytes', ctypes.c_short)]
|
('bytes', ctypes.c_short)]
|
||||||
|
|
||||||
# C interface class
|
# C interface class
|
||||||
|
|
||||||
|
|
||||||
class CTaosInterface(object):
|
class CTaosInterface(object):
|
||||||
|
|
||||||
libtaos = ctypes.CDLL('libtaos.dylib')
|
libtaos = ctypes.CDLL('libtaos.dylib')
|
||||||
|
@ -216,7 +360,7 @@ class CTaosInterface(object):
|
||||||
except AttributeError:
|
except AttributeError:
|
||||||
raise AttributeError("config is expected as a str")
|
raise AttributeError("config is expected as a str")
|
||||||
|
|
||||||
if config != None:
|
if config is not None:
|
||||||
CTaosInterface.libtaos.taos_options(3, self._config)
|
CTaosInterface.libtaos.taos_options(3, self._config)
|
||||||
|
|
||||||
CTaosInterface.libtaos.taos_init()
|
CTaosInterface.libtaos.taos_init()
|
||||||
|
@ -227,7 +371,13 @@ class CTaosInterface(object):
|
||||||
"""
|
"""
|
||||||
return self._config
|
return self._config
|
||||||
|
|
||||||
def connect(self, host=None, user="root", password="taosdata", db=None, port=0):
|
def connect(
|
||||||
|
self,
|
||||||
|
host=None,
|
||||||
|
user="root",
|
||||||
|
password="taosdata",
|
||||||
|
db=None,
|
||||||
|
port=0):
|
||||||
'''
|
'''
|
||||||
Function to connect to server
|
Function to connect to server
|
||||||
|
|
||||||
|
@ -236,7 +386,7 @@ class CTaosInterface(object):
|
||||||
# host
|
# host
|
||||||
try:
|
try:
|
||||||
_host = ctypes.c_char_p(host.encode(
|
_host = ctypes.c_char_p(host.encode(
|
||||||
"utf-8")) if host != None else ctypes.c_char_p(None)
|
"utf-8")) if host is not None else ctypes.c_char_p(None)
|
||||||
except AttributeError:
|
except AttributeError:
|
||||||
raise AttributeError("host is expected as a str")
|
raise AttributeError("host is expected as a str")
|
||||||
|
|
||||||
|
@ -255,7 +405,7 @@ class CTaosInterface(object):
|
||||||
# db
|
# db
|
||||||
try:
|
try:
|
||||||
_db = ctypes.c_char_p(
|
_db = ctypes.c_char_p(
|
||||||
db.encode("utf-8")) if db != None else ctypes.c_char_p(None)
|
db.encode("utf-8")) if db is not None else ctypes.c_char_p(None)
|
||||||
except AttributeError:
|
except AttributeError:
|
||||||
raise AttributeError("db is expected as a str")
|
raise AttributeError("db is expected as a str")
|
||||||
|
|
||||||
|
@ -268,11 +418,11 @@ class CTaosInterface(object):
|
||||||
connection = ctypes.c_void_p(CTaosInterface.libtaos.taos_connect(
|
connection = ctypes.c_void_p(CTaosInterface.libtaos.taos_connect(
|
||||||
_host, _user, _password, _db, _port))
|
_host, _user, _password, _db, _port))
|
||||||
|
|
||||||
if connection.value == None:
|
if connection.value is None:
|
||||||
print('connect to TDengine failed')
|
print('connect to TDengine failed')
|
||||||
raise ConnectionError("connect to TDengine failed")
|
raise ConnectionError("connect to TDengine failed")
|
||||||
# sys.exit(1)
|
# sys.exit(1)
|
||||||
#else:
|
# else:
|
||||||
# print('connect to TDengine success')
|
# print('connect to TDengine success')
|
||||||
|
|
||||||
return connection
|
return connection
|
||||||
|
@ -293,7 +443,8 @@ class CTaosInterface(object):
|
||||||
@rtype: 0 on success and -1 on failure
|
@rtype: 0 on success and -1 on failure
|
||||||
'''
|
'''
|
||||||
try:
|
try:
|
||||||
return CTaosInterface.libtaos.taos_query(connection, ctypes.c_char_p(sql.encode('utf-8')))
|
return CTaosInterface.libtaos.taos_query(
|
||||||
|
connection, ctypes.c_char_p(sql.encode('utf-8')))
|
||||||
except AttributeError:
|
except AttributeError:
|
||||||
raise AttributeError("sql is expected as a string")
|
raise AttributeError("sql is expected as a string")
|
||||||
# finally:
|
# finally:
|
||||||
|
@ -308,7 +459,7 @@ class CTaosInterface(object):
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def subscribe(connection, restart, topic, sql, interval):
|
def subscribe(connection, restart, topic, sql, interval):
|
||||||
"""Create a subscription
|
"""Create a subscription
|
||||||
@restart boolean,
|
@restart boolean,
|
||||||
@sql string, sql statement for data query, must be a 'select' statement.
|
@sql string, sql statement for data query, must be a 'select' statement.
|
||||||
@topic string, name of this subscription
|
@topic string, name of this subscription
|
||||||
"""
|
"""
|
||||||
|
@ -360,35 +511,49 @@ class CTaosInterface(object):
|
||||||
result, ctypes.byref(pblock))
|
result, ctypes.byref(pblock))
|
||||||
if num_of_rows == 0:
|
if num_of_rows == 0:
|
||||||
return None, 0
|
return None, 0
|
||||||
isMicro = (CTaosInterface.libtaos.taos_result_precision(result) == FieldType.C_TIMESTAMP_MICRO)
|
isMicro = (CTaosInterface.libtaos.taos_result_precision(
|
||||||
|
result) == FieldType.C_TIMESTAMP_MICRO)
|
||||||
blocks = [None] * len(fields)
|
blocks = [None] * len(fields)
|
||||||
fieldL = CTaosInterface.libtaos.taos_fetch_lengths(result)
|
fieldL = CTaosInterface.libtaos.taos_fetch_lengths(result)
|
||||||
fieldLen = [ele for ele in ctypes.cast(fieldL, ctypes.POINTER(ctypes.c_int))[:len(fields)]]
|
fieldLen = [
|
||||||
|
ele for ele in ctypes.cast(
|
||||||
|
fieldL, ctypes.POINTER(
|
||||||
|
ctypes.c_int))[
|
||||||
|
:len(fields)]]
|
||||||
for i in range(len(fields)):
|
for i in range(len(fields)):
|
||||||
data = ctypes.cast(pblock, ctypes.POINTER(ctypes.c_void_p))[i]
|
data = ctypes.cast(pblock, ctypes.POINTER(ctypes.c_void_p))[i]
|
||||||
if fields[i]['type'] not in _CONVERT_FUNC_BLOCK:
|
if fields[i]['type'] not in _CONVERT_FUNC_BLOCK:
|
||||||
raise DatabaseError("Invalid data type returned from database")
|
raise DatabaseError("Invalid data type returned from database")
|
||||||
blocks[i] = _CONVERT_FUNC_BLOCK[fields[i]['type']](data, num_of_rows, fieldLen[i], isMicro)
|
blocks[i] = _CONVERT_FUNC_BLOCK[fields[i]['type']](
|
||||||
|
data, num_of_rows, fieldLen[i], isMicro)
|
||||||
|
|
||||||
return blocks, abs(num_of_rows)
|
return blocks, abs(num_of_rows)
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def fetchRow(result, fields):
|
def fetchRow(result, fields):
|
||||||
pblock = ctypes.c_void_p(0)
|
pblock = ctypes.c_void_p(0)
|
||||||
pblock = CTaosInterface.libtaos.taos_fetch_row(result)
|
pblock = CTaosInterface.libtaos.taos_fetch_row(result)
|
||||||
if pblock :
|
if pblock:
|
||||||
num_of_rows = 1
|
num_of_rows = 1
|
||||||
isMicro = (CTaosInterface.libtaos.taos_result_precision(result) == FieldType.C_TIMESTAMP_MICRO)
|
isMicro = (CTaosInterface.libtaos.taos_result_precision(
|
||||||
|
result) == FieldType.C_TIMESTAMP_MICRO)
|
||||||
blocks = [None] * len(fields)
|
blocks = [None] * len(fields)
|
||||||
fieldL = CTaosInterface.libtaos.taos_fetch_lengths(result)
|
fieldL = CTaosInterface.libtaos.taos_fetch_lengths(result)
|
||||||
fieldLen = [ele for ele in ctypes.cast(fieldL, ctypes.POINTER(ctypes.c_int))[:len(fields)]]
|
fieldLen = [
|
||||||
|
ele for ele in ctypes.cast(
|
||||||
|
fieldL, ctypes.POINTER(
|
||||||
|
ctypes.c_int))[
|
||||||
|
:len(fields)]]
|
||||||
for i in range(len(fields)):
|
for i in range(len(fields)):
|
||||||
data = ctypes.cast(pblock, ctypes.POINTER(ctypes.c_void_p))[i]
|
data = ctypes.cast(pblock, ctypes.POINTER(ctypes.c_void_p))[i]
|
||||||
if fields[i]['type'] not in _CONVERT_FUNC:
|
if fields[i]['type'] not in _CONVERT_FUNC:
|
||||||
raise DatabaseError("Invalid data type returned from database")
|
raise DatabaseError(
|
||||||
|
"Invalid data type returned from database")
|
||||||
if data is None:
|
if data is None:
|
||||||
blocks[i] = [None]
|
blocks[i] = [None]
|
||||||
else:
|
else:
|
||||||
blocks[i] = _CONVERT_FUNC[fields[i]['type']](data, num_of_rows, fieldLen[i], isMicro)
|
blocks[i] = _CONVERT_FUNC[fields[i]['type']](
|
||||||
|
data, num_of_rows, fieldLen[i], isMicro)
|
||||||
else:
|
else:
|
||||||
return None, 0
|
return None, 0
|
||||||
return blocks, abs(num_of_rows)
|
return blocks, abs(num_of_rows)
|
||||||
|
|
|
@ -2,9 +2,11 @@ from .cursor import TDengineCursor
|
||||||
from .subscription import TDengineSubscription
|
from .subscription import TDengineSubscription
|
||||||
from .cinterface import CTaosInterface
|
from .cinterface import CTaosInterface
|
||||||
|
|
||||||
|
|
||||||
class TDengineConnection(object):
|
class TDengineConnection(object):
|
||||||
""" TDengine connection object
|
""" TDengine connection object
|
||||||
"""
|
"""
|
||||||
|
|
||||||
def __init__(self, *args, **kwargs):
|
def __init__(self, *args, **kwargs):
|
||||||
self._conn = None
|
self._conn = None
|
||||||
self._host = None
|
self._host = None
|
||||||
|
@ -29,7 +31,7 @@ class TDengineConnection(object):
|
||||||
# password
|
# password
|
||||||
if 'password' in kwargs:
|
if 'password' in kwargs:
|
||||||
self._password = kwargs['password']
|
self._password = kwargs['password']
|
||||||
|
|
||||||
# database
|
# database
|
||||||
if 'database' in kwargs:
|
if 'database' in kwargs:
|
||||||
self._database = kwargs['database']
|
self._database = kwargs['database']
|
||||||
|
@ -43,7 +45,12 @@ class TDengineConnection(object):
|
||||||
self._config = kwargs['config']
|
self._config = kwargs['config']
|
||||||
|
|
||||||
self._chandle = CTaosInterface(self._config)
|
self._chandle = CTaosInterface(self._config)
|
||||||
self._conn = self._chandle.connect(self._host, self._user, self._password, self._database, self._port)
|
self._conn = self._chandle.connect(
|
||||||
|
self._host,
|
||||||
|
self._user,
|
||||||
|
self._password,
|
||||||
|
self._database,
|
||||||
|
self._port)
|
||||||
|
|
||||||
def close(self):
|
def close(self):
|
||||||
"""Close current connection.
|
"""Close current connection.
|
||||||
|
@ -55,7 +62,8 @@ class TDengineConnection(object):
|
||||||
"""
|
"""
|
||||||
if self._conn is None:
|
if self._conn is None:
|
||||||
return None
|
return None
|
||||||
sub = CTaosInterface.subscribe(self._conn, restart, topic, sql, interval)
|
sub = CTaosInterface.subscribe(
|
||||||
|
self._conn, restart, topic, sql, interval)
|
||||||
return TDengineSubscription(sub)
|
return TDengineSubscription(sub)
|
||||||
|
|
||||||
def cursor(self):
|
def cursor(self):
|
||||||
|
@ -80,7 +88,8 @@ class TDengineConnection(object):
|
||||||
"""
|
"""
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
conn = TDengineConnection(host='192.168.1.107')
|
conn = TDengineConnection(host='192.168.1.107')
|
||||||
conn.close()
|
conn.close()
|
||||||
print("Hello world")
|
print("Hello world")
|
||||||
|
|
|
@ -3,6 +3,7 @@
|
||||||
|
|
||||||
from .dbapi import *
|
from .dbapi import *
|
||||||
|
|
||||||
|
|
||||||
class FieldType(object):
|
class FieldType(object):
|
||||||
"""TDengine Field Types
|
"""TDengine Field Types
|
||||||
"""
|
"""
|
||||||
|
@ -18,13 +19,21 @@ class FieldType(object):
|
||||||
C_BINARY = 8
|
C_BINARY = 8
|
||||||
C_TIMESTAMP = 9
|
C_TIMESTAMP = 9
|
||||||
C_NCHAR = 10
|
C_NCHAR = 10
|
||||||
|
C_TINYINT_UNSIGNED = 12
|
||||||
|
C_SMALLINT_UNSIGNED = 13
|
||||||
|
C_INT_UNSIGNED = 14
|
||||||
|
C_BIGINT_UNSIGNED = 15
|
||||||
# NULL value definition
|
# NULL value definition
|
||||||
# NOTE: These values should change according to C definition in tsdb.h
|
# NOTE: These values should change according to C definition in tsdb.h
|
||||||
C_BOOL_NULL = 0x02
|
C_BOOL_NULL = 0x02
|
||||||
C_TINYINT_NULL = -128
|
C_TINYINT_NULL = -128
|
||||||
|
C_TINYINT_UNSIGNED_NULL = 255
|
||||||
C_SMALLINT_NULL = -32768
|
C_SMALLINT_NULL = -32768
|
||||||
|
C_SMALLINT_UNSIGNED_NULL = 65535
|
||||||
C_INT_NULL = -2147483648
|
C_INT_NULL = -2147483648
|
||||||
|
C_INT_UNSIGNED_NULL = 4294967295
|
||||||
C_BIGINT_NULL = -9223372036854775808
|
C_BIGINT_NULL = -9223372036854775808
|
||||||
|
C_BIGINT_UNSIGNED_NULL = 18446744073709551615
|
||||||
C_FLOAT_NULL = float('nan')
|
C_FLOAT_NULL = float('nan')
|
||||||
C_DOUBLE_NULL = float('nan')
|
C_DOUBLE_NULL = float('nan')
|
||||||
C_BINARY_NULL = bytearray([int('0xff', 16)])
|
C_BINARY_NULL = bytearray([int('0xff', 16)])
|
||||||
|
|
|
@ -5,6 +5,7 @@ import threading
|
||||||
|
|
||||||
# querySeqNum = 0
|
# querySeqNum = 0
|
||||||
|
|
||||||
|
|
||||||
class TDengineCursor(object):
|
class TDengineCursor(object):
|
||||||
"""Database cursor which is used to manage the context of a fetch operation.
|
"""Database cursor which is used to manage the context of a fetch operation.
|
||||||
|
|
||||||
|
@ -107,8 +108,8 @@ class TDengineCursor(object):
|
||||||
# if threading.get_ident() != self._threadId:
|
# if threading.get_ident() != self._threadId:
|
||||||
# info ="Cursor execute:Thread ID not match,creater:"+str(self._threadId)+" caller:"+str(threading.get_ident())
|
# info ="Cursor execute:Thread ID not match,creater:"+str(self._threadId)+" caller:"+str(threading.get_ident())
|
||||||
# raise OperationalError(info)
|
# raise OperationalError(info)
|
||||||
# print(info)
|
# print(info)
|
||||||
# return None
|
# return None
|
||||||
|
|
||||||
if not operation:
|
if not operation:
|
||||||
return None
|
return None
|
||||||
|
@ -137,8 +138,8 @@ class TDengineCursor(object):
|
||||||
if errno == 0:
|
if errno == 0:
|
||||||
if CTaosInterface.fieldsCount(self._result) == 0:
|
if CTaosInterface.fieldsCount(self._result) == 0:
|
||||||
self._affected_rows += CTaosInterface.affectedRows(
|
self._affected_rows += CTaosInterface.affectedRows(
|
||||||
self._result )
|
self._result)
|
||||||
return CTaosInterface.affectedRows(self._result )
|
return CTaosInterface.affectedRows(self._result)
|
||||||
else:
|
else:
|
||||||
self._fields = CTaosInterface.useResult(
|
self._fields = CTaosInterface.useResult(
|
||||||
self._result)
|
self._result)
|
||||||
|
@ -168,11 +169,26 @@ class TDengineCursor(object):
|
||||||
if (dataType.upper() == "TINYINT"):
|
if (dataType.upper() == "TINYINT"):
|
||||||
if (self._description[col][1] == FieldType.C_TINYINT):
|
if (self._description[col][1] == FieldType.C_TINYINT):
|
||||||
return True
|
return True
|
||||||
|
if (dataType.upper() == "TINYINT UNSIGNED"):
|
||||||
|
if (self._description[col][1] == FieldType.C_TINYINT_UNSIGNED):
|
||||||
|
return True
|
||||||
|
if (dataType.upper() == "SMALLINT"):
|
||||||
|
if (self._description[col][1] == FieldType.C_SMALLINT):
|
||||||
|
return True
|
||||||
|
if (dataType.upper() == "SMALLINT UNSIGNED"):
|
||||||
|
if (self._description[col][1] == FieldType.C_SMALLINT_UNSIGNED):
|
||||||
|
return True
|
||||||
if (dataType.upper() == "INT"):
|
if (dataType.upper() == "INT"):
|
||||||
if (self._description[col][1] == FieldType.C_INT):
|
if (self._description[col][1] == FieldType.C_INT):
|
||||||
return True
|
return True
|
||||||
|
if (dataType.upper() == "INT UNSIGNED"):
|
||||||
|
if (self._description[col][1] == FieldType.C_INT_UNSIGNED):
|
||||||
|
return True
|
||||||
if (dataType.upper() == "BIGINT"):
|
if (dataType.upper() == "BIGINT"):
|
||||||
if (self._description[col][1] == FieldType.C_INT):
|
if (self._description[col][1] == FieldType.C_BIGINT):
|
||||||
|
return True
|
||||||
|
if (dataType.upper() == "BIGINT UNSIGNED"):
|
||||||
|
if (self._description[col][1] == FieldType.C_BIGINT_UNSIGNED):
|
||||||
return True
|
return True
|
||||||
if (dataType.upper() == "FLOAT"):
|
if (dataType.upper() == "FLOAT"):
|
||||||
if (self._description[col][1] == FieldType.C_FLOAT):
|
if (self._description[col][1] == FieldType.C_FLOAT):
|
||||||
|
@ -201,10 +217,13 @@ class TDengineCursor(object):
|
||||||
buffer = [[] for i in range(len(self._fields))]
|
buffer = [[] for i in range(len(self._fields))]
|
||||||
self._rowcount = 0
|
self._rowcount = 0
|
||||||
while True:
|
while True:
|
||||||
block, num_of_fields = CTaosInterface.fetchRow(self._result, self._fields)
|
block, num_of_fields = CTaosInterface.fetchRow(
|
||||||
|
self._result, self._fields)
|
||||||
errno = CTaosInterface.libtaos.taos_errno(self._result)
|
errno = CTaosInterface.libtaos.taos_errno(self._result)
|
||||||
if errno != 0:
|
if errno != 0:
|
||||||
raise ProgrammingError(CTaosInterface.errStr(self._result), errno)
|
raise ProgrammingError(
|
||||||
|
CTaosInterface.errStr(
|
||||||
|
self._result), errno)
|
||||||
if num_of_fields == 0:
|
if num_of_fields == 0:
|
||||||
break
|
break
|
||||||
self._rowcount += num_of_fields
|
self._rowcount += num_of_fields
|
||||||
|
@ -219,15 +238,20 @@ class TDengineCursor(object):
|
||||||
buffer = [[] for i in range(len(self._fields))]
|
buffer = [[] for i in range(len(self._fields))]
|
||||||
self._rowcount = 0
|
self._rowcount = 0
|
||||||
while True:
|
while True:
|
||||||
block, num_of_fields = CTaosInterface.fetchBlock(self._result, self._fields)
|
block, num_of_fields = CTaosInterface.fetchBlock(
|
||||||
|
self._result, self._fields)
|
||||||
errno = CTaosInterface.libtaos.taos_errno(self._result)
|
errno = CTaosInterface.libtaos.taos_errno(self._result)
|
||||||
if errno != 0:
|
if errno != 0:
|
||||||
raise ProgrammingError(CTaosInterface.errStr(self._result), errno)
|
raise ProgrammingError(
|
||||||
if num_of_fields == 0: break
|
CTaosInterface.errStr(
|
||||||
|
self._result), errno)
|
||||||
|
if num_of_fields == 0:
|
||||||
|
break
|
||||||
self._rowcount += num_of_fields
|
self._rowcount += num_of_fields
|
||||||
for i in range(len(self._fields)):
|
for i in range(len(self._fields)):
|
||||||
buffer[i].extend(block[i])
|
buffer[i].extend(block[i])
|
||||||
return list(map(tuple, zip(*buffer)))
|
return list(map(tuple, zip(*buffer)))
|
||||||
|
|
||||||
def nextset(self):
|
def nextset(self):
|
||||||
"""
|
"""
|
||||||
"""
|
"""
|
||||||
|
@ -259,8 +283,8 @@ class TDengineCursor(object):
|
||||||
# if threading.get_ident() != self._threadId:
|
# if threading.get_ident() != self._threadId:
|
||||||
# info = "Cursor handleresult:Thread ID not match,creater:"+str(self._threadId)+" caller:"+str(threading.get_ident())
|
# info = "Cursor handleresult:Thread ID not match,creater:"+str(self._threadId)+" caller:"+str(threading.get_ident())
|
||||||
# raise OperationalError(info)
|
# raise OperationalError(info)
|
||||||
# print(info)
|
# print(info)
|
||||||
# return None
|
# return None
|
||||||
|
|
||||||
self._description = []
|
self._description = []
|
||||||
for ele in self._fields:
|
for ele in self._fields:
|
||||||
|
@ -268,4 +292,3 @@ class TDengineCursor(object):
|
||||||
(ele['name'], ele['type'], None, None, None, None, False))
|
(ele['name'], ele['type'], None, None, None, None, False))
|
||||||
|
|
||||||
return self._result
|
return self._result
|
||||||
|
|
||||||
|
|
|
@ -4,6 +4,7 @@
|
||||||
import time
|
import time
|
||||||
import datetime
|
import datetime
|
||||||
|
|
||||||
|
|
||||||
class DBAPITypeObject(object):
|
class DBAPITypeObject(object):
|
||||||
def __init__(self, *values):
|
def __init__(self, *values):
|
||||||
self.values = values
|
self.values = values
|
||||||
|
@ -16,23 +17,28 @@ class DBAPITypeObject(object):
|
||||||
else:
|
else:
|
||||||
return -1
|
return -1
|
||||||
|
|
||||||
|
|
||||||
Date = datetime.date
|
Date = datetime.date
|
||||||
Time = datetime.time
|
Time = datetime.time
|
||||||
Timestamp = datetime.datetime
|
Timestamp = datetime.datetime
|
||||||
|
|
||||||
|
|
||||||
def DataFromTicks(ticks):
|
def DataFromTicks(ticks):
|
||||||
return Date(*time.localtime(ticks)[:3])
|
return Date(*time.localtime(ticks)[:3])
|
||||||
|
|
||||||
|
|
||||||
def TimeFromTicks(ticks):
|
def TimeFromTicks(ticks):
|
||||||
return Time(*time.localtime(ticks)[3:6])
|
return Time(*time.localtime(ticks)[3:6])
|
||||||
|
|
||||||
|
|
||||||
def TimestampFromTicks(ticks):
|
def TimestampFromTicks(ticks):
|
||||||
return Timestamp(*time.localtime(ticks)[:6])
|
return Timestamp(*time.localtime(ticks)[:6])
|
||||||
|
|
||||||
|
|
||||||
Binary = bytes
|
Binary = bytes
|
||||||
|
|
||||||
# STRING = DBAPITypeObject(*constants.FieldType.get_string_types())
|
# STRING = DBAPITypeObject(*constants.FieldType.get_string_types())
|
||||||
# BINARY = DBAPITypeObject(*constants.FieldType.get_binary_types())
|
# BINARY = DBAPITypeObject(*constants.FieldType.get_binary_types())
|
||||||
# NUMBER = BAPITypeObject(*constants.FieldType.get_number_types())
|
# NUMBER = BAPITypeObject(*constants.FieldType.get_number_types())
|
||||||
# DATETIME = DBAPITypeObject(*constants.FieldType.get_timestamp_types())
|
# DATETIME = DBAPITypeObject(*constants.FieldType.get_timestamp_types())
|
||||||
# ROWID = DBAPITypeObject()
|
# ROWID = DBAPITypeObject()
|
||||||
|
|
|
@ -1,35 +1,41 @@
|
||||||
"""Python exceptions
|
"""Python exceptions
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
|
||||||
class Error(Exception):
|
class Error(Exception):
|
||||||
def __init__(self, msg=None, errno=None):
|
def __init__(self, msg=None, errno=None):
|
||||||
self.msg = msg
|
self.msg = msg
|
||||||
self._full_msg = self.msg
|
self._full_msg = self.msg
|
||||||
self.errno = errno
|
self.errno = errno
|
||||||
|
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
return self._full_msg
|
return self._full_msg
|
||||||
|
|
||||||
|
|
||||||
class Warning(Exception):
|
class Warning(Exception):
|
||||||
"""Exception raised for important warnings like data truncations while inserting.
|
"""Exception raised for important warnings like data truncations while inserting.
|
||||||
"""
|
"""
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
|
||||||
class InterfaceError(Error):
|
class InterfaceError(Error):
|
||||||
"""Exception raised for errors that are related to the database interface rather than the database itself.
|
"""Exception raised for errors that are related to the database interface rather than the database itself.
|
||||||
"""
|
"""
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
|
||||||
class DatabaseError(Error):
|
class DatabaseError(Error):
|
||||||
"""Exception raised for errors that are related to the database.
|
"""Exception raised for errors that are related to the database.
|
||||||
"""
|
"""
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
|
||||||
class DataError(DatabaseError):
|
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.
|
"""Exception raised for errors that are due to problems with the processed data like division by zero, numeric value out of range.
|
||||||
"""
|
"""
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
|
||||||
class OperationalError(DatabaseError):
|
class OperationalError(DatabaseError):
|
||||||
"""Exception raised for errors that are related to the database's operation and not necessarily under the control of the programmer
|
"""Exception raised for errors that are related to the database's operation and not necessarily under the control of the programmer
|
||||||
"""
|
"""
|
||||||
|
@ -41,17 +47,20 @@ class IntegrityError(DatabaseError):
|
||||||
"""
|
"""
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
|
||||||
class InternalError(DatabaseError):
|
class InternalError(DatabaseError):
|
||||||
"""Exception raised when the database encounters an internal error.
|
"""Exception raised when the database encounters an internal error.
|
||||||
"""
|
"""
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
|
||||||
class ProgrammingError(DatabaseError):
|
class ProgrammingError(DatabaseError):
|
||||||
"""Exception raised for programming errors.
|
"""Exception raised for programming errors.
|
||||||
"""
|
"""
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
|
||||||
class NotSupportedError(DatabaseError):
|
class NotSupportedError(DatabaseError):
|
||||||
"""Exception raised in case a method or database API was used which is not supported by the database,.
|
"""Exception raised in case a method or database API was used which is not supported by the database,.
|
||||||
"""
|
"""
|
||||||
pass
|
pass
|
||||||
|
|
|
@ -1,32 +1,33 @@
|
||||||
from .cinterface import CTaosInterface
|
from .cinterface import CTaosInterface
|
||||||
from .error import *
|
from .error import *
|
||||||
|
|
||||||
|
|
||||||
class TDengineSubscription(object):
|
class TDengineSubscription(object):
|
||||||
"""TDengine subscription object
|
"""TDengine subscription object
|
||||||
"""
|
"""
|
||||||
|
|
||||||
def __init__(self, sub):
|
def __init__(self, sub):
|
||||||
self._sub = sub
|
self._sub = sub
|
||||||
|
|
||||||
|
|
||||||
def consume(self):
|
def consume(self):
|
||||||
"""Consume rows of a subscription
|
"""Consume rows of a subscription
|
||||||
"""
|
"""
|
||||||
if self._sub is None:
|
if self._sub is None:
|
||||||
raise OperationalError("Invalid use of consume")
|
raise OperationalError("Invalid use of consume")
|
||||||
|
|
||||||
result, fields = CTaosInterface.consume(self._sub)
|
result, fields = CTaosInterface.consume(self._sub)
|
||||||
buffer = [[] for i in range(len(fields))]
|
buffer = [[] for i in range(len(fields))]
|
||||||
while True:
|
while True:
|
||||||
block, num_of_fields = CTaosInterface.fetchBlock(result, fields)
|
block, num_of_fields = CTaosInterface.fetchBlock(result, fields)
|
||||||
if num_of_fields == 0: break
|
if num_of_fields == 0:
|
||||||
|
break
|
||||||
for i in range(len(fields)):
|
for i in range(len(fields)):
|
||||||
buffer[i].extend(block[i])
|
buffer[i].extend(block[i])
|
||||||
|
|
||||||
self.fields = fields
|
self.fields = fields
|
||||||
return list(map(tuple, zip(*buffer)))
|
return list(map(tuple, zip(*buffer)))
|
||||||
|
|
||||||
|
def close(self, keepProgress=True):
|
||||||
def close(self, keepProgress = True):
|
|
||||||
"""Close the Subscription.
|
"""Close the Subscription.
|
||||||
"""
|
"""
|
||||||
if self._sub is None:
|
if self._sub is None:
|
||||||
|
@ -38,15 +39,19 @@ class TDengineSubscription(object):
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
from .connection import TDengineConnection
|
from .connection import TDengineConnection
|
||||||
conn = TDengineConnection(host="127.0.0.1", user="root", password="taosdata", database="test")
|
conn = TDengineConnection(
|
||||||
|
host="127.0.0.1",
|
||||||
|
user="root",
|
||||||
|
password="taosdata",
|
||||||
|
database="test")
|
||||||
|
|
||||||
# Generate a cursor object to run SQL commands
|
# Generate a cursor object to run SQL commands
|
||||||
sub = conn.subscribe(True, "test", "select * from meters;", 1000)
|
sub = conn.subscribe(True, "test", "select * from meters;", 1000)
|
||||||
|
|
||||||
for i in range(0,10):
|
for i in range(0, 10):
|
||||||
data = sub.consume()
|
data = sub.consume()
|
||||||
for d in data:
|
for d in data:
|
||||||
print(d)
|
print(d)
|
||||||
|
|
||||||
sub.close()
|
sub.close()
|
||||||
conn.close()
|
conn.close()
|
||||||
|
|
|
@ -3,7 +3,6 @@ from .connection import TDengineConnection
|
||||||
from .cursor import TDengineCursor
|
from .cursor import TDengineCursor
|
||||||
|
|
||||||
# Globals
|
# Globals
|
||||||
apilevel = '2.0.3'
|
|
||||||
threadsafety = 0
|
threadsafety = 0
|
||||||
paramstyle = 'pyformat'
|
paramstyle = 'pyformat'
|
||||||
|
|
||||||
|
@ -21,4 +20,4 @@ def connect(*args, **kwargs):
|
||||||
|
|
||||||
@rtype: TDengineConnector
|
@rtype: TDengineConnector
|
||||||
"""
|
"""
|
||||||
return TDengineConnection(*args, **kwargs)
|
return TDengineConnection(*args, **kwargs)
|
||||||
|
|
|
@ -3,7 +3,6 @@ from .connection import TDengineConnection
|
||||||
from .cursor import TDengineCursor
|
from .cursor import TDengineCursor
|
||||||
|
|
||||||
# Globals
|
# Globals
|
||||||
apilevel = '2.0.3'
|
|
||||||
threadsafety = 0
|
threadsafety = 0
|
||||||
paramstyle = 'pyformat'
|
paramstyle = 'pyformat'
|
||||||
|
|
||||||
|
@ -21,4 +20,4 @@ def connect(*args, **kwargs):
|
||||||
|
|
||||||
@rtype: TDengineConnector
|
@rtype: TDengineConnector
|
||||||
"""
|
"""
|
||||||
return TDengineConnection(*args, **kwargs)
|
return TDengineConnection(*args, **kwargs)
|
||||||
|
|
|
@ -0,0 +1,56 @@
|
||||||
|
###################################################################
|
||||||
|
# Copyright (c) 2016 by TAOS Technologies, Inc.
|
||||||
|
# All rights reserved.
|
||||||
|
#
|
||||||
|
# This file is proprietary and confidential to TAOS Technologies.
|
||||||
|
# No part of this file may be reproduced, stored, transmitted,
|
||||||
|
# disclosed or used in any form or by any means other than as
|
||||||
|
# expressly provided by the written permission from Jianhui Tao
|
||||||
|
#
|
||||||
|
###################################################################
|
||||||
|
|
||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
|
||||||
|
import sys
|
||||||
|
from util.log import *
|
||||||
|
from util.cases import *
|
||||||
|
from util.sql import *
|
||||||
|
|
||||||
|
|
||||||
|
class TDTestCase:
|
||||||
|
def init(self, conn, logSql):
|
||||||
|
tdLog.debug("start to execute %s" % __file__)
|
||||||
|
tdSql.init(conn.cursor(), logSql)
|
||||||
|
|
||||||
|
def run(self):
|
||||||
|
tdSql.prepare()
|
||||||
|
|
||||||
|
ret = tdSql.execute(
|
||||||
|
'create table tb (ts timestamp, speed int unsigned)')
|
||||||
|
|
||||||
|
insertRows = 10
|
||||||
|
tdLog.info("insert %d rows" % (insertRows))
|
||||||
|
for i in range(0, insertRows):
|
||||||
|
ret = tdSql.execute(
|
||||||
|
'insert into tb values (now + %dm, %d)' %
|
||||||
|
(i, i))
|
||||||
|
|
||||||
|
tdLog.info("insert earlier data")
|
||||||
|
tdSql.execute('insert into tb values (now - 5m , 10)')
|
||||||
|
tdSql.execute('insert into tb values (now - 6m , 10)')
|
||||||
|
tdSql.execute('insert into tb values (now - 7m , 10)')
|
||||||
|
tdSql.execute('insert into tb values (now - 8m , 4294967294)')
|
||||||
|
|
||||||
|
tdSql.error('insert into tb values (now - 9m, -1)')
|
||||||
|
tdSql.error('insert into tb values (now - 9m, 4294967295)')
|
||||||
|
|
||||||
|
tdSql.query("select * from tb")
|
||||||
|
tdSql.checkRows(insertRows + 4)
|
||||||
|
|
||||||
|
def stop(self):
|
||||||
|
tdSql.close()
|
||||||
|
tdLog.success("%s successfully executed" % __file__)
|
||||||
|
|
||||||
|
|
||||||
|
tdCases.addWindows(__file__, TDTestCase())
|
||||||
|
tdCases.addLinux(__file__, TDTestCase())
|
Loading…
Reference in New Issue