include/dbapi/driver/dbapi_driver_convert.hpp

Go to the documentation of this file.
00001 #ifndef DBAPI_DRIVER___DBAPI_DRIVER_CONVERT__HPP
00002 #define DBAPI_DRIVER___DBAPI_DRIVER_CONVERT__HPP
00003 
00004 /* $Id: dbapi_driver_convert.hpp 169152 2009-08-26 16:47:29Z ivanovp $
00005  * ===========================================================================
00006  *
00007  *                            PUBLIC DOMAIN NTOICE
00008  *               National Center for Biotechnology Information
00009  *
00010  *  This software/database is a "United States Government Work" under the
00011  *  terms of the United States Copyright Act.  It was written as part of
00012  *  the author's official duties as a United States Government employee and
00013  *  thus cannot be copyrighted.  This software/database is freely available
00014  *  to the public for use. The National Library of Medicine and the U.S.
00015  *  Government have not placed any restriction on its use or reproduction.
00016  *
00017  *  Although all reasonable efforts have been taken to ensure the accuracy
00018  *  and reliability of the software and data, the NLM and the U.S.
00019  *  Government do not and cannot warrant the performance or results that
00020  *  may be obtained by using this software or data. The NLM and the U.S.
00021  *  Government disclaim all warranties, express or implied, including
00022  *  warranties of performance, merchantability or fitness for any particular
00023  *  purpose.
00024  *
00025  *  Please cite the author in any work or product based on this material.
00026  *
00027  * ===========================================================================
00028  *
00029  * Author:  Sergey Sikorskiy
00030  *
00031  * File Description:
00032  *
00033  */
00034 
00035 #include <dbapi/driver/public.hpp>
00036 #include <dbapi/driver/dbapi_object_convert.hpp>
00037 // Future development ...
00038 // #include <dbapi/driver/dbapi_driver_value_slice.hpp>
00039 
00040 #include <vector>
00041 #include <set>
00042 #include <stack>
00043 
00044 BEGIN_NCBI_SCOPE
00045 
00046 namespace value_slice
00047 {
00048 
00049 ////////////////////////////////////////////////////////////////////////////////
00050 template <>
00051 class CValueConvert<SSafeCP, CDB_Result>
00052 {
00053 public:
00054     typedef const CDB_Result obj_type;
00055     typedef SSafeCP CP;
00056 
00057     CValueConvert(obj_type& value)
00058     : m_Value(&value)
00059     {
00060     }
00061 
00062 public:
00063     operator bool(void) const
00064     {
00065         CDB_Bit db_obj;
00066         const_cast<CDB_Result*>(m_Value)->GetItem(&db_obj);
00067         if (db_obj.IsNULL()) {
00068             throw CInvalidConversionException();
00069         }
00070         return db_obj.Value() != 0;
00071     }
00072     operator Uint1(void) const
00073     {
00074         return ConvertFrom<Uint1, CDB_TinyInt>();
00075     }
00076     operator Int2(void) const
00077     {
00078         return ConvertFrom<Int2, CDB_SmallInt>();
00079     }
00080     operator Int4(void) const
00081     {
00082         return ConvertFrom<Int4, CDB_Int>();
00083     }
00084     operator Int8(void) const
00085     {
00086         return ConvertFrom<Int8, CDB_BigInt>();
00087     }
00088     operator float(void) const
00089     {
00090         return ConvertFrom<float, CDB_Float>();
00091     }
00092     operator double(void) const
00093     {
00094         return ConvertFrom<double, CDB_Double>();
00095     }
00096     operator string(void) const
00097     {
00098         CDB_VarChar db_obj;
00099         const_cast<CDB_Result*>(m_Value)->GetItem(&db_obj);
00100         if (db_obj.IsNULL()) {
00101             throw CInvalidConversionException();
00102         }
00103         return string(db_obj.Value(), db_obj.Size());
00104     }
00105     operator CTime(void) const
00106     {
00107         return ConvertFrom<const CTime&, CDB_DateTime>();
00108     }
00109 
00110 private:
00111     template <typename TO, typename FROM>
00112     TO ConvertFrom(void) const
00113     {
00114         FROM db_obj;
00115         const_cast<CDB_Result*>(m_Value)->GetItem(&db_obj);
00116         if (db_obj.IsNULL()) {
00117             throw CInvalidConversionException();
00118         }
00119         return MakeCP<CP>(db_obj.Value());
00120     }
00121 
00122 private:
00123     obj_type* m_Value;
00124 };
00125 
00126 ////////////////////////////////////////////////////////////////////////////////
00127 template <>
00128 class CValueConvert<SSafeSqlCP, CDB_Result>
00129 {
00130 public:
00131     typedef const CDB_Result obj_type;
00132     typedef SSafeSqlCP CP;
00133 
00134     CValueConvert(const CValueConvert<CP, CDB_Result>& value)
00135     : m_Value(value.m_Value)
00136     {
00137     }
00138     CValueConvert(obj_type& value)
00139     : m_Value(&value)
00140     {
00141     }
00142 
00143 public:
00144     operator bool(void) const
00145     {
00146         const int item_num = m_Value->CurrentItemNo();
00147         const EDB_Type db_type = m_Value->ItemDataType(item_num);
00148 
00149         // *null* is reported as eDB_Int by several drivers.
00150         // That means that *null* can be checked using Int4 type only.
00151         // List of *special* drivers: ftds64, ctlib.
00152         if (db_type == eDB_Int) {
00153             CDB_Int db_obj_int;
00154 
00155             const_cast<CDB_Result*>(m_Value)->GetItem(&db_obj_int);
00156             if (db_obj_int.IsNULL()) {
00157                 return bool();
00158             }
00159 
00160             throw CInvalidConversionException();
00161         }
00162 
00163         CDB_Bit db_obj;
00164         const_cast<CDB_Result*>(m_Value)->GetItem(&db_obj);
00165 
00166         if (db_obj.IsNULL()) {
00167             return bool();
00168         }
00169 
00170         return db_obj.Value() != 0;
00171     }
00172     operator Uint1(void) const
00173     {
00174         return ConvertFrom<Uint1, CDB_TinyInt>();
00175     }
00176     operator Int2(void) const
00177     {
00178         return ConvertFrom<Int2, CDB_SmallInt>();
00179     }
00180     operator Int4(void) const
00181     {
00182         CDB_Int db_obj;
00183         const_cast<CDB_Result*>(m_Value)->GetItem(&db_obj);
00184 
00185         if (db_obj.IsNULL()) {
00186             return Int4();
00187         }
00188 
00189         // We are using SSafeCP intentionally here ...
00190         return MakeCP<SSafeCP>(db_obj.Value());
00191     }
00192     operator Int8(void) const
00193     {
00194         return ConvertFrom<Int8, CDB_BigInt>();
00195     }
00196     operator float(void) const
00197     {
00198         return ConvertFrom<float, CDB_Float>();
00199     }
00200     operator double(void) const
00201     {
00202         return ConvertFrom<double, CDB_Double>();
00203     }
00204     operator string(void) const
00205     {
00206         const int item_num = m_Value->CurrentItemNo();
00207         const EDB_Type db_type = m_Value->ItemDataType(item_num);
00208 
00209         // *null* is reported as eDB_Int by several drivers.
00210         // That means that *null* can be checked using Int4 type only.
00211         // List of *special* drivers: ftds64, ctlib.
00212         CDB_Int db_obj_int;
00213         if (db_type == eDB_Int) {
00214 
00215             const_cast<CDB_Result*>(m_Value)->GetItem(&db_obj_int);
00216             if (db_obj_int.IsNULL()) {
00217                 return string();
00218             }
00219 
00220             throw CInvalidConversionException();
00221         }
00222 
00223         CDB_VarChar db_obj;
00224         const_cast<CDB_Result*>(m_Value)->GetItem(&db_obj);
00225         if (db_obj.IsNULL()) {
00226             return string();
00227         }
00228         return string(db_obj.Value(), db_obj.Size());
00229     }
00230     operator CTime(void) const
00231     {
00232         return ConvertFrom<CTime, CDB_DateTime>();
00233     }
00234 
00235 private:
00236     template <typename TO, typename FROM>
00237     TO ConvertFrom(void) const
00238     {
00239         const int item_num = m_Value->CurrentItemNo();
00240         const EDB_Type db_type = m_Value->ItemDataType(item_num);
00241 
00242         // *null* is reported as eDB_Int by several drivers.
00243         // That means that *null* can be checked using Int4 type only.
00244         // List of *special* drivers: ftds64, ctlib.
00245         if (db_type == eDB_Int) {
00246             CDB_Int db_obj_int;
00247 
00248             const_cast<CDB_Result*>(m_Value)->GetItem(&db_obj_int);
00249             if (db_obj_int.IsNULL()) {
00250                 return TO();
00251             }
00252 
00253             throw CInvalidConversionException();
00254         }
00255 
00256         FROM db_obj;
00257         const_cast<CDB_Result*>(m_Value)->GetItem(&db_obj);
00258 
00259         if (db_obj.IsNULL()) {
00260             return TO();
00261         }
00262 
00263         // We are using SSafeCP intentionally here ...
00264         return MakeCP<SSafeCP>(db_obj.Value());
00265     }
00266 
00267 private:
00268     obj_type* m_Value;
00269 };
00270 
00271 ////////////////////////////////////////////////////////////////////////////////
00272 template <>
00273 class  CValueConvert<SRunTimeCP, CDB_Result>
00274 {
00275 public:
00276     typedef const CDB_Result obj_type;
00277 
00278     CValueConvert(obj_type& value);
00279 
00280 public:
00281     operator bool(void) const;
00282     operator Int1(void) const;
00283     operator Uint1(void) const;
00284     operator Int2(void) const;
00285     operator Uint2(void) const;
00286     operator Int4(void) const;
00287     operator Uint4(void) const;
00288     operator Int8(void) const;
00289     operator Uint8(void) const;
00290     operator float(void) const;
00291     operator double(void) const;
00292     operator string(void) const;
00293     operator CTime(void) const;
00294 
00295 private:
00296     /* future development ...
00297     template <typename TO, typename FROM>
00298     TO ConvertFrom(void) const
00299     {
00300         FROM db_obj;
00301         wrapper<FROM> obj_wrapper(db_obj);
00302 
00303         const_cast<CDB_Result*>(m_Value)->GetItem(&db_obj);
00304         if (obj_wrapper.is_null()) {
00305             throw CInvalidConversionException();
00306         }
00307 
00308         // return MakeCP<SRunTimeCP>(obj_wrapper.get_value());
00309         return Convert(obj_wrapper.get_value());
00310     }
00311     */
00312 
00313     template <typename TO, typename FROM>
00314     TO ConvertFrom(void) const
00315     {
00316         FROM db_obj;
00317 
00318         const_cast<CDB_Result*>(m_Value)->GetItem(&db_obj);
00319         if (db_obj.IsNULL()) {
00320             throw CInvalidConversionException();
00321         }
00322 
00323         return Convert(db_obj.Value());
00324     }
00325 
00326     template <typename TO, typename FROM>
00327     TO ConvertFromStr(void) const
00328     {
00329         FROM db_obj;
00330 
00331         const_cast<CDB_Result*>(m_Value)->GetItem(&db_obj);
00332         if (db_obj.IsNULL()) {
00333             throw CInvalidConversionException();
00334         }
00335 
00336         return Convert(string(static_cast<const char*>(db_obj.Value()), db_obj.Size()));
00337     }
00338 
00339     template <typename TO, typename FROM>
00340     TO ConvertFromChar(const int item_num) const
00341     {
00342         FROM db_obj(m_Value->ItemMaxSize(item_num));
00343 
00344         const_cast<CDB_Result*>(m_Value)->GetItem(&db_obj);
00345         if (db_obj.IsNULL()) {
00346             throw CInvalidConversionException();
00347         }
00348 
00349         return Convert(string(static_cast<const char*>(db_obj.Value()), db_obj.Size()));
00350     }
00351 
00352     template <typename TO, typename FROM>
00353     TO ConvertFromLOB(void) const
00354     {
00355         FROM db_obj;
00356         string result;
00357 
00358         const_cast<CDB_Result*>(m_Value)->GetItem(&db_obj);
00359         if (db_obj.IsNULL()) {
00360             throw CInvalidConversionException();
00361         }
00362 
00363         result.resize(db_obj.Size());
00364         db_obj.Read(const_cast<void*>(static_cast<const void*>(result.c_str())),
00365                 db_obj.Size()
00366                 );
00367 
00368         return Convert(result);
00369     }
00370 
00371     template <typename TO, typename FROM>
00372     TO Convert2CTime(void) const
00373     {
00374         FROM db_obj;
00375 
00376         const_cast<CDB_Result*>(m_Value)->GetItem(&db_obj);
00377         if (db_obj.IsNULL()) {
00378             throw CInvalidConversionException();
00379         }
00380 
00381         return CTime(time_t(Convert(db_obj.Value())));
00382     }
00383 
00384     template <typename TO>
00385     void ReadCDBObject(TO& value) const
00386     {
00387         const int item_num = m_Value->CurrentItemNo();
00388         const EDB_Type db_type = m_Value->ItemDataType(item_num);
00389 
00390         switch (db_type) {
00391             case eDB_Int:
00392                 value = ConvertFrom<TO, CDB_Int>();
00393                 break;
00394             case eDB_SmallInt:
00395                 value = ConvertFrom<TO, CDB_SmallInt>();
00396                 break;
00397             case eDB_TinyInt:
00398                 value = ConvertFrom<TO, CDB_TinyInt>();
00399                 break;
00400             case eDB_BigInt:
00401                 value = ConvertFrom<TO, CDB_BigInt>();
00402                 break;
00403             case eDB_VarChar:
00404                 value = ConvertFromStr<TO, CDB_VarChar>();
00405                 break;
00406             case eDB_Char:
00407                 value = ConvertFromChar<TO, CDB_Char>(item_num);
00408                 break;
00409             case eDB_VarBinary:
00410                 value = ConvertFromStr<TO, CDB_VarBinary>();
00411                 break;
00412             case eDB_Binary:
00413                 value = ConvertFromChar<TO, CDB_Binary>(item_num);
00414                 break;
00415             case eDB_Float:
00416                 value = ConvertFrom<TO, CDB_Float>();
00417                 break;
00418             case eDB_Double:
00419                 value = ConvertFrom<TO, CDB_Double>();
00420                 break;
00421                 // case eDB_DateTime:
00422                 //     value = ConvertFrom<TO, CDB_DateTime>();
00423                 // case eDB_SmallDateTime:
00424                 //     value = ConvertFrom<TO, CDB_SmallDateTime>();
00425             case eDB_Text:
00426                 value = ConvertFromLOB<TO, CDB_Text>();
00427                 break;
00428             case eDB_Image:
00429                 value = ConvertFromLOB<TO, CDB_Image>();
00430                 break;
00431             case eDB_Bit:
00432                 value = ConvertFrom<TO, CDB_Bit>();
00433                 break;
00434             case eDB_Numeric:
00435                 value = ConvertFrom<TO, CDB_Numeric>();
00436                 break;
00437             case eDB_LongChar:
00438                 value = ConvertFromChar<TO, CDB_LongChar>(item_num);
00439                 break;
00440             case eDB_LongBinary:
00441                 {
00442                     CDB_LongBinary db_obj(m_Value->ItemMaxSize(item_num));
00443 
00444                     const_cast<CDB_Result*>(m_Value)->GetItem(&db_obj);
00445                     if (db_obj.IsNULL()) {
00446                         throw CInvalidConversionException();
00447                     }
00448 
00449                     value = Convert(string(static_cast<const char*>(db_obj.Value()), db_obj.DataSize()));
00450                 }
00451                 break;
00452             default:
00453                 throw CInvalidConversionException();
00454         }
00455     }
00456 
00457 private:
00458     obj_type* m_Value;
00459 };
00460 
00461 ////////////////////////////////////////////////////////////////////////////////
00462 template <>
00463 class  CValueConvert<SRunTimeSqlCP, CDB_Result>
00464 {
00465 public:
00466     typedef const CDB_Result obj_type;
00467 
00468     CValueConvert(obj_type& value);
00469 
00470 public:
00471     operator bool(void) const;
00472     operator Int1(void) const;
00473     operator Uint1(void) const;
00474     operator Int2(void) const;
00475     operator Uint2(void) const;
00476     operator Int4(void) const;
00477     operator Uint4(void) const;
00478     operator Int8(void) const;
00479     operator Uint8(void) const;
00480     operator float(void) const;
00481     operator double(void) const;
00482     operator string(void) const;
00483     operator CTime(void) const;
00484 
00485 private:
00486     template <typename TO, typename FROM>
00487     TO ConvertFrom(void) const
00488     {
00489         FROM db_obj;
00490 
00491         const_cast<CDB_Result*>(m_Value)->GetItem(&db_obj);
00492         if (db_obj.IsNULL()) {
00493             return TO();
00494         }
00495 
00496         return Convert(db_obj.Value());
00497     }
00498 
00499     template <typename TO, typename FROM>
00500     TO ConvertFromStr(void) const
00501     {
00502         FROM db_obj;
00503 
00504         const_cast<CDB_Result*>(m_Value)->GetItem(&db_obj);
00505         if (db_obj.IsNULL()) {
00506             return TO();
00507         }
00508 
00509         return Convert(string(static_cast<const char*>(db_obj.Value()), db_obj.Size()));
00510     }
00511 
00512     template <typename TO, typename FROM>
00513     TO ConvertFromChar(const int item_num) const
00514     {
00515         FROM db_obj(m_Value->ItemMaxSize(item_num));
00516 
00517         const_cast<CDB_Result*>(m_Value)->GetItem(&db_obj);
00518         if (db_obj.IsNULL()) {
00519             return TO();
00520         }
00521 
00522         return Convert(string(static_cast<const char*>(db_obj.Value()), db_obj.Size()));
00523     }
00524 
00525     template <typename TO, typename FROM>
00526     TO ConvertFromLOB(void) const
00527     {
00528         FROM db_obj;
00529         string result;
00530 
00531         const_cast<CDB_Result*>(m_Value)->GetItem(&db_obj);
00532         if (db_obj.IsNULL()) {
00533             return TO();
00534         }
00535 
00536         result.resize(db_obj.Size());
00537         db_obj.Read(const_cast<void*>(static_cast<const void*>(result.c_str())),
00538                 db_obj.Size()
00539                 );
00540 
00541         return Convert(result);
00542     }
00543 
00544     template <typename TO, typename FROM>
00545     TO Convert2CTime(void) const
00546     {
00547         FROM db_obj;
00548 
00549         const_cast<CDB_Result*>(m_Value)->GetItem(&db_obj);
00550         if (db_obj.IsNULL()) {
00551             return TO();
00552         }
00553 
00554         return CTime(time_t(Convert(db_obj.Value())));
00555     }
00556 
00557     template <typename TO>
00558     void ReadCDBObject(TO& value) const
00559     {
00560         const int item_num = m_Value->CurrentItemNo();
00561         const EDB_Type db_type = m_Value->ItemDataType(item_num);
00562 
00563         switch (db_type) {
00564             case eDB_Int:
00565                 value = ConvertFrom<TO, CDB_Int>();
00566                 break;
00567             case eDB_SmallInt:
00568                 value = ConvertFrom<TO, CDB_SmallInt>();
00569                 break;
00570             case eDB_TinyInt:
00571                 value = ConvertFrom<TO, CDB_TinyInt>();
00572                 break;
00573             case eDB_BigInt:
00574                 value = ConvertFrom<TO, CDB_BigInt>();
00575                 break;
00576             case eDB_VarChar:
00577                 value = ConvertFromStr<TO, CDB_VarChar>();
00578                 break;
00579             case eDB_Char:
00580                 value = ConvertFromChar<TO, CDB_Char>(item_num);
00581                 break;
00582             case eDB_VarBinary:
00583                 value = ConvertFromStr<TO, CDB_VarBinary>();
00584                 break;
00585             case eDB_Binary:
00586                 value = ConvertFromChar<TO, CDB_Binary>(item_num);
00587                 break;
00588             case eDB_Float:
00589                 value = ConvertFrom<TO, CDB_Float>();
00590                 break;
00591             case eDB_Double:
00592                 value = ConvertFrom<TO, CDB_Double>();
00593                 break;
00594                 // case eDB_DateTime:
00595                 //     value = ConvertFrom<TO, CDB_DateTime>();
00596                 // case eDB_SmallDateTime:
00597                 //     value = ConvertFrom<TO, CDB_SmallDateTime>();
00598             case eDB_Text:
00599                 value = ConvertFromLOB<TO, CDB_Text>();
00600                 break;
00601             case eDB_Image:
00602                 value = ConvertFromLOB<TO, CDB_Image>();
00603                 break;
00604             case eDB_Bit:
00605                 value = ConvertFrom<TO, CDB_Bit>();
00606                 break;
00607             case eDB_Numeric:
00608                 value = ConvertFrom<TO, CDB_Numeric>();
00609                 break;
00610             case eDB_LongChar:
00611                 value = ConvertFromChar<TO, CDB_LongChar>(item_num);
00612                 break;
00613             case eDB_LongBinary:
00614                 {
00615                     CDB_LongBinary db_obj(m_Value->ItemMaxSize(item_num));
00616 
00617                     const_cast<CDB_Result*>(m_Value)->GetItem(&db_obj);
00618                     if (db_obj.IsNULL()) {
00619                         value = TO();
00620                     }
00621 
00622                     value = Convert(string(static_cast<const char*>(db_obj.Value()), db_obj.DataSize()));
00623                 }
00624                 break;
00625             default:
00626                 throw CInvalidConversionException();
00627         }
00628     }
00629 
00630 private:
00631     obj_type* m_Value;
00632 };
00633 
00634 ///////////////////////////////////////////////////////////////////////////////
00635 template <typename CP, typename R, typename S>
00636 class CMakeObject
00637 {
00638 public:
00639     static R Make(S& source)
00640     {
00641         return R();
00642     }
00643 };
00644 
00645 template <typename CP, typename R>
00646 class CMakeObject<CP, R, CDB_Result>
00647 {
00648 public:
00649     static R Make(CDB_Result& source)
00650     {
00651         typedef CValueConvert<CP, CDB_Result> TResult;
00652 
00653         return TResult(source);
00654     }
00655 };
00656 
00657 template <typename T1, typename T2>
00658 class CMakeObject<SRunTimeCP, pair<T1, T2>, CDB_Result>
00659 {
00660 public:
00661     typedef pair<T1, T2> TValue;
00662     typedef SRunTimeCP CP;
00663 
00664     static TValue Make(CDB_Result& source)
00665     {
00666         typedef CValueConvert<CP, CDB_Result> TResult;
00667 
00668         TResult result(source);
00669 
00670         // We may get an error at run-time ...
00671         T1 v1 = CMakeObject<CP, T1, CDB_Result>::Make(source);
00672         T2 v2 = CMakeObject<CP, T2, CDB_Result>::Make(source);
00673 
00674         return TValue(v1, v2);
00675     }
00676 };
00677 
00678 template <typename T1, typename T2>
00679 class CMakeObject<SSafeCP, pair<T1, T2>, CDB_Result>
00680 {
00681 public:
00682     typedef pair<T1, T2> TValue;
00683     typedef SSafeCP CP;
00684 
00685     static TValue Make(CDB_Result& source)
00686     {
00687         typedef CValueConvert<CP, CDB_Result> TResult;
00688 
00689         TResult result(source);
00690 
00691         /* Not all data types have default constructor. */
00692         const unsigned int n = source.NofItems();
00693 
00694         T1 v1 = T1();
00695         T2 v2 = T2();
00696 
00697         if (static_cast<unsigned int>(source.CurrentItemNo()) < n) {
00698             v1 = CMakeObject<CP, T1, CDB_Result>::Make(source);
00699         }
00700 
00701         if (static_cast<unsigned int>(source.CurrentItemNo()) < n) {
00702             v2 = CMakeObject<CP, T2, CDB_Result>::Make(source);
00703         }
00704 
00705         return TValue(v1, v2);
00706     }
00707 };
00708 
00709 template <typename CP, typename T>
00710 class CMakeObject<CP, vector<T>, CDB_Result>
00711 {
00712 public:
00713     typedef vector<T> TValue;
00714 
00715     static TValue Make(CDB_Result& source)
00716     {
00717         typedef CValueConvert<CP, CDB_Result> TResult;
00718 
00719         TResult result(source);
00720         const unsigned int n = source.NofItems();
00721         TValue res_val;
00722 
00723         for (unsigned int i = source.CurrentItemNo(); i < n; i = source.CurrentItemNo()) {
00724             res_val.push_back(CMakeObject<CP, T, CDB_Result>::Make(source));
00725         }
00726 
00727         return res_val;
00728     }
00729 };
00730 
00731 template <typename CP, typename T>
00732 class CMakeObject<CP, stack<T>, CDB_Result>
00733 {
00734 public:
00735     typedef stack<T> TValue;
00736 
00737     static TValue Make(CDB_Result& source)
00738     {
00739         typedef CValueConvert<CP, CDB_Result> TResult;
00740 
00741         TResult result(source);
00742         const unsigned int n = source.NofItems();
00743         TValue res_val;
00744 
00745         for (unsigned int i = source.CurrentItemNo(); i < n; i = source.CurrentItemNo()) {
00746             res_val.push(CMakeObject<CP, T, CDB_Result>::Make(source));
00747         }
00748 
00749         return res_val;
00750     }
00751 };
00752 
00753 template <typename CP, typename T>
00754 class CMakeObject<CP, deque<T>, CDB_Result>
00755 {
00756 public:
00757     typedef deque<T> TValue;
00758 
00759     static TValue Make(CDB_Result& source)
00760     {
00761         typedef CValueConvert<CP, CDB_Result> TResult;
00762 
00763         TResult result(source);
00764         const unsigned int n = source.NofItems();
00765         TValue res_val;
00766 
00767         for (unsigned int i = source.CurrentItemNo(); i < n; i = source.CurrentItemNo()) {
00768             res_val.push_back(CMakeObject<CP, T, CDB_Result>::Make(source));
00769         }
00770 
00771         return res_val;
00772     }
00773 };
00774 
00775 template <typename CP, typename T>
00776 class CMakeObject<CP, set<T>, CDB_Result>
00777 {
00778 public:
00779     typedef set<T> TValue;
00780 
00781     static TValue Make(CDB_Result& source)
00782     {
00783         typedef CValueConvert<CP, CDB_Result> TResult;
00784 
00785         TResult result(source);
00786         const unsigned int n = source.NofItems();
00787         TValue res_val;
00788 
00789         for (unsigned int i = source.CurrentItemNo(); i < n; i = source.CurrentItemNo()) {
00790             res_val.insert(CMakeObject<CP, T, CDB_Result>::Make(source));
00791         }
00792 
00793         return res_val;
00794     }
00795 };
00796 
00797 template <typename K, typename V>
00798 class CMakeObject<SRunTimeCP, map<K, V>, CDB_Result>
00799 {
00800 public:
00801     typedef map<K, V> TValue;
00802     typedef SRunTimeCP CP;
00803 
00804     static TValue Make(CDB_Result& source)
00805     {
00806         typedef CValueConvert<CP, CDB_Result> TResult;
00807 
00808         TResult result(source);
00809         const unsigned int n = source.NofItems();
00810         TValue res_val;
00811 
00812         for (unsigned int i = source.CurrentItemNo(); i < n; i = source.CurrentItemNo()) {
00813             // We may get an error at run-time ...
00814             K k = CMakeObject<CP, K, CDB_Result>::Make(source);
00815             V v = CMakeObject<CP, V, CDB_Result>::Make(source);
00816 
00817             res_val.insert(pair<K, V>(k, v));
00818         }
00819 
00820         return res_val;
00821     }
00822 };
00823 
00824 template <typename K, typename V>
00825 class CMakeObject<SSafeCP, map<K, V>, CDB_Result>
00826 {
00827 public:
00828     typedef map<K, V> TValue;
00829     typedef SSafeCP CP;
00830 
00831     static TValue Make(CDB_Result& source)
00832     {
00833         typedef CValueConvert<CP, CDB_Result> TResult;
00834 
00835         TResult result(source);
00836         const unsigned int n = source.NofItems();
00837         TValue res_val;
00838 
00839         for (unsigned int i = source.CurrentItemNo(); i < n; i = source.CurrentItemNo()) {
00840             /* Not all data types have default constructor ... */
00841             K k = CMakeObject<CP, K, CDB_Result>::Make(source);
00842             V v = V();
00843 
00844             if (static_cast<unsigned int>(source.CurrentItemNo()) < n) {
00845                 v = CMakeObject<CP, V, CDB_Result>::Make(source);
00846             }
00847 
00848             res_val.insert(pair<K, V>(k, v));
00849         }
00850 
00851         return res_val;
00852     }
00853 };
00854 
00855 ////////////////////////////////////////////////////////////////////////////////
00856 template <typename CP, typename TO>
00857 class CConvertTO
00858 {
00859 public:
00860     typedef TO TValue;
00861 
00862     static void Convert(const auto_ptr<CDB_Result>& rs, TValue& value)
00863     {
00864         if (rs->Fetch()) {
00865              value = CMakeObject<CP, TValue, CDB_Result>::Make(*rs);
00866         }
00867     }
00868 };
00869 
00870 template <typename CP, typename T>
00871 class CConvertTO<CP, vector<T> >
00872 {
00873 public:
00874     typedef vector<T> TValue;
00875 
00876     static void Convert(const auto_ptr<CDB_Result>& rs, TValue& value)
00877     {
00878         while (rs->Fetch()) {
00879             value.push_back(CMakeObject<CP, T, CDB_Result>::Make(*rs));
00880         }
00881     }
00882 };
00883 
00884 template <typename CP, typename T>
00885 class CConvertTO<CP, deque<T> >
00886 {
00887 public:
00888     typedef deque<T> TValue;
00889 
00890     static void Convert(const auto_ptr<CDB_Result>& rs, TValue& value)
00891     {
00892         while (rs->Fetch()) {
00893             value.push_back(CMakeObject<CP, T, CDB_Result>::Make(*rs));
00894         }
00895     }
00896 };
00897 
00898 template <typename CP, typename T>
00899 class CConvertTO<CP, set<T> >
00900 {
00901 public:
00902     typedef set<T> TValue;
00903 
00904     static void Convert(const auto_ptr<CDB_Result>& rs, TValue& value)
00905     {
00906         while (rs->Fetch()) {
00907             value.insert(CMakeObject<CP, T, CDB_Result>::Make(*rs));
00908         }
00909     }
00910 };
00911 
00912 template <typename CP, typename T>
00913 class CConvertTO<CP, stack<T> >
00914 {
00915 public:
00916     typedef stack<T> TValue;
00917 
00918     static void Convert(const auto_ptr<CDB_Result>& rs, TValue& value)
00919     {
00920         while (rs->Fetch()) {
00921             value.push(CMakeObject<CP, T, CDB_Result>::Make(*rs));
00922         }
00923     }
00924 };
00925 
00926 template <typename CP, typename K, typename V>
00927 class CConvertTO<CP, map<K, V> >
00928 {
00929 public:
00930     typedef map<K, V> TValue;
00931 
00932     static void Convert(const auto_ptr<CDB_Result>& rs, TValue& value)
00933     {
00934         while (rs->Fetch()) {
00935             K k = CMakeObject<CP, K, CDB_Result>::Make(*rs);
00936             V v = CMakeObject<CP, V, CDB_Result>::Make(*rs);
00937 
00938             value.insert(pair<K, V>(k, v));
00939         }
00940     }
00941 };
00942 
00943 ////////////////////////////////////////////////////////////////////////////////
00944 template <typename CP>
00945 class CValueConvert<CP, CDB_LangCmd>
00946 {
00947 public:
00948     typedef CDB_LangCmd TObj;
00949 
00950     CValueConvert(const CValueConvert<CP, TObj>& other)
00951     : m_Stmt(other.m_Stmt)
00952     {
00953     }
00954     CValueConvert(TObj& value)
00955     : m_Stmt(&value)
00956     {
00957         if (!m_Stmt->Send()) {
00958             throw CInvalidConversionException();
00959         }
00960     }
00961     ~CValueConvert(void)
00962     {
00963         try {
00964             m_Stmt->DumpResults();
00965         }
00966         // NCBI_CATCH_ALL_X( 6, NCBI_CURRENT_FUNCTION )
00967         catch (...)
00968         {
00969             ;
00970         }
00971     }
00972 
00973 public:
00974     template <typename TO>
00975     operator TO(void) const
00976     {
00977         TO result;
00978 
00979         while (m_Stmt->HasMoreResults()) {
00980             auto_ptr<CDB_Result> rs(m_Stmt->Result());
00981 
00982             if (rs.get() == NULL) {
00983                 continue;
00984             }
00985 
00986             CConvertTO<CP, TO>::Convert(rs, result);
00987 
00988             break;
00989         }
00990 
00991         return result;
00992     }
00993 
00994 private:
00995     TObj* m_Stmt;
00996 };
00997 
00998 template <typename CP>
00999 class CValueConvert<CP, CDB_LangCmd*>
01000 {
01001 public:
01002     typedef CDB_LangCmd TObj;
01003 
01004     CValueConvert(const CValueConvert<CP, TObj*>& other)
01005     : m_Stmt(other.m_Stmt)
01006     {
01007     }
01008     CValueConvert(TObj* value)
01009     : m_Stmt(value)
01010     {
01011         if (!m_Stmt->Send()) {
01012             throw CInvalidConversionException();
01013         }
01014     }
01015     ~CValueConvert(void)
01016     {
01017         try {
01018             m_Stmt->DumpResults();
01019         }
01020         // NCBI_CATCH_ALL_X( 6, NCBI_CURRENT_FUNCTION )
01021         catch (...)
01022         {
01023             ;
01024         }
01025     }
01026 
01027 public:
01028     template <typename TO>
01029     operator TO(void) const
01030     {
01031         TO result;
01032 
01033         while (m_Stmt->HasMoreResults()) {
01034             auto_ptr<CDB_Result> rs(m_Stmt->Result());
01035 
01036             if (rs.get() == NULL) {
01037                 continue;
01038             }
01039 
01040             CConvertTO<CP, TO>::Convert(rs, result);
01041 
01042             break;
01043         }
01044 
01045         return result;
01046     }
01047 
01048 private:
01049     mutable auto_ptr<TObj> m_Stmt;
01050 };
01051 
01052 ////////////////////////////////////////////////////////////////////////////////
01053 template <typename CP>
01054 class CValueConvert<CP, CDB_RPCCmd>
01055 {
01056 public:
01057     typedef CDB_RPCCmd TObj;
01058 
01059     CValueConvert(const CValueConvert<CP, TObj>& other)
01060     : m_Stmt(other.m_Stmt)
01061     {
01062     }
01063     CValueConvert(TObj& value)
01064     : m_Stmt(&value)
01065     {
01066         if (!m_Stmt->Send()) {
01067             throw CInvalidConversionException();
01068         }
01069     }
01070     ~CValueConvert(void)
01071     {
01072         try {
01073             m_Stmt->DumpResults();
01074         }
01075         // NCBI_CATCH_ALL_X( 6, NCBI_CURRENT_FUNCTION )
01076         catch (...)
01077         {
01078             ;
01079         }
01080     }
01081 
01082 public:
01083     template <typename TO>
01084     operator TO(void) const
01085     {
01086         TO result;
01087 
01088         while (m_Stmt->HasMoreResults()) {
01089             auto_ptr<CDB_Result> rs(m_Stmt->Result());
01090 
01091             if (rs.get() == NULL) {
01092                 continue;
01093             }
01094 
01095             CConvertTO<CP, TO>::Convert(rs, result);
01096 
01097             break;
01098         }
01099 
01100         return result;
01101     }
01102 
01103 private:
01104     TObj* m_Stmt;
01105 };
01106 
01107 template <typename CP>
01108 class CValueConvert<CP, CDB_RPCCmd*>
01109 {
01110 public:
01111     typedef CDB_RPCCmd TObj;
01112 
01113     CValueConvert(const CValueConvert<CP, TObj*>& other)
01114     : m_Stmt(other.m_Stmt)
01115     {
01116     }
01117     CValueConvert(TObj* value)
01118     : m_Stmt(value)
01119     {
01120         if (!m_Stmt->Send()) {
01121             throw CInvalidConversionException();
01122         }
01123     }
01124     ~CValueConvert(void)
01125     {
01126         try {
01127             m_Stmt->DumpResults();
01128         }
01129         // NCBI_CATCH_ALL_X( 6, NCBI_CURRENT_FUNCTION )
01130         catch (...)
01131         {
01132             ;
01133         }
01134     }
01135 
01136 public:
01137     template <typename TO>
01138     operator TO(void) const
01139     {
01140         TO result;
01141 
01142         while (m_Stmt->HasMoreResults()) {
01143             auto_ptr<CDB_Result> rs(m_Stmt->Result());
01144 
01145             if (rs.get() == NULL) {
01146                 continue;
01147             }
01148 
01149             CConvertTO<CP, TO>::Convert(rs, result);
01150 
01151             break;
01152         }
01153 
01154         return result;
01155     }
01156 
01157 private:
01158     mutable auto_ptr<TObj> m_Stmt;
01159 };
01160 
01161 ////////////////////////////////////////////////////////////////////////////////
01162 template <typename CP>
01163 class CValueConvert<CP, CDB_CursorCmd>
01164 {
01165 public:
01166     typedef CDB_CursorCmd TObj;
01167 
01168     CValueConvert(const CValueConvert<CP, TObj>& other)
01169     : m_Stmt(other.m_Stmt)
01170     , m_RS(other.m_RS)
01171     {
01172     }
01173     CValueConvert(TObj& value)
01174     : m_Stmt(&value)
01175     , m_RS(value.Open())
01176     {
01177         if (!m_RS.get()) {
01178             throw CInvalidConversionException();
01179         }
01180     }
01181     ~CValueConvert(void)
01182     {
01183     }
01184 
01185 public:
01186     template <typename TO>
01187     operator TO(void) const
01188     {
01189         TO result;
01190 
01191         CConvertTO<CP, TO>::Convert(m_RS, result);
01192 
01193         return result;
01194     }
01195 
01196 private:
01197     TObj* m_Stmt;
01198     auto_ptr<CDB_Result> m_RS;
01199 };
01200 
01201 template <typename CP>
01202 class CValueConvert<CP, CDB_CursorCmd*>
01203 {
01204 public:
01205     typedef CDB_CursorCmd TObj;
01206 
01207     CValueConvert(const CValueConvert<CP, TObj*>& other)
01208     : m_Stmt(other.m_Stmt)
01209     , m_RS(other.m_RS)
01210     {
01211     }
01212     CValueConvert(TObj* value)
01213     : m_Stmt(value)
01214     , m_RS(value->Open())
01215     {
01216         if (!m_RS.get()) {
01217             throw CInvalidConversionException();
01218         }
01219     }
01220     ~CValueConvert(void)
01221     {
01222     }
01223 
01224 public:
01225     template <typename TO>
01226     operator TO(void) const
01227     {
01228         TO result;
01229 
01230         CConvertTO<CP, TO>::Convert(m_RS, result);
01231 
01232         return result;
01233     }
01234 
01235 private:
01236     mutable auto_ptr<TObj> m_Stmt;
01237     mutable auto_ptr<CDB_Result> m_RS;
01238 };
01239 
01240 } // namespace value_slice
01241 
01242 END_NCBI_SCOPE
01243 
01244 
01245 #endif // DBAPI_DRIVER___DBAPI_DRIVER_CONVERT__HPP
01246 
01247 
01248 

Generated on Sun Dec 6 22:01:38 2009 for NCBI C++ ToolKit by  doxygen 1.4.6
Modified on Mon Dec 07 16:20:35 2009 by modify_doxy.py rev. 173732