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 8 : free(buf);
36 8 : odbc_disconnect();
37 : }
38 :
39 : static int
40 8 : test_insert(void *buf, SQLLEN buflen)
41 : {
42 8 : SQLHSTMT odbc_stmt = SQL_NULL_HSTMT;
43 : SQLLEN strlen_or_ind;
44 8 : const char *qstr = "insert into " TEST_TABLE_NAME " values (?)";
45 :
46 8 : assert(odbc_conn);
47 8 : assert(odbc_env);
48 :
49 : /* allocate new statement handle */
50 8 : CHKAllocHandle(SQL_HANDLE_STMT, odbc_conn, &odbc_stmt, "SI");
51 :
52 : /* execute query */
53 8 : CHKPrepare(T(qstr), SQL_NTS, "SI");
54 :
55 8 : strlen_or_ind = buflen;
56 8 : CHKBindParameter(1, SQL_PARAM_INPUT, SQL_C_BINARY, SQL_LONGVARBINARY, (SQLUINTEGER) (-1), 0, buf, buflen,
57 : &strlen_or_ind, "SI");
58 :
59 8 : CHKExecute("SI");
60 :
61 : /* this command shouldn't fail */
62 8 : odbc_command("DECLARE @i INT");
63 :
64 8 : SQLFreeHandle(SQL_HANDLE_STMT, odbc_stmt);
65 8 : return 0;
66 : }
67 :
68 :
69 : static int
70 8 : test_select(void *buf, SQLINTEGER buflen, SQLLEN * bytes_returned)
71 : {
72 8 : SQLHSTMT odbc_stmt = SQL_NULL_HSTMT;
73 8 : SQLLEN strlen_or_ind = 0;
74 8 : const char *qstr = "select * from " TEST_TABLE_NAME;
75 :
76 8 : assert(odbc_conn);
77 8 : assert(odbc_env);
78 :
79 : /* allocate new statement handle */
80 8 : CHKAllocHandle(SQL_HANDLE_STMT, odbc_conn, &odbc_stmt, "SI");
81 :
82 : /* execute query */
83 8 : CHKExecDirect(T(qstr), SQL_NTS, "SINo");
84 :
85 : /* fetch first page of first result row of unbound column */
86 8 : CHKFetch("S");
87 :
88 8 : strlen_or_ind = 0;
89 8 : CHKGetData(1, SQL_C_BINARY, buf, buflen, &strlen_or_ind, "SINo");
90 :
91 8 : *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 8 : CHKFetch("No");
95 :
96 8 : SQLFreeHandle(SQL_HANDLE_STMT, odbc_stmt);
97 8 : ODBC_FREE();
98 8 : return 0;
99 : }
100 :
101 : #define BYTE_AT(n) (((n) * 123) & 0xff)
102 :
103 : int
104 8 : main(int argc, char **argv)
105 : {
106 : int i;
107 : SQLLEN bytes_returned;
108 :
109 : /* do not allocate so big memory in stack */
110 8 : buf = (unsigned char *) malloc(TEST_BUF_LEN);
111 :
112 8 : odbc_connect();
113 :
114 8 : odbc_command("create table " TEST_TABLE_NAME " (im IMAGE)");
115 8 : odbc_command("SET TEXTSIZE 1000000");
116 :
117 : /* populate test buffer with ramp */
118 1048584 : for (i = 0; i < TEST_BUF_LEN; i++) {
119 1048576 : buf[i] = BYTE_AT(i);
120 : }
121 :
122 : /* insert test pattern into database */
123 8 : if (test_insert(buf, TEST_BUF_LEN) == -1) {
124 : clean_up();
125 0 : return -1;
126 : }
127 :
128 8 : memset(buf, 0, TEST_BUF_LEN);
129 :
130 : /* read test pattern from database */
131 8 : 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 8 : 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 1048576 : for (i = 0; i < TEST_BUF_LEN; ++i) {
145 1048576 : 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 8 : printf("Input and output buffers of length %d match.\nTest passed.\n", TEST_BUF_LEN);
154 : clean_up();
155 8 : return 0;
156 : }
|