DBUtil(连接和sql处理类)声明
#pragma once
#include "pch.h"
#include "ResultSet.h"
#define STR(x) std::to_string(x)
using namespace std;
// interaction class of database
class DBUtil {
public:
// execute DQL synchronously
// return result set
static ResultSet ExecuteQuery(TAOS* handle, const char* sql);
// callbacks of SQL asynchronously
static void ExecuteQueyCallback(void* param, TAOS_RES* resultSet, int code);
public:
DBUtil();
DBUtil(DBUtil&& rv) noexcept;
DBUtil& operator=(DBUtil&& rv) noexcept;
~DBUtil();
bool Connect(const char* host, const char* user, const char* passwd, const char* dbName, int port = 0);
void Disconnect();
// execute DQL synchronously
ResultSet ExecuteQuery(const char* sql);
// execute DML、DDL synchronously
// return affect rows
// return -1 if fail
long long ExecuteUpdate(const char* sql);
// execute DQL asynchronously
std::future<ResultSet> ExecuteQuery(const char* sql, bool asynchronous);
// select database
bool Usedb(const char* dbName);
inline TAOS* Handle() { return this->taos; }
protected:
// handle of database
TAOS* taos;
};
DBUtil实现
#include "DBUtil.h"
using namespace std;
DBUtil::DBUtil() :taos(nullptr){ }
DBUtil::DBUtil(DBUtil&& rv) noexcept :taos(rv.taos) {
memset(&rv, 0, sizeof(DBUtil));
}
DBUtil& DBUtil::operator=(DBUtil&& rv) noexcept {
memcpy(this, &rv, sizeof(DBUtil));
memset(&rv, 0, sizeof(DBUtil));
return *this;
}
DBUtil::~DBUtil() {
if (this->taos) {
taos_close(this->taos);
taos_cleanup();
}
}
bool DBUtil::Connect(const char* host, const char* user, const char* passwd, const char* dbName, int port) {
return this->taos = taos_connect(host, user, passwd, dbName, port);
}
void DBUtil::Disconnect() {
taos_close(this->taos);
this->taos = nullptr;
taos_cleanup();
}
// execute DQL synchronously
ResultSet DBUtil::ExecuteQuery(const char* sql) {
return taos_query(taos, sql);
}
// execute DML、DDL synchronously
// return affect rows
// return -1 if fail
long long DBUtil::ExecuteUpdate(const char* sql) {
ResultSet res = taos_query(this->taos, sql);
if (!res) return -1;
return res.AffectItems();
}
// execute DQL asynchronously
std::future<ResultSet> DBUtil::ExecuteQuery(const char* sql, bool asynchronous) {
std::promise<ResultSet>* proSet = new std::promise<ResultSet>;
std::future<ResultSet> res = proSet->get_future();
taos_query_a(this->taos, sql, ExecuteQueyCallback, proSet);
return std::move(res);
}
// select database
bool DBUtil::Usedb(const char* dbName) {
return !taos_select_db(this->taos, dbName);
}
// callbacks of SQL asynchronously
void DBUtil::ExecuteQueyCallback(void* param, TAOS_RES* resultSet, int code) {
std::promise<ResultSet>* proSet = (std::promise<ResultSet>*)param;
proSet->set_value(resultSet);
delete proSet;
}
// execute DQL synchronously
// return result set
ResultSet DBUtil::ExecuteQuery(TAOS* handle, const char* sql) {
return taos_query(handle, sql);
}
ResultSet(结果集处理类)声明
#pragma once
#include "pch.h"
class ResultSet {
public:
ResultSet();
ResultSet(TAOS_RES* _resultSet);
ResultSet(const ResultSet& cp) = default;
ResultSet(ResultSet&& mv) noexcept;
~ResultSet();
ResultSet& operator=(const ResultSet& cp) = default;
ResultSet& operator=(ResultSet&& mv) noexcept;
// get fileds of result set
// return nullptr if fail
// TAOS_FIELD:
// char name[65] filed name
// int8_t type
// int32_t bytes type length
TAOS_FIELD* Desc();
// get columns of result set
int Columns();
// get rows of result set
int64_t Rows();
// return the number of items affected by the last operation
int64_t AffectItems();
// next row of result set
// return nullptr if over
TAOS_ROW Next();
// print information of result set
void Print();
// used with asynchronous query
// this call should be made after the asynchronous query has completed
void Print(bool asynchronous);
// print error messages
void CheckError();
// check error
// error occurs if return true
bool operator!();
inline TAOS_RES* GetResultSet() { return this->resultSet; }
inline void SetResultSet(TAOS_RES* resultSet) { this->resultSet = resultSet; }
protected:
// print one row
void PrintRow(TAOS_ROW row, TAOS_FIELD* fields, int numFields);
// callbacks of Print asynchronously
static void PrintCallback(void* param, TAOS_RES* res, int rows);
protected:
TAOS_RES* resultSet;
};
ResultSet实现
#include "ResultSet.h"
ResultSet::ResultSet() :resultSet(nullptr) {};
ResultSet::ResultSet(TAOS_RES* _resultSet) :resultSet(_resultSet) {};
ResultSet::ResultSet(ResultSet&& mv)noexcept :resultSet(mv.resultSet) {
memset(&mv, 0, sizeof(ResultSet));
};
ResultSet::~ResultSet() {
if (this->resultSet) {
taos_free_result(this->resultSet);
}
}
ResultSet& ResultSet::operator=(ResultSet&& mv) noexcept {
memcpy(this, &mv, sizeof(ResultSet));
memset(&mv, 0, sizeof(ResultSet));
return *this;
}
// get fileds of result set
// return nullptr if fail
// TAOS_FIELD:
// char name[65] filed name
// int8_t type
// int32_t bytes type length
TAOS_FIELD* ResultSet::Desc() { return this->resultSet ? taos_fetch_fields(this->resultSet) : nullptr; }
// get columns of result set
int ResultSet::Columns() { return this->resultSet ? taos_num_fields(this->resultSet) : 0; }
// get rows of result set
int64_t ResultSet::Rows() { return this->resultSet ? taos_affected_rows64(this->resultSet) : 0; }
// return the number of items affected by the last operation
int64_t ResultSet::AffectItems() { return taos_affected_rows64(this->resultSet); }
// next row of result set
// return nullptr if over
TAOS_ROW ResultSet::Next() { return this->resultSet ? taos_fetch_row(this->resultSet) : nullptr; }
void ResultSet::Print() {
if (!this->resultSet) return;
// fileds
TAOS_FIELD* fd = this->Desc();
int cols = this->Columns();
for (int i = 0; i < cols; i++) printf("%s\t\t", fd[i].name);
puts("");
// items
TAOS_ROW data;
while (data = this->Next()) {
this->PrintRow(data, fd, cols);
puts("");
}
}
// used with asynchronous query
// this call should be made after the asynchronous query has completed
void ResultSet::Print(bool asynchronous) {
if (!this->resultSet) return;
// fileds
TAOS_FIELD* fd = this->Desc();
int cols = this->Columns();
for (int i = 0; i < cols; i++) printf("%s\t\t", fd[i].name);
puts("");
// items
taos_fetch_rows_a(this->resultSet, this->PrintCallback, this);
}
// print error messages
void ResultSet::CheckError() {
printf("Error code: %d\n Error message: %s\n", taos_errno(this->resultSet), taos_errstr(this->resultSet));
}
bool ResultSet::operator!(){
if (taos_errno(this->resultSet)) {
this->CheckError();
return true;
}
return false;
}
// print one row
void ResultSet::PrintRow(TAOS_ROW row, TAOS_FIELD* fields, int numFields) {
for (int i = 0; i < numFields; ++i) {
if (row[i] == nullptr) {
printf("NULL\t\t");
continue;
}
switch (fields[i].type) {
case TSDB_DATA_TYPE_TINYINT:
printf("%d\t\t", *((int8_t*)row[i]));
break;
case TSDB_DATA_TYPE_UTINYINT:
printf("%u\t\t", *((uint8_t*)row[i]));
break;
case TSDB_DATA_TYPE_SMALLINT:
printf("%d\t\t", *((int16_t*)row[i]));
break;
case TSDB_DATA_TYPE_USMALLINT:
printf("%u\t\t", *((uint16_t*)row[i]));
break;
case TSDB_DATA_TYPE_INT:
printf("%d\t\t", *((int32_t*)row[i]));
break;
case TSDB_DATA_TYPE_UINT:
printf("%u\t\t", *((uint32_t*)row[i]));
break;
case TSDB_DATA_TYPE_BIGINT:
printf("%lld\t\t", *((int64_t*)row[i]));
break;
case TSDB_DATA_TYPE_UBIGINT:
printf("%llu\t\t", *((uint64_t*)row[i]));
break;
case TSDB_DATA_TYPE_FLOAT:
printf("%f\t\t", *(float*)(row[i]));
break;
case TSDB_DATA_TYPE_DOUBLE:
printf("%lf\t\t", *(float*)(row[i]));
break;
case TSDB_DATA_TYPE_BINARY:
case TSDB_DATA_TYPE_NCHAR:
case TSDB_DATA_TYPE_GEOMETRY:
printf("%s\t\t", (char*)row[i]);
break;
case TSDB_DATA_TYPE_TIMESTAMP:
printf("%lld\t\t", *((int64_t*)row[i]));
break;
case TSDB_DATA_TYPE_BOOL:
printf("%d\t\t", *((int8_t*)row[i]));
default:
break;
}
}
}
// callbacks of Print asynchronously
void ResultSet::PrintCallback(void* param, TAOS_RES* res, int rows) {
ResultSet* handle = (ResultSet*)param;
if (rows > 0) {
TAOS_FIELD* fd = handle->Desc();
int cols = handle->Columns();
// data of each line
TAOS_ROW data;
// get data of next line
for (int i = 0; i < rows; ++i) {
data = handle->Next();
handle->PrintRow(data, fd, cols);
puts("");
}
taos_fetch_rows_a(handle->resultSet, handle->PrintCallback, handle);
return;
}
else if (rows < 0) handle->CheckError();
}