Added .cpp and .h files under the sql/src subdirectory
git-svn-id: https://svn.code.sf.net/p/flaim/code/trunk@469 0109f412-320b-0410-ab79-c3e0c5ffbbe6
This commit is contained in:
293
sql/src/flkeyret.cpp
Normal file
293
sql/src/flkeyret.cpp
Normal file
@@ -0,0 +1,293 @@
|
||||
//------------------------------------------------------------------------------
|
||||
// Desc: This file contains the F_Db::keyRetrieve method.
|
||||
//
|
||||
// Tabs: 3
|
||||
//
|
||||
// Copyright (c) 1998-2006 Novell, Inc. All Rights Reserved.
|
||||
//
|
||||
// This program is free software; you can redistribute it and/or
|
||||
// modify it under the terms of version 2 of the GNU General Public
|
||||
// License as published by the Free Software Foundation.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program; if not, contact Novell, Inc.
|
||||
//
|
||||
// To contact Novell about this file by physical or electronic mail,
|
||||
// you may find current contact information at www.novell.com
|
||||
//
|
||||
// $Id: flkeyret.cpp 3113 2006-01-19 13:20:35 -0700 (Thu, 19 Jan 2006) dsanders $
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
#include "flaimsys.h"
|
||||
|
||||
/*****************************************************************************
|
||||
Desc: Retrieves a key from an index.
|
||||
******************************************************************************/
|
||||
RCODE F_Db::keyRetrieve(
|
||||
FLMUINT uiIndex,
|
||||
F_DataVector * pSearchKey,
|
||||
FLMUINT uiFlags,
|
||||
F_DataVector * pFoundKey)
|
||||
{
|
||||
RCODE rc = NE_SFLM_OK;
|
||||
F_INDEX * pIndex = NULL;
|
||||
LFILE * pLFile;
|
||||
FLMBYTE * pucSearchKey = NULL;
|
||||
FLMBYTE * pucFoundKey = NULL;
|
||||
void * pvMark = m_tempPool.poolMark();
|
||||
FLMUINT uiSearchKeyLen = 0;
|
||||
FLMUINT uiFoundKeyLen;
|
||||
FLMUINT uiOriginalFlags;
|
||||
F_Btree * pbtree = NULL;
|
||||
FLMUINT uiDataLen;
|
||||
FLMBOOL bStartedTrans = FALSE;
|
||||
FLMUINT uiIdMatchFlags = uiFlags & FLM_MATCH_ROW_ID;
|
||||
IXKeyCompare compareObject;
|
||||
FLMBOOL bCompareRowId = FALSE;
|
||||
|
||||
// See if the database is being forced to close
|
||||
|
||||
if (RC_BAD( rc = checkState( __FILE__, __LINE__)))
|
||||
{
|
||||
goto Exit;
|
||||
}
|
||||
|
||||
// If we are not in a transaction, we cannot read.
|
||||
|
||||
if (m_eTransType == SFLM_NO_TRANS)
|
||||
{
|
||||
if( RC_BAD( rc = transBegin( SFLM_READ_TRANS)))
|
||||
{
|
||||
goto Exit;
|
||||
}
|
||||
|
||||
bStartedTrans = TRUE;
|
||||
}
|
||||
|
||||
// See if we have a transaction going which should be aborted.
|
||||
|
||||
if( RC_BAD( m_AbortRc))
|
||||
{
|
||||
rc = RC_SET( NE_SFLM_ABORT_TRANS);
|
||||
goto Exit;
|
||||
}
|
||||
|
||||
// Allocate key buffers.
|
||||
|
||||
if (pSearchKey)
|
||||
{
|
||||
if (RC_BAD( rc = m_tempPool.poolAlloc( SFLM_MAX_KEY_SIZE,
|
||||
(void **)&pucSearchKey)))
|
||||
{
|
||||
goto Exit;
|
||||
}
|
||||
}
|
||||
|
||||
if (RC_BAD( rc = m_tempPool.poolAlloc( SFLM_MAX_KEY_SIZE, (void **)&pucFoundKey)))
|
||||
{
|
||||
goto Exit;
|
||||
}
|
||||
|
||||
// Make sure it is a valid index definition
|
||||
|
||||
pIndex = m_pDict->getIndex( uiIndex);
|
||||
|
||||
if (RC_BAD( rc = flushKeys()))
|
||||
{
|
||||
goto Exit;
|
||||
}
|
||||
|
||||
if (uiFlags & FLM_FIRST || (!pSearchKey &&
|
||||
!(uiFlags & FLM_FIRST) && !(uiFlags & FLM_LAST)))
|
||||
{
|
||||
uiOriginalFlags = uiFlags = FLM_FIRST;
|
||||
}
|
||||
else if (uiFlags & FLM_LAST)
|
||||
{
|
||||
uiOriginalFlags = uiFlags = FLM_LAST;
|
||||
}
|
||||
else
|
||||
{
|
||||
uiOriginalFlags = uiFlags;
|
||||
if (uiFlags & FLM_EXACT)
|
||||
{
|
||||
flmAssert( !(uiFlags & FLM_KEY_EXACT));
|
||||
uiFlags = FLM_EXACT;
|
||||
}
|
||||
else if (uiFlags & FLM_EXCL)
|
||||
{
|
||||
uiFlags = FLM_EXCL;
|
||||
}
|
||||
else
|
||||
{
|
||||
uiFlags = FLM_INCL;
|
||||
}
|
||||
|
||||
if (RC_BAD( rc = pSearchKey->outputKey( this, uiIndex, uiIdMatchFlags,
|
||||
pucSearchKey, SFLM_MAX_KEY_SIZE, &uiSearchKeyLen, SEARCH_KEY_FLAG)))
|
||||
{
|
||||
goto Exit;
|
||||
}
|
||||
|
||||
// If we are not matching on the IDs and this is an FLM_EXCL
|
||||
// search, tack on a 0xFF for the IDs, which should get us past
|
||||
// all keys that match. We need to turn on the match IDs flags
|
||||
// in this case so that the comparison routine will match on the
|
||||
// 0xFF.
|
||||
|
||||
if (!uiIdMatchFlags && (uiFlags & FLM_EXCL))
|
||||
{
|
||||
pucSearchKey [uiSearchKeyLen++] = 0xFF;
|
||||
bCompareRowId = TRUE;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (uiIdMatchFlags & FLM_MATCH_ROW_ID)
|
||||
{
|
||||
bCompareRowId = TRUE;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
compareObject.setIxInfo( this, pIndex);
|
||||
compareObject.setCompareRowId( bCompareRowId);
|
||||
compareObject.setSearchKey( pSearchKey);
|
||||
|
||||
// Get a btree
|
||||
|
||||
if (RC_BAD( rc = gv_SFlmSysData.pBtPool->btpReserveBtree( &pbtree)))
|
||||
{
|
||||
goto Exit;
|
||||
}
|
||||
|
||||
if( RC_BAD( rc = pbtree->btOpen( this, pLFile,
|
||||
(pIndex->uiFlags & IXD_ABS_POS)
|
||||
? TRUE
|
||||
: FALSE,
|
||||
(pIndex->pDataIcds)
|
||||
? TRUE
|
||||
: FALSE, &compareObject)))
|
||||
{
|
||||
goto Exit;
|
||||
}
|
||||
|
||||
// Search the for the key
|
||||
|
||||
if (uiSearchKeyLen)
|
||||
{
|
||||
f_memcpy( pucFoundKey, pucSearchKey, uiSearchKeyLen);
|
||||
}
|
||||
uiFoundKeyLen = uiSearchKeyLen;
|
||||
|
||||
if( RC_BAD( rc = pbtree->btLocateEntry(
|
||||
pucFoundKey, SFLM_MAX_KEY_SIZE, &uiFoundKeyLen, uiFlags, NULL,
|
||||
&uiDataLen)))
|
||||
{
|
||||
if (rc == NE_SFLM_EOF_HIT && uiOriginalFlags & FLM_EXACT)
|
||||
{
|
||||
rc = RC_SET( NE_SFLM_NOT_FOUND);
|
||||
}
|
||||
goto Exit;
|
||||
}
|
||||
|
||||
// See if we are in the same key
|
||||
|
||||
if (uiOriginalFlags & FLM_KEY_EXACT)
|
||||
{
|
||||
FLMINT iTmpCmp;
|
||||
|
||||
if (RC_BAD( rc = ixKeyCompare( this, pIndex,
|
||||
pSearchKey, NULL, NULL,
|
||||
(uiIdMatchFlags == FLM_MATCH_ROW_ID) ? TRUE : FALSE,
|
||||
pucFoundKey, uiFoundKeyLen,
|
||||
pucSearchKey, uiSearchKeyLen, &iTmpCmp)))
|
||||
{
|
||||
goto Exit;
|
||||
}
|
||||
|
||||
if (iTmpCmp != 0)
|
||||
{
|
||||
rc = (uiOriginalFlags & (FLM_INCL | FLM_EXCL))
|
||||
? RC_SET( NE_SFLM_EOF_HIT)
|
||||
: RC_SET( NE_SFLM_NOT_FOUND);
|
||||
goto Exit;
|
||||
}
|
||||
}
|
||||
|
||||
// Parse the found key into its individual components
|
||||
|
||||
if (pFoundKey)
|
||||
{
|
||||
pFoundKey->reset();
|
||||
if (RC_BAD( rc = pFoundKey->inputKey( this, uiIndex,
|
||||
pucFoundKey, uiFoundKeyLen)))
|
||||
{
|
||||
goto Exit;
|
||||
}
|
||||
|
||||
// See if there is a data part
|
||||
|
||||
if (pIndex->pDataIcds)
|
||||
{
|
||||
FLMUINT uiDataBufSize;
|
||||
FLMBYTE * pucData;
|
||||
|
||||
// If the data will fit in the search key buffer, just
|
||||
// reuse it since we are not going to do anything with
|
||||
// it after this. Otherwise, allocate a new buffer.
|
||||
|
||||
if (uiDataLen <= SFLM_MAX_KEY_SIZE && pucSearchKey)
|
||||
{
|
||||
uiDataBufSize = SFLM_MAX_KEY_SIZE;
|
||||
pucData = pucSearchKey;
|
||||
}
|
||||
else
|
||||
{
|
||||
uiDataBufSize = uiDataLen;
|
||||
if (RC_BAD( rc = m_tempPool.poolAlloc( uiDataBufSize,
|
||||
(void **)&pucData)))
|
||||
{
|
||||
goto Exit;
|
||||
}
|
||||
}
|
||||
|
||||
// Retrieve the data
|
||||
|
||||
if (RC_BAD( rc = pbtree->btGetEntry(
|
||||
pucFoundKey, SFLM_MAX_KEY_SIZE, uiFoundKeyLen,
|
||||
pucData, uiDataBufSize, &uiDataLen)))
|
||||
{
|
||||
goto Exit;
|
||||
}
|
||||
|
||||
// Parse the data
|
||||
|
||||
if (RC_BAD( rc = pFoundKey->inputData( this, uiIndex,
|
||||
pucData, uiDataLen)))
|
||||
{
|
||||
goto Exit;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Exit:
|
||||
|
||||
m_tempPool.poolReset( pvMark);
|
||||
|
||||
if (pbtree)
|
||||
{
|
||||
gv_SFlmSysData.pBtPool->btpReturnBtree( &pbtree);
|
||||
}
|
||||
|
||||
if( bStartedTrans)
|
||||
{
|
||||
transAbort();
|
||||
}
|
||||
|
||||
return( rc);
|
||||
}
|
||||
Reference in New Issue
Block a user