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