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

生物技术

开发平台:

C/C++

  1. /*
  2.  * ===========================================================================
  3.  * PRODUCTION $Log: result.cpp,v $
  4.  * PRODUCTION Revision 1000.2  2004/06/01 19:20:21  gouriano
  5.  * PRODUCTION PRODUCTION: UPGRADED [GCC34_MSVC7] Dev-tree R1.22
  6.  * PRODUCTION
  7.  * ===========================================================================
  8.  */
  9. /* $Id: result.cpp,v 1000.2 2004/06/01 19:20:21 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 Results
  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. BEGIN_NCBI_SCOPE
  49. // Aux. for s_*GetItem()
  50. static CDB_Object* s_GenericGetItem(EDB_Type data_type, CDB_Object* item_buff,
  51.                                     EDB_Type b_type, const BYTE* d_ptr, DBINT d_len)
  52. {
  53.     switch (data_type) {
  54.     case eDB_VarBinary: {
  55.         if (item_buff) {
  56.             switch (b_type) {
  57.             case eDB_VarBinary:
  58.                 ((CDB_VarBinary*) item_buff)->SetValue((const void*) d_ptr,
  59.                                                        (size_t) d_len);
  60.                 break;
  61.             case eDB_Binary:
  62.                 ((CDB_Binary*)    item_buff)->SetValue((const void*) d_ptr,
  63.                                                        (size_t) d_len);
  64.                 break;
  65.             case eDB_VarChar:
  66.                 ((CDB_VarChar*)   item_buff)->SetValue((const char*) d_ptr,
  67.                                                        (size_t) d_len);
  68.                 break;
  69.             case eDB_Char:
  70.                 ((CDB_Char*)      item_buff)->SetValue((const char*) d_ptr,
  71.                                                        (size_t) d_len);
  72.                 break;
  73. case eDB_LongBinary:
  74.                 ((CDB_LongBinary*)item_buff)->SetValue((const void*) d_ptr,
  75.                                                        (size_t) d_len);
  76.                 break;
  77.             case eDB_LongChar:
  78.                 ((CDB_LongChar*)  item_buff)->SetValue((const char*) d_ptr,
  79.                                                        (size_t) d_len);
  80.                 break;
  81.             default:
  82.                 throw CDB_ClientEx(eDB_Error, 230020, "s_GenericGetItem",
  83.                                    "wrong type of CDB_Object");
  84.             }
  85.             return item_buff;
  86.         }
  87.         return d_ptr ? new CDB_VarBinary((const void*) d_ptr, (size_t) d_len)
  88.             : new CDB_VarBinary();
  89.     }
  90.     case eDB_Bit: {
  91.         DBBIT* v = (DBBIT*) d_ptr;
  92.         if (item_buff) {
  93.             if (v) {
  94.                 switch (b_type) {
  95.                 case eDB_Bit:
  96.                     *((CDB_Bit*)      item_buff) = (int) *v;
  97.                     break;
  98.                 case eDB_TinyInt:
  99.                     *((CDB_TinyInt*)  item_buff) = *v ? 1 : 0;
  100.                     break;
  101.                 case eDB_SmallInt:
  102.                     *((CDB_SmallInt*) item_buff) = *v ? 1 : 0;
  103.                     break;
  104.                 case eDB_Int:
  105.                     *((CDB_Int*)      item_buff) = *v ? 1 : 0;
  106.                     break;
  107.                 default:
  108.                     throw CDB_ClientEx(eDB_Error, 230020, "s_GenericGetItem",
  109.                                        "wrong type of CDB_Object");
  110.                 }
  111.             } else
  112.                 item_buff->AssignNULL();
  113.             return item_buff;
  114.         }
  115.         return v ? new CDB_Bit((int) *v) : new CDB_Bit;
  116.     }
  117.     case eDB_VarChar: {
  118.         if (item_buff) {
  119.             switch (b_type) {
  120.             case eDB_VarChar:
  121.                 ((CDB_VarChar*)   item_buff)->SetValue((const char*) d_ptr,
  122.                                                        (size_t) d_len);
  123.                 break;
  124.             case eDB_Char:
  125.                 ((CDB_Char*)      item_buff)->SetValue((const char*) d_ptr,
  126.                                                        (size_t) d_len);
  127.                 break;
  128.             case eDB_LongChar:
  129.                 ((CDB_LongChar*)  item_buff)->SetValue((const char*) d_ptr,
  130.                                                        (size_t) d_len);
  131.                 break;
  132.             case eDB_VarBinary:
  133.                 ((CDB_VarBinary*) item_buff)->SetValue((const void*) d_ptr,
  134.                                                        (size_t) d_len);
  135.                 break;
  136.             case eDB_Binary:
  137.                 ((CDB_Binary*)    item_buff)->SetValue((const void*) d_ptr,
  138.                                                        (size_t) d_len);
  139.                 break;
  140.             case eDB_LongBinary:
  141.                 ((CDB_LongBinary*)item_buff)->SetValue((const void*) d_ptr,
  142.                                                        (size_t) d_len);
  143.                 break;
  144.             default:
  145.                 throw CDB_ClientEx(eDB_Error, 230020, "s_GenericGetItem",
  146.                                    "wrong type of CDB_Object");
  147.             }
  148.             return item_buff;
  149.         }
  150.         return d_ptr ? new CDB_VarChar((const char*) d_ptr, (size_t) d_len)
  151.             : new CDB_VarChar();
  152.     }
  153.     case eDB_DateTime: {
  154.         DBDATETIME* v = (DBDATETIME*) d_ptr;
  155.         if (item_buff) {
  156.             if (b_type != eDB_DateTime) {
  157.                 throw CDB_ClientEx(eDB_Error, 230020, "s_GenericGetItem",
  158.                                    "wrong type of CDB_Object");
  159.             }
  160.             if (v)
  161.                 ((CDB_DateTime*) item_buff)->Assign(v->dtdays, v->dttime);
  162.             else
  163.                 item_buff->AssignNULL();
  164.             return item_buff;
  165.         }
  166.         return v ? new CDB_DateTime(v->dtdays, v->dttime) : new CDB_DateTime;
  167.     }
  168.     case eDB_SmallDateTime: {
  169.         DBDATETIME4* v = (DBDATETIME4*)d_ptr;
  170.         if (item_buff) {
  171.             if (v) {
  172.                 switch (b_type) {
  173.                 case eDB_SmallDateTime:
  174.                     ((CDB_SmallDateTime*) item_buff)->Assign
  175.                         (DBDATETIME4_days(v),             DBDATETIME4_mins(v));
  176.                     break;
  177.                 case eDB_DateTime:
  178.                     ((CDB_DateTime*)      item_buff)->Assign
  179.                         ((int) DBDATETIME4_days(v), (int) DBDATETIME4_mins(v)*60*300);
  180.                     break;
  181.                 default:
  182.                     throw CDB_ClientEx(eDB_Error, 230020, "s_GenericGetItem",
  183.                                        "wrong type of CDB_Object");
  184.                 }
  185.             } else
  186.                 item_buff->AssignNULL();
  187.             return item_buff;
  188.         }
  189.         return v ?
  190.             new CDB_SmallDateTime(DBDATETIME4_days(v), DBDATETIME4_mins(v)) : new CDB_SmallDateTime;
  191.     }
  192.     case eDB_TinyInt: {
  193.         DBTINYINT* v = (DBTINYINT*) d_ptr;
  194.         if (item_buff) {
  195.             if (v) {
  196.                 switch (b_type) {
  197.                 case eDB_TinyInt:
  198.                     *((CDB_TinyInt*)  item_buff) = (Uint1) *v;
  199.                     break;
  200.                 case eDB_SmallInt:
  201.                     *((CDB_SmallInt*) item_buff) = (Int2)  *v;
  202.                     break;
  203.                 case eDB_Int:
  204.                     *((CDB_Int*)      item_buff) = (Int4)  *v;
  205.                     break;
  206.                 default:
  207.                     throw CDB_ClientEx(eDB_Error, 230020, "s_GenericGetItem",
  208.                                        "wrong type of CDB_Object");
  209.                 }
  210.             } else
  211.                 item_buff->AssignNULL();
  212.             return item_buff;
  213.         }
  214.         return v ? new CDB_TinyInt((Uint1) *v) : new CDB_TinyInt;
  215.     }
  216.     case eDB_SmallInt: {
  217.         DBSMALLINT* v = (DBSMALLINT*) d_ptr;
  218.         if (item_buff) {
  219.             if (v) {
  220.                 switch (b_type) {
  221.                 case eDB_SmallInt:
  222.                     *((CDB_SmallInt*) item_buff) = (Int2) *v;
  223.                     break;
  224.                 case eDB_Int:
  225.                     *((CDB_Int*)      item_buff) = (Int4) *v;
  226.                         break;
  227.                 default:
  228.                     throw CDB_ClientEx(eDB_Error, 230020, "s_GenericGetItem",
  229.                                        "wrong type of CDB_Object");
  230.                 }
  231.             } else
  232.                 item_buff->AssignNULL();
  233.             return item_buff;
  234.         }
  235.         return v ? new CDB_SmallInt((Int2) *v) : new CDB_SmallInt;
  236.     }
  237.     case eDB_Int: {
  238.         DBINT* v = (DBINT*) d_ptr;
  239.         if (item_buff) {
  240.             if (v) {
  241.                 if (b_type == eDB_Int)
  242.                     *((CDB_Int*) item_buff) = (Int4) *v;
  243.                 else {
  244.                     throw CDB_ClientEx(eDB_Error, 230020, "s_GenericGetItem",
  245.                                        "wrong type of CDB_Object");
  246.                 }
  247.             } else
  248.                 item_buff->AssignNULL();
  249.             return item_buff;
  250.         }
  251.         return v ? new CDB_Int((Int4) *v) : new CDB_Int;
  252.     }
  253.     case eDB_Double: {
  254.         if (item_buff && b_type != eDB_Double) {
  255.             throw CDB_ClientEx(eDB_Error, 130020, "s_GenericGetItem",
  256.                                "wrong type of CDB_Object");
  257.         }
  258.         DBFLT8* v = (DBFLT8*) d_ptr;
  259.         if (item_buff) {
  260.             if (v)
  261.                 *((CDB_Double*) item_buff) = (double) *v;
  262.             else
  263.                 item_buff->AssignNULL();
  264.             return item_buff;
  265.         }
  266.         return v ? new CDB_Double((double)*v) : new CDB_Double;
  267.     }
  268.     case eDB_Float: {
  269.         if (item_buff && b_type != eDB_Float) {
  270.             throw CDB_ClientEx(eDB_Error, 130020, "s_GenericGetItem",
  271.                                "wrong type of CDB_Object");
  272.         }
  273.         DBREAL* v = (DBREAL*) d_ptr;
  274.         if (item_buff) {
  275.             if (v)
  276.                 *((CDB_Float*) item_buff) = (float) *v;
  277.             else
  278.                 item_buff->AssignNULL();
  279.             return item_buff;
  280.         }
  281.         return v ? new CDB_Float((float)*v) : new CDB_Float;
  282.     }
  283.     case eDB_LongBinary: {
  284.         if (item_buff) {
  285.             switch (b_type) {
  286. case eDB_LongBinary:
  287.                 ((CDB_LongBinary*)item_buff)->SetValue((const void*) d_ptr,
  288.                                                        (size_t) d_len);
  289.                 break;
  290.             case eDB_LongChar:
  291.                 ((CDB_LongChar*)  item_buff)->SetValue((const char*) d_ptr,
  292.                                                        (size_t) d_len);
  293.                 break;
  294.             default:
  295.                 throw CDB_ClientEx(eDB_Error, 230020, "s_GenericGetItem",
  296.                                    "wrong type of CDB_Object");
  297.             }
  298.             return item_buff;
  299.         }
  300.         return d_ptr ? new CDB_LongBinary((size_t) d_len, (const void*) d_ptr, 
  301.                                           (size_t) d_len)
  302.             : new CDB_LongBinary();
  303.     }
  304.     case eDB_LongChar: {
  305.         if (item_buff) {
  306.             switch (b_type) {
  307.             case eDB_LongChar:
  308.                 ((CDB_LongChar*)  item_buff)->SetValue((const char*) d_ptr,
  309.                                                        (size_t) d_len);
  310.                 break;
  311.             case eDB_LongBinary:
  312.                 ((CDB_LongBinary*)item_buff)->SetValue((const void*) d_ptr,
  313.                                                        (size_t) d_len);
  314.                 break;
  315.             default:
  316.                 throw CDB_ClientEx(eDB_Error, 230020, "s_GenericGetItem",
  317.                                    "wrong type of CDB_Object");
  318.             }
  319.             return item_buff;
  320.         }
  321.         return d_ptr ? new CDB_LongChar((size_t) d_len, (const char*) d_ptr)
  322.             : new CDB_LongChar();
  323.     }
  324.     default:
  325.         return 0;
  326.     }
  327. }
  328. /////////////////////////////////////////////////////////////////////////////
  329. static EDB_Type s_GetDataType(DBPROCESS* cmd, int n)
  330. {
  331.     switch (dbcoltype(cmd, n)) {
  332.     case SYBBINARY:    return (dbcollen(cmd, n) > 255) ? eDB_LongBinary : 
  333.                                                          eDB_VarBinary;
  334.     case SYBBIT:       return eDB_Bit;
  335.     case SYBCHAR:      return (dbcollen(cmd, n) > 255) ? eDB_LongChar :
  336.                                                          eDB_VarChar;
  337.     case SYBDATETIME:  return eDB_DateTime;
  338.     case SYBDATETIME4: return eDB_SmallDateTime;
  339.     case SYBINT1:      return eDB_TinyInt;
  340.     case SYBINT2:      return eDB_SmallInt;
  341.     case SYBINT4:      return eDB_Int;
  342.     case SYBDECIMAL:
  343.     case SYBNUMERIC:   break;
  344.     case SYBFLT8:      return eDB_Double;
  345.     case SYBREAL:      return eDB_Float;
  346.     case SYBTEXT:      return eDB_Text;
  347.     case SYBIMAGE:     return eDB_Image;
  348.     default:           return eDB_UnsupportedType;
  349.     }
  350. #ifdef MS_DBLIB_IN_USE
  351.     DBCOL dbcol; dbcol.SizeOfStruct = sizeof(DBCOL);
  352.     RETCODE res = dbcolinfo(cmd, CI_REGULAR, n, 0, &dbcol );
  353.     return dbcol.Scale == 0 && dbcol.Precision < 20 ? eDB_BigInt : eDB_Numeric;
  354. #else
  355.     DBTYPEINFO* t = dbcoltypeinfo(cmd, n);
  356.     return t->scale == 0 && t->precision < 20 ? eDB_BigInt : eDB_Numeric;
  357. #endif
  358. }
  359. /////////////////////////////////////////////////////////////////////////////
  360. //
  361. //  CDBL_RowResult::
  362. //
  363. CDBL_RowResult::CDBL_RowResult(DBPROCESS* cmd,
  364.                                unsigned int* res_status, bool need_init) :
  365.     m_Cmd(cmd), m_CurrItem(-1), m_EOR(false),
  366.     m_ResStatus(res_status), m_Offset(0)
  367. {
  368.     if (!need_init)
  369.         return;
  370.     m_NofCols = dbnumcols(cmd);
  371.     m_CmdNum = DBCURCMD(cmd);
  372.     m_ColFmt = new SDBL_ColDescr[m_NofCols];
  373.     for (unsigned int n = 0; n < m_NofCols; n++) {
  374.         m_ColFmt[n].max_length = dbcollen(m_Cmd, n + 1);
  375.         m_ColFmt[n].data_type = s_GetDataType(m_Cmd, n + 1);
  376.         const char* s = dbcolname(m_Cmd, n + 1);
  377.         m_ColFmt[n].col_name = s ? s : "";
  378.     }
  379. }
  380. EDB_ResType CDBL_RowResult::ResultType() const
  381. {
  382.     return eDB_RowResult;
  383. }
  384. unsigned int CDBL_RowResult::NofItems() const
  385. {
  386.     return m_NofCols;
  387. }
  388. const char* CDBL_RowResult::ItemName(unsigned int item_num) const
  389. {
  390.     return item_num < m_NofCols ? m_ColFmt[item_num].col_name.c_str() : 0;
  391. }
  392. size_t CDBL_RowResult::ItemMaxSize(unsigned int item_num) const
  393. {
  394.     return item_num < m_NofCols ? m_ColFmt[item_num].max_length : 0;
  395. }
  396. EDB_Type CDBL_RowResult::ItemDataType(unsigned int item_num) const
  397. {
  398.     return item_num < m_NofCols
  399.         ? m_ColFmt[item_num].data_type : eDB_UnsupportedType;
  400. }
  401. bool CDBL_RowResult::Fetch()
  402. {
  403.     m_CurrItem = -1;
  404.     if (!m_EOR) {
  405.         switch (dbnextrow(m_Cmd)) {
  406.         case REG_ROW:
  407.             m_CurrItem = 0;
  408.             m_Offset = 0;
  409.             return true;
  410.         case NO_MORE_ROWS:
  411.             m_EOR = true;
  412.             break;
  413.         case FAIL:
  414.             throw CDB_ClientEx(eDB_Error, 230003, "CDBL_RowResult::Fetch",
  415.                                "error in fetching row");
  416.         case BUF_FULL:
  417.             throw CDB_ClientEx(eDB_Error, 230006, "CDBL_RowResult::Fetch",
  418.                                "buffer is full");
  419.         default:
  420.             *m_ResStatus|= 0x10;
  421.             m_EOR = true;
  422.             break;
  423.         }
  424.     }
  425.     return false;
  426. }
  427. int CDBL_RowResult::CurrentItemNo() const
  428. {
  429.     return m_CurrItem;
  430. }
  431. // Aux. for CDBL_RowResult::GetItem()
  432. static CDB_Object* s_GetItem(DBPROCESS* cmd, int item_no,
  433.                              SDBL_ColDescr* fmt, CDB_Object* item_buff)
  434. {
  435.     EDB_Type b_type = item_buff ? item_buff->GetType() : eDB_UnsupportedType;
  436.     const BYTE* d_ptr = dbdata  (cmd, item_no);
  437.     DBINT d_len = dbdatlen(cmd, item_no);
  438.     CDB_Object* val = s_GenericGetItem(fmt->data_type, item_buff,
  439.                                        b_type, d_ptr, d_len);
  440.     if (val)
  441.         return val;
  442.     switch (fmt->data_type) {
  443.     case eDB_BigInt: {
  444.         DBNUMERIC* v = (DBNUMERIC*) d_ptr;
  445.         if (item_buff) {
  446.             if (v) {
  447.                 if (b_type == eDB_Numeric) {
  448.                     ((CDB_Numeric*) item_buff)->Assign
  449.                         ((unsigned int)   v->precision,
  450.                          (unsigned int)   v->scale,
  451.                          (unsigned char*) DBNUMERIC_val(v));
  452.                 } else if (b_type == eDB_BigInt) {
  453.                     *((CDB_BigInt*) item_buff) = numeric_to_longlong
  454.                         ((unsigned int) v->precision, DBNUMERIC_val(v));
  455.                 } else {
  456.                     throw CDB_ClientEx(eDB_Error, 230020, "s_GetItem",
  457.                                        "wrong type of CDB_Object");
  458.                 }
  459.             } else
  460.                 item_buff->AssignNULL();
  461.             return item_buff;
  462.         }
  463.         return v ?
  464.             new CDB_BigInt(numeric_to_longlong((unsigned int) v->precision,
  465.                                                DBNUMERIC_val(v))) : new CDB_BigInt;
  466.     }
  467.     case eDB_Numeric: {
  468.         DBNUMERIC* v = (DBNUMERIC*) d_ptr;
  469.         if (item_buff) {
  470.                 if (v) {
  471.                     if (b_type == eDB_Numeric) {
  472.                         ((CDB_Numeric*) item_buff)->Assign
  473.                             ((unsigned int)   v->precision,
  474.                              (unsigned int)   v->scale,
  475.                              (unsigned char*) DBNUMERIC_val(v));
  476.                     } else {
  477.                         throw CDB_ClientEx(eDB_Error, 230020, "s_GetItem",
  478.                                            "wrong type of CDB_Object");
  479.                     }
  480.                 } else
  481.                     item_buff->AssignNULL();
  482.                 return item_buff;
  483.         }
  484.         return v ?
  485.             new CDB_Numeric((unsigned int)   v->precision,
  486.                             (unsigned int)   v->scale,
  487.                             (unsigned char*) DBNUMERIC_val(v)) : new CDB_Numeric;
  488.     }
  489.     case eDB_Text: {
  490.         if (item_buff && b_type != eDB_Text && b_type != eDB_Image) {
  491.             throw CDB_ClientEx(eDB_Error, 130020, "s_GetItem",
  492.                                "wrong type of CDB_Object");
  493.         }
  494.         CDB_Text* v = item_buff ? (CDB_Text*) item_buff : new CDB_Text;
  495.         v->Append((char*) d_ptr, (int) d_len);
  496.         return v;
  497.     }
  498.     case eDB_Image: {
  499.         if (item_buff && b_type != eDB_Text && b_type != eDB_Image) {
  500.             throw CDB_ClientEx(eDB_Error, 130020, "s_GetItem",
  501.                                "wrong type of CDB_Object");
  502.         }
  503.         CDB_Image* v = item_buff ? (CDB_Image*) item_buff : new CDB_Image;
  504.         v->Append((void*) d_ptr, (int) d_len);
  505.         return v;
  506.     }
  507.     default:
  508.         throw CDB_ClientEx(eDB_Error, 130004, "s_GetItem",
  509.                            "unexpected result type");
  510.     }
  511. }
  512. CDB_Object* CDBL_RowResult::GetItem(CDB_Object* item_buff)
  513. {
  514.     if ((unsigned int) m_CurrItem >= m_NofCols) {
  515.         return 0;
  516.     }
  517.     CDB_Object* r = s_GetItem(m_Cmd, m_CurrItem + 1,
  518.                               &m_ColFmt[m_CurrItem], item_buff);
  519.     ++m_CurrItem;
  520.     m_Offset = 0;
  521.     return r;
  522. }
  523. size_t CDBL_RowResult::ReadItem(void* buffer, size_t buffer_size,bool* is_null)
  524. {
  525.     if ((unsigned int) m_CurrItem >= m_NofCols) {
  526.         if (is_null)
  527.             *is_null = true;
  528.         return 0;
  529.     }
  530.     const BYTE* d_ptr = dbdata  (m_Cmd, m_CurrItem + 1);
  531.     DBINT d_len = dbdatlen(m_Cmd, m_CurrItem + 1);
  532.     if (d_ptr == 0 || d_len < 1) { // NULL value
  533.         ++m_CurrItem;
  534.         m_Offset = 0;
  535.         if (is_null)
  536.             *is_null = true;
  537.         return 0;
  538.     }
  539.     if (is_null)
  540.         *is_null = false;
  541.     if ((size_t) d_len - m_Offset < buffer_size)
  542.         buffer_size = (size_t) d_len - m_Offset;
  543.     memcpy(buffer, d_ptr + m_Offset, buffer_size);
  544.     m_Offset += buffer_size;
  545.     if (m_Offset >= (size_t) d_len) {
  546.         m_Offset = 0;
  547.         ++m_CurrItem;
  548.     }
  549.     return buffer_size;
  550. }
  551. I_ITDescriptor* CDBL_RowResult::GetImageOrTextDescriptor()
  552. {
  553.     if ((unsigned int) m_CurrItem >= m_NofCols)
  554.         return 0;
  555.     return new CDBL_ITDescriptor(m_Cmd, m_CurrItem+1);
  556. }
  557. bool CDBL_RowResult::SkipItem()
  558. {
  559.     if ((unsigned int) m_CurrItem < m_NofCols) {
  560.         ++m_CurrItem;
  561.         m_Offset = 0;
  562.         return true;
  563.     }
  564.     return false;
  565. }
  566. CDBL_RowResult::~CDBL_RowResult()
  567. {
  568.     if (m_ColFmt) {
  569.         delete[] m_ColFmt;
  570.         m_ColFmt = 0;
  571.     }
  572.     if (!m_EOR)
  573.         dbcanquery(m_Cmd);
  574. }
  575. /////////////////////////////////////////////////////////////////////////////
  576. //
  577. //  CDBL_BlobResult::
  578. CDBL_BlobResult::CDBL_BlobResult(DBPROCESS* cmd) :
  579.     m_Cmd(cmd), m_CurrItem(-1), m_EOR(false)
  580. {
  581.     m_CmdNum = DBCURCMD(cmd);
  582.     m_ColFmt.max_length = dbcollen(m_Cmd, 1);
  583.     m_ColFmt.data_type = s_GetDataType(m_Cmd, 1);
  584.     const char* s = dbcolname(m_Cmd, 1);
  585.     m_ColFmt.col_name = s ? s : "";
  586. }
  587. EDB_ResType CDBL_BlobResult::ResultType() const
  588. {
  589.     return eDB_RowResult;
  590. }
  591. unsigned int CDBL_BlobResult::NofItems() const
  592. {
  593.     return 1;
  594. }
  595. const char* CDBL_BlobResult::ItemName(unsigned int item_num) const
  596. {
  597.     return item_num ? 0 : m_ColFmt.col_name.c_str();
  598. }
  599. size_t CDBL_BlobResult::ItemMaxSize(unsigned int item_num) const
  600. {
  601.     return item_num ? 0 : m_ColFmt.max_length;
  602. }
  603. EDB_Type CDBL_BlobResult::ItemDataType(unsigned int) const
  604. {
  605.     return m_ColFmt.data_type;
  606. }
  607. bool CDBL_BlobResult::Fetch()
  608. {
  609.     if (m_EOR)
  610.         return false;
  611.     STATUS s;
  612.     if (m_CurrItem == 0) {
  613.         while ((s = dbreadtext(m_Cmd, m_Buff, (DBINT) sizeof(m_Buff))) > 0)
  614.             ;
  615.         switch (s) {
  616.         case 0:
  617.             break;
  618.         case NO_MORE_ROWS:
  619.             m_EOR = true;
  620.             return false;
  621.         default:
  622.             throw CDB_ClientEx(eDB_Error, 280003, "CDBL_BlobResult::Fetch",
  623.                                "error in fetching row");
  624.         }
  625.     }
  626.     else m_CurrItem = 0;
  627.     s = dbreadtext(m_Cmd, m_Buff, (DBINT) sizeof(m_Buff));
  628.     if(s == NO_MORE_ROWS) return false;
  629.     if(s < 0) {
  630.         throw CDB_ClientEx(eDB_Error, 280003, "CDBL_BlobResult::Fetch",
  631.                            "error in fetching row");
  632.     }
  633.     m_BytesInBuffer= s;
  634.     m_ReadedBytes= 0;
  635.     return true;
  636. }
  637. int CDBL_BlobResult::CurrentItemNo() const
  638. {
  639.     return m_CurrItem;
  640. }
  641. CDB_Object* CDBL_BlobResult::GetItem(CDB_Object* item_buff)
  642. {
  643.     if (m_CurrItem)
  644.         return 0;
  645.     EDB_Type b_type = item_buff ? item_buff->GetType() : eDB_UnsupportedType;
  646.     if (item_buff && b_type != eDB_Text && b_type != eDB_Image) {
  647.         throw CDB_ClientEx(eDB_Error, 230020, "CDBL_BlobResult::GetItem",
  648.                            "wrong type of CDB_Object");
  649.     }
  650.     if (item_buff == 0) {
  651.         item_buff = m_ColFmt.data_type == eDB_Text
  652.             ? (CDB_Object*) new CDB_Text : (CDB_Object*) new CDB_Image;
  653.     }
  654.     CDB_Text* val = (CDB_Text*) item_buff;
  655.     // check if we do have something in buffer
  656.     if(m_ReadedBytes < m_BytesInBuffer) {
  657.         val->Append(m_Buff + m_ReadedBytes, m_BytesInBuffer - m_ReadedBytes);
  658.         m_ReadedBytes= m_BytesInBuffer;
  659.     }
  660.     if(m_BytesInBuffer == 0) {
  661.         return item_buff;
  662.     }
  663.         
  664.     STATUS s;
  665.     while ((s = dbreadtext(m_Cmd, m_Buff, (DBINT) sizeof(m_Buff))) > 0)
  666.         val->Append(m_Buff, (s < sizeof(m_Buff))? (size_t)s : sizeof(m_Buff));
  667.     switch (s) {
  668.     case NO_MORE_ROWS:
  669.         m_EOR = true;
  670.     case 0:
  671.         m_CurrItem = 1;
  672.         break;
  673.     default:
  674.         throw CDB_ClientEx(eDB_Error, 280003, "CDBL_BlobResult::GetItem",
  675.                            "dbreadtext failed");
  676.     }
  677.     return item_buff;
  678. }
  679. size_t CDBL_BlobResult::ReadItem(void* buffer, size_t buffer_size,
  680.                                  bool* is_null)
  681. {
  682.     if(m_BytesInBuffer == 0) 
  683.         m_CurrItem= 1;
  684.     if (m_CurrItem != 0) {
  685.         if (is_null)
  686.             *is_null = true;
  687.         return 0;
  688.     }
  689.     size_t l= 0;
  690.     // check if we do have something in buffer
  691.     if(m_ReadedBytes < m_BytesInBuffer) {
  692.         l= m_BytesInBuffer - m_ReadedBytes;
  693.         if(l >= buffer_size) {
  694.             memcpy(buffer, m_Buff + m_ReadedBytes, buffer_size);
  695.             m_ReadedBytes+= buffer_size;
  696.             if (is_null)
  697.                 *is_null = false;
  698.             return buffer_size;
  699.         }
  700.         memcpy(buffer, m_Buff + m_ReadedBytes, l);
  701.     }
  702.         
  703.     STATUS s = dbreadtext(m_Cmd, (void*)((char*)buffer + l), (DBINT)(buffer_size-l));
  704.     switch (s) {
  705.     case NO_MORE_ROWS:
  706.         m_EOR = true;
  707.     case 0:
  708.         m_CurrItem = 1;
  709.         break;
  710.     case -1:
  711.         throw CDB_ClientEx(eDB_Error, 280003, "CDBL_BlobResult::ReadItem",
  712.                            "dbreadtext failed");
  713.     default:
  714.         break;
  715.     }
  716.     if(is_null) *is_null= (m_BytesInBuffer == 0 && s <= 0);
  717.     return (size_t) s + l;
  718. }
  719. I_ITDescriptor* CDBL_BlobResult::GetImageOrTextDescriptor()
  720. {
  721.     if (m_CurrItem != 0)
  722.         return 0;
  723.     return new CDBL_ITDescriptor(m_Cmd, 1);
  724. }
  725. bool CDBL_BlobResult::SkipItem()
  726. {
  727.     if (m_EOR || m_CurrItem)
  728.         return false;
  729.     STATUS s;
  730.     while ((s = dbreadtext(m_Cmd, m_Buff, (DBINT) sizeof(m_Buff))) > 0);
  731.     switch (s) {
  732.     case NO_MORE_ROWS:
  733.         m_EOR = true;
  734.     case 0:
  735.         m_CurrItem = 1;
  736.         break;
  737.     default:
  738.         throw CDB_ClientEx(eDB_Error, 280003, "CDBL_BlobResult::SkipItem",
  739.                            "dbreadtext failed");
  740.     }
  741.     return true;
  742. }
  743. CDBL_BlobResult::~CDBL_BlobResult()
  744. {
  745.     if (!m_EOR)
  746.         dbcanquery(m_Cmd);
  747. }
  748. /////////////////////////////////////////////////////////////////////////////
  749. static EDB_Type s_RetGetDataType(DBPROCESS* cmd, int n)
  750. {
  751.     switch (dbrettype(cmd, n)) {
  752.     case SYBBINARY:    return (dbretlen(cmd, n) > 255)? eDB_LongBinary : 
  753.                                                         eDB_VarBinary;
  754.     case SYBBIT:       return eDB_Bit;
  755.     case SYBCHAR:      return (dbretlen(cmd, n) > 255)? eDB_LongChar : 
  756.                                                         eDB_VarChar;
  757.     case SYBDATETIME:  return eDB_DateTime;
  758.     case SYBDATETIME4: return eDB_SmallDateTime;
  759.     case SYBINT1:      return eDB_TinyInt;
  760.     case SYBINT2:      return eDB_SmallInt;
  761.     case SYBINT4:      return eDB_Int;
  762.     case SYBFLT8:      return eDB_Double;
  763.     case SYBREAL:      return eDB_Float;
  764.     default:           return eDB_UnsupportedType;
  765.     }
  766. }
  767. // Aux. for CDBL_ParamResult::GetItem()
  768. static CDB_Object* s_RetGetItem(DBPROCESS* cmd, int item_no,
  769.                                 SDBL_ColDescr* fmt, CDB_Object* item_buff)
  770. {
  771.     EDB_Type b_type = item_buff ? item_buff->GetType() : eDB_UnsupportedType;
  772.     const BYTE* d_ptr = dbretdata(cmd, item_no);
  773.     DBINT d_len = dbretlen (cmd, item_no);
  774.     CDB_Object* val = s_GenericGetItem(fmt->data_type, item_buff,
  775.                                        b_type, d_ptr, d_len);
  776.     if (!val) {
  777.         throw CDB_ClientEx(eDB_Error, 230004, "s_RetGetItem",
  778.                            "unexpected result type");
  779.     }
  780.     return val;
  781. }
  782. /////////////////////////////////////////////////////////////////////////////
  783. //
  784. //  CDBL_ParamResult::
  785. //
  786. CDBL_ParamResult::CDBL_ParamResult(DBPROCESS* cmd, int nof_params) :
  787.     CDBL_RowResult(cmd, 0, false)
  788. {
  789.     m_NofCols = nof_params;
  790.     m_CmdNum = DBCURCMD(cmd);
  791.     m_ColFmt = new SDBL_ColDescr[m_NofCols];
  792.     for (unsigned int n = 0; n < m_NofCols; n++) {
  793.         m_ColFmt[n].max_length = 255;
  794.         m_ColFmt[n].data_type = s_RetGetDataType(m_Cmd, n + 1);
  795.         const char* s = dbretname(m_Cmd, n + 1);
  796.         m_ColFmt[n].col_name = s ? s : "";
  797.     }
  798.     m_1stFetch = true;
  799. }
  800. EDB_ResType CDBL_ParamResult::ResultType() const
  801. {
  802.     return eDB_ParamResult;
  803. }
  804. bool CDBL_ParamResult::Fetch()
  805. {
  806.     if (m_1stFetch) { // we didn't get the items yet;
  807.         m_1stFetch = false;
  808. m_CurrItem= 0;
  809.         return true;
  810.     }
  811.     m_CurrItem= -1;
  812.     return false;
  813. }
  814. CDB_Object* CDBL_ParamResult::GetItem(CDB_Object* item_buff)
  815. {
  816.     if ((unsigned int) m_CurrItem >= m_NofCols) {
  817.         return 0;
  818.     }
  819.     CDB_Object* r = s_RetGetItem(m_Cmd, m_CurrItem + 1,
  820.                                  &m_ColFmt[m_CurrItem], item_buff);
  821.     ++m_CurrItem;
  822.     m_Offset = 0;
  823.     return r;
  824. }
  825. size_t CDBL_ParamResult::ReadItem(void* buffer, size_t buffer_size,
  826.                                   bool* is_null)
  827. {
  828.     if ((unsigned int) m_CurrItem >= m_NofCols) {
  829.         if (is_null)
  830.             *is_null = true;
  831.         return 0;
  832.     }
  833.     const BYTE* d_ptr = dbretdata(m_Cmd, m_CurrItem + 1);
  834.     DBINT d_len = dbretlen (m_Cmd, m_CurrItem + 1);
  835.     if (d_ptr == 0 || d_len < 1) { // NULL value
  836.         ++m_CurrItem;
  837.         m_Offset = 0;
  838.         if (is_null)
  839.             *is_null = true;
  840.         return 0;
  841.     }
  842.     if (is_null)
  843.         *is_null = false;
  844.     if ((size_t) d_len - m_Offset < buffer_size)
  845.         buffer_size = (size_t) d_len - m_Offset;
  846.     memcpy(buffer, d_ptr + m_Offset, buffer_size);
  847.     m_Offset += buffer_size;
  848.     if (m_Offset >= (size_t) d_len) {
  849.         m_Offset = 0;
  850.         ++m_CurrItem;
  851.     }
  852.     return buffer_size;
  853. }
  854. I_ITDescriptor* CDBL_ParamResult::GetImageOrTextDescriptor()
  855. {
  856.     return 0;
  857. }
  858. CDBL_ParamResult::~CDBL_ParamResult()
  859. {
  860.     if (m_ColFmt) {
  861.         delete[] m_ColFmt;
  862.         m_ColFmt = 0;
  863.     }
  864. }
  865. /////////////////////////////////////////////////////////////////////////////
  866. static EDB_Type s_AltGetDataType(DBPROCESS* cmd, int id, int n)
  867. {
  868.     switch (dbalttype(cmd, id, n)) {
  869.     case SYBBINARY:    return (dbaltlen(cmd, id, n) > 255)? eDB_LongBinary : 
  870.                                                         eDB_VarBinary;
  871.     case SYBBIT:       return eDB_Bit;
  872.     case SYBCHAR:      return (dbaltlen(cmd, id, n) > 255)? eDB_LongChar : 
  873.                                                         eDB_VarChar;
  874.     case SYBDATETIME:  return eDB_DateTime;
  875.     case SYBDATETIME4: return eDB_SmallDateTime;
  876.     case SYBINT1:      return eDB_TinyInt;
  877.     case SYBINT2:      return eDB_SmallInt;
  878.     case SYBINT4:      return eDB_Int;
  879.     case SYBFLT8:      return eDB_Double;
  880.     case SYBREAL:      return eDB_Float;
  881.     default:           return eDB_UnsupportedType;
  882.     }
  883. }
  884. // Aux. for CDBL_ComputeResult::GetItem()
  885. static CDB_Object* s_AltGetItem(DBPROCESS* cmd, int id, int item_no,
  886.                                 SDBL_ColDescr* fmt, CDB_Object* item_buff)
  887. {
  888.     EDB_Type b_type = item_buff ? item_buff->GetType() : eDB_UnsupportedType;
  889.     const BYTE* d_ptr = dbadata(cmd, id, item_no);
  890.     DBINT d_len = dbadlen(cmd, id, item_no);
  891.     CDB_Object* val = s_GenericGetItem(fmt->data_type, item_buff,
  892.                                        b_type, d_ptr, d_len);
  893.     if (!val) {
  894.         throw CDB_ClientEx(eDB_Error, 130004, "s_AltGetItem",
  895.                            "unexpected result type");
  896.     }
  897.     return val;
  898. }
  899. /////////////////////////////////////////////////////////////////////////////
  900. //
  901. //  CTL_ComputeResult::
  902. //
  903. CDBL_ComputeResult::CDBL_ComputeResult(DBPROCESS* cmd,
  904.                                        unsigned int* res_stat) :
  905.     CDBL_RowResult(cmd, res_stat, false)
  906. {
  907.     m_ComputeId = DBROWTYPE(cmd);
  908.     if (m_ComputeId == REG_ROW || m_ComputeId == NO_MORE_ROWS) {
  909.         throw CDB_ClientEx(eDB_Error, 270000,
  910.                            "CDBL_ComputeResult::CDBL_ComputeResult",
  911.                            "no compute row found");
  912.     }
  913.     m_NofCols = dbnumalts(cmd, m_ComputeId);
  914.     if (m_NofCols < 1) {
  915.         throw CDB_ClientEx(eDB_Error, 270001,
  916.                            "CDBL_ComputeResult::CDBL_ComputeResult",
  917.                            "compute id is invalid");
  918.     }
  919.     m_CmdNum = DBCURCMD(cmd);
  920.     m_ColFmt = new SDBL_ColDescr[m_NofCols];
  921.     for (unsigned int n = 0; n < m_NofCols; n++) {
  922.         m_ColFmt[n].max_length = dbaltlen(m_Cmd, m_ComputeId, n+1);
  923.         m_ColFmt[n].data_type = s_AltGetDataType(m_Cmd, m_ComputeId, n + 1);
  924.         int op = dbaltop(m_Cmd, m_ComputeId, n + 1);
  925.         const char* s = op != -1 ? dbprtype(op) : "Unknown";
  926.         m_ColFmt[n].col_name = s ? s : "";
  927.     }
  928.     m_1stFetch = true;
  929. }
  930. EDB_ResType CDBL_ComputeResult::ResultType() const
  931. {
  932.     return eDB_ComputeResult;
  933. }
  934. bool CDBL_ComputeResult::Fetch()
  935. {
  936.     if (m_1stFetch) { // we didn't get the items yet;
  937.         m_1stFetch = false;
  938. m_CurrItem= 0;
  939.         return true;
  940.     }
  941.     STATUS s = dbnextrow(m_Cmd);
  942.     switch (s) {
  943.     case REG_ROW:
  944.     case NO_MORE_ROWS:
  945.         *m_ResStatus ^= 0x10;
  946.         break;
  947.     case FAIL:
  948.         throw CDB_ClientEx(eDB_Error, 270003, "CDBL_ComputeResult::Fetch",
  949.                            "error in fetching row");
  950.     case BUF_FULL:
  951.         throw CDB_ClientEx(eDB_Error, 270006, "CDBL_ComputeResult::Fetch",
  952.                            "buffer is full");
  953.     default:
  954.         break;
  955.     }
  956.     m_EOR = true;
  957.     m_CurrItem= -1;
  958.     return false;
  959. }
  960. int CDBL_ComputeResult::CurrentItemNo() const
  961. {
  962.     return m_CurrItem;
  963. }
  964. CDB_Object* CDBL_ComputeResult::GetItem(CDB_Object* item_buff)
  965. {
  966.     if ((unsigned int) m_CurrItem >= m_NofCols) {
  967.         return 0;
  968.     }
  969.     CDB_Object* r = s_AltGetItem(m_Cmd, m_ComputeId, m_CurrItem + 1,
  970.                                  &m_ColFmt[m_CurrItem], item_buff);
  971.     ++m_CurrItem;
  972.     m_Offset = 0;
  973.     return r;
  974. }
  975. size_t CDBL_ComputeResult::ReadItem(void* buffer, size_t buffer_size,
  976.                                     bool* is_null)
  977. {
  978.     if ((unsigned int) m_CurrItem >= m_NofCols) {
  979.         if (is_null)
  980.             *is_null = true;
  981.         return 0;
  982.     }
  983.     const BYTE* d_ptr = dbadata(m_Cmd, m_ComputeId, m_CurrItem + 1);
  984.     DBINT d_len = dbadlen(m_Cmd, m_ComputeId, m_CurrItem + 1);
  985.     if (d_ptr == 0 || d_len < 1) { // NULL value
  986.         ++m_CurrItem;
  987.         m_Offset = 0;
  988.         if (is_null)
  989.             *is_null = true;
  990.         return 0;
  991.     }
  992.     if (is_null)
  993.         *is_null = false;
  994.     if ((size_t) d_len - m_Offset < buffer_size)
  995.         buffer_size = (size_t) d_len - m_Offset;
  996.     memcpy(buffer, d_ptr + m_Offset, buffer_size);
  997.     m_Offset += buffer_size;
  998.     if (m_Offset >= (size_t) d_len) {
  999.         m_Offset = 0;
  1000.         ++m_CurrItem;
  1001.     }
  1002.     return buffer_size;
  1003. }
  1004. I_ITDescriptor* CDBL_ComputeResult::GetImageOrTextDescriptor()
  1005. {
  1006.     return 0;
  1007. }
  1008. CDBL_ComputeResult::~CDBL_ComputeResult()
  1009. {
  1010.     if (m_ColFmt) {
  1011.         delete[] m_ColFmt;
  1012.         m_ColFmt = 0;
  1013.     }
  1014.     while (!m_EOR)
  1015.         Fetch();
  1016. }
  1017. /////////////////////////////////////////////////////////////////////////////
  1018. //
  1019. //  CTL_StatusResult::
  1020. //
  1021. CDBL_StatusResult::CDBL_StatusResult(DBPROCESS* cmd) :
  1022.     m_Offset(0), m_1stFetch(true)
  1023. {
  1024.     m_Val = dbretstatus(cmd);
  1025. }
  1026. EDB_ResType CDBL_StatusResult::ResultType() const
  1027. {
  1028.     return eDB_StatusResult;
  1029. }
  1030. unsigned int CDBL_StatusResult::NofItems() const
  1031. {
  1032.     return 1;
  1033. }
  1034. const char* CDBL_StatusResult::ItemName(unsigned int) const
  1035. {
  1036.     return 0;
  1037. }
  1038. size_t CDBL_StatusResult::ItemMaxSize(unsigned int) const
  1039. {
  1040.     return sizeof(DBINT);
  1041. }
  1042. EDB_Type CDBL_StatusResult::ItemDataType(unsigned int) const
  1043. {
  1044.     return eDB_Int;
  1045. }
  1046. bool CDBL_StatusResult::Fetch()
  1047. {
  1048.     if (m_1stFetch) {
  1049.         m_1stFetch = false;
  1050.         return true;
  1051.     }
  1052.     return false;
  1053. }
  1054. int CDBL_StatusResult::CurrentItemNo() const
  1055. {
  1056.     return m_1stFetch? -1 : 0;
  1057. }
  1058. CDB_Object* CDBL_StatusResult::GetItem(CDB_Object* item_buff)
  1059. {
  1060.     if (!item_buff)
  1061.         return new CDB_Int(m_Val);
  1062.     if (item_buff->GetType() != eDB_Int) {
  1063.         throw CDB_ClientEx(eDB_Error, 230020, "CDBL_StatusResult::GetItem",
  1064.                            "wrong type of CDB_Object");
  1065.     }
  1066.     CDB_Int* i = (CDB_Int*) item_buff;
  1067.     *i = m_Val;
  1068.     return item_buff;
  1069. }
  1070. size_t CDBL_StatusResult::ReadItem(void* buffer, size_t buffer_size,
  1071.                                    bool* is_null)
  1072. {
  1073.     if (is_null)
  1074.         *is_null = false;
  1075.     if (sizeof(m_Val) <= m_Offset)
  1076.         return 0;
  1077.     size_t l = sizeof(int) - m_Offset;
  1078.     char* p = (char*) &m_Val;
  1079.     if (buffer_size > l)
  1080.         buffer_size = l;
  1081.     memcpy(buffer, p + m_Offset, buffer_size);
  1082.     m_Offset += buffer_size;
  1083.     return buffer_size;
  1084. }
  1085. I_ITDescriptor* CDBL_StatusResult::GetImageOrTextDescriptor()
  1086. {
  1087.     return 0;
  1088. }
  1089. bool CDBL_StatusResult::SkipItem()
  1090. {
  1091.     return false;
  1092. }
  1093. CDBL_StatusResult::~CDBL_StatusResult()
  1094. {
  1095. }
  1096. /////////////////////////////////////////////////////////////////////////////
  1097. //
  1098. //  CTL_CursorResult::
  1099. //
  1100. CDBL_CursorResult::CDBL_CursorResult(CDB_LangCmd* cmd) :
  1101.     m_Cmd(cmd), m_Res(0)
  1102. {
  1103.     try {
  1104.         m_Cmd->Send();
  1105.         while (m_Cmd->HasMoreResults()) {
  1106.             m_Res = m_Cmd->Result();
  1107.             if (m_Res && m_Res->ResultType() == eDB_RowResult) {
  1108.                 return;
  1109.             }
  1110.             if (m_Res) {
  1111.                 while (m_Res->Fetch())
  1112.                     ;
  1113.                 delete m_Res;
  1114.                 m_Res = 0;
  1115.             }
  1116.         }
  1117.     } catch (CDB_Exception& ) {
  1118.         throw CDB_ClientEx(eDB_Error, 222010,
  1119.                            "CDBL_CursorResult::CDBL_CursorResult",
  1120.                            "failed to get the results");
  1121.     }
  1122. }
  1123. EDB_ResType CDBL_CursorResult::ResultType() const
  1124. {
  1125.     return eDB_CursorResult;
  1126. }
  1127. unsigned int CDBL_CursorResult::NofItems() const
  1128. {
  1129.     return m_Res? m_Res->NofItems() : 0;
  1130. }
  1131. const char* CDBL_CursorResult::ItemName(unsigned int item_num) const
  1132. {
  1133.     return m_Res ? m_Res->ItemName(item_num) : 0;
  1134. }
  1135. size_t CDBL_CursorResult::ItemMaxSize(unsigned int item_num) const
  1136. {
  1137.     return m_Res ? m_Res->ItemMaxSize(item_num) : 0;
  1138. }
  1139. EDB_Type CDBL_CursorResult::ItemDataType(unsigned int item_num) const
  1140. {
  1141.     return m_Res ? m_Res->ItemDataType(item_num) : eDB_UnsupportedType;
  1142. }
  1143. bool CDBL_CursorResult::Fetch()
  1144. {
  1145.     if (!m_Res)
  1146.         return false;
  1147.     if (m_Res->Fetch())
  1148.         return true;
  1149.     try {
  1150.         // finish this command
  1151.         delete m_Res;
  1152.         while (m_Cmd->HasMoreResults()) {
  1153.             m_Res = m_Cmd->Result();
  1154.             if (m_Res) {
  1155.                 while (m_Res->Fetch())
  1156.                     ;
  1157.                 delete m_Res;
  1158.                 m_Res = 0;
  1159.             }
  1160.         }
  1161.         // send the another "fetch cursor_name" command
  1162.         m_Cmd->Send();
  1163.         while (m_Cmd->HasMoreResults()) {
  1164.             m_Res = m_Cmd->Result();
  1165.             if (m_Res && m_Res->ResultType() == eDB_RowResult) {
  1166.                 return m_Res->Fetch();
  1167.             }
  1168.             if (m_Res) {
  1169.                 while (m_Res->Fetch())
  1170.                     ;
  1171.                 delete m_Res;
  1172.                 m_Res = 0;
  1173.             }
  1174.         }
  1175.     } catch (CDB_Exception& ) {
  1176.         throw CDB_ClientEx(eDB_Error, 222011, "CDBL_CursorResult::Fetch",
  1177.                            "Failed to fetch the results");
  1178.     }
  1179.     return false;
  1180. }
  1181. int CDBL_CursorResult::CurrentItemNo() const
  1182. {
  1183.     return m_Res ? m_Res->CurrentItemNo() : -1;
  1184. }
  1185. CDB_Object* CDBL_CursorResult::GetItem(CDB_Object* item_buff)
  1186. {
  1187.     return m_Res ? m_Res->GetItem(item_buff) : 0;
  1188. }
  1189. size_t CDBL_CursorResult::ReadItem(void* buffer, size_t buffer_size,
  1190.                                    bool* is_null)
  1191. {
  1192.     if (m_Res) {
  1193.         return m_Res->ReadItem(buffer, buffer_size, is_null);
  1194.     }
  1195.     if (is_null)
  1196.         *is_null = true;
  1197.     return 0;
  1198. }
  1199. I_ITDescriptor* CDBL_CursorResult::GetImageOrTextDescriptor()
  1200. {
  1201.     return m_Res ? m_Res->GetImageOrTextDescriptor() : 0;
  1202. }
  1203. bool CDBL_CursorResult::SkipItem()
  1204. {
  1205.     return m_Res ? m_Res->SkipItem() : false;
  1206. }
  1207. CDBL_CursorResult::~CDBL_CursorResult()
  1208. {
  1209.     if (m_Res)
  1210.         delete m_Res;
  1211. }
  1212. /////////////////////////////////////////////////////////////////////////////
  1213. //
  1214. //  CDBL_ITDescriptor::
  1215. //
  1216. CDBL_ITDescriptor::CDBL_ITDescriptor(DBPROCESS* dblink, int col_num)
  1217. {
  1218. #ifdef MS_DBLIB_IN_USE /*Text,Image*/
  1219.     const char* pColName = dbcolname(dblink,col_num);
  1220.     if(pColName == NULL) {
  1221.         throw CDB_ClientEx(eDB_Error, 280000,
  1222.                            "CDBL_ITDescriptor::CDBL_ITDescriptor",
  1223.                            "dbcolname() returns NULL");
  1224.     }
  1225.     // We have to use an offset in some undocumented structure
  1226.     // (obtained with the help of a debugger).
  1227.     // It may change in future MS dblib versions...
  1228.     const char* pTabName = *(char**)(pColName+50);
  1229.     m_ObjName += pTabName;
  1230.     m_ObjName += ".";
  1231.     m_ObjName += pColName;
  1232. #else
  1233.     DBCOLINFO* col_info = (DBCOLINFO*) dbcolname(dblink, col_num);
  1234.     if (col_info == 0) {
  1235.         throw CDB_ClientEx(eDB_Error, 280000,
  1236.                            "CDBL_ITDescriptor::CDBL_ITDescriptor",
  1237.                            "Can not get the DBCOLINFO*");
  1238.     }
  1239.     if (!x_MakeObjName(col_info)) {
  1240.         m_ObjName = "";
  1241.     }
  1242. #endif
  1243.     DBBINARY* p = dbtxptr(dblink, col_num);
  1244.     if (p) {
  1245.         memcpy(m_TxtPtr, p, DBTXPLEN);
  1246.         m_TxtPtr_is_NULL = false;
  1247.     } else
  1248.         m_TxtPtr_is_NULL = true;
  1249.     p = dbtxtimestamp(dblink, col_num);
  1250.     if (p) {
  1251.         memcpy(m_TimeStamp, p, DBTXTSLEN);
  1252.         m_TimeStamp_is_NULL = false;
  1253.     } else
  1254.         m_TimeStamp_is_NULL = true;
  1255. }
  1256. CDBL_ITDescriptor::CDBL_ITDescriptor(DBPROCESS* dblink, const CDB_ITDescriptor& inp_d)
  1257. {
  1258.     m_ObjName= inp_d.TableName();
  1259.     m_ObjName+= ".";
  1260.     m_ObjName+= inp_d.ColumnName();
  1261.     
  1262.     DBBINARY* p = dbtxptr(dblink, 1);
  1263.     if (p) {
  1264.         memcpy(m_TxtPtr, p, DBTXPLEN);
  1265.         m_TxtPtr_is_NULL = false;
  1266.     } else
  1267.         m_TxtPtr_is_NULL = true;
  1268.     p = dbtxtimestamp(dblink, 1);
  1269.     if (p) {
  1270.         memcpy(m_TimeStamp, p, DBTXTSLEN);
  1271.         m_TimeStamp_is_NULL = false;
  1272.     } else
  1273.         m_TimeStamp_is_NULL = true;
  1274. }
  1275. int CDBL_ITDescriptor::DescriptorType() const
  1276. {
  1277. #ifndef MS_DBLIB_IN_USE
  1278.     return CDBL_ITDESCRIPTOR_TYPE_MAGNUM;
  1279. #else
  1280. return CMSDBL_ITDESCRIPTOR_TYPE_MAGNUM;
  1281. #endif
  1282. }
  1283. CDBL_ITDescriptor::~CDBL_ITDescriptor()
  1284. {
  1285. }
  1286. #ifndef MS_DBLIB_IN_USE
  1287. bool CDBL_ITDescriptor::x_MakeObjName(DBCOLINFO* col_info)
  1288. {
  1289.     if (!col_info || !col_info->coltxobjname)
  1290.         return false;
  1291.     m_ObjName = col_info->coltxobjname;
  1292.     // check if we do have ".colname" suffix already
  1293.     char* p_dot = strrchr(col_info->coltxobjname, '.');
  1294.     if (!p_dot || strcmp(p_dot + 1, col_info->colname) != 0) {
  1295.         // we don't have a suffix. Add it now
  1296.         m_ObjName += '.';
  1297.         m_ObjName += col_info->colname;
  1298.     }
  1299.     return true;
  1300. }
  1301. #endif
  1302. END_NCBI_SCOPE
  1303. /*
  1304.  * ===========================================================================
  1305.  * $Log: result.cpp,v $
  1306.  * Revision 1000.2  2004/06/01 19:20:21  gouriano
  1307.  * PRODUCTION: UPGRADED [GCC34_MSVC7] Dev-tree R1.22
  1308.  *
  1309.  * Revision 1.22  2004/05/18 18:30:36  gorelenk
  1310.  * PCH <ncbi_pch.hpp> moved to correct place .
  1311.  *
  1312.  * Revision 1.21  2004/05/17 21:12:41  gorelenk
  1313.  * Added include of PCH ncbi_pch.hpp
  1314.  *
  1315.  * Revision 1.20  2004/04/08 19:05:51  gorelenk
  1316.  * Changed declalation of s_GenericGetItem (added 'const' to 'BYTE* d_ptr')
  1317.  * and fixed compilation errors on MSVC 7.10 .
  1318.  *
  1319.  * Revision 1.19  2003/04/29 21:16:21  soussov
  1320.  * new datatypes CDB_LongChar and CDB_LongBinary added
  1321.  *
  1322.  * Revision 1.18  2003/01/31 16:50:12  lavr
  1323.  * Remove unused variable "e" from catch() clause
  1324.  *
  1325.  * Revision 1.17  2003/01/06 16:40:49  soussov
  1326.  * sets m_CurrItem = -1 for all result types if no fetch was called
  1327.  *
  1328.  * Revision 1.16  2003/01/03 21:48:08  soussov
  1329.  * set m_CurrItem = -1 if fetch failes
  1330.  *
  1331.  * Revision 1.15  2002/07/18 14:59:10  soussov
  1332.  * fixes bug in blob result
  1333.  *
  1334.  * Revision 1.14  2002/07/02 16:05:50  soussov
  1335.  * splitting Sybase dblib and MS dblib
  1336.  *
  1337.  * Revision 1.13  2002/05/29 22:04:58  soussov
  1338.  * Makes BlobResult read ahead
  1339.  *
  1340.  * Revision 1.12  2002/03/26 15:37:52  soussov
  1341.  * new image/text operations added
  1342.  *
  1343.  * Revision 1.11  2002/02/06 22:27:54  soussov
  1344.  * fixes the arguments order in numeric assign
  1345.  *
  1346.  * Revision 1.10  2002/01/11 20:11:43  vakatov
  1347.  * Fixed CVS logs from prev. revision that messed up the compilation
  1348.  *
  1349.  * Revision 1.9  2002/01/10 22:05:52  sapojnik
  1350.  * MS-specific workarounds needed to use blobs via I_ITDescriptor
  1351.  * (see Text,Image)
  1352.  *
  1353.  * Revision 1.8  2002/01/08 18:10:18  sapojnik
  1354.  * Syabse to MSSQL name translations moved to interface_p.hpp
  1355.  *
  1356.  * Revision 1.7  2002/01/03 17:01:56  sapojnik
  1357.  * fixing CR/LF mixup
  1358.  *
  1359.  * Revision 1.6  2002/01/03 15:46:23  sapojnik
  1360.  * ported to MS SQL (about 12 'ifdef NCBI_OS_MSWIN' in 6 files)
  1361.  *
  1362.  * Revision 1.5  2001/11/06 17:59:58  lavr
  1363.  * Formatted uniformly as the rest of the library
  1364.  *
  1365.  * Revision 1.4  2001/10/24 16:38:42  lavr
  1366.  * Explicit casts (where necessary) to eliminate 64->32 bit compiler warnings
  1367.  *
  1368.  * Revision 1.3  2001/10/24 05:19:24  vakatov
  1369.  * Fixed return type for ItemMaxSize()
  1370.  *
  1371.  * Revision 1.2  2001/10/22 16:28:01  lavr
  1372.  * Default argument values removed
  1373.  * (mistakenly left while moving code from header files)
  1374.  *
  1375.  * Revision 1.1  2001/10/22 15:19:55  lavr
  1376.  * This is a major revamp (by Anton Lavrentiev, with help from Vladimir
  1377.  * Soussov and Denis Vakatov) of the DBAPI "driver" libs originally
  1378.  * written by Vladimir Soussov. The revamp follows the one of CTLib
  1379.  * driver, and it involved massive code shuffling and grooming, numerous
  1380.  * local API redesigns, adding comments and incorporating DBAPI to
  1381.  * the C++ Toolkit.
  1382.  *
  1383.  * ===========================================================================
  1384.  */