1 #include "common.h"
2 
3 /* first MARS test, test 2 concurrent recordset */
4 
5 #define SET_STMT(n) do { \
6 	if (pcur_stmt != &n) { \
7 		if (pcur_stmt) *pcur_stmt = odbc_stmt; \
8 		pcur_stmt = &n; \
9 		odbc_stmt = *pcur_stmt; \
10 	} \
11 } while(0)
12 
13 static void
AutoCommit(int onoff)14 AutoCommit(int onoff)
15 {
16 	CHKSetConnectAttr(SQL_ATTR_AUTOCOMMIT, TDS_INT2PTR(onoff), 0, "S");
17 }
18 
19 static void
EndTransaction(SQLSMALLINT type)20 EndTransaction(SQLSMALLINT type)
21 {
22 	CHKEndTran(SQL_HANDLE_DBC, odbc_conn, type, "S");
23 }
24 
25 
26 static void
my_attrs(void)27 my_attrs(void)
28 {
29 	SQLSetConnectAttr(odbc_conn, 1224 /*SQL_COPT_SS_MARS_ENABLED*/, (SQLPOINTER) 1 /*SQL_MARS_ENABLED_YES*/, SQL_IS_UINTEGER);
30 }
31 
32 int
main(int argc,char * argv[])33 main(int argc, char *argv[])
34 {
35 	SQLINTEGER len, out;
36 	int i;
37 	SQLHSTMT stmt1, stmt2;
38 	SQLHSTMT *pcur_stmt = NULL;
39 
40 	odbc_use_version3 = 1;
41 	odbc_set_conn_attr = my_attrs;
42 	odbc_connect();
43 
44 	stmt1 = odbc_stmt;
45 
46 	out = 0;
47 	len = sizeof(out);
48 	CHKGetConnectAttr(1224, (SQLPOINTER) &out, sizeof(out), &len, "SE");
49 
50 	/* test we really support MARS on this connection */
51 	/* TODO should out be correct ?? */
52 	printf("Following row can contain an error due to MARS detection (is expected)\n");
53 	if (!out || odbc_command2("BEGIN TRANSACTION", "SNoE") != SQL_ERROR) {
54 		printf("MARS not supported for this connection\n");
55 		odbc_disconnect();
56 		odbc_test_skipped();
57 		return 0;
58 	}
59 	odbc_read_error();
60 	if (!strstr(odbc_err, "MARS")) {
61 		fprintf(stderr, "Error message invalid \"%s\"\n", odbc_err);
62 		return 1;
63 	}
64 
65 	/* create a test table with some data */
66 	odbc_command("create table #mars1 (n int, v varchar(100))");
67 	for (i = 0; i < 60; ++i) {
68 		char cmd[120], buf[80];
69 		memset(buf, 'a' + (i % 26), sizeof(buf));
70 		buf[i * 7 % 73] = 0;
71 		sprintf(cmd, "insert into #mars1 values(%d, '%s')", i, buf);
72 		odbc_command(cmd);
73 	}
74 
75 	/* and another to avid locking problems */
76 	odbc_command("create table #mars2 (n int, v varchar(100))");
77 
78 	AutoCommit(SQL_AUTOCOMMIT_OFF);
79 
80 	/* try to do a select which return a lot of data (to test server didn't cache everything) */
81 	odbc_command("select a.n, b.n, a.v from #mars1 a, #mars1 b order by a.n, b.n");
82 	CHKFetch("S");
83 
84 	/* try to do other commands */
85 	CHKAllocStmt(&stmt2, "S");
86 	SET_STMT(stmt2);
87 	odbc_command("insert into #mars2 values(1, 'foo')");
88 	SET_STMT(stmt1);
89 
90 	CHKFetch("S");
91 
92 	/* reset statements */
93 	odbc_reset_statement();
94 	SET_STMT(stmt2);
95 	odbc_reset_statement();
96 
97 	/* now to 2 select with prepare/execute */
98 	CHKPrepare(T("select a.n, b.n, a.v from #mars1 a, #mars1 b order by a.n, b.n"), SQL_NTS, "S");
99 	SET_STMT(stmt1);
100 	CHKPrepare(T("select a.n, b.n, a.v from #mars1 a, #mars1 b order by a.n desc, b.n"), SQL_NTS, "S");
101 	SET_STMT(stmt2);
102 	CHKExecute("S");
103 	SET_STMT(stmt1);
104 	CHKExecute("S");
105 	SET_STMT(stmt2);
106 	CHKFetch("S");
107 	SET_STMT(stmt1);
108 	CHKFetch("S");
109 	SET_STMT(stmt2);
110 	CHKFetch("S");
111 	odbc_reset_statement();
112 	SET_STMT(stmt1);
113 	CHKFetch("S");
114 	odbc_reset_statement();
115 
116 	EndTransaction(SQL_COMMIT);
117 
118 	/* TODO test receiving large data should not take much memory */
119 
120 	odbc_disconnect();
121 	return 0;
122 }
123 
124