cinterface.py 19.2 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 17 18 19

def _crow_timestamp_to_python(data, num_of_rows, nbytes=None, micro=False):
    """Function to convert C bool row to python row
    """
weixin_48148422's avatar
weixin_48148422 已提交
20
    _timestamp_converter = _convert_millisecond_to_datetime
H
hzcheng 已提交
21
    if micro:
weixin_48148422's avatar
weixin_48148422 已提交
22
        _timestamp_converter = _convert_microsecond_to_datetime
H
hzcheng 已提交
23

24 25 26 27 28
    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)]]
29

H
hzcheng 已提交
30 31 32 33

def _crow_bool_to_python(data, num_of_rows, nbytes=None, micro=False):
    """Function to convert C bool row to python row
    """
34 35 36 37 38
    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)]]
39

H
hzcheng 已提交
40 41 42 43

def _crow_tinyint_to_python(data, num_of_rows, nbytes=None, micro=False):
    """Function to convert C tinyint row to python row
    """
44 45
    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)]]
46

47

48 49 50 51 52
def _crow_tinyint_unsigned_to_python(
        data,
        num_of_rows,
        nbytes=None,
        micro=False):
53 54
    """Function to convert C tinyint row to python row
    """
55 56 57 58 59
    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)]]
60

61

H
hzcheng 已提交
62 63 64
def _crow_smallint_to_python(data, num_of_rows, nbytes=None, micro=False):
    """Function to convert C smallint row to python row
    """
65 66 67 68 69
    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 已提交
70

71 72 73

def _crow_smallint_unsigned_to_python(
        data, num_of_rows, nbytes=None, micro=False):
74 75
    """Function to convert C smallint row to python row
    """
76 77 78 79 80
    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)]]
81

82

H
hzcheng 已提交
83 84 85
def _crow_int_to_python(data, num_of_rows, nbytes=None, micro=False):
    """Function to convert C int row to python row
    """
86 87
    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)]]
88

H
hzcheng 已提交
89

90 91 92
def _crow_int_unsigned_to_python(data, num_of_rows, nbytes=None, micro=False):
    """Function to convert C int row to python row
    """
93 94 95 96 97
    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)]]
98

99

H
hzcheng 已提交
100 101 102
def _crow_bigint_to_python(data, num_of_rows, nbytes=None, micro=False):
    """Function to convert C bigint row to python row
    """
103 104
    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)]]
105

H
hzcheng 已提交
106

107 108 109 110 111
def _crow_bigint_unsigned_to_python(
        data,
        num_of_rows,
        nbytes=None,
        micro=False):
112 113
    """Function to convert C bigint row to python row
    """
114 115 116 117 118
    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)]]
119

120

H
hzcheng 已提交
121 122 123
def _crow_float_to_python(data, num_of_rows, nbytes=None, micro=False):
    """Function to convert C float row to python row
    """
124 125
    return [None if math.isnan(ele) else ele for ele in ctypes.cast(
        data, ctypes.POINTER(ctypes.c_float))[:abs(num_of_rows)]]
126

H
hzcheng 已提交
127 128 129 130

def _crow_double_to_python(data, num_of_rows, nbytes=None, micro=False):
    """Function to convert C double row to python row
    """
131 132
    return [None if math.isnan(ele) else ele for ele in ctypes.cast(
        data, ctypes.POINTER(ctypes.c_double))[:abs(num_of_rows)]]
133

H
hzcheng 已提交
134 135 136 137

def _crow_binary_to_python(data, num_of_rows, nbytes=None, micro=False):
    """Function to convert C binary row to python row
    """
138
    assert(nbytes is not None)
139 140
    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)]]
141

H
hzcheng 已提交
142 143 144 145 146

def _crow_nchar_to_python(data, num_of_rows, nbytes=None, micro=False):
    """Function to convert C nchar row to python row
    """
    assert(nbytes is not None)
147
    res = []
H
hzcheng 已提交
148 149 150
    for i in range(abs(num_of_rows)):
        try:
            if num_of_rows >= 0:
151
                tmpstr = ctypes.c_char_p(data)
152
                res.append(tmpstr.value.decode())
H
hzcheng 已提交
153
            else:
154 155
                res.append((ctypes.cast(data + nbytes * i,
                                        ctypes.POINTER(ctypes.c_wchar * (nbytes // 4))))[0].value)
H
hzcheng 已提交
156 157 158
        except ValueError:
            res.append(None)

159 160
    return res

161 162 163 164

def _crow_binary_to_python_block(data, num_of_rows, nbytes=None, micro=False):
    """Function to convert C binary row to python row
    """
165
    assert(nbytes is not None)
166
    res = []
167 168 169 170 171 172 173 174 175 176 177
    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)
178 179
    return res

180

181 182 183 184
def _crow_nchar_to_python_block(data, num_of_rows, nbytes=None, micro=False):
    """Function to convert C nchar row to python row
    """
    assert(nbytes is not None)
185
    res = []
186 187 188 189 190 191
    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 已提交
192 193
    return res

194

H
hzcheng 已提交
195 196
_CONVERT_FUNC = {
    FieldType.C_BOOL: _crow_bool_to_python,
197 198 199 200 201 202
    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 已提交
203
    FieldType.C_BINARY: _crow_binary_to_python,
204 205 206 207 208 209
    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 已提交
210 211
}

212 213
_CONVERT_FUNC_BLOCK = {
    FieldType.C_BOOL: _crow_bool_to_python,
214 215 216 217 218 219
    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,
220
    FieldType.C_BINARY: _crow_binary_to_python_block,
221 222 223 224 225 226
    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
227 228
}

H
hzcheng 已提交
229
# Corresponding TAOS_FIELD structure in C
230 231


H
hzcheng 已提交
232
class TaosField(ctypes.Structure):
B
Bomin Zhang 已提交
233 234 235
    _fields_ = [('name', ctypes.c_char * 65),
                ('type', ctypes.c_char),
                ('bytes', ctypes.c_short)]
H
hzcheng 已提交
236 237

# C interface class
238 239


240 241 242 243 244
def _load_taos_linux():
    return ctypes.CDLL('libtaos.so')


def _load_taos_darwin():
J
Jun Li 已提交
245
    return ctypes.CDLL('libtaos.dylib')
246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263


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 已提交
264 265
class CTaosInterface(object):

266
    libtaos = _load_taos()
H
hzcheng 已提交
267 268 269 270

    libtaos.taos_fetch_fields.restype = ctypes.POINTER(TaosField)
    libtaos.taos_init.restype = None
    libtaos.taos_connect.restype = ctypes.c_void_p
271
    # libtaos.taos_use_result.restype = ctypes.c_void_p
H
hzcheng 已提交
272 273
    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 已提交
274 275
    libtaos.taos_subscribe.restype = ctypes.c_void_p
    libtaos.taos_consume.restype = ctypes.c_void_p
276
    libtaos.taos_fetch_lengths.restype = ctypes.c_void_p
277
    libtaos.taos_free_result.restype = None
T
Tao Liu 已提交
278
    libtaos.taos_errno.restype = ctypes.c_int
T
Tao Liu 已提交
279
    libtaos.taos_query.restype = ctypes.POINTER(ctypes.c_void_p)
H
hzcheng 已提交
280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299

    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")

300
        if config is not None:
H
hzcheng 已提交
301 302 303 304 305 306 307 308 309 310
            CTaosInterface.libtaos.taos_options(3, self._config)

        CTaosInterface.libtaos.taos_init()

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

311 312 313 314 315 316 317
    def connect(
            self,
            host=None,
            user="root",
            password="taosdata",
            db=None,
            port=0):
H
hzcheng 已提交
318 319 320 321 322 323 324 325
        '''
        Function to connect to server

        @rtype: c_void_p, TDengine handle
        '''
        # host
        try:
            _host = ctypes.c_char_p(host.encode(
326
                "utf-8")) if host is not None else ctypes.c_char_p(None)
H
hzcheng 已提交
327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344
        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(
345
                db.encode("utf-8")) if db is not None else ctypes.c_char_p(None)
H
hzcheng 已提交
346 347 348 349 350 351 352 353 354 355 356 357
        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))

358
        if connection.value is None:
H
hzcheng 已提交
359
            print('connect to TDengine failed')
360
            raise ConnectionError("connect to TDengine failed")
H
hzcheng 已提交
361
            # sys.exit(1)
362
        # else:
363
        #    print('connect to TDengine success')
H
hzcheng 已提交
364 365 366 367 368 369 370 371

        return connection

    @staticmethod
    def close(connection):
        '''Close the TDengine handle
        '''
        CTaosInterface.libtaos.taos_close(connection)
372
        # print('connection is closed')
H
hzcheng 已提交
373 374 375 376 377 378 379 380 381 382

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

        @sql: str, sql string to run

        @rtype: 0 on success and -1 on failure
        '''
        try:
383 384
            return CTaosInterface.libtaos.taos_query(
                connection, ctypes.c_char_p(sql.encode('utf-8')))
H
hzcheng 已提交
385 386
        except AttributeError:
            raise AttributeError("sql is expected as a string")
H
Hongze Cheng 已提交
387 388
        # finally:
        #     CTaosInterface.libtaos.close(connection)
389

H
hzcheng 已提交
390
    @staticmethod
391
    def affectedRows(result):
H
hzcheng 已提交
392 393
        """The affected rows after runing query
        """
394
        return CTaosInterface.libtaos.taos_affected_rows(result)
H
hzcheng 已提交
395

weixin_48148422's avatar
weixin_48148422 已提交
396 397 398
    @staticmethod
    def subscribe(connection, restart, topic, sql, interval):
        """Create a subscription
399
         @restart boolean,
weixin_48148422's avatar
weixin_48148422 已提交
400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430
         @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 已提交
431
    @staticmethod
432
    def useResult(result):
H
hzcheng 已提交
433 434 435 436
        '''Use result after calling self.query
        '''
        fields = []
        pfields = CTaosInterface.fetchFields(result)
437
        for i in range(CTaosInterface.fieldsCount(result)):
H
hzcheng 已提交
438 439 440 441
            fields.append({'name': pfields[i].name.decode('utf-8'),
                           'bytes': pfields[i].bytes,
                           'type': ord(pfields[i].type)})

442
        return fields
H
hzcheng 已提交
443 444 445

    @staticmethod
    def fetchBlock(result, fields):
446 447 448 449 450
        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
451 452
        isMicro = (CTaosInterface.libtaos.taos_result_precision(
            result) == FieldType.C_TIMESTAMP_MICRO)
453 454
        blocks = [None] * len(fields)
        fieldL = CTaosInterface.libtaos.taos_fetch_lengths(result)
455 456 457 458 459
        fieldLen = [
            ele for ele in ctypes.cast(
                fieldL, ctypes.POINTER(
                    ctypes.c_int))[
                :len(fields)]]
460 461 462 463
        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")
464 465
            blocks[i] = _CONVERT_FUNC_BLOCK[fields[i]['type']](
                data, num_of_rows, fieldLen[i], isMicro)
466 467

        return blocks, abs(num_of_rows)
468

469 470
    @staticmethod
    def fetchRow(result, fields):
H
hzcheng 已提交
471
        pblock = ctypes.c_void_p(0)
472 473
        pblock = CTaosInterface.libtaos.taos_fetch_row(result)
        if pblock:
L
liuyq-617 已提交
474
            num_of_rows = 1
475 476
            isMicro = (CTaosInterface.libtaos.taos_result_precision(
                result) == FieldType.C_TIMESTAMP_MICRO)
L
liuyq-617 已提交
477 478
            blocks = [None] * len(fields)
            fieldL = CTaosInterface.libtaos.taos_fetch_lengths(result)
479 480 481 482 483
            fieldLen = [
                ele for ele in ctypes.cast(
                    fieldL, ctypes.POINTER(
                        ctypes.c_int))[
                    :len(fields)]]
L
liuyq-617 已提交
484 485 486
            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:
487 488
                    raise DatabaseError(
                        "Invalid data type returned from database")
L
liuyq-617 已提交
489 490 491
                if data is None:
                    blocks[i] = [None]
                else:
492 493
                    blocks[i] = _CONVERT_FUNC[fields[i]['type']](
                        data, num_of_rows, fieldLen[i], isMicro)
L
liuyq-617 已提交
494
        else:
H
hzcheng 已提交
495 496
            return None, 0
        return blocks, abs(num_of_rows)
497

H
hzcheng 已提交
498 499 500 501 502 503
    @staticmethod
    def freeResult(result):
        CTaosInterface.libtaos.taos_free_result(result)
        result.value = None

    @staticmethod
504 505
    def fieldsCount(result):
        return CTaosInterface.libtaos.taos_field_count(result)
H
hzcheng 已提交
506 507 508 509 510 511 512 513 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

    @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):
540
    #         return ctypes.cast(data,  ctypes.POINTER(ctypes.c_int64))[0]
H
hzcheng 已提交
541 542 543 544 545 546 547
    #     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):
548
    #         return ctypes.cast(data,  ctypes.POINTER(ctypes.c_int64))[0]
H
hzcheng 已提交
549 550 551 552
    #     elif (dtype == CTaosInterface.TSDB_DATA_TYPE_NCHAR):
    #         return (ctypes.cast(data,  ctypes.c_char_p).value).rstrip('\x00')

    @staticmethod
553
    def errno(result):
H
hzcheng 已提交
554 555
        """Return the error number.
        """
556
        return CTaosInterface.libtaos.taos_errno(result)
H
hzcheng 已提交
557 558

    @staticmethod
559
    def errStr(result):
H
hzcheng 已提交
560 561
        """Return the error styring
        """
562
        return CTaosInterface.libtaos.taos_errstr(result).decode('utf-8')
weixin_48148422's avatar
weixin_48148422 已提交
563 564 565 566 567


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

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

572
    fields = CTaosInterface.useResult(result)
weixin_48148422's avatar
weixin_48148422 已提交
573

574
    data, num_of_rows = CTaosInterface.fetchBlock(result, fields)
weixin_48148422's avatar
weixin_48148422 已提交
575 576 577

    print(data)

T
Tao Liu 已提交
578
    cinter.freeResult(result)
579
    cinter.close(conn)