Line data Source code
1 : #include "common.h"
2 : #include <freetds/bool.h>
3 :
4 : static int
5 16 : Test(bool discard_test)
6 : {
7 16 : ODBC_BUF *odbc_buf = NULL;
8 : SQLINTEGER out_buf;
9 : SQLLEN out_len;
10 : SQLLEN rows;
11 16 : int retcode = 0;
12 : SQLTCHAR buf[512];
13 : SQLTCHAR sqlstate[6];
14 :
15 16 : const char *createErrorProcedure = "CREATE PROCEDURE testerror AS\n"
16 : "SELECT value FROM TestTransaction\n" "SELECT value / (value-value) FROM TestTransaction\n";
17 :
18 : /* select after insert is required to test data discarding */
19 : char createProcedure[512];
20 :
21 16 : sprintf(createProcedure,
22 : "CREATE PROCEDURE testinsert @value INT AS\n"
23 : "INSERT INTO TestTransaction VALUES ( @value )\n%s", discard_test ? "SELECT * FROM TestTransaction\n" : "");
24 :
25 : /* create stored proc */
26 16 : odbc_command_with_result(odbc_stmt, "DROP PROCEDURE testinsert");
27 :
28 16 : odbc_command(createProcedure);
29 :
30 : /* create stored proc that generates an error */
31 16 : odbc_command_with_result(odbc_stmt, "DROP PROCEDURE testerror");
32 :
33 16 : odbc_command(createErrorProcedure);
34 :
35 : /* Start transaction */
36 16 : CHKSetConnectAttr(SQL_ATTR_AUTOCOMMIT, (void *) SQL_AUTOCOMMIT_OFF, 0, "S");
37 :
38 : /* Insert a value */
39 16 : odbc_command("EXEC testinsert 1");
40 :
41 : /* we should be able to read row count */
42 16 : CHKRowCount(&rows, "S");
43 :
44 : /* Commit transaction */
45 16 : CHKEndTran(SQL_HANDLE_DBC, odbc_conn, SQL_COMMIT, "S");
46 :
47 16 : SQLCloseCursor(odbc_stmt);
48 :
49 : /* Start transaction */
50 16 : CHKSetConnectAttr(SQL_ATTR_AUTOCOMMIT, (void *) SQL_AUTOCOMMIT_OFF, 0, "S");
51 :
52 : /* Insert another value */
53 16 : odbc_command("EXEC testinsert 2");
54 :
55 : /* Roll back transaction */
56 16 : CHKEndTran(SQL_HANDLE_DBC, odbc_conn, SQL_ROLLBACK, "S");
57 :
58 : /* TODO test row inserted */
59 :
60 16 : CHKSetConnectAttr(SQL_ATTR_AUTOCOMMIT, (void *) SQL_AUTOCOMMIT_ON, 0, "S");
61 :
62 : /* generate an error */
63 16 : odbc_command("EXEC testerror");
64 16 : CHKBindCol(1, SQL_C_SLONG, &out_buf, sizeof(out_buf), &out_len, "S");
65 :
66 56 : while (CHKFetch("SNo") == SQL_SUCCESS) {
67 24 : printf("\t%ld\n", (long int) out_buf);
68 24 : if (out_buf != 1) {
69 0 : fprintf(stderr, "error: expected to select 1 got %ld\n", (long int) out_buf);
70 0 : retcode = 1;
71 0 : goto cleanup;
72 : }
73 : }
74 :
75 16 : CHKMoreResults("E");
76 :
77 16 : CHKGetDiagRec(SQL_HANDLE_STMT, odbc_stmt, 1, sqlstate, NULL, buf, TDS_VECTOR_SIZE(buf), NULL, "SI");
78 16 : printf("err=%s\n", C(buf));
79 :
80 16 : CHKMoreResults("No");
81 :
82 16 : cleanup:
83 : /* drop table */
84 16 : odbc_command_with_result(odbc_stmt, "DROP PROCEDURE testinsert");
85 16 : odbc_command_with_result(odbc_stmt, "DROP PROCEDURE testerror");
86 :
87 16 : ODBC_FREE();
88 16 : return retcode;
89 : }
90 :
91 : int
92 8 : main(int argc, char *argv[])
93 : {
94 8 : int retcode = 0;
95 :
96 8 : odbc_connect();
97 :
98 : /* create table */
99 8 : odbc_command_with_result(odbc_stmt, "DROP TABLE TestTransaction");
100 8 : odbc_command("CREATE TABLE TestTransaction ( value INT )");
101 :
102 : if (!retcode)
103 8 : retcode = Test(true);
104 8 : if (!retcode)
105 8 : retcode = Test(false);
106 :
107 : /* drop table */
108 8 : odbc_command_with_result(odbc_stmt, "DROP TABLE TestTransaction");
109 :
110 8 : odbc_disconnect();
111 :
112 8 : printf("Done.\n");
113 : return retcode;
114 : }
|