Add a test case cursor-block-delete which deletes all the tuples using SQLFetchScroll...
authorHiroshi Inoue <h-inoue@dream.email.ne.jp>
Sun, 1 May 2016 10:54:58 +0000 (19:54 +0900)
committerHiroshi Inoue <h-inoue@dream.email.ne.jp>
Mon, 2 May 2016 11:21:54 +0000 (20:21 +0900)
test/expected/cursor-block-delete.out [new file with mode: 0755]
test/src/cursor-block-delete-test.c [new file with mode: 0644]
test/tests

diff --git a/test/expected/cursor-block-delete.out b/test/expected/cursor-block-delete.out
new file mode 100755 (executable)
index 0000000..b9cd76d
--- /dev/null
@@ -0,0 +1,53 @@
+connected
+   orientation=2 delete count=0
+   orientation=4 delete count=30
+   orientation=1 delete count=53
+   orientation=4 delete count=70
+   orientation=1 delete count=83
+   orientation=4 delete count=93
+   orientation=1 delete count=100
+   orientation=4 delete count=105
+   orientation=1 delete count=109
+   orientation=4 delete count=112
+   orientation=1 delete count=114
+   orientation=4 delete count=116
+   orientation=1 delete count=117
+   orientation=4 delete count=118
+   orientation=1 delete count=119
+   orientation=4 delete count=120
+delete all count 120
+   orientation=2 delete count=0
+   orientation=4 delete count=32
+   orientation=1 delete count=56
+   orientation=4 delete count=74
+   orientation=1 delete count=88
+   orientation=4 delete count=98
+   orientation=1 delete count=106
+   orientation=4 delete count=112
+   orientation=1 delete count=116
+   orientation=4 delete count=119
+   orientation=1 delete count=122
+   orientation=4 delete count=124
+   orientation=1 delete count=125
+   orientation=4 delete count=126
+   orientation=1 delete count=127
+   orientation=4 delete count=128
+delete all count 128
+   orientation=2 delete count=0
+   orientation=4 delete count=31
+   orientation=1 delete count=55
+   orientation=4 delete count=73
+   orientation=1 delete count=86
+   orientation=4 delete count=96
+   orientation=1 delete count=103
+   orientation=4 delete count=109
+   orientation=1 delete count=113
+   orientation=4 delete count=116
+   orientation=1 delete count=118
+   orientation=4 delete count=120
+   orientation=1 delete count=121
+   orientation=4 delete count=122
+   orientation=1 delete count=123
+   orientation=4 delete count=124
+delete all count 124
+disconnecting
diff --git a/test/src/cursor-block-delete-test.c b/test/src/cursor-block-delete-test.c
new file mode 100644 (file)
index 0000000..6374d4f
--- /dev/null
@@ -0,0 +1,149 @@
+/*
+ * Test deleting tuples all with scrolling block cursors BOF ->
+ * EOF -> BOF -> ...
+ */
+
+#include <string.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+#include "common.h"
+
+#define    TOTAL   120
+#define    BLOCK   4
+
+static SQLRETURN delete_loop(HSTMT hstmt)
+{
+   SQLRETURN   rc;
+   BOOL    use_first_last = 0;
+   int delcnt = 0, delsav;
+   SQLSMALLINT orientation = SQL_FETCH_FIRST;
+   
+   do {
+       printf("\torientation=%d delete count=%d\n", orientation, delcnt);
+       delsav = delcnt;
+       if (use_first_last)
+           orientation = (orientation == SQL_FETCH_NEXT ? SQL_FETCH_FIRST : SQL_FETCH_LAST);
+       while (rc = SQLFetchScroll(hstmt, orientation, 0), SQL_SUCCEEDED(rc))
+       {
+           orientation = (orientation == SQL_FETCH_NEXT ? SQL_FETCH_NEXT : (orientation == SQL_FETCH_FIRST ? SQL_FETCH_NEXT : SQL_FETCH_PRIOR));
+           rc = SQLSetPos(hstmt, 1, SQL_DELETE, SQL_LCK_NO_CHANGE);
+           CHECK_STMT_RESULT(rc, "SQLSetPos delete failed", hstmt);
+           delcnt++;
+       }
+       if (SQL_NO_DATA != rc)
+       {
+           CHECK_STMT_RESULT(rc, "SQLFetchScroll failed", hstmt);
+       }
+       orientation = (orientation == SQL_FETCH_NEXT ? SQL_FETCH_PRIOR : SQL_FETCH_NEXT);
+   } while (delcnt != delsav);
+   printf("delete all count %d\n", delcnt);
+
+   return  SQL_SUCCESS;
+}
+
+int main(int argc, char **argv)
+{
+   int     rc;
+   HSTMT       hstmt = SQL_NULL_HSTMT, hstmt2 = SQL_NULL_HSTMT;
+   int     i, j, k;
+   int     count = TOTAL;  
+   char        query[100];
+   SQLLEN      rowArraySize = BLOCK;
+   SQLULEN     rowsFetched;
+   SQLINTEGER  id[BLOCK];
+   SQLLEN      cbLen[BLOCK];
+
+   /****
+     * Run this test with UseDeclareFetch = 1 and Fetch=37.
+     */
+   test_connect_ext("UseDeclareFetch=1");
+
+   rc = SQLAllocHandle(SQL_HANDLE_STMT, conn, &hstmt);
+   if (!SQL_SUCCEEDED(rc))
+   {
+       print_diag("failed to allocate stmt handle", SQL_HANDLE_DBC, conn);
+       exit(1);
+   }
+   rc = SQLAllocHandle(SQL_HANDLE_STMT, conn, &hstmt2);
+   if (!SQL_SUCCEEDED(rc))
+   {
+       print_diag("failed to allocate stmt handle2", SQL_HANDLE_DBC, conn);
+       exit(1);
+   }
+
+   rc = SQLExecDirect(hstmt, (SQLCHAR *) "create temporary table tmptable(id int4 primary key)", SQL_NTS);
+   CHECK_STMT_RESULT(rc, "SQLExecDirect create table failed", hstmt);
+
+   /* insert into a table */
+   for (i = 0; i < count; i++)
+   {
+       snprintf(query, sizeof(query), "insert into tmptable values (%d)", i);
+       rc = SQLExecDirect(hstmt, (SQLCHAR *) query, SQL_NTS);
+       CHECK_STMT_RESULT(rc, "insert into table failed", hstmt);
+   }
+   rc = SQLFreeStmt(hstmt, SQL_CLOSE);
+   CHECK_STMT_RESULT(rc, "SQLFreeStmt failed", hstmt);
+
+   /*
+    * Block cursor
+    */
+   rc = SQLSetStmtAttr(hstmt, SQL_ATTR_ROWS_FETCHED_PTR, (SQLPOINTER) &rowsFetched, 0);
+   CHECK_STMT_RESULT(rc, "SQLSetStmtAttr ROWS_FETCHED_PTR failed", hstmt);
+   rc = SQLBindCol(hstmt, 1, SQL_C_SLONG, &id, 0, cbLen);
+   CHECK_STMT_RESULT(rc, "SQLBindCol failed", hstmt);
+   rc = SQLSetStmtAttr(hstmt, SQL_ATTR_ROW_ARRAY_SIZE, (SQLPOINTER) rowArraySize, SQL_IS_UINTEGER);
+   CHECK_STMT_RESULT(rc, "SQLSetStmtAttr ROW_ARRAY_SIZE failed", hstmt);
+   rc = SQLSetStmtAttr(hstmt, SQL_ATTR_CONCURRENCY, (SQLPOINTER) SQL_CONCUR_ROWVER, 0);
+   CHECK_STMT_RESULT(rc, "SQLSetStmtAttr CONCURRENCY failed", hstmt);
+   rc = SQLSetConnectAttr(conn, SQL_AUTOCOMMIT, (SQLPOINTER) SQL_AUTOCOMMIT_OFF, 0);
+   
+   rc = SQLSetStmtAttr(hstmt, SQL_ATTR_CURSOR_TYPE, (SQLPOINTER) SQL_CURSOR_STATIC, 0);
+   CHECK_STMT_RESULT(rc, "SQLSetStmtAttr CURSOR_TYPE failed", hstmt);
+   rc = SQLExecDirect(hstmt, (SQLCHAR *) "select * from tmptable", SQL_NTS);
+   CHECK_STMT_RESULT(rc, "select failed", hstmt);
+   rc = SQLExecDirect(hstmt2, (SQLCHAR *) "savepoint yuuki", SQL_NTS);
+   CHECK_STMT_RESULT(rc, "savepoint failed", hstmt2);
+   /*
+    * Scroll next -> EOF -> prior -> BOF -> next -> EOF ->
+    * ......
+    */
+   delete_loop(hstmt); /* the 1st loop */
+
+   rc = SQLExecDirect(hstmt2, (SQLCHAR *) "rollback to yuuki", SQL_NTS);
+   CHECK_STMT_RESULT(rc, "rollback failed", hstmt2);
+   for (i = 0, j = count, i = 0; i < 2; i++)
+   {
+       for (k = 0; k < rowArraySize; k++)
+       {
+           cbLen[k] = 0;
+           id[k] = j++;
+       }
+       /* rc = SQLBulkOperations(hstmt, SQL_ADD);
+       CHECK_STMT_RESULT(rc, "SQLBulkOperations SQL_ADD failed", hstmt); */
+       rc = SQLSetPos(hstmt, 0, SQL_ADD, SQL_LCK_NO_CHANGE);
+       CHECK_STMT_RESULT(rc, "SQLSetPos SQL_ADD failed", hstmt);
+       if (0 == i)
+       {
+           rc = SQLExecDirect(hstmt2, (SQLCHAR *) "savepoint yuuki", SQL_NTS);
+           CHECK_STMT_RESULT(rc, "savpoint failed", hstmt2);
+       }
+   }   
+   
+   delete_loop(hstmt); /* the 2nd loop */
+
+   rc = SQLExecDirect(hstmt2, (SQLCHAR *) "rollback to yuuki", SQL_NTS);
+   CHECK_STMT_RESULT(rc, "rollback failed", hstmt2);
+
+   delete_loop(hstmt); /* the 3rd loop */
+
+   rc = SQLEndTran(SQL_HANDLE_DBC, conn, SQL_ROLLBACK);
+   CHECK_STMT_RESULT(rc, "SQLEndTran failed", hstmt);
+   rc = SQLFreeStmt(hstmt, SQL_CLOSE);
+   CHECK_STMT_RESULT(rc, "SQLFreeStmt failed", hstmt);
+   
+   /* Clean up */
+   test_disconnect();
+
+   return 0;
+}
index a699d5dc2b2eb6588fdc11c86b316498f751684f..d5b2fdfd8612b99fe07fb1b86f330b09d08ac120 100644 (file)
@@ -34,6 +34,7 @@ TESTBINS = src/connect-test \
    src/cursor-movement-test \
    src/cursor-commit-test \
    src/cursor-name-test \
+   src/cursor-block-delete-test \
    src/bookmark-test \
    src/declare-fetch-commit-test \
    src/declare-fetch-block-test \