Add a new test case to test ODBC functions deprecated in ODBC 3.0
authorHeikki Linnakangas <heikki.linnakangas@iki.fi>
Thu, 20 Mar 2014 08:19:27 +0000 (09:19 +0100)
committerHeikki Linnakangas <heikki.linnakangas@iki.fi>
Thu, 20 Mar 2014 08:19:27 +0000 (09:19 +0100)
Michael Paquier

Makefile.am
test/Makefile.in
test/expected/deprecated.out [new file with mode: 0644]
test/src/common.c
test/src/deprecated-test.c [new file with mode: 0644]

index c67afca4a1c0e558d345f0451c5c2bb1c233fc56..270f49ec766d8a46fd223c0d5ef204b3492cc93a 100644 (file)
@@ -98,6 +98,7 @@ EXTRA_DIST = license.txt readme.txt readme_winbuild.txt \
    test/expected/cursors_1.out \
    test/expected/cvtnulldate.out \
    test/expected/dataatexecution.out \
+   test/expected/deprecated.out \
    test/expected/getresult.out \
    test/expected/insertreturning.out \
    test/expected/lfconversion.out \
@@ -129,6 +130,7 @@ EXTRA_DIST = license.txt readme.txt readme_winbuild.txt \
    test/src/cursors-test.c \
    test/src/cvtnulldate-test.c \
    test/src/dataatexecution-test.c \
+   test/src/deprecated-test.c \
    test/src/getresult-test.c \
    test/src/insertreturning-test.c \
    test/src/lfconversion-test.c \
index c9b82e8d357621b536b12ce046b083bf8d705de8..cb4ed02737ce499afa4c0efe069813f66d443871 100644 (file)
@@ -1,7 +1,7 @@
 TESTS = connect stmthandles select commands multistmt getresult prepare \
    params notice arraybinding insertreturning dataatexecution \
    boolsaschar cvtnulldate alter quotes cursors positioned-update \
-   catalogfunctions bindcol lfconversion cte
+   catalogfunctions bindcol lfconversion cte deprecated
 
 TESTBINS = $(patsubst %,src/%-test, $(TESTS))
 TESTSQLS = $(patsubst %,sql/%.sql, $(TESTS))
diff --git a/test/expected/deprecated.out b/test/expected/deprecated.out
new file mode 100644 (file)
index 0000000..7e31d76
--- /dev/null
@@ -0,0 +1,29 @@
+\! ./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 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 SQLFreeStmt
+Check for SQLFreeConnect
+Check for SQLFreeEnv
+connected
+Check for SQLTransact
+Result set:
+disconnecting
index 091dd1a8acb96eb2c139b35d479436423c387f10..904b10d9aa09f6fd104f3d3c0a5314ec49c1d3d3 100644 (file)
@@ -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 (file)
index 0000000..2fa7e0c
--- /dev/null
@@ -0,0 +1,326 @@
+/*
+ * Tests for deprecated functions.
+ */
+
+#include <string.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+#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);
+
+   /*
+    * 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;
+       }
+   }
+
+   /*
+    * SQLFreeStmt(SQL_DROP) -> SQLFreeHandle
+    *
+    * Free the statement handle used. SQL_DROP is deprecated, other
+    * options are not.
+    */
+   printf("Check for SQLFreeStmt\n");
+   rc = SQLFreeStmt(hstmt, SQL_DROP);
+   CHECK_STMT_RESULT(rc, "SQLFreeStmt with SQL_DROP 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();
+}