dbapi_testspeed.cpp
上传用户:yhdzpy8989
上传日期:2007-06-13
资源大小:13604k
文件大小:11k
源码类别:

生物技术

开发平台:

C/C++

  1. /*
  2.  * ===========================================================================
  3.  * PRODUCTION $Log: dbapi_testspeed.cpp,v $
  4.  * PRODUCTION Revision 1000.4  2004/06/01 19:22:35  gouriano
  5.  * PRODUCTION PRODUCTION: UPGRADED [GCC34_MSVC7] Dev-tree R1.14
  6.  * PRODUCTION
  7.  * ===========================================================================
  8.  */
  9. /*  $Id: dbapi_testspeed.cpp,v 1000.4 2004/06/01 19:22:35 gouriano Exp $
  10. * ===========================================================================
  11. *
  12. *                            PUBLIC DOMAIN NOTICE
  13. *               National Center for Biotechnology Information
  14. *
  15. *  This software/database is a "United States Government Work" under the
  16. *  terms of the United States Copyright Act.  It was written as part of
  17. *  the author's official duties as a United States Government employee and
  18. *  thus cannot be copyrighted.  This software/database is freely available
  19. *  to the public for use. The National Library of Medicine and the U.S.
  20. *  Government have not placed any restriction on its use or reproduction.
  21. *
  22. *  Although all reasonable efforts have been taken to ensure the accuracy
  23. *  and reliability of the software and data, the NLM and the U.S.
  24. *  Government do not and cannot warrant the performance or results that
  25. *  may be obtained by using this software or data. The NLM and the U.S.
  26. *  Government disclaim all warranties, express or implied, including
  27. *  warranties of performance, merchantability or fitness for any particular
  28. *  purpose.
  29. *
  30. *  Please cite the author in any work or product based on this material.
  31. *
  32. * ===========================================================================
  33. *
  34. * File Description:
  35. *   Run a series of insert/update/select statement,
  36. *   measure the time required for their execution.
  37. *
  38. *============================================================================
  39. */
  40. #include <ncbi_pch.hpp>
  41. #include "dbapi_testspeed.hpp"
  42. #include <corelib/ncbitime.hpp>
  43. #include <corelib/ncbifile.hpp>
  44. USING_NCBI_SCOPE;
  45. const char usage[] =
  46.   "Run a series of BCP/insert/select commands,n"
  47.   "measure the time required for their execution. n"
  48.   "n"
  49.   "USAGE:   dbapi_testspeed -parameters [file]n"
  50.   "REQUIRED PARAMETERS:n"
  51.   "  -S servern"
  52.   "  -d driver (e.g. ctlib dblib ftds odbc gateway)n"
  53.   "  -g sss_server:port for gateway database drivern"
  54.   "     (only one of -d/-g is required to be present)n"
  55.   "OPTIONAL PARAMETERS:n"
  56.   "  -r row_count (default is 1)n"
  57.   "  -b text_blob_size in kilobytes (default is 1 kb)n"
  58.   "  -c column_count  1..5 (int_val fl_val date_val str_val txt_val)n"
  59.   "  -t table_name (default is 'TestSpeed')n"
  60.   "  -m mode_character:n"
  61.   "     r  write and read as usual,n"
  62.   "        use CDB_Result->ReadItem() instead of GetItem() whenever possiblen"
  63.   "     w  write to the table, do not read, do not delete itn"
  64.   "     R  read using ReadItem() (can be done many times after '-m w' )n"
  65.   "     G  read using GetItem()  (can be done many times after '-m w' )n"
  66.   "FILE (optional):n"
  67.   "  Upload the specified file as a blob into the table,n"
  68.   "  then download it to "./testspeed.out".n"
  69.   "  "diff" can then be used to verify the data.n"
  70.   "  -r -b -c parameterss are ignored.n"
  71.   "n"
  72.   ;
  73. int Usage()
  74. {
  75.   cout << usage;
  76.   return 1;
  77. }
  78. // Create a table with 5 columns, fill it using BCP or insert commands(1),
  79. // fetch results(2), delete the table. Execution time is measured for steps 1, 2.
  80. int main (int argc, char* argv[])
  81. {
  82.   int count=0;
  83.   I_DriverContext* my_context;
  84.   CDB_Connection* con;
  85.   CDB_BCPInCmd* bcp=NULL;
  86.   CDB_LangCmd* ins_cmd=NULL;
  87.   CStopWatch timer;
  88.   // Command line args
  89.   string server_name, driver_name;
  90.   int row_count;
  91.   string table_name = "TestSpeed";
  92.   int blob_size=1;
  93.   int col_count=5;
  94.   const char* p = NULL;
  95.   bool readItems=false;
  96.   bool writeOnly=false;
  97.   bool selectOnly=false;
  98.   double timeElapsed;
  99.   // Read required args
  100.   p= getParam('S', argc, argv);
  101.   if(p) { server_name = p; } else return Usage();
  102.   p= getParam('d', argc, argv);
  103.   if(p) { driver_name = p; };
  104.   string sss_host, sss_port;
  105.   p= getParam('g', argc, argv);
  106.   if(p){
  107.     sss_host=p;
  108.     int i=NStr::Find(sss_host, ":");
  109.     if(i>0) {
  110.       sss_port = sss_host.substr(i+1);
  111.       sss_host.resize(i);
  112.     }
  113.     if( driver_name.size()==0 ) {
  114.       driver_name="gateway";
  115.     }
  116.   }
  117.   // one fo "-d" or "-g" must be present
  118.   if( driver_name.size()==0 ) return Usage();
  119.   // Read optional args
  120.   p= getParam('r', argc, argv);
  121.   if(p){
  122.     row_count = atoi(p);
  123.     if(row_count<1 || row_count>0x100000) {
  124.       cerr << "Error -- invalid row count; valid values are 1 .. 1 Meg.n";
  125.       return Usage();
  126.     }
  127.   }
  128.   //else return Usage();
  129.   else row_count=1;
  130.   p= getParam('c', argc, argv);
  131.   if(p){
  132.     col_count = atoi(p);
  133.     if(col_count<1 || col_count>5) {
  134.       cerr << "Error -- invalid column count = " << col_count << "; valid values are: 1..5n";
  135.       return Usage();
  136.     }
  137.   }
  138.   p= getParam('b', argc, argv);
  139.   if(p){
  140.     blob_size = atoi(p);
  141.     if(blob_size<1 || blob_size>1024000 ) {
  142.       cerr << "Error -- invalid blob size; valid values are 1 (kb) to 1000 (kb)n";
  143.       return Usage();
  144.     }
  145.     if(col_count<5) {
  146.       cerr << "Error -- blob size makes sense for '-c 5' only.n";
  147.       return 1;
  148.     }
  149.   }
  150.   p= getParam('t', argc, argv);
  151.   if(p) { table_name = p; };
  152.   p= getParam('m', argc, argv);
  153.   if(p) {
  154.     switch(*p) {
  155.       case 'r': readItems  = true; break;
  156.       case 'w': writeOnly  = true; break;
  157.       case 'G': selectOnly = true; break;
  158.       case 'R': selectOnly = true; readItems = true; break;
  159.       default:
  160.         cerr << "Error -- invalid mode character '" << p[0] << "'n";
  161.         return Usage();
  162.     }
  163.   };
  164.   char *fileParam=getParam(0, argc, argv);
  165.   /*
  166.   char *param;
  167.   while( param=getParam(0, argc, argv) ) {
  168.     cout << ">" << param << "<n";
  169.   }
  170.   return 0;
  171.   */
  172.   // Load the database driver
  173.   C_DriverMgr drv_mgr;
  174.   string err_msg;
  175.   map<string, string> mapDrvAttrib;
  176.   if(driver_name == "dblib") {
  177.     // Needed to work with BCP when using dblib Sybase 12.5
  178.     mapDrvAttrib.insert(
  179.       map<string,string>::value_type( string("version"), string("100") )
  180.     );
  181.   }
  182.   else{
  183.     if( sss_port.size() ) {
  184.       mapDrvAttrib.insert(
  185.         map<string,string>::value_type( string("port"), sss_port )
  186.       );
  187.     }
  188.     if( sss_host.size() ) {
  189.       mapDrvAttrib.insert(
  190.         map<string,string>::value_type( string("host"), sss_host )
  191.       );
  192.     }
  193.   }
  194.   if( mapDrvAttrib.size() ) {
  195.     my_context = drv_mgr.GetDriverContext(driver_name, &err_msg, &mapDrvAttrib);
  196.   }
  197.   else{
  198.     my_context = drv_mgr.GetDriverContext( driver_name, &err_msg );
  199.   }
  200.   if(!my_context) {
  201.     cerr << "Can not load a driver " << driver_name
  202.          << " [" << err_msg << "]n";
  203.     return 1;
  204.   }
  205.   try {
  206.     // Prepare the connection
  207.     con = my_context->Connect(
  208.         server_name, "anyone", "allowed", I_DriverContext::fBcpIn);
  209.     CDB_LangCmd* set_cmd= con->LangCmd("use DBAPI_Sample");
  210.     set_cmd->Send();
  211.     CDB_Result* r;
  212.     while(set_cmd->HasMoreResults()) {
  213.       r= set_cmd->Result();
  214.       if(r) delete r;
  215.     }
  216.     delete set_cmd;
  217.     set_cmd= con->LangCmd("set textsize 1024000");
  218.     set_cmd->Send();
  219.     while(set_cmd->HasMoreResults()) {
  220.       r= set_cmd->Result();
  221.       if(r) delete r;
  222.     }
  223.     delete set_cmd;
  224.     //cout<< "driver " << driver_name;
  225.     // Create table, insert data
  226.     if(!selectOnly) {
  227.       CreateTable(con, table_name); // Deletes the pre-existing table, if present
  228.       cout<< ", rows " << row_count
  229.           << ", cols " << col_count
  230.           << ", blob size " << blob_size << "n";
  231.       if(col_count>4) {
  232.         // "Bulk copy in" command
  233.         bcp = con->BCPIn(table_name, col_count);
  234.       }
  235.       else {
  236.         //cerr << "-c option not supported yetn";
  237.         //return 1;
  238.         string s  = "insert into ";
  239.         s+= table_name;
  240.         s+= " (int_val";
  241.         string sv = "@i";
  242.         if(col_count>1) { s+= ", fl_val"  ; sv+=", @f"; }
  243.         if(col_count>2) { s+= ", date_val"; sv+=", @d"; }
  244.         if(col_count>3) { s+= ", str_val" ; sv+=", @s"; }
  245.         s+= ") values (";
  246.         s+= sv;
  247.         s+= ")";
  248.         ins_cmd = con->LangCmd(s);
  249.       }
  250.       CDB_Int int_val;
  251.       CDB_Float fl_val;
  252.       CDB_DateTime date_val(CTime::eCurrent);
  253.       CDB_VarChar str_val;
  254.       CDB_Text pTxt;
  255.       int i;
  256.       if(fileParam) {
  257.         CNcbiIfstream f(fileParam, IOS_BASE::in|IOS_BASE::binary);
  258.         if(!f.is_open()) {
  259.           cerr << "Error -- cannot read '" << fileParam << "'n";
  260.           return 1;
  261.         }
  262.         char buf[10240];
  263.         int sz;
  264.         while( f.good() && !f.eof() ) {
  265.           f.read( buf, sizeof(buf) );
  266.           sz = f.gcount();
  267.           // cout << sz << "n";
  268.           if( sz <= 0 ) break;
  269.           pTxt.Append(buf, sz);
  270.           if( sz != sizeof(buf) ) break;
  271.         }
  272.         f.close();
  273.         // cout << "pTxt.Size()=" << pTxt.Size() << "n";
  274.         col_count=5;
  275.         row_count=1;
  276.       }
  277.       else if(col_count>4) {
  278.         for(i=0; i<blob_size; i++) {
  279.           // Add 1024 chars
  280.           for( int j=0; j<32; j++ ) {
  281.             pTxt.Append("If you want to know who we are--");
  282.           }
  283.         }
  284.       }
  285.       timer.Start();
  286.       // Bind program variables as data source
  287.       if(bcp) {
  288.         bcp->Bind(0, &int_val);
  289.         if(col_count>1) bcp->Bind(1, &fl_val  );
  290.         if(col_count>2) bcp->Bind(2, &date_val);
  291.         if(col_count>3) bcp->Bind(3, &str_val );
  292.         if(col_count>4) bcp->Bind(4, &pTxt    );
  293.       }
  294.       else{
  295.         if( !ins_cmd->BindParam("@i", &int_val) ) {
  296.           cerr << "Error in BindParam()n";
  297.           DeleteTable(con, table_name);
  298.           return 1;
  299.         }
  300.         if(col_count>1) ins_cmd->BindParam("@f", &fl_val  );
  301.         if(col_count>2) ins_cmd->BindParam("@d", &date_val);
  302.         if(col_count>3) ins_cmd->BindParam("@s", &str_val );
  303.       }
  304.       for(i= 0; i<row_count; i++) {
  305.         int_val  = i;
  306.         fl_val   = i + 0.999;
  307.         if(fileParam) {
  308.           CDirEntry fileEntry(fileParam);
  309.           CTime fileTime;
  310.           fileEntry.GetTime(&fileTime);
  311.           date_val = fileTime;
  312.           str_val = fileParam;
  313.         }
  314.         else {
  315.           date_val = date_val.Value();
  316.           str_val  = string("Franz Joseph Haydn symphony # ")+NStr::IntToString(i);
  317.         }
  318.         pTxt.MoveTo(0);
  319.         if( bcp ) {
  320.           bcp->SendRow();
  321.           if (count == 2) {
  322.             bcp->CompleteBatch();
  323.             count = 0;
  324.           }
  325.           count++;
  326.         }
  327.         else {
  328.           ins_cmd->Send();
  329.           CDB_Result* r;
  330.           while(ins_cmd->HasMoreResults()) {
  331.             r= ins_cmd->Result();
  332.             if(r) delete r;
  333.           }
  334.         }
  335.       }
  336.       if( bcp ) {
  337.         bcp->CompleteBCP();
  338.         delete bcp;
  339.       }
  340.       if( ins_cmd ) {
  341.         delete ins_cmd;
  342.       }
  343.       timeElapsed = timer.Elapsed();
  344.       cout << "inserting timeElapsed=" << NStr::DoubleToString(timeElapsed, 2) << "n";
  345.     }
  346.     else{
  347.       cout << "n";
  348.     }
  349.     if(!writeOnly) {
  350.       // Read data
  351.       timer.Start();
  352.       if(fileParam) {
  353.         FetchFile(con, table_name, readItems);
  354.       }
  355.       else {
  356.         FetchResults(con, table_name, readItems);
  357.       }
  358.       timeElapsed = timer.Elapsed();
  359.       cout << "fetching timeElapsed=" << NStr::DoubleToString(timeElapsed,2) << "n";
  360.       cout << "n";
  361.     }
  362.     if(!(selectOnly || writeOnly)) {
  363.       DeleteTable(con, table_name);
  364.     }
  365.     delete con;
  366.   }
  367.   catch (CDB_Exception& e) {
  368.     HandleIt(&e);
  369.     //DeleteTable(con, table_name);
  370.     return 1;
  371.   }
  372.   return 0;
  373. }