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

生物技术

开发平台:

C/C++

  1. /*
  2.  * ===========================================================================
  3.  * PRODUCTION $Log: bcp.cpp,v $
  4.  * PRODUCTION Revision 1000.1  2004/06/01 19:21:37  gouriano
  5.  * PRODUCTION PRODUCTION: UPGRADED [GCC34_MSVC7] Dev-tree R1.5
  6.  * PRODUCTION
  7.  * ===========================================================================
  8.  */
  9. /* $Id: bcp.cpp,v 1000.1 2004/06/01 19:21:37 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:  ODBC bcp-in command
  37.  *
  38.  */
  39. #include <ncbi_pch.hpp>
  40. #include <dbapi/driver/odbc/interfaces.hpp>
  41. #include <dbapi/driver/util/numeric_convert.hpp>
  42. #include <string.h>
  43. #include <odbcss.h>
  44. BEGIN_NCBI_SCOPE
  45. #define DBDATETIME4_days(x) ((x)->numdays)
  46. #define DBDATETIME4_mins(x) ((x)->nummins)
  47. #define DBNUMERIC_val(x) ((x)->val)
  48. #define SQL_VARLEN_DATA (-10)
  49. /////////////////////////////////////////////////////////////////////////////
  50. //
  51. //  CODBC_BCPInCmd::
  52. //
  53. CODBC_BCPInCmd::CODBC_BCPInCmd(CODBC_Connection* con,
  54.                                SQLHDBC       cmd,
  55.                                const string&    table_name,
  56.                                unsigned int     nof_columns) :
  57.     m_Connect(con), m_Cmd(cmd), m_Params(nof_columns),
  58.     m_WasSent(false), m_HasFailed(false),
  59.     m_HasTextImage(false), m_WasBound(false), 
  60. m_Reporter(&con->m_MsgHandlers, SQL_HANDLE_DBC, cmd)
  61. {
  62.     if (bcp_init(cmd, (char*) table_name.c_str(), 0, 0, DB_IN) != SUCCEED) {
  63. m_Reporter.ReportErrors();
  64.         throw CDB_ClientEx(eDB_Fatal, 423001,
  65.                            "CODBC_BCPInCmd::CODBC_BCPInCmd", "bcp_init failed");
  66.     }
  67. }
  68. bool CODBC_BCPInCmd::Bind(unsigned int column_num, CDB_Object* param_ptr)
  69. {
  70.     return m_Params.BindParam(column_num,  kEmptyStr, param_ptr);
  71. }
  72. bool CODBC_BCPInCmd::x_AssignParams(void* pb)
  73. {
  74.     RETCODE r;
  75.     
  76.     if (!m_WasBound) {
  77.         for (unsigned int i = 0; i < m_Params.NofParams(); i++) {
  78.             if (m_Params.GetParamStatus(i) == 0) {
  79. bcp_bind(m_Cmd, (BYTE*) pb, 0, SQL_NULL_DATA, 0, 0, 0, i+1);
  80.                 continue;
  81. }
  82.             
  83.             CDB_Object& param = *m_Params.GetParam(i);
  84.             
  85.             switch ( param.GetType() ) {
  86.             case eDB_Int:
  87.                 r = bcp_bind(m_Cmd, (BYTE*) pb, 0,
  88.                              SQL_VARLEN_DATA, 0, 0, SQLINT4, i + 1);
  89.                 break;
  90.             case eDB_SmallInt:
  91.                 r = bcp_bind(m_Cmd, (BYTE*) pb, 0,
  92.                              SQL_VARLEN_DATA, 0, 0, SQLINT2, i + 1);
  93.                 break;
  94.             case eDB_TinyInt: 
  95.                 r = bcp_bind(m_Cmd, (BYTE*) pb, 0,
  96.                              SQL_VARLEN_DATA, 0, 0, SQLINT1, i + 1);
  97.                 break;
  98.             case eDB_BigInt: 
  99.                 r = bcp_bind(m_Cmd, (BYTE*) pb, 0,
  100.                              SQL_VARLEN_DATA, 0, 0, SQLNUMERIC, i + 1);
  101.                 break;
  102.             case eDB_Char:
  103.             case eDB_VarChar:
  104. case eDB_LongChar:
  105.                 r = bcp_bind(m_Cmd, (BYTE*) pb, 0,
  106.                              SQL_VARLEN_DATA,(BYTE*) "", 1, SQLCHARACTER, i + 1);
  107.                 break;
  108. #if 0
  109.             case eDB_VarChar:
  110.                 r = bcp_bind(m_Cmd, (BYTE*) pb, 0,
  111.                              SQL_VARLEN_DATA,(BYTE*) "", 1, SQLCHARACTER, i + 1);
  112.                 break;
  113.             case eDB_Binary:
  114.                 r = bcp_bind(m_Cmd, (BYTE*) pb, 0,
  115.                              SQL_VARLEN_DATA, 0, 0, SQLBINARY, i + 1);
  116.                 break;
  117. #endif
  118.             case eDB_Binary:
  119.             case eDB_VarBinary:
  120. case eDB_LongBinary:
  121.                 r = bcp_bind(m_Cmd, (BYTE*) pb, 0,
  122.                              SQL_VARLEN_DATA, 0, 0, SQLBINARY, i + 1);
  123.                 break;
  124.             case eDB_Float:
  125.                 r = bcp_bind(m_Cmd, (BYTE*) pb, 0,
  126.                              SQL_VARLEN_DATA, 0, 0, SQLFLT4, i + 1);
  127.                 break;
  128.             case eDB_Double:
  129.                 r = bcp_bind(m_Cmd, (BYTE*) pb, 0,
  130.                              SQL_VARLEN_DATA, 0, 0, SQLFLT8, i + 1);
  131.                 break;
  132.             case eDB_SmallDateTime:
  133.                 r = bcp_bind(m_Cmd, (BYTE*) pb, 0, SQL_VARLEN_DATA,
  134.                              0, 0, SQLDATETIM4,  i + 1);
  135.                 break;
  136.             case eDB_DateTime:
  137.                 r = bcp_bind(m_Cmd, (BYTE*) pb, 0, SQL_VARLEN_DATA,
  138.                              0, 0, SQLDATETIME, i + 1);
  139.                 break;
  140.             case eDB_Text:
  141.                 r = bcp_bind(m_Cmd, 0, 0,
  142.                              SQL_VARLEN_DATA, (BYTE*) "", 1, 
  143.  SQLTEXT, i + 1);
  144.                 m_HasTextImage = true;
  145.                 break;
  146.             case eDB_Image:
  147.                 r = bcp_bind(m_Cmd, 0, 0,
  148.                              1, 0, 0, SQLIMAGE, i + 1);
  149.                 m_HasTextImage = true;
  150.                 break;
  151.             default:
  152.                 return false;
  153.             }
  154.             if (r != SUCCEED) {
  155. m_Reporter.ReportErrors();
  156.                 return false;
  157. }
  158.         }
  159.         m_WasBound = true;
  160.     }
  161.     for (unsigned int i = 0; i < m_Params.NofParams(); i++) {
  162.         if (m_Params.GetParamStatus(i) == 0)
  163.             continue;
  164.         
  165.         CDB_Object& param = *m_Params.GetParam(i);
  166.         
  167.         switch ( param.GetType() ) {
  168.         case eDB_Int: {
  169.             CDB_Int& val = dynamic_cast<CDB_Int&> (param);
  170.             // DBINT v = (DBINT) val.Value();
  171.             r = bcp_colptr(m_Cmd, (BYTE*) val.BindVal(), i + 1)
  172.                 == SUCCEED &&
  173.                 bcp_collen(m_Cmd,  val.IsNULL() ? SQL_NULL_DATA : sizeof(Int4), i + 1)
  174.                 == SUCCEED ? SUCCEED : FAIL;
  175.         }
  176.         break;
  177.         case eDB_SmallInt: {
  178.             CDB_SmallInt& val = dynamic_cast<CDB_SmallInt&> (param);
  179.             // DBSMALLINT v = (DBSMALLINT) val.Value();
  180.             r = bcp_colptr(m_Cmd, (BYTE*) val.BindVal(), i + 1)
  181.                 == SUCCEED &&
  182.                 bcp_collen(m_Cmd,  val.IsNULL() ? SQL_NULL_DATA : sizeof(Int2), i + 1)
  183.                 == SUCCEED ? SUCCEED : FAIL;
  184.         }
  185.         break;
  186.         case eDB_TinyInt: {
  187.             CDB_TinyInt& val = dynamic_cast<CDB_TinyInt&> (param);
  188.             // DBTINYINT v = (DBTINYINT) val.Value();
  189.             r = bcp_colptr(m_Cmd, (BYTE*) val.BindVal(), i + 1)
  190.                 == SUCCEED &&
  191.                 bcp_collen(m_Cmd, val.IsNULL() ? SQL_NULL_DATA : sizeof(Uint1), i + 1)
  192.                 == SUCCEED ? SUCCEED : FAIL;
  193.         }
  194.         break;
  195.         case eDB_BigInt: {
  196.             CDB_BigInt& val = dynamic_cast<CDB_BigInt&> (param);
  197.             DBNUMERIC* v = (DBNUMERIC*) pb;
  198.             Int8 v8 = val.Value();
  199.             if (longlong_to_numeric(v8, 18, DBNUMERIC_val(v)) == 0)
  200.                 return false;
  201.             r = bcp_colptr(m_Cmd, (BYTE*) v, i + 1)
  202.                 == SUCCEED &&
  203.                 bcp_collen(m_Cmd,  val.IsNULL() ? SQL_NULL_DATA : sizeof(DBNUMERIC), i + 1)
  204.                 == SUCCEED ? SUCCEED : FAIL;
  205.             pb = (void*) (v + 1);
  206.         }
  207.         break;
  208.         case eDB_Char: {
  209.             CDB_Char& val = dynamic_cast<CDB_Char&> (param);
  210.             r = bcp_colptr(m_Cmd, (!val.IsNULL())? ((BYTE*) val.Value()) : (BYTE*)pb, i + 1)
  211.                 == SUCCEED &&
  212.                 bcp_collen(m_Cmd, val.IsNULL() ? SQL_NULL_DATA : SQL_VARLEN_DATA, i + 1)
  213.                 == SUCCEED ? SUCCEED : FAIL;
  214.         }
  215.         break;
  216.         case eDB_VarChar: {
  217.             CDB_VarChar& val = dynamic_cast<CDB_VarChar&> (param);
  218.             r = bcp_colptr(m_Cmd, (!val.IsNULL())? ((BYTE*) val.Value()) : (BYTE*)pb, i + 1)
  219.                 == SUCCEED &&
  220.                 bcp_collen(m_Cmd, val.IsNULL() ? SQL_NULL_DATA : SQL_VARLEN_DATA, i + 1)
  221.                 == SUCCEED ? SUCCEED : FAIL;
  222.         }
  223.         break;
  224.         case eDB_LongChar: {
  225.             CDB_LongChar& val = dynamic_cast<CDB_LongChar&> (param);
  226.             r = bcp_colptr(m_Cmd, (!val.IsNULL())? ((BYTE*) val.Value()) : (BYTE*)pb, i + 1)
  227.                 == SUCCEED &&
  228.                 bcp_collen(m_Cmd, val.IsNULL() ? SQL_NULL_DATA : SQL_VARLEN_DATA, i + 1)
  229.                 == SUCCEED ? SUCCEED : FAIL;
  230.         }
  231.         break;
  232.         case eDB_Binary: {
  233.             CDB_Binary& val = dynamic_cast<CDB_Binary&> (param);
  234.             r = bcp_colptr(m_Cmd, (!val.IsNULL())? ((BYTE*) val.Value()) : (BYTE*)pb, i + 1)
  235.                 == SUCCEED &&
  236.                 bcp_collen(m_Cmd,
  237.                            val.IsNULL() ? SQL_NULL_DATA : (Int4) val.Size(), i + 1)
  238.                 == SUCCEED ? SUCCEED : FAIL;
  239.         }
  240.         break;
  241.         case eDB_VarBinary: {
  242.             CDB_VarBinary& val = dynamic_cast<CDB_VarBinary&> (param);
  243.             r = bcp_colptr(m_Cmd, (!val.IsNULL())? ((BYTE*) val.Value()) : (BYTE*)pb, i + 1)
  244.                 == SUCCEED &&
  245.                 bcp_collen(m_Cmd,
  246.                            val.IsNULL() ? SQL_NULL_DATA : (Int4) val.Size(), i + 1)
  247.                 == SUCCEED ? SUCCEED : FAIL;
  248.         }
  249.         break;
  250.         case eDB_LongBinary: {
  251.             CDB_LongBinary& val = dynamic_cast<CDB_LongBinary&> (param);
  252.             r = bcp_colptr(m_Cmd, (!val.IsNULL())? ((BYTE*) val.Value()) : (BYTE*)pb, i + 1)
  253.                 == SUCCEED &&
  254.                 bcp_collen(m_Cmd,
  255.                            val.IsNULL() ? SQL_NULL_DATA : (Int4) val.DataSize(), i + 1)
  256.                 == SUCCEED ? SUCCEED : FAIL;
  257.         }
  258.         break;
  259.         case eDB_Float: {
  260.             CDB_Float& val = dynamic_cast<CDB_Float&> (param);
  261.             //DBREAL v = (DBREAL) val.Value();
  262.             r = bcp_colptr(m_Cmd, (BYTE*) val.BindVal(), i + 1)
  263.                 == SUCCEED &&
  264.                 bcp_collen(m_Cmd,  val.IsNULL() ? SQL_NULL_DATA : sizeof(float), i + 1)
  265.                 == SUCCEED ? SUCCEED : FAIL;
  266.         }
  267.         break;
  268.         case eDB_Double: {
  269.             CDB_Double& val = dynamic_cast<CDB_Double&> (param);
  270.             //DBFLT8 v = (DBFLT8) val.Value();
  271.             r = bcp_colptr(m_Cmd, (BYTE*) val.BindVal(), i + 1)
  272.                 == SUCCEED &&
  273.                 bcp_collen(m_Cmd,  val.IsNULL() ? SQL_NULL_DATA : sizeof(double), i + 1)
  274.                 == SUCCEED ? SUCCEED : FAIL;
  275.         }
  276.         break;
  277.         case eDB_SmallDateTime: {
  278.             CDB_SmallDateTime& val =
  279.                 dynamic_cast<CDB_SmallDateTime&> (param);
  280.             DBDATETIM4* dt = (DBDATETIM4*) pb;
  281.             DBDATETIME4_days(dt)        = val.GetDays();
  282.             DBDATETIME4_mins(dt)     = val.GetMinutes();
  283.             r = bcp_colptr(m_Cmd, (BYTE*) dt, i + 1)
  284.                 == SUCCEED &&
  285.                 bcp_collen(m_Cmd, val.IsNULL() ? SQL_NULL_DATA : sizeof(DBDATETIM4), i + 1)
  286.                 == SUCCEED ? SUCCEED : FAIL;
  287.             pb = (void*) (dt + 1);
  288.         }
  289.         break;
  290.         case eDB_DateTime: {
  291.             CDB_DateTime& val = dynamic_cast<CDB_DateTime&> (param);
  292.             DBDATETIME* dt = (DBDATETIME*) pb;
  293.             dt->dtdays     = val.GetDays();
  294.             dt->dttime     = val.Get300Secs();
  295.             r = bcp_colptr(m_Cmd, (BYTE*) dt, i + 1)
  296.                 == SUCCEED &&
  297.                 bcp_collen(m_Cmd, val.IsNULL() ? SQL_NULL_DATA : sizeof(DBDATETIME), i + 1)
  298.                 == SUCCEED ? SUCCEED : FAIL;
  299.             pb = (void*) (dt + 1);
  300.         }
  301.         break;
  302.         case eDB_Text: {
  303.             CDB_Text& val = dynamic_cast<CDB_Text&> (param);
  304.             r = bcp_collen(m_Cmd, (DBINT) val.Size(), i + 1);
  305.         }
  306.         break;
  307.         case eDB_Image: {
  308.             CDB_Image& val = dynamic_cast<CDB_Image&> (param);
  309.             r = bcp_collen(m_Cmd, (DBINT) val.Size(), i + 1);
  310.         }
  311.         break;
  312.         default:
  313.             return false;
  314.         }
  315.         if (r != SUCCEED) {
  316. m_Reporter.ReportErrors();
  317.             return false;
  318. }
  319.     }
  320.     return true;
  321. }
  322. bool CODBC_BCPInCmd::SendRow()
  323. {
  324.     char param_buff[2048]; // maximal row size, assured of buffer overruns
  325.     
  326.     if (!x_AssignParams(param_buff)) {
  327.         m_HasFailed = true;
  328.         throw CDB_ClientEx(eDB_Error, 423004,
  329.                            "CODBC_BCPInCmd::SendRow", "cannot assign params");
  330.     }
  331.     if (bcp_sendrow(m_Cmd) != SUCCEED) {
  332.         m_HasFailed = true;
  333. m_Reporter.ReportErrors();
  334.         throw CDB_ClientEx(eDB_Error, 423005,
  335.                            "CODBC_BCPInCmd::SendRow", "bcp_sendrow failed");
  336.     }
  337.     m_WasSent = true;
  338.     if (m_HasTextImage) { // send text/image data
  339.         char buff[1800]; // text/image page size
  340.         for (unsigned int i = 0; i < m_Params.NofParams(); i++) {
  341.             if (m_Params.GetParamStatus(i) == 0)
  342.                 continue;
  343.             CDB_Object& param = *m_Params.GetParam(i);
  344.             if (param.GetType() != eDB_Text &&
  345.                 param.GetType() != eDB_Image)
  346.                 continue;
  347.             CDB_Stream& val = dynamic_cast<CDB_Stream&> (param);
  348.             size_t s = val.Size();
  349.             do {
  350.                 size_t l = val.Read(buff, sizeof(buff));
  351.                 if (l > s)
  352.                     l = s;
  353.                 if (bcp_moretext(m_Cmd, (DBINT) l, (BYTE*) buff) != SUCCEED) {
  354.                     m_HasFailed = true;
  355. m_Reporter.ReportErrors();
  356.                     throw CDB_ClientEx(eDB_Error, 423006,
  357.                                        "CODBC_BCPInCmd::SendRow",
  358.                                        param.GetType() == eDB_Text ?
  359.                                        "bcp_moretext for text failed" :
  360.                                        "bcp_moretext for image failed");
  361.                 }
  362.                 if (!l)
  363.                     break;
  364.                 s -= l;
  365.             } while (s);
  366.         }
  367.     }
  368.     return true;
  369. }
  370. bool CODBC_BCPInCmd::Cancel()
  371. {
  372.     if(m_WasSent) {
  373.         DBINT outrow = bcp_done(m_Cmd);
  374.         m_WasSent= false;
  375.         return outrow == 0;
  376.     }
  377.     return true;
  378. }
  379. bool CODBC_BCPInCmd::CompleteBatch()
  380. {
  381.     if(m_WasSent) {
  382.         Int4 outrow = bcp_batch(m_Cmd);
  383. if(outrow == -1) {
  384. m_Reporter.ReportErrors();
  385. return false;
  386. }
  387.         return true;
  388.     }
  389.     return false;
  390. }
  391. bool CODBC_BCPInCmd::CompleteBCP()
  392. {
  393.     if(m_WasSent) {
  394.         Int4 outrow = bcp_done(m_Cmd);
  395.         m_WasSent= false;
  396. if(outrow == -1) {
  397. m_Reporter.ReportErrors();
  398. return false;
  399. }
  400.         return true;
  401.     }
  402.     return false;
  403. }
  404. void CODBC_BCPInCmd::Release()
  405. {
  406.     m_BR = 0;
  407.     if (m_WasSent) {
  408.         Cancel();
  409.         m_WasSent = false;
  410.     }
  411.     m_Connect->DropCmd(*this);
  412.     delete this;
  413. }
  414. CODBC_BCPInCmd::~CODBC_BCPInCmd()
  415. {
  416.     if (m_BR)
  417.         *m_BR = 0;
  418.     if (m_WasSent)
  419.         Cancel();
  420. }
  421. END_NCBI_SCOPE
  422. /*
  423.  * ===========================================================================
  424.  * $Log: bcp.cpp,v $
  425.  * Revision 1000.1  2004/06/01 19:21:37  gouriano
  426.  * PRODUCTION: UPGRADED [GCC34_MSVC7] Dev-tree R1.5
  427.  *
  428.  * Revision 1.5  2004/05/17 21:16:05  gorelenk
  429.  * Added include of PCH ncbi_pch.hpp
  430.  *
  431.  * Revision 1.4  2003/05/08 20:30:24  soussov
  432.  * CDB_LongChar CDB_LongBinary added
  433.  *
  434.  * Revision 1.3  2002/09/12 14:14:59  soussov
  435.  * fixed typo in binding [var]char/binary with NULL value
  436.  *
  437.  * Revision 1.2  2002/09/11 20:23:54  soussov
  438.  * fixed bug in binding [var]char/binary with NULL value
  439.  *
  440.  * Revision 1.1  2002/06/18 22:06:24  soussov
  441.  * initial commit
  442.  *
  443.  *
  444.  * ===========================================================================
  445.  */