windows-nt/Source/XPSP1/NT/inetsrv/query/bigtable/tbrowkey.cxx
2020-09-26 16:20:57 +08:00

278 lines
7.6 KiB
C++

//+---------------------------------------------------------------------------
//
// Microsoft Windows
// Copyright (C) Microsoft Corporation, 1995 - 2000.
//
// File: tbrowkey.cxx
//
// Contents:
//
// Classes:
//
// Functions:
//
// History: 2-15-95 srikants Created
//
//----------------------------------------------------------------------------
#include "pch.cxx"
#pragma hdrstop
#include <objcur.hxx>
#include <tableseg.hxx>
CTableRowKey::CTableRowKey( CSortSet const & sortSet )
: _cCols(sortSet.Count()), _sortSet(sortSet),
_acbVariants( _cCols ), _apVariants( _cCols )
{
Win4Assert( sizeof(CInlineVariant) == sizeof(CTableVariant) );
for ( unsigned i = 0; i < _cCols; i++ )
{
_acbVariants[i] = 0;
_apVariants[i] = 0;
}
}
//+---------------------------------------------------------------------------
//
// Method: CTableRowKey ~dtor
//
// Synopsis:
//
// Returns:
//
// Modifies:
//
// History: 2-15-95 srikants Created
//
//----------------------------------------------------------------------------
CTableRowKey::~CTableRowKey()
{
for ( unsigned i = 0; i < _cCols; i++ )
delete [] (BYTE *) _apVariants[i];
}
//+---------------------------------------------------------------------------
//
// Method: CTableRowKey::ReAlloc
//
// Synopsis: Reallocates memory for the indicated column. Note that
// the old contents may be tossed out.
//
// Arguments: [i] - The column for which reallocation is needed.
// [vt] - Variant type of the variant
// [cb] - Number of bytes needed for the variant.
//
// History: 2-15-95 srikants Created
//
//----------------------------------------------------------------------------
void CTableRowKey::ReAlloc( unsigned i, VARTYPE vt, unsigned cb )
{
Win4Assert( i < _cCols );
const ULONG cbHeader = sizeof(CInlineVariant);
ULONG cbTotal = cb;
Win4Assert( cbTotal >= cbHeader );
if ( _acbVariants[i] < cbTotal )
{
delete [] (BYTE *) _apVariants[i];
_apVariants[i] = 0;
_acbVariants[i] = 0;
ULONG cbToAlloc = cbTotal;
_apVariants[i] = (CInlineVariant *) new BYTE [cbToAlloc];
_acbVariants[i] = cbToAlloc;
}
}
//+---------------------------------------------------------------------------
//
// Method: CTableRowKey::Init
//
// Synopsis: Initialized the column "i" with the source variant.
//
// Arguments: [i] - Column to be initialized.
// [src] - Source variant
// [pbSrcBias] - Bais of the data allocation in the source
// variant.
//
// History: 2-15-95 srikants Created
//
//----------------------------------------------------------------------------
void CTableRowKey::Init( unsigned i, CTableVariant & src, BYTE * pbSrcBias )
{
Win4Assert( i < _cCols );
const ULONG cbHeader = sizeof(CInlineVariant);
ULONG cbVarData = src.VarDataSize();
ULONG cbTotal = cbVarData + cbHeader;
if ( _acbVariants[i] < cbTotal )
ReAlloc( i, src.vt, cbTotal );
Win4Assert( _acbVariants[i] >= cbTotal );
Win4Assert( _acbVariants[i]-cbHeader >= cbVarData );
CVarBufferAllocator bufAlloc( _apVariants[i]->GetVarBuffer(), cbVarData );
bufAlloc.SetBase(0);
src.Copy( _apVariants[i], bufAlloc, (USHORT) cbVarData, pbSrcBias );
}
//+---------------------------------------------------------------------------
//
// Function: assignemnt operator
//
// Synopsis: Copies the contents of the source bucket row into this.
//
// Arguments: [src] - The source bucket row.
//
// Returns: A reference to this bucket row.
//
// History: 2-15-95 srikants Created
//
//----------------------------------------------------------------------------
CTableRowKey & CTableRowKey::operator=( CTableRowKey & src )
{
Win4Assert( src._cCols == _cCols );
for ( unsigned i = 0; i < _cCols; i++ )
Init( i, *(src._apVariants[i]) );
return *this;
}
//+---------------------------------------------------------------------------
//
// Method: CTableRowKey::PreSet
//
// Synopsis: Get ready for use later.
//
// Arguments: [pObj] - value retriever for the object
// [pInfoSortKey] - sort info
//
// History: 8-20-98 dlee Created
//
//----------------------------------------------------------------------------
void CTableRowKey::PreSet(
CRetriever * pObj,
XArray<VARTYPE> * pInfoSortKey )
{
_pObj = pObj;
_pVarType = pInfoSortKey;
} //PreSet
//+---------------------------------------------------------------------------
//
// Method: CTableRowKey::MakeReady
//
// Synopsis: Retrieves the sort key values
//
// History: 8-20-98 dlee Created
//
//----------------------------------------------------------------------------
void CTableRowKey::MakeReady()
{
Set( *_pObj, *_pVarType );
} //MakeReady
//+---------------------------------------------------------------------------
//
// Method: CTableRowKey::Set
//
// Synopsis: Given a "row" and the "obj" for a row, it
// fills the "row" with the data from the "obj". It retrieves
// only the columns in the sort key.
//
// Arguments: [row] - The row to fill
// [obj] - Retriever for the columns.
//
// History: 2-15-95 srikants Created
//
//----------------------------------------------------------------------------
void CTableRowKey::Set( CRetriever & obj, XArray<VARTYPE> & vtInfoSortKey )
{
Win4Assert( _sortSet.Count() == _cCols );
for ( ULONG i = 0; i < _cCols; i++ )
{
SSortKey & key = _sortSet.Get(i);
PROPID pid = key.pidColumn;
ULONG cbVarnt;
CTableVariant * pvarnt = Get(i, cbVarnt);
GetValueResult eGvr;
VARTYPE vt = vtInfoSortKey.Get()[i];
if ( 0 == pvarnt )
{
//
// This is the first time we are setting the value of this
// variant. Determine its type and allocate the optimum amount
// of memory.
//
CTableVariant varnt;
cbVarnt = sizeof(varnt);
pvarnt = &varnt;
eGvr = obj.GetPropertyValue( pid, pvarnt, &cbVarnt );
if ( GVRSuccess != eGvr &&
GVRNotEnoughSpace != eGvr &&
GVRSharingViolation != eGvr )
{
if ( eGvr == GVRNotSupported || eGvr == GVRNotAvailable )
{
THROW( CException( QUERY_E_INVALIDSORT ) );
}
else
{
THROW( CException(CRetriever::NtStatusFromGVR(eGvr)) );
}
}
if ( ( GVRSharingViolation == eGvr ) ||
( 0 == cbVarnt ) )
cbVarnt = sizeof varnt;
ReAlloc( i, vt, cbVarnt );
pvarnt = Get( i, cbVarnt );
}
Win4Assert( 0 != pvarnt );
eGvr = obj.GetPropertyValue( pid, pvarnt, &cbVarnt );
if ( GVRNotEnoughSpace == eGvr )
{
//
// This path should be executed very rarely because for strings
// we over-allocate the memory and for "fixed" length variants
// the correct length must have been allocated the first time.
//
ReAlloc( i, vt, cbVarnt );
pvarnt = Get( i, cbVarnt );
eGvr = obj.GetPropertyValue( pid, pvarnt, &cbVarnt );
}
if ( GVRSharingViolation == eGvr )
pvarnt->vt = VT_EMPTY;
else if ( GVRSuccess != eGvr )
THROW( CException(CRetriever::NtStatusFromGVR(eGvr)) );
}
} //Set