diff --git a/docs-examples/c/async_query_example.c b/docs-examples/c/async_query_example.c index ec7bd61293a36f7be44c1255ddff9aa6da1795e2..c45e5de39d7da49766e80f935b8cb06b2c14b005 100644 --- a/docs-examples/c/async_query_example.c +++ b/docs-examples/c/async_query_example.c @@ -1,4 +1,192 @@ -// compiple with: +// compile with: // gcc -o async_query_example async_query_example.c -ltaos -// writing... \ No newline at end of file +#include +#include +#include +#include +#include + +typedef int16_t VarDataLenT; + +#define TSDB_NCHAR_SIZE sizeof(int32_t) +#define VARSTR_HEADER_SIZE sizeof(VarDataLenT) + +#define GET_FLOAT_VAL(x) (*(float *)(x)) +#define GET_DOUBLE_VAL(x) (*(double *)(x)) + +#define varDataLen(v) ((VarDataLenT *)(v))[0] + +int printRow(char *str, TAOS_ROW row, TAOS_FIELD *fields, int numFields) { + int len = 0; + char split = ' '; + + for (int i = 0; i < numFields; ++i) { + if (i > 0) { + str[len++] = split; + } + + if (row[i] == NULL) { + len += sprintf(str + len, "%s", "NULL"); + continue; + } + + switch (fields[i].type) { + case TSDB_DATA_TYPE_TINYINT: + len += sprintf(str + len, "%d", *((int8_t *)row[i])); + break; + + case TSDB_DATA_TYPE_UTINYINT: + len += sprintf(str + len, "%u", *((uint8_t *)row[i])); + break; + + case TSDB_DATA_TYPE_SMALLINT: + len += sprintf(str + len, "%d", *((int16_t *)row[i])); + break; + + case TSDB_DATA_TYPE_USMALLINT: + len += sprintf(str + len, "%u", *((uint16_t *)row[i])); + break; + + case TSDB_DATA_TYPE_INT: + len += sprintf(str + len, "%d", *((int32_t *)row[i])); + break; + + case TSDB_DATA_TYPE_UINT: + len += sprintf(str + len, "%u", *((uint32_t *)row[i])); + break; + + case TSDB_DATA_TYPE_BIGINT: + len += sprintf(str + len, "%" PRId64, *((int64_t *)row[i])); + break; + + case TSDB_DATA_TYPE_UBIGINT: + len += sprintf(str + len, "%" PRIu64, *((uint64_t *)row[i])); + break; + + case TSDB_DATA_TYPE_FLOAT: { + float fv = 0; + fv = GET_FLOAT_VAL(row[i]); + len += sprintf(str + len, "%f", fv); + } break; + + case TSDB_DATA_TYPE_DOUBLE: { + double dv = 0; + dv = GET_DOUBLE_VAL(row[i]); + len += sprintf(str + len, "%lf", dv); + } break; + + case TSDB_DATA_TYPE_BINARY: + case TSDB_DATA_TYPE_NCHAR: { + int32_t charLen = varDataLen((char *)row[i] - VARSTR_HEADER_SIZE); + memcpy(str + len, row[i], charLen); + len += charLen; + } break; + + case TSDB_DATA_TYPE_TIMESTAMP: + len += sprintf(str + len, "%" PRId64, *((int64_t *)row[i])); + break; + + case TSDB_DATA_TYPE_BOOL: + len += sprintf(str + len, "%d", *((int8_t *)row[i])); + default: + break; + } + } + + return len; +} + +void printHeader(TAOS_RES *res) { + int numFields = taos_num_fields(res); + TAOS_FIELD *fields = taos_fetch_fields(res); + char header[256] = {0}; + int len = 0; + for (int i = 0; i < numFields; ++i) { + len += sprintf(header + len, "%s ", fields[i].name); + } + puts(header); +} + +// ANCHOR: demo + +/** + * @brief call back function of taos_fetch_row_a + * + * @param param : the third parameter you passed to taos_fetch_row_a + * @param res : pointer of TAOS_RES + * @param numOfRow : number of rows fetched in this batch. will be 0 if there is no more data. + * @return void* + */ +void *fetch_row_callback(void *param, TAOS_RES *res, int numOfRow) { + printf("numOfRow = %d \n", numOfRow); + int numFields = taos_num_fields(res); + TAOS_FIELD *fields = taos_fetch_fields(res); + TAOS *_taos = (TAOS *)param; + if (numOfRow > 0) { + for (int i = 0; i < numOfRow; ++i) { + TAOS_ROW row = taos_fetch_row(res); + char temp[256] = {0}; + printRow(temp, row, fields, numFields); + puts(temp); + } + taos_fetch_rows_a(res, fetch_row_callback, _taos); + } else { + taos_free_result(res); + taos_close(_taos); + taos_cleanup(); + } +} + +/** + * @brief callback function of taos_query_a + * + * @param param: the fourth parameter you passed to taos_query_a + * @param res : the result set + * @param code : status code + * @return void* + */ +void *select_callback(void *param, TAOS_RES *res, int code) { + printf("query callback ...\n"); + TAOS *_taos = (TAOS *)param; + if (code == 0 && res) { + printHeader(res); + taos_fetch_rows_a(res, fetch_row_callback, _taos); + } else { + printf("failed to exeuce taos_query. error: %s\n", taos_errstr(res)); + taos_free_result(res); + taos_close(_taos); + taos_cleanup(); + exit(EXIT_FAILURE); + } +} + +int main() { + TAOS *taos = taos_connect("localhost", "root", "taosdata", "power", 6030); + if (taos == NULL) { + puts("failed to connect to server"); + exit(EXIT_FAILURE); + } + // param one is the connection returned by taos_connect. + // param two is the SQL to execute. + // param three is the callback function. + // param four can be any pointer. It will be passed to your callback function as the first parameter. we use taos + // here, because we want to close it after getting data. + taos_query_a(taos, "SELECT * FROM meters", select_callback, taos); + getchar(); +} + +// output: +// query callback ... +// ts current voltage phase location groupid +// numOfRow = 8 +// 1538548685000 10.300000 219 0.310000 beijing.chaoyang 2 +// 1538548695000 12.600000 218 0.330000 beijing.chaoyang 2 +// 1538548696800 12.300000 221 0.310000 beijing.chaoyang 2 +// 1538548696650 10.300000 218 0.250000 beijing.chaoyang 3 +// 1538548685500 11.800000 221 0.280000 beijing.haidian 2 +// 1538548696600 13.400000 223 0.290000 beijing.haidian 2 +// 1538548685000 10.800000 223 0.290000 beijing.haidian 3 +// 1538548686500 11.500000 221 0.350000 beijing.haidian 3 +// numOfRow = 0 +// ANCHOR_END: demo \ No newline at end of file