00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041 #include <ncbi_pch.hpp>
00042
00043 #include "dbapi_sample_base.hpp"
00044 #include <corelib/ncbiargs.hpp>
00045 #include <corelib/ncbienv.hpp>
00046 #include <corelib/ncbi_process.hpp>
00047 #include <util/smalldns.hpp>
00048 #include <dbapi/driver/driver_mgr.hpp>
00049 #include <dbapi/driver/dbapi_svc_mapper.hpp>
00050 #include <dbapi/driver/drivers.hpp>
00051 #include <dbapi/error_codes.hpp>
00052 #include <util/random_gen.hpp>
00053
00054 #include <algorithm>
00055
00056
00057 #define NCBI_USE_ERRCODE_X Dbapi_SampleBase
00058
00059 BEGIN_NCBI_SCOPE
00060
00061
00062 const char* file_name[] = {
00063 "../test1.txt",
00064 "../test2.txt",
00065 "../test3.txt",
00066 "../test4.txt",
00067 "../test5.txt",
00068 ""
00069 };
00070
00071
00072
00073
00074
00075
00076
00077 CDbapiSampleApp::CDbapiSampleApp(EUseSampleDatabase sd)
00078 : CNcbiApplication(),
00079 m_DriverContext(0),
00080 m_UseSampleDatabase(sd),
00081 m_UseSvcMapper(false)
00082 {
00083 m_TableUID += "_" + CSmallDNS::GetLocalHost() + "_";
00084 m_TableUID += NStr::IntToString(CProcess::GetCurrentPid()) + "_";
00085 m_TableUID += CTime(CTime::eCurrent).AsString("MDy");
00086 replace( m_TableUID.begin(), m_TableUID.end(), '-', '_' );
00087
00088 #ifdef NCBI_DLL_SUPPORT
00089 CPluginManager_DllResolver::EnableGlobally(true);
00090 #else
00091
00092 #ifdef HAVE_LIBSYBASE
00093 DBAPI_RegisterDriver_CTLIB();
00094 #endif
00095
00096 #ifdef HAVE_ODBC
00097 DBAPI_RegisterDriver_ODBC();
00098 #endif
00099
00100 DBAPI_RegisterDriver_FTDS();
00101
00102 #endif // NCBI_DLL_BUILD
00103 }
00104
00105
00106 CDbapiSampleApp::~CDbapiSampleApp()
00107 {
00108 return;
00109 }
00110
00111
00112
00113 void
00114 CDbapiSampleApp::InitSample(CArgDescriptions&)
00115 {
00116 }
00117
00118
00119
00120 void
00121 CDbapiSampleApp::ExitSample(void)
00122 {
00123 }
00124
00125
00126 CDbapiSampleApp::EServerType
00127 CDbapiSampleApp::GetServerType(void) const
00128 {
00129 if ( GetServerName() == "STRAUSS"
00130 || GetServerName() == "MOZART"
00131 || GetServerName() == "SCHUMANN"
00132 || GetServerName() == "CLEMENTI"
00133 || GetServerName() == "OBERON"
00134 || GetServerName() == "TAPER"
00135 || GetServerName() == "THALBERG"
00136 || GetServerName() == "DBAPI_SYB_TEST"
00137 || NStr::StartsWith(GetServerName(), "DBAPI_DEV")
00138 || NStr::StartsWith(GetServerName(), "BARTOK")
00139 ) {
00140 return eSybase;
00141 } else if (NStr::StartsWith(GetServerName(), "MS_DEV")
00142 || NStr::StartsWith(GetServerName(), "MSSQL")
00143 || GetServerName() == "DBAPI_MS_TEST"
00144 ) {
00145 return eMsSql;
00146 }
00147
00148 return eUnknown;
00149 }
00150
00151
00152 void
00153 CDbapiSampleApp::Init()
00154 {
00155
00156 auto_ptr<CArgDescriptions> arg_desc(new CArgDescriptions);
00157
00158
00159 arg_desc->SetUsageContext(GetArguments().GetProgramBasename(),
00160 "DBAPI Sample Application");
00161
00162
00163 #if defined(NCBI_OS_MSWIN)
00164 #define DEF_SERVER "MS_DEV1"
00165 #define DEF_DRIVER "ftds"
00166 #define ALL_DRIVERS "ctlib", "dblib", "ftds", \
00167 "gateway", "odbc"
00168 #elif defined(HAVE_LIBSYBASE)
00169 #define DEF_SERVER "CLEMENTI"
00170 #define DEF_DRIVER "ctlib"
00171 #define ALL_DRIVERS "ctlib", "dblib", "ftds", "gateway", \
00172 "odbc"
00173 #else
00174 #define DEF_SERVER "MS_DEV1"
00175 #define DEF_DRIVER "ftds"
00176 #define ALL_DRIVERS "ftds", "gateway", \
00177 "odbc"
00178 #endif
00179
00180 arg_desc->AddDefaultKey("S", "server",
00181 "Name of the SQL server to connect to",
00182 CArgDescriptions::eString, DEF_SERVER);
00183
00184 arg_desc->AddDefaultKey("d", "driver",
00185 "Name of the DBAPI driver to use",
00186 CArgDescriptions::eString,
00187 DEF_DRIVER);
00188 arg_desc->SetConstraint("d", &(*new CArgAllow_Strings, ALL_DRIVERS));
00189
00190 arg_desc->AddDefaultKey("U", "username",
00191 "User name",
00192 CArgDescriptions::eString, "anyone");
00193
00194 arg_desc->AddDefaultKey("P", "password",
00195 "Password",
00196 CArgDescriptions::eString, "allowed");
00197
00198 arg_desc->AddOptionalKey("v", "version",
00199 "TDS protocol version",
00200 CArgDescriptions::eInteger);
00201
00202 arg_desc->AddDefaultKey("lb", "use_load_balancer",
00203 "Use load balancer for service mapping",
00204 CArgDescriptions::eString, "off");
00205 arg_desc->SetConstraint("lb", &(*new CArgAllow_Strings,
00206 "on", "off", "random"));
00207
00208
00209 InitSample(*arg_desc);
00210
00211
00212 SetupArgDescriptions(arg_desc.release());
00213 }
00214
00215
00216 int
00217 CDbapiSampleApp::Run()
00218 {
00219
00220 const CArgs& args = GetArgs();
00221
00222
00223 m_DriverName = args["d"].AsString();
00224 m_ServerName = args["S"].AsString();
00225 m_UserName = args["U"].AsString();
00226 m_Password = args["P"].AsString();
00227 if ( args["v"].HasValue() ) {
00228 m_TDSVersion = args["v"].AsString();
00229 } else {
00230 m_TDSVersion.erase();
00231 }
00232
00233 string service_mapping = args["lb"].AsString();
00234 if (service_mapping == "on") {
00235 m_UseSvcMapper = true;
00236 } else if (service_mapping == "random") {
00237 static Uint4 rdm_seed = static_cast<Uint4>(time(NULL));
00238 static CRandom rdm_gen(rdm_seed);
00239 m_UseSvcMapper = (rdm_gen.GetRand(0, 1) != 0);
00240 }
00241
00242 if (UseSvcMapper()) {
00243 DBLB_INSTALL_DEFAULT();
00244 #ifdef HAVE_LIBCONNEXT
00245 LOG_POST_X(1, "Using load-balancer service to server mapper ...");
00246 #else
00247 ERR_POST_X(2, "Load balancing requested, but not available in this build");
00248 #endif
00249 }
00250
00251 if ( m_TDSVersion.empty() ) {
00252
00253 if ( GetDriverName() == "dblib" &&
00254 GetServerType() == eSybase ) {
00255
00256
00257 SetDatabaseParameter("version", "100");
00258
00259
00260 }
00261 } else {
00262 SetDatabaseParameter("version", m_TDSVersion);
00263 }
00264
00265 try {
00266 return RunSample();
00267 } catch ( CDB_Exception& e ) {
00268 CDB_UserHandler::GetDefault().HandleIt(&e);
00269 return 1;
00270 }
00271
00272 return 0;
00273 }
00274
00275
00276 void
00277 CDbapiSampleApp::Exit()
00278 {
00279 ExitSample();
00280 }
00281
00282
00283 I_DriverContext&
00284 CDbapiSampleApp::GetDriverContext(void)
00285 {
00286 if ( m_DriverContext.get() )
00287 return *m_DriverContext;
00288
00289
00290 C_DriverMgr driver_mgr;
00291 string err_msg;
00292 m_DriverContext.reset
00293 (driver_mgr.GetDriverContext(GetDriverName(),
00294 &err_msg,
00295 &GetDatabaseParameters()));
00296
00297 if ( !m_DriverContext.get() ) {
00298 ERR_POST_X(3, Fatal << "Cannot load driver: " << GetDriverName() << " ["
00299 << err_msg << "] ");
00300 }
00301
00302 return *m_DriverContext;
00303 }
00304
00305
00306 CDB_Connection*
00307 CDbapiSampleApp::CreateConnection(IConnValidator* validator,
00308 I_DriverContext::TConnectionMode mode,
00309 bool reusable,
00310 const string& pool_name)
00311 {
00312 auto_ptr<CDB_Connection> conn;
00313 I_DriverContext& dc(GetDriverContext());
00314
00315 if (validator) {
00316 conn.reset(dc.ConnectValidated(GetServerName(),
00317 GetUserName(),
00318 GetPassword(),
00319 *validator,
00320 mode,
00321 reusable,
00322 pool_name));
00323 } else {
00324 conn.reset(dc.Connect(GetServerName(),
00325 GetUserName(),
00326 GetPassword(),
00327 mode,
00328 reusable,
00329 pool_name));
00330 }
00331
00332 if ( !conn.get() ) {
00333 ERR_POST_X(4, Fatal << "Cannot open connection to the server: "
00334 << GetServerName());
00335 }
00336
00337
00338 string sql("select @@servername");
00339
00340 auto_ptr<CDB_LangCmd> stmt(conn->LangCmd(sql));
00341 stmt->Send();
00342
00343 while ( stmt->HasMoreResults() ) {
00344 auto_ptr<CDB_Result> result(stmt->Result());
00345 if ( !result.get() )
00346 continue;
00347
00348 if ( result->ResultType() == eDB_RowResult ) {
00349 if ( result->Fetch() ) {
00350 CDB_LongChar v;
00351 result->GetItem(&v);
00352 LOG_POST_X(5, "Connected to the server '" << v.Value() << "'");
00353 }
00354 }
00355 }
00356
00357 if ( m_UseSampleDatabase == eUseSampleDatabase ) {
00358 conn->SetDatabaseName("DBAPI_Sample");
00359 }
00360
00361 return conn.release();
00362 }
00363
00364 void
00365 CDbapiSampleApp::DeleteTable(const string& table_name)
00366 {
00367 try {
00368 string sql;
00369
00370
00371 sql = "DROP TABLE " + table_name;
00372 auto_ptr<CDB_LangCmd> lcmd(GetConnection().LangCmd(sql));
00373 lcmd->Send();
00374 lcmd->DumpResults();
00375 } catch ( const CDB_Exception& ) {
00376 }
00377 }
00378
00379
00380 void
00381 CDbapiSampleApp::DeleteLostTables(void)
00382 {
00383 string sql = "select name from sysobjects WHERE type = 'U'";
00384 typedef list<string> table_name_list_t;
00385 table_name_list_t table_name_list;
00386 table_name_list_t::const_iterator citer;
00387
00388 auto_ptr<CDB_LangCmd> lcmd(GetConnection().LangCmd(sql));
00389 lcmd->Send();
00390
00391 while ( lcmd->HasMoreResults() ) {
00392
00393 auto_ptr<CDB_Result> r(lcmd->Result());
00394 if ( !r.get() ) continue;
00395 if ( r->ResultType() == eDB_RowResult ) {
00396
00397 while ( r->Fetch() ) {
00398 EDB_Type rt = r->ItemDataType(0);
00399
00400 if ( !(rt == eDB_Char || rt == eDB_VarChar) ) continue;
00401 CDB_VarChar str_val;
00402 r->GetItem(&str_val);
00403
00404 if ( str_val.IsNULL() ) continue;
00405 string table_creation_date;
00406 string table_name = str_val.Value();
00407 string::size_type pos = table_name.find_last_of('_');
00408
00409 if ( pos == string::npos ) continue;
00410 table_creation_date = table_name.substr(pos + 1);
00411 try {
00412
00413 CTime creation_date(table_creation_date, "MDy");
00414
00415 if ( CTimeSpan(3, 0, 0, 0) < (CTime(CTime::eCurrent) - creation_date) ) {
00416 table_name_list.push_back(table_name);
00417 }
00418 }
00419 catch(CException&)
00420 {
00421
00422 }
00423 }
00424 }
00425 }
00426
00427 for(citer = table_name_list.begin(); citer != table_name_list.end(); ++citer)
00428 {
00429 DeleteTable(*citer);
00430 }
00431 }
00432
00433 void
00434 CDbapiSampleApp::ShowResults (const string& query)
00435 {
00436 auto_ptr<CDB_LangCmd> lcmd(GetConnection().LangCmd(query));
00437 lcmd->Send();
00438
00439 while ( lcmd->HasMoreResults() ) {
00440 auto_ptr<CDB_Result> r(lcmd->Result());
00441 if ( !r.get() )
00442 continue;
00443
00444 if ( r->ResultType() == eDB_RowResult ) {
00445 while ( r->Fetch() ) {
00446 cout << "<ROW>";
00447 for ( unsigned int j = 0; j < r->NofItems(); j++ ) {
00448 EDB_Type rt = r->ItemDataType(j);
00449 const string iname = r->ItemName(j);
00450 cout << '<' << iname << '>';
00451 if ( rt == eDB_Char || rt == eDB_VarChar ) {
00452 CDB_VarChar v;
00453 r->GetItem(&v);
00454 cout << (v.IsNULL()? "{NULL}" : v.Value());
00455 } else if ( rt == eDB_Int ||
00456 rt == eDB_SmallInt ||
00457 rt == eDB_TinyInt ) {
00458 CDB_Int v;
00459 r->GetItem(&v);
00460 if ( v.IsNULL() ) {
00461 cout << "{NULL}";
00462 } else {
00463 cout << v.Value();
00464 }
00465 } else if ( rt == eDB_Float ) {
00466 CDB_Float v;
00467 r->GetItem(&v);
00468 if ( v.IsNULL() ) {
00469 cout << "{NULL}";
00470 } else {
00471 cout << v.Value();
00472 }
00473 } else if ( rt == eDB_Double ) {
00474 CDB_Double v;
00475 r->GetItem(&v);
00476 if ( v.IsNULL() ) {
00477 cout << "{NULL}";
00478 } else {
00479 cout << v.Value();
00480 }
00481 } else if ( rt == eDB_DateTime ||
00482 rt == eDB_SmallDateTime ) {
00483 CDB_DateTime v;
00484 r->GetItem(&v);
00485 if ( v.IsNULL() ) {
00486 cout << "{NULL}";
00487 } else {
00488 cout << v.Value().AsString();
00489 }
00490 } else if ( rt == eDB_Numeric ) {
00491 CDB_Numeric v;
00492 r->GetItem(&v);
00493 if ( v.IsNULL() ) {
00494 cout << "{NULL}";
00495 } else {
00496 cout << v.Value();
00497 }
00498 } else if ( rt == eDB_Text ) {
00499 CDB_Text v;
00500 r->GetItem(&v);
00501 cout << "{text (" << v.Size() << " bytes)}";
00502 } else if ( rt == eDB_Image ) {
00503 CDB_Image v;
00504 r->GetItem(&v);
00505 cout << "{image (" << v.Size() << " bytes)}";
00506 } else {
00507 r->SkipItem();
00508 cout << "{unprintable}";
00509 }
00510 cout << "</" << iname << '>';
00511 }
00512 cout << "</ROW>" << endl << endl;
00513 }
00514 }
00515 }
00516
00517 }
00518
00519 void
00520 CDbapiSampleApp::CreateTable (const string& table_name)
00521 {
00522 string sql;
00523
00524
00525 sql = string(" IF EXISTS (select * from sysobjects WHERE name = '");
00526 sql += table_name + "' AND type = 'U') begin ";
00527 sql += " DROP TABLE " + table_name + " end ";
00528
00529 auto_ptr<CDB_LangCmd> lcmd(GetConnection().LangCmd (sql));
00530 lcmd->Send();
00531 lcmd->DumpResults();
00532
00533
00534 sql = " create table " + table_name + "( \n";
00535 sql += " int_val int not null, \n";
00536 sql += " fl_val real not null, \n";
00537 sql += " date_val datetime not null, \n";
00538 sql += " str_val varchar(255) null, \n";
00539 sql += " txt_val text null \n";
00540
00541 sql += ")";
00542
00543 lcmd.reset(GetConnection().LangCmd ( sql ));
00544 lcmd->Send();
00545 lcmd->DumpResults();
00546 }
00547
00548
00549 CDB_Connection&
00550 CDbapiSampleApp::GetConnection(void)
00551 {
00552 if ( !m_Connection.get() ) {
00553 m_Connection.reset(CreateConnection());
00554 }
00555
00556 return *m_Connection;
00557 }
00558
00559
00560
00561 CDbapiSampleErrHandler::CDbapiSampleErrHandler(void)
00562 {
00563 }
00564
00565 CDbapiSampleErrHandler::~CDbapiSampleErrHandler(void)
00566 {
00567 }
00568
00569
00570 bool
00571 CDbapiSampleErrHandler::HandleIt(CDB_Exception* ex)
00572 {
00573 if ( !ex )
00574 return false;
00575
00576
00577
00578 if (ex->GetDBErrCode() == 0)
00579 return true;
00580
00581
00582 throw *ex;
00583 }
00584
00585 END_NCBI_SCOPE
00586
00587
00588
00589