#include "os.h" #include #include #include #include #include "os.h" #include "../src/todbc_log.h" // static const char *dsn = "TAOS_DSN"; // static const char *uid = "root"; // static const char *pwd = "taosdata"; #define CHK_TEST(statement) \ do { \ D("testing: %s", #statement); \ int r = (statement); \ if (r) return 1; \ } while (0); typedef struct data_s data_t; struct data_s { int64_t ts; int8_t b; int8_t v1; int16_t v2; int32_t v4; int64_t v8; float f4; double f8; char bin[40+1]; char blob[40+1]; // why 80? ref: tests/examples/c/apitest.c }; static const char *pre_stmts[] = { "create database db", "use db", "create table t (ts timestamp, b bool, v1 tinyint, v2 smallint, v4 int, v8 bigint, f4 float, f8 double, bin binary(40), blob nchar(10))" }; static const char *pro_stmts[] = { // "insert into t values ('2019-07-15 00:00:00', 1)", // "insert into t values ('2019-07-15 01:00:00', 2)", "select * from t" // "drop database db" }; #define CHK_RESULT(r, ht, h, fmt, ...) \ do { \ if (r==0) break; \ SQLCHAR ss[10]; \ SQLINTEGER ne = 0; \ SQLCHAR es[4096]; \ SQLSMALLINT n = 0; \ ss[0] = '\0'; \ es[0] = '\0'; \ SQLRETURN ret = SQLGetDiagRec(ht, h, 1, ss, &ne, es, sizeof(es), &n); \ if (ret) break; \ D("[%s]%s: " fmt "", ss, es, ##__VA_ARGS__); \ } while (0) static int open_connect(const char *dsn, const char *uid, const char *pwd, SQLHENV *pEnv, SQLHDBC *pConn) { SQLRETURN r; SQLHENV env = {0}; SQLHDBC conn = {0}; r = SQLAllocEnv(&env); if (r!=SQL_SUCCESS) return 1; do { r = SQLAllocConnect(env, &conn); CHK_RESULT(r, SQL_HANDLE_ENV, env, ""); if (r!=SQL_SUCCESS) break; do { r = SQLConnect(conn, (SQLCHAR*)dsn, (SQLSMALLINT)strlen(dsn), (SQLCHAR*)uid, (SQLSMALLINT)strlen(uid), (SQLCHAR*)pwd, (SQLSMALLINT)strlen(pwd)); CHK_RESULT(r, SQL_HANDLE_DBC, conn, ""); if (r==SQL_SUCCESS) { *pEnv = env; *pConn = conn; return 0; } } while (0); SQLFreeConnect(conn); } while (0); SQLFreeEnv(env); return 1; } static int open_driver_connect(const char *connstr, SQLHENV *pEnv, SQLHDBC *pConn) { SQLRETURN r; SQLHENV env = {0}; SQLHDBC conn = {0}; r = SQLAllocEnv(&env); if (r!=SQL_SUCCESS) return 1; do { r = SQLAllocConnect(env, &conn); CHK_RESULT(r, SQL_HANDLE_ENV, env, ""); if (r!=SQL_SUCCESS) break; do { SQLCHAR buf[4096]; SQLSMALLINT blen = 0; SQLHDBC ConnectionHandle = conn; SQLHWND WindowHandle = NULL; SQLCHAR * InConnectionString = (SQLCHAR*)connstr; SQLSMALLINT StringLength1 = (SQLSMALLINT)strlen(connstr); SQLCHAR * OutConnectionString = buf; SQLSMALLINT BufferLength = sizeof(buf); SQLSMALLINT * StringLength2Ptr = &blen; SQLUSMALLINT DriverCompletion = SQL_DRIVER_NOPROMPT; r = SQLDriverConnect(ConnectionHandle, WindowHandle, InConnectionString, StringLength1, OutConnectionString, BufferLength, StringLength2Ptr, DriverCompletion); CHK_RESULT(r, SQL_HANDLE_DBC, conn, ""); if (r==SQL_SUCCESS) { *pEnv = env; *pConn = conn; return 0; } } while (0); SQLFreeConnect(conn); } while (0); SQLFreeEnv(env); return 1; } static int do_statement(SQLHSTMT stmt, const char *statement) { SQLRETURN r = 0; do { r = SQLExecDirect(stmt, (SQLCHAR*)statement, SQL_NTS); CHK_RESULT(r, SQL_HANDLE_STMT, stmt, "statement: [%s]", statement); if (r) break; SQLSMALLINT cols = 0; r = SQLNumResultCols(stmt, &cols); CHK_RESULT(r, SQL_HANDLE_STMT, stmt, ""); if (r) break; if (cols <= 0) break; char buf[4096]; while (1) { SQLRETURN r = SQLFetch(stmt); if (r==SQL_NO_DATA) break; CHK_RESULT(r, SQL_HANDLE_STMT, stmt, ""); for (size_t i=0; i0) fprintf(stdout, "\n"); return r; } } if (soi==SQL_NULL_DATA) { fprintf(stdout, "%snull", i==0?"":","); } else { fprintf(stdout, "%s\"%s\"", i==0?"":",", buf); } } fprintf(stdout, "\n"); } // r = SQLFetch(stmt); // if (r==SQL_NO_DATA) { // D(".........."); // r = SQL_SUCCESS; // break; // } // CHK_RESULT(r, SQL_HANDLE_STMT, stmt, ""); // if (r) break; // r = SQLPrepare(stmt, (SQLCHAR*)statement, strlen(statement)); // CHK_RESULT(r, SQL_HANDLE_STMT, stmt, ""); // if (r) break; // r = SQLExecute(stmt); // CHK_RESULT(r, SQL_HANDLE_STMT, stmt, "statement: %s", statement); // if (r) break; } while (0); return r; } static int do_insert(SQLHSTMT stmt, data_t data) { SQLRETURN r = 0; SQLLEN lbin; SQLLEN lblob; const char *statement = "insert into t values (?, ?, ?, ?, ?, ?, ?, ?, ?,?)"; #define ignored 0 do { r = SQLPrepare(stmt, (SQLCHAR*)statement, (SQLINTEGER)strlen(statement)); CHK_RESULT(r, SQL_HANDLE_STMT, stmt, "statement: %s", statement); if (r) break; r = SQLBindParameter(stmt, 1, SQL_PARAM_INPUT, SQL_C_SBIGINT, SQL_TIMESTAMP, ignored, ignored, &data.ts, ignored, NULL); CHK_RESULT(r, SQL_HANDLE_STMT, stmt, "statement: %s", statement); if (r) break; r = SQLBindParameter(stmt, 2, SQL_PARAM_INPUT, SQL_C_BIT, SQL_BIT, ignored, ignored, &data.b, ignored, NULL); CHK_RESULT(r, SQL_HANDLE_STMT, stmt, "statement: %s", statement); if (r) break; r = SQLBindParameter(stmt, 3, SQL_PARAM_INPUT, SQL_C_TINYINT, SQL_TINYINT, ignored, ignored, &data.v1, ignored, NULL); CHK_RESULT(r, SQL_HANDLE_STMT, stmt, "statement: %s", statement); if (r) break; r = SQLBindParameter(stmt, 4, SQL_PARAM_INPUT, SQL_C_SHORT, SQL_SMALLINT, ignored, ignored, &data.v2, ignored, NULL); CHK_RESULT(r, SQL_HANDLE_STMT, stmt, "statement: %s", statement); if (r) break; r = SQLBindParameter(stmt, 5, SQL_PARAM_INPUT, SQL_C_LONG, SQL_INTEGER, ignored, ignored, &data.v4, ignored, NULL); CHK_RESULT(r, SQL_HANDLE_STMT, stmt, "statement: %s", statement); if (r) break; r = SQLBindParameter(stmt, 6, SQL_PARAM_INPUT, SQL_C_SBIGINT, SQL_BIGINT, ignored, ignored, &data.v8, ignored, NULL); CHK_RESULT(r, SQL_HANDLE_STMT, stmt, "statement: %s", statement); if (r) break; r = SQLBindParameter(stmt, 7, SQL_PARAM_INPUT, SQL_C_FLOAT, SQL_FLOAT, ignored, ignored, &data.f4, ignored, NULL); CHK_RESULT(r, SQL_HANDLE_STMT, stmt, "statement: %s", statement); if (r) break; r = SQLBindParameter(stmt, 8, SQL_PARAM_INPUT, SQL_C_DOUBLE, SQL_DOUBLE, ignored, ignored, &data.f8, ignored, NULL); CHK_RESULT(r, SQL_HANDLE_STMT, stmt, "statement: %s", statement); if (r) break; lbin = SQL_NTS; r = SQLBindParameter(stmt, 9, SQL_PARAM_INPUT, SQL_C_BINARY, SQL_VARBINARY, sizeof(data.bin)-1, ignored, &data.bin, ignored, &lbin); CHK_RESULT(r, SQL_HANDLE_STMT, stmt, "statement: %s", statement); if (r) break; lblob = SQL_NTS; r = SQLBindParameter(stmt, 10, SQL_PARAM_INPUT, SQL_C_CHAR, SQL_VARCHAR, sizeof(data.blob)-1, ignored, &data.blob, ignored, &lblob); CHK_RESULT(r, SQL_HANDLE_STMT, stmt, "statement: %s", statement); if (r) break; r = SQLExecute(stmt); CHK_RESULT(r, SQL_HANDLE_STMT, stmt, "statement: %s", statement); if (r) break; // ts += 1; // v = 2; // r = SQLExecute(stmt); // if (r) break; } while (0); #undef ignored return r; } static int test1(const char *dsn, const char *uid, const char *pwd) { SQLHENV env = {0}; SQLHDBC conn = {0}; int n = open_connect(dsn, uid, pwd, &env, &conn); if (n) return 1; int ok = 0; do { SQLRETURN r = SQL_SUCCESS; SQLHSTMT stmt = {0}; r = SQLAllocHandle(SQL_HANDLE_STMT, conn, &stmt); if (r!=SQL_SUCCESS) break; do { if (do_statement(stmt, "drop database if exists db")) { break; } for (size_t i=0; i1) ? argv[1] : NULL; const char *uid = (argc>2) ? argv[2] : NULL; const char *pwd = (argc>3) ? argv[3] : NULL; const char *connstr = (argc>4) ? argv[4] : NULL; const char *sqls = (argc>5) ? argv[5] : NULL; if (1) { CHK_TEST(test_env()); CHK_TEST(test1(dsn, uid, pwd)); const char *statements[] = { "drop database if exists m", "create database m", "use m", "drop database m", NULL }; CHK_TEST(test_statements(dsn, uid, pwd, statements)); if (connstr) CHK_TEST(test_driver_connect(connstr)); if (connstr) { SQLHENV env = {0}; SQLHDBC conn = {0}; CHK_TEST(open_driver_connect(connstr, &env, &conn)); int r = tests(env, conn); SQLDisconnect(conn); SQLFreeConnect(conn); SQLFreeEnv(env); if (r) return 1; } } if ((dsn || connstr) && 1) { CHK_TEST(test_sqls(dsn, uid, pwd, connstr, sqls)); } return 0; }