home *** CD-ROM | disk | FTP | other *** search
- //-----------------------------------------------------------------------------
- // Microsoft OLE DB QLAPDEMO Sample
- // Copyright (C) 1995-1998 Microsoft Corporation
- //
- // File: OLAPTab.cpp
- //
- // This file implements the class OLAPTab.
- //
- //-----------------------------------------------------------------------------
-
- #include "OLAP.h"
-
- /////////////////////////////////////////////////////////////////////////////////////
- OLAPTab::OLAPTab( LPTSTR pFormat, TCHAR tDelimeter )
-
- // Constructor for the OLAPTab
- /////////////////////////////////////////////////////////////////////////////////////
- {
- m_tDelimeter = tDelimeter;
- m_cColumns = Set(pFormat);
- }
-
- /////////////////////////////////////////////////////////////////////////////////////
- OLAPTab::~OLAPTab()
-
- // Destructor for the OLAPTab
- /////////////////////////////////////////////////////////////////////////////////////
- {
- }
-
- //////////////////////////////////////////////////////////////////////////////////////
- LONG OLAPTab::First( TCHAR* string, TCHAR** text, TCHAR** next )
-
- //
- //////////////////////////////////////////////////////////////////////////////////////
- {
- assert ( string && text && next );
-
- *text = string;
- *next = _tcschr( *text, m_tDelimeter );
-
- if ( *next ) *(*next) = 0;
-
- return (*next) ? *next - *text : _tcslen(*text);
- }
-
-
- //////////////////////////////////////////////////////////////////////////////////////
- LONG OLAPTab::Next( TCHAR** text, TCHAR** next )
-
- //
- //////////////////////////////////////////////////////////////////////////////////////
- {
- assert ( text && next );
-
- LONG length;
-
- if ( *next ) {
- *text = *next + 1;
- *next = _tcschr( *text, m_tDelimeter );
-
- if ( *next ) {
- *(*next) = 0;
- length = *next - *text;
- }
- else {
- length = _tcslen(*text);
- }
- }
- else {
- length = 0;
- }
- return length;
- }
-
-
- /////////////////////////////////////////////////////////////////////////////////////
- LONG OLAPTab::Set( LPTSTR tstrFormat )
-
- // Set the format for output
- /////////////////////////////////////////////////////////////////////////////////////
- {
- m_cColumns = 0;
-
- memset( m_pColumnLen, 0, sizeof(m_pColumnLen) );
- memset( m_pColumnStr, 0, sizeof(m_pColumnStr) );
-
- if ( tstrFormat ) {
- _tcsncpy( m_pColumnBuffer, tstrFormat, OLAP_APP_MAX_STRING_LEN );
- m_pColumnBuffer[OLAP_APP_MAX_STRING_LEN-1] = 0;
-
- TCHAR* pText;
- TCHAR* pNext;
- LONG lLength = First( m_pColumnBuffer, &pText, &pNext );
-
- for ( LONG i = 0; i < OLAP_APP_MAX_COLUMNS; i++ ) {
- if ( !lLength ) break;
-
- m_pColumnLen[m_cColumns] = lLength;
- m_pColumnStr[m_cColumns] = pText;
- m_cColumns++;
-
- lLength = Next( &pText, &pNext );
- }
- }
- return m_cColumns;
- }
-
-
-
- /////////////////////////////////////////////////////////////////////////////////////
- HRESULT OLAPTab::PrintPropertiesInfo( IDBCreateSession* pIDBSource, DWORD dwFlags )
-
- // Print session properties.
- /////////////////////////////////////////////////////////////////////////////////////
- {
- if ( !pIDBSource ) return E_FAIL;
-
- IDBProperties* pIDBProperties = NULL;
-
- DBPROPIDSET rgPropertyIDSets[1];
- ULONG cPropertyInfoSets = 0, i, j, k;
- DBPROPINFOSET* rgPropertyInfoSets = NULL;
- OLECHAR* pDescBuffer = NULL;
-
- // Get propirties interface
- HRESULT hr = pIDBSource->QueryInterface( IID_IDBProperties, (void**) &pIDBProperties );
- if ( FAILED(hr) || !pIDBProperties )
- goto CLEANUP;
-
- // Get propirties info
- hr = pIDBProperties->GetPropertyInfo( 0,
- rgPropertyIDSets,
- &cPropertyInfoSets,
- &rgPropertyInfoSets,
- &pDescBuffer );
- if ( FAILED(hr) || !cPropertyInfoSets )
- goto CLEANUP;
-
- _tprintf( TEXT("\n") );
- PrintColumnCaption( 0, 45, TEXT("Description") );
- PrintColumnCaption( 1, 25, TEXT("Group") );
- PrintColumnCaption( 2, 12, TEXT("Type") );
- PrintColumnCaption( 3, OLAP_APP_MAX_COLUMN_STR, TEXT("Value") );
-
- _tprintf( TEXT("\n") );
- PrintColumnDelimiter( 0, 11);
- PrintColumnDelimiter( 1, 5 );
- PrintColumnDelimiter( 2, 4 );
- PrintColumnDelimiter( 3, 5 );
-
- for ( i = 0; i < cPropertyInfoSets; i++ ) {
- for ( j = 0, k = 0; j < rgPropertyInfoSets[i].cPropertyInfos; j++ ) {
- if ( !(rgPropertyInfoSets[i].rgPropertyInfos[j].dwFlags & dwFlags) )
- continue;
-
- k++;
-
- _tprintf( TEXT("\n") );
- PrintColumnString( 0, rgPropertyInfoSets[i].rgPropertyInfos[j].pwszDescription );
-
-
- if ( rgPropertyInfoSets[i].rgPropertyInfos[j].dwFlags & DBPROPFLAGS_NOTSUPPORTED ) {
- PrintColumnString( 1, TEXT("Not Supported") );
- }
- else if ( rgPropertyInfoSets[i].rgPropertyInfos[j].dwFlags & DBPROPFLAGS_COLUMN ) {
- PrintColumnString( 1, TEXT("Column") );
- }
- else if ( rgPropertyInfoSets[i].rgPropertyInfos[j].dwFlags & DBPROPFLAGS_DATASOURCE ) {
- PrintColumnString( 1, TEXT("Data Source") );
- }
- else if ( rgPropertyInfoSets[i].rgPropertyInfos[j].dwFlags & DBPROPFLAGS_DATASOURCECREATE ) {
- PrintColumnString( 1, TEXT("Data Source Creation") );
- }
- else if ( rgPropertyInfoSets[i].rgPropertyInfos[j].dwFlags & DBPROPFLAGS_DATASOURCEINFO ) {
- PrintColumnString( 1, TEXT("Data Source Information") );
- }
- else if ( rgPropertyInfoSets[i].rgPropertyInfos[j].dwFlags & DBPROPFLAGS_DBINIT ) {
- PrintColumnString( 1, TEXT("Initialization") );
- }
- else if ( rgPropertyInfoSets[i].rgPropertyInfos[j].dwFlags & DBPROPFLAGS_INDEX ) {
- PrintColumnString( 1, TEXT("Index") );
- }
- else if ( (rgPropertyInfoSets[i].rgPropertyInfos[j].dwFlags & DBPROPFLAGS_ROWSET) &&
- (rgPropertyInfoSets[i].rgPropertyInfos[j].dwFlags & DBPROPFLAGS_COLUMNOK) ) {
- PrintColumnString( 1, TEXT("Rowset & Column OK") );
- }
- else if ( rgPropertyInfoSets[i].rgPropertyInfos[j].dwFlags & DBPROPFLAGS_ROWSET ) {
- PrintColumnString( 1, TEXT("Rowset") );
- }
- else if ( rgPropertyInfoSets[i].rgPropertyInfos[j].dwFlags & DBPROPFLAGS_SESSION ) {
- PrintColumnString( 1, TEXT("Session") );
- }
- else if ( rgPropertyInfoSets[i].rgPropertyInfos[j].dwFlags & DBPROPFLAGS_TABLE ) {
- PrintColumnString( 1, TEXT("Table") );
- }
-
-
- if ( (rgPropertyInfoSets[i].rgPropertyInfos[j].dwFlags & DBPROPFLAGS_READ) &&
- (rgPropertyInfoSets[i].rgPropertyInfos[j].dwFlags & DBPROPFLAGS_WRITE) ) {
- PrintColumnString( 2, TEXT("Read/Write") );
- }
- else if ( rgPropertyInfoSets[i].rgPropertyInfos[j].dwFlags & DBPROPFLAGS_READ ) {
- PrintColumnString( 2, TEXT("Read") );
- }
- else if ( rgPropertyInfoSets[i].rgPropertyInfos[j].dwFlags & DBPROPFLAGS_WRITE ) {
- PrintColumnString( 2, TEXT("Write") );
- }
- if ( rgPropertyInfoSets[i].rgPropertyInfos[j].dwFlags & DBPROPFLAGS_REQUIRED ) {
- PrintColumnString( 2, TEXT("Required") );
- }
-
- DBPROPIDSET rgPropertyIDSets[1];
- ULONG cPropertySets = 0;
- DBPROPSET* rgPropertySets = NULL;
-
- rgPropertyIDSets[0].rgPropertyIDs = &rgPropertyInfoSets[i].rgPropertyInfos[j].dwPropertyID;
- rgPropertyIDSets[0].cPropertyIDs = 1;
- rgPropertyIDSets[0].guidPropertySet = rgPropertyInfoSets[i].guidPropertySet;
-
-
- // Get property value.
- hr = pIDBProperties->GetProperties ( 1,
- rgPropertyIDSets,
- &cPropertySets,
- &rgPropertySets );
-
-
- if ( FAILED(hr) || !cPropertySets || !rgPropertySets[0].cProperties )
- continue;
-
- PrintColumnVariant( 3 ,&rgPropertySets[0].rgProperties[0].vValue );
-
- // Clean property data.
- if ( rgPropertySets ) {
- VariantClear( &rgPropertySets[0].rgProperties[0].vValue );
- CoTaskMemFree(rgPropertySets[0].rgProperties);
- CoTaskMemFree(rgPropertySets);
- }
- }
- // Clean info data.
- if ( rgPropertyInfoSets[i].rgPropertyInfos )
- CoTaskMemFree(rgPropertyInfoSets[i].rgPropertyInfos);
-
- if ( k ) _tprintf( TEXT("\n") );
- }
-
- CLEANUP:
- if ( rgPropertyInfoSets ) CoTaskMemFree(rgPropertyInfoSets);
- if ( pDescBuffer ) CoTaskMemFree(pDescBuffer);
-
- if ( pIDBProperties ) pIDBProperties->Release();
-
-
- return S_OK;
- }
-
-
- /////////////////////////////////////////////////////////////////////////////////////
- HRESULT OLAPTab::PrintSchemaRowset( IDBCreateCommand* pIDBSession, LPTSTR pSchema, GUID* pGuid )
-
- // Print schema.
- /////////////////////////////////////////////////////////////////////////////////////
- {
- if ( !pIDBSession ) return E_FAIL;
-
- static struct Info {
- const GUID* pGuid;
- const TCHAR* pName;
- const TCHAR* pShortName;
- } rgInfo[] = {
- { &DBSCHEMA_CATALOGS, TEXT("Catalogs"), TEXT("C") },
- { &DBSCHEMA_SCHEMATA, TEXT("Schemas"), TEXT("S") },
- { &MDSCHEMA_CUBES, TEXT("Cubes"), TEXT("Cub") },
- { &MDSCHEMA_MEASURES, TEXT("Measures"), TEXT("M") },
- { &MDSCHEMA_DIMENSIONS, TEXT("Dimensions"), TEXT("Dim") },
- { &MDSCHEMA_HIERARCHIES, TEXT("Hierarchies"), TEXT("H") },
- { &MDSCHEMA_LEVELS, TEXT("Levels"), TEXT("L") },
- { &MDSCHEMA_PROPERTIES, TEXT("Properties"), TEXT("P") },
- { &MDSCHEMA_MEMBERS, TEXT("Members"), TEXT("Mem") },
- };
-
- ULONG i;
-
- if ( !pGuid && pSchema ) {
- for ( i = 0; i < NUMELEM(rgInfo); i++ ) {
- if ( !OLAP_strcmp(rgInfo[i].pName,OLAP_ALL,pSchema,OLAP_ALL) ||
- !OLAP_strcmp(rgInfo[i].pShortName,OLAP_ALL,pSchema,OLAP_ALL) ) {
- pGuid = (GUID*) rgInfo[i].pGuid;
- break;
- }
- }
- }
- if ( !pGuid ) pGuid = (GUID*) rgInfo[0].pGuid;
-
- // Check if this supported.
- IDBSchemaRowset* pIDBSchemaRowset = NULL;
- IRowset* pIRowset = NULL;
-
- ULONG cSchemas;
- GUID* pSchemaGuids = NULL;
- ULONG* rgRestrictionSupport = NULL;
-
- // Get Schema interface
- HRESULT hr = pIDBSession->QueryInterface( IID_IDBSchemaRowset, (void**) &pIDBSchemaRowset );
- if ( FAILED(hr) || !pIDBSchemaRowset )
- goto CLEANUP;
-
- hr = pIDBSchemaRowset->GetSchemas( &cSchemas, &pSchemaGuids, &rgRestrictionSupport );
- if ( FAILED(hr) && !cSchemas )
- goto CLEANUP;
-
- for ( i = 0; i < cSchemas; i++ ) {
- if ( *pGuid == pSchemaGuids[i] )
- break;
- }
- if ( i == cSchemas )
- goto CLEANUP;
-
-
- // Get rowset
- hr = pIDBSchemaRowset->GetRowset( NULL,
- *pGuid,
- 0, // cRestrictions
- NULL, // rgRestrictions
- IID_IRowset,
- 0, // cPropertySets
- NULL, // rgPropertySets,
- (IUnknown**) &pIRowset );
- if ( FAILED(hr) || !pIRowset )
- goto CLEANUP;
-
- PrintRowset( pIRowset );
-
- CLEANUP:
- if ( pSchemaGuids ) CoTaskMemFree(pSchemaGuids);
- if ( rgRestrictionSupport ) CoTaskMemFree(rgRestrictionSupport);
-
- if ( pIDBSchemaRowset ) pIDBSchemaRowset->Release();
- if ( pIRowset ) pIRowset->Release();
-
- return hr;
- }
-
-
- /////////////////////////////////////////////////////////////////////////////////////
- HRESULT OLAPTab::PrintAxisRowset( IMDDataset* pIMDDataset, LONG iAxis, LPTSTR pAxis )
-
- // Print schema.
- /////////////////////////////////////////////////////////////////////////////////////
- {
- if ( !pIMDDataset ) return E_FAIL;
-
- static struct Info {
- LONG iAxis;
- const TCHAR* pName;
- const TCHAR* pShortName;
- } rgInfo[] = {
- { 0, TEXT("Columns"), TEXT("0") },
- { 1, TEXT("Rows"), TEXT("1") },
- { 2, TEXT("Pages"), TEXT("2") },
- { 3, TEXT("3"), TEXT("3") },
- { 4, TEXT("4"), TEXT("4") },
- { 5, TEXT("5"), TEXT("5") },
- { 6, TEXT("6"), TEXT("6") },
- { 7, TEXT("7"), TEXT("7") },
- };
-
- ULONG i;
-
- if ( iAxis < 0 && pAxis ) {
- for ( i = 0; i < NUMELEM(rgInfo); i++ ) {
- if ( !OLAP_strcmp(rgInfo[i].pName,OLAP_ALL,pAxis,OLAP_ALL) ||
- !OLAP_strcmp(rgInfo[i].pShortName,OLAP_ALL,pAxis,OLAP_ALL) ) {
- iAxis = rgInfo[i].iAxis;
- break;
- }
- }
- }
-
- // Get Axis info
- ULONG cAxis;
- MDAXISINFO* rgAxisInfo = NULL;
-
- IRowset* pIRowset = NULL;
-
-
- HRESULT hr = pIMDDataset->GetAxisInfo( &cAxis, &rgAxisInfo );
- if ( FAILED(hr) || !cAxis )
- goto CLEANUP;
-
-
- // Axis not exist in query result
- if ( iAxis > 0 && iAxis >= (LONG) cAxis )
- return S_OK;
-
- if ( iAxis < 0 ) {
- // Print all
- iAxis = 0;
- }
- else {
- // Print one
- cAxis = iAxis + 1;
- }
-
- for ( ; iAxis < (LONG) cAxis; iAxis++ ) {
- // Clean rowset.
- if ( pIRowset ) { pIRowset->Release(); pIRowset = NULL; }
-
- // Get rowset
- hr = pIMDDataset->GetAxisRowset( NULL,
- iAxis,
- IID_IRowset,
- 0,
- NULL,
- (IUnknown**) &pIRowset );
- if ( FAILED(hr) || !pIRowset )
- goto CLEANUP;
-
- PrintRowset( pIRowset );
-
- // Format will applay for first axis.
- m_cColumns = 0;
- }
-
- CLEANUP:
- if ( rgAxisInfo ) pIMDDataset->FreeAxisInfo( cAxis, rgAxisInfo );
- if ( pIRowset ) pIRowset->Release();
-
- return hr;
- }
-
-
- /////////////////////////////////////////////////////////////////////////////////////
- BOOL OLAPTab::PrintColumnCaption( LONG iColumn, LONG lLength, LPTSTR pCaption )
-
- // Init column length and caption.
- /////////////////////////////////////////////////////////////////////////////////////
- {
- if ( !lLength ) m_pColumnLen[iColumn] = 0;
-
- if ( iColumn < m_cColumns && m_pColumnLen[iColumn] > 0 ) {
- if ( m_pColumnStr[iColumn] && *m_pColumnStr[iColumn] ) {
- if ( !_stscanf( m_pColumnStr[iColumn], _TEXT("%ld"), &m_pColumnLen[iColumn] ) ) {
- m_pColumnLen[iColumn] = 0;
- }
- }
- else {
- m_pColumnLen[iColumn] = 0;
- }
- }
- else {
- if ( !m_pColumnLen[iColumn] ) m_pColumnLen[iColumn] = lLength;
- }
- if ( !m_pColumnLen[iColumn] )
- return FALSE;
-
- PrintColumnString( iColumn, pCaption );
-
- return TRUE;
- }
-
- /////////////////////////////////////////////////////////////////////////////////////
- BOOL OLAPTab::PrintColumnDelimiter( LONG iColumn, LONG lLength )
-
- // Init column length and caption.
- /////////////////////////////////////////////////////////////////////////////////////
- {
- if ( !m_pColumnLen[iColumn] ) return FALSE;
-
- TCHAR pBuffer[OLAP_APP_MAX_COLUMN_STR + 1];
-
- if ( lLength > m_pColumnLen[iColumn] )
- lLength = m_pColumnLen[iColumn];
-
- if ( lLength > OLAP_APP_MAX_COLUMN_STR )
- lLength = OLAP_APP_MAX_COLUMN_STR;
-
- for ( LONG i = 0; i < lLength; i++ )
- pBuffer[i] = TEXT('-');
- pBuffer[i] = 0;
-
- // Print caption delimiters
- PrintColumnString( iColumn, pBuffer );
-
- return TRUE;
- }
-
-
- /////////////////////////////////////////////////////////////////////////////////////
- BOOL OLAPTab::PrintColumnString( LONG iColumn, LPTSTR pString )
-
- // Init column length and caption.
- /////////////////////////////////////////////////////////////////////////////////////
- {
- if ( m_pColumnLen[iColumn] ) {
- if ( pString ) _tprintf( TEXT("%-*s "), m_pColumnLen[iColumn], pString );
- else _tprintf( TEXT("%-*s "), m_pColumnLen[iColumn], TEXT(" ") );
-
- return TRUE;
- }
- return FALSE;
- }
-
-
- /////////////////////////////////////////////////////////////////////////////////////
- BOOL OLAPTab::PrintColumnVariant( LONG iColumn, VARIANT* pData )
-
- // Print session properties.
- /////////////////////////////////////////////////////////////////////////////////////
- {
- if ( !m_pColumnLen[iColumn] )
- return FALSE;
-
- if ( !pData ) {
- _tprintf( TEXT("%-*s "), m_pColumnLen[iColumn], TEXT(" ") );
- return TRUE;
- }
-
- switch ( V_VT(pData) ) {
- case VT_BSTR:
- case VT_LPSTR:
- case VT_LPWSTR:
- case VT_BSTR | VT_BYREF:
- case VT_LPSTR | VT_BYREF:
- case VT_LPWSTR | VT_BYREF: PRINT_VB(TEXT("%-*s"),V_BSTR,pData); break;
- case VT_I1:
- case VT_I1 | VT_BYREF: PRINT_VB(TEXT("%-*d"),V_I1,pData); break;
- case VT_UI1:
- case VT_UI1 | VT_BYREF: PRINT_VB(TEXT("%-*d"),V_UI1,pData); break;
- case VT_I2:
- case VT_I2 | VT_BYREF: PRINT_VB(TEXT("%-*d"),V_I2,pData); break;
- case VT_UI2:
- case VT_UI2 | VT_BYREF: PRINT_VB(TEXT("%-*d"),V_UI2,pData); break;
- case VT_BOOL:
- if ( V_BOOL(pData) != VARIANT_FALSE )
- PrintColumnString( iColumn, TEXT("TRUE") );
- else
- PrintColumnString( iColumn, TEXT("FALSE") );
- break;
- case VT_BOOL | VT_BYREF:
- if ( *V_BOOLREF(pData) != VARIANT_FALSE )
- PrintColumnString( iColumn, TEXT("TRUE") );
- else
- PrintColumnString( iColumn, TEXT("FALSE") );
- break;
- case VT_INT:
- case VT_INT | VT_BYREF: PRINT_VB(TEXT("%-*ld"),V_INT,pData); break;
- case VT_UINT:
- case VT_UINT | VT_BYREF: PRINT_VB(TEXT("%-*ld"),V_UINT,pData); break;
- case VT_I4:
- case VT_I4 | VT_BYREF: PRINT_VB(TEXT("%-*ld"),V_I4,pData); break;
- case VT_UI4:
- case VT_UI4 | VT_BYREF: PRINT_VB(TEXT("%-*ld"),V_UI4,pData); break;
- case VT_R4:
- case VT_R4 | VT_BYREF: PRINT_VB(TEXT("%-*f"),V_R4,pData); break;
- case VT_R8:
- case VT_R8 | VT_BYREF: PRINT_VB(TEXT("%-*f"),V_R8,pData); break;
- }
- return TRUE;
- }
-
-
-
- /////////////////////////////////////////////////////////////////////////////////////
- HRESULT OLAPTab::PrintRowset( IRowset* pIRowset )
-
- // Print Rowset.
- /////////////////////////////////////////////////////////////////////////////////////
- {
- if ( !pIRowset ) return E_FAIL;
-
- ULONG iCol, cCol, iColumn, cColumn, iBind;
- IColumnsInfo* pIColumnsInfo = NULL;
- DBCOLUMNINFO* pInfo = NULL;
- TCHAR* pStringsBuffer = NULL;
- IAccessor* pIAccessor = NULL;
- COLUMNDATA* pColumn = NULL;
-
- DBBINDING rgBind[OLAP_APP_MAX_BINDINGS + 1];
- BYTE pData[OLAP_APP_MAX_STRING_LEN + 1];
- ULONG dwLength, dwDesc, dwOffset = 0;
-
- HACCESSOR hAccessor = DB_NULL_HACCESSOR;
-
- ULONG cRowsObtained = 0;
- HROW* pRows = NULL;
- ULONG iRow;
-
-
- // Get Column info.
- HRESULT hr = pIRowset->QueryInterface( IID_IColumnsInfo, (void**) &pIColumnsInfo );
- if ( FAILED(hr) || !pIColumnsInfo )
- goto CLEANUP;
-
- hr = pIColumnsInfo->GetColumnInfo( &cCol,
- &pInfo,
- &pStringsBuffer );
- if ( FAILED(hr) || !cCol )
- goto CLEANUP;
-
- // Start table captions
- _tprintf(TEXT("\n\n"));
-
- // Create bindings. Bind everything as string.
- for ( iCol = 0, iBind = 0, iColumn = 0; iCol < cCol; iCol++ ) {
- // Skip columns of type _VECTOR.
- // Probably binary data.
- if ( pInfo[iCol].wType & DBTYPE_VECTOR ) {
- continue;
- }
-
-
- // correct for strings.
- dwDesc = (pInfo[iCol].pwszName) ? _tcslen(pInfo[iCol].pwszName) : 0;
-
- if ( pInfo[iCol].wType == DBTYPE_STR ) {
- dwLength = max(dwDesc, pInfo[iCol].ulColumnSize);
- }
- else if ( pInfo[iCol].wType == DBTYPE_WSTR ) {
- dwLength = max(dwDesc, pInfo[iCol].ulColumnSize/sizeof(TCHAR));
- }
- else if ( pInfo[iCol].wType == DBTYPE_VARIANT ) {
- dwLength = max(dwDesc, OLAP_APP_MIN_COLUMN_STR);
- }
- else {
- dwLength = max(dwDesc, OLAP_APP_MIN_COLUMN_VAL);
- }
- if ( dwLength > OLAP_APP_MAX_COLUMN_STR ) dwLength = OLAP_APP_MAX_COLUMN_STR;
- dwLength *= sizeof(TCHAR);
-
- // Print column caption.
- if ( !PrintColumnCaption( iColumn++, dwLength/sizeof(TCHAR), pInfo[iCol].pwszName ) )
- continue;
-
- rgBind[iBind].iOrdinal = pInfo[iCol].iOrdinal;
- rgBind[iBind].obValue = dwOffset + offsetof(COLUMNDATA,bData);
- rgBind[iBind].obLength = dwOffset + offsetof(COLUMNDATA,dwLength);
- rgBind[iBind].obStatus = dwOffset + offsetof(COLUMNDATA,dwStatus);
- rgBind[iBind].pTypeInfo = NULL;
- rgBind[iBind].pObject = NULL;
- rgBind[iBind].pBindExt = NULL;
- rgBind[iBind].dwFlags = 0;
- rgBind[iBind].eParamIO = DBPARAMIO_NOTPARAM;
- rgBind[iBind].dwPart = DBPART_VALUE | DBPART_LENGTH | DBPART_STATUS;
- rgBind[iBind].dwMemOwner = DBMEMOWNER_CLIENTOWNED;
- rgBind[iBind].bPrecision = 0;
- rgBind[iBind].bScale = 0;
-
- rgBind[iBind].cbMaxLen = (m_pColumnLen[iColumn-1] + 1)*sizeof(TCHAR);
- rgBind[iBind].wType = DBTYPE_WSTR;
-
- // Keep our limits
- if ( dwOffset + dwLength + offsetof(COLUMNDATA,bData) > OLAP_APP_MAX_STRING_LEN ||
- iColumn == OLAP_APP_MAX_BINDINGS )
- break;
-
- dwOffset += rgBind[iBind].cbMaxLen + offsetof(COLUMNDATA,bData);
- dwOffset = ROUND_UP( dwOffset, COLUMN_ALIGNVAL );
- iBind++;
- }
- cColumn = iColumn;
-
-
- // Print caption delimiters
- _tprintf(TEXT("\n"));
-
- for ( iCol = 0, iColumn = 0; iCol < cCol && iColumn < cColumn; iCol++ ) {
- // Skip columns of type _VECTOR.
- // Probably binary data.
- if ( (pInfo[iCol].wType & DBTYPE_VECTOR) || !m_pColumnLen[iColumn++] ) {
- continue;
- }
-
- // Print caption delimiters
- PrintColumnDelimiter( iColumn-1, (pInfo[iCol].pwszName) ? _tcslen(pInfo[iCol].pwszName) : rgBind[iBind].cbMaxLen/sizeof(TCHAR) );
- }
-
- // Create the accessor.
- hr = pIRowset->QueryInterface( IID_IAccessor, (void**) &pIAccessor );
- if ( FAILED(hr) || !pIAccessor )
- goto CLEANUP;
-
- hr = pIAccessor->CreateAccessor( DBACCESSOR_ROWDATA, iBind, rgBind, dwOffset, &hAccessor, NULL );
- if ( FAILED(hr) )
- goto CLEANUP;
-
- while( SUCCEEDED(hr) ) {
- // Prepare internal buffers and get handles to the rows.
- hr = pIRowset->GetNextRows( NULL, // hChapter
- 0, // cRowsToSkip
- NUMROWS_CHUNK, // cRowsDesired
- &cRowsObtained,
- &pRows ); // filled in w/ row handles
- if ( FAILED(hr) || !cRowsObtained || !pRows )
- break;
-
- for ( iRow = 0; iRow < cRowsObtained; iRow++ ) {
- // Populate our row buffer.
- hr = pIRowset->GetData( pRows[iRow],
- hAccessor,
- pData );
- if ( FAILED(hr) )
- break;
-
- // Print each column we're bound to.
- _tprintf(TEXT("\n"));
-
- for ( iCol = 0, iBind = 0, iColumn = 0; iCol < cCol && iColumn < cColumn; iCol++ ) {
- // Limit to first dwLength characters.
- if ( (pInfo[iCol].wType & DBTYPE_VECTOR) || !m_pColumnLen[iColumn++] ) {
- continue;
- }
-
- pColumn = (COLUMNDATA*) (pData + rgBind[iBind++].obLength);
-
- if ( pColumn->dwStatus == DBSTATUS_S_ISNULL ) {
- PrintColumnString(iColumn-1,TEXT("<null>"));
- }
- else if ( pColumn->dwStatus != DBSTATUS_S_OK &&
- pColumn->dwStatus != DBSTATUS_S_TRUNCATED ) {
- PrintColumnString(iColumn-1,TEXT("<error>"));
- }
- else {
- PrintColumnString(iColumn-1,(LPTSTR) pColumn->bData);
- }
- }
- }
- pIRowset->ReleaseRows( cRowsObtained, pRows, NULL, NULL, NULL );
- cRowsObtained = 0;
- }
-
- CLEANUP:
- if ( pRows ) CoTaskMemFree(pRows);
- if ( pInfo ) CoTaskMemFree(pInfo);
-
- if ( pStringsBuffer ) CoTaskMemFree(pStringsBuffer);
-
- if ( cRowsObtained ) pIRowset->ReleaseRows( cRowsObtained, pRows, NULL, NULL, NULL );
-
- if ( hAccessor != DB_NULL_HACCESSOR ) pIAccessor->ReleaseAccessor( hAccessor, NULL );
-
- if ( pIColumnsInfo ) pIColumnsInfo->Release();
- if ( pIAccessor ) pIAccessor->Release();
-
- return hr;
- }
-
-
- ///////////////////////////////////////////////////////////////////////////////
- HRESULT OLAPTab::PrintDataset( IMDDataset* pIMDDataset )
-
- // Print Dataset.
- ///////////////////////////////////////////////////////////////////////////////
- {
- if ( !pIMDDataset ) return E_FAIL;
-
- ULONG iCell, cCell;
- ULONG iAxis, cAxis;
- ULONG iCol, cCol, iColumn, cColumn, iBind;
-
- MDAXISINFO* rgAxisInfo = NULL;
-
- IColumnsInfo* pIColumnsInfo = NULL;
-
- DBCOLUMNINFO* pInfo = NULL;
- TCHAR* pStringsBuffer = NULL;
- IAccessor* pIAccessor = NULL;
- COLUMNDATA* pColumn = NULL;
-
-
- DBBINDING rgBind[OLAP_APP_MAX_BINDINGS + 1];
- BYTE pData[OLAP_APP_MAX_STRING_LEN + 1];
- ULONG dwLength, dwDesc, dwOffset = 0;
-
- HACCESSOR hAccessor = DB_NULL_HACCESSOR;
-
-
- HRESULT hr = pIMDDataset->GetAxisInfo( &cAxis, &rgAxisInfo );
- if ( FAILED(hr) || !cAxis )
- goto CLEANUP;
-
- // Calculate the total number of cells in this cellset
- for ( iAxis = 0, cCell = 1; iAxis < cAxis; iAxis++ ) {
- cCell *= MDAXISINFO_GETAT(rgAxisInfo,iAxis).cCoordinates;
- }
- if ( !cCell ) return S_OK;
-
-
-
- // Get Column info.
- hr = pIMDDataset->QueryInterface( IID_IColumnsInfo, (void**) &pIColumnsInfo );
- if ( FAILED(hr) || !pIColumnsInfo )
- goto CLEANUP;
-
- hr = pIColumnsInfo->GetColumnInfo( &cCol,
- &pInfo,
- &pStringsBuffer );
- if ( FAILED(hr) || !cCol )
- goto CLEANUP;
-
- // Start table captions
- _tprintf(TEXT("\n\n"));
-
- // Create bindings. Bind everything as string.
- for ( iCol = 0, iBind = 0, iColumn = 0; iCol < cCol; iCol++ ) {
- // Skip columns of type _VECTOR.
- // Probably binary data.
- if ( pInfo[iCol].wType & DBTYPE_VECTOR ) {
- continue;
- }
-
- // correct for strings.
- dwDesc = (pInfo[iCol].pwszName) ? _tcslen(pInfo[iCol].pwszName) : 0;
-
- if ( pInfo[iCol].wType == DBTYPE_STR ) {
- dwLength = max(dwDesc, pInfo[iCol].ulColumnSize);
- }
- else if ( pInfo[iCol].wType == DBTYPE_WSTR ) {
- dwLength = max(dwDesc, pInfo[iCol].ulColumnSize/sizeof(TCHAR));
- }
- else if ( pInfo[iCol].wType == DBTYPE_VARIANT ) {
- dwLength = max(dwDesc, OLAP_APP_MIN_COLUMN_STR);
- }
- else {
- dwLength = max(dwDesc, OLAP_APP_MIN_COLUMN_VAL);
- }
- if ( dwLength > OLAP_APP_MAX_COLUMN_STR ) dwLength = OLAP_APP_MAX_COLUMN_STR;
- dwLength *= sizeof(TCHAR);
-
-
- // Print column caption.
- if ( !PrintColumnCaption( iColumn++, dwLength/sizeof(TCHAR), pInfo[iCol].pwszName ) )
- continue;
-
- rgBind[iBind].iOrdinal = pInfo[iCol].iOrdinal;
- rgBind[iBind].obValue = dwOffset + offsetof(COLUMNDATA,bData);
- rgBind[iBind].obLength = dwOffset + offsetof(COLUMNDATA,dwLength);
- rgBind[iBind].obStatus = dwOffset + offsetof(COLUMNDATA,dwStatus);
- rgBind[iBind].pTypeInfo = NULL;
- rgBind[iBind].pObject = NULL;
- rgBind[iBind].pBindExt = NULL;
- rgBind[iBind].dwFlags = 0;
- rgBind[iBind].eParamIO = DBPARAMIO_NOTPARAM;
- rgBind[iBind].dwPart = DBPART_VALUE | DBPART_LENGTH | DBPART_STATUS;
- rgBind[iBind].dwMemOwner = DBMEMOWNER_CLIENTOWNED;
- rgBind[iBind].bPrecision = 0;
- rgBind[iBind].bScale = 0;
-
- rgBind[iBind].cbMaxLen = (m_pColumnLen[iColumn-1] + 1)*sizeof(TCHAR);
- rgBind[iBind].wType = DBTYPE_WSTR;
-
- // Keep our limits
- if ( dwOffset + dwLength + offsetof(COLUMNDATA,bData) > OLAP_APP_MAX_STRING_LEN ||
- iColumn == OLAP_APP_MAX_BINDINGS )
- break;
-
- dwOffset += rgBind[iBind].cbMaxLen + offsetof(COLUMNDATA,bData);
- dwOffset = ROUND_UP( dwOffset, COLUMN_ALIGNVAL );
- iBind++;
- }
- cColumn = iColumn;
-
-
- // Print caption delimiters
- _tprintf(TEXT("\n"));
-
- for ( iCol = 0, iColumn = 0; iCol < cCol && iColumn < cColumn; iCol++ ) {
- // Skip columns of type _VECTOR.
- // Probably binary data.
- if ( (pInfo[iCol].wType & DBTYPE_VECTOR) || !m_pColumnLen[iColumn++] ) {
- continue;
- }
-
- // Print caption delimiters
- PrintColumnDelimiter( iColumn-1, (pInfo[iCol].pwszName) ? _tcslen(pInfo[iCol].pwszName) : rgBind[iBind].cbMaxLen/sizeof(TCHAR) );
- }
-
- // Create the accessor.
- hr = pIMDDataset->QueryInterface( IID_IAccessor, (void**) &pIAccessor );
- if ( FAILED(hr) || !pIAccessor )
- goto CLEANUP;
-
- hr = pIAccessor->CreateAccessor( DBACCESSOR_ROWDATA, iBind, rgBind, dwOffset, &hAccessor, NULL );
- if ( FAILED(hr) )
- goto CLEANUP;
-
-
- // Prepare internal buffers and get handles to the rows.
- for ( iCell = 0; iCell < cCell; iCell++) {
- // Populate Cell buffer.
- hr = pIMDDataset->GetCellData( hAccessor,
- iCell,
- iCell,
- pData );
- if ( FAILED(hr) )
- break;
-
- // Print each column we're bound to.
- _tprintf(TEXT("\n"));
-
- for ( iCol = 0, iBind = 0, iColumn = 0; iCol < cCol && iColumn < cColumn; iCol++ ) {
- // Limit to first dwLength characters.
- if ( (pInfo[iCol].wType & DBTYPE_VECTOR) || !m_pColumnLen[iColumn++] ) {
- continue;
- }
-
- pColumn = (COLUMNDATA*) (pData + rgBind[iBind++].obLength);
-
- if ( pColumn->dwStatus == DBSTATUS_S_ISNULL ) {
- PrintColumnString(iColumn-1,TEXT("<null>"));
- }
- else if ( pColumn->dwStatus != DBSTATUS_S_OK &&
- pColumn->dwStatus != DBSTATUS_S_TRUNCATED ) {
- PrintColumnString(iColumn-1,TEXT("<error>"));
- }
- else {
- PrintColumnString(iColumn-1,(LPTSTR) pColumn->bData);
- }
- }
- }
-
- CLEANUP:
- if ( pInfo ) CoTaskMemFree(pInfo);
- if ( pStringsBuffer ) CoTaskMemFree(pStringsBuffer);
-
- if ( rgAxisInfo ) pIMDDataset->FreeAxisInfo( cAxis, rgAxisInfo );
-
- if ( hAccessor != DB_NULL_HACCESSOR ) pIAccessor->ReleaseAccessor( hAccessor, NULL );
-
- if ( pIColumnsInfo ) pIColumnsInfo->Release();
- if ( pIAccessor ) pIAccessor->Release();
-
- return hr;
- }
-
-
- /////////////////////////////////////////////////////////////////////////////////////
- HRESULT OLAPTab::PrintQuery( IMDDataset* pIMDDataset )
-
- // Print
- ///////////////////////////////////////////////////////////////////////////////
- {
- if ( !pIMDDataset ) return E_FAIL;
-
- // Get Axis info
- LONG iAxis, cAxis, iAxisMove, iDim, cDim, iCol;
- MDAXISINFO* rgAxisInfo = NULL;
-
-
- COLUMNDATA* pColumn = NULL;
-
- DBBINDING rgBind[OLAP_APP_MAX_BINDINGS + 1];
- BYTE pData[OLAP_APP_MAX_STRING_LEN + 1];
- ULONG dwOffset = 0;
- ULONG iBind;
-
- ULONG iRowsIndex[OLAP_APP_MAX_BINDINGS + 1];
- ULONG cRowsObtained[OLAP_APP_MAX_BINDINGS + 1];
- HROW* pRows[OLAP_APP_MAX_BINDINGS + 1];
- ULONG iColumn, cColumn, iCell, cCell, iCells = 0;
-
- IAccessor* pIAccessor[OLAP_APP_MAX_BINDINGS + 1];
- IRowset* pIRowset[OLAP_APP_MAX_BINDINGS + 1];
- HACCESSOR hAccessor[OLAP_APP_MAX_BINDINGS + 1];
-
-
- // Init arrays
- memset( pIAccessor, 0, sizeof(pIAccessor) );
- memset( pIRowset, 0, sizeof(pIRowset) );
-
- memset( hAccessor, 0, sizeof(hAccessor) );
-
- memset( iRowsIndex, 0, sizeof(iRowsIndex) );
- memset( cRowsObtained, 0, sizeof(cRowsObtained) );
- memset( pRows, 0, sizeof(pRows) );
-
-
-
- HRESULT hr = pIMDDataset->GetAxisInfo( (ULONG*) &cAxis, &rgAxisInfo );
- if ( FAILED(hr) || !cAxis )
- goto CLEANUP;
-
- // Print slice
- iAxis = cAxis - 1;
- cDim = MDAXISINFO_GETAT(rgAxisInfo,iAxis).cDimensions;
-
- if ( cDim ) {
- hr = pIMDDataset->GetAxisRowset( NULL,
- iAxis,
- IID_IRowset,
- 0,
- NULL,
- (IUnknown**) &pIRowset[iAxis] );
- if ( FAILED(hr) || !pIRowset[iAxis] )
- goto CLEANUP;
-
- for ( iDim = 0, iCol = 2, iBind = 0; iDim < cDim; iDim++ ) {
- // correct for strings.
- rgBind[iBind].iOrdinal = iCol;
- rgBind[iBind].obValue = dwOffset + offsetof(COLUMNDATA,bData);
- rgBind[iBind].obLength = dwOffset + offsetof(COLUMNDATA,dwLength);
- rgBind[iBind].obStatus = dwOffset + offsetof(COLUMNDATA,dwStatus);
- rgBind[iBind].pTypeInfo = NULL;
- rgBind[iBind].pObject = NULL;
- rgBind[iBind].pBindExt = NULL;
- rgBind[iBind].dwFlags = 0;
- rgBind[iBind].eParamIO = DBPARAMIO_NOTPARAM;
- rgBind[iBind].dwPart = DBPART_VALUE | DBPART_LENGTH | DBPART_STATUS;
- rgBind[iBind].dwMemOwner = DBMEMOWNER_CLIENTOWNED;
- rgBind[iBind].bPrecision = 0;
- rgBind[iBind].bScale = 0;
-
- rgBind[iBind].cbMaxLen = OLAP_APP_MAX_COLUMN_STR*sizeof(TCHAR);
- rgBind[iBind].wType = DBTYPE_WSTR;
-
- // Keep our limits
- if ( dwOffset + rgBind[iBind].cbMaxLen + offsetof(COLUMNDATA,bData) > OLAP_APP_MAX_STRING_LEN ||
- iDim == OLAP_APP_MAX_BINDINGS )
- break;
-
- dwOffset += rgBind[iBind].cbMaxLen + offsetof(COLUMNDATA,bData);
- dwOffset = ROUND_UP( dwOffset, COLUMN_ALIGNVAL );
- iBind++;
-
- // Move to first column of next dimension.
- iCol += MDAXISINFO_GETAT(rgAxisInfo,iAxis).rgcColumns[iDim];
- }
-
- // Create the accessor.
- hr = pIRowset[iAxis]->QueryInterface( IID_IAccessor, (void**) &pIAccessor[iAxis] );
- if ( FAILED(hr) || !pIAccessor[iAxis] )
- goto CLEANUP;
-
- hr = pIAccessor[iAxis]->CreateAccessor( DBACCESSOR_ROWDATA, iBind, rgBind, dwOffset, &hAccessor[iAxis], NULL );
- if ( FAILED(hr) )
- goto CLEANUP;
-
-
- // Prepare internal buffers and get handles to the rows.
- hr = pIRowset[iAxis]->GetNextRows( NULL, // hChapter
- 0, // cRowsToSkip
- 1, // cRowsDesired
- &cRowsObtained[iAxis],
- &pRows[iAxis] ); // filled in w/ row handles
- if ( FAILED(hr) || !cRowsObtained[iAxis] || !pRows[iAxis] )
- goto CLEANUP;
-
- // Populate our row buffer.
- hr = pIRowset[iAxis]->GetData( pRows[iAxis][0],
- hAccessor[iAxis],
- pData );
- if ( FAILED(hr) )
- goto CLEANUP;
-
-
- for ( iDim = 0; iDim < cDim; iDim++ ) {
- // Print dimension name,
- _tprintf(TEXT("\n%-16s: "), MDAXISINFO_GETAT(rgAxisInfo,iAxis).rgpwszDimensionNames[iDim]);
-
- // Print member unique name.
- pColumn = (COLUMNDATA*) (pData + rgBind[iDim].obLength);
-
- if ( pColumn->dwStatus == DBSTATUS_S_ISNULL ) {
- _tprintf(TEXT("<null>"));
- }
- else if ( pColumn->dwStatus != DBSTATUS_S_OK &&
- pColumn->dwStatus != DBSTATUS_S_TRUNCATED ) {
- _tprintf(TEXT("<error>"));
- }
- else {
- _tprintf(TEXT("%s"), (LPTSTR) pColumn->bData );
- }
- }
- pIRowset[iAxis]->ReleaseRows( cRowsObtained[iAxis], pRows[iAxis], NULL, NULL, NULL );
- pIAccessor[iAxis]->ReleaseAccessor( hAccessor[iAxis], NULL );
-
- if ( pRows[iAxis] ) CoTaskMemFree(pRows[iAxis]);
-
- cRowsObtained[iAxis] = 0;
- pRows[iAxis] = NULL;
-
- hAccessor[iAxis] = DB_NULL_HACCESSOR;
-
- pIRowset[iAxis]->Release();
- pIRowset[iAxis] = NULL;
-
- pIAccessor[iAxis]->Release();
- pIAccessor[iAxis] = NULL;
- }
-
-
- // Start table
- _tprintf( TEXT("\n\n") );
-
- // Bind axes
- for ( iAxis = cAxis - 2, iColumn = 0; iAxis >= 0; iAxis-- ) {
- // Get Axis schema
- cDim = MDAXISINFO_GETAT(rgAxisInfo,iAxis).cDimensions;
-
- hr = pIMDDataset->GetAxisRowset( NULL,
- iAxis,
- IID_IRowset,
- 0,
- NULL,
- (IUnknown**) &pIRowset[iAxis] );
- if ( FAILED(hr) || !pIRowset[iAxis] )
- goto CLEANUP;
-
- for ( iDim = 0, iCol = 3, iBind = 0, dwOffset = 0; iDim < cDim; iDim++ ) {
- // correct for strings.
- rgBind[iBind].iOrdinal = iCol;
- rgBind[iBind].obValue = dwOffset + offsetof(COLUMNDATA,bData);
- rgBind[iBind].obLength = dwOffset + offsetof(COLUMNDATA,dwLength);
- rgBind[iBind].obStatus = dwOffset + offsetof(COLUMNDATA,dwStatus);
- rgBind[iBind].pTypeInfo = NULL;
- rgBind[iBind].pObject = NULL;
- rgBind[iBind].pBindExt = NULL;
- rgBind[iBind].dwFlags = 0;
- rgBind[iBind].eParamIO = DBPARAMIO_NOTPARAM;
- rgBind[iBind].dwPart = DBPART_VALUE | DBPART_LENGTH | DBPART_STATUS;
- rgBind[iBind].dwMemOwner = DBMEMOWNER_CLIENTOWNED;
- rgBind[iBind].bPrecision = 0;
- rgBind[iBind].bScale = 0;
-
- rgBind[iBind].cbMaxLen = OLAP_APP_MIN_COLUMN_STR*sizeof(TCHAR);
- rgBind[iBind].wType = DBTYPE_WSTR;
-
- // Keep our limits
- if ( dwOffset + rgBind[iBind].cbMaxLen + offsetof(COLUMNDATA,bData) > OLAP_APP_MAX_STRING_LEN ||
- iDim == OLAP_APP_MAX_BINDINGS )
- break;
-
- dwOffset += rgBind[iBind].cbMaxLen + offsetof(COLUMNDATA,bData);
- dwOffset = ROUND_UP( dwOffset, COLUMN_ALIGNVAL );
- iBind++;
-
- // Move to first column of next dimension.
- iCol += MDAXISINFO_GETAT(rgAxisInfo,iAxis).rgcColumns[iDim];
-
- // Print caption for this dimension
- PrintColumnCaption( iColumn++, OLAP_APP_MIN_COLUMN_STR, MDAXISINFO_GETAT(rgAxisInfo,iAxis).rgpwszDimensionNames[iDim] );
- }
-
- // Create the accessor.
- hr = pIRowset[iAxis]->QueryInterface( IID_IAccessor, (void**) &pIAccessor[iAxis] );
- if ( FAILED(hr) || !pIAccessor[iAxis] )
- goto CLEANUP;
-
- hr = pIAccessor[iAxis]->CreateAccessor( DBACCESSOR_ROWDATA, iBind, rgBind, dwOffset, &hAccessor[iAxis], NULL );
- if ( FAILED(hr) )
- goto CLEANUP;
-
- // Move to first record in every axis.
- hr = pIRowset[iAxis]->GetNextRows( NULL, // hChapter
- 0, // cRowsToSkip
- 1, // cRowsDesired
- &cRowsObtained[iAxis],
- &pRows[iAxis] ); // filled in w/ row handles
- if ( FAILED(hr) || !cRowsObtained[iAxis] || !pRows[iAxis] )
- goto CLEANUP;
-
- }
-
-
- // Data bind.
- iAxis = cAxis - 1;
- iBind = 0;
-
- rgBind[iBind].iOrdinal = 2;
- rgBind[iBind].obValue = offsetof(COLUMNDATA,bData);
- rgBind[iBind].obLength = offsetof(COLUMNDATA,dwLength);
- rgBind[iBind].obStatus = offsetof(COLUMNDATA,dwStatus);
- rgBind[iBind].pTypeInfo = NULL;
- rgBind[iBind].pObject = NULL;
- rgBind[iBind].pBindExt = NULL;
- rgBind[iBind].dwFlags = 0;
- rgBind[iBind].eParamIO = DBPARAMIO_NOTPARAM;
- rgBind[iBind].dwPart = DBPART_VALUE | DBPART_LENGTH | DBPART_STATUS;
- rgBind[iBind].dwMemOwner = DBMEMOWNER_CLIENTOWNED;
- rgBind[iBind].bPrecision = 0;
- rgBind[iBind].bScale = 0;
-
- rgBind[iBind].cbMaxLen = OLAP_APP_MIN_COLUMN_STR*sizeof(TCHAR);
- rgBind[iBind].wType = DBTYPE_WSTR;
-
- dwOffset = rgBind[iBind].cbMaxLen + offsetof(COLUMNDATA,bData);
- dwOffset = ROUND_UP( dwOffset, COLUMN_ALIGNVAL );
-
- PrintColumnCaption( iColumn++, OLAP_APP_MIN_COLUMN_STR, TEXT("Value") );
-
- hr = pIMDDataset->QueryInterface( IID_IAccessor, (void**) &pIAccessor[iAxis] );
- if ( FAILED(hr) || !pIAccessor[iAxis] )
- goto CLEANUP;
-
- hr = pIAccessor[iAxis]->CreateAccessor( DBACCESSOR_ROWDATA, 1, rgBind, dwOffset, &hAccessor[iAxis], NULL );
- if ( FAILED(hr) )
- goto CLEANUP;
-
-
-
- // Axis delimeterss.
- _tprintf( TEXT("\n") );
- cColumn = iColumn;
-
- for ( iColumn = 0; iColumn < cColumn - 1; iColumn++ ) {
- PrintColumnDelimiter( iColumn, OLAP_APP_MIN_COLUMN_STR );
- }
- PrintColumnDelimiter( iColumn, 5 );
-
- iAxis = 0;
-
- iCell = 0;
- cCell = MDAXISINFO_GETAT(rgAxisInfo,iAxis).cCoordinates;
-
- iColumn = 0;
-
- // Traverse all cells of query.
- while (TRUE) {
- _tprintf(TEXT("\n"));
-
- for ( iAxis = cAxis - 2; iAxis >= 0; iAxis-- ) {
- // Populate our row buffer.
- hr = pIRowset[iAxis]->GetData( pRows[iAxis][0],
- hAccessor[iAxis],
- pData );
- if ( FAILED(hr) )
- goto CLEANUP;
-
- cDim = MDAXISINFO_GETAT(rgAxisInfo,iAxis).cDimensions;
-
- for ( iDim = 0, dwOffset = 0; iDim < cDim; iDim++ ) {
- // Column data
- pColumn = (COLUMNDATA*) (pData + dwOffset);
-
- if ( iAxis > iAxisMove ) {
- PrintColumnString(iColumn,TEXT(" "));
- }
- else if ( pColumn->dwStatus == DBSTATUS_S_ISNULL ) {
- PrintColumnString(iColumn,TEXT("<null>"));
- }
- else if ( pColumn->dwStatus != DBSTATUS_S_OK &&
- pColumn->dwStatus != DBSTATUS_S_TRUNCATED ) {
- PrintColumnString(iColumn,TEXT("<error>"));
- }
- else {
- PrintColumnString(iColumn,(LPTSTR) pColumn->bData);
- }
- dwOffset += OLAP_APP_MIN_COLUMN_STR*sizeof(TCHAR) + offsetof(COLUMNDATA,bData);
- dwOffset = ROUND_UP( dwOffset, COLUMN_ALIGNVAL );
- }
- }
-
- // Populate Cell buffer.
- hr = pIMDDataset->GetCellData( hAccessor[cAxis - 1],
- iCells,
- iCells,
- pData );
- if ( FAILED(hr) )
- break;
-
- // Print each column we're bound to.
- pColumn = (COLUMNDATA*) pData;
-
- if ( pColumn->dwStatus == DBSTATUS_S_ISNULL ) {
- PrintColumnString(iColumn,TEXT("<null>"));
- }
- else if ( pColumn->dwStatus != DBSTATUS_S_OK &&
- pColumn->dwStatus != DBSTATUS_S_TRUNCATED ) {
- PrintColumnString(iColumn,TEXT("<error>"));
- }
- else {
- PrintColumnString(iColumn,(LPTSTR) pColumn->bData);
- }
-
- // Move to next tuple on current axis.
- for ( iAxisMove = 0; iAxisMove < cAxis - 1; iAxisMove++ ) {
- if ( ++iRowsIndex[iAxisMove] < MDAXISINFO_GETAT(rgAxisInfo,iAxisMove).cCoordinates ) {
- // Free previous record
- pIRowset[iAxisMove]->ReleaseRows( cRowsObtained[iAxisMove], pRows[iAxisMove], NULL, NULL, NULL );
- cRowsObtained[iAxisMove] = 0;
-
- // Next on this axis.
- hr = pIRowset[iAxisMove]->GetNextRows( NULL, // hChapter
- 0, // cRowsToSkip
- 1, // cRowsDesired
- &cRowsObtained[iAxisMove],
- &pRows[iAxisMove] ); // filled in w/ row handles
- if ( FAILED(hr) || !cRowsObtained[iAxisMove] || !pRows[iAxisMove] )
- goto CLEANUP;
- break;
- }
- else {
- // Last axis finish.
- if ( iAxisMove == cAxis - 2 )
- goto CLEANUP;
-
- // Free previous record
- pIRowset[iAxisMove]->ReleaseRows( cRowsObtained[iAxisMove], pRows[iAxisMove], NULL, NULL, NULL );
- cRowsObtained[iAxisMove] = 0;
-
- // Move to next axis.
- hr = pIRowset[iAxisMove]->RestartPosition(0);
- if ( FAILED(hr) )
- goto CLEANUP;
-
- // First on this axis.
- hr = pIRowset[iAxisMove]->GetNextRows( NULL, // hChapter
- 0, // cRowsToSkip
- 1, // cRowsDesired
- &cRowsObtained[iAxisMove],
- &pRows[iAxisMove] ); // filled in w/ row handles
- if ( FAILED(hr) || !cRowsObtained[iAxisMove] || !pRows[iAxisMove] )
- goto CLEANUP;
-
- iRowsIndex[iAxisMove] = 0;
- }
- }
- iCells++;
- }
-
- CLEANUP:
- _tprintf(TEXT("\n\n"));
-
- if ( rgAxisInfo ) pIMDDataset->FreeAxisInfo( cAxis, rgAxisInfo );
-
- for ( iAxis = 0; iAxis < cAxis; iAxis++ ) {
- if ( cRowsObtained[iAxis] ) pIRowset[iAxis]->ReleaseRows( cRowsObtained[iAxis], pRows[iAxis], NULL, NULL, NULL );
-
- if ( hAccessor[iAxis] != DB_NULL_HACCESSOR ) pIAccessor[iAxis]->ReleaseAccessor( hAccessor[iAxis], NULL );
-
- if ( pRows[iAxis] ) CoTaskMemFree(pRows[iAxis]);
-
- if ( pIRowset[iAxis] ) pIRowset[iAxis]->Release();
- if ( pIAccessor[iAxis] ) pIAccessor[iAxis]->Release();
- }
- return hr;
- }
-
-
- /////////////////////////////////////////////////////////////////////////////////////
- HRESULT OLAPTab::PrintError()
-
- // Print error info
- /////////////////////////////////////////////////////////////////////////////////////
- {
- IErrorInfo* pIErrorInfo = NULL;
- IErrorRecords* pIErrorRecords = NULL;
-
- ULONG iRecord, cRecord = 0;
-
- BSTR bstr = NULL;
-
- // Start error report
- _tprintf(TEXT("\nError: "));
-
- HRESULT hr = GetErrorInfo( 0, &pIErrorInfo );
- if ( FAILED(hr) || !pIErrorInfo )
- goto CLEANUP;
-
- hr = pIErrorInfo->QueryInterface( IID_IErrorRecords, (void**) &pIErrorRecords );
- if ( FAILED(hr) || !pIErrorRecords )
- goto CLEANUP;
-
- hr = pIErrorRecords->GetRecordCount(&cRecord);
- if ( FAILED(hr) )
- goto CLEANUP;
-
-
- for ( iRecord=0; iRecord < cRecord; iRecord++ ) {
- if ( pIErrorInfo ) { pIErrorInfo->Release(); pIErrorInfo = NULL; }
-
- hr = pIErrorRecords->GetErrorInfo( iRecord,
- GetUserDefaultLCID(),
- &pIErrorInfo );
- if ( FAILED(hr) || !pIErrorInfo )
- goto CLEANUP;
-
-
- if ( bstr ) { SysFreeString(bstr); bstr = NULL; }
- hr = pIErrorInfo->GetSource(&bstr);
- if ( FAILED(hr) )
- goto CLEANUP;
-
- // Print error info
- _tprintf(TEXT("\n%s;"),bstr);
-
- if ( bstr ) { SysFreeString(bstr); bstr = NULL; }
- hr = pIErrorInfo->GetDescription(&bstr);
- if ( FAILED(hr) )
- goto CLEANUP;
-
- // Print error info
- _tprintf(TEXT("\n%s;"),bstr);
- }
-
- // End error report
- _tprintf(TEXT("\n\n"));
-
- CLEANUP:
- if ( bstr ) SysFreeString(bstr);
-
- if ( pIErrorInfo ) pIErrorInfo->Release();
- if ( pIErrorRecords ) pIErrorRecords->Release();
-
- if ( !cRecord ) {
- _tprintf(TEXT("Unknown!"));
- }
- return hr;
- }
-
-
-
-