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

生物技术

开发平台:

C/C++

  1. /*
  2.  * ===========================================================================
  3.  * PRODUCTION $Log: bcp.cpp,v $
  4.  * PRODUCTION Revision 1000.1  2004/06/01 19:20:00  gouriano
  5.  * PRODUCTION PRODUCTION: UPGRADED [GCC34_MSVC7] Dev-tree R1.10
  6.  * PRODUCTION
  7.  * ===========================================================================
  8.  */
  9. /* $Id: bcp.cpp,v 1000.1 2004/06/01 19:20:00 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.  * Author:  Vladimir Soussov
  35.  *
  36.  * File Description:  DBLib bcp-in command
  37.  *
  38.  */
  39. #include <ncbi_pch.hpp>
  40. #ifndef USE_MS_DBLIB
  41. #  include <dbapi/driver/dblib/interfaces.hpp>
  42. #  include <dbapi/driver/dblib/interfaces_p.hpp>
  43. #else
  44. #  include <dbapi/driver/msdblib/interfaces.hpp>
  45. #  include <dbapi/driver/msdblib/interfaces_p.hpp>
  46. #endif
  47. #include <dbapi/driver/util/numeric_convert.hpp>
  48. #include <string.h>
  49. BEGIN_NCBI_SCOPE
  50. /////////////////////////////////////////////////////////////////////////////
  51. //
  52. //  CDBL_BCPInCmd::
  53. //
  54. CDBL_BCPInCmd::CDBL_BCPInCmd(CDBL_Connection* con,
  55.                              DBPROCESS*       cmd,
  56.                              const string&    table_name,
  57.                              unsigned int     nof_columns) :
  58.     m_Connect(con), m_Cmd(cmd), m_Params(nof_columns),
  59.     m_WasSent(false), m_HasFailed(false),
  60.     m_HasTextImage(false), m_WasBound(false)
  61. {
  62.     if (bcp_init(cmd, (char*) table_name.c_str(), 0, 0, DB_IN) != SUCCEED) {
  63.         throw CDB_ClientEx(eDB_Fatal, 223001,
  64.                            "CDBL_BCPInCmd::CDBL_BCPInCmd", "bcp_init failed");
  65.     }
  66. }
  67. bool CDBL_BCPInCmd::Bind(unsigned int column_num, CDB_Object* param_ptr)
  68. {
  69.     return m_Params.BindParam(column_num,  kEmptyStr, param_ptr);
  70. }
  71. bool CDBL_BCPInCmd::x_AssignParams(void* pb)
  72. {
  73.     RETCODE r;
  74.     if (!m_WasBound) {
  75.         for (unsigned int i = 0; i < m_Params.NofParams(); i++) {
  76.             if (m_Params.GetParamStatus(i) == 0)
  77.                 continue;
  78.             CDB_Object& param = *m_Params.GetParam(i);
  79.             switch ( param.GetType() ) {
  80.             case eDB_Int: {
  81.                 CDB_Int& val = dynamic_cast<CDB_Int&> (param);
  82.                 // DBINT v = (DBINT) val.Value();
  83.                 r = bcp_bind(m_Cmd, (BYTE*) val.BindVal(), 0,
  84.                              val.IsNULL() ? 0 : -1, 0, 0, SYBINT4, i + 1);
  85.             }
  86.             break;
  87.             case eDB_SmallInt: {
  88.                 CDB_SmallInt& val = dynamic_cast<CDB_SmallInt&> (param);
  89.                 // DBSMALLINT v = (DBSMALLINT) val.Value();
  90.                 r = bcp_bind(m_Cmd, (BYTE*) val.BindVal(), 0,
  91.                              val.IsNULL() ? 0 : -1, 0, 0, SYBINT2, i + 1);
  92.             }
  93.             break;
  94.             case eDB_TinyInt: {
  95.                 CDB_TinyInt& val = dynamic_cast<CDB_TinyInt&> (param);
  96.                 // DBTINYINT v = (DBTINYINT) val.Value();
  97.                 r = bcp_bind(m_Cmd, (BYTE*) val.BindVal(), 0,
  98.                              val.IsNULL() ? 0 : -1, 0, 0, SYBINT1, i + 1);
  99.             }
  100.             break;
  101.             case eDB_BigInt: {
  102.                 CDB_BigInt& val = dynamic_cast<CDB_BigInt&> (param);
  103.                 DBNUMERIC* v = reinterpret_cast<DBNUMERIC*> (pb);
  104.                 Int8 v8 = val.Value();
  105.                 if (longlong_to_numeric(v8, 18, DBNUMERIC_val(v)) == 0)
  106.                     return false;
  107.                 r = bcp_bind(m_Cmd, (BYTE*) v, 0,
  108.                              val.IsNULL() ? 0 : -1, 0, 0, SYBNUMERIC, i + 1);
  109.                 pb = (void*) (v + 1);
  110.             }
  111.             break;
  112.             case eDB_Char: {
  113.                 CDB_Char& val = dynamic_cast<CDB_Char&> (param);
  114.                 r = bcp_bind(m_Cmd, (BYTE*) val.Value(), 0,
  115.                              val.IsNULL() ? 0 : -1,
  116.                              (BYTE*) "", 1, SYBCHAR, i + 1);
  117.             }
  118.             break;
  119.             case eDB_VarChar: {
  120.                 CDB_VarChar& val = dynamic_cast<CDB_VarChar&> (param);
  121.                 r = bcp_bind(m_Cmd, (BYTE*) val.Value(), 0,
  122.                              val.IsNULL() ? 0 : -1,
  123.                              (BYTE*) "", 1, SYBCHAR, i + 1);
  124.             }
  125.             break;
  126.             case eDB_Binary: {
  127.                 CDB_Binary& val = dynamic_cast<CDB_Binary&> (param);
  128.                 r = bcp_bind(m_Cmd, (BYTE*) val.Value(), 0,
  129.                              val.IsNULL() ? 0 : (DBINT) val.Size(),
  130.                              0, 0, SYBBINARY, i + 1);
  131.             }
  132.             break;
  133.             case eDB_VarBinary: {
  134.                 CDB_VarBinary& val = dynamic_cast<CDB_VarBinary&> (param);
  135.                 r = bcp_bind(m_Cmd, (BYTE*) val.Value(), 0,
  136.                              val.IsNULL() ? 0 : (DBINT) val.Size(),
  137.                              0, 0, SYBBINARY, i + 1);
  138.             }
  139.             break;
  140.             case eDB_Float: {
  141.                 CDB_Float& val = dynamic_cast<CDB_Float&> (param);
  142.                 // DBREAL v = (DBREAL) val.Value();
  143.                 r = bcp_bind(m_Cmd, (BYTE*) val.BindVal(), 0,
  144.                              val.IsNULL() ? 0 : -1, 0, 0, SYBREAL, i + 1);
  145.             }
  146.             break;
  147.             case eDB_Double: {
  148.                 CDB_Double& val = dynamic_cast<CDB_Double&> (param);
  149.                 // DBFLT8 v = (DBFLT8) val.Value();
  150.                 r = bcp_bind(m_Cmd, (BYTE*) val.BindVal(), 0,
  151.                              val.IsNULL() ? 0 : -1, 0, 0, SYBFLT8, i + 1);
  152.             }
  153.             break;
  154.             case eDB_SmallDateTime: {
  155.                 CDB_SmallDateTime& val =
  156.                     dynamic_cast<CDB_SmallDateTime&> (param);
  157.                 DBDATETIME4* dt = (DBDATETIME4*) pb;
  158.                 DBDATETIME4_days(dt)        = val.GetDays();
  159.                 DBDATETIME4_mins(dt)     = val.GetMinutes();
  160.                 r = bcp_bind(m_Cmd, (BYTE*) dt, 0, val.IsNULL() ? 0 : -1,
  161.                              0, 0, SYBDATETIME4,  i + 1);
  162.                 pb = (void*) (dt + 1);
  163.             }
  164.             break;
  165.             case eDB_DateTime: {
  166.                 CDB_DateTime& val = dynamic_cast<CDB_DateTime&> (param);
  167.                 DBDATETIME* dt = (DBDATETIME*) pb;
  168.                 dt->dtdays     = val.GetDays();
  169.                 dt->dttime     = val.Get300Secs();
  170.                 r = bcp_bind(m_Cmd, (BYTE*) dt, 0, val.IsNULL() ? 0 : -1,
  171.                              0, 0, SYBDATETIME, i + 1);
  172.                 pb = (void*) (dt + 1);
  173.             }
  174.             break;
  175.             case eDB_Text: {
  176.                 CDB_Text& val = dynamic_cast<CDB_Text&> (param);
  177.                 r = bcp_bind(m_Cmd, 0, 0,
  178.                              val.IsNULL() ? 0 : (DBINT) val.Size(),
  179.                              0, 0, SYBTEXT, i + 1);
  180.                 m_HasTextImage = true;
  181.             }
  182.             break;
  183.             case eDB_Image: {
  184.                 CDB_Image& val = dynamic_cast<CDB_Image&> (param);
  185.                 r = bcp_bind(m_Cmd, 0, 0,
  186.                              val.IsNULL() ? 0 : (DBINT) val.Size(),
  187.                              0, 0, SYBIMAGE, i + 1);
  188.                 m_HasTextImage = true;
  189.             }
  190.             break;
  191.             default:
  192.                 return false;
  193.             }
  194.             if (r != CS_SUCCEED)
  195.                 return false;
  196.         }
  197.         m_WasBound = true;
  198.     } else {
  199.         for (unsigned int i = 0; i < m_Params.NofParams(); i++) {
  200.             if (m_Params.GetParamStatus(i) == 0)
  201.                 continue;
  202.             CDB_Object& param = *m_Params.GetParam(i);
  203.             switch ( param.GetType() ) {
  204.             case eDB_Int: {
  205.                 CDB_Int& val = dynamic_cast<CDB_Int&> (param);
  206.                 // DBINT v = (DBINT) val.Value();
  207.                 r = bcp_colptr(m_Cmd, (BYTE*) val.BindVal(), i + 1)
  208.                     == SUCCEED &&
  209.                     bcp_collen(m_Cmd,  val.IsNULL() ? 0 : -1, i + 1)
  210.                     == SUCCEED ? SUCCEED : FAIL;
  211.             }
  212.             break;
  213.             case eDB_SmallInt: {
  214.                 CDB_SmallInt& val = dynamic_cast<CDB_SmallInt&> (param);
  215.                 // DBSMALLINT v = (DBSMALLINT) val.Value();
  216.                 r = bcp_colptr(m_Cmd, (BYTE*) val.BindVal(), i + 1)
  217.                     == SUCCEED &&
  218.                     bcp_collen(m_Cmd,  val.IsNULL() ? 0 : -1, i + 1)
  219.                     == SUCCEED ? SUCCEED : FAIL;
  220.             }
  221.             break;
  222.             case eDB_TinyInt: {
  223.                 CDB_TinyInt& val = dynamic_cast<CDB_TinyInt&> (param);
  224.                 // DBTINYINT v = (DBTINYINT) val.Value();
  225.                 r = bcp_colptr(m_Cmd, (BYTE*) val.BindVal(), i + 1)
  226.                     == SUCCEED &&
  227.                     bcp_collen(m_Cmd, val.IsNULL() ? 0 : -1, i + 1)
  228.                     == SUCCEED ? SUCCEED : FAIL;
  229.             }
  230.             break;
  231.             case eDB_BigInt: {
  232.                 CDB_BigInt& val = dynamic_cast<CDB_BigInt&> (param);
  233.                 DBNUMERIC* v = (DBNUMERIC*) pb;
  234.                 Int8 v8 = val.Value();
  235.                 if (longlong_to_numeric(v8, 18, DBNUMERIC_val(v)) == 0)
  236.                     return false;
  237.                 r = bcp_colptr(m_Cmd, (BYTE*) v, i + 1)
  238.                     == SUCCEED &&
  239.                     bcp_collen(m_Cmd,  val.IsNULL() ? 0 : -1, i + 1)
  240.                     == SUCCEED ? SUCCEED : FAIL;
  241.                 pb = (void*) (v + 1);
  242.             }
  243.             break;
  244.             case eDB_Char: {
  245.                 CDB_Char& val = dynamic_cast<CDB_Char&> (param);
  246.                 r = bcp_colptr(m_Cmd, (BYTE*) val.Value(), i + 1)
  247.                     == SUCCEED &&
  248.                     bcp_collen(m_Cmd, val.IsNULL() ? 0 : -1, i + 1)
  249.                     == SUCCEED ? SUCCEED : FAIL;
  250.             }
  251.             break;
  252.             case eDB_VarChar: {
  253.                 CDB_VarChar& val = dynamic_cast<CDB_VarChar&> (param);
  254.                 r = bcp_colptr(m_Cmd, (BYTE*) val.Value(), i + 1)
  255.                     == SUCCEED &&
  256.                     bcp_collen(m_Cmd, val.IsNULL() ? 0 : -1, i + 1)
  257.                     == SUCCEED ? SUCCEED : FAIL;
  258.             }
  259.             break;
  260.             case eDB_Binary: {
  261.                 CDB_Binary& val = dynamic_cast<CDB_Binary&> (param);
  262.                 r = bcp_colptr(m_Cmd, (BYTE*) val.Value(), i + 1)
  263.                     == SUCCEED &&
  264.                     bcp_collen(m_Cmd,
  265.                                val.IsNULL() ? 0 : (DBINT) val.Size(), i + 1)
  266.                     == SUCCEED ? SUCCEED : FAIL;
  267.             }
  268.             break;
  269.             case eDB_VarBinary: {
  270.                 CDB_VarBinary& val = dynamic_cast<CDB_VarBinary&> (param);
  271.                 r = bcp_colptr(m_Cmd, (BYTE*) val.Value(), i + 1)
  272.                     == SUCCEED &&
  273.                     bcp_collen(m_Cmd,
  274.                                val.IsNULL() ? 0 : (DBINT) val.Size(), i + 1)
  275.                     == SUCCEED ? SUCCEED : FAIL;
  276.             }
  277.             break;
  278.             case eDB_Float: {
  279.                 CDB_Float& val = dynamic_cast<CDB_Float&> (param);
  280.                 //DBREAL v = (DBREAL) val.Value();
  281.                 r = bcp_colptr(m_Cmd, (BYTE*) val.BindVal(), i + 1)
  282.                     == SUCCEED &&
  283.                     bcp_collen(m_Cmd,  val.IsNULL() ? 0 : -1, i + 1)
  284.                     == SUCCEED ? SUCCEED : FAIL;
  285.             }
  286.             break;
  287.             case eDB_Double: {
  288.                 CDB_Double& val = dynamic_cast<CDB_Double&> (param);
  289.                 //DBFLT8 v = (DBFLT8) val.Value();
  290.                 r = bcp_bind(m_Cmd, (BYTE*) val.BindVal(), 0,
  291.                              val.IsNULL() ? 0 : -1, 0, 0, SYBFLT8, i + 1);
  292.             }
  293.             break;
  294.             case eDB_SmallDateTime: {
  295.                 CDB_SmallDateTime& val =
  296.                     dynamic_cast<CDB_SmallDateTime&> (param);
  297.                 DBDATETIME4* dt = (DBDATETIME4*) pb;
  298.                 DBDATETIME4_days(dt)        = val.GetDays();
  299.                 DBDATETIME4_mins(dt)     = val.GetMinutes();
  300.                 r = bcp_colptr(m_Cmd, (BYTE*) dt, i + 1)
  301.                     == SUCCEED &&
  302.                     bcp_collen(m_Cmd, val.IsNULL() ? 0 : -1, i + 1)
  303.                     == SUCCEED ? SUCCEED : FAIL;
  304.                 pb = (void*) (dt + 1);
  305.             }
  306.             break;
  307.             case eDB_DateTime: {
  308.                 CDB_DateTime& val = dynamic_cast<CDB_DateTime&> (param);
  309.                 DBDATETIME* dt = (DBDATETIME*) pb;
  310.                 dt->dtdays     = val.GetDays();
  311.                 dt->dttime     = val.Get300Secs();
  312.                 r = bcp_colptr(m_Cmd, (BYTE*) dt, i + 1)
  313.                     == SUCCEED &&
  314.                     bcp_collen(m_Cmd, val.IsNULL() ? 0 : -1, i + 1)
  315.                     == SUCCEED ? SUCCEED : FAIL;
  316.                 pb = (void*) (dt + 1);
  317.             }
  318.             break;
  319.             case eDB_Text: {
  320.                 CDB_Text& val = dynamic_cast<CDB_Text&> (param);
  321.                 r = bcp_collen(m_Cmd, (DBINT) val.Size(), i + 1);
  322.             }
  323.             break;
  324.             case eDB_Image: {
  325.                 CDB_Image& val = dynamic_cast<CDB_Image&> (param);
  326.                 r = bcp_collen(m_Cmd, (DBINT) val.Size(), i + 1);
  327.             }
  328.             break;
  329.             default:
  330.                 return false;
  331.             }
  332.             if (r != CS_SUCCEED)
  333.                 return false;
  334.         }
  335.     }
  336.     return true;
  337. }
  338. bool CDBL_BCPInCmd::SendRow()
  339. {
  340.     char param_buff[2048]; // maximal row size, assured of buffer overruns
  341.     if (!x_AssignParams(param_buff)) {
  342.         m_HasFailed = true;
  343.         throw CDB_ClientEx(eDB_Error, 223004,
  344.                            "CDBL_BCPInCmd::SendRow", "cannot assign params");
  345.     }
  346.     if (bcp_sendrow(m_Cmd) != SUCCEED) {
  347.         m_HasFailed = true;
  348.         throw CDB_ClientEx(eDB_Error, 223005,
  349.                            "CDBL_BCPInCmd::SendRow", "bcp_sendrow failed");
  350.     }
  351.     m_WasSent = true;
  352.     if (m_HasTextImage) { // send text/image data
  353.         char buff[1800]; // text/image page size
  354.         for (unsigned int i = 0; i < m_Params.NofParams(); i++) {
  355.             if (m_Params.GetParamStatus(i) == 0)
  356.                 continue;
  357.             CDB_Object& param = *m_Params.GetParam(i);
  358.             if (param.GetType() != eDB_Text &&
  359.                 param.GetType() != eDB_Image)
  360.                 continue;
  361.             CDB_Stream& val = dynamic_cast<CDB_Stream&> (param);
  362.             size_t s = val.Size();
  363.             do {
  364.                 size_t l = val.Read(buff, sizeof(buff));
  365.                 if (l > s)
  366.                     l = s;
  367.                 if (bcp_moretext(m_Cmd, (DBINT) l, (BYTE*) buff) != SUCCEED) {
  368.                     m_HasFailed = true;
  369.                     throw CDB_ClientEx(eDB_Error, 223006,
  370.                                        "CDBL_BCPInCmd::SendRow",
  371.                                        param.GetType() == eDB_Text ?
  372.                                        "bcp_moretext for text failed" :
  373.                                        "bcp_moretext for image failed");
  374.                 }
  375.                 if (!l)
  376.                     break;
  377.                 s -= l;
  378.             } while (s);
  379.         }
  380.     }
  381.     return true;
  382. }
  383. bool CDBL_BCPInCmd::Cancel()
  384. {
  385.     if(m_WasSent) {
  386. DBINT outrow = bcp_done(m_Cmd);
  387. m_WasSent= false;
  388. return outrow == 0;
  389.     }
  390.     return true;
  391. }
  392. bool CDBL_BCPInCmd::CompleteBatch()
  393. {
  394.     if(m_WasSent) {
  395. CS_INT outrow = bcp_batch(m_Cmd);
  396. return outrow != -1;
  397.     }
  398.     return false;
  399. }
  400. bool CDBL_BCPInCmd::CompleteBCP()
  401. {
  402.     if(m_WasSent) {
  403. DBINT outrow = bcp_done(m_Cmd);
  404. m_WasSent= false;
  405. return outrow != -1;
  406.     }
  407.     return false;
  408. }
  409. void CDBL_BCPInCmd::Release()
  410. {
  411.     m_BR = 0;
  412.     if (m_WasSent) {
  413.         Cancel();
  414.         m_WasSent = false;
  415.     }
  416.     m_Connect->DropCmd(*this);
  417.     delete this;
  418. }
  419. CDBL_BCPInCmd::~CDBL_BCPInCmd()
  420. {
  421.     if (m_BR)
  422.         *m_BR = 0;
  423.     if (m_WasSent)
  424.         Cancel();
  425. }
  426. END_NCBI_SCOPE
  427. /*
  428.  * ===========================================================================
  429.  * $Log: bcp.cpp,v $
  430.  * Revision 1000.1  2004/06/01 19:20:00  gouriano
  431.  * PRODUCTION: UPGRADED [GCC34_MSVC7] Dev-tree R1.10
  432.  *
  433.  * Revision 1.10  2004/05/18 18:30:36  gorelenk
  434.  * PCH <ncbi_pch.hpp> moved to correct place .
  435.  *
  436.  * Revision 1.9  2004/05/17 21:12:41  gorelenk
  437.  * Added include of PCH ncbi_pch.hpp
  438.  *
  439.  * Revision 1.8  2002/07/02 16:05:49  soussov
  440.  * splitting Sybase dblib and MS dblib
  441.  *
  442.  * Revision 1.7  2002/03/04 19:07:21  soussov
  443.  * fixed bug in m_WasSent flag setting
  444.  *
  445.  * Revision 1.6  2002/01/08 18:10:18  sapojnik
  446.  * Syabse to MSSQL name translations moved to interface_p.hpp
  447.  *
  448.  * Revision 1.5  2002/01/03 17:01:56  sapojnik
  449.  * fixing CR/LF mixup
  450.  *
  451.  * Revision 1.4  2002/01/03 15:46:23  sapojnik
  452.  * ported to MS SQL (about 12 'ifdef NCBI_OS_MSWIN' in 6 files)
  453.  *
  454.  * Revision 1.3  2001/10/24 16:38:53  lavr
  455.  * Explicit casts (where necessary) to eliminate 64->32 bit compiler warnings
  456.  *
  457.  * Revision 1.2  2001/10/22 18:38:49  soussov
  458.  * sending NULL instead of emty string fixed
  459.  *
  460.  * Revision 1.1  2001/10/22 15:19:55  lavr
  461.  * This is a major revamp (by Anton Lavrentiev, with help from Vladimir
  462.  * Soussov and Denis Vakatov) of the DBAPI "driver" libs originally
  463.  * written by Vladimir Soussov. The revamp follows the one of CTLib
  464.  * driver, and it involved massive code shuffling and grooming, numerous
  465.  * local API redesigns, adding comments and incorporating DBAPI to
  466.  * the C++ Toolkit.
  467.  *
  468.  * ===========================================================================
  469.  */