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

生物技术

开发平台:

C/C++

  1. /*
  2.  * ===========================================================================
  3.  * PRODUCTION $Log: bcp.cpp,v $
  4.  * PRODUCTION Revision 1000.1  2004/06/01 19:20:40  gouriano
  5.  * PRODUCTION PRODUCTION: UPGRADED [GCC34_MSVC7] Dev-tree R1.6
  6.  * PRODUCTION
  7.  * ===========================================================================
  8.  */
  9. /* $Id: bcp.cpp,v 1000.1 2004/06/01 19:20:40 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:  TDS bcp-in command
  37.  *
  38.  */
  39. #include <ncbi_pch.hpp>
  40. #include <dbapi/driver/ftds/interfaces.hpp>
  41. #include <dbapi/driver/util/numeric_convert.hpp>
  42. #include <string.h>
  43. BEGIN_NCBI_SCOPE
  44. /////////////////////////////////////////////////////////////////////////////
  45. //
  46. //  CTDS_BCPInCmd::
  47. //
  48. CTDS_BCPInCmd::CTDS_BCPInCmd(CTDS_Connection* con,
  49.                              DBPROCESS*       cmd,
  50.                              const string&    table_name,
  51.                              unsigned int     nof_columns) :
  52.     m_Connect(con), m_Cmd(cmd), m_Params(nof_columns),
  53.     m_WasSent(false), m_HasFailed(false),
  54.     m_HasTextImage(false), m_WasBound(false)
  55. {
  56.     if (bcp_init(cmd, (char*) table_name.c_str(), 0, 0, DB_IN) != SUCCEED) {
  57.         throw CDB_ClientEx(eDB_Fatal, 223001,
  58.                            "CTDS_BCPInCmd::CTDS_BCPInCmd", "bcp_init failed");
  59.     }
  60. }
  61. bool CTDS_BCPInCmd::Bind(unsigned int column_num, CDB_Object* param_ptr)
  62. {
  63.     return m_Params.BindParam(column_num,  kEmptyStr, param_ptr);
  64. }
  65. bool CTDS_BCPInCmd::x_AssignParams(void* pb)
  66. {
  67.     RETCODE r;
  68.     if (!m_WasBound) {
  69.         for (unsigned int i = 0; i < m_Params.NofParams(); i++) {
  70.             if (m_Params.GetParamStatus(i) == 0)
  71.                 continue;
  72.             CDB_Object& param = *m_Params.GetParam(i);
  73.             
  74.             switch ( param.GetType() ) {
  75.             case eDB_Int: {
  76.                 CDB_Int& val = dynamic_cast<CDB_Int&> (param);
  77.                 // DBINT v = (DBINT) val.Value();
  78.                 r = bcp_bind(m_Cmd, (BYTE*) val.BindVal(), 0,
  79.                              val.IsNULL() ? 0 : -1, 0, 0, SYBINT4, i + 1);
  80.             }
  81.             break;
  82.             case eDB_SmallInt: {
  83.                 CDB_SmallInt& val = dynamic_cast<CDB_SmallInt&> (param);
  84.                 // DBSMALLINT v = (DBSMALLINT) val.Value();
  85.                 r = bcp_bind(m_Cmd, (BYTE*) val.BindVal(), 0,
  86.                              val.IsNULL() ? 0 : -1, 0, 0, SYBINT2, i + 1);
  87.             }
  88.             break;
  89.             case eDB_TinyInt: {
  90.                 CDB_TinyInt& val = dynamic_cast<CDB_TinyInt&> (param);
  91.                 // DBTINYINT v = (DBTINYINT) val.Value();
  92.                 r = bcp_bind(m_Cmd, (BYTE*) val.BindVal(), 0,
  93.                              val.IsNULL() ? 0 : -1, 0, 0, SYBINT1, i + 1);
  94.             }
  95.             break;
  96.             case eDB_BigInt: {
  97.                 CDB_BigInt& val = dynamic_cast<CDB_BigInt&> (param);
  98.                 DBNUMERIC* v = reinterpret_cast<DBNUMERIC*> (pb);
  99.                 Int8 v8 = val.Value();
  100.                 v->precision= 18;
  101.                 v->scale= 0;
  102.                 if (longlong_to_numeric(v8, 18, v->array) == 0)
  103.                     return false;
  104.                 r = bcp_bind(m_Cmd, (BYTE*) v, 0,
  105.                              val.IsNULL() ? 0 : -1, 0, 0, SYBNUMERIC, i + 1);
  106.                 pb = (void*) (v + 1);
  107.             }
  108.             break;
  109.             case eDB_Char: {
  110.                 CDB_Char& val = dynamic_cast<CDB_Char&> (param);
  111.                 r = bcp_bind(m_Cmd, (BYTE*) val.Value(), 0,
  112.                              val.IsNULL() ? 0 : -1,
  113.                              (BYTE*) "", 1, SYBCHAR, i + 1);
  114.             }
  115.             break;
  116.             case eDB_VarChar: {
  117.                 CDB_VarChar& val = dynamic_cast<CDB_VarChar&> (param);
  118.                 r = bcp_bind(m_Cmd, (BYTE*) val.Value(), 0,
  119.                              val.IsNULL() ? 0 : -1,
  120.                              (BYTE*) "", 1, SYBCHAR, i + 1);
  121.             }
  122.             break;
  123.             case eDB_LongChar: {
  124.                 CDB_LongChar& val = dynamic_cast<CDB_LongChar&> (param);
  125.                 r = bcp_bind(m_Cmd, (BYTE*) val.Value(), 0,
  126.                              val.IsNULL() ? 0 : -1,
  127.                              (BYTE*) "", 1, SYBCHAR, i + 1);
  128.             }
  129.             break;
  130.             case eDB_Binary: {
  131.                 CDB_Binary& val = dynamic_cast<CDB_Binary&> (param);
  132.                 r = bcp_bind(m_Cmd, (BYTE*) val.Value(), 0,
  133.                              val.IsNULL() ? 0 : val.Size(),
  134.                              0, 0, SYBBINARY, i + 1);
  135.             }
  136.             break;
  137.             case eDB_VarBinary: {
  138.                 CDB_VarBinary& val = dynamic_cast<CDB_VarBinary&> (param);
  139.                 r = bcp_bind(m_Cmd, (BYTE*) val.Value(), 0,
  140.                              val.IsNULL() ? 0 : val.Size(),
  141.                              0, 0, SYBBINARY, i + 1);
  142.             }
  143.             break;
  144.             case eDB_LongBinary: {
  145.                 CDB_LongBinary& val = dynamic_cast<CDB_LongBinary&> (param);
  146.                 r = bcp_bind(m_Cmd, (BYTE*) val.Value(), 0,
  147.                              val.IsNULL() ? 0 : val.DataSize(),
  148.                              0, 0, SYBBINARY, i + 1);
  149.             }
  150.             break;
  151.             case eDB_Float: {
  152.                 CDB_Float& val = dynamic_cast<CDB_Float&> (param);
  153.                 // DBREAL v = (DBREAL) val.Value();
  154.                 r = bcp_bind(m_Cmd, (BYTE*) val.BindVal(), 0,
  155.                              val.IsNULL() ? 0 : -1, 0, 0, SYBREAL, i + 1);
  156.             }
  157.             break;
  158.             case eDB_Double: {
  159.                 CDB_Double& val = dynamic_cast<CDB_Double&> (param);
  160.                 // DBFLT8 v = (DBFLT8) val.Value();
  161.                 r = bcp_bind(m_Cmd, (BYTE*) val.BindVal(), 0,
  162.                              val.IsNULL() ? 0 : -1, 0, 0, SYBFLT8, i + 1);
  163.             }
  164.             break;
  165.             case eDB_SmallDateTime: {
  166.                 CDB_SmallDateTime& val =
  167.                     dynamic_cast<CDB_SmallDateTime&> (param);
  168.                 DBDATETIME4* dt = (DBDATETIME4*) pb;
  169.                 dt->days        = val.GetDays();
  170.                 dt->minutes     = val.GetMinutes();
  171.                 r = bcp_bind(m_Cmd, (BYTE*) dt, 0, val.IsNULL() ? 0 : -1,
  172.                              0, 0, SYBDATETIME4,  i + 1);
  173.                 pb = (void*) (dt + 1);
  174.             }
  175.             break;
  176.             case eDB_DateTime: {
  177.                 CDB_DateTime& val = dynamic_cast<CDB_DateTime&> (param);
  178.                 DBDATETIME* dt = (DBDATETIME*) pb;
  179.                 dt->dtdays     = val.GetDays();
  180.                 dt->dttime     = val.Get300Secs();
  181.                 r = bcp_bind(m_Cmd, (BYTE*) dt, 0, val.IsNULL() ? 0 : -1,
  182.                              0, 0, SYBDATETIME, i + 1);
  183.                 pb = (void*) (dt + 1);
  184.             }
  185.             break;
  186.             case eDB_Text: {
  187.                 CDB_Text& val = dynamic_cast<CDB_Text&> (param);
  188.                 r = bcp_bind(m_Cmd, 0, 0, val.IsNULL() ? 0 : val.Size(),
  189.                              0, 0, SYBTEXT, i + 1);
  190.                 m_HasTextImage = true;
  191.             }
  192.             break;
  193.             case eDB_Image: {
  194.                 CDB_Image& val = dynamic_cast<CDB_Image&> (param);
  195.                 r = bcp_bind(m_Cmd, 0, 0, val.IsNULL() ? 0 : val.Size(),
  196.                              0, 0, SYBIMAGE, i + 1);
  197.                 m_HasTextImage = true;
  198.             }
  199.             break;
  200.             default:
  201.                 return false;
  202.             }
  203.             if (r != CS_SUCCEED)
  204.                 return false;
  205.         }
  206.         m_WasBound = true;
  207.     } else {
  208.         for (unsigned int i = 0; i < m_Params.NofParams(); i++) {
  209.             if (m_Params.GetParamStatus(i) == 0)
  210.                 continue;
  211.             CDB_Object& param = *m_Params.GetParam(i);
  212.             switch ( param.GetType() ) {
  213.             case eDB_Int: {
  214.                 CDB_Int& val = dynamic_cast<CDB_Int&> (param);
  215.                 // DBINT v = (DBINT) 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_SmallInt: {
  223.                 CDB_SmallInt& val = dynamic_cast<CDB_SmallInt&> (param);
  224.                 // DBSMALLINT v = (DBSMALLINT) 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_TinyInt: {
  232.                 CDB_TinyInt& val = dynamic_cast<CDB_TinyInt&> (param);
  233.                 // DBTINYINT v = (DBTINYINT) val.Value();
  234.                 r = bcp_colptr(m_Cmd, (BYTE*) val.BindVal(), i + 1)
  235.                     == SUCCEED &&
  236.                     bcp_collen(m_Cmd, val.IsNULL() ? 0 : -1, i + 1)
  237.                     == SUCCEED ? SUCCEED : FAIL;
  238.             }
  239.             break;
  240.             case eDB_BigInt: {
  241.                 CDB_BigInt& val = dynamic_cast<CDB_BigInt&> (param);
  242.                 DBNUMERIC* v = (DBNUMERIC*) pb;
  243.                 v->precision= 18;
  244.                 v->scale= 0;
  245.                 Int8 v8 = val.Value();
  246.                 if (longlong_to_numeric(v8, 18, v->array) == 0)
  247.                     return false;
  248.                 r = bcp_colptr(m_Cmd, (BYTE*) v, i + 1)
  249.                     == SUCCEED &&
  250.                     bcp_collen(m_Cmd,  val.IsNULL() ? 0 : -1, i + 1)
  251.                     == SUCCEED ? SUCCEED : FAIL;
  252.                 pb = (void*) (v + 1);
  253.             }
  254.             break;
  255.             case eDB_Char: {
  256.                 CDB_Char& val = dynamic_cast<CDB_Char&> (param);
  257.                 r = bcp_colptr(m_Cmd, (BYTE*) val.Value(), i + 1)
  258.                     == SUCCEED &&
  259.                     bcp_collen(m_Cmd, val.IsNULL() ? 0 : -1, i + 1)
  260.                     == SUCCEED ? SUCCEED : FAIL;
  261.             }
  262.             break;
  263.             case eDB_VarChar: {
  264.                 CDB_VarChar& val = dynamic_cast<CDB_VarChar&> (param);
  265.                 r = bcp_colptr(m_Cmd, (BYTE*) val.Value(), i + 1)
  266.                     == SUCCEED &&
  267.                     bcp_collen(m_Cmd, val.IsNULL() ? 0 : -1, i + 1)
  268.                     == SUCCEED ? SUCCEED : FAIL;
  269.             }
  270.             break;
  271.             case eDB_LongChar: {
  272.                 CDB_LongChar& val = dynamic_cast<CDB_LongChar&> (param);
  273.                 r = bcp_colptr(m_Cmd, (BYTE*) val.Value(), i + 1)
  274.                     == SUCCEED &&
  275.                     bcp_collen(m_Cmd, val.IsNULL() ? 0 : -1, i + 1)
  276.                     == SUCCEED ? SUCCEED : FAIL;
  277.             }
  278.             break;
  279.             case eDB_Binary: {
  280.                 CDB_Binary& val = dynamic_cast<CDB_Binary&> (param);
  281.                 r = bcp_colptr(m_Cmd, (BYTE*) val.Value(), i + 1)
  282.                     == SUCCEED &&
  283.                     bcp_collen(m_Cmd, val.IsNULL() ? 0 : val.Size(), i + 1)
  284.                     == SUCCEED ? SUCCEED : FAIL;
  285.             }
  286.             break;
  287.             case eDB_VarBinary: {
  288.                 CDB_VarBinary& val = dynamic_cast<CDB_VarBinary&> (param);
  289.                 r = bcp_colptr(m_Cmd, (BYTE*) val.Value(), i + 1)
  290.                     == SUCCEED &&
  291.                     bcp_collen(m_Cmd, val.IsNULL() ? 0 : val.Size(), i + 1)
  292.                     == SUCCEED ? SUCCEED : FAIL;
  293.             }
  294.             break;
  295.             case eDB_LongBinary: {
  296.                 CDB_LongBinary& val = dynamic_cast<CDB_LongBinary&> (param);
  297.                 r = bcp_colptr(m_Cmd, (BYTE*) val.Value(), i + 1)
  298.                     == SUCCEED &&
  299.                     bcp_collen(m_Cmd, val.IsNULL() ? 0 : val.DataSize(), i + 1)
  300.                     == SUCCEED ? SUCCEED : FAIL;
  301.             }
  302.             break;
  303.             case eDB_Float: {
  304.                 CDB_Float& val = dynamic_cast<CDB_Float&> (param);
  305.                 //DBREAL v = (DBREAL) val.Value();
  306.                 r = bcp_colptr(m_Cmd, (BYTE*) val.BindVal(), i + 1)
  307.                     == SUCCEED &&
  308.                     bcp_collen(m_Cmd,  val.IsNULL() ? 0 : -1, i + 1)
  309.                     == SUCCEED ? SUCCEED : FAIL;
  310.             }
  311.             break;
  312.             case eDB_Double: {
  313.                 CDB_Double& val = dynamic_cast<CDB_Double&> (param);
  314.                 //DBFLT8 v = (DBFLT8) val.Value();
  315.                 r = bcp_bind(m_Cmd, (BYTE*) val.BindVal(), 0,
  316.                              val.IsNULL() ? 0 : -1, 0, 0, SYBFLT8, i + 1);
  317.             }
  318.             break;
  319.             case eDB_SmallDateTime: {
  320.                 CDB_SmallDateTime& val =
  321.                     dynamic_cast<CDB_SmallDateTime&> (param);
  322.                 DBDATETIME4* dt = (DBDATETIME4*) pb;
  323.                 dt->days        = val.GetDays();
  324.                 dt->minutes     = val.GetMinutes();
  325.                 r = bcp_colptr(m_Cmd, (BYTE*) dt, i + 1)
  326.                     == SUCCEED &&
  327.                     bcp_collen(m_Cmd, val.IsNULL() ? 0 : -1, i + 1)
  328.                     == SUCCEED ? SUCCEED : FAIL;
  329.                 pb = (void*) (dt + 1);
  330.             }
  331.             break;
  332.             case eDB_DateTime: {
  333.                 CDB_DateTime& val = dynamic_cast<CDB_DateTime&> (param);
  334.                 DBDATETIME* dt = (DBDATETIME*) pb;
  335.                 dt->dtdays     = val.GetDays();
  336.                 dt->dttime     = val.Get300Secs();
  337.                 r = bcp_colptr(m_Cmd, (BYTE*) dt, i + 1)
  338.                     == SUCCEED &&
  339.                     bcp_collen(m_Cmd, val.IsNULL() ? 0 : -1, i + 1)
  340.                     == SUCCEED ? SUCCEED : FAIL;
  341.                 pb = (void*) (dt + 1);
  342.             }
  343.             break;
  344.             case eDB_Text: {
  345.                 CDB_Text& val = dynamic_cast<CDB_Text&> (param);
  346.                 r = bcp_collen(m_Cmd, val.Size(), i + 1);
  347.             }
  348.             break;
  349.             case eDB_Image: {
  350.                 CDB_Image& val = dynamic_cast<CDB_Image&> (param);
  351.                 r = bcp_collen(m_Cmd, val.Size(), i + 1);
  352.             }
  353.             break;
  354.             default:
  355.                 return false;
  356.             }
  357.             if (r != CS_SUCCEED)
  358.                 return false;
  359.         }
  360.     }
  361.     return true;
  362. }
  363. bool CTDS_BCPInCmd::SendRow()
  364. {
  365.     char param_buff[2048]; // maximal row size, assured of buffer overruns
  366.     if (!x_AssignParams(param_buff)) {
  367.         m_HasFailed = true;
  368.         throw CDB_ClientEx(eDB_Error, 223004,
  369.                            "CTDS_BCPInCmd::SendRow", "cannot assign params");
  370.     }
  371.     if (bcp_sendrow(m_Cmd) != SUCCEED) {
  372.         m_HasFailed = true;
  373.         throw CDB_ClientEx(eDB_Error, 223005,
  374.                            "CTDS_BCPInCmd::SendRow", "bcp_sendrow failed");
  375.     }
  376.     m_WasSent = true;
  377.     if (m_HasTextImage) { // send text/image data
  378.         char buff[1800]; // text/image page size
  379.         for (unsigned int i = 0; i < m_Params.NofParams(); i++) {
  380.             if (m_Params.GetParamStatus(i) == 0)
  381.                 continue;
  382.             CDB_Object& param = *m_Params.GetParam(i);
  383.             if (param.GetType() != eDB_Text &&
  384.                 param.GetType() != eDB_Image)
  385.                 continue;
  386.             CDB_Stream& val = dynamic_cast<CDB_Stream&> (param);
  387.             size_t s = val.Size();
  388.             do {
  389.                 size_t l = val.Read(buff, sizeof(buff));
  390.                 if (l > s)
  391.                     l = s;
  392.                 if (bcp_moretext(m_Cmd, l, (BYTE*) buff) != SUCCEED) {
  393.                     m_HasFailed = true;
  394.                     throw CDB_ClientEx(eDB_Error, 223006,
  395.                                        "CTDS_BCPInCmd::SendRow",
  396.                                        param.GetType() == eDB_Text ?
  397.                                        "bcp_moretext for text failed" :
  398.                                        "bcp_moretext for image failed");
  399.                 }
  400.                 if (!l)
  401.                     break;
  402.                 s -= l;
  403.             } while (s);
  404.         }
  405.     }
  406.     return true;
  407. }
  408. bool CTDS_BCPInCmd::Cancel()
  409. {
  410.     if(m_WasSent) {
  411.         DBINT outrow = bcp_done(m_Cmd);
  412.         m_WasSent= false;
  413.         return outrow == 0;
  414.     }
  415.     return false;
  416. }
  417. bool CTDS_BCPInCmd::CompleteBatch()
  418. {
  419.     if(m_WasSent) {
  420.         DBINT outrow = bcp_batch(m_Cmd);
  421.         if(outrow < 0) {
  422.             m_HasFailed= true;
  423.             throw CDB_ClientEx(eDB_Error, 223020,
  424.                                "CTDS_BCPInCmd::CompleteBatch", 
  425.                                "bcp_batch failed");
  426.         }
  427.         return outrow > 0;
  428.     }
  429.     return false;
  430. }
  431. bool CTDS_BCPInCmd::CompleteBCP()
  432. {
  433.     if(m_WasSent) {
  434.         DBINT outrow = bcp_done(m_Cmd);
  435.         if(outrow < 0) {
  436.             m_HasFailed = true;
  437.             throw CDB_ClientEx(eDB_Error, 223020,
  438.                                "CTDS_BCPInCmd::CompleteBCP", 
  439.                                "bcp_done failed");
  440.         }
  441.         m_WasSent= false;
  442.         return outrow > 0;
  443.     }
  444.     return false;
  445. }
  446. void CTDS_BCPInCmd::Release()
  447. {
  448.     m_BR = 0;
  449.     if (m_WasSent) {
  450.         Cancel();
  451.         m_WasSent = false;
  452.     }
  453.     m_Connect->DropCmd(*this);
  454.     delete this;
  455. }
  456. CTDS_BCPInCmd::~CTDS_BCPInCmd()
  457. {
  458.     if (m_BR)
  459.         *m_BR = 0;
  460.     if (m_WasSent)
  461.         Cancel();
  462. }
  463. END_NCBI_SCOPE
  464. /*
  465.  * ===========================================================================
  466.  * $Log: bcp.cpp,v $
  467.  * Revision 1000.1  2004/06/01 19:20:40  gouriano
  468.  * PRODUCTION: UPGRADED [GCC34_MSVC7] Dev-tree R1.6
  469.  *
  470.  * Revision 1.6  2004/05/17 21:13:37  gorelenk
  471.  * Added include of PCH ncbi_pch.hpp
  472.  *
  473.  * Revision 1.5  2003/04/29 21:15:03  soussov
  474.  * new datatypes CDB_LongChar and CDB_LongBinary added
  475.  *
  476.  * Revision 1.4  2002/12/03 19:20:40  soussov
  477.  * some minor fixes in bcp_batch, bcp_done
  478.  *
  479.  * Revision 1.3  2002/03/04 19:09:27  soussov
  480.  * fixed bug in m_WasSent flag setting
  481.  *
  482.  * Revision 1.2  2001/11/06 18:00:02  lavr
  483.  * Formatted uniformly as the rest of the library
  484.  *
  485.  * Revision 1.1  2001/10/25 00:39:22  vakatov
  486.  * Initial revision
  487.  *
  488.  * ===========================================================================
  489.  */