diff --git a/test/expected/deprecated.out b/test/expected/deprecated.out new file mode 100644 index 0000000..191101d --- /dev/null +++ b/test/expected/deprecated.out @@ -0,0 +1,32 @@ +\! ./src/deprecated-test +Check for SQLAllocEnv +Check for SQLAllocConnect +Check for SQLAllocStmt +Check for SQLSetConnectOption +Check for SQLError +Error check: ERROR: relation "table_not_here" does not exist; +Error while executing the query +Check for SQLFreeStmt +Check for SQLBindParam +Result set: +bar +Check for SQLSetParam +Result set: +100 +Check for SQLGetStmtOption +Cursor type is: forward +Check for SQLSetStmtOption +Cursor type is: static +Check for SQLSetScrollOptions +Cursor type is: forward +Check for SQLColAttributes +Column 1: foo +Column 2: bar +Check for SQLParamOptions +Status of execution +Check for SQLFreeConnect +Check for SQLFreeEnv +connected +Check for SQLTransact +Result set: +disconnecting diff --git a/test/src/common.c b/test/src/common.c index 091dd1a..904b10d 100644 --- a/test/src/common.c +++ b/test/src/common.c @@ -68,7 +68,7 @@ test_disconnect(void) exit(1); } - rc = SQLFreeConnect(conn); + rc = SQLFreeHandle(SQL_HANDLE_DBC, conn); if (!SQL_SUCCEEDED(rc)) { print_diag("SQLFreeConnect failed", SQL_HANDLE_DBC, conn); @@ -76,7 +76,7 @@ test_disconnect(void) } conn = NULL; - rc = SQLFreeEnv(env); + rc = SQLFreeHandle(SQL_HANDLE_ENV, env); if (!SQL_SUCCEEDED(rc)) { print_diag("SQLFreeEnv failed", SQL_HANDLE_ENV, env); diff --git a/test/src/deprecated-test.c b/test/src/deprecated-test.c new file mode 100644 index 0000000..a960b57 --- /dev/null +++ b/test/src/deprecated-test.c @@ -0,0 +1,347 @@ +/* + * Tests for deprecated functions. + */ + +#include +#include +#include + +#include "common.h" + +void +print_cursor_type(SQLINTEGER cursor_type) +{ + printf( "Cursor type is: " ) ; + if (cursor_type == SQL_CURSOR_FORWARD_ONLY) + printf("forward\n"); + else if (cursor_type == SQL_CURSOR_STATIC) + printf("static\n"); + else if (cursor_type == SQL_SCROLL_DYNAMIC) + printf("dynamic\n"); + else + { + printf("Incorrect type of cursor\n"); + exit(1); + } +} + +/* Array size for SQLParamOptions test */ +#define ARRAY_SIZE 10 + +int +main(int argc, char **argv) +{ + SQLRETURN rc; + HSTMT hstmt = SQL_NULL_HSTMT; + SQLHDBC conn2; + SQLHENV env2; + SQLSMALLINT val; + SQLINTEGER valint; + SQLLEN paramlen; + char buffer[256]; + char message[1000]; + int i; + + /* Parameters for SQLParamOptions */ + SQLULEN nprocessed; + SQLLEN int_ind_array[ARRAY_SIZE]; + SQLLEN str_ind_array[ARRAY_SIZE]; + SQLUSMALLINT status_array[ARRAY_SIZE]; + SQLUINTEGER int_array[ARRAY_SIZE]; + SQLCHAR str_array[ARRAY_SIZE][30]; + + /* + * SQLAllocConnect -> SQLAllocHandle + * SQLAllocEnv -> SQLAllocHandle + * Get a connection. + */ + printf("Check for SQLAllocEnv\n"); + rc = SQLAllocEnv(&env2); + if (!SQL_SUCCEEDED(rc)) + { + print_diag("SQLAllocEnv failed", SQL_HANDLE_ENV, env2); + exit(1); + } + SQLSetEnvAttr(env2, SQL_ATTR_ODBC_VERSION, (void *) SQL_OV_ODBC3, 0); + printf("Check for SQLAllocConnect\n"); + rc = SQLAllocConnect(env2, &conn2); + if (!SQL_SUCCEEDED(rc)) + { + print_diag("SQLAllocConnect failed", SQL_HANDLE_DBC, conn2); + exit(1); + } + + rc = SQLDriverConnect(conn2, NULL, "DSN=psqlodbc_test_dsn;", SQL_NTS, + NULL, 0, &val, + SQL_DRIVER_COMPLETE); + if (!SQL_SUCCEEDED(rc)) + { + print_diag("SQLDriverConnect failed", SQL_HANDLE_DBC, conn2); + exit(1); + } + + /* + * SQLAllocStmt -> SQLAllocHandle + * Allocate a statement handle. + */ + printf("Check for SQLAllocStmt\n"); + rc = SQLAllocStmt(conn2, &hstmt); + if (!SQL_SUCCEEDED(rc)) + { + print_diag("SQLAllocStmt failed", SQL_HANDLE_DBC, conn2); + exit(1); + } + + /* + * SQLGetConnectOption -> SQLGetConnectAttr + * Test connection attribute. + */ + printf("Check for SQLSetConnectOption\n"); + rc = SQLSetConnectOption(conn2, + SQL_ATTR_ACCESS_MODE, + SQL_MODE_READ_WRITE); + CHECK_STMT_RESULT(rc, "SQLSetConnectOption failed", hstmt); + + /* + * SQLError -> SQLGetDiagRec + * Trigger an error. + */ + printf("Check for SQLError\n"); + rc = SQLExecDirect(hstmt, + (SQLCHAR *) "INSERT INTO table_not_here VALUES (1)", + SQL_NTS); + rc = SQLError(env2, conn2, hstmt, buffer, &valint, + message, 256, &val); + CHECK_STMT_RESULT(rc, "SQLError failed", hstmt); + printf("Error check: %s\n", (CHAR *)message); + + /* + * SQLFreeStmt -> SQLFreeHandle + * Free the statement handle used. + */ + printf("Check for SQLFreeStmt\n"); + rc = SQLFreeStmt(hstmt, SQL_CLOSE); + CHECK_STMT_RESULT(rc, "SQLFreeStmt failed", hstmt); + + /* + * SQLBindParam[1] -> SQLBindParameter + * Test for bind parameter. + */ + printf("Check for SQLBindParam\n"); + paramlen = SQL_NTS; + strcpy(buffer, "bar"); + rc = SQLBindParam(hstmt, 1, + SQL_C_CHAR, + SQL_CHAR, + 20, + 0, + buffer, + ¶mlen); + CHECK_STMT_RESULT(rc, "SQLBindParam failed", hstmt); + rc = SQLExecDirect(hstmt, (SQLCHAR *) "SELECT ?::text AS foo", SQL_NTS); + CHECK_STMT_RESULT(rc, "SQLExecDirect failed", hstmt); + print_result(hstmt); + rc = SQLFreeStmt(hstmt, SQL_CLOSE); + CHECK_STMT_RESULT(rc, "SQLFreeStmt failed", hstmt); + + /* + * SQLSetParam[2] -> SQLBindParameter + * Test for set parameter, somewhat similar to last example. + */ + printf("Check for SQLSetParam\n"); + val = 100; + SQLSetParam(hstmt, 1, SQL_C_SHORT, SQL_SMALLINT, 0, 0, + &val, NULL); + CHECK_STMT_RESULT(rc, "SQLSetParam failed", hstmt); + rc = SQLExecDirect(hstmt, (SQLCHAR *) "SELECT ?::int AS foo", SQL_NTS); + CHECK_STMT_RESULT(rc, "SQLExecDirect failed", hstmt); + print_result(hstmt); + rc = SQLFreeStmt(hstmt, SQL_CLOSE); + CHECK_STMT_RESULT(rc, "SQLFreeStmt failed", hstmt); + + /* + * SQLGetStmtOption -> SQLGetStmtAttr + * SQLSetStmtOption -> SQLSetStmtAttr + * SQLSetScrollOptions -> SQLSetStmtAttr + * Test for statement and cursor options. + */ + + /* Pointer should be forward-only here */ + printf("Check for SQLGetStmtOption\n"); + rc = SQLGetStmtOption(hstmt, SQL_ATTR_CURSOR_TYPE, &valint); + CHECK_STMT_RESULT(rc, "SQLGetStmtOption failed", hstmt); + print_cursor_type(valint); + + /* Change it to static and check its new value */ + printf("Check for SQLSetStmtOption\n"); + rc = SQLSetStmtOption(hstmt, SQL_ATTR_CURSOR_TYPE, SQL_CURSOR_STATIC); + CHECK_STMT_RESULT(rc, "SQLSetStmtOption failed", hstmt); + rc = SQLGetStmtOption(hstmt, SQL_ATTR_CURSOR_TYPE, &valint); + CHECK_STMT_RESULT(rc, "SQLGetStmtOption failed", hstmt); + print_cursor_type(valint); + rc = SQLFreeStmt(hstmt, SQL_CLOSE); + CHECK_STMT_RESULT(rc, "SQLFreeStmt failed", hstmt); + + /* Change it now to dynamic using another function */ + printf("Check for SQLSetScrollOptions\n"); + rc = SQLSetScrollOptions(hstmt, SQL_CONCUR_READ_ONLY, + SQL_SCROLL_FORWARD_ONLY, 1); + CHECK_STMT_RESULT(rc, "SQLSetScrollOptions failed", hstmt); + rc = SQLGetStmtOption(hstmt, SQL_ATTR_CURSOR_TYPE, &valint); + CHECK_STMT_RESULT(rc, "SQLGetStmtOption failed", hstmt); + print_cursor_type(valint); + rc = SQLFreeStmt(hstmt, SQL_CLOSE); + CHECK_STMT_RESULT(rc, "SQLFreeStmt failed", hstmt); + + /* + * SQLColAttributes -> SQLColAttribute + * Test for column attributes. Return column attributes of + * a simple query. + */ + printf("Check for SQLColAttributes\n"); + rc = SQLExecDirect(hstmt, + (SQLCHAR *) "SELECT '1'::int AS foo, 'foobar'::text AS bar", + SQL_NTS); + CHECK_STMT_RESULT(rc, "SQLExecDirect failed", hstmt); + for (i = 0 ; i < 2; i++) + { + char buffer[64]; + rc = SQLColAttribute(hstmt, (SQLUSMALLINT) i + 1, + SQL_DESC_LABEL, buffer, 64, NULL, NULL); + CHECK_STMT_RESULT(rc, "SQLColAttribute failed", hstmt); + printf("Column %d: %s\n", i + 1, buffer); + } + rc = SQLFreeStmt(hstmt, SQL_CLOSE); + CHECK_STMT_RESULT(rc, "SQLFreeStmt failed", hstmt); + + /* + * SQLParamOptions -> SQLSetStmtAttr + * Test for parameter options. SQLParamOptions is mapped using + * SQL_ATTR_PARAMS_PROCESSED_PTR and SQL_ATTR_PARAMSET_SIZE. Here + * we insert a set of values in a temporary table. + */ + + /* Fill in array values */ + for (i = 0; i < ARRAY_SIZE; i++) + { + int_array[i] = i; + int_ind_array[i] = 0; + sprintf(str_array[i], "column num %d", i); + str_ind_array[i] = SQL_NTS; + } + printf("Check for SQLParamOptions\n"); + rc = SQLExecDirect(hstmt, + (SQLCHAR *) "CREATE TEMPORARY TABLE tmptable (i int4, t text)", + SQL_NTS); + CHECK_STMT_RESULT(rc, "SQLExecDirect failed for table creation", hstmt); + + rc = SQLParamOptions(hstmt, (SQLULEN) ARRAY_SIZE, &nprocessed); + CHECK_STMT_RESULT(rc, "SQLParamOptions failed", hstmt); + + /* Set some extra parameters */ + SQLSetStmtAttr(hstmt, SQL_ATTR_PARAM_BIND_TYPE, SQL_PARAM_BIND_BY_COLUMN, 0); + SQLSetStmtAttr(hstmt, SQL_ATTR_PARAM_STATUS_PTR, status_array, 0); + + /* Bind the parameter arrays. */ + SQLBindParameter(hstmt, 1, SQL_PARAM_INPUT, SQL_C_ULONG, SQL_INTEGER, 5, 0, + int_array, 0, int_ind_array); + SQLBindParameter(hstmt, 2, SQL_PARAM_INPUT, SQL_C_CHAR, SQL_CHAR, 29, 0, + str_array, 30, str_ind_array); + + /* Execute and fetch statuses */ + rc = SQLExecDirect(hstmt, + (SQLCHAR *) "INSERT INTO tmptable VALUES (?, ?)", + SQL_NTS); + CHECK_STMT_RESULT(rc, "SQLExecDirect failed", hstmt); + printf("Status of execution\n"); + for (i = 0; i < nprocessed; i++) + { + switch (status_array[i]) + { + case SQL_PARAM_SUCCESS: + case SQL_PARAM_SUCCESS_WITH_INFO: + break; + + case SQL_PARAM_ERROR: + printf("%d\tError\n", i); + break; + + case SQL_PARAM_UNUSED: + printf("%d\tUnused\n", i); + break; + + case SQL_PARAM_DIAG_UNAVAILABLE: + printf("%d\tDiag unavailable\n", i); + break; + } + } + rc = SQLFreeStmt(hstmt, SQL_CLOSE); + CHECK_STMT_RESULT(rc, "SQLFreeStmt failed", hstmt); + + /* + * SQLFreeConnect -> SQLFreeHandle + * SQLFreeEnv -> SQLFreeHandle + * Disconnect and free connection. + */ + rc = SQLDisconnect(conn2); + if (!SQL_SUCCEEDED(rc)) + { + print_diag("SQLDisconnect failed", SQL_HANDLE_DBC, conn2); + exit(1); + } + printf("Check for SQLFreeConnect\n"); + rc = SQLFreeConnect(conn2); + if (!SQL_SUCCEEDED(rc)) + { + print_diag("SQLFreeConnect failed", SQL_HANDLE_DBC, conn2); + exit(1); + } + printf("Check for SQLFreeEnv\n"); + rc = SQLFreeEnv(env2); + if (!SQL_SUCCEEDED(rc)) + { + print_diag("SQLFreeEnv failed", SQL_HANDLE_ENV, env2); + exit(1); + } + + /* Grab new connection and handle for the next tests */ + test_connect(); + rc = SQLAllocStmt(conn, &hstmt); + if (!SQL_SUCCEEDED(rc)) + { + print_diag("failed to allocate stmt handle", SQL_HANDLE_DBC, conn); + exit(1); + } + + /* + * SQLTransact -> SQLEndTran + * Check transaction ROLLBACK using SQLTransact. + */ + printf("Check for SQLTransact\n"); + + /* First disable autocommit */ + rc = SQLSetConnectAttr(conn, + SQL_ATTR_AUTOCOMMIT, + (SQLPOINTER)SQL_AUTOCOMMIT_OFF, + SQL_IS_UINTEGER); + + /* Insert a row and rollback it */ + rc = SQLExecDirect(hstmt, + (SQLCHAR *) "INSERT INTO testtab1 VALUES (200, 'foo')", + SQL_NTS); + CHECK_STMT_RESULT(rc, "SQLExecDirect failed", hstmt); + rc = SQLTransact(SQL_NULL_HENV, conn, SQL_ROLLBACK); + CHECK_STMT_RESULT(rc, "SQLTransact failed", hstmt); + + /* Now check that the row is not inserted */ + rc = SQLExecDirect(hstmt, + (SQLCHAR *) "SELECT t FROM testtab1 WHERE id = 200", + SQL_NTS); + CHECK_STMT_RESULT(rc, "SQLExecDirect failed", hstmt); + print_result(hstmt); + rc = SQLFreeStmt(hstmt, SQL_CLOSE); + CHECK_STMT_RESULT(rc, "SQLFreeStmt failed", hstmt); + + /* Clean up */ + test_disconnect(); +}