#include "stdafx.h" #include ".\ioledb.h" #include ".\QueryResult.h" #define DBINITCONSTANTS #define INITGUID #include #include // OLE DB Header #include // OLE DB Errors #include #include #include #include // for cenumlator #define OLEHR(hr) \ if(FAILED(hr)) \ goto CLEANUP; #define OLEOK(hr) \ if(hr) \ goto CLEANUP; IOLEDB::IOLEDB(void) : m_pIDataInitialize ( NULL ), m_pIDBInitialize ( NULL ), m_pIDBCreateSession ( NULL ), m_pIDBCreateCommand ( NULL ), m_pICommand ( NULL ), m_pICommandText ( NULL ), m_pIRowset ( NULL ), m_pIColumnsInfo ( NULL ), m_pIAccessor ( NULL ), m_hAccessor ( NULL ), m_hRow ( NULL ), m_phRow ( NULL ), m_pDBColumnInfo ( NULL ) { CoInitialize( NULL ); } IOLEDB::~IOLEDB(void) { CoUninitialize(); } VOID IOLEDB::Release() { if( m_pIAccessor ) m_pIAccessor->ReleaseAccessor( m_hAccessor, NULL ); SAFE_RELEASE( m_pIAccessor ); SAFE_RELEASE( m_pIRowset ); SAFE_RELEASE( m_pICommandText ); SAFE_RELEASE(m_pICommand); SAFE_RELEASE(m_pIDBCreateCommand); SAFE_RELEASE(m_pIDBCreateSession); SAFE_RELEASE(m_pIDBInitialize); SAFE_RELEASE(m_pIDataInitialize); } BOOL IOLEDB::Init( char * pszIPAddress, char * pszDatabaseName, char * pszUserName, char * pszUserPassword, fnCallBackMessage fnErrorMessage ) { IDBCInterface::Init( pszIPAddress, pszDatabaseName, pszUserName, pszUserPassword, fnErrorMessage ); HRESULT hr; #if (0) m_phRow = &m_hRow; CLSID clsidOLEDB; OLECHAR oledbCLSID[256]; MultiByteToWideChar( CP_ACP, 0, "SQLOLEDB.1", -1, oledbCLSID, 256 ); CLSIDFromProgID( oledbCLSID , &clsidOLEDB ); OLEHR( hr = CoCreateInstance( clsidOLEDB, 0, CLSCTX_INPROC_SERVER, IID_IDBInitialize, (VOID **)&m_pIDBInitialize ) ); #else #if (1) /// Create DBInitialize /// OLEHR( hr = CoCreateInstance( CLSID_SQLOLEDB, 0, CLSCTX_INPROC_SERVER, IID_IDBInitialize, (VOID **)&m_pIDBInitialize ) ); #else /// OLEDB provider for ODBC OLEHR( hr = CoCreateInstance( CLSID_MSDAINITIALIZE, NULL, CLSCTX_INPROC_SERVER, IID_IDataInitialize, (VOID **)&m_pIDataInitialize ) ); CLSID clsidOLEDB; OLEHR( hr = CLSIDFromProgID(L"SQLOLEDB", &clsidOLEDB) ); OLEHR( hr = m_pIDataInitialize->CreateDBInstance( clsidOLEDB, NULL, CLSCTX_INPROC_SERVER, NULL, IID_IDBInitialize, (IUnknown **)&m_pIDBInitialize ) ); #endif #endif return TRUE; CLEANUP: SQLError( hr ); SAFE_RELEASE(m_pIDBInitialize); return FALSE; } BOOL IOLEDB::Connect() { HRESULT hr = 0; const int MAX_PROPERTY_NUM = 6; DBPROP properties[MAX_PROPERTY_NUM]; DBPROPSET propertySet; for( int i = 0 ; i < MAX_PROPERTY_NUM ; ++i ) { VariantInit( &properties[i].vValue ); properties[i].dwOptions = DBPROPOPTIONS_REQUIRED; properties[i].colid = DB_NULLID; } OLECHAR IPAddress[32], DataBase[32], UserID[32], Password[32]; MultiByteToWideChar( CP_ACP, 0, m_pszIPAddress, -1, IPAddress, 32 ); MultiByteToWideChar( CP_ACP, 0, m_pszDatabaseName, -1, DataBase, 32 ); MultiByteToWideChar( CP_ACP, 0, m_pszUserName, -1, UserID, 32 ); MultiByteToWideChar( CP_ACP, 0, m_pszUserPassword, -1, Password, 32 ); properties[0].dwPropertyID = DBPROP_INIT_PROMPT; properties[0].vValue.vt = VT_I2; properties[0].vValue.iVal = DBPROMPT_NOPROMPT; properties[1].dwPropertyID = DBPROP_INIT_LOCATION; properties[1].vValue.vt = VT_BSTR; properties[1].vValue.bstrVal = SysAllocString( IPAddress ); properties[2].dwPropertyID = DBPROP_INIT_DATASOURCE; properties[2].vValue.vt = VT_BSTR; properties[2].vValue.bstrVal = SysAllocString( IPAddress ); properties[3].dwPropertyID = DBPROP_INIT_CATALOG; properties[3].vValue.vt = VT_BSTR; properties[3].vValue.bstrVal = SysAllocString( DataBase ); properties[4].dwPropertyID = DBPROP_AUTH_USERID; properties[4].vValue.vt = VT_BSTR; properties[4].vValue.bstrVal = SysAllocString( UserID ); properties[5].dwPropertyID = DBPROP_AUTH_PASSWORD; properties[5].vValue.vt = VT_BSTR; properties[5].vValue.bstrVal = SysAllocString( Password ); // level of prompting that will be done to complete the connection process propertySet.guidPropertySet = DBPROPSET_DBINIT; propertySet.cProperties = MAX_PROPERTY_NUM; propertySet.rgProperties = properties; /// Create DBProperties IDBProperties * pIDBProperties; OLEHR( m_pIDBInitialize->QueryInterface( IID_IDBProperties, (VOID **)&pIDBProperties) ); OLEHR( pIDBProperties->SetProperties( 1, &propertySet ) ); pIDBProperties->Release(); for( i = 1 ; i < MAX_PROPERTY_NUM ; ++i ) SysFreeString( properties[i].vValue.bstrVal ); OLEHR( hr = m_pIDBInitialize->Initialize() ); /// Create DBCreateSession OLEHR( hr = m_pIDBInitialize->QueryInterface( IID_IDBCreateSession, (VOID **)&m_pIDBCreateSession ) ); /// Create DBCreateCommand OLEHR( hr = m_pIDBCreateSession->CreateSession( NULL, IID_IDBCreateCommand, (IUnknown **)&m_pIDBCreateCommand ) ); /// Create Command OLEHR( hr = m_pIDBCreateCommand->CreateCommand( NULL, IID_ICommand, (IUnknown **)&m_pICommand ) ); //pIDBCreateCommand->CreateCommand( NULL, IID_ICommandText, (IUnknown**) &pICommandText) /// Create CommandText OLEHR( hr = m_pICommand->QueryInterface( IID_ICommandText, (VOID **)&m_pICommandText ) ); return TRUE; CLEANUP: SQLError( hr ); SAFE_RELEASE(m_pICommandText); SAFE_RELEASE(m_pICommand); SAFE_RELEASE(m_pIDBCreateCommand); SAFE_RELEASE(m_pIDBCreateSession); return FALSE; } VOID IOLEDB::Disconnect() { SAFE_RELEASE(m_pICommandText); SAFE_RELEASE(m_pICommand); SAFE_RELEASE(m_pIDBCreateCommand); SAFE_RELEASE(m_pIDBCreateSession); } BOOL IOLEDB::Execute( Query * pQuery ) { HRESULT hr; OLECHAR ocQuery[MAX_QUERY_LENGTH]; ::MultiByteToWideChar( CP_ACP, 0, pQuery->GetQuery(), -1, ocQuery, MAX_QUERY_LENGTH ); OLEHR( hr = m_pICommandText->SetCommandText( DBGUID_DBSQL, ocQuery ) ); OLEHR( hr = m_pICommandText->Execute( NULL, IID_IRowset, NULL, pQuery->GetAffectNumPtr(), (IUnknown **)&m_pIRowset ) ); OLEOK( 0 == pQuery->GetAffectNum() || NULL == m_pIRowset ); /* // columnÁ¤º¸¸¦ ÀÐÀ» Çʿ䰡 ¾ø´Ù. OLEHR( hr = m_pIRowset->QueryInterface( IID_IColumnsInfo, (VOID **)&m_pIColumnsInfo ) ); OLECHAR * wcStringBuffer; OLEHR( hr = m_pIColumnsInfo->GetColumnInfo( pQuery->GetResultColNumPtr(), &m_pDBColumnInfo, &wcStringBuffer ) ); CoTaskMemFree(wcStringBuffer); m_pIColumnsInfo->Release(); */ ULONG offset; ULONG * pOffset = &offset; LONG csize; SHORT sType; for( ULONG i = 0 ; i < pQuery->GetMaxColNum() ; ++i ) { pQuery->GetColumnInfo( 0, i, pOffset, csize, sType); m_pDBBindings[i].iOrdinal = i+1; ///< index m_pDBBindings[i].wType = sType; ///< GetOleType() m_pDBBindings[i].cbMaxLen = csize; ///< sizeofType m_pDBBindings[i].obValue = offset; ///< offsetbuffer() m_pDBBindings[i].obStatus = NULL; m_pDBBindings[i].obLength = NULL; m_pDBBindings[i].pTypeInfo = NULL; m_pDBBindings[i].pObject = NULL; m_pDBBindings[i].pBindExt = NULL; m_pDBBindings[i].dwPart = DBPART_VALUE; m_pDBBindings[i].dwMemOwner = DBMEMOWNER_CLIENTOWNED; m_pDBBindings[i].eParamIO = DBPARAMIO_NOTPARAM; m_pDBBindings[i].dwFlags = NULL; m_pDBBindings[i].bPrecision = 0; m_pDBBindings[i].bScale = 0; } OLEHR( hr = m_pIRowset->QueryInterface( IID_IAccessor, (VOID **)&m_pIAccessor ) ); OLEHR( hr = m_pIAccessor->CreateAccessor( DBACCESSOR_ROWDATA, pQuery->GetMaxColNum(), m_pDBBindings, 0, &m_hAccessor, NULL ) ); ULONG ulRow = 0; do { m_pIRowset->GetNextRows( DB_NULL_HCHAPTER, 0, 1, pQuery->GetResultRowNumPtr(), &m_phRow ); if( 0 == pQuery->GetResultRowNum() ) break; OLEHR( hr = m_pIRowset->GetData( m_phRow[0], m_hAccessor, pQuery->GetBuffer(ulRow) ) ); OLEHR( hr = m_pIRowset->ReleaseRows( pQuery->GetResultRowNum(), m_phRow, NULL, NULL, NULL ) ); ++ulRow; } while(TRUE); pQuery->SetResultRowNum( ulRow ); pQuery->SetResultColNum( pQuery->GetMaxColNum() ); if( m_pIAccessor ) m_pIAccessor->ReleaseAccessor( m_hAccessor, NULL ); SAFE_RELEASE( m_pIAccessor ); SAFE_RELEASE( m_pIRowset ); return TRUE; CLEANUP: // ÃʱⰪ ¼ÂÆÃ pQuery->SetAffectNum( 0 ); pQuery->SetResultRowNum( 0 ); pQuery->SetResultColNum( 0 ); SQLError( hr ); if( m_pIAccessor ) m_pIAccessor->ReleaseAccessor( m_hAccessor, NULL ); SAFE_RELEASE( m_pIAccessor ); SAFE_RELEASE( m_pIRowset ); return FALSE; } /* VOID IOLEDB::GetString() { switch( m_pDBBindings[dwColPos].wType ) { case DBTYPE_R4: // 4 Byte Float case DBTYPE_R8: // 8 Byte Float case DBTYPE_I8: // 8 Byte int case DBTYPE_UI8: // 8 Byte unsinged int case DBTYPE_I1: // 1 Byte int case DBTYPE_I2: // 2 Byte int case DBTYPE_I4: // 4 Byte int case DBTYPE_UI1: // 1 Byte unsinged int case DBTYPE_UI2: // 2 Byte unsinged int case DBTYPE_UI4: // 4 Byte unsinged int case DBTYPE_STR : // String case DBTYPE_BSTR : // UniCode String case DBTYPE_WSTR : // UniCode End-Null String case DBTYPE_DBDATE : // DB Date case DBTYPE_DBTIME : // DB Time case DBTYPE_DBTIMESTAMP : // DB TimeStamp } } */ VOID IOLEDB::zDisplayProvider() { HRESULT hr; CEnumerator enumDataSource; hr = enumDataSource.Open(); hr = enumDataSource.MoveFirst(); while(hr == S_OK) { hr = enumDataSource.GetData(); // DataSource ¾ò±â CLSID clsid; LPOLESTR lpwstrProgID; char strDesc[256], strProgID[256], strCLSID[256]; // CLSID·Î ProgID ¾ò±â CLSIDFromString(enumDataSource.m_pAccessor->m_szParseName, &clsid); ProgIDFromCLSID(clsid, &lpwstrProgID); // Char º¯È¯ WideCharToMultiByte(CP_ACP, 0, enumDataSource.m_pAccessor->m_szDescription, -1, strDesc, 256, NULL, NULL); WideCharToMultiByte(CP_ACP, 0, lpwstrProgID, -1, strProgID, 256, NULL, NULL); WideCharToMultiByte(CP_ACP, 0, enumDataSource.m_pAccessor->m_szParseName, -1, strCLSID, 256, NULL, NULL); char aaa[256]; sprintf(aaa, "%s, %s, %s\n", strDesc, strProgID, strCLSID); m_fnErrorMessage(aaa ); ::GlobalFree(lpwstrProgID); hr = enumDataSource.MoveNext(); } } BOOL IOLEDB::SQLError( HRESULT hr ) { if( 0 == hr ) return TRUE; typedef struct { DWORD dwFlag; char *szText; } Note; static Note ResultCodes[] = { // oledberr.h error codes NOTE(DB_E_BADACCESSORHANDLE), NOTE(DB_E_BADACCESSORHANDLE), NOTE(DB_E_ROWLIMITEXCEEDED), NOTE(DB_E_READONLYACCESSOR), NOTE(DB_E_SCHEMAVIOLATION), NOTE(DB_E_BADROWHANDLE), NOTE(DB_E_OBJECTOPEN), NOTE(DB_E_BADBINDINFO), NOTE(DB_SEC_E_PERMISSIONDENIED), NOTE(DB_E_NOTAREFERENCECOLUMN), NOTE(DB_E_NOCOMMAND), NOTE(DB_E_BADBOOKMARK), NOTE(DB_E_BADLOCKMODE), NOTE(DB_E_PARAMNOTOPTIONAL), NOTE(DB_E_BADRATIO), NOTE(DB_E_ERRORSINCOMMAND), NOTE(DB_E_BADSTARTPOSITION), NOTE(DB_E_NOTREENTRANT), NOTE(DB_E_NOAGGREGATION), NOTE(DB_E_DELETEDROW), NOTE(DB_E_CANTFETCHBACKWARDS), NOTE(DB_E_ROWSNOTRELEASED), NOTE(DB_E_BADSTORAGEFLAG), NOTE(DB_E_BADSTATUSVALUE), NOTE(DB_E_CANTSCROLLBACKWARDS), NOTE(DB_E_INTEGRITYVIOLATION), NOTE(DB_E_ABORTLIMITREACHED), NOTE(DB_E_DUPLICATEINDEXID), NOTE(DB_E_NOINDEX), NOTE(DB_E_INDEXINUSE), NOTE(DB_E_NOTABLE), NOTE(DB_E_CONCURRENCYVIOLATION), NOTE(DB_E_BADCOPY), NOTE(DB_E_BADPRECISION), NOTE(DB_E_BADSCALE), NOTE(DB_E_BADID), NOTE(DB_E_BADTYPE), NOTE(DB_E_DUPLICATECOLUMNID), NOTE(DB_E_DUPLICATETABLEID), NOTE(DB_E_TABLEINUSE), NOTE(DB_E_NOLOCALE), NOTE(DB_E_BADRECORDNUM), NOTE(DB_E_BOOKMARKSKIPPED), NOTE(DB_E_BADPROPERTYVALUE), NOTE(DB_E_INVALID), NOTE(DB_E_BADACCESSORFLAGS), NOTE(DB_E_BADSTORAGEFLAGS), NOTE(DB_E_BYREFACCESSORNOTSUPPORTED), NOTE(DB_E_NULLACCESSORNOTSUPPORTED), NOTE(DB_E_NOTPREPARED), NOTE(DB_E_BADACCESSORTYPE), NOTE(DB_E_WRITEONLYACCESSOR), NOTE(DB_SEC_E_AUTH_FAILED), NOTE(DB_E_CANCELED), NOTE(DB_E_BADSOURCEHANDLE), NOTE(DB_S_ROWLIMITEXCEEDED), NOTE(DB_S_COLUMNTYPEMISMATCH), NOTE(DB_S_TYPEINFOOVERRIDDEN), NOTE(DB_S_BOOKMARKSKIPPED), NOTE(DB_S_ENDOFROWSET), NOTE(DB_S_BUFFERFULL), NOTE(DB_S_CANTRELEASE), NOTE(DB_S_DIALECTIGNORED), NOTE(DB_S_UNWANTEDPHASE), NOTE(DB_S_COLUMNSCHANGED), NOTE(DB_S_ERRORSRETURNED), NOTE(DB_S_BADROWHANDLE), NOTE(DB_S_DELETEDROW), NOTE(DB_S_STOPLIMITREACHED), NOTE(DB_S_LOCKUPGRADED), NOTE(DB_S_PROPERTIESCHANGED), NOTE(DB_S_ERRORSOCCURRED), NOTE(DB_S_PARAMUNAVAILABLE), NOTE(DB_S_MULTIPLECHANGES), // winerr.h NOTE(E_UNEXPECTED), NOTE(E_NOTIMPL), NOTE(E_OUTOFMEMORY), NOTE(E_INVALIDARG), NOTE(E_NOINTERFACE), NOTE(E_POINTER), NOTE(E_HANDLE), NOTE(E_ABORT), NOTE(E_FAIL), NOTE(E_ACCESSDENIED), NOTE(S_OK), NOTE(S_FALSE), NOTE(E_UNEXPECTED), NOTE(E_NOTIMPL), NOTE(E_OUTOFMEMORY), NOTE(E_INVALIDARG), NOTE(E_NOINTERFACE), NOTE(E_POINTER), NOTE(E_HANDLE), NOTE(E_ABORT), NOTE(E_FAIL), NOTE(E_ACCESSDENIED), // BindMoniker Errors NOTE(MK_E_NOOBJECT), NOTE(MK_E_EXCEEDEDDEADLINE), NOTE(MK_E_CONNECTMANUALLY), NOTE(MK_E_INTERMEDIATEINTERFACENOTSUPPORTED), NOTE(STG_E_ACCESSDENIED), NOTE(MK_E_SYNTAX), NOTE(MK_E_CANTOPENFILE), }; char buff[255]; int err_num = sizeof(ResultCodes)/sizeof(*ResultCodes); for( int j = 0; j < err_num ; ++j ) { if (ResultCodes[j].dwFlag == (DWORD)hr) break; } if( j == err_num ) sprintf( buff, "HREULT : " ); else sprintf( buff, "HREULT : %d, %s", ResultCodes[j].dwFlag, ResultCodes[j].szText ); m_fnErrorMessage( buff ); return FALSE; }