cinterface.py 20.0 KB
Newer Older
H
hzcheng 已提交
1 2 3 4 5
import ctypes
from .constants import FieldType
from .error import *
import math
import datetime
6
import platform
H
hzcheng 已提交
7

8

H
hzcheng 已提交
9
def _convert_millisecond_to_datetime(milli):
10 11
    return datetime.datetime.fromtimestamp(milli / 1000.0)

H
hzcheng 已提交
12 13

def _convert_microsecond_to_datetime(micro):
14 15
    return datetime.datetime.fromtimestamp(micro / 1000000.0)

H
hzcheng 已提交
16

H
Haojun Liao 已提交
17 18 19 20 21
def _convert_nanosecond_to_datetime(nanosec):
    return nanosec


def _crow_timestamp_to_python(data, num_of_rows, nbytes=None, precision=FieldType.C_TIMESTAMP_UNKNOWN):
H
hzcheng 已提交
22 23
    """Function to convert C bool row to python row
    """
weixin_48148422's avatar
weixin_48148422 已提交
24
    _timestamp_converter = _convert_millisecond_to_datetime
H
Haojun Liao 已提交
25 26 27
    if precision == FieldType.C_TIMESTAMP_MILLI:
        _timestamp_converter = _convert_millisecond_to_datetime
    elif precision == FieldType.C_TIMESTAMP_MICRO:
weixin_48148422's avatar
weixin_48148422 已提交
28
        _timestamp_converter = _convert_microsecond_to_datetime
H
Haojun Liao 已提交
29 30 31 32
    elif precision == FieldType.C_TIMESTAMP_NANO:
        _timestamp_converter = _convert_nanosecond_to_datetime
    else:
        raise DatabaseError("Unknown precision returned from database")
H
hzcheng 已提交
33

34 35 36 37 38
    return [
        None if ele == FieldType.C_BIGINT_NULL else _timestamp_converter(ele) for ele in ctypes.cast(
            data, ctypes.POINTER(
                ctypes.c_int64))[
            :abs(num_of_rows)]]
39

H
hzcheng 已提交
40

H
Haojun Liao 已提交
41
def _crow_bool_to_python(data, num_of_rows, nbytes=None, precision=FieldType.C_TIMESTAMP_UNKNOWN):
H
hzcheng 已提交
42 43
    """Function to convert C bool row to python row
    """
44 45 46 47 48
    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)]]
49

H
hzcheng 已提交
50

H
Haojun Liao 已提交
51
def _crow_tinyint_to_python(data, num_of_rows, nbytes=None, precision=FieldType.C_TIMESTAMP_UNKNOWN):
H
hzcheng 已提交
52 53
    """Function to convert C tinyint row to python row
    """
54 55
    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)]]
56

57

58 59 60 61
def _crow_tinyint_unsigned_to_python(
        data,
        num_of_rows,
        nbytes=None,
H
Haojun Liao 已提交
62
        precision=FieldType.C_TIMESTAMP_UNKNOWN):
63 64
    """Function to convert C tinyint row to python row
    """
65 66 67 68 69
    return [
        None if ele == FieldType.C_TINYINT_UNSIGNED_NULL else ele for ele in ctypes.cast(
            data, ctypes.POINTER(
                ctypes.c_ubyte))[
            :abs(num_of_rows)]]
70

71

H
Haojun Liao 已提交
72
def _crow_smallint_to_python(data, num_of_rows, nbytes=None, precision=FieldType.C_TIMESTAMP_UNKNOWN):
H
hzcheng 已提交
73 74
    """Function to convert C smallint row to python row
    """
75 76 77 78 79
    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)]]
H
hzcheng 已提交
80

81 82

def _crow_smallint_unsigned_to_python(
H
Haojun Liao 已提交
83
        data, num_of_rows, nbytes=None, precision=FieldType.C_TIMESTAMP_UNKNOWN):
84 85
    """Function to convert C smallint row to python row
    """
86 87 88 89 90
    return [
        None if ele == FieldType.C_SMALLINT_UNSIGNED_NULL else ele for ele in ctypes.cast(
            data, ctypes.POINTER(
                ctypes.c_ushort))[
            :abs(num_of_rows)]]
91

92

H
Haojun Liao 已提交
93
def _crow_int_to_python(data, num_of_rows, nbytes=None, precision=FieldType.C_TIMESTAMP_UNKNOWN):
H
hzcheng 已提交
94 95
    """Function to convert C int row to python row
    """
96 97
    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)]]
98

H
hzcheng 已提交
99

H
Haojun Liao 已提交
100
def _crow_int_unsigned_to_python(data, num_of_rows, nbytes=None, precision=FieldType.C_TIMESTAMP_UNKNOWN):
101 102
    """Function to convert C int row to python row
    """
103 104 105 106 107
    return [
        None if ele == FieldType.C_INT_UNSIGNED_NULL else ele for ele in ctypes.cast(
            data, ctypes.POINTER(
                ctypes.c_uint))[
            :abs(num_of_rows)]]
108

109

H
Haojun Liao 已提交
110
def _crow_bigint_to_python(data, num_of_rows, nbytes=None, precision=FieldType.C_TIMESTAMP_UNKNOWN):
H
hzcheng 已提交
111 112
    """Function to convert C bigint row to python row
    """
113 114
    return [None if ele == FieldType.C_BIGINT_NULL else ele for ele in ctypes.cast(
        data, ctypes.POINTER(ctypes.c_int64))[:abs(num_of_rows)]]
115

H
hzcheng 已提交
116

117 118 119 120
def _crow_bigint_unsigned_to_python(
        data,
        num_of_rows,
        nbytes=None,
H
Haojun Liao 已提交
121
        precision=FieldType.C_TIMESTAMP_UNKNOWN):
122 123
    """Function to convert C bigint row to python row
    """
124 125 126 127 128
    return [
        None if ele == FieldType.C_BIGINT_UNSIGNED_NULL else ele for ele in ctypes.cast(
            data, ctypes.POINTER(
                ctypes.c_uint64))[
            :abs(num_of_rows)]]
129

130

H
Haojun Liao 已提交
131
def _crow_float_to_python(data, num_of_rows, nbytes=None, precision=FieldType.C_TIMESTAMP_UNKNOWN):
H
hzcheng 已提交
132 133
    """Function to convert C float row to python row
    """
134 135
    return [None if math.isnan(ele) else ele for ele in ctypes.cast(
        data, ctypes.POINTER(ctypes.c_float))[:abs(num_of_rows)]]
136

H
hzcheng 已提交
137

H
Haojun Liao 已提交
138
def _crow_double_to_python(data, num_of_rows, nbytes=None, precision=FieldType.C_TIMESTAMP_UNKNOWN):
H
hzcheng 已提交
139 140
    """Function to convert C double row to python row
    """
141 142
    return [None if math.isnan(ele) else ele for ele in ctypes.cast(
        data, ctypes.POINTER(ctypes.c_double))[:abs(num_of_rows)]]
143

H
hzcheng 已提交
144

H
Haojun Liao 已提交
145
def _crow_binary_to_python(data, num_of_rows, nbytes=None, precision=FieldType.C_TIMESTAMP_UNKNOWN):
H
hzcheng 已提交
146 147
    """Function to convert C binary row to python row
    """
148
    assert(nbytes is not None)
149 150
    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)]]
151

H
hzcheng 已提交
152

H
Haojun Liao 已提交
153
def _crow_nchar_to_python(data, num_of_rows, nbytes=None, precision=FieldType.C_TIMESTAMP_UNKNOWN):
H
hzcheng 已提交
154 155 156
    """Function to convert C nchar row to python row
    """
    assert(nbytes is not None)
157
    res = []
H
hzcheng 已提交
158 159 160
    for i in range(abs(num_of_rows)):
        try:
            if num_of_rows >= 0:
161
                tmpstr = ctypes.c_char_p(data)
162
                res.append(tmpstr.value.decode())
H
hzcheng 已提交
163
            else:
164 165
                res.append((ctypes.cast(data + nbytes * i,
                                        ctypes.POINTER(ctypes.c_wchar * (nbytes // 4))))[0].value)
H
hzcheng 已提交
166 167 168
        except ValueError:
            res.append(None)

169 170
    return res

171

H
Haojun Liao 已提交
172
def _crow_binary_to_python_block(data, num_of_rows, nbytes=None, precision=FieldType.C_TIMESTAMP_UNKNOWN):
173 174
    """Function to convert C binary row to python row
    """
175
    assert(nbytes is not None)
176
    res = []
177 178 179 180 181 182 183 184 185 186 187
    for i in range(abs(num_of_rows)):
        try:
            rbyte = ctypes.cast(
                data + nbytes * i,
                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:
            res.append(None)
188 189
    return res

190

H
Haojun Liao 已提交
191
def _crow_nchar_to_python_block(data, num_of_rows, nbytes=None, precision=FieldType.C_TIMESTAMP_UNKNOWN):
192 193 194
    """Function to convert C nchar row to python row
    """
    assert(nbytes is not None)
195
    res = []
196 197 198 199 200 201
    for i in range(abs(num_of_rows)):
        try:
            tmpstr = ctypes.c_char_p(data + nbytes * i + 2)
            res.append(tmpstr.value.decode())
        except ValueError:
            res.append(None)
H
hzcheng 已提交
202 203
    return res

204

H
hzcheng 已提交
205 206
_CONVERT_FUNC = {
    FieldType.C_BOOL: _crow_bool_to_python,
207 208 209 210 211 212
    FieldType.C_TINYINT: _crow_tinyint_to_python,
    FieldType.C_SMALLINT: _crow_smallint_to_python,
    FieldType.C_INT: _crow_int_to_python,
    FieldType.C_BIGINT: _crow_bigint_to_python,
    FieldType.C_FLOAT: _crow_float_to_python,
    FieldType.C_DOUBLE: _crow_double_to_python,
H
hzcheng 已提交
213
    FieldType.C_BINARY: _crow_binary_to_python,
214 215 216 217 218 219
    FieldType.C_TIMESTAMP: _crow_timestamp_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
H
hzcheng 已提交
220 221
}

222 223
_CONVERT_FUNC_BLOCK = {
    FieldType.C_BOOL: _crow_bool_to_python,
224 225 226 227 228 229
    FieldType.C_TINYINT: _crow_tinyint_to_python,
    FieldType.C_SMALLINT: _crow_smallint_to_python,
    FieldType.C_INT: _crow_int_to_python,
    FieldType.C_BIGINT: _crow_bigint_to_python,
    FieldType.C_FLOAT: _crow_float_to_python,
    FieldType.C_DOUBLE: _crow_double_to_python,
230
    FieldType.C_BINARY: _crow_binary_to_python_block,
231 232 233 234 235 236
    FieldType.C_TIMESTAMP: _crow_timestamp_to_python,
    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
237 238
}

H
hzcheng 已提交
239
# Corresponding TAOS_FIELD structure in C
240 241


H
hzcheng 已提交
242
class TaosField(ctypes.Structure):
B
Bomin Zhang 已提交
243 244 245
    _fields_ = [('name', ctypes.c_char * 65),
                ('type', ctypes.c_char),
                ('bytes', ctypes.c_short)]
H
hzcheng 已提交
246 247

# C interface class
248 249


250 251 252 253 254
def _load_taos_linux():
    return ctypes.CDLL('libtaos.so')


def _load_taos_darwin():
H
Haojun Liao 已提交
255
    return ctypes.CDLL('libtaos.dylib')
256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273


def _load_taos_windows():
    return ctypes.windll.LoadLibrary('taos')


def _load_taos():
    load_func = {
        'Linux': _load_taos_linux,
        'Darwin': _load_taos_darwin,
        'Windows': _load_taos_windows,
    }
    try:
        return load_func[platform.system()]()
    except:
        sys.exit('unsupported platform to TDengine connector')


H
hzcheng 已提交
274 275
class CTaosInterface(object):

276
    libtaos = _load_taos()
H
hzcheng 已提交
277 278 279 280

    libtaos.taos_fetch_fields.restype = ctypes.POINTER(TaosField)
    libtaos.taos_init.restype = None
    libtaos.taos_connect.restype = ctypes.c_void_p
281
    # libtaos.taos_use_result.restype = ctypes.c_void_p
H
hzcheng 已提交
282 283
    libtaos.taos_fetch_row.restype = ctypes.POINTER(ctypes.c_void_p)
    libtaos.taos_errstr.restype = ctypes.c_char_p
weixin_48148422's avatar
weixin_48148422 已提交
284 285
    libtaos.taos_subscribe.restype = ctypes.c_void_p
    libtaos.taos_consume.restype = ctypes.c_void_p
286
    libtaos.taos_fetch_lengths.restype = ctypes.c_void_p
287
    libtaos.taos_free_result.restype = None
T
Tao Liu 已提交
288
    libtaos.taos_errno.restype = ctypes.c_int
T
Tao Liu 已提交
289
    libtaos.taos_query.restype = ctypes.POINTER(ctypes.c_void_p)
H
hzcheng 已提交
290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309

    def __init__(self, config=None):
        '''
        Function to initialize the class
        @host     : str, hostname to connect
        @user     : str, username to connect to server
        @password : str, password to connect to server
        @db       : str, default db to use when log in
        @config   : str, config directory

        @rtype    : None
        '''
        if config is None:
            self._config = ctypes.c_char_p(None)
        else:
            try:
                self._config = ctypes.c_char_p(config.encode('utf-8'))
            except AttributeError:
                raise AttributeError("config is expected as a str")

310
        if config is not None:
H
hzcheng 已提交
311 312 313 314 315 316 317 318 319 320
            CTaosInterface.libtaos.taos_options(3, self._config)

        CTaosInterface.libtaos.taos_init()

    @property
    def config(self):
        """ Get current config
        """
        return self._config

321 322 323 324 325 326 327
    def connect(
            self,
            host=None,
            user="root",
            password="taosdata",
            db=None,
            port=0):
H
hzcheng 已提交
328 329 330 331 332 333 334 335
        '''
        Function to connect to server

        @rtype: c_void_p, TDengine handle
        '''
        # host
        try:
            _host = ctypes.c_char_p(host.encode(
336
                "utf-8")) if host is not None else ctypes.c_char_p(None)
H
hzcheng 已提交
337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354
        except AttributeError:
            raise AttributeError("host is expected as a str")

        # user
        try:
            _user = ctypes.c_char_p(user.encode("utf-8"))
        except AttributeError:
            raise AttributeError("user is expected as a str")

        # password
        try:
            _password = ctypes.c_char_p(password.encode("utf-8"))
        except AttributeError:
            raise AttributeError("password is expected as a str")

        # db
        try:
            _db = ctypes.c_char_p(
355
                db.encode("utf-8")) if db is not None else ctypes.c_char_p(None)
H
hzcheng 已提交
356 357 358 359 360 361 362 363 364 365 366 367
        except AttributeError:
            raise AttributeError("db is expected as a str")

        # port
        try:
            _port = ctypes.c_int(port)
        except TypeError:
            raise TypeError("port is expected as an int")

        connection = ctypes.c_void_p(CTaosInterface.libtaos.taos_connect(
            _host, _user, _password, _db, _port))

368
        if connection.value is None:
H
hzcheng 已提交
369
            print('connect to TDengine failed')
370
            raise ConnectionError("connect to TDengine failed")
H
hzcheng 已提交
371
            # sys.exit(1)
372
        # else:
373
        #    print('connect to TDengine success')
H
hzcheng 已提交
374 375 376 377 378 379 380 381

        return connection

    @staticmethod
    def close(connection):
        '''Close the TDengine handle
        '''
        CTaosInterface.libtaos.taos_close(connection)
382
        # print('connection is closed')
H
hzcheng 已提交
383 384 385 386 387 388 389 390 391 392

    @staticmethod
    def query(connection, sql):
        '''Run SQL

        @sql: str, sql string to run

        @rtype: 0 on success and -1 on failure
        '''
        try:
393 394
            return CTaosInterface.libtaos.taos_query(
                connection, ctypes.c_char_p(sql.encode('utf-8')))
H
hzcheng 已提交
395 396
        except AttributeError:
            raise AttributeError("sql is expected as a string")
H
Hongze Cheng 已提交
397 398
        # finally:
        #     CTaosInterface.libtaos.close(connection)
399

H
hzcheng 已提交
400
    @staticmethod
401
    def affectedRows(result):
H
hzcheng 已提交
402 403
        """The affected rows after runing query
        """
404
        return CTaosInterface.libtaos.taos_affected_rows(result)
H
hzcheng 已提交
405

weixin_48148422's avatar
weixin_48148422 已提交
406 407 408
    @staticmethod
    def subscribe(connection, restart, topic, sql, interval):
        """Create a subscription
409
         @restart boolean,
weixin_48148422's avatar
weixin_48148422 已提交
410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440
         @sql string, sql statement for data query, must be a 'select' statement.
         @topic string, name of this subscription
        """
        return ctypes.c_void_p(CTaosInterface.libtaos.taos_subscribe(
            connection,
            1 if restart else 0,
            ctypes.c_char_p(topic.encode('utf-8')),
            ctypes.c_char_p(sql.encode('utf-8')),
            None,
            None,
            interval))

    @staticmethod
    def consume(sub):
        """Consume data of a subscription
        """
        result = ctypes.c_void_p(CTaosInterface.libtaos.taos_consume(sub))
        fields = []
        pfields = CTaosInterface.fetchFields(result)
        for i in range(CTaosInterface.libtaos.taos_num_fields(result)):
            fields.append({'name': pfields[i].name.decode('utf-8'),
                           'bytes': pfields[i].bytes,
                           'type': ord(pfields[i].type)})
        return result, fields

    @staticmethod
    def unsubscribe(sub, keepProgress):
        """Cancel a subscription
        """
        CTaosInterface.libtaos.taos_unsubscribe(sub, 1 if keepProgress else 0)

H
hzcheng 已提交
441
    @staticmethod
442
    def useResult(result):
H
hzcheng 已提交
443 444 445 446
        '''Use result after calling self.query
        '''
        fields = []
        pfields = CTaosInterface.fetchFields(result)
447
        for i in range(CTaosInterface.fieldsCount(result)):
H
hzcheng 已提交
448 449 450 451
            fields.append({'name': pfields[i].name.decode('utf-8'),
                           'bytes': pfields[i].bytes,
                           'type': ord(pfields[i].type)})

452
        return fields
H
hzcheng 已提交
453 454 455

    @staticmethod
    def fetchBlock(result, fields):
456 457 458 459 460
        pblock = ctypes.c_void_p(0)
        num_of_rows = CTaosInterface.libtaos.taos_fetch_block(
            result, ctypes.byref(pblock))
        if num_of_rows == 0:
            return None, 0
H
Haojun Liao 已提交
461
        precision = CTaosInterface.libtaos.taos_result_precision(result)
462 463
        blocks = [None] * len(fields)
        fieldL = CTaosInterface.libtaos.taos_fetch_lengths(result)
464 465 466 467 468
        fieldLen = [
            ele for ele in ctypes.cast(
                fieldL, ctypes.POINTER(
                    ctypes.c_int))[
                :len(fields)]]
469 470 471 472
        for i in range(len(fields)):
            data = ctypes.cast(pblock, ctypes.POINTER(ctypes.c_void_p))[i]
            if fields[i]['type'] not in _CONVERT_FUNC_BLOCK:
                raise DatabaseError("Invalid data type returned from database")
473
            blocks[i] = _CONVERT_FUNC_BLOCK[fields[i]['type']](
H
Haojun Liao 已提交
474
                data, num_of_rows, fieldLen[i], precision)
475 476

        return blocks, abs(num_of_rows)
477

478 479
    @staticmethod
    def fetchRow(result, fields):
H
hzcheng 已提交
480
        pblock = ctypes.c_void_p(0)
481 482
        pblock = CTaosInterface.libtaos.taos_fetch_row(result)
        if pblock:
L
liuyq-617 已提交
483
            num_of_rows = 1
H
Haojun Liao 已提交
484
            precision = CTaosInterface.libtaos.taos_result_precision(result)
L
liuyq-617 已提交
485 486
            blocks = [None] * len(fields)
            fieldL = CTaosInterface.libtaos.taos_fetch_lengths(result)
487 488 489 490 491
            fieldLen = [
                ele for ele in ctypes.cast(
                    fieldL, ctypes.POINTER(
                        ctypes.c_int))[
                    :len(fields)]]
L
liuyq-617 已提交
492 493 494
            for i in range(len(fields)):
                data = ctypes.cast(pblock, ctypes.POINTER(ctypes.c_void_p))[i]
                if fields[i]['type'] not in _CONVERT_FUNC:
495 496
                    raise DatabaseError(
                        "Invalid data type returned from database")
L
liuyq-617 已提交
497 498 499
                if data is None:
                    blocks[i] = [None]
                else:
500
                    blocks[i] = _CONVERT_FUNC[fields[i]['type']](
H
Haojun Liao 已提交
501
                        data, num_of_rows, fieldLen[i], precision)
L
liuyq-617 已提交
502
        else:
H
hzcheng 已提交
503 504
            return None, 0
        return blocks, abs(num_of_rows)
505

H
hzcheng 已提交
506 507 508 509 510 511
    @staticmethod
    def freeResult(result):
        CTaosInterface.libtaos.taos_free_result(result)
        result.value = None

    @staticmethod
512 513
    def fieldsCount(result):
        return CTaosInterface.libtaos.taos_field_count(result)
H
hzcheng 已提交
514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547

    @staticmethod
    def fetchFields(result):
        return CTaosInterface.libtaos.taos_fetch_fields(result)

    # @staticmethod
    # def fetchRow(result, fields):
    #     l = []
    #     row = CTaosInterface.libtaos.taos_fetch_row(result)
    #     if not row:
    #         return None

    #     for i in range(len(fields)):
    #         l.append(CTaosInterface.getDataValue(
    #             row[i], fields[i]['type'], fields[i]['bytes']))

    #     return tuple(l)

    # @staticmethod
    # def getDataValue(data, dtype, byte):
    #     '''
    #     '''
    #     if not data:
    #         return None

    #     if (dtype == CTaosInterface.TSDB_DATA_TYPE_BOOL):
    #         return ctypes.cast(data,  ctypes.POINTER(ctypes.c_bool))[0]
    #     elif (dtype == CTaosInterface.TSDB_DATA_TYPE_TINYINT):
    #         return ctypes.cast(data,  ctypes.POINTER(ctypes.c_byte))[0]
    #     elif (dtype == CTaosInterface.TSDB_DATA_TYPE_SMALLINT):
    #         return ctypes.cast(data,  ctypes.POINTER(ctypes.c_short))[0]
    #     elif (dtype == CTaosInterface.TSDB_DATA_TYPE_INT):
    #         return ctypes.cast(data,  ctypes.POINTER(ctypes.c_int))[0]
    #     elif (dtype == CTaosInterface.TSDB_DATA_TYPE_BIGINT):
548
    #         return ctypes.cast(data,  ctypes.POINTER(ctypes.c_int64))[0]
H
hzcheng 已提交
549 550 551 552 553 554 555
    #     elif (dtype == CTaosInterface.TSDB_DATA_TYPE_FLOAT):
    #         return ctypes.cast(data,  ctypes.POINTER(ctypes.c_float))[0]
    #     elif (dtype == CTaosInterface.TSDB_DATA_TYPE_DOUBLE):
    #         return ctypes.cast(data,  ctypes.POINTER(ctypes.c_double))[0]
    #     elif (dtype == CTaosInterface.TSDB_DATA_TYPE_BINARY):
    #         return (ctypes.cast(data,  ctypes.POINTER(ctypes.c_char))[0:byte]).rstrip('\x00')
    #     elif (dtype == CTaosInterface.TSDB_DATA_TYPE_TIMESTAMP):
556
    #         return ctypes.cast(data,  ctypes.POINTER(ctypes.c_int64))[0]
H
hzcheng 已提交
557 558 559 560
    #     elif (dtype == CTaosInterface.TSDB_DATA_TYPE_NCHAR):
    #         return (ctypes.cast(data,  ctypes.c_char_p).value).rstrip('\x00')

    @staticmethod
561
    def errno(result):
H
hzcheng 已提交
562 563
        """Return the error number.
        """
564
        return CTaosInterface.libtaos.taos_errno(result)
H
hzcheng 已提交
565 566

    @staticmethod
567
    def errStr(result):
H
hzcheng 已提交
568 569
        """Return the error styring
        """
570
        return CTaosInterface.libtaos.taos_errstr(result).decode('utf-8')
weixin_48148422's avatar
weixin_48148422 已提交
571 572 573 574 575


if __name__ == '__main__':
    cinter = CTaosInterface()
    conn = cinter.connect()
576
    result = cinter.query(conn, 'show databases')
weixin_48148422's avatar
weixin_48148422 已提交
577

578
    print('Query Affected rows: {}'.format(cinter.affectedRows(result)))
weixin_48148422's avatar
weixin_48148422 已提交
579

580
    fields = CTaosInterface.useResult(result)
weixin_48148422's avatar
weixin_48148422 已提交
581

582
    data, num_of_rows = CTaosInterface.fetchBlock(result, fields)
weixin_48148422's avatar
weixin_48148422 已提交
583 584 585

    print(data)

T
Tao Liu 已提交
586
    cinter.freeResult(result)
587
    cinter.close(conn)