Line data Source code
1 : /* This test requires no wide characters */
2 : #undef UNICODE
3 : #undef _UNICODE
4 :
5 : /* Use common.c functions compiled without wide characters in all cases */
6 : #include "common.c"
7 :
8 : /* test binding with UTF-8 encoding */
9 :
10 : #ifndef _WIN32
11 : /* test table name, it contains two japanese characters */
12 : static const char table_name[] = "mytab\xe7\x8e\x8b\xe9\xb4\xbb";
13 :
14 : static const char * const strings[] = {
15 : /* ascii */
16 : "aaa", "aaa",
17 : /* latin 1*/
18 : "abc\xc3\xa9\xc3\xa1\xc3\xb4", "abc\xc3\xa9\xc3\xae\xc3\xb4",
19 : /* Japanese... */
20 : "abc\xe7\x8e\x8b\xe9\xb4\xbb", "abc\xe7\x8e\x8b\xe9\xb4\xbb\xe5\x82\x91\xe7\x8e\x8b\xe9\xb4\xbb\xe5\x82\x91",
21 : NULL, NULL
22 : };
23 :
24 : /* same strings in hex */
25 : static const char * const strings_hex[] = {
26 : /* ascii */
27 : "0x610061006100", "0x610061006100",
28 : /* latin 1*/
29 : "0x610062006300e900e100f400", "0x610062006300e900ee00f400",
30 : /* Japanese... */
31 : "0x6100620063008b733b9d", "0x6100620063008b733b9d91508b733b9d9150",
32 : NULL, NULL
33 : };
34 :
35 : static char tmp[1024*3];
36 :
37 : static void
38 16 : TestBinding(bool minimun)
39 : {
40 : const char * const*p;
41 : SQLINTEGER n;
42 : SQLLEN n_len;
43 :
44 16 : sprintf(tmp, "DELETE FROM %s", table_name);
45 16 : odbc_command(tmp);
46 :
47 : /* insert with SQLPrepare/SQLBindParameter/SQLExecute */
48 16 : sprintf(tmp, "INSERT INTO %s VALUES(?,?,?)", table_name);
49 16 : CHKPrepare(T(tmp), SQL_NTS, "S");
50 16 : CHKBindParameter(1, SQL_PARAM_INPUT, SQL_C_LONG,
51 : SQL_INTEGER, 0, 0, &n, 0, &n_len, "S");
52 16 : n_len = sizeof(n);
53 :
54 64 : for (n = 1, p = strings; p[0] && p[1]; p += 2, ++n) {
55 : SQLLEN s1_len, s2_len;
56 : unsigned int len;
57 :
58 48 : len = minimun ? ((int) strlen(strings_hex[p-strings]) - 2) / 4 : 40;
59 48 : CHKBindParameter(2, SQL_PARAM_INPUT, SQL_C_CHAR,
60 : SQL_WCHAR, len, 0, (void *) p[0], 0, &s1_len, "S");
61 48 : len = minimun ? ((int) strlen(strings_hex[p+1-strings]) - 2) / 4 : 40;
62 : /* FIXME this with SQL_VARCHAR produce wrong protocol data */
63 48 : CHKBindParameter(3, SQL_PARAM_INPUT, SQL_C_CHAR,
64 : SQL_WVARCHAR, len, 0, (void *) p[1], 0, &s2_len, "S");
65 48 : s1_len = strlen(p[0]);
66 48 : s2_len = strlen(p[1]);
67 48 : printf("insert #%d\n", (int) n);
68 48 : CHKExecute("S");
69 : }
70 :
71 : /* check rows */
72 64 : for (n = 1, p = strings_hex; p[0] && p[1]; p += 2, ++n) {
73 48 : sprintf(tmp, "IF NOT EXISTS(SELECT * FROM %s WHERE k = %d AND c = %s AND vc = %s) SELECT 1", table_name, (int) n, p[0], p[1]);
74 48 : odbc_check_no_row(tmp);
75 : }
76 :
77 16 : odbc_reset_statement();
78 16 : }
79 :
80 10 : TEST_MAIN()
81 : {
82 : const char * const*p;
83 : SQLINTEGER n;
84 :
85 10 : odbc_use_version3 = true;
86 10 : odbc_conn_additional_params = "ClientCharset=UTF-8;";
87 :
88 10 : odbc_connect();
89 10 : if (!odbc_driver_is_freetds()) {
90 0 : odbc_disconnect();
91 0 : printf("Driver is not FreeTDS, exiting\n");
92 0 : odbc_test_skipped();
93 : return 0;
94 : }
95 :
96 10 : if (!odbc_db_is_microsoft() || odbc_db_version_int() < 0x08000000u) {
97 2 : odbc_disconnect();
98 2 : printf("Test for MSSQL only\n");
99 2 : odbc_test_skipped();
100 : return 0;
101 : }
102 :
103 8 : CHKAllocStmt(&odbc_stmt, "S");
104 :
105 : /* create test table */
106 8 : sprintf(tmp, "IF OBJECT_ID(N'%s') IS NOT NULL DROP TABLE %s", table_name, table_name);
107 8 : odbc_command(tmp);
108 8 : sprintf(tmp, "CREATE TABLE %s (k int, c NCHAR(10), vc NVARCHAR(10))", table_name);
109 8 : odbc_command(tmp);
110 :
111 : /* insert with INSERT statements */
112 32 : for (n = 1, p = strings; p[0] && p[1]; p += 2, ++n) {
113 24 : sprintf(tmp, "INSERT INTO %s VALUES (%d,N'%s',N'%s')", table_name, (int) n, p[0], p[1]);
114 24 : odbc_command(tmp);
115 : }
116 :
117 : /* check rows */
118 24 : for (n = 1, p = strings_hex; p[0] && p[1]; p += 2, ++n) {
119 24 : sprintf(tmp, "IF NOT EXISTS(SELECT * FROM %s WHERE k = %d AND c = %s AND vc = %s) SELECT 1", table_name, (int) n, p[0], p[1]);
120 24 : odbc_check_no_row(tmp);
121 : }
122 :
123 8 : TestBinding(false);
124 :
125 8 : TestBinding(true);
126 :
127 : /* cleanup */
128 8 : sprintf(tmp, "IF OBJECT_ID(N'%s') IS NOT NULL DROP TABLE %s", table_name, table_name);
129 8 : odbc_command(tmp);
130 :
131 8 : odbc_disconnect();
132 8 : printf("Done.\n");
133 : return 0;
134 : }
135 :
136 : #else
137 :
138 : TEST_MAIN()
139 : {
140 : /* on Windows SQLExecDirect is always converted to SQLExecDirectW by the DM */
141 : printf("Not possible for this platform.\n");
142 : odbc_test_skipped();
143 : return 0;
144 : }
145 : #endif
|