提交 0280f366 编写于 作者: S Shuduo Sang

add few more cases and support check data type in connector.

上级 3936e2df
from .cinterface import CTaosInterface from .cinterface import CTaosInterface
from .error import * from .error import *
from .constants import FieldType
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.
...@@ -19,7 +21,7 @@ class TDengineCursor(object): ...@@ -19,7 +21,7 @@ class TDengineCursor(object):
if the cursor has not had an operation invoked via the .execute*() method yet. if the cursor has not had an operation invoked via the .execute*() method yet.
.rowcount:This read-only attribute specifies the number of rows that the last .rowcount:This read-only attribute specifies the number of rows that the last
.execute*() produced (for DQL statements like SELECT) or affected .execute*() produced (for DQL statements like SELECT) or affected
""" """
def __init__(self, connection=None): def __init__(self, connection=None):
...@@ -44,13 +46,14 @@ class TDengineCursor(object): ...@@ -44,13 +46,14 @@ class TDengineCursor(object):
raise OperationalError("Invalid use of fetch iterator") raise OperationalError("Invalid use of fetch iterator")
if self._block_rows <= self._block_iter: if self._block_rows <= self._block_iter:
block, self._block_rows = CTaosInterface.fetchBlock(self._result, self._fields) block, self._block_rows = CTaosInterface.fetchBlock(
self._result, self._fields)
if self._block_rows == 0: if self._block_rows == 0:
raise StopIteration raise StopIteration
self._block = list(map(tuple, zip(*block))) self._block = list(map(tuple, zip(*block)))
self._block_iter = 0 self._block_iter = 0
data = self._block[self._block_iter] data = self._block[self._block_iter]
self._block_iter += 1 self._block_iter += 1
return data return data
...@@ -85,7 +88,7 @@ class TDengineCursor(object): ...@@ -85,7 +88,7 @@ class TDengineCursor(object):
""" """
if self._connection is None: if self._connection is None:
return False return False
self._connection.clear_result_set() self._connection.clear_result_set()
self._reset_result() self._reset_result()
self._connection = None self._connection = None
...@@ -101,24 +104,28 @@ class TDengineCursor(object): ...@@ -101,24 +104,28 @@ class TDengineCursor(object):
if not self._connection: if not self._connection:
# TODO : change the exception raised here # TODO : change the exception raised here
raise ProgrammingError("Cursor is not connected") raise ProgrammingError("Cursor is not connected")
self._connection.clear_result_set() self._connection.clear_result_set()
self._reset_result() self._reset_result()
stmt = operation stmt = operation
if params is not None: if params is not None:
pass pass
res = CTaosInterface.query(self._connection._conn, stmt) res = CTaosInterface.query(self._connection._conn, stmt)
if res == 0: if res == 0:
if CTaosInterface.fieldsCount(self._connection._conn) == 0: if CTaosInterface.fieldsCount(self._connection._conn) == 0:
self._affected_rows += CTaosInterface.affectedRows(self._connection._conn) self._affected_rows += CTaosInterface.affectedRows(
self._connection._conn)
return CTaosInterface.affectedRows(self._connection._conn) return CTaosInterface.affectedRows(self._connection._conn)
else: else:
self._result, self._fields = CTaosInterface.useResult(self._connection._conn) self._result, self._fields = CTaosInterface.useResult(
self._connection._conn)
return self._handle_result() return self._handle_result()
else: else:
raise ProgrammingError(CTaosInterface.errStr(self._connection._conn)) raise ProgrammingError(
CTaosInterface.errStr(
self._connection._conn))
def executemany(self, operation, seq_of_parameters): def executemany(self, operation, seq_of_parameters):
"""Prepare a database operation (query or command) and then execute it against all parameter sequences or mappings found in the sequence seq_of_parameters. """Prepare a database operation (query or command) and then execute it against all parameter sequences or mappings found in the sequence seq_of_parameters.
...@@ -130,6 +137,37 @@ class TDengineCursor(object): ...@@ -130,6 +137,37 @@ class TDengineCursor(object):
""" """
pass pass
def istype(self, col, dataType):
if (dataType.upper() == "BOOL"):
if (self._description[col][1] == FieldType.C_BOOL):
return True
if (dataType.upper() == "TINYINT"):
if (self._description[col][1] == FieldType.C_TINYINT):
return True
if (dataType.upper() == "INT"):
if (self._description[col][1] == FieldType.C_INT):
return True
if (dataType.upper() == "BIGINT"):
if (self._description[col][1] == FieldType.C_INT):
return True
if (dataType.upper() == "FLOAT"):
if (self._description[col][1] == FieldType.C_FLOAT):
return True
if (dataType.upper() == "DOUBLE"):
if (self._description[col][1] == FieldType.C_DOUBLE):
return True
if (dataType.upper() == "BINARY"):
if (self._description[col][1] == FieldType.C_BINARY):
return True
if (dataType.upper() == "TIMESTAMP"):
if (self._description[col][1] == FieldType.C_TIMESTAMP):
return True
if (dataType.upper() == "NCHAR"):
if (self._description[col][1] == FieldType.C_NCHAR):
return True
return False
def fetchmany(self): def fetchmany(self):
pass pass
...@@ -138,21 +176,21 @@ class TDengineCursor(object): ...@@ -138,21 +176,21 @@ class TDengineCursor(object):
""" """
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")
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(
if num_of_fields == 0: break self._result, self._fields)
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])
self._connection.clear_result_set() self._connection.clear_result_set()
return list(map(tuple, zip(*buffer)))
return list(map(tuple, zip(*buffer)))
def nextset(self): def nextset(self):
""" """
...@@ -176,12 +214,13 @@ class TDengineCursor(object): ...@@ -176,12 +214,13 @@ class TDengineCursor(object):
self._block_rows = -1 self._block_rows = -1
self._block_iter = 0 self._block_iter = 0
self._affected_rows = 0 self._affected_rows = 0
def _handle_result(self): def _handle_result(self):
"""Handle the return result from query. """Handle the return result from query.
""" """
self._description = [] self._description = []
for ele in self._fields: for ele in self._fields:
self._description.append((ele['name'], ele['type'], None, None, None, None, False)) self._description.append(
(ele['name'], ele['type'], None, None, None, None, False))
return self._result return self._result
from .cinterface import CTaosInterface from .cinterface import CTaosInterface
from .error import * from .error import *
from .constants import FieldType
# 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.
...@@ -21,7 +23,7 @@ class TDengineCursor(object): ...@@ -21,7 +23,7 @@ class TDengineCursor(object):
if the cursor has not had an operation invoked via the .execute*() method yet. if the cursor has not had an operation invoked via the .execute*() method yet.
.rowcount:This read-only attribute specifies the number of rows that the last .rowcount:This read-only attribute specifies the number of rows that the last
.execute*() produced (for DQL statements like SELECT) or affected .execute*() produced (for DQL statements like SELECT) or affected
""" """
def __init__(self, connection=None): def __init__(self, connection=None):
...@@ -46,13 +48,14 @@ class TDengineCursor(object): ...@@ -46,13 +48,14 @@ class TDengineCursor(object):
raise OperationalError("Invalid use of fetch iterator") raise OperationalError("Invalid use of fetch iterator")
if self._block_rows <= self._block_iter: if self._block_rows <= self._block_iter:
block, self._block_rows = CTaosInterface.fetchBlock(self._result, self._fields) block, self._block_rows = CTaosInterface.fetchBlock(
self._result, self._fields)
if self._block_rows == 0: if self._block_rows == 0:
raise StopIteration raise StopIteration
self._block = list(map(tuple, zip(*block))) self._block = list(map(tuple, zip(*block)))
self._block_iter = 0 self._block_iter = 0
data = self._block[self._block_iter] data = self._block[self._block_iter]
self._block_iter += 1 self._block_iter += 1
return data return data
...@@ -87,7 +90,7 @@ class TDengineCursor(object): ...@@ -87,7 +90,7 @@ class TDengineCursor(object):
""" """
if self._connection is None: if self._connection is None:
return False return False
self._connection.clear_result_set() self._connection.clear_result_set()
self._reset_result() self._reset_result()
self._connection = None self._connection = None
...@@ -103,14 +106,13 @@ class TDengineCursor(object): ...@@ -103,14 +106,13 @@ class TDengineCursor(object):
if not self._connection: if not self._connection:
# TODO : change the exception raised here # TODO : change the exception raised here
raise ProgrammingError("Cursor is not connected") raise ProgrammingError("Cursor is not connected")
self._connection.clear_result_set() self._connection.clear_result_set()
self._reset_result() self._reset_result()
stmt = operation stmt = operation
if params is not None: if params is not None:
pass pass
# global querySeqNum # global querySeqNum
# querySeqNum += 1 # querySeqNum += 1
...@@ -121,13 +123,17 @@ class TDengineCursor(object): ...@@ -121,13 +123,17 @@ class TDengineCursor(object):
if res == 0: if res == 0:
if CTaosInterface.fieldsCount(self._connection._conn) == 0: if CTaosInterface.fieldsCount(self._connection._conn) == 0:
self._affected_rows += CTaosInterface.affectedRows(self._connection._conn) self._affected_rows += CTaosInterface.affectedRows(
self._connection._conn)
return CTaosInterface.affectedRows(self._connection._conn) return CTaosInterface.affectedRows(self._connection._conn)
else: else:
self._result, self._fields = CTaosInterface.useResult(self._connection._conn) self._result, self._fields = CTaosInterface.useResult(
self._connection._conn)
return self._handle_result() return self._handle_result()
else: else:
raise ProgrammingError(CTaosInterface.errStr(self._connection._conn)) raise ProgrammingError(
CTaosInterface.errStr(
self._connection._conn))
def executemany(self, operation, seq_of_parameters): def executemany(self, operation, seq_of_parameters):
"""Prepare a database operation (query or command) and then execute it against all parameter sequences or mappings found in the sequence seq_of_parameters. """Prepare a database operation (query or command) and then execute it against all parameter sequences or mappings found in the sequence seq_of_parameters.
...@@ -142,26 +148,57 @@ class TDengineCursor(object): ...@@ -142,26 +148,57 @@ class TDengineCursor(object):
def fetchmany(self): def fetchmany(self):
pass pass
def istype(self, col, dataType):
if (dataType.upper() == "BOOL"):
if (self._description[col][1] == FieldType.C_BOOL):
return True
if (dataType.upper() == "TINYINT"):
if (self._description[col][1] == FieldType.C_TINYINT):
return True
if (dataType.upper() == "INT"):
if (self._description[col][1] == FieldType.C_INT):
return True
if (dataType.upper() == "BIGINT"):
if (self._description[col][1] == FieldType.C_INT):
return True
if (dataType.upper() == "FLOAT"):
if (self._description[col][1] == FieldType.C_FLOAT):
return True
if (dataType.upper() == "DOUBLE"):
if (self._description[col][1] == FieldType.C_DOUBLE):
return True
if (dataType.upper() == "BINARY"):
if (self._description[col][1] == FieldType.C_BINARY):
return True
if (dataType.upper() == "TIMESTAMP"):
if (self._description[col][1] == FieldType.C_TIMESTAMP):
return True
if (dataType.upper() == "NCHAR"):
if (self._description[col][1] == FieldType.C_NCHAR):
return True
return False
def fetchall(self): def fetchall(self):
"""Fetch all (remaining) rows of a query result, returning them as a sequence of sequences (e.g. a list of tuples). Note that the cursor's arraysize attribute can affect the performance of this operation. """Fetch all (remaining) rows of a query result, returning them as a sequence of sequences (e.g. a list of tuples). Note that the cursor's arraysize attribute can affect the performance of this operation.
""" """
if self._result is None or self._fields is None: if self._result is None or self._fields is None:
raise OperationalError("Invalid use of fetchall") raise OperationalError("Invalid use of fetchall")
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(
if num_of_fields == 0: break self._result, self._fields)
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])
self._connection.clear_result_set() self._connection.clear_result_set()
return list(map(tuple, zip(*buffer)))
return list(map(tuple, zip(*buffer)))
def nextset(self): def nextset(self):
""" """
...@@ -185,12 +222,13 @@ class TDengineCursor(object): ...@@ -185,12 +222,13 @@ class TDengineCursor(object):
self._block_rows = -1 self._block_rows = -1
self._block_iter = 0 self._block_iter = 0
self._affected_rows = 0 self._affected_rows = 0
def _handle_result(self): def _handle_result(self):
"""Handle the return result from query. """Handle the return result from query.
""" """
self._description = [] self._description = []
for ele in self._fields: for ele in self._fields:
self._description.append((ele['name'], ele['type'], None, None, None, None, False)) self._description.append(
(ele['name'], ele['type'], None, None, None, None, False))
return self._result return self._result
...@@ -22,6 +22,32 @@ python3 ./test.py $1 -f table/tablename-boundary.py ...@@ -22,6 +22,32 @@ python3 ./test.py $1 -f table/tablename-boundary.py
# tag # tag
python3 ./test.py $1 -f tag_lite/filter.py python3 ./test.py $1 -f tag_lite/filter.py
python3 ./test.py $1 -f tag_lite/create-tags-boundary.py python3 ./test.py $1 -f tag_lite/create-tags-boundary.py
python3 ./test.py $1 -f tag_lite/3.py
python3 ./test.py $1 -f tag_lite/4.py
python3 ./test.py $1 -f tag_lite/5.py
python3 ./test.py $1 -f tag_lite/6.py
python3 ./test.py $1 -f tag_lite/add.py
python3 ./test.py $1 -f tag_lite/bigint.py
python3 ./test.py $1 -f tag_lite/binary_binary.py
python3 ./test.py $1 -f tag_lite/binary.py
python3 ./test.py $1 -f tag_lite/bool_binary.py
python3 ./test.py $1 -f tag_lite/bool_int.py
python3 ./test.py $1 -f tag_lite/bool.py
python3 ./test.py $1 -f tag_lite/change.py
python3 ./test.py $1 -f tag_lite/column.py
python3 ./test.py $1 -f tag_lite/commit.py
python3 ./test.py $1 -f tag_lite/create.py
python3 ./test.py $1 -f tag_lite/datatype.py
python3 ./test.py $1 -f tag_lite/datatype-without-alter.py
python3 ./test.py $1 -f tag_lite/delete.py
python3 ./test.py $1 -f tag_lite/double.py
python3 ./test.py $1 -f tag_lite/float.py
python3 ./test.py $1 -f tag_lite/int_binary.py
python3 ./test.py $1 -f tag_lite/int_float.py
python3 ./test.py $1 -f tag_lite/int.py
python3 ./test.py $1 -f tag_lite/set.py
python3 ./test.py $1 -f tag_lite/smallint.py
python3 ./test.py $1 -f tag_lite/tinyint.py
python3 ./test.py $1 -f dbmgmt/database-name-boundary.py python3 ./test.py $1 -f dbmgmt/database-name-boundary.py
......
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
...@@ -23,7 +23,7 @@ class TDLog: ...@@ -23,7 +23,7 @@ class TDLog:
self.path = "" self.path = ""
def info(self, info): def info(self, info):
print("%s %s" % (datetime.datetime.now(), info)) print("%s %s\n" % (datetime.datetime.now(), info))
def sleep(self, sec): def sleep(self, sec):
print("%s sleep %d seconds" % (datetime.datetime.now(), sec)) print("%s sleep %d seconds" % (datetime.datetime.now(), sec))
......
...@@ -77,6 +77,31 @@ class TDSql: ...@@ -77,6 +77,31 @@ class TDSql:
tdLog.info("sql:%s, queryRows:%d == expect:%d" % tdLog.info("sql:%s, queryRows:%d == expect:%d" %
(self.sql, self.queryRows, expectRows)) (self.sql, self.queryRows, expectRows))
def checkDataType(self, row, col, dataType):
frame = inspect.stack()[1]
callerModule = inspect.getmodule(frame[0])
callerFilename = callerModule.__file__
if row < 0:
tdLog.exit(
"%s failed: sql:%s, row:%d is smaller than zero" %
(callerFilename, self.sql, row))
if col < 0:
tdLog.exit(
"%s failed: sql:%s, col:%d is smaller than zero" %
(callerFilename, self.sql, col))
if row > self.queryRows:
tdLog.exit(
"%s failed: sql:%s, row:%d is larger than queryRows:%d" %
(callerFilename, self.sql, row, self.queryRows))
if col > self.queryCols:
tdLog.exit(
"%s failed: sql:%s, col:%d is larger than queryCols:%d" %
(callerFilename, self.sql, col, self.queryCols))
return self.cursor.istype(col, dataType)
def checkData(self, row, col, data): def checkData(self, row, col, data):
frame = inspect.stack()[1] frame = inspect.stack()[1]
callerModule = inspect.getmodule(frame[0]) callerModule = inspect.getmodule(frame[0])
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册