CSCommon: ODBCRecordset.h 소스 파일

MAIET

ODBCRecordset.h

00001 
00002 #ifndef __ODBCRECORDSET_H__
00003 #define __ODBCRECORDSET_H__
00004 
00005 #if _MSC_VER > 1000
00006 #pragma once
00007 #endif // _MSC_VER > 1000
00008 
00009 #include <vector>
00010 using std::vector;
00011 
00012 #include <afxdb.h>
00013 #include <afxtempl.h>
00014 #include <afxdtctl.h>
00015 
00016 #define BINARY_FIELD_MAX_SIZE   7000    // DB에 사용할 Binary필드의 최대 크기(최대크기는 8000).
00017 #define BINARY_CHUNK_SIZE       7000    // Binary필드에 데이터를 전송할때 BINARY_CHUNK_SIZE보다 크면 나누어 보냄.
00018 #define RESERVE_SIZE            100     // CDBBinary클래스 vector자료구조를 위해서 사용.
00019 
00020 
00021 class CSimpleDBBinary
00022 {
00023 public :
00024     CSimpleDBBinary() : m_UsedSize( 0 ) {}
00025     ~CSimpleDBBinary() {}
00026 
00027     int GetUsedSize() { return m_UsedSize; }
00028 
00029     void SetUsedSize( const int iSize ) 
00030     { 
00031         m_UsedSize = iSize; 
00032     }
00033 
00034     int GetData( char* pOutBuf, const int nOutBufSize )
00035     {
00036         if( (0 == pOutBuf) || 
00037             (m_UsedSize > nOutBufSize) ||
00038             (0 >= nOutBufSize) )
00039             return -1;
00040 
00041         memcpy( pOutBuf, m_Data, m_UsedSize );
00042 
00043         return m_UsedSize;
00044     }
00045 
00046     int SetData( const char* pData, const int nInDataSize )
00047     {
00048         if( (0 == pData) || 
00049             (BINARY_FIELD_MAX_SIZE < nInDataSize) || 
00050             (0 >= nInDataSize) )
00051             return -1;
00052 
00053         m_UsedSize = nInDataSize;
00054 
00055         memcpy( m_Data, pData, nInDataSize );
00056 
00057         return m_UsedSize;
00058     }
00059 
00060 private :
00061     char    m_Data[ BINARY_FIELD_MAX_SIZE ];
00062     int     m_UsedSize;
00063 
00064 public :
00065     int test;
00066 };
00067 
00068 
00069 
00070 class CDBBinary
00071 {
00072 public :
00073     CDBBinary( const int iFieldNum = RESERVE_SIZE, const int iReserveSize = RESERVE_SIZE ) : 
00074        m_iIndex( 0 ), m_iCurrentUsedSize( 0 ), m_ReserveSize( iReserveSize )
00075     {
00076         Reserve( iFieldNum );
00077     }
00078 
00079     ~CDBBinary()
00080     {
00081         m_vBinary.clear();
00082     }
00083 
00084     typedef int                         BinaryLength;
00085     typedef vector< CSimpleDBBinary >   BinaryDataVec;
00086     typedef BinaryDataVec::iterator     BinaryDataIter;
00087 
00088     void Begin()
00089     {
00090         m_iIndex = 0;
00091     }
00092 
00093     void Clear() { m_vBinary.clear(); }
00094     
00095     int GetCurUsedSize()    { return m_iCurrentUsedSize; }
00096     int GetCurIndex()       { return m_iIndex; }
00097     int GetReserverSize()   { return m_ReserveSize; }
00098 
00099     void SetCurUsedSize( const int iCurUsedSize ) { m_iCurrentUsedSize = iCurUsedSize; }
00100 
00101     void SetReserveSize( const int nReserveSize ) 
00102     {
00103         if( 0 > nReserveSize )
00104         {
00105             ASSERT( 0 );
00106             return;
00107         }
00108 
00109         m_ReserveSize = nReserveSize;
00110     }
00111 
00112     int GetNextData( char* pOutputBuf, const int nDestBufSize )
00113     {
00114         if( m_iIndex > m_iCurrentUsedSize )
00115             return -1;
00116 
00117         if( -1 == m_vBinary[m_iIndex].GetData(pOutputBuf, nDestBufSize) )
00118             return -1;
00119 
00120         return m_vBinary[ m_iIndex++ ].GetUsedSize();
00121     }
00122 
00123     int InsertData( const char* pData, const int nSrcDataSize )
00124     {
00125         // 현제까지 할당된 공간이 충분한지 검사.
00126         if( m_iIndex >= static_cast<int>(m_vBinary.capacity()) )
00127         {
00128             // 공간이 부족하면 추가적인 공간 할당을 함.
00129             if( !Reserve(m_ReserveSize) )
00130                 return -1;
00131         }
00132 
00133         ++m_iIndex;
00134         m_iCurrentUsedSize = m_iIndex;
00135 
00136         CSimpleDBBinary sbn;
00137 
00138         // test
00139         sbn.test = m_iIndex;
00140 
00141         // Insert작업이 끝난후의 데이터가 원본 데이터의 크기와 같은지 비교.
00142         if( nSrcDataSize != sbn.SetData(pData, nSrcDataSize) )
00143         {
00144             --m_iIndex;
00145             --m_iCurrentUsedSize;
00146 
00147             return -1;
00148         }
00149 
00150         m_vBinary.push_back( sbn );
00151         
00152         return sbn.GetUsedSize();
00153     }
00154 
00155 private :
00156     bool Reserve( const int iExtSize )
00157     {
00158         if( 0 > iExtSize )
00159         {
00160             ASSERT( 0 );
00161             return false;
00162         }
00163 
00164         // 공간 확보. 공간 확보 실패시를 대비해서.
00165         try
00166         {
00167             m_vBinary.reserve( iExtSize + m_vBinary.size() );
00168         }
00169         catch( ... )
00170         {
00171             // 실패하면 크기 관련된 데이터를 -1로 설정.
00172             m_iCurrentUsedSize  = -1;
00173             m_iIndex            = -1;
00174 
00175             return false;
00176         }
00177 
00178         return true;
00179     }
00180     
00181 private :
00182     int             m_iIndex;               // Insert, Get에 의해 참조된 마지막index.
00183     int             m_iCurrentUsedSize;     // InsertData( )에 의해서 추가된 총 필드 수.
00184     int             m_ReserveSize;
00185     BinaryDataVec   m_vBinary;
00186 };
00187 
00188 
00189 class   CDBField : public CDBVariant {
00190 //  Constructors are private to avoid instantiation except by CODBCRecordset
00191 private:
00192     CDBField();
00193     CDBField( const CDBField& dbv );
00194     
00195     CDBField& operator =( const CDBField& dbv );
00196 
00197     virtual ~CDBField();
00198 
00199 public:
00200     //  Assignment operators
00201     CDBField& operator =( const bool bVal );
00202     CDBField& operator =( const char chVal );
00203     CDBField& operator =( const unsigned char chVal );
00204     CDBField& operator =( const short sVal );
00205     CDBField& operator =( const int iVal );
00206     CDBField& operator =( const long lVal );
00207     CDBField& operator =( const float fVal );
00208     CDBField& operator =( const double fVal );
00209     CDBField& operator =( const COleDateTime& dtVal );
00210     CDBField& operator =( const CString& cVal );
00211     CDBField& operator =( const LPCTSTR szVal );
00212 
00213 
00214 
00215     //  Get the bool value. Do appropriate conversion.
00216     bool            AsBool()    const;
00217     //  Get the unsigned char value. Do appropriate conversion.
00218     unsigned char   AsChar()    const;
00219     //  Get the short value. Do appropriate conversion.
00220     short           AsShort()   const;
00221     //***   Get the int value which is equal to long value. Do appropriate conversion.
00222     int             AsInt()     const;
00223     //  Get the long value. Do appropriate conversion.
00224     long            AsLong()    const;
00225     //  Get the float value. Do appropriate conversion.
00226     float           AsFloat()   const;
00227     //  Get the double value. Do appropriate conversion.
00228     double          AsDouble()  const;
00229     //  Get the date and time value. Do appropriate conversion.
00230     COleDateTime    AsDate()    const;
00231     //  Get the CString value. Do appropriate conversion.
00232     CString         AsString()  const;
00233     //  Get the long binary value. Do appropriate conversion.
00234     CLongBinary*    AsBinary()  const;
00235 
00236 
00237     //  Data type conversion operators
00238 
00239     operator    bool() const;
00240     operator    unsigned char() const;
00241     operator    short() const;
00242     operator    int() const;
00243     operator    long() const;
00244     operator    float() const;
00245     operator    double() const;
00246     operator    COleDateTime() const;
00247     operator    CString() const;
00248     operator    CLongBinary*() const;
00249 
00250     //  Field type query methods
00251 
00252     bool    IsNull()    const   { return m_bIsNull || m_dwType == DBVT_NULL; };
00253     bool    IsBool()    const   { return m_dwType == DBVT_BOOL; };
00254     bool    IsChar()    const   { return m_dwType == DBVT_UCHAR; };
00255     bool    IsShort()   const   { return m_dwType == DBVT_SHORT; };
00256     bool    IsInt()     const   { return m_dwType == DBVT_LONG; };
00257     bool    IsLong()    const   { return m_dwType == DBVT_LONG; };
00258     bool    IsFloat()   const   { return m_dwType == DBVT_SINGLE; };
00259     bool    IsDouble()  const   { return m_dwType == DBVT_DOUBLE; };
00260     bool    IsNumber()  const   { return IsShort() || IsLong() || IsFloat() || IsDouble(); };
00261     bool    IsDate()    const   { return m_dwType == DBVT_DATE; };
00262     bool    IsString()  const   { return m_dwType == DBVT_STRING; };
00263     bool    IsBinary()  const   { return m_dwType == DBVT_BINARY; };
00264 
00265     //  Get the field name
00266     const   CString&    GetName()   const;
00267 
00268 private:
00269     bool        m_bIsNull;  //  If this field contain a NULL value
00270     CString     m_cName;    //  Contain the field (column) name
00271     
00272     void    SetNull( bool bIsNull ) { m_bIsNull = bIsNull; };
00273 
00274     friend  class   CODBCRecordset;
00275 };
00277 inline
00278 const   CString&    CDBField::GetName() const {
00279     return  m_cName;
00280 }
00281 
00282 inline
00283 CDBField::operator  bool() const {
00284     return  AsBool();
00285 }
00286 inline
00287 CDBField::operator  unsigned char() const {
00288     return  AsChar();
00289 }
00290 inline
00291 CDBField::operator  short() const {
00292     return  AsShort();
00293 }
00294 inline
00295 CDBField::operator  int() const {
00296     return  AsInt();
00297 }
00298 inline
00299 CDBField::operator  long() const {
00300     return  AsLong();
00301 }
00302 inline
00303 CDBField::operator  float() const {
00304     return  AsFloat();
00305 }
00306 inline
00307 CDBField::operator  double() const {
00308     return  AsDouble();
00309 }
00310 inline
00311 CDBField::operator  COleDateTime() const {
00312     return  AsDate();
00313 }
00314 inline
00315 CDBField::operator  CString() const {
00316     return  AsString();
00317 }
00318 inline
00319 CDBField::operator  CLongBinary*() const {
00320     return  NULL;
00321 }
00323 
00324 
00325 
00327 //  CODBCRecordset
00328 class   CODBCRecordset : public CRecordset
00329 {
00330 public:
00331     // Our constructor uses CRecordset constructor
00332     CODBCRecordset( CDatabase* pDatabase = NULL );
00333     virtual ~CODBCRecordset();
00334 
00335     virtual BOOL    Open( LPCTSTR lpszSQL, 
00336                           UINT nOpenType = AFX_DB_USE_DEFAULT_TYPE,
00337                           DWORD dwOptions = 0 );
00338 
00339     virtual void    Move( long nRows, WORD wFetchType = SQL_FETCH_RELATIVE );// throw( CDBException, CMemoryException );
00340 
00341 
00342     //  Number of fields could be get by 
00343     //  CRecordset::GetODBCFieldCount() method
00344 
00345 
00346     //  New functions:
00347 
00348     //  Get the field ID by name - case insensitive
00349     //  CRecordset::GetFieldIndexByName() works, 
00350     //  but is case sensitive
00351     int         GetFieldID( LPCTSTR szName );
00352     //  Get the field name by ID
00353     CString     GetFieldName( int nID );
00354 
00355 
00356     //  Gets a field by name
00357     CDBField&   Field( LPCTSTR szName );
00358     //  Gets a field by number
00359     CDBField&   Field( int nField );
00360 
00361     //  Gets a field by name
00362     CDBField&   operator()( LPCTSTR szField );
00363     //  Gets a field by number
00364     CDBField&   operator()( int nField );
00365 
00366 
00367     //  Get values by field names. Do conversion as appropriate.
00368 
00369     bool            GetBool( LPCTSTR szName );
00370     unsigned char   GetChar( LPCTSTR szName );
00371     short           GetShort( LPCTSTR szName );
00372     int             GetInt( LPCTSTR szName );
00373     long            GetLong( LPCTSTR szName );
00374     float           GetFloat( LPCTSTR szName );
00375     double          GetDouble( LPCTSTR szName );
00376     COleDateTime    GetDate( LPCTSTR szName );
00377     CString         GetString( LPCTSTR szName );
00378     CLongBinary*    GetBinary( LPCTSTR szName );
00379 
00380 
00381     //  Get values by field number. Do conversion as appropriate.
00382 
00383     bool            GetBool( int nCol );
00384     unsigned char   GetChar( int nCol );
00385     short           GetShort( int nCol );
00386     int             GetInt( int nCol );
00387     long            GetLong( int nCol );
00388     float           GetFloat( int nCol );
00389     double          GetDouble( int nCol );
00390     COleDateTime    GetDate( int nCol );
00391     CString         GetString( int nCol );
00392     CLongBinary*    GetBinary( int nCol );
00393 
00394     bool        InsertBinary( CString strQuery, char* pData, const int nSize );
00395     CDBBinary&  SelectBinary( CString strQuery );
00396 
00397 
00398 private:
00399     CDBField*           m_fields;           //  Storage for fields
00400     int                 m_AllocatedFields;  //  Used to make smart storage reallocation
00401     CMapStringToPtr     m_mapNameIdx;       //  Map field names to their ID
00402     bool                m_bNotLoadedFieldsMap;  //  Is field names map still not loaded
00403 
00404     void    LoadFieldNamesMap();
00405 
00406     //  Clear the internal data structures
00407     void    Clear();
00408     
00409     //  RFX support
00410     virtual void    DoFieldExchange( CFieldExchange* pFX );
00411 
00412     //  Allocate data buffer and set the field type
00413     void        AllocDataBuffer( CDBVariant& varValue, CODBCFieldInfo& fi );
00414     short       GetCFieldType( short nSQLType );
00415 };
00417 
00418 
00419 
00421 //  CODBCRecordset class inline methods
00422 inline
00423 //  Gets a field by name
00424 CDBField&   CODBCRecordset::Field( LPCTSTR szName ) {
00425     return  Field( GetFieldID( szName ) );
00426 }
00427 
00428 inline
00429 //  Gets a field by number
00430 CDBField&   CODBCRecordset::Field( int nField ) {
00431     //  There is no allocated storage
00432     ASSERT( m_fields != NULL );
00433     //  The field ID is invalid
00434     ASSERT( nField >= 0 );
00435     ASSERT( nField < GetODBCFieldCount() );
00436     //  There is no data in the current recordset position
00437     ASSERT( IsOpen() );
00438 
00439     return  m_fields[ nField ];
00440 }
00441 
00443 //  Get field methods
00444 inline
00445 CDBField&   CODBCRecordset::operator()( LPCTSTR szField ) {
00446     return  Field( szField );
00447 }
00448 
00449 inline
00450 CDBField&   CODBCRecordset::operator()( int nField ) {
00451     return  Field( nField );
00452 }
00453 
00455 //  Get by Column Name
00456 inline
00457 bool    CODBCRecordset::GetBool( LPCTSTR szName ) {
00458     return  Field( szName ).AsBool();
00459 }
00460 
00461 inline
00462 unsigned char   CODBCRecordset::GetChar( LPCTSTR szName ) {
00463     return  Field( szName ).AsChar();
00464 }
00465 
00466 inline
00467 short   CODBCRecordset::GetShort( LPCTSTR szName ) {
00468     return  Field( szName ).AsShort();
00469 }
00470 
00471 inline
00472 int     CODBCRecordset::GetInt( LPCTSTR szName ) {
00473     return  Field( szName ).AsInt();
00474 }
00475 
00476 inline
00477 long    CODBCRecordset::GetLong( LPCTSTR szName ) {
00478     return  Field( szName ).AsLong();
00479 }
00480 
00481 inline
00482 float   CODBCRecordset::GetFloat( LPCTSTR szName ) {
00483     return  Field( szName ).AsFloat();
00484 }
00485 
00486 inline
00487 double  CODBCRecordset:: GetDouble( LPCTSTR szName ) {
00488     return  Field( szName ).AsDouble();
00489 }
00490 
00491 inline
00492 COleDateTime    CODBCRecordset::GetDate( LPCTSTR szName ) {
00493     return  Field( szName ).AsDate();
00494 }
00495 
00496 inline
00497 CString CODBCRecordset::GetString( LPCTSTR szName ) {
00498     return  Field( szName ).AsString();
00499 }
00500 
00501 inline
00502 CLongBinary*    CODBCRecordset::GetBinary( LPCTSTR szName ) {
00503     return  Field( szName ).AsBinary();
00504 }
00505 
00507 // Get by Column Number
00508 inline
00509 bool    CODBCRecordset::GetBool( int nCol ) {
00510     return  Field( nCol ).AsBool();
00511 }
00512 
00513 inline
00514 unsigned char   CODBCRecordset::GetChar( int nCol ) {
00515     return  Field( nCol ).AsChar();
00516 }
00517 
00518 inline
00519 short   CODBCRecordset::GetShort( int nCol ) {
00520     return  Field( nCol ).AsShort();
00521 }
00522 
00523 inline
00524 int     CODBCRecordset::GetInt( int nCol ) {
00525     return  Field( nCol ).AsInt();
00526 }
00527 
00528 inline
00529 long    CODBCRecordset::GetLong( int nCol ) {
00530     return  Field( nCol ).AsLong();
00531 }
00532 
00533 inline
00534 float   CODBCRecordset::GetFloat( int nCol ) {
00535     return  Field( nCol ).AsFloat();
00536 }
00537 
00538 inline
00539 double  CODBCRecordset:: GetDouble( int nCol ) {
00540     return  Field( nCol ).AsDouble();
00541 }
00542 
00543 inline
00544 COleDateTime    CODBCRecordset::GetDate( int nCol ) {
00545     return  Field( nCol ).AsDate();
00546 }
00547 
00548 inline
00549 CString CODBCRecordset::GetString( int nCol ) {
00550     return  Field( nCol ).AsString();
00551 }
00552 
00553 inline
00554 CLongBinary*    CODBCRecordset::GetBinary( int nCol ) {
00555     return  Field( nCol ).AsBinary();
00556 }
00558 
00559 #endif      //      __ODBCRECORDSET_H__


MAIET entertainment