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 10 : TEST_MAIN()
104 : {
105 : int i;
106 : SQLLEN bytes_returned;
107 :
108 : /* do not allocate so big memory in stack */
109 10 : buf = (unsigned char *) malloc(TEST_BUF_LEN);
110 :
111 10 : odbc_connect();
112 :
113 10 : odbc_command("create table " TEST_TABLE_NAME " (im IMAGE)");
114 10 : odbc_command("SET TEXTSIZE 1000000");
115 :
116 : /* populate test buffer with ramp */
117 1310730 : for (i = 0; i < TEST_BUF_LEN; i++) {
118 1310720 : buf[i] = BYTE_AT(i);
119 : }
120 :
121 : /* insert test pattern into database */
122 10 : if (test_insert(buf, TEST_BUF_LEN) == -1) {
123 : clean_up();
124 0 : return -1;
125 : }
126 :
127 10 : memset(buf, 0, TEST_BUF_LEN);
128 :
129 : /* read test pattern from database */
130 10 : if (test_select(buf, TEST_BUF_LEN, &bytes_returned) == -1) {
131 : clean_up();
132 0 : return -1;
133 : }
134 :
135 : /* compare inserted and read back test patterns */
136 10 : if (bytes_returned != TEST_BUF_LEN) {
137 0 : show_error("main(): comparing buffers", "Mismatch in input and output pattern sizes.");
138 0 : printf("Expected %lu got %lu\n", (unsigned long) TEST_BUF_LEN, (unsigned long) bytes_returned);
139 : clean_up();
140 0 : return -1;
141 : }
142 :
143 1310720 : for (i = 0; i < TEST_BUF_LEN; ++i) {
144 1310720 : if (buf[i] != BYTE_AT(i)) {
145 0 : printf("mismatch at pos %d %d != %d\n", i, buf[i], BYTE_AT(i));
146 0 : show_error("main(): comparing buffers", "Mismatch in input and output patterns.");
147 : clean_up();
148 0 : return -1;
149 : }
150 : }
151 :
152 10 : printf("Input and output buffers of length %d match.\nTest passed.\n", TEST_BUF_LEN);
153 : clean_up();
154 10 : return 0;
155 : }
|