Line data Source code
1 : /**
2 : * Summary: Freetds binary patch test.
3 : * Author: Gerhard Esterhuizen <ge AT swistgroup.com>
4 : * Date: April 2003
5 : */
6 :
7 : #include "common.h"
8 : #include <assert.h>
9 :
10 : #define ERR_BUF_SIZE 256
11 : /*
12 : Name of table used by the test. Should contain single column,
13 : of IMAGE type and should contain NO rows at time of program invocation.
14 : */
15 : #define TEST_TABLE_NAME "#binary_test"
16 :
17 : /*
18 : Size (in bytes) of the test pattern written to and read from
19 : the database.
20 : */
21 : #define TEST_BUF_LEN (1024*128)
22 :
23 :
24 : static unsigned char *buf;
25 :
26 : static void
27 : show_error(const char *where, const char *what)
28 : {
29 0 : printf("ERROR in %s: %s.\n", where, what);
30 : }
31 :
32 : static void
33 : clean_up(void)
34 : {
35 10 : free(buf);
36 10 : odbc_disconnect();
37 : }
38 :
39 : static int
40 10 : test_insert(void *buf, SQLLEN buflen)
41 : {
42 10 : SQLHSTMT odbc_stmt = SQL_NULL_HSTMT;
43 : SQLLEN strlen_or_ind;
44 10 : const char *qstr = "insert into " TEST_TABLE_NAME " values (?)";
45 :
46 10 : assert(odbc_conn);
47 10 : assert(odbc_env);
48 :
49 : /* allocate new statement handle */
50 10 : CHKAllocHandle(SQL_HANDLE_STMT, odbc_conn, &odbc_stmt, "SI");
51 :
52 : /* execute query */
53 10 : CHKPrepare(T(qstr), SQL_NTS, "SI");
54 :
55 10 : strlen_or_ind = buflen;
56 10 : CHKBindParameter(1, SQL_PARAM_INPUT, SQL_C_BINARY, SQL_LONGVARBINARY, (SQLUINTEGER) (-1), 0, buf, buflen,
57 : &strlen_or_ind, "SI");
58 :
59 10 : CHKExecute("SI");
60 :
61 : /* this command shouldn't fail */
62 10 : odbc_command("DECLARE @i INT");
63 :
64 10 : SQLFreeHandle(SQL_HANDLE_STMT, odbc_stmt);
65 10 : return 0;
66 : }
67 :
68 :
69 : static int
70 10 : test_select(void *buf, SQLINTEGER buflen, SQLLEN * bytes_returned)
71 : {
72 10 : SQLHSTMT odbc_stmt = SQL_NULL_HSTMT;
73 10 : SQLLEN strlen_or_ind = 0;
74 10 : const char *qstr = "select * from " TEST_TABLE_NAME;
75 :
76 10 : assert(odbc_conn);
77 10 : assert(odbc_env);
78 :
79 : /* allocate new statement handle */
80 10 : CHKAllocHandle(SQL_HANDLE_STMT, odbc_conn, &odbc_stmt, "SI");
81 :
82 : /* execute query */
83 10 : CHKExecDirect(T(qstr), SQL_NTS, "SINo");
84 :
85 : /* fetch first page of first result row of unbound column */
86 10 : CHKFetch("S");
87 :
88 10 : strlen_or_ind = 0;
89 10 : CHKGetData(1, SQL_C_BINARY, buf, buflen, &strlen_or_ind, "SINo");
90 :
91 10 : *bytes_returned = ((strlen_or_ind > buflen || (strlen_or_ind == SQL_NO_TOTAL)) ? buflen : strlen_or_ind);
92 :
93 : /* ensure that this was the only row */
94 10 : CHKFetch("No");
95 :
96 10 : SQLFreeHandle(SQL_HANDLE_STMT, odbc_stmt);
97 10 : ODBC_FREE();
98 10 : return 0;
99 : }
100 :
101 : #define BYTE_AT(n) (((n) * 123) & 0xff)
102 :
103 : int
104 10 : main(void)
105 : {
106 : int i;
107 : SQLLEN bytes_returned;
108 :
109 : /* do not allocate so big memory in stack */
110 10 : buf = (unsigned char *) malloc(TEST_BUF_LEN);
111 :
112 10 : odbc_connect();
113 :
114 10 : odbc_command("create table " TEST_TABLE_NAME " (im IMAGE)");
115 10 : odbc_command("SET TEXTSIZE 1000000");
116 :
117 : /* populate test buffer with ramp */
118 1310730 : for (i = 0; i < TEST_BUF_LEN; i++) {
119 1310720 : buf[i] = BYTE_AT(i);
120 : }
121 :
122 : /* insert test pattern into database */
123 10 : if (test_insert(buf, TEST_BUF_LEN) == -1) {
124 : clean_up();
125 0 : return -1;
126 : }
127 :
128 10 : memset(buf, 0, TEST_BUF_LEN);
129 :
130 : /* read test pattern from database */
131 10 : if (test_select(buf, TEST_BUF_LEN, &bytes_returned) == -1) {
132 : clean_up();
133 0 : return -1;
134 : }
135 :
136 : /* compare inserted and read back test patterns */
137 10 : if (bytes_returned != TEST_BUF_LEN) {
138 0 : show_error("main(): comparing buffers", "Mismatch in input and output pattern sizes.");
139 0 : printf("Expected %lu got %lu\n", (unsigned long) TEST_BUF_LEN, (unsigned long) bytes_returned);
140 : clean_up();
141 0 : return -1;
142 : }
143 :
144 1310720 : for (i = 0; i < TEST_BUF_LEN; ++i) {
145 1310720 : if (buf[i] != BYTE_AT(i)) {
146 0 : printf("mismatch at pos %d %d != %d\n", i, buf[i], BYTE_AT(i));
147 0 : show_error("main(): comparing buffers", "Mismatch in input and output patterns.");
148 : clean_up();
149 0 : return -1;
150 : }
151 : }
152 :
153 10 : printf("Input and output buffers of length %d match.\nTest passed.\n", TEST_BUF_LEN);
154 : clean_up();
155 10 : return 0;
156 : }
|