1 #include "common.h"
2 #include <assert.h>
3 
4 /* test conversion using SQLGetData */
5 
6 int
main(int argc,char * argv[])7 main(int argc, char *argv[])
8 {
9 	SQLLEN len;
10 	unsigned char buf[30];
11 	static const char expected[] = "\xf0\x9f\x8e\x84";
12 	int i;
13 
14 	odbc_use_version3 = 1;
15 	odbc_conn_additional_params = "ClientCharset=UTF-8;";
16 
17 	odbc_connect();
18 	if (!odbc_driver_is_freetds()) {
19 		odbc_disconnect();
20 		printf("Driver is not FreeTDS, exiting\n");
21 		odbc_test_skipped();
22 		return 0;
23 	}
24 
25 	if (!odbc_db_is_microsoft() || odbc_tds_version() < 0x700) {
26 		odbc_disconnect();
27 		/* we need NVARCHAR */
28 		printf("Test for MSSQL only using protocol 7.0\n");
29 		odbc_test_skipped();
30 		return 0;
31 	}
32 
33 	CHKAllocStmt(&odbc_stmt, "S");
34 
35 	/* a Christmas tree */
36 	odbc_command("SELECT CONVERT(NVARCHAR(10), CONVERT(VARBINARY(20), 0x3CD884DF))");
37 
38 	CHKFetch("S");
39 
40 	/* read one byte at a time and test it */
41 	for (i = 0; i < 4; ++i) {
42 		memset(buf, '-', sizeof(buf));
43 		CHKGetData(1, SQL_C_CHAR, buf, 2, &len, i < 3 ? "I" : "S");
44 		printf("res %ld buf { 0x%02x, 0x%02x }\n", (long int) len, buf[0], buf[1]);
45 		assert(len == SQL_NO_TOTAL || len == 4 - i);
46 		assert(buf[0] == (unsigned char) expected[i]);
47 		assert(buf[1] == 0);
48 	}
49 	CHKGetData(1, SQL_C_CHAR, buf, 2, &len, "No");
50 
51 	odbc_reset_statement();
52 
53 #define CN_STRING \
54 	"202020202052656974657261746520486f6c642028324829207261a174696e6720a15820" \
55 	"a14ea16fa172a173a174a161a172a1207265706f72746564206120736574206f6620756e" \
56 	"6578636974696e6720726573756c74732077697468206d6f646573742067726f77746820" \
57 	"696e20726576656e756520616e6420626f74746f6d206c696e652e20457870616e73696f" \
58 	"6e20696e746f2074686520646f6d6573"
59 
60 	/* insert does not change as much as CONVERT so insert first into a new table */
61 	odbc_command("CREATE TABLE #tmp1(c VARCHAR(200) COLLATE Chinese_PRC_CI_AS NULL)");
62 	odbc_command("INSERT INTO #tmp1 VALUES(CONVERT(VARBINARY(200), 0x" CN_STRING "))");
63 	odbc_command("SELECT c FROM #tmp1");
64 	CHKFetch("S");
65 	for (i = 0; i < 5; ++i) {
66 		memset(buf, 0, sizeof(buf));
67 		CHKGetData(1, SQL_C_CHAR, buf, sizeof(buf), &len, "I");
68 		printf("loop %d output '%s'\n", i, buf);
69 		assert(strlen((char *) buf) == sizeof(buf) - 1);
70 	}
71 	CHKGetData(1, SQL_C_CHAR, buf, sizeof(buf), &len, "S");
72 
73 	odbc_disconnect();
74 	return 0;
75 }
76 
77