NCBI C++ ToolKit
transaction2.c
Go to the documentation of this file.

Go to the SVN repository for this file.

1 #include "common.h"
2 
3 #include <common/test_assert.h>
4 
5 /* Test transaction types */
6 
7 static void
9 {
11  SQLTCHAR *err = (SQLTCHAR *) ODBC_GET(sizeof(odbc_err)*sizeof(SQLTCHAR));
12  SQLTCHAR *state = (SQLTCHAR *) ODBC_GET(sizeof(odbc_sqlstate)*sizeof(SQLTCHAR));
13 
14  memset(odbc_err, 0, sizeof(odbc_err));
15  memset(odbc_sqlstate, 0, sizeof(odbc_sqlstate));
16  CHKGetDiagRec(SQL_HANDLE_DBC, odbc_conn, 1, state, NULL, err, sizeof(odbc_err), NULL, "SI");
17  strcpy(odbc_err, C(err));
18  strcpy(odbc_sqlstate, C(state));
19  ODBC_FREE();
20  printf("Message: '%s' %s\n", odbc_sqlstate, odbc_err);
21 }
22 
23 static void
24 AutoCommit(int onoff)
25 {
27 }
28 
29 static void
31 {
33 }
34 
35 #define SWAP(t,a,b) do { t xyz = a; a = b; b = xyz; } while(0)
36 #define SWAP_CONN() do { SWAP(HENV,env,odbc_env); SWAP(HDBC,dbc,odbc_conn); SWAP(HSTMT,stmt,odbc_stmt);} while(0)
37 
41 
42 static int
44 {
45  SQLRETURN RetCode;
46 
47  /* transaction 1 try to change a row but not commit */
48  odbc_command("UPDATE test_transaction SET t = 'second' WHERE n = 1");
49 
50  SWAP_CONN();
51 
52  /* second transaction try to fetch uncommited row */
53  RetCode = odbc_command2("SELECT * FROM test_transaction WHERE t = 'second' AND n = 1", "SE");
54  if (RetCode == SQL_ERROR) {
56  SWAP_CONN();
58  return 0; /* no dirty read */
59  }
60 
61  CHKFetch("S");
62  CHKFetch("No");
65  SWAP_CONN();
67  return 1;
68 }
69 
70 static int
72 {
73  SQLRETURN RetCode;
74 
75  /* transaction 2 read a row */
76  SWAP_CONN();
77  odbc_command("SELECT * FROM test_transaction WHERE t = 'initial' AND n = 1");
79 
80  /* transaction 1 change a row and commit */
81  SWAP_CONN();
82  RetCode = odbc_command2("UPDATE test_transaction SET t = 'second' WHERE n = 1", "SE");
83  if (RetCode == SQL_ERROR) {
85  SWAP_CONN();
87  SWAP_CONN();
88  return 0; /* no dirty read */
89  }
91 
92  SWAP_CONN();
93 
94  /* second transaction try to fetch commited row */
95  odbc_command("SELECT * FROM test_transaction WHERE t = 'second' AND n = 1");
96 
97  CHKFetch("S");
98  CHKFetch("No");
101  SWAP_CONN();
102  odbc_command("UPDATE test_transaction SET t = 'initial' WHERE n = 1");
104  return 1;
105 }
106 
107 static int
109 {
110  SQLRETURN RetCode;
111 
112  /* transaction 2 read a row */
113  SWAP_CONN();
114  odbc_command("SELECT * FROM test_transaction WHERE t = 'initial'");
116 
117  /* transaction 1 insert a row that match critera */
118  SWAP_CONN();
119  RetCode = odbc_command2("INSERT INTO test_transaction(n, t) VALUES(2, 'initial')", "SE");
120  if (RetCode == SQL_ERROR) {
122  SWAP_CONN();
124  SWAP_CONN();
125  return 0; /* no dirty read */
126  }
128 
129  SWAP_CONN();
130 
131  /* second transaction try to fetch commited row */
132  odbc_command("SELECT * FROM test_transaction WHERE t = 'initial'");
133 
134  CHKFetch("S");
135  CHKFetch("S");
136  CHKFetch("No");
139  SWAP_CONN();
140  odbc_command("DELETE test_transaction WHERE n = 2");
142  return 1;
143 }
144 
145 static int test_with_connect = 0;
146 
147 static int global_txn;
148 
149 static int hide_error;
150 
151 static void
152 my_attrs(void)
153 {
156 }
157 
158 static void
160 {
161  global_txn = txn;
163  odbc_connect();
165 }
166 
167 static int
168 Test(int txn, const char *expected)
169 {
170  int dirty, repeatable, phantom;
171  char buf[128];
172 
173  SWAP_CONN();
174  if (test_with_connect) {
175  odbc_disconnect();
176  ConnectWithTxn(txn);
178  } else {
180  }
181  SWAP_CONN();
182 
183  dirty = CheckDirtyRead();
184  repeatable = CheckNonrepeatableRead();
185  phantom = CheckPhantom();
186 
187  sprintf(buf, "dirty %d non repeatable %d phantom %d", dirty, repeatable, phantom);
188  if (strcmp(buf, expected) != 0) {
189  if (hide_error) {
190  hide_error = 0;
191  return 0;
192  }
193  fprintf(stderr, "detected wrong TXN\nexpected '%s' got '%s'\n", expected, buf);
194  exit(1);
195  }
196  hide_error = 0;
197  return 1;
198 }
199 
200 int
201 main(int argc, char *argv[])
202 {
203  odbc_use_version3 = 1;
204  odbc_connect();
205 
206  /* Invalid argument value */
208  ReadErrorConn();
209  if (strcmp(odbc_sqlstate, "HY024") != 0) {
210  odbc_disconnect();
211  fprintf(stderr, "Unexpected success\n");
212  return 1;
213  }
214 
215  /* here we can't use temporary table cause we use two connection */
216  odbc_command("IF OBJECT_ID('test_transaction') IS NOT NULL DROP TABLE test_transaction");
217  odbc_command("CREATE TABLE test_transaction(n NUMERIC(18,0) PRIMARY KEY, t VARCHAR(30))");
218 
220 
222  odbc_command("INSERT INTO test_transaction(n, t) VALUES(1, 'initial')");
223 
224 #ifdef ENABLE_DEVELOPING
225  /* test setting with active transaction "Operation invalid at this time" */
227  ReadErrorConn();
228  if (strcmp(odbc_sqlstate, "HY011") != 0) {
229  odbc_disconnect();
230  fprintf(stderr, "Unexpected success\n");
231  return 1;
232  }
233 #endif
234 
236 
237  odbc_command("SELECT * FROM test_transaction");
238 
239  /* test setting with pending data */
241  ReadErrorConn();
242  if (strcmp(odbc_sqlstate, "HY011") != 0) {
243  odbc_disconnect();
244  fprintf(stderr, "Unexpected success\n");
245  return 1;
246  }
247 
249 
251 
252 
253  /* save this connection and do another */
254  SWAP_CONN();
255 
256  odbc_connect();
257 
260 
261  SWAP_CONN();
262 
264  Test(SQL_TXN_READ_UNCOMMITTED, "dirty 1 non repeatable 1 phantom 1");
265  Test(SQL_TXN_READ_COMMITTED, "dirty 0 non repeatable 1 phantom 1");
266  if (odbc_db_is_microsoft()) {
267  Test(SQL_TXN_REPEATABLE_READ, "dirty 0 non repeatable 0 phantom 1");
268  } else {
269  hide_error = 1;
270  if (!Test(SQL_TXN_REPEATABLE_READ, "dirty 0 non repeatable 0 phantom 1"))
271  Test(SQL_TXN_REPEATABLE_READ, "dirty 0 non repeatable 0 phantom 0");
272  }
273  Test(SQL_TXN_SERIALIZABLE, "dirty 0 non repeatable 0 phantom 0");
274  }
275 
276  odbc_disconnect();
277 
278  SWAP_CONN();
279 
281 
282  /* Sybase do not accept DROP TABLE during a transaction */
284  odbc_command("DROP TABLE test_transaction");
285 
286  odbc_disconnect();
287  return 0;
288 }
#define int2ptr(i)
Definition: common.h:101
#define ODBC_GET(s)
Definition: common.h:217
#define C(s)
Definition: common.h:231
#define odbc_command(cmd)
Definition: common.h:179
#define CHKSetConnectAttr(a, b, c, res)
Definition: common.h:152
#define ODBC_FREE()
Definition: common.h:218
#define odbc_command2(cmd, res)
Definition: common.h:180
#define CHKGetDiagRec(a, b, c, d, e, f, g, h, res)
Definition: common.h:128
#define CHKSetStmtAttr(a, b, c, res)
Definition: common.h:158
#define CHKEndTran(a, b, c, res)
Definition: common.h:110
#define CHKFetch(res)
Definition: common.h:118
static SQLRETURN odbc_connect(TDS_DBC *dbc, TDSLOGIN *login)
Definition: odbc.c:356
static const char * expected[]
Definition: bcp.c:42
HSTMT odbc_stmt
Definition: common.c:33
char odbc_sqlstate[6]
Definition: common.c:635
int odbc_disconnect(void)
Definition: common.c:290
char odbc_err[512]
Definition: common.c:634
int odbc_use_version3
Definition: common.c:34
int odbc_db_is_microsoft(void)
Definition: common.c:325
void(* odbc_set_conn_attr)(void)
Definition: common.c:35
HDBC odbc_conn
Definition: common.c:32
static void EndTransaction(SQLSMALLINT type)
Definition: transaction2.c:30
int main(int argc, char *argv[])
Definition: transaction2.c:201
static void AutoCommit(int onoff)
Definition: transaction2.c:24
static int global_txn
Definition: transaction2.c:147
static void my_attrs(void)
Definition: transaction2.c:152
static int Test(int txn, const char *expected)
Definition: transaction2.c:168
static HSTMT stmt
Definition: transaction2.c:40
#define SWAP_CONN()
Definition: transaction2.c:36
static void ReadErrorConn(void)
Definition: transaction2.c:8
static int test_with_connect
Definition: transaction2.c:145
static int CheckDirtyRead(void)
Definition: transaction2.c:43
static int hide_error
Definition: transaction2.c:149
static int CheckPhantom(void)
Definition: transaction2.c:108
static HENV env
Definition: transaction2.c:38
static int CheckNonrepeatableRead(void)
Definition: transaction2.c:71
static HDBC dbc
Definition: transaction2.c:39
static void ConnectWithTxn(int txn)
Definition: transaction2.c:159
#define NULL
Definition: ncbistd.hpp:225
exit(2)
char * buf
int strcmp(const char *str1, const char *str2)
Definition: odbc_utils.hpp:160
#define SQL_COMMIT
Definition: sql.h:271
#define SQL_TXN_REPEATABLE_READ
Definition: sql.h:568
#define SQL_NULL_HSTMT
Definition: sql.h:277
#define SQL_NULL_HENV
Definition: sql.h:275
#define SQL_NULL_HDBC
Definition: sql.h:276
#define SQL_TXN_SERIALIZABLE
Definition: sql.h:570
#define SQL_TXN_READ_COMMITTED
Definition: sql.h:566
#define SQL_TXN_READ_UNCOMMITTED
Definition: sql.h:564
#define SQL_ROLLBACK
Definition: sql.h:272
#define SQL_HANDLE_DBC
Definition: sql.h:65
#define SQL_ERROR
Definition: sql.h:36
#define SQL_ATTR_TXN_ISOLATION
Definition: sqlext.h:138
#define SQL_ATTR_AUTOCOMMIT
Definition: sqlext.h:124
#define SQL_ATTR_QUERY_TIMEOUT
Definition: sqlext.h:271
#define SQL_AUTOCOMMIT_ON
Definition: sqlext.h:183
SQLRETURN SQLMoreResults(SQLHSTMT hstmt)
Definition: odbc.c:865
#define SQL_AUTOCOMMIT_OFF
Definition: sqlext.h:182
SQLHANDLE HSTMT
Definition: sqltypes.h:238
void * SQLPOINTER
Definition: sqltypes.h:195
SQLHANDLE HDBC
Definition: sqltypes.h:237
SQLCHAR SQLTCHAR
Definition: sqltypes.h:463
SQLHANDLE HENV
Definition: sqltypes.h:236
signed short int SQLSMALLINT
Definition: sqltypes.h:201
SQLSMALLINT SQLRETURN
Definition: sqltypes.h:210
Definition: type.c:6
Modified on Sat Jun 15 11:52:08 2024 by modify_doxy.py rev. 669887