TDS_DESC * desc_alloc(SQLHANDLE parent, int desc_type, int alloc_type) { TDS_DESC *desc; desc = tds_new0(TDS_DESC, 1); if (!desc || tds_mutex_init(&desc->mtx)) { free(desc); return NULL; } /* set default header values */ desc->htype = SQL_HANDLE_DESC; desc->type = desc_type; desc->parent = parent; desc->header.sql_desc_alloc_type = alloc_type; desc->header.sql_desc_count = 0; desc->records = NULL; switch (desc_type) { case DESC_IRD: case DESC_IPD: break; case DESC_ARD: case DESC_APD: desc->header.sql_desc_bind_type = SQL_BIND_BY_COLUMN; desc->header.sql_desc_array_size = 1; break; default: free(desc); return NULL; } return desc; }
int main(int argc, char **argv) { if (tds_mutex_init(&mtx)) return 1; if (odbc_read_login_info()) exit(1); /* * prepare our odbcinst.ini * is better to do it before connect cause uniODBC cache INIs * the name must be odbcinst.ini cause unixODBC accept only this name */ if (odbc_driver[0]) { FILE *f = fopen("odbcinst.ini", "w"); if (f) { fprintf(f, "[FreeTDS]\nDriver = %s\nThreading = 0\n", odbc_driver); fclose(f); /* force iODBC */ setenv("ODBCINSTINI", "./odbcinst.ini", 1); setenv("SYSODBCINSTINI", "./odbcinst.ini", 1); /* force unixODBC (only directory) */ setenv("ODBCSYSINI", ".", 1); } } odbc_use_version3 = 1; odbc_connect(); odbc_command("IF OBJECT_ID('tab1') IS NOT NULL DROP TABLE tab1"); odbc_command("CREATE TABLE tab1 ( k INT, vc VARCHAR(200) )"); printf(">> Creating tab1...\n"); odbc_command("DECLARE @i INT\n" "SET @i = 1\n" "WHILE @i <= 2000 BEGIN\n" "INSERT INTO tab1 VALUES ( @i, 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa' )\n" "SET @i = @i + 1\n" "END"); while (CHKMoreResults("SNo") == SQL_SUCCESS) continue; printf(">> ...done.\n"); odbc_reset_statement(); Test(0, 0); Test(1, 0); Test(0, 1); Test(1, 1); odbc_command("DROP TABLE tab1"); odbc_disconnect(); return 0; }
/* * pool_init creates a named pool and opens connections to the database */ static TDS_POOL * pool_init(const char *name) { TDS_POOL *pool; char *err = NULL; /* initialize the pool */ pool = (TDS_POOL *) calloc(1, sizeof(TDS_POOL)); pool->event_fd = INVALID_SOCKET; if (tds_mutex_init(&pool->events_mtx)) { fprintf(stderr, "Error initializing pool mutex\n"); exit(EXIT_FAILURE); } /* FIXME -- read this from the conf file */ if (!pool_read_conf_file(name, pool, &err)) { fprintf(stderr, "Configuration for pool ``%s'' not found.\n", name); exit(EXIT_FAILURE); } if (err) { fprintf(stderr, "%s\n", err); exit(EXIT_FAILURE); } check_field(name, pool->user, "user"); check_field(name, pool->server, "server"); check_field(name, pool->port, "port"); if (pool->max_open_conn < pool->min_open_conn) { fprintf(stderr, "Max connections less than minimum\n"); exit(EXIT_FAILURE); } pool->name = strdup(name); pool_open_logfile(pool); pool_mbr_init(pool); pool_user_init(pool); pool_socket_init(pool); return pool; }
int main(int argc, char *argv[]) { SQLTCHAR tmp[2048]; char conn[128]; SQLTCHAR sqlstate[6]; SQLSMALLINT len; int port; time_t start_time, end_time; #ifdef _WIN32 WSADATA wsaData; WSAStartup(MAKEWORD(1, 1), &wsaData); #endif if (tds_mutex_init(&mtx)) return 1; if (odbc_read_login_info()) exit(1); /* * prepare our odbcinst.ini * is better to do it before connect cause uniODBC cache INIs * the name must be odbcinst.ini cause unixODBC accept only this name */ if (odbc_driver[0]) { FILE *f = fopen("odbcinst.ini", "w"); if (f) { fprintf(f, "[FreeTDS]\nDriver = %s\n", odbc_driver); fclose(f); /* force iODBC */ setenv("ODBCINSTINI", "./odbcinst.ini", 1); setenv("SYSODBCINSTINI", "./odbcinst.ini", 1); /* force unixODBC (only directory) */ setenv("ODBCSYSINI", ".", 1); } } for (port = 12340; port < 12350; ++port) if (!init_fake_server(port)) break; if (port == 12350) { fprintf(stderr, "Cannot bind to a port\n"); return 1; } printf("Fake server bound at port %d\n", port); init_connect(); CHKSetConnectAttr(SQL_ATTR_CONNECTION_TIMEOUT, (SQLPOINTER) 10, sizeof(SQLINTEGER), "SI"); CHKSetConnectAttr(SQL_ATTR_LOGIN_TIMEOUT, (SQLPOINTER) 10, SQL_IS_UINTEGER, "SI"); /* this is expected to work with unixODBC */ printf("try to connect to our port just to check connection timeout\n"); sprintf(conn, "DRIVER=FreeTDS;SERVER=127.0.0.1;Port=%d;TDS_Version=7.0;UID=test;PWD=test;DATABASE=tempdb;", port); start_time = time(NULL); CHKDriverConnect(NULL, T(conn), SQL_NTS, tmp, ODBC_VECTOR_SIZE(tmp), &len, SQL_DRIVER_NOPROMPT, "E"); end_time = time(NULL); memset(sqlstate, 'X', sizeof(sqlstate)); tmp[0] = 0; CHKGetDiagRec(SQL_HANDLE_DBC, odbc_conn, 1, sqlstate, NULL, tmp, ODBC_VECTOR_SIZE(tmp), NULL, "SI"); odbc_disconnect(); tds_mutex_lock(&mtx); CLOSESOCKET(fake_sock); tds_mutex_unlock(&mtx); tds_thread_join(fake_thread, NULL); printf("Message: %s - %s\n", C(sqlstate), C(tmp)); if (strcmp(C(sqlstate), "HYT00") || !strstr(C(tmp), "Timeout")) { fprintf(stderr, "Invalid timeout message\n"); return 1; } if (end_time - start_time < 10 || end_time - start_time > 16) { fprintf(stderr, "Unexpected connect timeout (%d)\n", (int) (end_time - start_time)); return 1; } printf("Done.\n"); ODBC_FREE(); return 0; }
int main(int argc, char **argv) { SQLLEN sql_nts = SQL_NTS; const char *query; SQLINTEGER id = 0; char string[64]; TDS_SYS_SOCKET last_socket; int port; const int num_inserts = 20; int is_freetds; #ifdef _WIN32 WSADATA wsaData; WSAStartup(MAKEWORD(1, 1), &wsaData); #endif if (tds_mutex_init(&mtx)) return 1; odbc_mark_sockets_opened(); odbc_connect(); /* * this does not work if server is not connected with socket * (ie ms driver connected locally) */ last_socket = odbc_find_last_socket(); if (TDS_IS_SOCKET_INVALID(last_socket)) { fprintf(stderr, "Error finding last socket opened\n"); return 1; } remote_addr_len = sizeof(remote_addr); if (tds_getpeername(last_socket, &remote_addr.sa, &remote_addr_len)) { fprintf(stderr, "Unable to get remote address\n"); return 1; } is_freetds = odbc_driver_is_freetds(); odbc_disconnect(); /* init fake server, behave like a proxy */ for (port = 12340; port < 12350; ++port) if (!init_fake_server(port)) break; if (port == 12350) { fprintf(stderr, "Cannot bind to a port\n"); return 1; } printf("Fake server bound at port %d\n", port); /* override connections */ if (is_freetds) { setenv("TDSHOST", "127.0.0.1", 1); sprintf(string, "%d", port); setenv("TDSPORT", string, 1); odbc_connect(); } else { char tmp[2048]; SQLSMALLINT len; CHKAllocEnv(&odbc_env, "S"); CHKAllocConnect(&odbc_conn, "S"); sprintf(tmp, "DRIVER={SQL Server};SERVER=127.0.0.1,%d;UID=%s;PWD=%s;DATABASE=%s;Network=DBMSSOCN;", port, odbc_user, odbc_password, odbc_database); printf("connection string: %s\n", tmp); CHKDriverConnect(NULL, T(tmp), SQL_NTS, (SQLTCHAR *) tmp, sizeof(tmp)/sizeof(SQLTCHAR), &len, SQL_DRIVER_NOPROMPT, "SI"); CHKAllocStmt(&odbc_stmt, "S"); } /* real test */ odbc_command("CREATE TABLE #test(i int, c varchar(40))"); odbc_reset_statement(); /* do not take into account connection statistics */ tds_mutex_lock(&mtx); round_trips = 0; inserts = 0; tds_mutex_unlock(&mtx); query = "insert into #test values (?, ?)"; CHKBindParameter(1, SQL_PARAM_INPUT, SQL_C_SLONG, SQL_INTEGER, sizeof(id), 0, &id, 0, &sql_nts, "SI"); CHKBindParameter(2, SQL_PARAM_INPUT, SQL_C_CHAR, SQL_VARCHAR, sizeof(string), 0, string, 0, &sql_nts, "SI"); CHKPrepare(T(query), SQL_NTS, "SI"); tds_mutex_lock(&mtx); printf("%u round trips %u inserts\n", round_trips, inserts); tds_mutex_unlock(&mtx); for (id = 0; id < num_inserts; id++) { sprintf(string, "This is a test (%d)", (int) id); CHKExecute("SI"); CHKFreeStmt(SQL_CLOSE, "S"); } tds_mutex_lock(&mtx); printf("%u round trips %u inserts\n", round_trips, inserts); tds_mutex_unlock(&mtx); odbc_reset_statement(); tds_mutex_lock(&mtx); if (inserts > 1 || round_trips > (unsigned) (num_inserts * 2 + 6)) { fprintf(stderr, "Too much round trips (%u) or insert (%u) !!!\n", round_trips, inserts); tds_mutex_unlock(&mtx); return 1; } printf("%u round trips %u inserts\n", round_trips, inserts); tds_mutex_unlock(&mtx); #ifdef ENABLE_DEVELOPING /* check for SQL_RESET_PARAMS */ tds_mutex_lock(&mtx); round_trips = 0; inserts = 0; tds_mutex_unlock(&mtx); CHKBindParameter(1, SQL_PARAM_INPUT, SQL_C_SLONG, SQL_INTEGER, sizeof(id), 0, &id, 0, &sql_nts, "SI"); CHKBindParameter(2, SQL_PARAM_INPUT, SQL_C_CHAR, SQL_VARCHAR, sizeof(string), 0, string, 0, &sql_nts, "SI"); CHKPrepare((SQLCHAR *) query, SQL_NTS, "SI"); tds_mutex_lock(&mtx); printf("%u round trips %u inserts\n", round_trips, inserts); tds_mutex_unlock(&mtx); for (id = 0; id < num_inserts; id++) { CHKBindParameter(1, SQL_PARAM_INPUT, SQL_C_SLONG, SQL_INTEGER, sizeof(id), 0, &id, 0, &sql_nts, "SI"); CHKBindParameter(2, SQL_PARAM_INPUT, SQL_C_CHAR, SQL_VARCHAR, sizeof(string), 0, string, 0, &sql_nts, "SI"); sprintf(string, "This is a test (%d)", (int) id); CHKExecute("SI"); CHKFreeStmt(SQL_RESET_PARAMS, "S"); } tds_mutex_lock(&mtx); printf("%u round trips %u inserts\n", round_trips, inserts); tds_mutex_unlock(&mtx); odbc_reset_statement(); tds_mutex_lock(&mtx); if (inserts > 1 || round_trips > num_inserts * 2 + 6) { fprintf(stderr, "Too much round trips (%u) or insert (%u) !!!\n", round_trips, inserts); tds_mutex_unlock(&mtx); return 1; } printf("%u round trips %u inserts\n", round_trips, inserts); tds_mutex_unlock(&mtx); #endif odbc_disconnect(); alarm(10); tds_thread_join(fake_thread, NULL); return 0; }