Line data Source code
1 : #include "common.h"
2 : #include <assert.h>
3 : #define TDS_DONT_DEFINE_DEFAULT_FUNCTIONS
4 : #include "../../tds/unittests/common.h"
5 : #include <freetds/odbc.h>
6 :
7 : /* Check we support any possible types from the server */
8 :
9 : static int sql_c_types[100];
10 : static const char *sql_c_types_names[100];
11 : static unsigned num_c_types = 0;
12 :
13 : static TDS_STMT *stmt;
14 :
15 968 : static void test_type(TDSSOCKET *tds TDS_UNUSED, TDSCOLUMN *col)
16 : {
17 : unsigned n;
18 :
19 : /* check that we can get type information from column */
20 : struct _drecord drec;
21 968 : memset(&drec, 0, sizeof(drec));
22 968 : odbc_set_sql_type_info(col, &drec, SQL_OV_ODBC3);
23 :
24 968 : assert(drec.sql_desc_literal_prefix);
25 968 : assert(drec.sql_desc_literal_suffix);
26 968 : assert(drec.sql_desc_type_name);
27 968 : assert(drec.sql_desc_type_name[0]);
28 :
29 : /* check we can attempt to convert from any type to any
30 : * SQL C type */
31 24200 : for (n = 0; n < num_c_types; ++n) {
32 : TDS_CHAR buffer[256];
33 : SQLLEN len;
34 24200 : int sql_c_type = sql_c_types[n];
35 24200 : const char *sql_c_type_name = sql_c_types_names[n];
36 : struct _drecord drec_ixd;
37 24200 : SQLLEN dest_len = sizeof(buffer);
38 : TDSPARAMINFO *params;
39 :
40 24200 : len = odbc_tds2sql_col(stmt, col, sql_c_type, buffer, sizeof(buffer), NULL);
41 24200 : if (len == SQL_NULL_DATA) {
42 12072 : printf("error converting to %3d (%s)\n", sql_c_type, sql_c_type_name);
43 12072 : continue;
44 : }
45 :
46 12128 : params = tds_alloc_param_result(NULL);
47 12128 : assert(params);
48 :
49 : /* convert back to server */
50 12128 : memset(&drec_ixd, 0, sizeof(drec_ixd));
51 12128 : drec_ixd.sql_desc_concise_type = sql_c_type;
52 12128 : drec_ixd.sql_desc_data_ptr = buffer;
53 12128 : drec_ixd.sql_desc_octet_length_ptr = &dest_len;
54 12128 : drec_ixd.sql_desc_precision = 18;
55 12128 : drec_ixd.sql_desc_scale = 4;
56 12128 : odbc_sql2tds(stmt, &drec_ixd, &drec, params->columns[0], true, stmt->ard, 0);
57 12128 : tds_free_param_results(params);
58 : }
59 968 : }
60 :
61 : int
62 8 : main(void)
63 : {
64 : TDS_DBC *dbc;
65 : TDS_ENV *env;
66 : SQLULEN ulen;
67 : int i;
68 :
69 : /* extract all C types we support */
70 3216 : for (i = -200; i <= 200; ++i) {
71 3208 : assert(num_c_types < 100);
72 3208 : if (odbc_c_to_server_type(i) != TDS_INVALID_TYPE) {
73 200 : sql_c_types[num_c_types] = i;
74 200 : sql_c_types_names[num_c_types] = odbc_lookup_value(i, odbc_sql_c_types, NULL);
75 200 : assert(sql_c_types_names[num_c_types] != NULL);
76 200 : num_c_types++;
77 : }
78 : }
79 :
80 : /* this specific test doesn't need a connection, so fake one */
81 8 : CHKAllocHandle(SQL_HANDLE_ENV, SQL_NULL_HANDLE, &odbc_env, "S");
82 8 : SQLSetEnvAttr(odbc_env, SQL_ATTR_ODBC_VERSION, (SQLPOINTER) SQL_OV_ODBC3, SQL_IS_UINTEGER);
83 8 : CHKAllocHandle(SQL_HANDLE_DBC, odbc_env, &odbc_conn, "S");
84 :
85 8 : if (!odbc_driver_is_freetds())
86 : return 0;
87 :
88 : /* get internal structures */
89 8 : CHKGetInfo(SQL_DRIVER_HDBC, &ulen, sizeof(ulen), NULL, "S");
90 8 : dbc = (TDS_DBC *) (TDS_UINTPTR) ulen;
91 8 : CHKGetInfo(SQL_DRIVER_HENV, &ulen, sizeof(ulen), NULL, "S");
92 8 : env = (TDS_ENV *) (TDS_UINTPTR) ulen;
93 8 : assert(dbc && env);
94 8 : assert(env->tds_ctx);
95 :
96 8 : assert(!dbc->tds_socket);
97 8 : dbc->tds_socket = tds_alloc_socket(env->tds_ctx, 512);
98 8 : assert(dbc->tds_socket);
99 8 : dbc->tds_socket->conn->use_iconv = 0;
100 8 : tds_set_parent(dbc->tds_socket, dbc);
101 8 : if (TDS_FAILED(tds_iconv_open(dbc->tds_socket->conn, "UTF-8", 1))) {
102 0 : fprintf(stderr, "Failed to initialize iconv\n");
103 0 : return 1;
104 : }
105 :
106 : /* get one statement to test with */
107 8 : assert(dbc->stmt_list == NULL);
108 8 : CHKAllocStmt(&odbc_stmt, "S");
109 8 : assert(dbc->stmt_list);
110 8 : stmt = dbc->stmt_list;
111 :
112 8 : tds_all_types(dbc->tds_socket, test_type);
113 :
114 8 : odbc_disconnect();
115 8 : return 0;
116 : }
|