git-svn-id: https://svn.code.sf.net/p/flaim/code/trunk@643 0109f412-320b-0410-ab79-c3e0c5ffbbe6
8492 lines
186 KiB
C++
8492 lines
186 KiB
C++
//------------------------------------------------------------------------------
|
|
// Desc: This is the master header file for FLAIM. It is included by nearly
|
|
// all of the source files.
|
|
//
|
|
// Tabs: 3
|
|
//
|
|
// Copyright (c) 1991-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: flaimsys.h 3108 2006-01-19 13:05:19 -0700 (Thu, 19 Jan 2006) dsanders $
|
|
//------------------------------------------------------------------------------
|
|
|
|
#ifndef FLAIMSYS_H
|
|
#define FLAIMSYS_H
|
|
|
|
// Public includes
|
|
|
|
#include "xflaim.h"
|
|
|
|
#ifdef HAVE_CONFIG_H
|
|
#include "../config.h"
|
|
#endif
|
|
|
|
#if defined( FLM_WIN)
|
|
// Conversion from XXX to YYY, possible loss of data
|
|
#pragma warning( disable : 4244)
|
|
|
|
// Local variable XXX may be used without having been initialized
|
|
#pragma warning( disable : 4701)
|
|
|
|
// Function XXX not inlined
|
|
#pragma warning( disable : 4710)
|
|
#endif
|
|
|
|
#if defined( FLM_WATCOM_NLM)
|
|
|
|
// Disable "Warning! W549: col(XX) 'sizeof' operand contains
|
|
// compiler generated information"
|
|
|
|
#pragma warning 549 9
|
|
#endif
|
|
|
|
// Put all forward references here
|
|
|
|
class F_Database;
|
|
class F_Dict;
|
|
class F_Db;
|
|
class F_NameTable;
|
|
class F_IOBuffer;
|
|
class F_Rfl;
|
|
class F_Btree;
|
|
class F_DOMNode;
|
|
class F_NodeList;
|
|
class F_Query;
|
|
class F_DbRebuild;
|
|
class F_DbCheck;
|
|
class F_DbInfo;
|
|
class F_KeyCollector;
|
|
class FSIndexCursor;
|
|
class FSCollectionCursor;
|
|
class F_CachedBlock;
|
|
class F_CachedNode;
|
|
class F_GlobalCacheMgr;
|
|
class F_BlockCacheMgr;
|
|
class F_NodeCacheMgr;
|
|
class F_NodeBufferIStream;
|
|
class F_BTreeIStream;
|
|
class F_QueryResultSet;
|
|
class F_BTreeInfo;
|
|
class F_AttrItem;
|
|
class F_NodeVerifier;
|
|
class F_RebuildNodeIStream;
|
|
|
|
// Internal includes
|
|
|
|
#include "fcollate.h"
|
|
#include "fdict.h"
|
|
#include "fxml.h"
|
|
#include "fstructs.h"
|
|
#include "fcache.h"
|
|
#include "flmstat.h"
|
|
#include "fxpath.h"
|
|
#include "fbtrset.h"
|
|
#include "fquery.h"
|
|
#include "fcollate.h"
|
|
#include "f_btree.h"
|
|
#include "f_btpool.h"
|
|
#include "rfl.h"
|
|
#include "filesys.h"
|
|
#include "flog.h"
|
|
#include "f_nici.h"
|
|
|
|
RCODE MapErrnoToFlaimErr(
|
|
int err,
|
|
RCODE defaultRc);
|
|
|
|
// Misc. global constants
|
|
|
|
#ifdef DEFINE_NUMBER_MAXIMUMS
|
|
#define GV_EXTERN
|
|
#else
|
|
#define GV_EXTERN extern
|
|
#endif
|
|
|
|
GV_EXTERN FLMBOOL gv_b32BitPlatform
|
|
#ifdef DEFINE_NUMBER_MAXIMUMS
|
|
= (FLMBOOL)(sizeof( FLMUINT) == 4 ? TRUE : FALSE)
|
|
#endif
|
|
;
|
|
|
|
GV_EXTERN FLMUINT gv_uiMaxUInt32Val
|
|
#ifdef DEFINE_NUMBER_MAXIMUMS
|
|
= (FLMUINT)0xFFFFFFFF
|
|
#endif
|
|
;
|
|
|
|
GV_EXTERN FLMUINT gv_uiMaxUIntVal
|
|
#ifdef DEFINE_NUMBER_MAXIMUMS
|
|
= (FLMUINT)(~(FLMUINT)0)
|
|
#endif
|
|
;
|
|
|
|
GV_EXTERN FLMUINT gv_uiMaxSignedIntVal
|
|
#ifdef DEFINE_NUMBER_MAXIMUMS
|
|
= (FLMUINT)((((~(FLMUINT)0) << 1) >> 1))
|
|
#endif
|
|
;
|
|
|
|
GV_EXTERN FLMUINT64 gv_ui64MaxSignedIntVal
|
|
#ifdef DEFINE_NUMBER_MAXIMUMS
|
|
= (FLMUINT64)((((~(FLMUINT64)0) << 1) >> 1))
|
|
#endif
|
|
;
|
|
|
|
GV_EXTERN F_DbSystem * gv_pXFlmDbSystem
|
|
#ifdef DEFINE_NUMBER_MAXIMUMS
|
|
= NULL
|
|
#endif
|
|
;
|
|
|
|
// A global module lock allows us to properly implement DllCanUnloadNow
|
|
// This is only used in a COM environment. The functions are actually
|
|
// defined in fdllmain.cpp
|
|
|
|
extern void LockModule(void);
|
|
extern void UnlockModule(void);
|
|
|
|
#define MAX_DIRTY_NODES_THRESHOLD 1024
|
|
#define MAX_DOM_HEADER_SIZE 118
|
|
#define FIXED_DOM_HEADER_SIZE 94
|
|
#define XFLM_FIXED_SIZE_HEADER_TOKEN 0xFF
|
|
|
|
// NOTE: ENCRYPT_MIN_CHUNK_SIZE should always be a power of 2
|
|
// getEncLen supposes that it is.
|
|
|
|
#define ENCRYPT_MIN_CHUNK_SIZE 16
|
|
#define ENCRYPT_BOUNDARY_MASK (~(ENCRYPT_MIN_CHUNK_SIZE - 1))
|
|
|
|
/*****************************************************************************
|
|
Desc:
|
|
******************************************************************************/
|
|
FINLINE RCODE convertToUINT(
|
|
FLMUINT64 ui64Num,
|
|
FLMBOOL bNeg,
|
|
FLMUINT * puiNum)
|
|
{
|
|
if( bNeg)
|
|
{
|
|
return( RC_SET( NE_XFLM_CONV_NUM_UNDERFLOW));
|
|
}
|
|
|
|
if( gv_b32BitPlatform && ui64Num > 0xFFFFFFFF)
|
|
{
|
|
return( RC_SET( NE_XFLM_CONV_NUM_OVERFLOW));
|
|
}
|
|
|
|
*puiNum = (FLMUINT)ui64Num;
|
|
return( NE_XFLM_OK);
|
|
}
|
|
|
|
/*****************************************************************************
|
|
Desc:
|
|
******************************************************************************/
|
|
FINLINE RCODE convertToUINT32(
|
|
FLMUINT64 ui64Num,
|
|
FLMBOOL bNeg,
|
|
FLMUINT32 * pui32Num)
|
|
{
|
|
if( bNeg)
|
|
{
|
|
return( RC_SET( NE_XFLM_CONV_NUM_UNDERFLOW));
|
|
}
|
|
|
|
if( ui64Num > 0xFFFFFFFF)
|
|
{
|
|
return( RC_SET( NE_XFLM_CONV_NUM_OVERFLOW));
|
|
}
|
|
|
|
*pui32Num = (FLMUINT32)ui64Num;
|
|
return( NE_XFLM_OK);
|
|
}
|
|
|
|
/*****************************************************************************
|
|
Desc:
|
|
******************************************************************************/
|
|
FINLINE RCODE convertToUINT64(
|
|
FLMUINT64 ui64Num,
|
|
FLMBOOL bNeg,
|
|
FLMUINT64 * pui64Num)
|
|
{
|
|
if( bNeg)
|
|
{
|
|
return( RC_SET( NE_XFLM_CONV_NUM_UNDERFLOW));
|
|
}
|
|
|
|
*pui64Num = ui64Num;
|
|
return( NE_XFLM_OK);
|
|
}
|
|
|
|
/*****************************************************************************
|
|
Desc:
|
|
******************************************************************************/
|
|
FINLINE RCODE convertToINT(
|
|
FLMUINT64 ui64Num,
|
|
FLMBOOL bNeg,
|
|
FLMINT * piNum)
|
|
{
|
|
if( bNeg)
|
|
{
|
|
if (ui64Num == (FLMUINT64)(FLM_MAX_INT) + 1)
|
|
{
|
|
*piNum = FLM_MIN_INT;
|
|
}
|
|
else if( ui64Num > (FLMUINT64)(FLM_MAX_INT) + 1)
|
|
{
|
|
return( RC_SET( NE_XFLM_CONV_NUM_UNDERFLOW));
|
|
}
|
|
else
|
|
{
|
|
*piNum = -((FLMINT)ui64Num);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if( ui64Num > (FLMUINT64)FLM_MAX_INT)
|
|
{
|
|
return( RC_SET( NE_XFLM_CONV_NUM_OVERFLOW));
|
|
}
|
|
|
|
*piNum = (FLMINT)ui64Num;
|
|
}
|
|
|
|
return( NE_XFLM_OK);
|
|
}
|
|
|
|
/*****************************************************************************
|
|
Desc:
|
|
******************************************************************************/
|
|
FINLINE RCODE convertToINT32(
|
|
FLMUINT64 ui64Num,
|
|
FLMBOOL bNeg,
|
|
FLMINT32 * pi32Num)
|
|
{
|
|
if( bNeg)
|
|
{
|
|
if (ui64Num == (FLMUINT64)(FLM_MAX_INT32) + 1)
|
|
{
|
|
*pi32Num = FLM_MIN_INT32;
|
|
}
|
|
else if( ui64Num > (FLMUINT64)(FLM_MAX_INT32) + 1)
|
|
{
|
|
return( RC_SET( NE_XFLM_CONV_NUM_UNDERFLOW));
|
|
}
|
|
else
|
|
{
|
|
*pi32Num = -((FLMINT32)ui64Num);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if( ui64Num > (FLMUINT64)FLM_MAX_INT32)
|
|
{
|
|
return( RC_SET( NE_XFLM_CONV_NUM_OVERFLOW));
|
|
}
|
|
|
|
*pi32Num = (FLMINT32)ui64Num;
|
|
}
|
|
|
|
return( NE_XFLM_OK);
|
|
}
|
|
|
|
/*****************************************************************************
|
|
Desc:
|
|
******************************************************************************/
|
|
FINLINE RCODE convertToINT64(
|
|
FLMUINT64 ui64Num,
|
|
FLMBOOL bNeg,
|
|
FLMINT64 * pi64Num)
|
|
{
|
|
if( bNeg)
|
|
{
|
|
if( ui64Num > gv_ui64MaxSignedIntVal + 1)
|
|
{
|
|
return( RC_SET( NE_XFLM_CONV_NUM_UNDERFLOW));
|
|
}
|
|
|
|
*pi64Num = -(FLMINT64)ui64Num;
|
|
}
|
|
else
|
|
{
|
|
if( ui64Num > gv_ui64MaxSignedIntVal)
|
|
{
|
|
return( RC_SET( NE_XFLM_CONV_NUM_OVERFLOW));
|
|
}
|
|
|
|
*pi64Num = (FLMINT64)ui64Num;
|
|
}
|
|
|
|
return( NE_XFLM_OK);
|
|
}
|
|
|
|
/*****************************************************************************
|
|
Desc: Calculate the number of bytes extra there are beyond the closest
|
|
encryption boundary.
|
|
******************************************************************************/
|
|
FINLINE FLMUINT extraEncBytes(
|
|
FLMUINT uiDataLen)
|
|
{
|
|
// This works if ENCRYPT_MIN_CHUNK_SIZE is a power of 2
|
|
// Otherwise, it needs to be changed to uiDataLen % ENCRYPT_MIN_CHUNK_SIZE
|
|
|
|
return( uiDataLen & (ENCRYPT_MIN_CHUNK_SIZE - 1));
|
|
}
|
|
|
|
/*****************************************************************************
|
|
Desc: Calculate the encryption length for a piece of data.
|
|
******************************************************************************/
|
|
FINLINE FLMUINT getEncLen(
|
|
FLMUINT uiDataLen)
|
|
{
|
|
return( extraEncBytes( uiDataLen)
|
|
? ((uiDataLen + ENCRYPT_MIN_CHUNK_SIZE) & ENCRYPT_BOUNDARY_MASK)
|
|
: uiDataLen);
|
|
}
|
|
|
|
/*============================================================================
|
|
Some simple inline functions for dealing with tag numbers
|
|
============================================================================*/
|
|
|
|
FINLINE FLMBOOL elementIsUserDefined(
|
|
FLMUINT uiNum)
|
|
{
|
|
return( uiNum <= XFLM_MAX_ELEMENT_NUM ? TRUE : FALSE);
|
|
}
|
|
|
|
FINLINE FLMBOOL attributeIsUserDefined(
|
|
FLMUINT uiNum)
|
|
{
|
|
return( uiNum <= XFLM_MAX_ATTRIBUTE_NUM ? TRUE : FALSE);
|
|
}
|
|
|
|
FINLINE FLMBOOL elementIsReservedTag(
|
|
FLMUINT uiNum)
|
|
{
|
|
return( uiNum >= XFLM_FIRST_RESERVED_ELEMENT_TAG &&
|
|
uiNum <= XFLM_LAST_RESERVED_ELEMENT_TAG ? TRUE : FALSE);
|
|
}
|
|
|
|
FINLINE FLMBOOL attributeIsReservedTag(
|
|
FLMUINT uiNum)
|
|
{
|
|
return( uiNum >= XFLM_FIRST_RESERVED_ATTRIBUTE_TAG &&
|
|
uiNum <= XFLM_LAST_RESERVED_ATTRIBUTE_TAG ? TRUE : FALSE);
|
|
}
|
|
|
|
/****************************************************************************
|
|
Stuff for F_NameTable class
|
|
****************************************************************************/
|
|
|
|
typedef struct FlmTagInfoTag
|
|
{
|
|
FLMUINT uiType;
|
|
FLMUNICODE * puzTagName;
|
|
FLMUINT uiTagNum;
|
|
FLMUINT uiDataType;
|
|
FLMUNICODE * puzNamespace;
|
|
} FLM_TAG_INFO;
|
|
|
|
/****************************************************************************
|
|
Desc: Class for name/number lookup.
|
|
****************************************************************************/
|
|
class F_NameTable : public F_Object
|
|
{
|
|
public:
|
|
|
|
F_NameTable();
|
|
|
|
~F_NameTable();
|
|
|
|
void clearTable(
|
|
FLMUINT uiPoolBlkSize);
|
|
|
|
RCODE addReservedDictTags( void);
|
|
|
|
RCODE getNextTagTypeAndNumOrder(
|
|
FLMUINT uiType,
|
|
FLMUINT * puiNextPos,
|
|
FLMUNICODE * puzTagName = NULL,
|
|
char * pszTagName = NULL,
|
|
FLMUINT uiNameBufSize = 0,
|
|
FLMUINT * puiTagNum = NULL,
|
|
FLMUINT * puiDataType = NULL,
|
|
FLMUNICODE * puzNamespace = NULL,
|
|
FLMUINT uiNamespaceBufSize = 0,
|
|
FLMBOOL bTruncatedNamesOk = TRUE);
|
|
|
|
RCODE getNextTagTypeAndNameOrder(
|
|
FLMUINT uiType,
|
|
FLMUINT * puiNextPos,
|
|
FLMUNICODE * puzTagName = NULL,
|
|
char * pszTagName = NULL,
|
|
FLMUINT uiNameBufSize = 0,
|
|
FLMUINT * puiTagNum = NULL,
|
|
FLMUINT * puiDataType = NULL,
|
|
FLMUNICODE * puzNamespace = NULL,
|
|
FLMUINT uiNamespaceBufSize = 0,
|
|
FLMBOOL bTruncatedNamesOk = TRUE);
|
|
|
|
RCODE getFromTagTypeAndName(
|
|
F_Db * pDb,
|
|
FLMUINT uiType,
|
|
const FLMUNICODE * puzTagName,
|
|
const char * pszTagName,
|
|
FLMBOOL bMatchNamespace,
|
|
const FLMUNICODE * puzNamespace = NULL,
|
|
FLMUINT * puiTagNum = NULL,
|
|
FLMUINT * puiDataType = NULL);
|
|
|
|
RCODE getFromTagTypeAndNum(
|
|
F_Db * pDb,
|
|
FLMUINT uiType,
|
|
FLMUINT uiTagNum,
|
|
FLMUNICODE * puzTagName = NULL,
|
|
char * pszTagName = NULL,
|
|
FLMUINT * puiNameBufSize = NULL,
|
|
FLMUINT * puiDataType = NULL,
|
|
FLMUNICODE * puzNamespace = NULL,
|
|
char * pszNamespace = NULL,
|
|
FLMUINT * puiNamespaceBufSize = NULL,
|
|
FLMBOOL bTruncatedNamesOk = TRUE);
|
|
|
|
RCODE addTag(
|
|
FLMUINT uiType,
|
|
FLMUNICODE * puzTagName,
|
|
const char * pszTagName,
|
|
FLMUINT uiTagNum,
|
|
FLMUINT uiDataType = 0,
|
|
FLMUNICODE * puzNamespace = NULL,
|
|
FLMBOOL bCheckDuplicates = TRUE,
|
|
FLMBOOL bLimitNumToLoad = TRUE);
|
|
|
|
void sortTags( void);
|
|
|
|
void removeTag(
|
|
FLMUINT uiType,
|
|
FLMUINT uiTagNum);
|
|
|
|
RCODE cloneNameTable(
|
|
F_NameTable * pSrcNameTable);
|
|
|
|
RCODE importFromNameTable(
|
|
F_NameTable * pSrcNameTable);
|
|
|
|
FINLINE FLMBOOL haveAllElements( void)
|
|
{
|
|
return m_bLoadedAllElements;
|
|
}
|
|
|
|
FINLINE FLMBOOL haveAllAttributes( void)
|
|
{
|
|
return m_bLoadedAllAttributes;
|
|
}
|
|
|
|
virtual FLMINT FLMAPI AddRef( void);
|
|
|
|
virtual FLMINT FLMAPI Release( void);
|
|
|
|
private:
|
|
|
|
RCODE allocTag(
|
|
FLMUINT uiType,
|
|
FLMUNICODE * puzTagName,
|
|
const char * pszTagName,
|
|
FLMUINT uiTagNum,
|
|
FLMUINT uiDataType,
|
|
FLMUNICODE * puzNamespace,
|
|
FLM_TAG_INFO ** ppTagInfo);
|
|
|
|
RCODE reallocSortTables(
|
|
FLMUINT uiNewTblSize);
|
|
|
|
RCODE copyTagName(
|
|
FLMUNICODE * puzDestTagName,
|
|
char * pszDestTagName,
|
|
FLMUINT * puiDestBufSize,
|
|
FLMUNICODE * puzSrcTagName,
|
|
FLMBOOL bTruncatedNamesOk);
|
|
|
|
FLM_TAG_INFO * findTagByTypeAndNum(
|
|
FLMUINT uiType,
|
|
FLMUINT uiTagNum,
|
|
FLMUINT * puiInsertPos = NULL);
|
|
|
|
FLM_TAG_INFO * findTagByTypeAndName(
|
|
FLMUINT uiType,
|
|
const FLMUNICODE * puzTagName,
|
|
const char * pszTagName,
|
|
FLMBOOL bMatchNamespace,
|
|
const FLMUNICODE * puzNamespace,
|
|
FLMBOOL * pbAmbiguous,
|
|
FLMUINT * puiInsertPos = NULL);
|
|
|
|
RCODE insertTagInTables(
|
|
FLM_TAG_INFO * pTagInfo,
|
|
FLMUINT uiTagTypeAndNameTblInsertPos,
|
|
FLMUINT uiTagTypeAndNumTblInsertPos);
|
|
|
|
FLMUNICODE * findNamespace(
|
|
FLMUNICODE * puzNamespace,
|
|
FLMUINT * puiInsertPos);
|
|
|
|
RCODE insertNamespace(
|
|
FLMUNICODE * puzNamespace,
|
|
FLMUINT uiInsertPos);
|
|
|
|
F_Pool m_pool;
|
|
FLMUINT m_uiMemoryAllocated;
|
|
FLM_TAG_INFO ** m_ppSortedByTagTypeAndName;
|
|
FLM_TAG_INFO ** m_ppSortedByTagTypeAndNum;
|
|
FLMUINT m_uiTblSize;
|
|
FLMUINT m_uiNumTags;
|
|
FLMBOOL m_bTablesSorted;
|
|
FLMBOOL m_bLoadedAllElements;
|
|
FLMBOOL m_bLoadedAllAttributes;
|
|
FLMUINT m_uiNumElementsLoaded;
|
|
FLMUINT m_uiNumAttributesLoaded;
|
|
FLMUNICODE ** m_ppuzNamespaces;
|
|
FLMUINT m_uiNamespaceTblSize;
|
|
FLMUINT m_uiNumNamespaces;
|
|
|
|
friend class F_Db;
|
|
};
|
|
|
|
/****************************************************************************
|
|
Storage conversion functions.
|
|
****************************************************************************/
|
|
|
|
#define FLM_MAX_NUM_BUF_SIZE 9
|
|
|
|
RCODE flmStorage2Number(
|
|
FLMUINT uiType,
|
|
FLMUINT uiBufLen,
|
|
const FLMBYTE * pucBuf,
|
|
FLMUINT * puiNum,
|
|
FLMINT * piNum);
|
|
|
|
RCODE flmStorage2Number64(
|
|
FLMUINT uiType,
|
|
FLMUINT uiBufLen,
|
|
const FLMBYTE * pucBuf,
|
|
FLMUINT64 * pui64Num,
|
|
FLMINT64 * pi64Num);
|
|
|
|
RCODE flmNumber64ToStorage(
|
|
FLMUINT64 ui64Num,
|
|
FLMUINT * puiBufLen,
|
|
FLMBYTE * pucBuf,
|
|
FLMBOOL bNegative,
|
|
FLMBOOL bCollation);
|
|
|
|
RCODE FlmUINT2Storage(
|
|
FLMUINT uiNum,
|
|
FLMUINT * puiBufLen,
|
|
FLMBYTE * pucBuf);
|
|
|
|
RCODE FlmINT2Storage(
|
|
FLMINT iNum,
|
|
FLMUINT * puiBufLen,
|
|
FLMBYTE * pucBuf);
|
|
|
|
RCODE flmUTF8ToStorage(
|
|
const FLMBYTE * pucUTF8,
|
|
FLMUINT uiBytesInBuffer,
|
|
FLMBYTE * pucBuf,
|
|
FLMUINT * puiBufLength);
|
|
|
|
RCODE flmGetCharCountFromStorageBuf(
|
|
const FLMBYTE ** ppucBuf,
|
|
FLMUINT uiBufSize,
|
|
FLMUINT * puiNumChars,
|
|
FLMUINT * puiSenLen = NULL);
|
|
|
|
RCODE flmStorage2UTF8(
|
|
FLMUINT uiType,
|
|
FLMUINT uiBufLength,
|
|
const FLMBYTE * pucBuffer,
|
|
FLMUINT * puiOutBufLen,
|
|
FLMBYTE * pucOutBuf);
|
|
|
|
RCODE flmStorage2Unicode(
|
|
FLMUINT uiType,
|
|
FLMUINT uiBufLength,
|
|
const FLMBYTE * pucBuffer,
|
|
FLMUINT * puiOutBufLen,
|
|
void * pOutBuf);
|
|
|
|
RCODE flmStorage2Unicode(
|
|
FLMUINT uiType,
|
|
FLMUINT uiStorageLength,
|
|
const FLMBYTE * pucStorageBuffer,
|
|
F_DynaBuf * pBuffer);
|
|
|
|
RCODE flmUnicode2Storage(
|
|
const FLMUNICODE * puzStr,
|
|
FLMUINT uiStrLen,
|
|
FLMBYTE * pucBuf,
|
|
FLMUINT * puiBufLength,
|
|
FLMUINT * puiCharCount);
|
|
|
|
RCODE flmStorageNum2StorageText(
|
|
const FLMBYTE * pucNum,
|
|
FLMUINT uiNumLen,
|
|
FLMBYTE * pucBuffer,
|
|
FLMUINT * puiBufLen);
|
|
|
|
/****************************************************************************
|
|
Desc: Returns the size of buffer needed to hold the unicode string in
|
|
FLAIM's storage format.
|
|
****************************************************************************/
|
|
FINLINE RCODE FlmGetUnicodeStorageLength(
|
|
FLMUNICODE * puzStr,
|
|
FLMUINT * puiByteCount)
|
|
{
|
|
FLMUINT uiByteCount;
|
|
RCODE rc;
|
|
|
|
if( RC_BAD( rc = flmUnicode2Storage( puzStr, 0, NULL,
|
|
&uiByteCount, NULL)))
|
|
{
|
|
return( rc);
|
|
}
|
|
|
|
*puiByteCount = uiByteCount + sizeof( FLMUNICODE);
|
|
return( NE_XFLM_OK);
|
|
}
|
|
|
|
/****************************************************************************
|
|
Desc: Copies and formats a Unicode string into FLAIM's storage format.
|
|
The Unicode string must be in little-endian byte order.
|
|
Unicode values that are not represented as WordPerfect 6.x characters
|
|
are preserved as non-WP characters.
|
|
****************************************************************************/
|
|
FINLINE RCODE FlmUnicode2Storage(
|
|
FLMUNICODE * puzStr,
|
|
FLMUINT * puiBufLength, // [IN] size of pBuf,
|
|
// [OUT] amount of pBuf used to hold puzStr
|
|
FLMBYTE * pBuf)
|
|
{
|
|
return( flmUnicode2Storage( puzStr, 0, pBuf, puiBufLength, NULL));
|
|
}
|
|
|
|
/****************************************************************************
|
|
Desc: Converts from FLAIM's internal storage format to a Unicode string
|
|
****************************************************************************/
|
|
FINLINE RCODE FlmStorage2Unicode(
|
|
FLMUINT uiType,
|
|
FLMUINT uiBufLength,
|
|
FLMBYTE * pBuffer,
|
|
FLMUINT * puiOutBufLen,
|
|
FLMUNICODE * puzOutBuf)
|
|
{
|
|
return( flmStorage2Unicode( uiType, uiBufLength, pBuffer,
|
|
puiOutBufLen, puzOutBuf));
|
|
}
|
|
|
|
/****************************************************************************
|
|
Desc: Convert storage text into a null-terminated UTF-8 string
|
|
****************************************************************************/
|
|
FINLINE RCODE FlmStorage2UTF8(
|
|
FLMUINT uiType,
|
|
FLMUINT uiBufLength,
|
|
FLMBYTE * pBuffer,
|
|
FLMUINT * puiOutBufLenRV,
|
|
// [IN] Specified the number of bytes available in buffer.
|
|
// [OUT] Returns the number of bytes of UTF-8 text. This value
|
|
// does not include a terminating NULL byte in the buffer.
|
|
FLMBYTE * pOutBuffer)
|
|
// [OUT] The buffer that will hold the output UTF-8 text.
|
|
// If this value is NULL then only bufLenRV will computed so that
|
|
// the caller may know how many bytes to allocate for a buffer.
|
|
{
|
|
return( flmStorage2UTF8( uiType, uiBufLength,
|
|
pBuffer, puiOutBufLenRV, pOutBuffer));
|
|
}
|
|
|
|
/****************************************************************************
|
|
Desc:
|
|
****************************************************************************/
|
|
typedef struct FlmVectorElementTag
|
|
{
|
|
FLMUINT64 ui64ID;
|
|
FLMUINT uiNameId;
|
|
FLMUINT uiFlags;
|
|
#define VECT_SLOT_HAS_DATA 0x01
|
|
#define VECT_SLOT_HAS_ID 0x02
|
|
#define VECT_SLOT_RIGHT_TRUNCATED 0x04
|
|
#define VECT_SLOT_LEFT_TRUNCATED 0x08
|
|
#define VECT_SLOT_HAS_NAME_ID 0x10
|
|
#define VECT_SLOT_IS_ATTR 0x20
|
|
#define VECT_SLOT_IS_DATA 0x40
|
|
FLMUINT uiDataType;
|
|
FLMUINT uiDataLength;
|
|
FLMUINT uiDataOffset;
|
|
} F_VECTOR_ELEMENT;
|
|
|
|
/*****************************************************************************
|
|
Desc: Used to build keys and data components
|
|
*****************************************************************************/
|
|
class F_DataVector : public IF_DataVector
|
|
{
|
|
public:
|
|
|
|
// Constructor/Destructor
|
|
|
|
F_DataVector();
|
|
virtual ~F_DataVector();
|
|
|
|
// Setter methods
|
|
|
|
FINLINE void FLMAPI setDocumentID(
|
|
FLMUINT64 ui64DocumentID)
|
|
{
|
|
m_ui64DocumentID = ui64DocumentID;
|
|
}
|
|
|
|
RCODE FLMAPI setID(
|
|
FLMUINT uiElementNumber,
|
|
FLMUINT64 ui64ID);
|
|
|
|
RCODE FLMAPI setNameId(
|
|
FLMUINT uiElementNumber,
|
|
FLMUINT uiNameId,
|
|
FLMBOOL bIsAttr,
|
|
FLMBOOL bIsData);
|
|
|
|
RCODE FLMAPI setINT(
|
|
FLMUINT uiElementNumber,
|
|
FLMINT iNum);
|
|
|
|
RCODE FLMAPI setINT64(
|
|
FLMUINT uiElementNumber,
|
|
FLMINT64 i64Num);
|
|
|
|
RCODE FLMAPI setUINT(
|
|
FLMUINT uiElementNumber,
|
|
FLMUINT uiNum);
|
|
|
|
RCODE FLMAPI setUINT64(
|
|
FLMUINT uiElementNumber,
|
|
FLMUINT64 ui64Num);
|
|
|
|
RCODE FLMAPI setUnicode(
|
|
FLMUINT uiElementNumber,
|
|
const FLMUNICODE * puzUnicode);
|
|
|
|
RCODE FLMAPI setUTF8(
|
|
FLMUINT uiElementNumber,
|
|
const FLMBYTE * pszUtf8,
|
|
FLMUINT uiBytesInBuffer = 0);
|
|
|
|
FINLINE RCODE FLMAPI setBinary(
|
|
FLMUINT uiElementNumber,
|
|
const void * pvBinary,
|
|
FLMUINT uiBinaryLen)
|
|
{
|
|
return( storeValue( uiElementNumber,
|
|
XFLM_BINARY_TYPE, (FLMBYTE *)pvBinary, uiBinaryLen));
|
|
}
|
|
|
|
FINLINE void FLMAPI setRightTruncated(
|
|
FLMUINT uiElementNumber)
|
|
{
|
|
F_VECTOR_ELEMENT * pVector;
|
|
|
|
if ((pVector = getVector( uiElementNumber, VECT_SLOT_HAS_DATA)) != NULL)
|
|
{
|
|
setRightTruncated( pVector);
|
|
}
|
|
else
|
|
{
|
|
// Need to set some data value before setting
|
|
// truncated.
|
|
flmAssert( 0);
|
|
}
|
|
}
|
|
|
|
FINLINE void FLMAPI setLeftTruncated(
|
|
FLMUINT uiElementNumber)
|
|
{
|
|
F_VECTOR_ELEMENT * pVector;
|
|
|
|
if ((pVector = getVector( uiElementNumber, VECT_SLOT_HAS_DATA)) != NULL)
|
|
{
|
|
setLeftTruncated( pVector);
|
|
}
|
|
else
|
|
{
|
|
// Need to set some data value before setting
|
|
// truncated.
|
|
flmAssert( 0);
|
|
}
|
|
}
|
|
|
|
FINLINE void FLMAPI clearRightTruncated(
|
|
FLMUINT uiElementNumber)
|
|
{
|
|
F_VECTOR_ELEMENT * pVector;
|
|
|
|
if ((pVector = getVector( uiElementNumber, VECT_SLOT_HAS_DATA)) != NULL)
|
|
{
|
|
clearRightTruncated( pVector);
|
|
}
|
|
else
|
|
{
|
|
// Need to set some data value before clearing
|
|
// truncated.
|
|
flmAssert( 0);
|
|
}
|
|
}
|
|
|
|
FINLINE void FLMAPI clearLeftTruncated(
|
|
FLMUINT uiElementNumber)
|
|
{
|
|
F_VECTOR_ELEMENT * pVector;
|
|
|
|
if ((pVector = getVector( uiElementNumber, VECT_SLOT_HAS_DATA)) != NULL)
|
|
{
|
|
clearLeftTruncated( pVector);
|
|
}
|
|
else
|
|
{
|
|
// Need to set some data value before clearing
|
|
// truncated.
|
|
flmAssert( 0);
|
|
}
|
|
}
|
|
|
|
FINLINE FLMBOOL FLMAPI isRightTruncated(
|
|
FLMUINT uiElementNumber)
|
|
{
|
|
F_VECTOR_ELEMENT * pVector;
|
|
|
|
if ((pVector = getVector( uiElementNumber, VECT_SLOT_HAS_DATA)) != NULL)
|
|
{
|
|
return( isRightTruncated( pVector));
|
|
}
|
|
|
|
return( FALSE);
|
|
}
|
|
|
|
FINLINE FLMBOOL FLMAPI isLeftTruncated(
|
|
FLMUINT uiElementNumber)
|
|
{
|
|
F_VECTOR_ELEMENT * pVector;
|
|
|
|
if ((pVector = getVector( uiElementNumber, VECT_SLOT_HAS_DATA)) != NULL)
|
|
{
|
|
return( isLeftTruncated( pVector));
|
|
}
|
|
|
|
return( FALSE);
|
|
}
|
|
|
|
// Getter methods
|
|
|
|
FINLINE FLMUINT64 FLMAPI getDocumentID( void)
|
|
{
|
|
return( m_ui64DocumentID);
|
|
}
|
|
|
|
FINLINE FLMUINT64 FLMAPI getID(
|
|
FLMUINT uiElementNumber)
|
|
{
|
|
F_VECTOR_ELEMENT * pVector;
|
|
|
|
if ((pVector = getVector( uiElementNumber, VECT_SLOT_HAS_ID)) == NULL)
|
|
{
|
|
return( 0);
|
|
}
|
|
else
|
|
{
|
|
return( pVector->ui64ID);
|
|
}
|
|
}
|
|
|
|
FINLINE FLMUINT FLMAPI getNameId(
|
|
FLMUINT uiElementNumber)
|
|
{
|
|
F_VECTOR_ELEMENT * pVector;
|
|
|
|
if ((pVector = getVector( uiElementNumber, VECT_SLOT_HAS_NAME_ID)) == NULL)
|
|
{
|
|
return( 0);
|
|
}
|
|
else
|
|
{
|
|
return( pVector->uiNameId);
|
|
}
|
|
}
|
|
|
|
FINLINE FLMBOOL FLMAPI isAttr(
|
|
FLMUINT uiElementNumber)
|
|
{
|
|
F_VECTOR_ELEMENT * pVector;
|
|
|
|
if ((pVector = getVector( uiElementNumber, VECT_SLOT_HAS_NAME_ID)) == NULL)
|
|
{
|
|
return( FALSE);
|
|
}
|
|
else
|
|
{
|
|
return( (pVector->uiFlags & VECT_SLOT_IS_ATTR) ? TRUE : FALSE);
|
|
}
|
|
}
|
|
|
|
FINLINE FLMBOOL FLMAPI isDataComponent(
|
|
FLMUINT uiElementNumber)
|
|
{
|
|
F_VECTOR_ELEMENT * pVector;
|
|
|
|
if ((pVector = getVector( uiElementNumber, VECT_SLOT_HAS_NAME_ID)) == NULL)
|
|
{
|
|
return( FALSE);
|
|
}
|
|
else
|
|
{
|
|
return( (pVector->uiFlags & VECT_SLOT_IS_DATA) ? TRUE : FALSE);
|
|
}
|
|
}
|
|
|
|
FINLINE FLMBOOL FLMAPI isKeyComponent(
|
|
FLMUINT uiElementNumber)
|
|
{
|
|
F_VECTOR_ELEMENT * pVector;
|
|
|
|
if ((pVector = getVector( uiElementNumber, VECT_SLOT_HAS_NAME_ID)) == NULL)
|
|
{
|
|
return( FALSE);
|
|
}
|
|
else
|
|
{
|
|
return( (pVector->uiFlags & VECT_SLOT_IS_DATA) ? FALSE : TRUE);
|
|
}
|
|
}
|
|
|
|
FLMUINT FLMAPI getDataLength(
|
|
FLMUINT uiElementNumber)
|
|
{
|
|
F_VECTOR_ELEMENT * pVector;
|
|
|
|
if ((pVector = getVector( uiElementNumber, VECT_SLOT_HAS_DATA)) == NULL)
|
|
{
|
|
return( 0);
|
|
}
|
|
else
|
|
{
|
|
return( pVector->uiDataLength);
|
|
}
|
|
}
|
|
|
|
FLMUINT FLMAPI getDataType(
|
|
FLMUINT uiElementNumber)
|
|
{
|
|
F_VECTOR_ELEMENT * pVector;
|
|
|
|
if ((pVector = getVector( uiElementNumber, VECT_SLOT_HAS_DATA)) == NULL)
|
|
{
|
|
return( XFLM_UNKNOWN_TYPE);
|
|
}
|
|
else
|
|
{
|
|
return( pVector->uiDataType);
|
|
}
|
|
}
|
|
|
|
RCODE FLMAPI getUTF8Ptr(
|
|
FLMUINT uiElementNumber,
|
|
const FLMBYTE ** ppszUTF8,
|
|
FLMUINT * puiBufLen);
|
|
|
|
FINLINE RCODE FLMAPI getINT(
|
|
FLMUINT uiElementNumber,
|
|
FLMINT * piNum)
|
|
{
|
|
F_VECTOR_ELEMENT * pVector;
|
|
|
|
return( (RCODE)((pVector = getVector( uiElementNumber,
|
|
VECT_SLOT_HAS_DATA)) != NULL
|
|
? flmStorage2Number( pVector->uiDataType,
|
|
pVector->uiDataLength,
|
|
(FLMBYTE *)getDataPtr( pVector),
|
|
NULL, piNum)
|
|
: RC_SET( NE_XFLM_NOT_FOUND)));
|
|
}
|
|
|
|
FINLINE RCODE FLMAPI getINT64(
|
|
FLMUINT uiElementNumber,
|
|
FLMINT64 * pi64Num)
|
|
{
|
|
F_VECTOR_ELEMENT * pVector;
|
|
|
|
return( (RCODE)((pVector = getVector( uiElementNumber,
|
|
VECT_SLOT_HAS_DATA)) != NULL
|
|
? flmStorage2Number64( pVector->uiDataType,
|
|
pVector->uiDataLength,
|
|
(FLMBYTE *)getDataPtr( pVector),
|
|
NULL, pi64Num)
|
|
: RC_SET( NE_XFLM_NOT_FOUND)));
|
|
}
|
|
|
|
FINLINE RCODE FLMAPI getUINT(
|
|
FLMUINT uiElementNumber,
|
|
FLMUINT * puiNum)
|
|
{
|
|
F_VECTOR_ELEMENT * pVector;
|
|
|
|
return( (RCODE)((pVector = getVector( uiElementNumber,
|
|
VECT_SLOT_HAS_DATA)) != NULL
|
|
? flmStorage2Number( pVector->uiDataType,
|
|
pVector->uiDataLength,
|
|
(FLMBYTE *)getDataPtr( pVector),
|
|
puiNum, NULL)
|
|
: RC_SET( NE_XFLM_NOT_FOUND)));
|
|
}
|
|
|
|
FINLINE RCODE FLMAPI getUINT64(
|
|
FLMUINT uiElementNumber,
|
|
FLMUINT64 * pui64Num)
|
|
{
|
|
F_VECTOR_ELEMENT * pVector;
|
|
|
|
return( (RCODE)((pVector = getVector( uiElementNumber,
|
|
VECT_SLOT_HAS_DATA)) != NULL
|
|
? flmStorage2Number64( pVector->uiDataType,
|
|
pVector->uiDataLength,
|
|
(FLMBYTE *)getDataPtr( pVector),
|
|
pui64Num, NULL)
|
|
: RC_SET( NE_XFLM_NOT_FOUND)));
|
|
}
|
|
|
|
RCODE FLMAPI getUnicode(
|
|
FLMUINT uiElementNumber,
|
|
FLMUNICODE ** ppuzUnicode);
|
|
|
|
FINLINE RCODE FLMAPI getUnicode(
|
|
FLMUINT uiElementNumber,
|
|
F_DynaBuf * pBuffer)
|
|
{
|
|
F_VECTOR_ELEMENT * pVector;
|
|
|
|
return( (RCODE)((pVector = getVector( uiElementNumber,
|
|
VECT_SLOT_HAS_DATA)) != NULL
|
|
? flmStorage2Unicode( pVector->uiDataType,
|
|
pVector->uiDataLength,
|
|
(FLMBYTE *)getDataPtr( pVector),
|
|
pBuffer)
|
|
: RC_SET( NE_XFLM_NOT_FOUND)));
|
|
}
|
|
|
|
FINLINE RCODE FLMAPI getUnicode(
|
|
FLMUINT uiElementNumber,
|
|
FLMUNICODE * puzUnicode,
|
|
FLMUINT * puiBufLen)
|
|
{
|
|
F_VECTOR_ELEMENT * pVector;
|
|
|
|
return( (RCODE)((pVector = getVector( uiElementNumber,
|
|
VECT_SLOT_HAS_DATA)) != NULL
|
|
? flmStorage2Unicode( pVector->uiDataType,
|
|
pVector->uiDataLength,
|
|
(FLMBYTE *)getDataPtr( pVector),
|
|
puiBufLen, puzUnicode)
|
|
: RC_SET( NE_XFLM_NOT_FOUND)));
|
|
}
|
|
|
|
FINLINE RCODE FLMAPI getUTF8(
|
|
FLMUINT uiElementNumber,
|
|
FLMBYTE * pszUTF8,
|
|
FLMUINT * puiBufLen)
|
|
{
|
|
F_VECTOR_ELEMENT * pVector;
|
|
|
|
return( (RCODE)((pVector = getVector( uiElementNumber,
|
|
VECT_SLOT_HAS_DATA)) != NULL
|
|
? flmStorage2UTF8( pVector->uiDataType,
|
|
pVector->uiDataLength,
|
|
(FLMBYTE *)getDataPtr( pVector),
|
|
puiBufLen, pszUTF8)
|
|
: RC_SET( NE_XFLM_NOT_FOUND)));
|
|
}
|
|
|
|
FINLINE RCODE FLMAPI getBinary(
|
|
FLMUINT uiElementNumber,
|
|
void * pvBuffer,
|
|
FLMUINT * puiLength)
|
|
{
|
|
F_VECTOR_ELEMENT * pVector;
|
|
|
|
if ((pVector = getVector( uiElementNumber, VECT_SLOT_HAS_DATA)) != NULL)
|
|
{
|
|
*puiLength = f_min( (*puiLength), pVector->uiDataLength);
|
|
if (pvBuffer && *puiLength)
|
|
{
|
|
f_memcpy( pvBuffer, getDataPtr( pVector), *puiLength);
|
|
}
|
|
|
|
return( NE_XFLM_OK);
|
|
}
|
|
else
|
|
{
|
|
*puiLength = 0;
|
|
}
|
|
|
|
return( RC_SET( NE_XFLM_NOT_FOUND));
|
|
}
|
|
|
|
FINLINE RCODE FLMAPI getBinary(
|
|
FLMUINT uiElementNumber,
|
|
F_DynaBuf * pBuffer)
|
|
{
|
|
F_VECTOR_ELEMENT * pVector;
|
|
|
|
pBuffer->truncateData( 0);
|
|
if ((pVector = getVector( uiElementNumber, VECT_SLOT_HAS_DATA)) != NULL)
|
|
{
|
|
return( pBuffer->appendData( getDataPtr( pVector),
|
|
pVector->uiDataLength));
|
|
}
|
|
|
|
return( RC_SET( NE_XFLM_NOT_FOUND));
|
|
}
|
|
|
|
RCODE FLMAPI outputKey(
|
|
IF_Db * pDb,
|
|
FLMUINT uiIndexNum,
|
|
FLMUINT uiMatchFlags,
|
|
FLMBYTE * pucKeyBuf,
|
|
FLMUINT uiKeyBufSize,
|
|
FLMUINT * puiKeyLen);
|
|
|
|
RCODE FLMAPI outputData(
|
|
IF_Db * pDb,
|
|
FLMUINT uiIndexNum,
|
|
FLMBYTE * pucDataBuf,
|
|
FLMUINT uiDataBufSize,
|
|
FLMUINT * puiDataLen);
|
|
|
|
RCODE FLMAPI inputKey(
|
|
IF_Db * pDb,
|
|
FLMUINT uiIndexNum,
|
|
const FLMBYTE * pucKey,
|
|
FLMUINT uiKeyLen);
|
|
|
|
RCODE FLMAPI inputData(
|
|
IF_Db * pDb,
|
|
FLMUINT uiIndexNum,
|
|
const FLMBYTE * pucData,
|
|
FLMUINT uiDataLen);
|
|
|
|
// Miscellaneous methods
|
|
|
|
void FLMAPI reset( void);
|
|
|
|
FINLINE const void * FLMAPI getDataPtr(
|
|
FLMUINT uiElementNumber)
|
|
{
|
|
return( getDataPtr( getVector( uiElementNumber, VECT_SLOT_HAS_DATA)));
|
|
}
|
|
|
|
private:
|
|
|
|
RCODE allocVectorArray(
|
|
FLMUINT uiElementNumber);
|
|
|
|
RCODE storeValue(
|
|
FLMINT uiElementNumber,
|
|
FLMUINT uiDataType,
|
|
const FLMBYTE * pucData,
|
|
FLMUINT uiDataLen,
|
|
FLMBYTE ** ppucDataPtr = NULL);
|
|
|
|
FINLINE F_VECTOR_ELEMENT * getVector(
|
|
FLMUINT uiElementNumber,
|
|
FLMUINT uiTestFlags)
|
|
{
|
|
F_VECTOR_ELEMENT * pVector;
|
|
|
|
if (uiElementNumber >= m_uiNumElements)
|
|
{
|
|
return( NULL);
|
|
}
|
|
pVector = &m_pVectorElements [uiElementNumber];
|
|
if (!(pVector->uiFlags & uiTestFlags))
|
|
{
|
|
return( NULL);
|
|
}
|
|
else
|
|
{
|
|
return( pVector);
|
|
}
|
|
}
|
|
|
|
FINLINE FLMBOOL isRightTruncated(
|
|
F_VECTOR_ELEMENT * pVector)
|
|
{
|
|
return( (pVector->uiFlags & VECT_SLOT_RIGHT_TRUNCATED)
|
|
? TRUE
|
|
: FALSE);
|
|
}
|
|
|
|
FINLINE void setRightTruncated(
|
|
F_VECTOR_ELEMENT * pVector)
|
|
{
|
|
pVector->uiFlags |= VECT_SLOT_RIGHT_TRUNCATED;
|
|
}
|
|
|
|
FINLINE void clearRightTruncated(
|
|
F_VECTOR_ELEMENT * pVector)
|
|
{
|
|
pVector->uiFlags &= (~(VECT_SLOT_RIGHT_TRUNCATED));
|
|
}
|
|
|
|
FINLINE FLMBOOL isLeftTruncated(
|
|
F_VECTOR_ELEMENT * pVector)
|
|
{
|
|
return( (pVector->uiFlags & VECT_SLOT_LEFT_TRUNCATED)
|
|
? TRUE
|
|
: FALSE);
|
|
}
|
|
|
|
FINLINE void setLeftTruncated(
|
|
F_VECTOR_ELEMENT * pVector)
|
|
{
|
|
pVector->uiFlags |= VECT_SLOT_LEFT_TRUNCATED;
|
|
}
|
|
|
|
FINLINE void clearLeftTruncated(
|
|
F_VECTOR_ELEMENT * pVector)
|
|
{
|
|
pVector->uiFlags &= (~(VECT_SLOT_LEFT_TRUNCATED));
|
|
}
|
|
|
|
FINLINE void * getDataPtr(
|
|
F_VECTOR_ELEMENT * pVector)
|
|
{
|
|
if (!pVector || !pVector->uiDataLength)
|
|
{
|
|
return( NULL);
|
|
}
|
|
else if (pVector->uiDataLength <= sizeof( FLMUINT))
|
|
{
|
|
return( (void *)&pVector->uiDataOffset);
|
|
}
|
|
else
|
|
{
|
|
return( (void *)(m_pucDataBuf + pVector->uiDataOffset));
|
|
}
|
|
}
|
|
|
|
RCODE outputKey(
|
|
IXD * pIxd,
|
|
FLMUINT uiMatchFlags,
|
|
FLMBYTE * pucKeyBuf,
|
|
FLMUINT uiKeyBufSize,
|
|
FLMUINT * puiKeyLen,
|
|
FLMUINT uiSearchKeyFlag);
|
|
|
|
RCODE outputData(
|
|
IXD * pIxd,
|
|
FLMBYTE * pucDataBuf,
|
|
FLMUINT uiDataBufSize,
|
|
FLMUINT * puiDataLen);
|
|
|
|
RCODE inputKey(
|
|
IXD * pIxd,
|
|
const FLMBYTE * pucKey,
|
|
FLMUINT uiKeyLen);
|
|
|
|
RCODE inputData(
|
|
IXD * pIxd,
|
|
const FLMBYTE * pucData,
|
|
FLMUINT uiDataLen);
|
|
|
|
#define MIN_VECTOR_ELEMENTS 6
|
|
F_VECTOR_ELEMENT m_VectorArray [MIN_VECTOR_ELEMENTS];
|
|
F_VECTOR_ELEMENT * m_pVectorElements; // Pointer to vector elements
|
|
FLMUINT m_uiVectorArraySize; // Size of vector array
|
|
FLMUINT m_uiNumElements; // Number of elements actually
|
|
// populated in the array.
|
|
|
|
FLMBYTE m_ucIntDataBuf[ 32]; // Internal data buffer
|
|
FLMBYTE * m_pucDataBuf; // Values stored here
|
|
FLMUINT m_uiDataBufLength; // Bytes of data allocated
|
|
FLMUINT m_uiDataBufOffset; // Current offset into allocated
|
|
// data buffer.
|
|
FLMUINT64 m_ui64DocumentID; // Document ID;
|
|
|
|
friend class F_Db;
|
|
friend class FSIndexCursor;
|
|
friend class FSCollectionCursor;
|
|
friend class F_QueryResultSet;
|
|
};
|
|
|
|
// Flags for the m_uiFlags member of the F_Db object
|
|
|
|
#define FDB_UPDATED_DICTIONARY 0x0001
|
|
// Flag indicating whether the file's
|
|
// local dictionary was updated
|
|
// during the transaction.
|
|
#define FDB_DO_TRUNCATE 0x0002
|
|
// Truncate log extents at the end
|
|
// of a transaction.
|
|
#define FDB_HAS_FILE_LOCK 0x0004
|
|
// FDB has a file lock.
|
|
#define FDB_FILE_LOCK_SHARED 0x0008
|
|
// File lock is shared. Update
|
|
// transactions are not allowed when
|
|
// the lock is shared.
|
|
#define FDB_FILE_LOCK_IMPLICIT 0x0010
|
|
// File lock is implicit - means file
|
|
// lock was obtained when the update
|
|
// transaction began and cannot be
|
|
// released by a call to FlmDbUnlock.
|
|
#define FDB_DONT_KILL_TRANS 0x0020
|
|
// Do not attempt to kill an active
|
|
// read transaction on this database
|
|
// handle. This is used by FlmDbBackup.
|
|
#define FDB_INTERNAL_OPEN 0x0040
|
|
// FDB is an internal one used by a
|
|
// background thread.
|
|
#define FDB_DONT_POISON_CACHE 0x0080
|
|
// If blocks are read from disk during
|
|
// a transaction, release them at the LRU
|
|
// end of the cache chain.
|
|
#define FDB_UPGRADING 0x0100
|
|
// Database is being upgraded.
|
|
#define FDB_REPLAYING_RFL 0x0200
|
|
// Database is being recovered
|
|
#define FDB_REPLAYING_COMMIT 0x0400
|
|
// During replay of the RFL, this
|
|
// is an actual call to FlmDbTransCommit.
|
|
#define FDB_BACKGROUND_INDEXING 0x0800
|
|
// FDB is being used by a background indexing
|
|
// thread
|
|
#define FDB_HAS_WRITE_LOCK 0x1000
|
|
// FDB has the write lock
|
|
#define FDB_REBUILDING_DATABASE 0x2000
|
|
// Database is being rebuilt
|
|
#define FDB_SWEEP_SCHEDULED 0x4000
|
|
// Sweep operation scheduled due to a
|
|
// dictionary change during the transaction
|
|
|
|
/*****************************************************************************
|
|
Desc: Class for performing database backup.
|
|
*****************************************************************************/
|
|
class F_Backup : public IF_Backup
|
|
{
|
|
public:
|
|
|
|
F_Backup();
|
|
virtual ~F_Backup();
|
|
|
|
FINLINE FLMUINT64 FLMAPI getBackupTransId( void)
|
|
{
|
|
return( m_ui64TransId);
|
|
}
|
|
|
|
FINLINE FLMUINT64 FLMAPI getLastBackupTransId( void)
|
|
{
|
|
return( m_ui64LastBackupTransId);
|
|
}
|
|
|
|
RCODE FLMAPI backup(
|
|
const char * pszBackupPath,
|
|
const char * pszPassword,
|
|
IF_BackupClient * pClient,
|
|
IF_BackupStatus * pStatus,
|
|
FLMUINT * puiIncSeqNum);
|
|
|
|
RCODE FLMAPI endBackup( void);
|
|
|
|
private:
|
|
|
|
void reset( void);
|
|
|
|
F_Db * m_pDb;
|
|
eDbTransType m_eTransType;
|
|
FLMUINT64 m_ui64TransId;
|
|
FLMUINT64 m_ui64LastBackupTransId;
|
|
FLMUINT m_uiDbVersion;
|
|
FLMUINT m_uiBlkChgSinceLastBackup;
|
|
FLMBOOL m_bTransStarted;
|
|
FLMUINT m_uiBlockSize;
|
|
FLMUINT m_uiLogicalEOF;
|
|
FLMUINT m_uiFirstReqRfl;
|
|
FLMUINT m_uiIncSeqNum;
|
|
FLMBOOL m_bCompletedBackup;
|
|
eDbBackupType m_eBackupType;
|
|
RCODE m_backupRc;
|
|
FLMBYTE m_ucNextIncSerialNum[ XFLM_SERIAL_NUM_SIZE];
|
|
char m_szDbPath[ F_PATH_MAX_SIZE];
|
|
XFLM_DB_HDR m_dbHdr;
|
|
|
|
friend class F_Db;
|
|
};
|
|
|
|
|
|
/*****************************************************************************
|
|
Desc: An implementation of IF_Backup_Client that backs up to the
|
|
local hard disk.
|
|
*****************************************************************************/
|
|
class F_DefaultBackupClient : public IF_BackupClient
|
|
{
|
|
public:
|
|
|
|
F_DefaultBackupClient(
|
|
const char * pszBackupPath);
|
|
|
|
virtual ~F_DefaultBackupClient();
|
|
|
|
RCODE FLMAPI WriteData(
|
|
const void * pvBuffer,
|
|
FLMUINT uiBytesToWrite);
|
|
|
|
virtual FLMINT FLMAPI getRefCount( void)
|
|
{
|
|
return( IF_BackupClient::getRefCount());
|
|
}
|
|
|
|
virtual FLMINT FLMAPI AddRef( void)
|
|
{
|
|
return( IF_BackupClient::AddRef());
|
|
}
|
|
|
|
virtual FLMINT FLMAPI Release( void)
|
|
{
|
|
return( IF_BackupClient::Release());
|
|
}
|
|
|
|
private:
|
|
|
|
char m_szPath[ F_PATH_MAX_SIZE];
|
|
IF_MultiFileHdl * m_pMultiFileHdl;
|
|
FLMUINT64 m_ui64Offset;
|
|
RCODE m_rc;
|
|
};
|
|
|
|
/*****************************************************************************
|
|
Desc: The F_FSRestore class is used to read backup and RFL files from
|
|
a disk file system.
|
|
*****************************************************************************/
|
|
class F_FSRestore : public IF_RestoreClient
|
|
{
|
|
public:
|
|
|
|
virtual ~F_FSRestore();
|
|
F_FSRestore();
|
|
|
|
RCODE setup(
|
|
const char * pszDbPath,
|
|
const char * pszBackupSetPath,
|
|
const char * pszRflDir);
|
|
|
|
RCODE FLMAPI openBackupSet( void);
|
|
|
|
RCODE FLMAPI openIncFile(
|
|
FLMUINT uiFileNum);
|
|
|
|
RCODE FLMAPI openRflFile(
|
|
FLMUINT uiFileNum);
|
|
|
|
RCODE FLMAPI read(
|
|
FLMUINT uiLength,
|
|
void * pvBuffer,
|
|
FLMUINT * puiBytesRead);
|
|
|
|
RCODE FLMAPI close( void);
|
|
|
|
RCODE FLMAPI abortFile( void);
|
|
|
|
virtual FLMINT FLMAPI getRefCount( void)
|
|
{
|
|
return( IF_RestoreClient::getRefCount());
|
|
}
|
|
|
|
virtual FLMINT FLMAPI AddRef( void)
|
|
{
|
|
return( IF_RestoreClient::AddRef());
|
|
}
|
|
|
|
virtual FLMINT FLMAPI Release( void)
|
|
{
|
|
return( IF_RestoreClient::Release());
|
|
}
|
|
|
|
protected:
|
|
|
|
IF_FileHdl * m_pFileHdl;
|
|
IF_MultiFileHdl * m_pMultiFileHdl;
|
|
FLMUINT64 m_ui64Offset;
|
|
FLMUINT m_uiDbVersion;
|
|
char m_szDbPath[ F_PATH_MAX_SIZE];
|
|
char m_szBackupSetPath[ F_PATH_MAX_SIZE];
|
|
char m_szRflDir[ F_PATH_MAX_SIZE];
|
|
FLMBOOL m_bSetupCalled;
|
|
FLMBOOL m_bOpen;
|
|
};
|
|
|
|
/*****************************************************************************
|
|
Desc: Default implementation of a restore status object than can
|
|
be inherited by a user implementation.
|
|
*****************************************************************************/
|
|
class F_DefaultRestoreStatus : public IF_RestoreStatus
|
|
{
|
|
public:
|
|
|
|
F_DefaultRestoreStatus()
|
|
{
|
|
}
|
|
|
|
RCODE FLMAPI reportProgress(
|
|
eRestoreAction * peAction,
|
|
FLMUINT64, // ui64BytesToDo,
|
|
FLMUINT64) // ui64BytesDone
|
|
{
|
|
*peAction = XFLM_RESTORE_ACTION_CONTINUE;
|
|
return( NE_XFLM_OK);
|
|
}
|
|
|
|
RCODE FLMAPI reportError(
|
|
eRestoreAction * peAction,
|
|
RCODE) // rcErr
|
|
{
|
|
*peAction = XFLM_RESTORE_ACTION_CONTINUE;
|
|
return( NE_XFLM_OK);
|
|
}
|
|
|
|
RCODE FLMAPI reportBeginTrans(
|
|
eRestoreAction * peAction,
|
|
FLMUINT64) // ui64TransId
|
|
{
|
|
*peAction = XFLM_RESTORE_ACTION_CONTINUE;
|
|
return( NE_XFLM_OK);
|
|
}
|
|
|
|
RCODE FLMAPI reportCommitTrans(
|
|
eRestoreAction * peAction,
|
|
FLMUINT64) // ui64TransId
|
|
{
|
|
*peAction = XFLM_RESTORE_ACTION_CONTINUE;
|
|
return( NE_XFLM_OK);
|
|
}
|
|
|
|
RCODE FLMAPI reportAbortTrans(
|
|
eRestoreAction * peAction,
|
|
FLMUINT64) // ui64TransId
|
|
{
|
|
*peAction = XFLM_RESTORE_ACTION_CONTINUE;
|
|
return( NE_XFLM_OK);
|
|
}
|
|
|
|
RCODE FLMAPI reportRemoveData(
|
|
eRestoreAction * peAction,
|
|
FLMUINT64, // ui64TransId,
|
|
FLMUINT, // uiLfNum,
|
|
FLMUINT, // uiKeyLen,
|
|
FLMBYTE *) // pucKey
|
|
{
|
|
*peAction = XFLM_RESTORE_ACTION_CONTINUE;
|
|
return( NE_XFLM_OK);
|
|
}
|
|
|
|
RCODE FLMAPI reportInsertData(
|
|
eRestoreAction * peAction,
|
|
FLMUINT64, // ui64TransId,
|
|
FLMUINT, // uiLfNum,
|
|
FLMUINT, // uiKeyLen,
|
|
FLMBYTE *) // pucKey
|
|
{
|
|
*peAction = XFLM_RESTORE_ACTION_CONTINUE;
|
|
return( NE_XFLM_OK);
|
|
}
|
|
|
|
RCODE FLMAPI reportReplaceData(
|
|
eRestoreAction * peAction,
|
|
FLMUINT64, // ui64TransId,
|
|
FLMUINT, // uiLfNum,
|
|
FLMUINT, // uiKeyLen,
|
|
FLMBYTE *) // pucKey
|
|
{
|
|
*peAction = XFLM_RESTORE_ACTION_CONTINUE;
|
|
return( NE_XFLM_OK);
|
|
}
|
|
|
|
RCODE FLMAPI reportLFileCreate(
|
|
eRestoreAction * peAction,
|
|
FLMUINT64, // ui64TransId,
|
|
FLMUINT) // uiLfNum
|
|
{
|
|
*peAction = XFLM_RESTORE_ACTION_CONTINUE;
|
|
return( NE_XFLM_OK);
|
|
}
|
|
|
|
RCODE FLMAPI reportLFileUpdate(
|
|
eRestoreAction * peAction,
|
|
FLMUINT64, // ui64TransId,
|
|
FLMUINT, // uiLfNum,
|
|
FLMUINT, // uiRootBlk,
|
|
FLMUINT64, // ui64NextNodeId,
|
|
FLMUINT64, // ui64FirstDocId,
|
|
FLMUINT64 // ui64LastDocId
|
|
)
|
|
{
|
|
*peAction = XFLM_RESTORE_ACTION_CONTINUE;
|
|
return( NE_XFLM_OK);
|
|
}
|
|
|
|
RCODE FLMAPI reportUpdateDict(
|
|
eRestoreAction * peAction,
|
|
FLMUINT64, // ui64TransId,
|
|
FLMUINT, // uiDictType,
|
|
FLMUINT, // uiDictNum,
|
|
FLMBOOL) // bDeleting
|
|
{
|
|
*peAction = XFLM_RESTORE_ACTION_CONTINUE;
|
|
return( NE_XFLM_OK);
|
|
}
|
|
|
|
RCODE FLMAPI reportIndexSuspend(
|
|
eRestoreAction * peAction,
|
|
FLMUINT64, // ui64TransId,
|
|
FLMUINT) // uiIndexNum
|
|
{
|
|
*peAction = XFLM_RESTORE_ACTION_CONTINUE;
|
|
return( NE_XFLM_OK);
|
|
}
|
|
|
|
RCODE FLMAPI reportIndexResume(
|
|
eRestoreAction * peAction,
|
|
FLMUINT64, // ui64TransId,
|
|
FLMUINT) // uiIndexNum
|
|
{
|
|
*peAction = XFLM_RESTORE_ACTION_CONTINUE;
|
|
return( NE_XFLM_OK);
|
|
}
|
|
|
|
RCODE FLMAPI reportReduce(
|
|
eRestoreAction * peAction,
|
|
FLMUINT64, // ui64TransId,
|
|
FLMUINT) // uiCount
|
|
{
|
|
*peAction = XFLM_RESTORE_ACTION_CONTINUE;
|
|
return( NE_XFLM_OK);
|
|
}
|
|
|
|
RCODE FLMAPI reportUpgrade(
|
|
eRestoreAction * peAction,
|
|
FLMUINT64, // ui64TransId,
|
|
FLMUINT, // uiOldDbVersion,
|
|
FLMUINT) // uiNewDbVersion
|
|
{
|
|
*peAction = XFLM_RESTORE_ACTION_CONTINUE;
|
|
return( NE_XFLM_OK);
|
|
}
|
|
|
|
RCODE FLMAPI reportEnableEncryption(
|
|
eRestoreAction * peAction,
|
|
FLMUINT64 // ui64TransId
|
|
)
|
|
{
|
|
*peAction = XFLM_RESTORE_ACTION_CONTINUE;
|
|
return( NE_XFLM_OK);
|
|
}
|
|
|
|
RCODE FLMAPI reportWrapKey(
|
|
eRestoreAction * peAction,
|
|
FLMUINT64) // ui64TransId
|
|
{
|
|
*peAction = XFLM_RESTORE_ACTION_CONTINUE;
|
|
return( NE_XFLM_OK);
|
|
}
|
|
|
|
RCODE FLMAPI reportOpenRflFile(
|
|
eRestoreAction * peAction,
|
|
FLMUINT) // uiFileNum
|
|
{
|
|
*peAction = XFLM_RESTORE_ACTION_CONTINUE;
|
|
return( NE_XFLM_OK);
|
|
}
|
|
|
|
RCODE FLMAPI reportRflRead(
|
|
eRestoreAction * peAction,
|
|
FLMUINT, // uiFileNum,
|
|
FLMUINT) // uiBytesRead
|
|
{
|
|
*peAction = XFLM_RESTORE_ACTION_CONTINUE;
|
|
return( NE_XFLM_OK);
|
|
}
|
|
|
|
virtual FLMINT FLMAPI getRefCount( void)
|
|
{
|
|
return( IF_RestoreStatus::getRefCount());
|
|
}
|
|
|
|
virtual FLMINT FLMAPI AddRef( void)
|
|
{
|
|
return( IF_RestoreStatus::AddRef());
|
|
}
|
|
|
|
virtual FLMINT FLMAPI Release( void)
|
|
{
|
|
return( IF_RestoreStatus::Release());
|
|
}
|
|
};
|
|
|
|
// Indexing actions
|
|
|
|
typedef enum IxActionTag
|
|
{
|
|
IX_UNLINK_NODE = 0,
|
|
IX_LINK_NODE,
|
|
IX_DEL_NODE_VALUE,
|
|
IX_ADD_NODE_VALUE,
|
|
IX_LINK_AND_ADD_NODE
|
|
} IxAction;
|
|
|
|
typedef struct ElmAttrStateInfo
|
|
{
|
|
FLMUINT uiDictType;
|
|
FLMUINT uiDictNum;
|
|
FLMUINT uiState;
|
|
FLMUINT64 ui64StateChangeCount;
|
|
} ELM_ATTR_STATE_INFO;
|
|
|
|
typedef struct KEY_GEN_INFO
|
|
{
|
|
FLMUINT64 ui64DocumentID;
|
|
IXD * pIxd;
|
|
FLMBOOL bIsAsia;
|
|
FLMBOOL bIsCompound;
|
|
CDL_HDR * pCdlTbl;
|
|
FLMBOOL bUseSubtreeNodes;
|
|
FLMBOOL bAddKeys;
|
|
FLMBYTE * pucKeyBuf;
|
|
FLMBYTE * pucData;
|
|
FLMUINT uiDataBufSize;
|
|
FLMBOOL bDataBufAllocated;
|
|
} KEY_GEN_INFO;
|
|
|
|
typedef struct OLD_NODE_DATA
|
|
{
|
|
eDomNodeType eNodeType;
|
|
FLMUINT uiCollection;
|
|
FLMUINT64 ui64NodeId;
|
|
FLMUINT uiNameId;
|
|
FLMBYTE * pucData;
|
|
FLMUINT uiDataLen;
|
|
} OLD_NODE_DATA;
|
|
|
|
/*****************************************************************************
|
|
Desc:
|
|
*****************************************************************************/
|
|
class F_OldNodeList : public F_Object
|
|
{
|
|
public:
|
|
|
|
F_OldNodeList()
|
|
{
|
|
m_pNodeList = NULL;
|
|
m_uiListSize = 0;
|
|
m_uiNodeCount = 0;
|
|
m_pool.poolInit( 512);
|
|
}
|
|
|
|
~F_OldNodeList();
|
|
|
|
RCODE setup( void);
|
|
|
|
FLMBOOL findNodeInList(
|
|
eDomNodeType eNodeType,
|
|
FLMUINT uiCollection,
|
|
FLMUINT64 ui64NodeId,
|
|
FLMUINT uiNameId,
|
|
FLMBYTE ** ppucData,
|
|
FLMUINT * puiDataLen,
|
|
FLMUINT * puiInsertPos);
|
|
|
|
RCODE addNodeToList(
|
|
F_Db * pDb,
|
|
F_DOMNode * pNode);
|
|
|
|
void resetList( void);
|
|
|
|
FINLINE FLMUINT getNodeCount( void)
|
|
{
|
|
return( m_uiNodeCount);
|
|
}
|
|
|
|
private:
|
|
|
|
OLD_NODE_DATA * m_pNodeList;
|
|
F_Pool m_pool;
|
|
FLMUINT m_uiListSize;
|
|
FLMUINT m_uiNodeCount;
|
|
};
|
|
|
|
/*****************************************************************************
|
|
Desc:
|
|
*****************************************************************************/
|
|
class F_Db : public IF_Db
|
|
{
|
|
public:
|
|
|
|
F_Db(
|
|
FLMBOOL bInternalOpen);
|
|
|
|
virtual ~F_Db();
|
|
|
|
RCODE FLMAPI transBegin(
|
|
eDbTransType eTransType,
|
|
FLMUINT uiMaxLockWait = FLM_NO_TIMEOUT,
|
|
FLMUINT uiFlags = 0,
|
|
XFLM_DB_HDR * pDbHeader = NULL);
|
|
|
|
RCODE FLMAPI transBegin(
|
|
IF_Db * pDb);
|
|
|
|
RCODE FLMAPI transCommit(
|
|
FLMBOOL * pbEmpty = NULL);
|
|
|
|
RCODE FLMAPI transAbort( void);
|
|
|
|
FINLINE eDbTransType FLMAPI getTransType( void)
|
|
{
|
|
return( m_eTransType);
|
|
}
|
|
|
|
RCODE FLMAPI doCheckpoint(
|
|
FLMUINT uiTimeout);
|
|
|
|
RCODE FLMAPI dbLock(
|
|
eLockType lockType,
|
|
FLMINT iPriority,
|
|
FLMUINT uiTimeout);
|
|
|
|
RCODE FLMAPI dbUnlock( void);
|
|
|
|
RCODE FLMAPI getLockType(
|
|
eLockType * pLockType,
|
|
FLMBOOL * pbImplicit);
|
|
|
|
RCODE FLMAPI getLockInfo(
|
|
FLMINT iPriority,
|
|
eLockType * pCurrLockType,
|
|
FLMUINT * puiThreadId,
|
|
FLMUINT * puiNumExclQueued,
|
|
FLMUINT * puiNumSharedQueued,
|
|
FLMUINT * puiPriorityCount);
|
|
|
|
RCODE dupTrans(
|
|
FLMUINT64 ui64TransId);
|
|
|
|
RCODE demoteTrans( void);
|
|
|
|
RCODE cancelTrans(
|
|
FLMUINT64 ui64TransId);
|
|
|
|
RCODE getCommitCnt(
|
|
FLMUINT64 * pui64CommitCount);
|
|
|
|
// Index methods
|
|
|
|
RCODE FLMAPI indexStatus(
|
|
FLMUINT uiIndexNum,
|
|
XFLM_INDEX_STATUS * pIndexStatus);
|
|
|
|
RCODE FLMAPI indexGetNext(
|
|
FLMUINT * puiIndexNum);
|
|
|
|
RCODE FLMAPI indexSuspend(
|
|
FLMUINT uiIndexNum);
|
|
|
|
RCODE FLMAPI indexResume(
|
|
FLMUINT uiIndexNum);
|
|
|
|
// Retrieval Functions
|
|
|
|
RCODE FLMAPI keyRetrieve(
|
|
FLMUINT uiIndex,
|
|
IF_DataVector * ifpSearchKey,
|
|
FLMUINT uiFlags,
|
|
IF_DataVector * ifpFoundKey);
|
|
|
|
RCODE FLMAPI enableEncryption( void);
|
|
|
|
RCODE FLMAPI wrapKey(
|
|
const char * pszPassword = NULL);
|
|
|
|
RCODE FLMAPI rollOverDbKey( void);
|
|
|
|
RCODE FLMAPI changeItemState(
|
|
FLMUINT uiDictType,
|
|
FLMUINT uiDictNum,
|
|
const char * pszState);
|
|
|
|
RCODE FLMAPI reduceSize(
|
|
FLMUINT uiCount,
|
|
FLMUINT * puiCountRV);
|
|
|
|
RCODE FLMAPI upgrade(
|
|
IF_UpgradeClient * pUpgradeClient);
|
|
|
|
RCODE FLMAPI createRootElement(
|
|
FLMUINT uiCollection,
|
|
FLMUINT uiNameId,
|
|
IF_DOMNode ** ppElementNode,
|
|
FLMUINT64 * pui64NodeId = NULL);
|
|
|
|
RCODE FLMAPI createDocument(
|
|
FLMUINT uiCollection,
|
|
IF_DOMNode ** ppDocumentNode,
|
|
FLMUINT64 * pui64NodeId = NULL);
|
|
|
|
RCODE FLMAPI getFirstDocument(
|
|
FLMUINT uiCollection,
|
|
IF_DOMNode ** ppDocumentNode);
|
|
|
|
RCODE FLMAPI getLastDocument(
|
|
FLMUINT uiCollection,
|
|
IF_DOMNode ** ppDocumentNode);
|
|
|
|
RCODE FLMAPI getDocument(
|
|
FLMUINT uiCollection,
|
|
FLMUINT uiFlags,
|
|
FLMUINT64 ui64DocumentId,
|
|
IF_DOMNode ** ppDocumentNode);
|
|
|
|
RCODE FLMAPI documentDone(
|
|
FLMUINT uiCollection,
|
|
FLMUINT64 ui64RootId);
|
|
|
|
RCODE FLMAPI documentDone(
|
|
IF_DOMNode * pDocNode);
|
|
|
|
FINLINE RCODE FLMAPI createElementDef(
|
|
const char * pszNamespaceURI,
|
|
const char * pszElementName,
|
|
FLMUINT uiDataType,
|
|
FLMUINT * puiElementNameId = NULL,
|
|
IF_DOMNode ** ppDocumentNode = NULL)
|
|
{
|
|
return( createElemOrAttrDef( TRUE, FALSE, pszNamespaceURI,
|
|
pszElementName, uiDataType, FALSE,
|
|
puiElementNameId, (F_DOMNode **)ppDocumentNode));
|
|
}
|
|
|
|
FINLINE RCODE FLMAPI createElementDef(
|
|
const FLMUNICODE * puzNamespaceURI,
|
|
const FLMUNICODE * puzElementName,
|
|
FLMUINT uiDataType,
|
|
FLMUINT * puiElementNameId = NULL,
|
|
IF_DOMNode ** ppDocumentNode = NULL)
|
|
{
|
|
return( createElemOrAttrDef( TRUE, TRUE, puzNamespaceURI,
|
|
puzElementName, uiDataType, FALSE,
|
|
puiElementNameId, (F_DOMNode **)ppDocumentNode));
|
|
}
|
|
|
|
FINLINE RCODE FLMAPI createUniqueElmDef(
|
|
const char * pszNamespaceURI,
|
|
const char * pszElementName,
|
|
FLMUINT * puiElementNameId = NULL,
|
|
IF_DOMNode ** ppDocumentNode = NULL)
|
|
{
|
|
return( createElemOrAttrDef( TRUE, FALSE, pszNamespaceURI,
|
|
pszElementName, XFLM_NODATA_TYPE, TRUE,
|
|
puiElementNameId, (F_DOMNode **)ppDocumentNode));
|
|
}
|
|
|
|
FINLINE RCODE FLMAPI createUniqueElmDef(
|
|
const FLMUNICODE * puzNamespaceURI,
|
|
const FLMUNICODE * puzElementName,
|
|
FLMUINT * puiElementNameId = NULL,
|
|
IF_DOMNode ** ppDocumentNode = NULL)
|
|
{
|
|
return( createElemOrAttrDef( TRUE, TRUE, puzNamespaceURI,
|
|
puzElementName, XFLM_NODATA_TYPE, TRUE,
|
|
puiElementNameId, (F_DOMNode **)ppDocumentNode));
|
|
}
|
|
|
|
RCODE FLMAPI getElementNameId(
|
|
const char * pszNamespaceURI,
|
|
const char * pszElementName,
|
|
FLMUINT * puiElementNameId);
|
|
|
|
RCODE FLMAPI getElementNameId(
|
|
const FLMUNICODE * puzNamespaceURI,
|
|
const FLMUNICODE * puzElementName,
|
|
FLMUINT * puiElementNameId);
|
|
|
|
FINLINE RCODE FLMAPI createAttributeDef(
|
|
const char * pszNamespaceURI,
|
|
const char * pszAttributeName,
|
|
FLMUINT uiDataType,
|
|
FLMUINT * puiAttributeNameId,
|
|
IF_DOMNode ** ppDocumentNode = NULL)
|
|
{
|
|
return( createElemOrAttrDef( FALSE, FALSE, pszNamespaceURI,
|
|
pszAttributeName, uiDataType, FALSE, puiAttributeNameId,
|
|
(F_DOMNode **)ppDocumentNode));
|
|
}
|
|
|
|
FINLINE RCODE FLMAPI createAttributeDef(
|
|
const FLMUNICODE * puzNamespaceURI,
|
|
const FLMUNICODE * puzAttributeName,
|
|
FLMUINT uiDataType,
|
|
FLMUINT * puiAttributeNameId,
|
|
IF_DOMNode ** ppDocumentNode = NULL)
|
|
{
|
|
return( createElemOrAttrDef( FALSE, TRUE, puzNamespaceURI,
|
|
puzAttributeName, uiDataType, FALSE, puiAttributeNameId,
|
|
(F_DOMNode **)ppDocumentNode));
|
|
}
|
|
|
|
RCODE FLMAPI getAttributeNameId(
|
|
const char * pszNamespaceURI,
|
|
const char * pszAttributeName,
|
|
FLMUINT * puiAttributeNameId);
|
|
|
|
RCODE FLMAPI getAttributeNameId(
|
|
const FLMUNICODE * puzNamespaceURI,
|
|
const FLMUNICODE * puzAttributeName,
|
|
FLMUINT * puiAttributeNameId);
|
|
|
|
FINLINE RCODE FLMAPI createPrefixDef(
|
|
const char * pszPrefixName,
|
|
FLMUINT * puiPrefixNumber)
|
|
{
|
|
return( createPrefixDef( FALSE, pszPrefixName, puiPrefixNumber));
|
|
}
|
|
|
|
FINLINE RCODE FLMAPI createPrefixDef(
|
|
const FLMUNICODE * puzPrefixName,
|
|
FLMUINT * puiPrefixNumber)
|
|
{
|
|
return( createPrefixDef( TRUE, puzPrefixName, puiPrefixNumber));
|
|
}
|
|
|
|
RCODE FLMAPI getPrefixId(
|
|
const char * pszPrefixName,
|
|
FLMUINT * puiPrefixNumber);
|
|
|
|
RCODE FLMAPI getPrefixId(
|
|
const FLMUNICODE * puzPrefixName,
|
|
FLMUINT * puiPrefixNumber);
|
|
|
|
FINLINE RCODE FLMAPI createEncDef(
|
|
const char * pszEncType,
|
|
const char * pszEncName,
|
|
FLMUINT uiKeySize = 0,
|
|
FLMUINT * puiEncDefNumber = NULL)
|
|
{
|
|
return( createEncDef( FALSE, pszEncType, pszEncName,
|
|
uiKeySize, puiEncDefNumber));
|
|
}
|
|
|
|
FINLINE RCODE FLMAPI createEncDef(
|
|
const FLMUNICODE * puzEncType,
|
|
const FLMUNICODE * puzEncName,
|
|
FLMUINT uiKeySize = 0,
|
|
FLMUINT * puiEncDefNumber = NULL)
|
|
{
|
|
return( createEncDef( TRUE, puzEncType, puzEncName,
|
|
uiKeySize, puiEncDefNumber));
|
|
}
|
|
|
|
RCODE FLMAPI getEncDefId(
|
|
const char * pszEncDefName,
|
|
FLMUINT * puiEncDefNumber);
|
|
|
|
RCODE FLMAPI getEncDefId(
|
|
const FLMUNICODE * puzEncDefName,
|
|
FLMUINT * puiEncDefNumber);
|
|
|
|
FINLINE RCODE FLMAPI createCollectionDef(
|
|
const char * pszCollectionName,
|
|
FLMUINT * puiCollectionNumber,
|
|
FLMUINT uiEncNumber = 0)
|
|
{
|
|
return( createCollectionDef( FALSE, pszCollectionName,
|
|
puiCollectionNumber, uiEncNumber));
|
|
}
|
|
|
|
FINLINE RCODE FLMAPI createCollectionDef(
|
|
const FLMUNICODE * puzCollectionName,
|
|
FLMUINT * puiCollectionNumber,
|
|
FLMUINT uiEncNumber = 0)
|
|
{
|
|
return( createCollectionDef( TRUE, puzCollectionName,
|
|
puiCollectionNumber, uiEncNumber));
|
|
}
|
|
|
|
RCODE FLMAPI getCollectionNumber(
|
|
const char * pszCollectionName,
|
|
FLMUINT * puiCollectionNumber);
|
|
|
|
RCODE FLMAPI getCollectionNumber(
|
|
const FLMUNICODE * puzCollectionName,
|
|
FLMUINT * puiCollectionNumber);
|
|
|
|
RCODE FLMAPI getIndexNumber(
|
|
const char * pszIndexName,
|
|
FLMUINT * puiIndexNumber);
|
|
|
|
RCODE FLMAPI getIndexNumber(
|
|
const FLMUNICODE * puzIndexName,
|
|
FLMUINT * puiIndexNumber);
|
|
|
|
RCODE FLMAPI getDictionaryDef(
|
|
FLMUINT uiDictType,
|
|
FLMUINT uiDictNumber,
|
|
IF_DOMNode ** ppDocumentNode);
|
|
|
|
RCODE FLMAPI getDictionaryName(
|
|
FLMUINT uiDictType,
|
|
FLMUINT uiDictNumber,
|
|
char * pszName,
|
|
FLMUINT * puiNameBufSize,
|
|
char * pszNamespace = NULL,
|
|
FLMUINT * puiNamespaceBufSize = NULL);
|
|
|
|
RCODE FLMAPI getDictionaryName(
|
|
FLMUINT uiDictType,
|
|
FLMUINT uiDictNumber,
|
|
FLMUNICODE * puzName,
|
|
FLMUINT * puiNameBufSize,
|
|
FLMUNICODE * puzNamespace = NULL,
|
|
FLMUINT * puiNamespaceBufSize = NULL);
|
|
|
|
RCODE FLMAPI getNode(
|
|
FLMUINT uiCollection,
|
|
FLMUINT64 ui64NodeId,
|
|
IF_DOMNode ** ifppNode)
|
|
{
|
|
return( getNode( uiCollection,
|
|
ui64NodeId, XFLM_EXACT, (F_DOMNode **)ifppNode));
|
|
}
|
|
|
|
FINLINE RCODE getNode(
|
|
FLMUINT uiCollection,
|
|
FLMUINT64 ui64NodeId,
|
|
F_DOMNode ** ppNode)
|
|
{
|
|
return( getNode( uiCollection, ui64NodeId, XFLM_EXACT, ppNode));
|
|
}
|
|
|
|
FINLINE RCODE getNextNode(
|
|
FLMUINT uiCollection,
|
|
FLMUINT64 ui64NodeId,
|
|
F_DOMNode ** ppNode)
|
|
{
|
|
return( getNode( uiCollection, ui64NodeId, XFLM_EXCL, ppNode));
|
|
}
|
|
|
|
RCODE FLMAPI getAttribute(
|
|
FLMUINT uiCollection,
|
|
FLMUINT64 ui64ElementId,
|
|
FLMUINT uiAttrName,
|
|
IF_DOMNode ** ppNode);
|
|
|
|
RCODE FLMAPI getDataType(
|
|
FLMUINT uiDictType,
|
|
FLMUINT uiNameId,
|
|
FLMUINT * puiDataType);
|
|
|
|
RCODE FLMAPI backupBegin(
|
|
eDbBackupType eBackupType,
|
|
eDbTransType eTransType,
|
|
FLMUINT uiMaxLockWait,
|
|
IF_Backup ** ppBackup);
|
|
|
|
void FLMAPI getRflFileName(
|
|
FLMUINT uiFileNum,
|
|
FLMBOOL bBaseOnly,
|
|
char * pszFileName,
|
|
FLMUINT * puiFileNameBufSize,
|
|
FLMBOOL * pbNameTruncated = NULL);
|
|
|
|
RCODE FLMAPI import(
|
|
IF_IStream * pIStream,
|
|
FLMUINT uiCollection,
|
|
IF_DOMNode * pNodeToLinkTo = NULL,
|
|
eNodeInsertLoc eInsertLoc = XFLM_LAST_CHILD,
|
|
XFLM_IMPORT_STATS * pImportStats = NULL);
|
|
|
|
RCODE FLMAPI importDocument(
|
|
IF_IStream * ifpStream,
|
|
FLMUINT uiCollection,
|
|
IF_DOMNode ** ppDocumentNode = NULL,
|
|
XFLM_IMPORT_STATS * pImportStats = NULL);
|
|
|
|
RCODE FLMAPI exportXML(
|
|
IF_DOMNode * pStartNode,
|
|
IF_OStream * pOStream,
|
|
eExportFormatType eFormat = XFLM_EXPORT_INDENT);
|
|
|
|
RCODE FLMAPI setNextNodeId(
|
|
FLMUINT uiCollection,
|
|
FLMUINT64 ui64NextNodeId);
|
|
|
|
RCODE FLMAPI setNextDictNum(
|
|
FLMUINT uiDictType,
|
|
FLMUINT uiDictNumber);
|
|
|
|
// Configuration methods
|
|
|
|
RCODE FLMAPI setRflKeepFilesFlag(
|
|
FLMBOOL bKeep);
|
|
|
|
RCODE FLMAPI getRflKeepFlag(
|
|
FLMBOOL * pbKeep);
|
|
|
|
RCODE FLMAPI setRflDir(
|
|
const char * pszNewRflDir);
|
|
|
|
void FLMAPI getRflDir(
|
|
char * pszRflDir);
|
|
|
|
RCODE FLMAPI getRflFileNum(
|
|
FLMUINT * puiRflFileNum);
|
|
|
|
RCODE FLMAPI getHighestNotUsedRflFileNum(
|
|
FLMUINT * puiHighestNotUsedRflFileNum);
|
|
|
|
RCODE FLMAPI setRflFileSizeLimits(
|
|
FLMUINT uiMinRflSize,
|
|
FLMUINT uiMaxRflSize);
|
|
|
|
RCODE FLMAPI getRflFileSizeLimits(
|
|
FLMUINT * puiRflMinFileSize,
|
|
FLMUINT * puiRflMaxFileSize);
|
|
|
|
RCODE FLMAPI rflRollToNextFile( void);
|
|
|
|
RCODE FLMAPI setKeepAbortedTransInRflFlag(
|
|
FLMBOOL bKeep);
|
|
|
|
RCODE FLMAPI getKeepAbortedTransInRflFlag(
|
|
FLMBOOL * pbKeep);
|
|
|
|
RCODE FLMAPI setAutoTurnOffKeepRflFlag(
|
|
FLMBOOL bAutoTurnOff);
|
|
|
|
RCODE FLMAPI getAutoTurnOffKeepRflFlag(
|
|
FLMBOOL * pbAutoTurnOff);
|
|
|
|
FINLINE void FLMAPI setFileExtendSize(
|
|
FLMUINT uiFileExtendSize)
|
|
{
|
|
m_pDatabase->m_uiFileExtendSize = uiFileExtendSize;
|
|
}
|
|
|
|
FINLINE FLMUINT FLMAPI getFileExtendSize( void)
|
|
{
|
|
return( m_pDatabase->m_uiFileExtendSize);
|
|
}
|
|
|
|
FINLINE void FLMAPI setAppData(
|
|
void * pvAppData)
|
|
{
|
|
m_pvAppData = pvAppData;
|
|
}
|
|
|
|
FINLINE void * FLMAPI getAppData( void)
|
|
{
|
|
return( m_pvAppData);
|
|
}
|
|
|
|
FINLINE void FLMAPI setDeleteStatusObject(
|
|
IF_DeleteStatus * pDeleteStatus)
|
|
{
|
|
if (m_pDeleteStatus)
|
|
{
|
|
m_pDeleteStatus->Release();
|
|
}
|
|
if ((m_pDeleteStatus = pDeleteStatus) != NULL)
|
|
{
|
|
m_pDeleteStatus->AddRef();
|
|
}
|
|
}
|
|
|
|
FINLINE void FLMAPI setCommitClientObject(
|
|
IF_CommitClient * pCommitClient)
|
|
{
|
|
if (m_pCommitClient)
|
|
{
|
|
m_pCommitClient->Release();
|
|
}
|
|
|
|
m_pCommitClient = pCommitClient;
|
|
|
|
if (m_pCommitClient)
|
|
{
|
|
m_pCommitClient->AddRef();
|
|
}
|
|
}
|
|
|
|
FINLINE void FLMAPI setIndexingClientObject(
|
|
IF_IxClient * pIxClient)
|
|
{
|
|
if (m_pIxClient)
|
|
{
|
|
m_pIxClient->Release();
|
|
}
|
|
m_pIxClient = pIxClient;
|
|
if (m_pIxClient)
|
|
{
|
|
m_pIxClient->AddRef();
|
|
}
|
|
}
|
|
|
|
FINLINE void FLMAPI setIndexingStatusObject(
|
|
IF_IxStatus * ifpIxStatus)
|
|
{
|
|
if (m_pIxStatus)
|
|
{
|
|
m_pIxStatus->Release();
|
|
}
|
|
m_pIxStatus = ifpIxStatus;
|
|
if (m_pIxStatus)
|
|
{
|
|
m_pIxStatus->AddRef();
|
|
}
|
|
}
|
|
|
|
// Configuration information getting methods
|
|
|
|
FINLINE FLMUINT FLMAPI getDbVersion( void)
|
|
{
|
|
return( (FLMUINT)m_pDatabase->m_lastCommittedDbHdr.ui32DbVersion);
|
|
}
|
|
|
|
FINLINE FLMUINT FLMAPI getBlockSize( void)
|
|
{
|
|
return( m_pDatabase->m_uiBlockSize);
|
|
}
|
|
|
|
FINLINE FLMUINT FLMAPI getDefaultLanguage( void)
|
|
{
|
|
return( m_pDatabase->m_uiDefaultLanguage);
|
|
}
|
|
|
|
FINLINE FLMUINT64 FLMAPI getTransID( void)
|
|
{
|
|
if (m_eTransType != XFLM_NO_TRANS)
|
|
{
|
|
return( m_ui64CurrTransID);
|
|
}
|
|
else if (m_uiFlags & FDB_HAS_FILE_LOCK)
|
|
{
|
|
return( m_pDatabase->m_lastCommittedDbHdr.ui64CurrTransID);
|
|
}
|
|
|
|
return( 0);
|
|
}
|
|
|
|
void FLMAPI getCheckpointInfo(
|
|
XFLM_CHECKPOINT_INFO * pCheckpointInfo);
|
|
|
|
RCODE FLMAPI getDbControlFileName(
|
|
char * pszControlFileName,
|
|
FLMUINT uiControlFileBufSize)
|
|
{
|
|
RCODE rc = NE_XFLM_OK;
|
|
FLMUINT uiLen = f_strlen( m_pDatabase->m_pszDbPath);
|
|
|
|
if (uiLen + 1 > uiControlFileBufSize)
|
|
{
|
|
uiLen = uiControlFileBufSize - 1;
|
|
rc = RC_SET( NE_XFLM_BUFFER_OVERFLOW);
|
|
}
|
|
f_memcpy( pszControlFileName, m_pDatabase->m_pszDbPath, uiLen);
|
|
pszControlFileName [uiLen] = 0;
|
|
return( rc);
|
|
}
|
|
|
|
FINLINE FLMBOOL threadWaitingLock( void)
|
|
{
|
|
return( m_pDatabase->m_pDatabaseLockObj->getWaiterCount() ? TRUE : FALSE);
|
|
}
|
|
|
|
RCODE FLMAPI getLockWaiters(
|
|
IF_LockInfoClient * pLockInfo);
|
|
|
|
RCODE FLMAPI getLastBackupTransID(
|
|
FLMUINT64 * pui64LastBackupTransID);
|
|
|
|
RCODE FLMAPI getBlocksChangedSinceBackup(
|
|
FLMUINT * puiBlocksChangedSinceBackup);
|
|
|
|
RCODE FLMAPI getNextIncBackupSequenceNum(
|
|
FLMUINT * puiNextIncBackupSequenceNum);
|
|
|
|
void FLMAPI getSerialNumber(
|
|
char * pucSerialNumber);
|
|
|
|
RCODE FLMAPI getDiskSpaceUsage(
|
|
FLMUINT64 * pui64DataSize,
|
|
FLMUINT64 * pui64RollbackSize,
|
|
FLMUINT64 * pui64RflSize);
|
|
|
|
FINLINE RCODE FLMAPI getMustCloseRC( void)
|
|
{
|
|
return( m_pDatabase->m_rcMustClose);
|
|
}
|
|
|
|
FINLINE RCODE FLMAPI getAbortRC( void)
|
|
{
|
|
return( m_AbortRc);
|
|
}
|
|
|
|
FINLINE RCODE startTransaction(
|
|
eDbTransType eReqTransType,
|
|
FLMBOOL * pbStartedTrans)
|
|
{
|
|
RCODE rc;
|
|
|
|
if( m_eTransType != XFLM_NO_TRANS)
|
|
{
|
|
return( RC_SET_AND_ASSERT( NE_XFLM_ILLEGAL_TRANS_OP));
|
|
}
|
|
|
|
if( !pbStartedTrans)
|
|
{
|
|
return( RC_SET( NE_XFLM_NO_TRANS_ACTIVE));
|
|
}
|
|
|
|
if( RC_BAD( rc = transBegin( eReqTransType)))
|
|
{
|
|
return( rc);
|
|
}
|
|
|
|
*pbStartedTrans = TRUE;
|
|
return( NE_XFLM_OK);
|
|
}
|
|
|
|
FINLINE RCODE checkTransaction(
|
|
eDbTransType eReqTransType,
|
|
FLMBOOL * pbStartedTrans)
|
|
{
|
|
if( m_AbortRc)
|
|
{
|
|
return( m_AbortRc);
|
|
}
|
|
else if( m_eTransType >= eReqTransType)
|
|
{
|
|
return( NE_XFLM_OK);
|
|
}
|
|
|
|
return( startTransaction( eReqTransType, pbStartedTrans));
|
|
}
|
|
|
|
FINLINE void FLMAPI setMustAbortTrans(
|
|
RCODE rc)
|
|
{
|
|
if( RC_BAD( rc) && RC_OK( m_AbortRc))
|
|
{
|
|
m_AbortRc = rc;
|
|
}
|
|
}
|
|
|
|
RCODE getDictionary(
|
|
F_Dict ** ppDict);
|
|
|
|
FINLINE RCODE checkState(
|
|
const char * pszFileName,
|
|
FLMINT iLineNumber)
|
|
{
|
|
RCODE rc = NE_XFLM_OK;
|
|
|
|
if (m_bMustClose)
|
|
{
|
|
m_pDatabase->logMustCloseReason( pszFileName, iLineNumber);
|
|
rc = RC_SET( NE_XFLM_MUST_CLOSE_DATABASE);
|
|
}
|
|
return( rc);
|
|
}
|
|
|
|
RCODE getElmAttrInfo(
|
|
FLMUINT uiType,
|
|
FLMUINT64 ui64DocumentID,
|
|
F_AttrElmInfo * pDefInfo,
|
|
FLMBOOL bOpeningDict,
|
|
FLMBOOL bDeleting);
|
|
|
|
RCODE getCollectionDef(
|
|
FLMUINT64 ui64DocumentID,
|
|
FLMUNICODE ** ppuzCollectionName,
|
|
FLMUINT * puiCollectionNumber,
|
|
FLMUINT * puiEncId);
|
|
|
|
RCODE getPrefixDef(
|
|
F_Dict * pDict,
|
|
FLMUINT64 ui64DocumentID,
|
|
FLMUNICODE ** ppuzPrefixName,
|
|
FLMUINT * puiPrefixNumber);
|
|
|
|
RCODE getEncDefDef(
|
|
F_Dict * pDict,
|
|
FLMUINT64 ui64DocumentID,
|
|
FLMUNICODE ** ppuzEncDefName,
|
|
FLMUINT * puiEncDefNumber,
|
|
FLMUINT * puiEncDefKeySize,
|
|
F_CCS ** ppCcs);
|
|
|
|
RCODE getIndexDef(
|
|
FLMUINT64 ui64DocumentID,
|
|
FLMUNICODE ** ppuzIndexName,
|
|
FLMUINT * puiIndexNumber,
|
|
FLMUINT * puiCollectionNumber,
|
|
FLMUINT * puiLanguage,
|
|
FLMUINT * puiFlags,
|
|
FLMUINT64 * pui64LastDocIndexed,
|
|
FLMUINT * puiEncId,
|
|
F_DOMNode ** ppNode,
|
|
FLMBOOL bOpeningDict,
|
|
FLMBOOL bDeleting);
|
|
|
|
RCODE getIndexComponentDef(
|
|
F_Dict * pDict,
|
|
F_DOMNode * pElementNode,
|
|
FLMUINT uiElementId,
|
|
IXD * pIxd,
|
|
ICD * pIcd);
|
|
|
|
RCODE getNameTable(
|
|
F_NameTable ** ppNameTable);
|
|
|
|
FINLINE F_Database * getDatabase( void)
|
|
{
|
|
return m_pDatabase;
|
|
}
|
|
|
|
RCODE backgroundIndexBuild(
|
|
IF_Thread * pThread,
|
|
FLMBOOL * pbShutdown,
|
|
FLMINT * piErrorLine);
|
|
|
|
FINLINE FLMUINT getLogicalEOF( void)
|
|
{
|
|
return( m_uiLogicalEOF);
|
|
}
|
|
|
|
// Key Collector object, used when checking indexes
|
|
|
|
FINLINE void setKeyCollector(
|
|
F_KeyCollector * pKeyColl)
|
|
{
|
|
m_pKeyColl = pKeyColl;
|
|
}
|
|
|
|
FINLINE F_KeyCollector * getKeyCollector( void)
|
|
{
|
|
return m_pKeyColl;
|
|
}
|
|
|
|
RCODE waitForMaintenanceToComplete( void);
|
|
|
|
FINLINE F_Dict * getDict( void)
|
|
{
|
|
return( m_pDict);
|
|
}
|
|
|
|
FINLINE F_OldNodeList * getOldNodeList( void)
|
|
{
|
|
return( m_pOldNodeList);
|
|
}
|
|
|
|
void removeCollectionNodes(
|
|
FLMUINT uiCollection,
|
|
FLMUINT64 ui64TransId);
|
|
|
|
private:
|
|
|
|
RCODE createElemOrAttrDef(
|
|
FLMBOOL bElement,
|
|
FLMBOOL bUnicode,
|
|
const void * pvNamespaceURI,
|
|
const void * pvLocalName,
|
|
FLMUINT uiDataType,
|
|
FLMBOOL bUniqueChildElms,
|
|
FLMUINT * puiNameId,
|
|
F_DOMNode ** ppRootNode);
|
|
|
|
RCODE createPrefixDef(
|
|
FLMBOOL bUnicode,
|
|
const void * pvName,
|
|
FLMUINT * puiPrefixNumber);
|
|
|
|
RCODE createCollectionDef(
|
|
FLMBOOL bUnicode,
|
|
const void * pvName,
|
|
FLMUINT * puiCollectionNumber,
|
|
FLMUINT uiEncDefId);
|
|
|
|
RCODE createEncDef(
|
|
FLMBOOL bUnicode,
|
|
const void * pvEncType,
|
|
const void * pvEncName,
|
|
FLMUINT uiKeySize,
|
|
FLMUINT * puiEncDefId);
|
|
|
|
// This routine assumes that the database mutex is locked
|
|
FINLINE void linkToDict(
|
|
F_Dict * pDict)
|
|
{
|
|
if (pDict != m_pDict)
|
|
{
|
|
if (m_pDict)
|
|
{
|
|
unlinkFromDict();
|
|
}
|
|
if ((m_pDict = pDict) != NULL)
|
|
{
|
|
pDict->incrUseCount();
|
|
}
|
|
}
|
|
}
|
|
|
|
// This routine assumes the database mutex is locked.
|
|
FINLINE void unlinkFromDict( void)
|
|
{
|
|
if (m_pDict)
|
|
{
|
|
|
|
// If the use count goes to zero and the F_Dict is not the first one
|
|
// in the file's list or it is not linked to a file, unlink the F_Dict
|
|
// object from its database and delete it.
|
|
|
|
if (!m_pDict->decrUseCount() &&
|
|
(m_pDict->getPrev() || !m_pDict->getDatabase()))
|
|
{
|
|
m_pDict->unlinkFromDatabase();
|
|
}
|
|
m_pDict = NULL;
|
|
}
|
|
}
|
|
|
|
RCODE linkToDatabase(
|
|
F_Database * pDatabase);
|
|
|
|
void unlinkFromDatabase();
|
|
|
|
RCODE initDbFiles(
|
|
const char * pszRflDir,
|
|
const char * pszDictFileName,
|
|
const char * pszDictBuf,
|
|
XFLM_CREATE_OPTS * pCreateOpts);
|
|
|
|
RCODE beginBackgroundTrans(
|
|
IF_Thread * pThread);
|
|
|
|
RCODE beginTrans(
|
|
eDbTransType eTransType,
|
|
FLMUINT uiMaxLockWait = FLM_NO_TIMEOUT,
|
|
FLMUINT uiFlags = 0,
|
|
XFLM_DB_HDR * pDbHdr = NULL);
|
|
|
|
RCODE beginTrans(
|
|
F_Db * pDb);
|
|
|
|
RCODE commitTrans(
|
|
FLMUINT uiNewLogicalEOF,
|
|
FLMBOOL bForceCheckpoint,
|
|
FLMBOOL * pbEmpty = NULL);
|
|
|
|
RCODE abortTrans(
|
|
FLMBOOL bOkToLogAbort = TRUE);
|
|
|
|
RCODE readRollbackLog(
|
|
FLMUINT uiLogEOF,
|
|
FLMUINT * puiCurrAddr,
|
|
F_BLK_HDR * pBlkHdr,
|
|
FLMBOOL * pbIsBeforeImageBlk);
|
|
|
|
RCODE processBeforeImage(
|
|
FLMUINT uiLogEOF,
|
|
FLMUINT * puiCurrAddrRV,
|
|
F_BLK_HDR * pBlkHdr,
|
|
FLMBOOL bDoingRecovery,
|
|
FLMUINT64 ui64MaxTransID);
|
|
|
|
RCODE physRollback(
|
|
FLMUINT uiLogEOF,
|
|
FLMUINT uiFirstLogBlkAddr,
|
|
FLMBOOL bDoingRecovery,
|
|
FLMUINT64 ui64MaxTransID);
|
|
|
|
void completeOpenOrCreate(
|
|
RCODE rc,
|
|
FLMBOOL bNewDatabase);
|
|
|
|
RCODE startBackgroundIndexing( void);
|
|
|
|
void unlinkFromTransList(
|
|
FLMBOOL bCommitting);
|
|
|
|
RCODE lockExclusive(
|
|
FLMUINT uiMaxLockWait);
|
|
|
|
void unlockExclusive( void);
|
|
|
|
RCODE readDictionary( void);
|
|
|
|
RCODE dictCreate(
|
|
const char * pszDictPath,
|
|
const char * pszDictBuf);
|
|
|
|
RCODE dictOpen( void);
|
|
|
|
RCODE dictReadLFH( void);
|
|
|
|
RCODE dictReadDefs(
|
|
FLMUINT uiDictType);
|
|
|
|
RCODE dictClone( void);
|
|
|
|
RCODE createNewDict( void);
|
|
|
|
FINLINE void getDbHdrInfo(
|
|
XFLM_DB_HDR * pDbHdr)
|
|
{
|
|
// IMPORTANT NOTE: Any changes to this method should also be
|
|
// mirrored with changes to the other getDbHdrInfo call - see below.
|
|
|
|
m_ui64CurrTransID = pDbHdr->ui64CurrTransID;
|
|
m_uiLogicalEOF = (FLMUINT)pDbHdr->ui32LogicalEOF;
|
|
|
|
// If we are doing a read transaction, this is only needed
|
|
// if we are checking the database.
|
|
|
|
m_uiFirstAvailBlkAddr = (FLMUINT)pDbHdr->ui32FirstAvailBlkAddr;
|
|
}
|
|
|
|
FINLINE void getDbHdrInfo(
|
|
F_Db * pDb)
|
|
{
|
|
m_ui64CurrTransID = pDb->m_ui64CurrTransID;
|
|
m_uiLogicalEOF = pDb->m_uiLogicalEOF;
|
|
|
|
// If we are doing a read transaction, this is only needed
|
|
// if we are checking the database.
|
|
|
|
m_uiFirstAvailBlkAddr = pDb->m_uiFirstAvailBlkAddr;
|
|
}
|
|
|
|
FINLINE FLMBOOL okToCommitTrans( void)
|
|
{
|
|
return( m_eTransType == XFLM_READ_TRANS ||
|
|
m_AbortRc == NE_XFLM_OK
|
|
? TRUE
|
|
: FALSE);
|
|
}
|
|
|
|
RCODE processDupKeys(
|
|
IXD * pIxd);
|
|
|
|
RCODE keysCommit(
|
|
FLMBOOL bCommittingTrans,
|
|
FLMBOOL bSortKeys = TRUE);
|
|
|
|
RCODE refUpdate(
|
|
LFILE * pLFile,
|
|
IXD * pIxd,
|
|
KREF_ENTRY * pKrefEntry,
|
|
FLMBOOL bNormalUpdate);
|
|
|
|
FINLINE RCODE flushKeys( void)
|
|
{
|
|
RCODE rc = NE_XFLM_OK;
|
|
|
|
if( m_bKrefSetup)
|
|
{
|
|
if( m_uiKrefCount)
|
|
{
|
|
if (RC_BAD( rc = keysCommit( FALSE)))
|
|
{
|
|
goto Exit;
|
|
}
|
|
}
|
|
|
|
m_pKrefReset = m_pKrefPool->poolMark();
|
|
}
|
|
|
|
Exit:
|
|
|
|
return( rc);
|
|
}
|
|
|
|
RCODE krefCntrlCheck( void);
|
|
|
|
void krefCntrlFree( void);
|
|
|
|
FINLINE FLMBOOL isKrefOverThreshold( void)
|
|
{
|
|
if( (((m_pKrefPool->getBlockSize() * 3) - 250) <= m_uiTotalKrefBytes) ||
|
|
m_uiKrefCount > (m_uiKrefTblSize - 128))
|
|
{
|
|
return( TRUE);
|
|
}
|
|
|
|
return( FALSE);
|
|
}
|
|
|
|
RCODE addToKrefTbl(
|
|
FLMUINT uiKeyLen,
|
|
FLMUINT uiDataLen);
|
|
|
|
RCODE verifyKeyContext(
|
|
FLMBOOL * pbVerified);
|
|
|
|
RCODE buildContext(
|
|
ICD * pIcd,
|
|
FLMUINT uiKeyLen,
|
|
FLMUINT uiDataLen);
|
|
|
|
RCODE buildData(
|
|
ICD * pIcd,
|
|
FLMUINT uiKeyLen,
|
|
FLMUINT uiDataLen);
|
|
|
|
RCODE finishKeyComponent(
|
|
ICD * pIcd,
|
|
FLMUINT uiKeyLen);
|
|
|
|
RCODE genTextKeyComponents(
|
|
F_DOMNode * pNode,
|
|
ICD * pIcd,
|
|
FLMUINT uiKeyLen,
|
|
FLMBYTE ** ppucTmpBuf,
|
|
FLMUINT * puiTmpBufSize,
|
|
void ** ppvMark);
|
|
|
|
RCODE genOtherKeyComponent(
|
|
F_DOMNode * pNode,
|
|
ICD * pIcd,
|
|
FLMUINT uiKeyLen);
|
|
|
|
RCODE buildKeys(
|
|
ICD * pIcd,
|
|
FLMUINT uiKeyLen);
|
|
|
|
RCODE buildKeys(
|
|
FLMUINT64 ui64DocumentID,
|
|
IXD * pIxd,
|
|
CDL_HDR * pCdlTbl,
|
|
FLMBOOL bUseSubtreeNodes,
|
|
FLMBOOL bAddKeys);
|
|
|
|
RCODE genIndexKeys(
|
|
FLMUINT64 ui64DocumentID,
|
|
F_DOMNode * pNode,
|
|
IXD * pIxd,
|
|
ICD * pIcd,
|
|
IxAction eAction);
|
|
|
|
RCODE updateIndexKeys(
|
|
FLMUINT uiCollectionNum,
|
|
F_DOMNode * pNode,
|
|
IxAction eAction,
|
|
FLMBOOL bStartOfUpdate,
|
|
FLMBOOL * pbIsIndexed = NULL);
|
|
|
|
RCODE attrIsInIndexDef(
|
|
FLMUINT uiAttrNameId,
|
|
FLMBOOL * pbIsInIndexDef);
|
|
|
|
void indexingAfterCommit( void);
|
|
|
|
void indexingAfterAbort( void);
|
|
|
|
RCODE addToStopList(
|
|
FLMUINT uiIndexNum);
|
|
|
|
RCODE addToStartList(
|
|
FLMUINT uiIndexNum);
|
|
|
|
void stopBackgroundIndexThread(
|
|
FLMUINT uiIndexNum,
|
|
FLMBOOL bWait,
|
|
FLMBOOL * pbStopped);
|
|
|
|
RCODE startIndexBuild(
|
|
FLMUINT uiIndexNum);
|
|
|
|
RCODE checkDictDefInfo(
|
|
FLMUINT64 ui64DocumentID,
|
|
FLMBOOL bDeleting,
|
|
FLMUINT * puiDictType,
|
|
FLMUINT * puiDictNumber);
|
|
|
|
RCODE dictDocumentDone(
|
|
FLMUINT64 ui64DocumentID,
|
|
FLMBOOL bDeleting,
|
|
FLMUINT * puiDictDefType);
|
|
|
|
RCODE outputContextKeys(
|
|
FLMUINT64 ui64DocumentId,
|
|
IXD * pIxd,
|
|
IX_CONTEXT * pIxContext,
|
|
IX_CONTEXT ** ppIxContextList);
|
|
|
|
RCODE removeCdls(
|
|
FLMUINT64 ui64DocumentId,
|
|
IXD * pIxd,
|
|
IX_CONTEXT * pIxContext,
|
|
ICD * pRefIcd);
|
|
|
|
RCODE indexDocument(
|
|
IXD * pIxd,
|
|
F_DOMNode * pDocNode);
|
|
|
|
RCODE indexSetOfDocuments(
|
|
FLMUINT uiIndexNum,
|
|
FLMUINT64 ui64StartDocumentId,
|
|
FLMUINT64 ui64EndDocumentId,
|
|
IF_IxStatus * ifpIxStatus,
|
|
IF_IxClient * ifpIxClient,
|
|
XFLM_INDEX_STATUS * pIndexStatus,
|
|
FLMBOOL * pbHitEnd,
|
|
IF_Thread * pThread = NULL);
|
|
|
|
RCODE setIxStateInfo(
|
|
FLMUINT uiIndexNum,
|
|
FLMUINT64 ui64LastDocumentIndexed,
|
|
FLMUINT uiState);
|
|
|
|
RCODE buildIndex(
|
|
FLMUINT uiIndexNum,
|
|
FLMUINT uiState);
|
|
|
|
RCODE readBlkHdr(
|
|
FLMUINT uiBlkAddress,
|
|
F_BLK_HDR * pBlkHdr,
|
|
FLMINT * piType);
|
|
|
|
XFLM_LFILE_STATS * getLFileStatPtr(
|
|
LFILE * pLFile);
|
|
|
|
RCODE checkAndUpdateState(
|
|
eDomNodeType eNodeType,
|
|
FLMUINT uiNameId);
|
|
|
|
#define FLM_UPD_ADD 0x00001
|
|
#define FLM_UPD_INTERNAL_CHANGE 0x00004
|
|
|
|
RCODE findNode(
|
|
FLMUINT uiCollection,
|
|
FLMUINT64 * pui64NodeId,
|
|
FLMUINT uiFlags);
|
|
|
|
RCODE getNode(
|
|
FLMUINT uiCollection,
|
|
FLMUINT64 ui64NodeId,
|
|
FLMUINT uiFlags,
|
|
F_DOMNode ** ppNode);
|
|
|
|
RCODE _updateNode(
|
|
F_CachedNode * pNode,
|
|
FLMUINT uiFlags);
|
|
|
|
FINLINE RCODE updateNode(
|
|
F_CachedNode * pCachedNode,
|
|
FLMUINT uiFlags)
|
|
{
|
|
flmAssert( !m_pDatabase->m_pRfl->isLoggingEnabled());
|
|
|
|
if( uiFlags || pCachedNode->getCollection() == XFLM_DICT_COLLECTION)
|
|
{
|
|
return( _updateNode( pCachedNode, uiFlags));
|
|
}
|
|
|
|
if( !pCachedNode->nodeIsDirty())
|
|
{
|
|
pCachedNode->setNodeDirty( this, FALSE);
|
|
}
|
|
|
|
return( NE_XFLM_OK);
|
|
}
|
|
|
|
RCODE getCachedBTree(
|
|
FLMUINT uiCollection,
|
|
F_Btree ** ppBTree);
|
|
|
|
RCODE flushNode(
|
|
F_Btree * pBTree,
|
|
F_CachedNode * pNode);
|
|
|
|
RCODE purgeNode(
|
|
FLMUINT uiCollection,
|
|
FLMUINT64 ui64NodeId);
|
|
|
|
RCODE allocNode(
|
|
eDomNodeType eNodeType,
|
|
F_DOMNode ** ppNode);
|
|
|
|
RCODE createRootNode(
|
|
FLMUINT uiCollection,
|
|
FLMUINT uiElementNameId,
|
|
eDomNodeType eNodeType,
|
|
F_DOMNode ** ppNewNode,
|
|
FLMUINT64 * pui64NodeId = NULL);
|
|
|
|
RCODE sweep(
|
|
IF_Thread * pThread);
|
|
|
|
RCODE sweepGatherList(
|
|
ELM_ATTR_STATE_INFO ** ppStateTbl,
|
|
FLMUINT * puiNumItems);
|
|
|
|
RCODE sweepCheckElementState(
|
|
F_DOMNode * pElementNode,
|
|
ELM_ATTR_STATE_INFO * pStateTbl,
|
|
FLMUINT * puiNumItems,
|
|
FLMBOOL * pbStartedTrans);
|
|
|
|
RCODE sweepCheckAttributeStates(
|
|
F_DOMNode * pElementNode,
|
|
ELM_ATTR_STATE_INFO * pStateTbl,
|
|
FLMUINT * puiNumItems,
|
|
FLMBOOL * pbStartedTrans);
|
|
|
|
RCODE sweepFinalizeStates(
|
|
ELM_ATTR_STATE_INFO * pStateTbl,
|
|
FLMUINT uiNumItems,
|
|
FLMBOOL * pbStartedTrans);
|
|
|
|
RCODE flushDirtyNodes( void);
|
|
|
|
RCODE flushDirtyNode(
|
|
F_CachedNode * pNode);
|
|
|
|
RCODE maintBlockChainFree(
|
|
FLMUINT64 ui64MaintDocID,
|
|
FLMUINT uiBlocksToDelete,
|
|
FLMUINT uiExpectedEndAddr,
|
|
FLMUINT * puiBlocksFreed);
|
|
|
|
RCODE encryptData(
|
|
FLMUINT uiEncDefId,
|
|
FLMBYTE * pucIV,
|
|
FLMBYTE * pucBuffer,
|
|
FLMUINT uiBufferSize,
|
|
FLMUINT uiDataLen,
|
|
FLMUINT * puiEncryptedLength);
|
|
|
|
RCODE decryptData(
|
|
FLMUINT uiEncDefId,
|
|
FLMBYTE * pucIV,
|
|
void * pvInBuf,
|
|
FLMUINT uiInLen,
|
|
void * pvOutBuf,
|
|
FLMUINT uiOutBufLen);
|
|
|
|
RCODE createDbKey();
|
|
|
|
// Private data members.
|
|
|
|
F_Database * m_pDatabase; // Pointer to F_Database object
|
|
F_Dict * m_pDict; // Pointer to dictionary object
|
|
F_Db * m_pNextForDatabase; // Next F_Db associated with F_Database
|
|
// NOTE: gv_XFlmSysData.hShareMutex
|
|
// must be locked to set this
|
|
F_Db * m_pPrevForDatabase; // Prev F_Db associated with F_Database
|
|
// NOTE: gv_XFlmSysData.hShareMutex
|
|
// must be locked to set this
|
|
void * m_pvAppData; // Application data that is used
|
|
// to associate this F_Db with
|
|
// an object in the application
|
|
// space.
|
|
FLMUINT m_uiThreadId; // Thread that started the current
|
|
// transaction, if any. NOTE:
|
|
// Only set on transaction begin.
|
|
// Hence, if operations are performed
|
|
// by multiple threads, within the
|
|
// transaction, it will not necessarily
|
|
// reflect the thread that is currently
|
|
// using the F_Db.
|
|
FLMBOOL m_bMustClose; // An error has occurred that requires
|
|
// the application to stop using (close)
|
|
// this FDB
|
|
F_SuperFileHdl * m_pSFileHdl; // Pointer to the super file handle
|
|
FLMUINT m_uiFlags; // Flags for this F_Db.
|
|
|
|
// TRANSACTION STATE STUFF
|
|
|
|
FLMUINT m_uiTransCount; // Transaction counter for the F_Db.
|
|
// Incremented whenever a transaction
|
|
// is started on this F_Db. Used so
|
|
// that FLAIM can tell if an implicit
|
|
// transaction it started is still in
|
|
// effect. This should NOT be
|
|
// confused with update transaction
|
|
// IDs.
|
|
eDbTransType m_eTransType; // Type of transaction
|
|
RCODE m_AbortRc; // If not NE_XFLM_OK, transaction must be
|
|
// aborted.
|
|
FLMUINT64 m_ui64CurrTransID;// Current transaction ID.
|
|
FLMUINT m_uiFirstAvailBlkAddr; // Address of first block in avail list
|
|
FLMUINT m_uiLogicalEOF; // Current logical end of file. New
|
|
// blocks are allocated at this address.
|
|
FLMUINT m_uiUpgradeCPFileNum;
|
|
FLMUINT m_uiUpgradeCPOffset;
|
|
// RFL file number and offset to set
|
|
// RFL to during an upgrade operation
|
|
// that happens during a restore or
|
|
// recovery.
|
|
FLMUINT m_uiTransEOF; // Address of logical end of file
|
|
// when the last transaction
|
|
// committed. A block beyond this
|
|
// point in the file is going to be
|
|
// a new block and will not need to
|
|
// be logged.
|
|
KEY_GEN_INFO m_keyGenInfo; // Information for generating index
|
|
// keys.
|
|
F_TMSTAMP m_TransStartTime; // Transaction start time, for stats
|
|
|
|
// KREF STUFF
|
|
|
|
KREF_ENTRY ** m_pKrefTbl; // Pointer to KREF table, which is an array
|
|
// of KREF_ENTRY * pointers.
|
|
FLMUINT m_uiKrefTblSize; // KREF table size.
|
|
FLMUINT m_uiKrefCount; // Number of entries in KREF table that
|
|
// are currently used.
|
|
FLMUINT m_uiTotalKrefBytes; // Total number of entries allocated
|
|
// in the pool.
|
|
FLMBYTE * m_pucKrefKeyBuf; // Pointer to temporary key buffer.
|
|
FLMBOOL m_bKrefSetup; // True if the KRef table has been initialized.
|
|
F_Pool * m_pKrefPool; // Memory pool to use
|
|
FLMBOOL m_bReuseKrefPool; // Reuse pool instead of free it?
|
|
FLMBOOL m_bKrefCompoundKey; // True if a compound key has been processed.
|
|
void * m_pKrefReset; // Used to reset the Kref pool on
|
|
// indexing failures
|
|
F_Pool m_tmpKrefPool; // KREF pool to be used during
|
|
// read transactions - only used when
|
|
// checking indexes.
|
|
|
|
// UPDATE TRANSACTION STUFF
|
|
|
|
FLMBOOL m_bHadUpdOper; // Did this transaction have any
|
|
// updates?
|
|
FLMUINT m_uiBlkChangeCnt; // Number of times ScaLogPhysBlk has
|
|
// been called during this transaction.
|
|
// This is used by the cursor code to
|
|
// know when it is necessary to
|
|
// re-position in the B-Tree.0
|
|
IXD_FIXUP * m_pIxdFixups; // List of indexes whose IXD needs
|
|
// to be restored to its prior
|
|
// state if the transaction aborts
|
|
// READ TRANSACTION STUFF
|
|
|
|
F_Db * m_pNextReadTrans; // Next active read transaction for
|
|
// this database.
|
|
// NOTE: If uiKilledTime (see below)
|
|
// is non-zero, then transaction is
|
|
// in killed list.
|
|
F_Db * m_pPrevReadTrans; // Previous active read transaction
|
|
// for this database.
|
|
// NOTE: If m_uiKilledTime (see below)
|
|
// is non-zero, then transaction is
|
|
// in killed list.
|
|
FLMUINT m_uiInactiveTime; // If non-zero, this is the last time
|
|
// the checkpoint thread marked this
|
|
// transaction as inactive. If zero,
|
|
// it means that the transaction is
|
|
// active, or it has not been marked
|
|
// by the checkpoint thread as
|
|
// inactive. If it stays non-zero for
|
|
// five or more minutes, it will be
|
|
// killed.
|
|
FLMUINT m_uiKilledTime; // Time transaction was killed, if
|
|
// non-zero.
|
|
// Misc. DB Info.
|
|
|
|
FLMBOOL m_bItemStateUpdOk;// This variable is used to ensure
|
|
// that FlmDbSweep / recovery are the
|
|
// only ways that:
|
|
// 1) an element or attribute's state
|
|
// can be changed to 'unused'
|
|
// 2) a 'purge' element or attribute
|
|
// can be deleted
|
|
|
|
F_Pool m_tempPool; // Temporary memory pool. It
|
|
// is only used for the duration of
|
|
// a FLAIM operation and then reset.
|
|
// The first block in the pool is
|
|
// retained between operations to
|
|
// help performance.
|
|
|
|
// Callback functions.
|
|
IF_DeleteStatus * m_pDeleteStatus; // Handles status info coming back
|
|
// from deleting a BTree
|
|
IF_IxClient * m_pIxClient; // Indexing callback
|
|
IF_IxStatus * m_pIxStatus; // Indexing status callback
|
|
IF_CommitClient * m_pCommitClient; // Commit callback
|
|
|
|
XFLM_STATS * m_pStats;
|
|
XFLM_DB_STATS * m_pDbStats; // DB statistics pointer.
|
|
XFLM_LFILE_STATS * m_pLFileStats; // LFILE statistics pointer.
|
|
FLMUINT m_uiLFileAllocSeq;// Allocation sequence number for
|
|
// LFILE statistics array so we
|
|
// can tell if the array has been
|
|
// reallocated and we need to reset
|
|
// our pLFileStats pointer.
|
|
XFLM_STATS m_Stats; // Statistics kept here until end
|
|
// of transaction.
|
|
FLMBOOL m_bStatsInitialized;// Has statistics structure been
|
|
// initialized?
|
|
F_BKGND_IX * m_pIxStartList; // Indexing threads to start at
|
|
// the conclusion of the transaction.
|
|
F_BKGND_IX * m_pIxStopList; // Indexing threads to stop at
|
|
// the conclusion of the transaction.
|
|
F_Btree * m_pCachedBTree; // BTree object used for node operations
|
|
F_KeyCollector * m_pKeyColl; // Special purpose object used when checking
|
|
// indexes in the F_DbCheck class.
|
|
F_OldNodeList * m_pOldNodeList; // List of old truncated nodes to use
|
|
// updating indexes.
|
|
FLMUINT m_uiDirtyNodeCount;
|
|
F_SEM m_hWaitSem; // Semaphore that is used when
|
|
// waiting for reads to complete
|
|
|
|
friend class F_Database;
|
|
friend class F_Dict;
|
|
friend class F_DbSystem;
|
|
friend class F_Rfl;
|
|
friend class F_Btree;
|
|
friend class F_Backup;
|
|
friend class F_DOMNode;
|
|
friend class F_BTreeIStream;
|
|
friend class F_DataVector;
|
|
friend class F_NodeList;
|
|
friend class F_XMLImport;
|
|
friend class F_DbRebuild;
|
|
friend class F_DbCheck;
|
|
friend class F_Query;
|
|
friend class FSIndexCursor;
|
|
friend class FSCollectionCursor;
|
|
friend class F_BtRSFactory;
|
|
friend class F_BtResultSet;
|
|
friend class F_CachedBlock;
|
|
friend class F_CachedNode;
|
|
friend class F_BlockCacheMgr;
|
|
friend class F_NodeCacheMgr;
|
|
friend class F_GlobalCacheMgr;
|
|
friend class F_QueryResultSet;
|
|
friend class F_BTreeInfo;
|
|
friend class F_AttrItem;
|
|
};
|
|
|
|
/****************************************************************************
|
|
Stuff for F_Query class
|
|
****************************************************************************/
|
|
|
|
#define FLM_FALSE 1
|
|
#define FLM_TRUE 2
|
|
#define FLM_UNK 4
|
|
|
|
FINLINE FLMBOOL isLegalOperator(
|
|
eQueryOperators eOperator)
|
|
{
|
|
return( (eOperator >= XFLM_AND_OP && eOperator <= XFLM_RBRACKET_OP)
|
|
? TRUE
|
|
: FALSE);
|
|
}
|
|
|
|
FINLINE FLMBOOL isLogicalOp(
|
|
eQueryOperators eOperator)
|
|
{
|
|
return( (eOperator >= XFLM_AND_OP && eOperator <= XFLM_NOT_OP) ? TRUE : FALSE);
|
|
}
|
|
|
|
FINLINE FLMBOOL isCompareOp(
|
|
eQueryOperators eOperator)
|
|
{
|
|
return( (eOperator >= XFLM_EQ_OP && eOperator <= XFLM_GE_OP) ? TRUE : FALSE);
|
|
}
|
|
|
|
FINLINE FLMBOOL isArithOp(
|
|
eQueryOperators eOperator)
|
|
{
|
|
return( (eOperator >= XFLM_FIRST_ARITH_OP &&
|
|
eOperator <= XFLM_LAST_ARITH_OP) ? TRUE : FALSE);
|
|
}
|
|
|
|
FINLINE FLMBOOL isUnsigned(
|
|
eValTypes eValType)
|
|
{
|
|
return( eValType == XFLM_UINT_VAL || eValType == XFLM_UINT64_VAL
|
|
? TRUE
|
|
: FALSE);
|
|
}
|
|
|
|
FINLINE FLMBOOL isSigned(
|
|
eValTypes eValType)
|
|
{
|
|
return( eValType == XFLM_INT_VAL || eValType == XFLM_INT64_VAL
|
|
? TRUE
|
|
: FALSE);
|
|
}
|
|
|
|
FINLINE FLMBOOL is64BitVal(
|
|
eValTypes eValType)
|
|
{
|
|
return( eValType == XFLM_UINT64_VAL || eValType == XFLM_INT64_VAL
|
|
? TRUE
|
|
: FALSE);
|
|
}
|
|
|
|
FINLINE FLMBOOL isNativeNum(
|
|
eValTypes eValType)
|
|
{
|
|
return( eValType == XFLM_UINT_VAL || eValType == XFLM_INT_VAL
|
|
? TRUE
|
|
: FALSE);
|
|
}
|
|
|
|
FINLINE FLMBOOL isUniversal(
|
|
FQNODE * pQNode)
|
|
{
|
|
return( pQNode->bNotted);
|
|
}
|
|
|
|
FINLINE FLMBOOL isExistential(
|
|
FQNODE * pQNode)
|
|
{
|
|
return( !pQNode->bNotted);
|
|
}
|
|
|
|
FINLINE FLMBOOL isBoolNode(
|
|
FQNODE * pQNode
|
|
)
|
|
{
|
|
return( (pQNode->eNodeType == FLM_VALUE_NODE &&
|
|
pQNode->currVal.eValType == XFLM_BOOL_VAL) ? TRUE : FALSE);
|
|
}
|
|
|
|
FINLINE FLMBOOL isSigned(
|
|
FQVALUE * pValue)
|
|
{
|
|
if( pValue->eValType == XFLM_INT_VAL || pValue->eValType == XFLM_INT64_VAL)
|
|
{
|
|
return( TRUE);
|
|
}
|
|
|
|
return( FALSE);
|
|
}
|
|
|
|
FINLINE FLMBOOL isUnsigned(
|
|
FQVALUE * pValue)
|
|
{
|
|
if( pValue->eValType == XFLM_UINT_VAL || pValue->eValType == XFLM_UINT64_VAL)
|
|
{
|
|
return( TRUE);
|
|
}
|
|
|
|
return( FALSE);
|
|
}
|
|
|
|
typedef struct ExprState * EXPR_STATE_p;
|
|
|
|
typedef struct ExprState
|
|
{
|
|
FQNODE * pExpr;
|
|
FQNODE * pCurOperatorNode;
|
|
FQNODE * pLastNode;
|
|
FLMUINT uiNestLevel;
|
|
FLMBOOL bExpectingOperator;
|
|
FLMBOOL bExpectingLParen;
|
|
FQFUNCTION * pQFunction;
|
|
XPATH_COMPONENT * pXPathComponent;
|
|
FLMUINT uiNumExprNeeded;
|
|
FLMUINT uiNumExpressions;
|
|
EXPR_STATE_p pPrev;
|
|
EXPR_STATE_p pNext;
|
|
} EXPR_STATE;
|
|
|
|
/*****************************************************************************
|
|
Desc: Object for gathering node information.
|
|
*****************************************************************************/
|
|
class F_NodeInfo : public IF_NodeInfo
|
|
{
|
|
public:
|
|
|
|
F_NodeInfo()
|
|
{
|
|
clearNodeInfo();
|
|
}
|
|
|
|
virtual ~F_NodeInfo()
|
|
{
|
|
}
|
|
|
|
FINLINE void FLMAPI clearNodeInfo( void)
|
|
{
|
|
f_memset( &m_nodeInfo, 0, sizeof( m_nodeInfo));
|
|
m_ui64TotalNodes = 0;
|
|
}
|
|
|
|
RCODE FLMAPI addNodeInfo(
|
|
IF_Db * pDb,
|
|
IF_DOMNode * pNode,
|
|
FLMBOOL bDoSubTree,
|
|
FLMBOOL bDoSelf = TRUE);
|
|
|
|
FINLINE FLMUINT64 FLMAPI getTotalNodeCount( void)
|
|
{
|
|
return( m_ui64TotalNodes);
|
|
}
|
|
|
|
FINLINE void FLMAPI getNodeInfo(
|
|
XFLM_NODE_INFO * pNodeInfo)
|
|
{
|
|
f_memcpy( pNodeInfo, &m_nodeInfo, sizeof( m_nodeInfo));
|
|
}
|
|
|
|
private:
|
|
|
|
XFLM_NODE_INFO m_nodeInfo;
|
|
FLMUINT64 m_ui64TotalNodes;
|
|
};
|
|
|
|
typedef struct BTREE_INFO
|
|
{
|
|
FLMUINT uiLfNum;
|
|
char * pszLfName;
|
|
FLMUINT uiNumLevels;
|
|
XFLM_BTREE_LEVEL_INFO levelInfo [MAX_LEVELS];
|
|
} BTREE_INFO;
|
|
|
|
/*****************************************************************************
|
|
Desc: Object for gathering B-Tree information.
|
|
*****************************************************************************/
|
|
class F_BTreeInfo : public IF_BTreeInfo
|
|
{
|
|
public:
|
|
F_BTreeInfo()
|
|
{
|
|
m_pIndexArray = NULL;
|
|
m_uiIndexArraySize = 0;
|
|
m_uiNumIndexes = 0;
|
|
m_pCollectionArray = NULL;
|
|
m_uiCollectionArraySize = 0;
|
|
m_uiNumCollections = 0;
|
|
m_pool.poolInit( 512);
|
|
}
|
|
|
|
virtual ~F_BTreeInfo()
|
|
{
|
|
if (m_pIndexArray)
|
|
{
|
|
f_free( &m_pIndexArray);
|
|
}
|
|
if (m_pCollectionArray)
|
|
{
|
|
f_free( &m_pCollectionArray);
|
|
}
|
|
m_pool.poolFree();
|
|
}
|
|
|
|
FINLINE void FLMAPI clearBTreeInfo( void)
|
|
{
|
|
m_uiNumIndexes = 0;
|
|
m_uiNumCollections = 0;
|
|
}
|
|
|
|
RCODE FLMAPI collectIndexInfo(
|
|
IF_Db * pDb,
|
|
FLMUINT uiIndexNum,
|
|
IF_BTreeInfoStatus * pInfoStatus);
|
|
|
|
RCODE FLMAPI collectCollectionInfo(
|
|
IF_Db * pDb,
|
|
FLMUINT uiCollectionNum,
|
|
IF_BTreeInfoStatus * pInfoStatus);
|
|
|
|
FINLINE FLMUINT FLMAPI getNumIndexes( void)
|
|
{
|
|
return( m_uiNumIndexes);
|
|
}
|
|
|
|
FINLINE FLMUINT FLMAPI getNumCollections( void)
|
|
{
|
|
return( m_uiNumCollections);
|
|
}
|
|
|
|
FINLINE FLMBOOL FLMAPI getIndexInfo(
|
|
FLMUINT uiNthIndex,
|
|
FLMUINT * puiIndexNum,
|
|
char ** ppszIndexName,
|
|
FLMUINT * puiNumLevels)
|
|
{
|
|
if (uiNthIndex < m_uiNumIndexes)
|
|
{
|
|
*puiIndexNum = m_pIndexArray [uiNthIndex].uiLfNum;
|
|
*puiNumLevels = m_pIndexArray [uiNthIndex].uiNumLevels;
|
|
*ppszIndexName = m_pIndexArray [uiNthIndex].pszLfName;
|
|
return( TRUE);
|
|
}
|
|
else
|
|
{
|
|
*puiIndexNum = 0;
|
|
*ppszIndexName = NULL;
|
|
*puiNumLevels = 0;
|
|
return( FALSE);
|
|
}
|
|
}
|
|
|
|
FINLINE FLMBOOL FLMAPI getCollectionInfo(
|
|
FLMUINT uiNthCollection,
|
|
FLMUINT * puiCollectionNum,
|
|
char ** ppszCollectionName,
|
|
FLMUINT * puiNumLevels)
|
|
{
|
|
if (uiNthCollection < m_uiNumCollections)
|
|
{
|
|
*puiCollectionNum = m_pCollectionArray [uiNthCollection].uiLfNum;
|
|
*puiNumLevels = m_pCollectionArray [uiNthCollection].uiNumLevels;
|
|
*ppszCollectionName = m_pCollectionArray [uiNthCollection].pszLfName;
|
|
return( TRUE);
|
|
}
|
|
else
|
|
{
|
|
*puiCollectionNum = 0;
|
|
*puiNumLevels = 0;
|
|
*ppszCollectionName = NULL;
|
|
return( FALSE);
|
|
}
|
|
}
|
|
|
|
FINLINE FLMBOOL FLMAPI getIndexLevelInfo(
|
|
FLMUINT uiNthIndex,
|
|
FLMUINT uiBTreeLevel,
|
|
XFLM_BTREE_LEVEL_INFO * pLevelInfo)
|
|
{
|
|
if (uiNthIndex < m_uiNumIndexes &&
|
|
uiBTreeLevel < m_pIndexArray [uiNthIndex].uiNumLevels)
|
|
{
|
|
f_memcpy( pLevelInfo,
|
|
&(m_pIndexArray [uiNthIndex].levelInfo [uiBTreeLevel]),
|
|
sizeof( XFLM_BTREE_LEVEL_INFO));
|
|
return( TRUE);
|
|
}
|
|
else
|
|
{
|
|
return( FALSE);
|
|
}
|
|
}
|
|
|
|
FINLINE FLMBOOL FLMAPI getCollectionLevelInfo(
|
|
FLMUINT uiNthCollection,
|
|
FLMUINT uiBTreeLevel,
|
|
XFLM_BTREE_LEVEL_INFO * pLevelInfo)
|
|
{
|
|
if (uiNthCollection < m_uiNumCollections &&
|
|
uiBTreeLevel < m_pCollectionArray [uiNthCollection].uiNumLevels)
|
|
{
|
|
f_memcpy( pLevelInfo,
|
|
&(m_pCollectionArray [uiNthCollection].levelInfo [uiBTreeLevel]),
|
|
sizeof( XFLM_BTREE_LEVEL_INFO));
|
|
return( TRUE);
|
|
}
|
|
else
|
|
{
|
|
return( FALSE);
|
|
}
|
|
}
|
|
|
|
private:
|
|
|
|
RCODE collectBlockInfo(
|
|
F_Db * pDb,
|
|
LFILE * pLFile,
|
|
BTREE_INFO * pBTreeInfo,
|
|
F_BTREE_BLK_HDR * pBlkHdr,
|
|
IXD * pIxd);
|
|
|
|
RCODE collectBTreeInfo(
|
|
F_Db * pDb,
|
|
LFILE * pLFile,
|
|
BTREE_INFO * pBTreeInfo,
|
|
IXD * pIxd);
|
|
|
|
FINLINE RCODE doCallback( void)
|
|
{
|
|
if (m_pInfoStatus)
|
|
{
|
|
return( m_pInfoStatus->infoStatus( m_uiCurrLfNum, m_bIsCollection,
|
|
m_pszCurrLfName, m_uiCurrLevel,
|
|
m_ui64CurrLfBlockCount, m_ui64CurrLevelBlockCount,
|
|
m_ui64TotalBlockCount));
|
|
}
|
|
else
|
|
{
|
|
return( NE_XFLM_OK);
|
|
}
|
|
}
|
|
|
|
BTREE_INFO * m_pIndexArray;
|
|
FLMUINT m_uiIndexArraySize;
|
|
FLMUINT m_uiNumIndexes;
|
|
BTREE_INFO * m_pCollectionArray;
|
|
FLMUINT m_uiCollectionArraySize;
|
|
FLMUINT m_uiNumCollections;
|
|
F_Pool m_pool;
|
|
|
|
// Items for the callback function.
|
|
|
|
IF_BTreeInfoStatus * m_pInfoStatus;
|
|
FLMUINT m_uiBlockSize;
|
|
FLMUINT m_uiCurrLfNum;
|
|
FLMBOOL m_bIsCollection;
|
|
char * m_pszCurrLfName;
|
|
FLMUINT m_uiCurrLevel;
|
|
FLMUINT64 m_ui64CurrLfBlockCount;
|
|
FLMUINT64 m_ui64CurrLevelBlockCount;
|
|
FLMUINT64 m_ui64TotalBlockCount;
|
|
};
|
|
|
|
RCODE ixKeyCompare(
|
|
F_Db * pDb,
|
|
IXD * pIxd,
|
|
F_DataVector * pSearchKey,
|
|
F_OldNodeList * pOldNodeList1,
|
|
F_OldNodeList * pOldNodeList2,
|
|
FLMBOOL bCompareDocId,
|
|
FLMBOOL bCompareNodeIds,
|
|
const void * pvKey1,
|
|
FLMUINT uiKeyLen1,
|
|
const void * pvKey2,
|
|
FLMUINT uiKeyLen2,
|
|
FLMINT * piCompare);
|
|
|
|
/********************************************************************
|
|
Desc: Class for comparing two keys in an index.
|
|
********************************************************************/
|
|
class IXKeyCompare : public IF_ResultSetCompare
|
|
{
|
|
public:
|
|
|
|
IXKeyCompare()
|
|
{
|
|
|
|
// m_pDb is used to sort truncated keys if necessary.
|
|
// m_pIxd is used for comparison
|
|
|
|
m_pDb = NULL;
|
|
m_pIxd = NULL;
|
|
m_pSearchKey = NULL;
|
|
m_pOldNodeList = NULL;
|
|
m_bCompareDocId = TRUE;
|
|
m_bCompareNodeIds = TRUE;
|
|
}
|
|
|
|
virtual ~IXKeyCompare()
|
|
{
|
|
if (m_pOldNodeList)
|
|
{
|
|
m_pOldNodeList->Release();
|
|
}
|
|
}
|
|
|
|
FINLINE RCODE FLMAPI compare(
|
|
const void * pvKey1,
|
|
FLMUINT uiKeyLen1,
|
|
const void * pvKey2,
|
|
FLMUINT uiKeyLen2,
|
|
FLMINT * piCompare)
|
|
{
|
|
return( ixKeyCompare( m_pDb, m_pIxd, m_pSearchKey, m_pOldNodeList,
|
|
m_pOldNodeList,
|
|
m_bCompareDocId, m_bCompareNodeIds,
|
|
pvKey1, uiKeyLen1, pvKey2, uiKeyLen2, piCompare));
|
|
}
|
|
|
|
FINLINE void setOldNodeList(
|
|
F_OldNodeList * pOldNodeList)
|
|
{
|
|
flmAssert( !m_pOldNodeList);
|
|
if ((m_pOldNodeList = pOldNodeList) != NULL)
|
|
{
|
|
m_pOldNodeList->AddRef();
|
|
}
|
|
}
|
|
|
|
FINLINE void setIxInfo(
|
|
F_Db * pDb,
|
|
IXD * pIxd)
|
|
{
|
|
m_pDb = pDb;
|
|
m_pIxd = pIxd;
|
|
}
|
|
|
|
FINLINE void setSearchKey(
|
|
F_DataVector * pSearchKey)
|
|
{
|
|
m_pSearchKey = pSearchKey;
|
|
}
|
|
|
|
FINLINE void setCompareNodeIds(
|
|
FLMBOOL bCompareNodeIds)
|
|
{
|
|
m_bCompareNodeIds = bCompareNodeIds;
|
|
}
|
|
|
|
FINLINE void setCompareDocId(
|
|
FLMBOOL bCompareDocId)
|
|
{
|
|
m_bCompareDocId = bCompareDocId;
|
|
}
|
|
|
|
virtual FLMINT FLMAPI getRefCount( void)
|
|
{
|
|
return( IF_ResultSetCompare::getRefCount());
|
|
}
|
|
|
|
virtual FLMINT FLMAPI AddRef( void)
|
|
{
|
|
return( IF_ResultSetCompare::AddRef());
|
|
}
|
|
|
|
virtual FLMINT FLMAPI Release( void)
|
|
{
|
|
return( IF_ResultSetCompare::Release());
|
|
}
|
|
|
|
private:
|
|
|
|
F_Db * m_pDb;
|
|
IXD * m_pIxd;
|
|
F_DataVector * m_pSearchKey;
|
|
F_OldNodeList * m_pOldNodeList;
|
|
FLMBOOL m_bCompareDocId;
|
|
FLMBOOL m_bCompareNodeIds;
|
|
};
|
|
|
|
/*=============================================================================
|
|
Desc: Result set class for queries that do sorting.
|
|
=============================================================================*/
|
|
class F_QueryResultSet : public F_Object
|
|
{
|
|
public:
|
|
|
|
F_QueryResultSet()
|
|
{
|
|
m_pBTree = NULL;
|
|
m_pResultSetDb = NULL;
|
|
m_pSrcDb = NULL;
|
|
m_pIxd = NULL;
|
|
m_uiCurrPos = FLM_MAX_UINT;
|
|
m_uiCount = 0;
|
|
m_bPositioned = FALSE;
|
|
m_hMutex = F_MUTEX_NULL;
|
|
}
|
|
|
|
~F_QueryResultSet();
|
|
|
|
// Initialize the result set
|
|
|
|
RCODE initResultSet(
|
|
FLMBOOL bUseIxCompareObj,
|
|
FLMBOOL bEnableEncryption);
|
|
|
|
FINLINE void setIxInfo(
|
|
F_Db * pSrcDb,
|
|
IXD * pIxd)
|
|
{
|
|
m_pSrcDb = pSrcDb;
|
|
m_pIxd = pIxd;
|
|
m_compareObj.setIxInfo( pSrcDb, pIxd);
|
|
}
|
|
|
|
// Entry Add and Sort Methods
|
|
|
|
RCODE addEntry( // Variable or fixed length entry coming in
|
|
FLMBYTE * pucKey, // key for sorting.
|
|
FLMUINT uiKeyLength,
|
|
FLMBOOL bLockMutex);
|
|
|
|
// Methods to read entries.
|
|
|
|
RCODE getFirst(
|
|
FLMBYTE * pucKey,
|
|
FLMUINT uiKeyBufSize,
|
|
FLMUINT * puiKeyLen,
|
|
FLMBOOL bLockMutex);
|
|
|
|
RCODE getLast(
|
|
FLMBYTE * pucKey,
|
|
FLMUINT uiKeyBufSize,
|
|
FLMUINT * puiKeyLen,
|
|
FLMBOOL bLockMutex);
|
|
|
|
RCODE getNext(
|
|
FLMBYTE * pucKey,
|
|
FLMUINT uiKeyBufSize,
|
|
FLMUINT * puiKeyLen,
|
|
FLMBOOL bLockMutex);
|
|
|
|
RCODE getPrev(
|
|
FLMBYTE * pucKey,
|
|
FLMUINT uiKeyBufSize,
|
|
FLMUINT * puiKeyLen,
|
|
FLMBOOL bLockMutex);
|
|
|
|
RCODE getCurrent(
|
|
FLMBYTE * pucKey,
|
|
FLMUINT uiKeyBufSize,
|
|
FLMUINT * puiKeyLen,
|
|
FLMBOOL bLockMutex);
|
|
|
|
RCODE positionToEntry(
|
|
FLMBYTE * pucKey,
|
|
FLMUINT uiKeyBufSize,
|
|
FLMUINT * puiKeyLen,
|
|
F_DataVector * pSearchKey,
|
|
FLMUINT uiFlags,
|
|
FLMBOOL bLockMutex);
|
|
|
|
RCODE positionToEntry(
|
|
FLMUINT uiPosition,
|
|
FLMBYTE * pucKey,
|
|
FLMUINT uiKeyBufSize,
|
|
FLMUINT * puiKeyLen,
|
|
FLMBOOL bLockMutex);
|
|
|
|
FINLINE FLMUINT getCount( void)
|
|
{
|
|
return( m_uiCount);
|
|
}
|
|
|
|
FINLINE FLMUINT getCurrPos( void)
|
|
{
|
|
return( m_uiCurrPos);
|
|
}
|
|
|
|
FINLINE void lockMutex( void)
|
|
{
|
|
f_mutexLock( m_hMutex);
|
|
}
|
|
|
|
FINLINE void unlockMutex( void)
|
|
{
|
|
f_mutexUnlock( m_hMutex);
|
|
}
|
|
|
|
private:
|
|
|
|
char m_szResultSetDibName [F_PATH_MAX_SIZE];
|
|
F_Db * m_pResultSetDb;
|
|
F_Btree * m_pBTree;
|
|
LFILE m_LFile;
|
|
F_Db * m_pSrcDb;
|
|
IXD * m_pIxd;
|
|
IXKeyCompare m_compareObj;
|
|
FLMUINT m_uiCurrPos;
|
|
FLMUINT m_uiCount;
|
|
FLMBOOL m_bPositioned;
|
|
F_MUTEX m_hMutex;
|
|
};
|
|
|
|
typedef struct RS_WAITER
|
|
{
|
|
FLMUINT uiThreadId; // Thread of waiter
|
|
F_SEM hESem; // Semaphore to signal to wake up thread.
|
|
RCODE * pRc; // Pointer to return code that is to
|
|
// be set.
|
|
FLMUINT uiWaitStartTime;
|
|
// Time we started waiting.
|
|
FLMUINT uiTimeLimit; // Maximum time (milliseconds) to wait
|
|
// before timing out.
|
|
FLMUINT uiNumToWaitFor;// Wait until we get at least this many
|
|
// in the result set - or until the
|
|
// result set is complete.
|
|
RS_WAITER * pNext; // Next lock waiter in list.
|
|
RS_WAITER * pPrev; // Previous lock waiter in list.
|
|
} RS_WAITER;
|
|
|
|
/****************************************************************************
|
|
Desc: Class for setting up query criteria
|
|
****************************************************************************/
|
|
class F_Query : public IF_Query
|
|
{
|
|
public:
|
|
|
|
F_Query();
|
|
|
|
virtual ~F_Query();
|
|
|
|
// Methods for constructing a query
|
|
|
|
FINLINE RCODE FLMAPI setLanguage(
|
|
FLMUINT uiLanguage)
|
|
{
|
|
|
|
// Cannot change language after optimization
|
|
|
|
if (m_bOptimized)
|
|
{
|
|
return( RC_SET( NE_XFLM_Q_ALREADY_OPTIMIZED));
|
|
}
|
|
m_uiLanguage = uiLanguage;
|
|
return( NE_XFLM_OK);
|
|
}
|
|
|
|
FINLINE RCODE FLMAPI setCollection(
|
|
FLMUINT uiCollection
|
|
)
|
|
{
|
|
|
|
// Cannot change collection after optimization
|
|
|
|
if (m_bOptimized)
|
|
{
|
|
return( RC_SET( NE_XFLM_Q_ALREADY_OPTIMIZED));
|
|
}
|
|
m_uiCollection = uiCollection;
|
|
return( NE_XFLM_OK);
|
|
}
|
|
|
|
FINLINE RCODE FLMAPI setupQueryExpr(
|
|
IF_Db * pDb,
|
|
const FLMUNICODE * puzQuery)
|
|
{
|
|
return( setupQueryExpr( TRUE, pDb, (void *)puzQuery));
|
|
}
|
|
|
|
FINLINE RCODE FLMAPI setupQueryExpr(
|
|
IF_Db * pDb,
|
|
const char * pszQuery)
|
|
{
|
|
return( setupQueryExpr( FALSE, pDb, (void *)pszQuery));
|
|
}
|
|
|
|
RCODE FLMAPI copyCriteria(
|
|
IF_Query * pSrcQuery);
|
|
|
|
RCODE FLMAPI addXPathComponent(
|
|
eXPathAxisTypes eXPathAxis,
|
|
eDomNodeType eNodeType,
|
|
FLMUINT uiNameId,
|
|
IF_QueryNodeSource * pNodeSource);
|
|
|
|
RCODE FLMAPI addOperator(
|
|
eQueryOperators eOperator,
|
|
FLMUINT uiCompareRules = 0,
|
|
IF_OperandComparer * pOpComparer = NULL);
|
|
|
|
RCODE FLMAPI addUnicodeValue(
|
|
const FLMUNICODE * puzVal);
|
|
|
|
RCODE FLMAPI addUTF8Value(
|
|
const char * pszVal,
|
|
FLMUINT uiUTF8Len = 0);
|
|
|
|
RCODE FLMAPI addBinaryValue(
|
|
const void * pvVal,
|
|
FLMUINT uiValLen);
|
|
|
|
RCODE FLMAPI addUINTValue(
|
|
FLMUINT uiVal);
|
|
|
|
RCODE FLMAPI addINTValue(
|
|
FLMINT iVal);
|
|
|
|
RCODE FLMAPI addUINT64Value(
|
|
FLMUINT64 ui64Val);
|
|
|
|
RCODE FLMAPI addINT64Value(
|
|
FLMINT64 i64Val);
|
|
|
|
RCODE FLMAPI addBoolean(
|
|
FLMBOOL bVal,
|
|
FLMBOOL bUnknown = FALSE);
|
|
|
|
FINLINE RCODE FLMAPI addFunction(
|
|
eQueryFunctions eFunction)
|
|
{
|
|
return( addFunction( eFunction, NULL, FALSE));
|
|
}
|
|
|
|
FINLINE RCODE FLMAPI addFunction(
|
|
IF_QueryValFunc * pFuncObj,
|
|
FLMBOOL bHasXPathExpr)
|
|
{
|
|
// Pass XFLM_FUNC_xxx to private addFunction method - it really
|
|
// doesn't matter, because it will be ignored.
|
|
|
|
flmAssert( pFuncObj);
|
|
return( addFunction( XFLM_FUNC_xxx, pFuncObj, bHasXPathExpr));
|
|
}
|
|
|
|
RCODE FLMAPI getFirst(
|
|
IF_Db * pDb,
|
|
IF_DOMNode ** ppNode,
|
|
FLMUINT uiTimeLimit = 0);
|
|
|
|
RCODE FLMAPI getLast(
|
|
IF_Db * pDb,
|
|
IF_DOMNode ** ppNode,
|
|
FLMUINT uiTimeLimit = 0);
|
|
|
|
RCODE FLMAPI getNext(
|
|
IF_Db * pDb,
|
|
IF_DOMNode ** ppNode,
|
|
FLMUINT uiTimeLimit = 0,
|
|
FLMUINT uiNumToSkip = 0,
|
|
FLMUINT * puiNumSkipped = NULL);
|
|
|
|
RCODE FLMAPI getPrev(
|
|
IF_Db * pDb,
|
|
IF_DOMNode ** ppNode,
|
|
FLMUINT uiTimeLimit = 0,
|
|
FLMUINT uiNumToSkip = 0,
|
|
FLMUINT * puiNumSkipped = NULL);
|
|
|
|
RCODE FLMAPI getCurrent(
|
|
IF_Db * pDb,
|
|
IF_DOMNode ** ppNode);
|
|
|
|
void FLMAPI resetQuery( void);
|
|
|
|
RCODE FLMAPI getStatsAndOptInfo(
|
|
FLMUINT * puiNumOptInfos,
|
|
XFLM_OPT_INFO ** ppOptInfo);
|
|
|
|
void FLMAPI freeStatsAndOptInfo(
|
|
XFLM_OPT_INFO ** ppOptInfo);
|
|
|
|
void FLMAPI setDupHandling(
|
|
FLMBOOL bRemoveDups);
|
|
|
|
RCODE FLMAPI setIndex(
|
|
FLMUINT uiIndex);
|
|
|
|
RCODE FLMAPI getIndex(
|
|
IF_Db * pDb,
|
|
FLMUINT * puiIndex,
|
|
FLMBOOL * pbHaveMultiple);
|
|
|
|
RCODE FLMAPI addSortKey(
|
|
void * pvSortKeyContext,
|
|
FLMBOOL bChildToContext,
|
|
FLMBOOL bElement,
|
|
FLMUINT uiNameId,
|
|
FLMUINT uiCompareRules,
|
|
FLMUINT uiLimit,
|
|
FLMUINT uiKeyComponent,
|
|
FLMBOOL bSortDescending,
|
|
FLMBOOL bSortMissingHigh,
|
|
void ** ppvContext);
|
|
|
|
FINLINE RCODE FLMAPI enablePositioning( void)
|
|
{
|
|
if (m_bOptimized)
|
|
{
|
|
return( RC_SET( NE_XFLM_ILLEGAL_OP));
|
|
}
|
|
else
|
|
{
|
|
m_bPositioningEnabled = TRUE;
|
|
}
|
|
return( NE_XFLM_OK);
|
|
}
|
|
|
|
RCODE FLMAPI positionTo(
|
|
IF_Db * pDb,
|
|
IF_DOMNode ** ppNode,
|
|
FLMUINT uiTimeLimit,
|
|
FLMUINT uiPosition);
|
|
|
|
RCODE FLMAPI positionTo(
|
|
IF_Db * pDb,
|
|
IF_DOMNode ** ppNode,
|
|
FLMUINT uiTimeLimit,
|
|
IF_DataVector * pSearchKey,
|
|
FLMUINT uiFlags);
|
|
|
|
RCODE FLMAPI getPosition(
|
|
IF_Db * pDb,
|
|
FLMUINT * puiPosition);
|
|
|
|
RCODE FLMAPI buildResultSet(
|
|
IF_Db * pDb,
|
|
FLMUINT uiTimeLimit);
|
|
|
|
void FLMAPI stopBuildingResultSet( void);
|
|
|
|
RCODE FLMAPI getCounts(
|
|
IF_Db * pDb,
|
|
FLMUINT uiTimeLimit,
|
|
FLMBOOL bPartialCountOk,
|
|
FLMUINT * puiReadCount,
|
|
FLMUINT * puiPassedCount,
|
|
FLMUINT * puiPositionableToCount,
|
|
FLMBOOL * pbDoneBuildingResultSet = NULL);
|
|
|
|
FINLINE void FLMAPI enableResultSetEncryption( void)
|
|
{
|
|
m_bEncryptResultSet = TRUE;
|
|
}
|
|
|
|
FINLINE void FLMAPI setQueryStatusObject(
|
|
IF_QueryStatus * pQueryStatus)
|
|
{
|
|
if (m_pQueryStatus)
|
|
{
|
|
m_pQueryStatus->Release();
|
|
}
|
|
if ((m_pQueryStatus = pQueryStatus) != NULL)
|
|
{
|
|
m_pQueryStatus->AddRef();
|
|
}
|
|
}
|
|
|
|
FINLINE void FLMAPI setQueryValidatorObject(
|
|
IF_QueryValidator * pQueryValidator)
|
|
{
|
|
if (m_pQueryValidator)
|
|
{
|
|
m_pQueryValidator->Release();
|
|
}
|
|
if ((m_pQueryValidator = pQueryValidator) != NULL)
|
|
{
|
|
m_pQueryValidator->AddRef();
|
|
}
|
|
}
|
|
|
|
private:
|
|
|
|
RCODE FLMAPI addFunction(
|
|
eQueryFunctions eFunction,
|
|
IF_QueryValFunc * pFuncObj,
|
|
FLMBOOL bHasXPathExpr);
|
|
|
|
FINLINE FLMBOOL timedOut( void)
|
|
{
|
|
if (m_uiTimeLimit)
|
|
{
|
|
FLMUINT uiCurrTime;
|
|
|
|
uiCurrTime = FLM_GET_TIMER();
|
|
if (FLM_ELAPSED_TIME( uiCurrTime, m_uiStartTime) > m_uiTimeLimit)
|
|
{
|
|
return( TRUE);
|
|
}
|
|
}
|
|
return( FALSE);
|
|
}
|
|
|
|
FINLINE RCODE queryStatus( void)
|
|
{
|
|
if (timedOut())
|
|
{
|
|
return( RC_SET( NE_XFLM_TIMEOUT));
|
|
}
|
|
if (m_uiBuildThreadId && m_bStopBuildingResultSet)
|
|
{
|
|
return( RC_SET( NE_XFLM_USER_ABORT));
|
|
}
|
|
return( (RCODE)(m_pQueryStatus
|
|
? m_pQueryStatus->queryStatus( m_pCurrOpt)
|
|
: (RCODE)NE_XFLM_OK));
|
|
}
|
|
|
|
FINLINE RCODE newSource( void)
|
|
{
|
|
if (timedOut())
|
|
{
|
|
return( RC_SET( NE_XFLM_TIMEOUT));
|
|
}
|
|
if (m_uiBuildThreadId && m_bStopBuildingResultSet)
|
|
{
|
|
return( RC_SET( NE_XFLM_USER_ABORT));
|
|
}
|
|
return( (RCODE)(m_pQueryStatus
|
|
? m_pQueryStatus->newSource( m_pCurrOpt)
|
|
: (RCODE)NE_XFLM_OK));
|
|
}
|
|
|
|
FINLINE RCODE incrNodesRead( void)
|
|
{
|
|
m_pCurrOpt->ui64NodesRead++;
|
|
return( queryStatus());
|
|
}
|
|
|
|
FINLINE FLMBOOL expectingOperand( void)
|
|
{
|
|
return( !m_pCurExprState->bExpectingOperator);
|
|
}
|
|
|
|
FINLINE FLMBOOL expectingOperator( void)
|
|
{
|
|
return( m_pCurExprState->bExpectingOperator);
|
|
}
|
|
|
|
FINLINE FLMBOOL parsingFunction( void)
|
|
{
|
|
return( (FLMBOOL)(m_pCurExprState->pPrev &&
|
|
m_pCurExprState->pQFunction
|
|
? TRUE
|
|
: FALSE));
|
|
}
|
|
|
|
FINLINE FLMBOOL parsingXPathExpr( void)
|
|
{
|
|
return( (FLMBOOL)(m_pCurExprState->pPrev &&
|
|
m_pCurExprState->pXPathComponent &&
|
|
!m_pCurExprState->pQFunction
|
|
? TRUE
|
|
: FALSE));
|
|
}
|
|
|
|
RCODE allocExprState( void);
|
|
|
|
RCODE allocValueNode(
|
|
FLMUINT uiValLen,
|
|
eValTypes eValType,
|
|
FQNODE ** ppQNode);
|
|
|
|
RCODE intersectPredicates(
|
|
CONTEXT_PATH * pContextPath,
|
|
FQNODE * pXPathNode,
|
|
eQueryOperators eOperator,
|
|
FLMUINT uiCompareRules,
|
|
IF_OperandComparer * pOpComparer,
|
|
FQNODE * pContextNode,
|
|
FLMBOOL bNotted,
|
|
FQVALUE * pQValue,
|
|
FLMBOOL * pbClipContext);
|
|
|
|
RCODE unionPredicates(
|
|
CONTEXT_PATH * pContextPath,
|
|
FQNODE * pXPathNode,
|
|
eQueryOperators eOperator,
|
|
FLMUINT uiCompareRules,
|
|
IF_OperandComparer * pOpComparer,
|
|
FQNODE * pContextNode,
|
|
FLMBOOL bNotted,
|
|
FQVALUE * pQValue);
|
|
|
|
RCODE addPredicateToContext(
|
|
OP_CONTEXT * pContext,
|
|
XPATH_COMPONENT * pXPathComponent,
|
|
XPATH_COMPONENT * pXPathComp,
|
|
eQueryOperators eOperator,
|
|
FLMUINT uiCompareRules,
|
|
IF_OperandComparer * pOpComparer,
|
|
FQNODE * pContextNode,
|
|
FLMBOOL bNotted,
|
|
FQVALUE * pQValue,
|
|
FLMBOOL * pbClipContext,
|
|
FQNODE ** ppQNode);
|
|
|
|
RCODE createOpContext(
|
|
OP_CONTEXT * pParentContext,
|
|
FLMBOOL bIntersect,
|
|
FQNODE * pQRootNode);
|
|
|
|
RCODE getPathPredicates(
|
|
FQNODE * pParentNode,
|
|
FQNODE ** ppQNode,
|
|
XPATH_COMPONENT * pXPathContext);
|
|
|
|
RCODE getPredicates(
|
|
FQNODE ** ppExpr,
|
|
FQNODE * pStartNode,
|
|
XPATH_COMPONENT * pXPathComponent);
|
|
|
|
RCODE optimizePredicate(
|
|
XPATH_COMPONENT * pXPathComponent,
|
|
PATH_PRED * pPred);
|
|
|
|
RCODE optimizePath(
|
|
CONTEXT_PATH * pContextPath,
|
|
PATH_PRED * pSingleNodeIdPred,
|
|
FLMBOOL bIntersect);
|
|
|
|
RCODE optimizeContext(
|
|
OP_CONTEXT * pContext,
|
|
CONTEXT_PATH * pSingleNodeIdPath,
|
|
PATH_PRED * pSingleNodeIdPred);
|
|
|
|
RCODE setupIndexScan( void);
|
|
|
|
RCODE checkSortIndex(
|
|
FLMUINT uiOptIndex);
|
|
|
|
RCODE optimize( void);
|
|
|
|
RCODE setupCurrPredicate(
|
|
FLMBOOL bForward);
|
|
|
|
RCODE testPassed(
|
|
IF_DOMNode ** ppNode,
|
|
FLMBOOL * pbPassed,
|
|
FLMBOOL * pbEliminatedDup);
|
|
|
|
RCODE nextFromIndex(
|
|
FLMBOOL bEvalCurrDoc,
|
|
FLMUINT uiMaxToSkip,
|
|
FLMUINT * puiNumSkipped,
|
|
IF_DOMNode ** ppNode);
|
|
|
|
RCODE prevFromIndex(
|
|
FLMBOOL bEvalCurrDoc,
|
|
FLMUINT uiMaxToSkip,
|
|
FLMUINT * puiNumSkipped,
|
|
IF_DOMNode ** ppNode);
|
|
|
|
RCODE getDocFromIndexScan(
|
|
FLMBOOL bFirstLast,
|
|
FLMBOOL bForward);
|
|
|
|
RCODE nextFromScan(
|
|
FLMBOOL bFirstDoc,
|
|
FLMUINT uiMaxToSkip,
|
|
FLMUINT * puiNumSkipped,
|
|
IF_DOMNode ** ppNode);
|
|
|
|
RCODE prevFromScan(
|
|
FLMBOOL bLastDoc,
|
|
FLMUINT uiMaxToSkip,
|
|
FLMUINT * puiNumSkipped,
|
|
IF_DOMNode ** ppNode);
|
|
|
|
void useLeafContext(
|
|
FLMBOOL bGetFirst);
|
|
|
|
FLMBOOL useNextPredicate( void);
|
|
|
|
FLMBOOL usePrevPredicate( void);
|
|
|
|
RCODE getNodeSourceNode(
|
|
FLMBOOL bForward,
|
|
IF_QueryNodeSource * pNodeSource,
|
|
IF_DOMNode * pContextNode,
|
|
IF_DOMNode ** ppCurrNode);
|
|
|
|
RCODE getRootAxisNode(
|
|
IF_DOMNode ** ppCurrNode);
|
|
|
|
RCODE walkDocument(
|
|
FLMBOOL bForward,
|
|
FLMBOOL bWalkAttributes,
|
|
FLMUINT uiAttrNameId,
|
|
IF_DOMNode ** ppCurrNode);
|
|
|
|
RCODE getChildAxisNode(
|
|
FLMBOOL bForward,
|
|
IF_DOMNode * pContextNode,
|
|
FLMUINT uiChildNameId,
|
|
IF_DOMNode ** ppCurrNode);
|
|
|
|
RCODE getParentAxisNode(
|
|
FLMBOOL bForward,
|
|
IF_DOMNode * pContextNode,
|
|
IF_DOMNode ** ppCurrNode);
|
|
|
|
RCODE getAncestorAxisNode(
|
|
FLMBOOL bForward,
|
|
FLMBOOL bIncludeSelf,
|
|
IF_DOMNode * pContextNode,
|
|
IF_DOMNode ** ppCurrNode);
|
|
|
|
RCODE getDescendantAxisNode(
|
|
FLMBOOL bForward,
|
|
FLMBOOL bIncludeSelf,
|
|
IF_DOMNode * pContextNode,
|
|
IF_DOMNode ** ppCurrNode);
|
|
|
|
RCODE getSibAxisNode(
|
|
FLMBOOL bForward,
|
|
FLMBOOL bPrevSibAxis,
|
|
IF_DOMNode * pContextNode,
|
|
IF_DOMNode ** ppCurrNode);
|
|
|
|
RCODE getPrevOrAfterAxisNode(
|
|
FLMBOOL bForward,
|
|
FLMBOOL bPrevAxis,
|
|
IF_DOMNode * pContextNode,
|
|
IF_DOMNode ** ppCurrNode);
|
|
|
|
RCODE getAttrAxisNode(
|
|
FLMBOOL bForward,
|
|
FLMBOOL bAttrAxis,
|
|
FLMUINT uiAttrNameId,
|
|
IF_DOMNode * pContextNode,
|
|
IF_DOMNode ** ppCurrNode);
|
|
|
|
RCODE verifyOccurrence(
|
|
FLMBOOL bUseKeyNodes,
|
|
XPATH_COMPONENT * pXPathComponent,
|
|
IF_DOMNode * pCurrNode,
|
|
FLMBOOL * pbPassed);
|
|
|
|
RCODE getXPathComponentFromAxis(
|
|
IF_DOMNode * pContextNode,
|
|
FLMBOOL bForward,
|
|
FLMBOOL bUseKeyNodes,
|
|
XPATH_COMPONENT * pXPathComponent,
|
|
IF_DOMNode ** ppCurrNode,
|
|
eXPathAxisTypes eAxis,
|
|
FLMBOOL bAxisInverted,
|
|
FLMBOOL bCountNodes);
|
|
|
|
RCODE getNextXPathValue(
|
|
IF_DOMNode * pContextNode,
|
|
FLMBOOL bForward,
|
|
FLMBOOL bUseKeyNodes,
|
|
FLMBOOL bXPathIsEntireExpr,
|
|
FQNODE * pQNode);
|
|
|
|
RCODE getNextFunctionValue(
|
|
IF_DOMNode * pContextNode,
|
|
FLMBOOL bForward,
|
|
FQNODE * pCurrNode,
|
|
F_DynaBuf * pDynaBuf);
|
|
|
|
RCODE getFuncValue(
|
|
IF_DOMNode * pContextNode,
|
|
FLMBOOL bForward,
|
|
FQNODE ** ppCurrNode,
|
|
FLMBOOL * pbGetNodeValue,
|
|
F_DynaBuf * pDynaBuf);
|
|
|
|
RCODE getXPathValue(
|
|
IF_DOMNode * pContextNode,
|
|
FLMBOOL bForward,
|
|
FQNODE ** ppCurrNode,
|
|
FLMBOOL * pbGetNodeValue,
|
|
FLMBOOL bUseKeyNodes,
|
|
FLMBOOL bXPathIsEntireExpr);
|
|
|
|
RCODE setExprReturnValue(
|
|
FLMBOOL bUseKeyNodes,
|
|
FQNODE * pQueryExpr,
|
|
FLMBOOL * pbPassed,
|
|
IF_DOMNode ** ppNode);
|
|
|
|
RCODE evalExpr(
|
|
IF_DOMNode * pContextNode,
|
|
FLMBOOL bForward,
|
|
FLMBOOL bUseKeyNodes,
|
|
FQNODE * pQueryExpr,
|
|
FLMBOOL * pbPassed,
|
|
IF_DOMNode ** ppNode);
|
|
|
|
RCODE getAppNode(
|
|
FLMBOOL * pbFirstLast,
|
|
FLMBOOL bForward,
|
|
XPATH_COMPONENT * pXPathComp);
|
|
|
|
RCODE testKey(
|
|
F_DataVector * pKey,
|
|
PATH_PRED * pPred,
|
|
FLMBOOL * pbPasses,
|
|
IF_DOMNode ** ppPassedNode);
|
|
|
|
RCODE getKey(
|
|
FLMBOOL * pbFirstLast,
|
|
FLMBOOL bForward,
|
|
XPATH_COMPONENT * pXPathComponent);
|
|
|
|
RCODE testMetaData(
|
|
IF_DOMNode * pNode,
|
|
FLMUINT uiMetaDataType,
|
|
PATH_PRED * pPred,
|
|
FLMBOOL * pbPasses);
|
|
|
|
RCODE getANode(
|
|
FLMBOOL * pbFirstLast,
|
|
FLMBOOL bForward,
|
|
XPATH_COMPONENT * pXPathComponent);
|
|
|
|
RCODE getContextNode(
|
|
FLMBOOL bForward,
|
|
XPATH_COMPONENT * pXPathComponent);
|
|
|
|
RCODE getNextIndexNode(
|
|
FLMBOOL * pbFirstLast,
|
|
FLMBOOL bForward,
|
|
FQNODE * pExprXPathSource,
|
|
FLMBOOL bSkipCurrKey);
|
|
|
|
RCODE objectAddRef(
|
|
F_Object * pObject);
|
|
|
|
RCODE setupQueryExpr(
|
|
FLMBOOL bUnicode,
|
|
IF_Db * pDb,
|
|
const void * pvQuery);
|
|
|
|
RCODE allocDupCheckSet( void);
|
|
|
|
RCODE checkIfDup(
|
|
IF_DOMNode ** ppNode,
|
|
FLMBOOL * pbPassed);
|
|
|
|
RCODE copyValue(
|
|
FQVALUE * pDestValue,
|
|
FQVALUE * pSrcValue);
|
|
|
|
RCODE copyXPath(
|
|
XPATH_COMPONENT * pXPathContext,
|
|
FQNODE * pDestNode,
|
|
FXPATH ** ppDestXPath,
|
|
FXPATH * pSrcXPath);
|
|
|
|
RCODE copyFunction(
|
|
XPATH_COMPONENT * pXPathContext,
|
|
FQFUNCTION ** ppDestFunc,
|
|
FQFUNCTION * pSrcFunc);
|
|
|
|
RCODE copyNode(
|
|
XPATH_COMPONENT * pXPathContext,
|
|
FQNODE ** ppDestNode,
|
|
FQNODE * pSrcNode);
|
|
|
|
RCODE copyExpr(
|
|
XPATH_COMPONENT * pXPathContext,
|
|
FQNODE ** ppDestExpr,
|
|
FQNODE * pSrcExpr);
|
|
|
|
void clearQuery( void);
|
|
|
|
void initVars( void);
|
|
|
|
FINLINE RCODE validateNode(
|
|
IF_DOMNode * pNode,
|
|
FLMBOOL * pbPassed)
|
|
{
|
|
RCODE rc = NE_XFLM_OK;
|
|
|
|
if (*pbPassed && m_pQueryValidator)
|
|
{
|
|
if (RC_BAD( rc = m_pQueryValidator->validateNode(
|
|
(IF_Db *)m_pDb, pNode, pbPassed)))
|
|
{
|
|
goto Exit;
|
|
}
|
|
if (!(*pbPassed))
|
|
{
|
|
if (!m_pQuery || m_pQuery->eNodeType != FLM_XPATH_NODE || m_bRemoveDups)
|
|
{
|
|
m_pCurrOpt->ui64DocsFailedValidation++;
|
|
}
|
|
m_pCurrOpt->ui64NodesFailedValidation++;
|
|
if (RC_BAD( rc = queryStatus()))
|
|
{
|
|
goto Exit;
|
|
}
|
|
}
|
|
}
|
|
Exit:
|
|
return( rc);
|
|
}
|
|
|
|
RCODE createResultSet( void);
|
|
|
|
RCODE buildResultSet(
|
|
IF_Db * pDb,
|
|
FLMUINT uiTimeLimit,
|
|
FLMUINT uiNumToWaitFor);
|
|
|
|
void checkResultSetWaiters(
|
|
RCODE rc);
|
|
|
|
RCODE waitResultSetBuild(
|
|
IF_Db * pDb,
|
|
FLMUINT uiTimeLimit,
|
|
FLMUINT uiNumToWaitFor);
|
|
|
|
RCODE getFirstFromResultSet(
|
|
IF_Db * pDb,
|
|
IF_DOMNode ** ppNode,
|
|
FLMUINT uiTimeLimit);
|
|
|
|
RCODE getLastFromResultSet(
|
|
IF_Db * pDb,
|
|
IF_DOMNode ** ppNode,
|
|
FLMUINT uiTimeLimit);
|
|
|
|
RCODE getNextFromResultSet(
|
|
IF_Db * pDb,
|
|
IF_DOMNode ** ppNode,
|
|
FLMUINT uiTimeLimit,
|
|
FLMUINT uiNumToSkip,
|
|
FLMUINT * puiNumSkipped);
|
|
|
|
RCODE getPrevFromResultSet(
|
|
IF_Db * pDb,
|
|
IF_DOMNode ** ppNode,
|
|
FLMUINT uiTimeLimit,
|
|
FLMUINT uiNumToSkip,
|
|
FLMUINT * puiNumSkipped);
|
|
|
|
RCODE getCurrentFromResultSet(
|
|
IF_Db * pDb,
|
|
IF_DOMNode ** ppNode);
|
|
|
|
RCODE verifySortKeys( void);
|
|
|
|
RCODE addToResultSet( void);
|
|
|
|
RCODE m_rc;
|
|
FQNODE * m_pQuery;
|
|
FLMBOOL m_bScan;
|
|
FLMBOOL m_bScanIndex;
|
|
FLMBOOL m_bResetAllXPaths;
|
|
FSIndexCursor * m_pFSIndexCursor;
|
|
XFLM_OPT_INFO m_scanOptInfo;
|
|
XFLM_OPT_INFO * m_pCurrOpt;
|
|
FLMBOOL m_bEmpty;
|
|
IXD * m_pSortIxd;
|
|
F_QueryResultSet * m_pSortResultSet;
|
|
RS_WAITER * m_pFirstWaiter;
|
|
FLMBOOL m_bStopBuildingResultSet;
|
|
FLMUINT m_uiBuildThreadId;
|
|
FLMBOOL m_bPositioningEnabled;
|
|
FLMBOOL m_bResultSetPopulated;
|
|
FLMBOOL m_bEntriesAlreadyInOrder;
|
|
FLMBOOL m_bEncryptResultSet;
|
|
FLMUINT64 m_ui64RSDocsRead;
|
|
FLMUINT64 m_ui64RSDocsPassed;
|
|
EXPR_STATE * m_pCurExprState;
|
|
F_Pool m_pool;
|
|
FLMBOOL m_bOptimized;
|
|
FLMUINT m_uiLanguage;
|
|
FLMUINT m_uiCollection;
|
|
IF_DOMNode * m_pCurrDoc;
|
|
IF_DOMNode * m_pCurrNode;
|
|
OP_CONTEXT * m_pCurrContext;
|
|
CONTEXT_PATH * m_pCurrContextPath;
|
|
PATH_PRED * m_pCurrPred;
|
|
FQNODE * m_pExprXPathSource;
|
|
eQueryStates m_eState;
|
|
IF_QueryStatus * m_pQueryStatus;
|
|
IF_QueryValidator * m_pQueryValidator;
|
|
F_Database * m_pDatabase;
|
|
F_Db * m_pDb;
|
|
F_Query * m_pNext; // Next query off of database
|
|
F_Query * m_pPrev; // Prev query off of database
|
|
F_Object ** m_ppObjectList;
|
|
FLMUINT m_uiObjectListSize;
|
|
FLMUINT m_uiObjectCount;
|
|
FLMBOOL m_bRemoveDups;
|
|
F_DynSearchSet * m_pDocIdSet;
|
|
FLMUINT m_uiIndex;
|
|
FLMBOOL m_bIndexSet;
|
|
FLMUINT m_uiTimeLimit;
|
|
FLMUINT m_uiStartTime;
|
|
|
|
friend class F_Db;
|
|
friend class F_Database;
|
|
friend class F_Dict;
|
|
friend class F_IStream;
|
|
};
|
|
|
|
/*****************************************************************************
|
|
Desc:
|
|
******************************************************************************/
|
|
class F_DbSystem : public IF_DbSystem, public F_OSBase
|
|
{
|
|
public:
|
|
|
|
F_DbSystem();
|
|
|
|
virtual ~F_DbSystem();
|
|
|
|
virtual FLMINT FLMAPI AddRef(
|
|
FLMBOOL bSysDataLocked);
|
|
|
|
virtual FLMINT FLMAPI AddRef( void)
|
|
{
|
|
return( AddRef( FALSE));
|
|
}
|
|
|
|
virtual FLMINT FLMAPI Release( void);
|
|
|
|
virtual FLMINT FLMAPI getRefCount( void)
|
|
{
|
|
return( (FLMINT)m_refCnt);
|
|
}
|
|
|
|
RCODE FLMAPI init( void);
|
|
|
|
RCODE FLMAPI updateIniFile(
|
|
const char * pszParamName,
|
|
const char * pszValue);
|
|
|
|
void FLMAPI getFileSystem(
|
|
IF_FileSystem ** ppFileSystem);
|
|
|
|
RCODE FLMAPI dbCreate(
|
|
const char * pszDbFileName,
|
|
const char * pszDataDir,
|
|
const char * pszRflDir,
|
|
const char * pszDictFileName,
|
|
const char * pszDictBuf,
|
|
XFLM_CREATE_OPTS * pCreateOpts,
|
|
FLMBOOL bTempDb,
|
|
IF_Db ** ppDb);
|
|
|
|
FINLINE RCODE FLMAPI dbCreate(
|
|
const char * pszDbFileName,
|
|
const char * pszDataDir,
|
|
const char * pszRflDir,
|
|
const char * pszDictFileName,
|
|
const char * pszDictBuf,
|
|
XFLM_CREATE_OPTS * pCreateOpts,
|
|
IF_Db ** ppDb)
|
|
{
|
|
return( dbCreate( pszDbFileName, pszDataDir, pszRflDir, pszDictFileName,
|
|
pszDictBuf, pCreateOpts, FALSE, ppDb));
|
|
}
|
|
|
|
FINLINE RCODE FLMAPI dbOpen(
|
|
const char * pszDbFileName,
|
|
const char * pszDataDir,
|
|
const char * pszRflDir,
|
|
const char * pszPassword,
|
|
FLMBOOL bAllowLimited,
|
|
IF_Db ** ppDb)
|
|
{
|
|
FLMUINT uiOpenFlags = bAllowLimited ? XFLM_ALLOW_LIMITED_MODE : 0;
|
|
|
|
return( openDb( pszDbFileName, pszDataDir, pszRflDir,
|
|
pszPassword, uiOpenFlags, ppDb));
|
|
}
|
|
|
|
RCODE FLMAPI dbRebuild(
|
|
const char * pszSourceDbPath,
|
|
const char * pszSourceDataDir,
|
|
const char * pszDestDbPath,
|
|
const char * pszDestDataDir,
|
|
const char * pszDestRflDir,
|
|
const char * pszDictPath,
|
|
const char * pszPassword,
|
|
XFLM_CREATE_OPTS * pCreateOpts,
|
|
FLMUINT64 * pui64TotNodes,
|
|
FLMUINT64 * pui64NodesRecov,
|
|
FLMUINT64 * pui64QuarantinedNodes,
|
|
IF_DbRebuildStatus * pRebuildStatus);
|
|
|
|
RCODE FLMAPI dbCheck(
|
|
const char * pszDbFileName,
|
|
const char * pszDataDir,
|
|
const char * pszRflDir,
|
|
const char * pszPassword,
|
|
FLMUINT uiFlags,
|
|
IF_DbInfo ** ppDbInfo,
|
|
IF_DbCheckStatus * pDbCheck);
|
|
|
|
FINLINE RCODE FLMAPI dbDup(
|
|
IF_Db * ifpDb,
|
|
IF_Db ** ppDb)
|
|
{
|
|
F_Db * pDb = (F_Db *)ifpDb;
|
|
|
|
return( openDatabase( pDb->m_pDatabase, NULL, NULL, NULL, NULL, 0,
|
|
FALSE, NULL, NULL, NULL, ppDb));
|
|
}
|
|
|
|
FINLINE RCODE FLMAPI setDynamicMemoryLimit(
|
|
FLMUINT uiCacheAdjustPercent,
|
|
FLMUINT uiCacheAdjustMin,
|
|
FLMUINT uiCacheAdjustMax,
|
|
FLMUINT uiCacheAdjustMinToLeave)
|
|
{
|
|
return( gv_XFlmSysData.pGlobalCacheMgr->setDynamicMemoryLimit(
|
|
uiCacheAdjustPercent, uiCacheAdjustMin,
|
|
uiCacheAdjustMax, uiCacheAdjustMinToLeave));
|
|
}
|
|
|
|
FINLINE RCODE FLMAPI setHardMemoryLimit(
|
|
FLMUINT uiPercent,
|
|
FLMBOOL bPercentOfAvail,
|
|
FLMUINT uiMin,
|
|
FLMUINT uiMax,
|
|
FLMUINT uiMinToLeave,
|
|
FLMBOOL bPreallocate)
|
|
{
|
|
return( gv_XFlmSysData.pGlobalCacheMgr->setHardMemoryLimit( uiPercent,
|
|
bPercentOfAvail, uiMin, uiMax, uiMinToLeave, bPreallocate));
|
|
}
|
|
|
|
// Determine if dyamic cache adjusting is supported.
|
|
|
|
FINLINE FLMBOOL FLMAPI getDynamicCacheSupported( void)
|
|
{
|
|
#ifdef FLM_CAN_GET_PHYS_MEM
|
|
return( TRUE);
|
|
#else
|
|
return( FALSE);
|
|
#endif
|
|
}
|
|
|
|
FINLINE void FLMAPI getCacheInfo(
|
|
XFLM_CACHE_INFO * pCacheInfo)
|
|
{
|
|
gv_XFlmSysData.pGlobalCacheMgr->getCacheInfo( pCacheInfo);
|
|
}
|
|
|
|
// Enable/disable cache debugging mode
|
|
|
|
void FLMAPI enableCacheDebug(
|
|
FLMBOOL bDebug);
|
|
|
|
FLMBOOL FLMAPI cacheDebugEnabled( void);
|
|
|
|
// Clear cache
|
|
|
|
FINLINE RCODE FLMAPI clearCache(
|
|
IF_Db * pDb)
|
|
{
|
|
return( gv_XFlmSysData.pGlobalCacheMgr->clearCache( pDb));
|
|
}
|
|
|
|
// Close all files that have not been used for the specified number of
|
|
// seconds.
|
|
|
|
RCODE FLMAPI closeUnusedFiles(
|
|
FLMUINT uiSeconds);
|
|
|
|
// Start gathering statistics.
|
|
|
|
void FLMAPI startStats( void);
|
|
|
|
// Stop gathering statistics.
|
|
|
|
void FLMAPI stopStats( void);
|
|
|
|
// Reset statistics.
|
|
|
|
void FLMAPI resetStats( void);
|
|
|
|
RCODE FLMAPI getStats(
|
|
XFLM_STATS * pFlmStats);
|
|
|
|
void FLMAPI freeStats(
|
|
XFLM_STATS * pFlmStats);
|
|
|
|
// Set the maximum number of queries to save.
|
|
|
|
void FLMAPI setQuerySaveMax(
|
|
FLMUINT uiMaxToSave);
|
|
|
|
FLMUINT FLMAPI getQuerySaveMax( void);
|
|
|
|
// Set temporary directory.
|
|
|
|
RCODE FLMAPI setTempDir(
|
|
const char * pszPath);
|
|
|
|
RCODE FLMAPI getTempDir(
|
|
char * pszPath);
|
|
|
|
// Maximum seconds between checkpoints.
|
|
|
|
void FLMAPI setCheckpointInterval(
|
|
FLMUINT uiSeconds);
|
|
|
|
FLMUINT FLMAPI getCheckpointInterval( void);
|
|
|
|
// Set interval for dynamically adjusting cache limit.
|
|
|
|
void FLMAPI setCacheAdjustInterval(
|
|
FLMUINT uiSeconds);
|
|
|
|
FLMUINT FLMAPI getCacheAdjustInterval( void);
|
|
|
|
// Set interval for dynamically cleaning out old cache blocks and records.
|
|
|
|
void FLMAPI setCacheCleanupInterval(
|
|
FLMUINT uiSeconds);
|
|
|
|
FLMUINT FLMAPI getCacheCleanupInterval( void);
|
|
|
|
// Set interval for cleaning up unused structures.
|
|
|
|
void FLMAPI setUnusedCleanupInterval(
|
|
FLMUINT uiSeconds);
|
|
|
|
FLMUINT FLMAPI getUnusedCleanupInterval( void);
|
|
|
|
// Set maximum time for an item to be unused.
|
|
|
|
void FLMAPI setMaxUnusedTime(
|
|
FLMUINT uiSeconds);
|
|
|
|
FLMUINT FLMAPI getMaxUnusedTime( void);
|
|
|
|
// Specify the logger object
|
|
|
|
void FLMAPI setLogger(
|
|
IF_LoggerClient * pLogger);
|
|
|
|
// Enable or disable use of ESM
|
|
|
|
void FLMAPI enableExtendedServerMemory(
|
|
FLMBOOL bEnable);
|
|
|
|
FLMBOOL FLMAPI extendedServerMemoryEnabled( void);
|
|
|
|
void FLMAPI deactivateOpenDb(
|
|
const char * pszDbFileName,
|
|
const char * pszDataDir);
|
|
|
|
// Maximum dirty cache.
|
|
|
|
void FLMAPI setDirtyCacheLimits(
|
|
FLMUINT uiMaxDirty,
|
|
FLMUINT uiLowDirty);
|
|
|
|
void FLMAPI getDirtyCacheLimits(
|
|
FLMUINT * puiMaxDirty,
|
|
FLMUINT * puiLowDirty);
|
|
|
|
RCODE FLMAPI getThreadInfo(
|
|
IF_ThreadInfo ** ppThreadInfo);
|
|
|
|
RCODE FLMAPI registerForEvent(
|
|
eEventCategory eCategory,
|
|
IF_EventClient * pEventClient);
|
|
|
|
void FLMAPI deregisterForEvent(
|
|
eEventCategory eCategory,
|
|
IF_EventClient * pEventClient);
|
|
|
|
RCODE FLMAPI getNextMetaphone(
|
|
IF_IStream * pIStream,
|
|
FLMUINT * puiMetaphone,
|
|
FLMUINT * puiAltMetaphone = NULL);
|
|
|
|
RCODE FLMAPI dbCopy(
|
|
const char * pszSrcDbName,
|
|
const char * pszSrcDataDir,
|
|
const char * pszSrcRflDir,
|
|
const char * pszDestDbName,
|
|
const char * pszDestDataDir,
|
|
const char * pszDestRflDir,
|
|
IF_DbCopyStatus * ifpStatus);
|
|
|
|
RCODE FLMAPI dbRemove(
|
|
const char * pszDbName,
|
|
const char * pszDataDir,
|
|
const char * pszRflDir,
|
|
FLMBOOL bRemoveRflFiles);
|
|
|
|
RCODE FLMAPI dbRename(
|
|
const char * pszDbName,
|
|
const char * pszDataDir,
|
|
const char * pszRflDir,
|
|
const char * pszNewDbName,
|
|
FLMBOOL bOverwriteDestOk,
|
|
IF_DbRenameStatus * ifpStatus);
|
|
|
|
RCODE FLMAPI dbRestore(
|
|
const char * pszDbPath,
|
|
const char * pszDataDir,
|
|
const char * pszRflDir,
|
|
const char * pszBackupPath,
|
|
const char * pszPassword,
|
|
IF_RestoreClient * pRestoreObj,
|
|
IF_RestoreStatus * pRestoreStatus);
|
|
|
|
RCODE FLMAPI strCmp(
|
|
FLMUINT uiCompFlags,
|
|
FLMUINT uiLanguage,
|
|
FLMUNICODE * uzStr1,
|
|
FLMUNICODE * uzStr2,
|
|
FLMINT * piCmp);
|
|
|
|
FLMBOOL FLMAPI errorIsFileCorrupt(
|
|
RCODE rc);
|
|
|
|
const char * FLMAPI checkErrorToStr(
|
|
FLMINT iCheckErrorCode);
|
|
|
|
RCODE FLMAPI openBufferIStream(
|
|
const char * pucBuffer,
|
|
FLMUINT uiLength,
|
|
IF_PosIStream ** ppIStream);
|
|
|
|
RCODE FLMAPI openFileIStream(
|
|
const char * pszPath,
|
|
IF_PosIStream ** ppIStream);
|
|
|
|
RCODE FLMAPI openMultiFileIStream(
|
|
const char * pszDirectory,
|
|
const char * pszBaseName,
|
|
IF_IStream ** ppIStream);
|
|
|
|
RCODE FLMAPI openBufferedIStream(
|
|
IF_IStream * pIStream,
|
|
FLMUINT uiBufferSize,
|
|
IF_IStream ** ppIStream);
|
|
|
|
RCODE FLMAPI openUncompressingIStream(
|
|
IF_IStream * pIStream,
|
|
IF_IStream ** ppIStream);
|
|
|
|
RCODE FLMAPI openFileOStream(
|
|
const char * pszFileName,
|
|
FLMBOOL bTruncateIfExists,
|
|
IF_OStream ** ppOStream);
|
|
|
|
RCODE FLMAPI openMultiFileOStream(
|
|
const char * pszDirectory,
|
|
const char * pszBaseName,
|
|
FLMUINT uiMaxFileSize,
|
|
FLMBOOL bOverwrite,
|
|
IF_OStream ** ppStream);
|
|
|
|
RCODE FLMAPI removeMultiFileStream(
|
|
const char * pszDirectory,
|
|
const char * pszBaseName);
|
|
|
|
RCODE FLMAPI openBufferedOStream(
|
|
IF_OStream * pOStream,
|
|
FLMUINT uiBufferSize,
|
|
IF_OStream ** ppOStream);
|
|
|
|
RCODE FLMAPI openCompressingOStream(
|
|
IF_OStream * pOStream,
|
|
IF_OStream ** ppOStream);
|
|
|
|
RCODE FLMAPI writeToOStream(
|
|
IF_IStream * pIStream,
|
|
IF_OStream * pOStream);
|
|
|
|
RCODE FLMAPI openBase64Encoder(
|
|
IF_IStream * pInputStream,
|
|
FLMBOOL bInsertLineBreaks,
|
|
IF_IStream ** ppEncodedStream);
|
|
|
|
RCODE FLMAPI openBase64Decoder(
|
|
IF_IStream * pInputStream,
|
|
IF_IStream ** ppDecodedStream);
|
|
|
|
RCODE FLMAPI createIFDataVector(
|
|
IF_DataVector ** ifppDV);
|
|
|
|
RCODE FLMAPI createIFResultSet(
|
|
IF_ResultSet ** ppResultSet);
|
|
|
|
RCODE FLMAPI createIFQuery(
|
|
IF_Query ** ppQuery);
|
|
|
|
FINLINE void FLMAPI freeMem(
|
|
void ** ppMem)
|
|
{
|
|
f_free( ppMem);
|
|
}
|
|
|
|
FINLINE RCODE internalDbOpen(
|
|
F_Database * pDatabase,
|
|
F_Db ** ppDb)
|
|
{
|
|
RCODE rc = NE_XFLM_OK;
|
|
IF_Db * pDb;
|
|
|
|
if (RC_OK( rc = openDatabase( pDatabase, NULL, NULL, NULL,
|
|
NULL, 0, TRUE, NULL, NULL, NULL, &pDb)))
|
|
{
|
|
*ppDb = (F_Db *)pDb;
|
|
}
|
|
return( rc);
|
|
}
|
|
|
|
RCODE openDb(
|
|
const char * pszDbFileName,
|
|
const char * pszDataDir,
|
|
const char * pszRflDir,
|
|
const char * pszPassword,
|
|
FLMUINT uiOpenFlags,
|
|
IF_Db ** ppDb);
|
|
|
|
static FINLINE FLMBOOL validBlockSize(
|
|
FLMUINT uiBlockSize)
|
|
{
|
|
if( uiBlockSize == 4096 || uiBlockSize == 8192)
|
|
{
|
|
return( TRUE);
|
|
}
|
|
|
|
return( FALSE);
|
|
}
|
|
|
|
RCODE FLMAPI compareUTF8Strings(
|
|
const FLMBYTE * pucLString,
|
|
FLMUINT uiLStrBytes,
|
|
FLMBOOL bLeftWild,
|
|
const FLMBYTE * pucRString,
|
|
FLMUINT uiRStrBytes,
|
|
FLMBOOL bRightWild,
|
|
FLMUINT uiCompareRules,
|
|
FLMUINT uiLanguage,
|
|
FLMINT * piResult);
|
|
|
|
RCODE FLMAPI compareUnicodeStrings(
|
|
const FLMUNICODE * puzLString,
|
|
FLMUINT uiLStrBytes,
|
|
FLMBOOL bLeftWild,
|
|
const FLMUNICODE * puzRString,
|
|
FLMUINT uiRStrBytes,
|
|
FLMBOOL bRightWild,
|
|
FLMUINT uiCompareRules,
|
|
FLMUINT uiLanguage,
|
|
FLMINT * piResult);
|
|
|
|
RCODE FLMAPI utf8IsSubStr(
|
|
const FLMBYTE * pszString,
|
|
const FLMBYTE * pszSubString,
|
|
FLMUINT uiCompareRules,
|
|
FLMUINT uiLanguage,
|
|
FLMBOOL * pbExists);
|
|
|
|
FLMBOOL FLMAPI uniIsUpper(
|
|
FLMUNICODE uzChar);
|
|
|
|
FLMBOOL FLMAPI uniIsLower(
|
|
FLMUNICODE uzChar);
|
|
|
|
FLMBOOL FLMAPI uniIsAlpha(
|
|
FLMUNICODE uzChar);
|
|
|
|
FLMBOOL FLMAPI uniIsDecimalDigit(
|
|
FLMUNICODE uzChar);
|
|
|
|
FLMUNICODE FLMAPI uniToLower(
|
|
FLMUNICODE uzChar);
|
|
|
|
RCODE FLMAPI nextUCS2Char(
|
|
const FLMBYTE ** ppszUTF8,
|
|
const FLMBYTE * pszEndOfUTF8String,
|
|
FLMUNICODE * puzChar);
|
|
|
|
RCODE FLMAPI numUCS2Chars(
|
|
const FLMBYTE * pszUTF8,
|
|
FLMUINT * puiNumChars);
|
|
|
|
RCODE FLMAPI waitToClose(
|
|
const char * pszDbPath);
|
|
|
|
RCODE FLMAPI createIFNodeInfo(
|
|
IF_NodeInfo ** ifppNodeInfo);
|
|
|
|
RCODE FLMAPI createIFBTreeInfo(
|
|
IF_BTreeInfo ** ifppBTreeInfo);
|
|
|
|
private:
|
|
|
|
// Methods
|
|
|
|
RCODE readIniFile( void);
|
|
|
|
RCODE setCacheParams(
|
|
IF_IniFile * pIniFile);
|
|
|
|
void cleanup( void);
|
|
|
|
FINLINE RCODE internalDbDup(
|
|
F_Db * pDb,
|
|
F_Db ** ppDb)
|
|
{
|
|
RCODE rc = NE_XFLM_OK;
|
|
IF_Db * ifpDb;
|
|
|
|
if (RC_OK( rc = openDatabase( pDb->m_pDatabase, NULL, NULL,
|
|
NULL, NULL, 0, TRUE, NULL, NULL, NULL, &ifpDb)))
|
|
{
|
|
*ppDb = (F_Db *)ifpDb;
|
|
}
|
|
|
|
return( rc);
|
|
}
|
|
|
|
RCODE allocDb(
|
|
F_Db ** ppDb,
|
|
FLMBOOL bInternalOpen);
|
|
|
|
RCODE findDatabase(
|
|
const char * pszDbPath,
|
|
const char * pszDataDir,
|
|
F_Database ** ppDatabase);
|
|
|
|
RCODE checkDatabaseClosed(
|
|
const char * pszDbName,
|
|
const char * pszDataDir);
|
|
|
|
RCODE allocDatabase(
|
|
const char * pszDbPath,
|
|
const char * pszDataDir,
|
|
FLMBOOL bTempDb,
|
|
F_Database ** ppDatabase);
|
|
|
|
RCODE openDatabase(
|
|
F_Database * pDatabase,
|
|
const char * pszDbPath,
|
|
const char * pszDataDir,
|
|
const char * pszRflDir,
|
|
const char * pszPassword,
|
|
FLMUINT uiOpenFlags,
|
|
FLMBOOL bInternalOpen,
|
|
IF_RestoreClient * pRestoreObj,
|
|
IF_RestoreStatus * pRestoreStatus,
|
|
IF_FileHdl * pLockFileHdl,
|
|
IF_Db ** ppDb);
|
|
|
|
RCODE copyDb(
|
|
const char * pszSrcDbName,
|
|
const char * pszSrcDataDir,
|
|
const char * pszSrcRflDir,
|
|
const char * pszDestDbName,
|
|
const char * pszDestDataDir,
|
|
const char * pszDestRflDir,
|
|
IF_DbCopyStatus * ifpStatus);
|
|
|
|
static RCODE FLMAPI monitorThrd(
|
|
IF_Thread * pThread);
|
|
|
|
static RCODE FLMAPI cacheCleanupThrd(
|
|
IF_Thread * pThread);
|
|
|
|
FLMATOMIC m_refCnt;
|
|
|
|
friend class F_Db;
|
|
friend class F_Database;
|
|
friend class F_DbRebuild;
|
|
friend class F_DbCheck;
|
|
};
|
|
|
|
void flmGetDbBasePath(
|
|
char * pszBaseDbName,
|
|
const char * pszDbName,
|
|
FLMUINT * puiBaseDbNameLen);
|
|
|
|
// Supported text types
|
|
|
|
typedef enum
|
|
{
|
|
XFLM_UNICODE_TEXT = 1,
|
|
XFLM_UTF8_TEXT
|
|
} eXFlmTextType;
|
|
|
|
/*------------------------------------------------------
|
|
FLAIM Processing Hooks (call-backs)
|
|
-------------------------------------------------------*/
|
|
|
|
#define FLM_DATA_LEFT_TRUNCATED 0x10 // Data is left truncated
|
|
#define FLM_DATA_RIGHT_TRUNCATED 0x20 // Data is right truncated
|
|
|
|
RCODE flmReadStorageAsText(
|
|
IF_IStream * pIStream,
|
|
FLMBYTE * pucStorageData,
|
|
FLMUINT uiDataLen,
|
|
FLMUINT uiDataType,
|
|
void * pvBuffer,
|
|
FLMUINT uiBufLen,
|
|
eXFlmTextType eTextType,
|
|
FLMUINT uiMaxCharsToRead,
|
|
FLMUINT uiCharOffset,
|
|
FLMUINT * puiCharsRead,
|
|
FLMUINT * puiBufferBytesUsed);
|
|
|
|
RCODE flmReadStorageAsBinary(
|
|
IF_IStream * pIStream,
|
|
void * pvBuffer,
|
|
FLMUINT uiBufLen,
|
|
FLMUINT uiByteOffset,
|
|
FLMUINT * puiBytesRead);
|
|
|
|
RCODE flmReadStorageAsNumber(
|
|
IF_IStream * pIStream,
|
|
FLMUINT uiDataType,
|
|
FLMUINT64 * pui64Number,
|
|
FLMBOOL * pbNeg);
|
|
|
|
RCODE flmReadLine(
|
|
IF_IStream * pIStream,
|
|
FLMBYTE * pucBuffer,
|
|
FLMUINT * puiSize);
|
|
|
|
#define FLM_ENCRYPT_CHUNK_SIZE 512
|
|
|
|
/*****************************************************************************
|
|
Desc:
|
|
******************************************************************************/
|
|
class F_BTreeIStream : public IF_PosIStream
|
|
{
|
|
public:
|
|
|
|
F_BTreeIStream()
|
|
{
|
|
m_pucBuffer = NULL;
|
|
m_pBTree = NULL;
|
|
m_bReleaseBTree = FALSE;
|
|
reset();
|
|
}
|
|
|
|
virtual ~F_BTreeIStream()
|
|
{
|
|
reset();
|
|
}
|
|
|
|
FINLINE void reset( void)
|
|
{
|
|
m_pNextInPool = NULL;
|
|
if( m_pBTree && m_bReleaseBTree)
|
|
{
|
|
m_pBTree->btClose();
|
|
gv_XFlmSysData.pBtPool->btpReturnBtree( &m_pBTree);
|
|
m_pBTree = NULL;
|
|
}
|
|
|
|
if( m_pucBuffer != &m_ucBuffer [0])
|
|
{
|
|
f_free( &m_pucBuffer);
|
|
}
|
|
|
|
m_pDb = NULL;
|
|
m_uiCollection = 0;
|
|
m_ui64NodeId = 0;
|
|
m_pBTree = NULL;
|
|
m_bReleaseBTree = FALSE;
|
|
m_uiKeyLength = 0;
|
|
m_uiStreamSize = 0;
|
|
m_uiBufferBytes = 0;
|
|
m_uiBufferOffset = 0;
|
|
m_uiBufferStartOffset = 0;
|
|
m_uiBufferSize = sizeof( m_ucBuffer);
|
|
m_pucBuffer = &m_ucBuffer [0];
|
|
m_ui32BlkAddr = 0;
|
|
m_uiOffsetIndex = 0;
|
|
m_bDataEncrypted = FALSE;
|
|
m_bBufferDecrypted = FALSE;
|
|
m_uiDataLength = 0;
|
|
m_uiEncDefId = 0;
|
|
}
|
|
|
|
RCODE open(
|
|
F_Db * pDb,
|
|
FLMUINT uiCollection,
|
|
FLMUINT64 ui64NodeId,
|
|
FLMUINT32 ui32BlkAddr = 0,
|
|
FLMUINT uiOffsetIndex = 0);
|
|
|
|
RCODE open(
|
|
F_Db * pDb,
|
|
F_Btree * pBTree,
|
|
FLMUINT uiFlags,
|
|
FLMUINT uiCollection,
|
|
FLMUINT64 ui64NodeId,
|
|
FLMUINT32 ui32BlkAddr = 0,
|
|
FLMUINT uiOffsetIndex = 0);
|
|
|
|
FINLINE FLMUINT64 FLMAPI totalSize( void)
|
|
{
|
|
return( m_uiStreamSize);
|
|
}
|
|
|
|
FINLINE FLMUINT64 FLMAPI remainingSize( void)
|
|
{
|
|
return( m_uiStreamSize - (m_uiBufferStartOffset + m_uiBufferOffset));
|
|
}
|
|
|
|
FINLINE RCODE FLMAPI close( void)
|
|
{
|
|
reset();
|
|
return( NE_XFLM_OK);
|
|
}
|
|
|
|
RCODE FLMAPI positionTo(
|
|
FLMUINT64 ui64Position);
|
|
|
|
FINLINE FLMUINT64 FLMAPI getCurrPosition( void)
|
|
{
|
|
return( m_uiBufferStartOffset + m_uiBufferOffset);
|
|
}
|
|
|
|
RCODE FLMAPI read(
|
|
void * pvBuffer,
|
|
FLMUINT uiBytesToRead,
|
|
FLMUINT * puiBytesRead);
|
|
|
|
FLMINT FLMAPI Release( void);
|
|
|
|
FINLINE FLMUINT32 getBlkAddr( void)
|
|
{
|
|
return( m_ui32BlkAddr);
|
|
}
|
|
|
|
FINLINE FLMUINT getOffsetIndex( void)
|
|
{
|
|
return( m_uiOffsetIndex);
|
|
}
|
|
|
|
private:
|
|
|
|
F_BTreeIStream * m_pNextInPool;
|
|
F_Db * m_pDb;
|
|
F_Btree * m_pBTree;
|
|
FLMUINT m_uiCollection;
|
|
FLMUINT64 m_ui64NodeId;
|
|
FLMUINT m_uiStreamSize;
|
|
FLMUINT m_uiKeyLength;
|
|
FLMUINT m_uiBufferBytes;
|
|
FLMUINT m_uiBufferSize;
|
|
FLMUINT m_uiBufferOffset;
|
|
FLMUINT m_uiBufferStartOffset;
|
|
FLMUINT m_uiDataLength;
|
|
FLMUINT m_uiEncDefId;
|
|
FLMBYTE m_ucBuffer[ FLM_ENCRYPT_CHUNK_SIZE];
|
|
FLMBYTE * m_pucBuffer;
|
|
FLMUINT m_uiOffsetIndex;
|
|
FLMUINT32 m_ui32BlkAddr;
|
|
FLMBOOL m_bReleaseBTree;
|
|
FLMBOOL m_bDataEncrypted;
|
|
FLMBOOL m_bBufferDecrypted;
|
|
FLMBYTE m_ucKey[ FLM_MAX_NUM_BUF_SIZE];
|
|
FLMBYTE m_ucIV [16];
|
|
friend class F_DOMNode;
|
|
friend class F_CachedNode;
|
|
friend class F_NodePool;
|
|
friend class F_Db;
|
|
};
|
|
|
|
/*****************************************************************************
|
|
Desc:
|
|
******************************************************************************/
|
|
class F_NodeBufferIStream : public IF_PosIStream
|
|
{
|
|
public:
|
|
|
|
F_NodeBufferIStream()
|
|
{
|
|
m_pCachedNode = NULL;
|
|
m_pBufferIStream = NULL;
|
|
reset();
|
|
}
|
|
|
|
virtual ~F_NodeBufferIStream()
|
|
{
|
|
reset();
|
|
}
|
|
|
|
RCODE FLMAPI open(
|
|
const char * pucBuffer,
|
|
FLMUINT uiLength,
|
|
char ** ppucAllocatedBuffer = NULL);
|
|
|
|
FINLINE FLMUINT64 FLMAPI totalSize( void)
|
|
{
|
|
return( m_pBufferIStream->totalSize());
|
|
}
|
|
|
|
FINLINE FLMUINT64 FLMAPI remainingSize( void)
|
|
{
|
|
return( m_pBufferIStream->remainingSize());
|
|
}
|
|
|
|
FINLINE RCODE FLMAPI close( void)
|
|
{
|
|
RCODE rc = NE_FLM_OK;
|
|
|
|
if( m_pBufferIStream)
|
|
{
|
|
m_pBufferIStream->Release();
|
|
m_pBufferIStream = NULL;
|
|
}
|
|
|
|
return( rc);
|
|
}
|
|
|
|
FINLINE RCODE FLMAPI positionTo(
|
|
FLMUINT64 ui64Position)
|
|
{
|
|
return( m_pBufferIStream->positionTo( ui64Position));
|
|
}
|
|
|
|
FINLINE FLMUINT64 FLMAPI getCurrPosition( void)
|
|
{
|
|
return( m_pBufferIStream->getCurrPosition());
|
|
}
|
|
|
|
FINLINE RCODE FLMAPI read(
|
|
void * pvBuffer,
|
|
FLMUINT uiBytesToRead,
|
|
FLMUINT * puiBytesRead)
|
|
{
|
|
return( m_pBufferIStream->read( pvBuffer, uiBytesToRead, puiBytesRead));
|
|
}
|
|
|
|
FINLINE void FLMAPI truncate(
|
|
FLMUINT uiOffset)
|
|
{
|
|
m_pBufferIStream->truncate( uiOffset);
|
|
}
|
|
|
|
FINLINE void reset( void)
|
|
{
|
|
if( m_pCachedNode)
|
|
{
|
|
f_mutexLock( gv_XFlmSysData.hNodeCacheMutex);
|
|
m_pCachedNode->decrNodeUseCount();
|
|
m_pCachedNode->decrStreamUseCount();
|
|
f_mutexUnlock( gv_XFlmSysData.hNodeCacheMutex);
|
|
m_pCachedNode = NULL;
|
|
}
|
|
|
|
if( m_pBufferIStream)
|
|
{
|
|
m_pBufferIStream->Release();
|
|
m_pBufferIStream = NULL;
|
|
}
|
|
}
|
|
|
|
F_CachedNode * m_pCachedNode;
|
|
IF_BufferIStream * m_pBufferIStream;
|
|
friend class F_CachedNode;
|
|
};
|
|
|
|
/*****************************************************************************
|
|
Desc:
|
|
******************************************************************************/
|
|
class F_DOMNode : public IF_DOMNode
|
|
{
|
|
public:
|
|
|
|
F_DOMNode()
|
|
{
|
|
m_pCachedNode = NULL;
|
|
resetDOMNode( FALSE);
|
|
}
|
|
|
|
virtual ~F_DOMNode()
|
|
{
|
|
resetDOMNode( FALSE);
|
|
}
|
|
|
|
void resetDOMNode(
|
|
FLMBOOL bMutexAlreadyLocked)
|
|
{
|
|
m_pNextInPool = NULL;
|
|
m_uiAttrNameId = 0;
|
|
|
|
if (m_pCachedNode)
|
|
{
|
|
if( !bMutexAlreadyLocked)
|
|
{
|
|
f_mutexLock( gv_XFlmSysData.hNodeCacheMutex);
|
|
}
|
|
m_pCachedNode->decrNodeUseCount();
|
|
if( !bMutexAlreadyLocked)
|
|
{
|
|
f_mutexUnlock( gv_XFlmSysData.hNodeCacheMutex);
|
|
}
|
|
m_pCachedNode = NULL;
|
|
}
|
|
}
|
|
|
|
FLMINT FLMAPI Release( void);
|
|
|
|
RCODE FLMAPI createNode(
|
|
IF_Db * pDb,
|
|
eDomNodeType eNodeType,
|
|
FLMUINT uiNameId,
|
|
eNodeInsertLoc eLocation,
|
|
IF_DOMNode ** ppNewNode,
|
|
FLMUINT64 * pui64NodeId = NULL);
|
|
|
|
RCODE FLMAPI createChildElement(
|
|
IF_Db * pDb,
|
|
FLMUINT uiChildElementNameId,
|
|
eNodeInsertLoc eLocation,
|
|
IF_DOMNode ** ppNewChildElementNode,
|
|
FLMUINT64 * pui64NodeId = NULL);
|
|
|
|
RCODE FLMAPI deleteNode(
|
|
IF_Db * pDb);
|
|
|
|
RCODE FLMAPI deleteChildren(
|
|
IF_Db * pDb,
|
|
FLMUINT uiNameId = 0);
|
|
|
|
RCODE FLMAPI createAttribute(
|
|
IF_Db * pDb,
|
|
FLMUINT uiAttrNameId,
|
|
IF_DOMNode ** ppAttrNode);
|
|
|
|
RCODE FLMAPI getFirstAttribute(
|
|
IF_Db * pDb,
|
|
IF_DOMNode ** ppAttrNode);
|
|
|
|
RCODE FLMAPI getLastAttribute(
|
|
IF_Db * pDb,
|
|
IF_DOMNode ** ppAttrNode);
|
|
|
|
FINLINE RCODE FLMAPI getAttribute(
|
|
IF_Db * pDb,
|
|
FLMUINT uiAttrNameId,
|
|
IF_DOMNode ** ppAttrNode)
|
|
{
|
|
return( hasAttribute( pDb, uiAttrNameId, ppAttrNode));
|
|
}
|
|
|
|
RCODE FLMAPI deleteAttribute(
|
|
IF_Db * pDb,
|
|
FLMUINT uiAttrNameId);
|
|
|
|
RCODE FLMAPI hasAttribute(
|
|
IF_Db * pDb,
|
|
FLMUINT uiAttrNameId,
|
|
IF_DOMNode ** ppAttrNode = NULL);
|
|
|
|
RCODE FLMAPI hasAttributes(
|
|
IF_Db * pDb,
|
|
FLMBOOL * pbHasAttrs);
|
|
|
|
RCODE FLMAPI hasNextSibling(
|
|
IF_Db * pDb,
|
|
FLMBOOL * pbHasNextSibling);
|
|
|
|
RCODE FLMAPI hasPreviousSibling(
|
|
IF_Db * pDb,
|
|
FLMBOOL * pbHasPreviousSibling);
|
|
|
|
RCODE FLMAPI hasChildren(
|
|
IF_Db * pDb,
|
|
FLMBOOL * pbHasChildren);
|
|
|
|
RCODE FLMAPI isNamespaceDecl(
|
|
IF_Db * pDb,
|
|
FLMBOOL * pbIsNamespaceDecl);
|
|
|
|
FINLINE eDomNodeType FLMAPI getNodeType( void)
|
|
{
|
|
if( m_uiAttrNameId)
|
|
{
|
|
return( ATTRIBUTE_NODE);
|
|
}
|
|
else if( m_pCachedNode)
|
|
{
|
|
return( m_pCachedNode->getNodeType());
|
|
}
|
|
|
|
flmAssert( 0);
|
|
return( INVALID_NODE);
|
|
}
|
|
|
|
RCODE FLMAPI getNodeId(
|
|
IF_Db * pDb,
|
|
FLMUINT64 * pui64NodeId);
|
|
|
|
RCODE FLMAPI getParentId(
|
|
IF_Db * pDb,
|
|
FLMUINT64 * pui64ParentId);
|
|
|
|
RCODE FLMAPI getDocumentId(
|
|
IF_Db * pDb,
|
|
FLMUINT64 * pui64DocumentId);
|
|
|
|
RCODE FLMAPI getPrevSibId(
|
|
IF_Db * pDb,
|
|
FLMUINT64 * pui64PrevSibId);
|
|
|
|
RCODE FLMAPI getNextSibId(
|
|
IF_Db * pDb,
|
|
FLMUINT64 * pui64NextSibId);
|
|
|
|
RCODE FLMAPI getFirstChildId(
|
|
IF_Db * pDb,
|
|
FLMUINT64 * pui64FirstChildId);
|
|
|
|
RCODE FLMAPI getLastChildId(
|
|
IF_Db * pDb,
|
|
FLMUINT64 * pui64LastChildId);
|
|
|
|
RCODE FLMAPI getNameId(
|
|
IF_Db * pDb,
|
|
FLMUINT * puiNameId);
|
|
|
|
virtual RCODE FLMAPI getEncDefId(
|
|
IF_Db * pDb,
|
|
FLMUINT * puiEncDefId);
|
|
|
|
RCODE FLMAPI getDataType(
|
|
IF_Db * pDb,
|
|
FLMUINT * puiDataType);
|
|
|
|
RCODE FLMAPI getDataLength(
|
|
IF_Db * pDb,
|
|
FLMUINT * puiLength);
|
|
|
|
FINLINE RCODE FLMAPI getUINT32(
|
|
IF_Db * pDb,
|
|
FLMUINT32 * pui32Value)
|
|
{
|
|
RCODE rc;
|
|
FLMUINT64 ui64Value;
|
|
|
|
if( RC_BAD( rc = getNumber64( (F_Db *)pDb, &ui64Value, NULL)))
|
|
{
|
|
return( rc);
|
|
}
|
|
|
|
return( convertToUINT32( ui64Value, FALSE, pui32Value));
|
|
}
|
|
|
|
FINLINE RCODE FLMAPI getUINT(
|
|
IF_Db * pDb,
|
|
FLMUINT * puiValue)
|
|
{
|
|
RCODE rc;
|
|
FLMUINT64 ui64Value;
|
|
|
|
if( RC_BAD( rc = getNumber64( (F_Db *)pDb, &ui64Value, NULL)))
|
|
{
|
|
return( rc);
|
|
}
|
|
|
|
return( convertToUINT( ui64Value, FALSE, puiValue));
|
|
}
|
|
|
|
FINLINE RCODE FLMAPI getUINT64(
|
|
IF_Db * pDb,
|
|
FLMUINT64 * pui64Value)
|
|
{
|
|
return( getNumber64( (F_Db *)pDb, pui64Value, NULL));
|
|
}
|
|
|
|
FINLINE RCODE FLMAPI getINT32(
|
|
IF_Db * pDb,
|
|
FLMINT32 * pi32Value)
|
|
{
|
|
RCODE rc;
|
|
FLMUINT64 ui64Value;
|
|
FLMBOOL bNeg;
|
|
|
|
if( RC_BAD( rc = getNumber64( (F_Db *)pDb, &ui64Value, &bNeg)))
|
|
{
|
|
return( rc);
|
|
}
|
|
|
|
return( convertToINT32( ui64Value, bNeg, pi32Value));
|
|
}
|
|
|
|
FINLINE RCODE FLMAPI getINT(
|
|
IF_Db * pDb,
|
|
FLMINT * piValue)
|
|
{
|
|
RCODE rc;
|
|
FLMUINT64 ui64Value;
|
|
FLMBOOL bNeg;
|
|
|
|
if( RC_BAD( rc = getNumber64( (F_Db *)pDb, &ui64Value, &bNeg)))
|
|
{
|
|
return( rc);
|
|
}
|
|
|
|
return( convertToINT( ui64Value, bNeg, piValue));
|
|
}
|
|
|
|
FINLINE RCODE FLMAPI getINT64(
|
|
IF_Db * pDb,
|
|
FLMINT64 * pi64Value)
|
|
{
|
|
RCODE rc;
|
|
FLMUINT64 ui64Value;
|
|
FLMBOOL bNeg;
|
|
|
|
if( RC_BAD( rc = getNumber64( (F_Db *)pDb, &ui64Value, &bNeg)))
|
|
{
|
|
return( rc);
|
|
}
|
|
|
|
return( convertToINT64( ui64Value, bNeg, pi64Value));
|
|
}
|
|
|
|
RCODE FLMAPI getMetaValue(
|
|
IF_Db * pDb,
|
|
FLMUINT64 * pui64Value);
|
|
|
|
FINLINE RCODE FLMAPI getUnicodeChars(
|
|
IF_Db * pDb,
|
|
FLMUINT * puiNumChars)
|
|
{
|
|
return( getUnicode( pDb, NULL, 0, 0, FLM_MAX_UINT, puiNumChars));
|
|
}
|
|
|
|
RCODE FLMAPI getUnicode(
|
|
IF_Db * pDb,
|
|
FLMUNICODE * puzValueBuffer,
|
|
FLMUINT uiBufferSize,
|
|
FLMUINT uiCharOffset,
|
|
FLMUINT uiMaxCharsRequested,
|
|
FLMUINT * puiCharsReturned = NULL,
|
|
FLMUINT * puiBufferBytesUsed = NULL);
|
|
|
|
RCODE FLMAPI getUnicode(
|
|
IF_Db * pDb,
|
|
FLMUNICODE ** ppuzUnicodeValue);
|
|
|
|
RCODE FLMAPI getUnicode(
|
|
IF_Db * pDb,
|
|
F_DynaBuf * pDynaBuf);
|
|
|
|
RCODE FLMAPI getUTF8(
|
|
IF_Db * pDb,
|
|
FLMBYTE * pszValueBuffer,
|
|
FLMUINT uiBufferSize,
|
|
FLMUINT uiCharOffset,
|
|
FLMUINT uiMaxCharsRequested,
|
|
FLMUINT * puiCharsReturned = NULL,
|
|
FLMUINT * puiBufferBytesUsed = NULL);
|
|
|
|
RCODE FLMAPI getUTF8(
|
|
IF_Db * pDb,
|
|
FLMBYTE ** ppszUTF8Value);
|
|
|
|
RCODE FLMAPI getUTF8(
|
|
IF_Db * pDb,
|
|
F_DynaBuf * pDynaBuf);
|
|
|
|
RCODE FLMAPI getBinary(
|
|
IF_Db * pDb,
|
|
void * pvValue,
|
|
FLMUINT uiByteOffset,
|
|
FLMUINT uiBytesRequested,
|
|
FLMUINT * puiBytesReturned);
|
|
|
|
RCODE FLMAPI getBinary(
|
|
IF_Db * pDb,
|
|
F_DynaBuf * pBuffer);
|
|
|
|
FINLINE RCODE FLMAPI getAttributeValueUINT32(
|
|
IF_Db * pDb,
|
|
FLMUINT uiAttrName,
|
|
FLMUINT32 * pui32Num)
|
|
{
|
|
RCODE rc = NE_XFLM_OK;
|
|
FLMUINT64 ui64Num;
|
|
FLMBOOL bNeg;
|
|
|
|
if( RC_BAD( rc = getAttributeValueNumber( (F_Db *)pDb,
|
|
uiAttrName, &ui64Num, &bNeg)))
|
|
{
|
|
return( rc);
|
|
}
|
|
|
|
return( convertToUINT32( ui64Num, bNeg, pui32Num));
|
|
}
|
|
|
|
FINLINE RCODE FLMAPI getAttributeValueUINT32(
|
|
IF_Db * pDb,
|
|
FLMUINT uiAttrName,
|
|
FLMUINT32 * pui32Num,
|
|
FLMUINT32 ui32NotFoundDefault)
|
|
{
|
|
RCODE rc = NE_XFLM_OK;
|
|
|
|
if( RC_BAD( rc = getAttributeValueUINT32(
|
|
pDb, uiAttrName, pui32Num)))
|
|
{
|
|
if( rc != NE_XFLM_DOM_NODE_NOT_FOUND)
|
|
{
|
|
return( rc);
|
|
}
|
|
|
|
*pui32Num = ui32NotFoundDefault;
|
|
rc = NE_XFLM_OK;
|
|
}
|
|
|
|
return( rc);
|
|
}
|
|
|
|
FINLINE RCODE FLMAPI getAttributeValueUINT(
|
|
IF_Db * pDb,
|
|
FLMUINT uiAttrName,
|
|
FLMUINT * puiNum)
|
|
{
|
|
RCODE rc = NE_XFLM_OK;
|
|
FLMUINT64 ui64Num;
|
|
FLMBOOL bNeg;
|
|
|
|
if( RC_BAD( rc = getAttributeValueNumber( (F_Db *)pDb,
|
|
uiAttrName, &ui64Num, &bNeg)))
|
|
{
|
|
return( rc);
|
|
}
|
|
|
|
return( convertToUINT( ui64Num, bNeg, puiNum));
|
|
}
|
|
|
|
FINLINE RCODE FLMAPI getAttributeValueUINT(
|
|
IF_Db * pDb,
|
|
FLMUINT uiAttrName,
|
|
FLMUINT * puiNum,
|
|
FLMUINT uiNotFoundDefault)
|
|
{
|
|
RCODE rc = NE_XFLM_OK;
|
|
|
|
if( RC_BAD( rc = getAttributeValueUINT(
|
|
pDb, uiAttrName, puiNum)))
|
|
{
|
|
if( rc != NE_XFLM_DOM_NODE_NOT_FOUND)
|
|
{
|
|
return( rc);
|
|
}
|
|
|
|
*puiNum = uiNotFoundDefault;
|
|
rc = NE_XFLM_OK;
|
|
}
|
|
|
|
return( rc);
|
|
}
|
|
|
|
FINLINE RCODE FLMAPI getAttributeValueUINT64(
|
|
IF_Db * pDb,
|
|
FLMUINT uiAttrName,
|
|
FLMUINT64 * pui64Num)
|
|
{
|
|
RCODE rc = NE_XFLM_OK;
|
|
FLMUINT64 ui64Num;
|
|
FLMBOOL bNeg;
|
|
|
|
if( RC_BAD( rc = getAttributeValueNumber( (F_Db *)pDb,
|
|
uiAttrName, &ui64Num, &bNeg)))
|
|
{
|
|
return( rc);
|
|
}
|
|
|
|
return( convertToUINT64( ui64Num, bNeg, pui64Num));
|
|
}
|
|
|
|
FINLINE RCODE FLMAPI getAttributeValueUINT64(
|
|
IF_Db * pDb,
|
|
FLMUINT uiAttrName,
|
|
FLMUINT64 * pui64Num,
|
|
FLMUINT64 ui64NotFoundDefault)
|
|
{
|
|
RCODE rc = NE_XFLM_OK;
|
|
|
|
if( RC_BAD( rc = getAttributeValueUINT64(
|
|
pDb, uiAttrName, pui64Num)))
|
|
{
|
|
if( rc != NE_XFLM_DOM_NODE_NOT_FOUND)
|
|
{
|
|
return( rc);
|
|
}
|
|
|
|
*pui64Num = ui64NotFoundDefault;
|
|
rc = NE_XFLM_OK;
|
|
}
|
|
|
|
return( rc);
|
|
}
|
|
|
|
FINLINE RCODE FLMAPI getAttributeValueINT(
|
|
IF_Db * pDb,
|
|
FLMUINT uiAttrName,
|
|
FLMINT * piNum)
|
|
{
|
|
RCODE rc = NE_XFLM_OK;
|
|
FLMUINT64 ui64Num;
|
|
FLMBOOL bNeg;
|
|
|
|
if( RC_BAD( rc = getAttributeValueNumber( (F_Db *)pDb,
|
|
uiAttrName, &ui64Num, &bNeg)))
|
|
{
|
|
return( rc);
|
|
}
|
|
|
|
return( convertToINT( ui64Num, bNeg, piNum));
|
|
}
|
|
|
|
FINLINE RCODE FLMAPI getAttributeValueINT(
|
|
IF_Db * pDb,
|
|
FLMUINT uiAttrName,
|
|
FLMINT * piNum,
|
|
FLMINT iNotFoundDefault)
|
|
{
|
|
RCODE rc = NE_XFLM_OK;
|
|
|
|
if( RC_BAD( rc = getAttributeValueINT(
|
|
pDb, uiAttrName, piNum)))
|
|
{
|
|
if( rc != NE_XFLM_DOM_NODE_NOT_FOUND)
|
|
{
|
|
return( rc);
|
|
}
|
|
|
|
*piNum = iNotFoundDefault;
|
|
rc = NE_XFLM_OK;
|
|
}
|
|
|
|
return( rc);
|
|
}
|
|
|
|
FINLINE RCODE FLMAPI getAttributeValueINT64(
|
|
IF_Db * pDb,
|
|
FLMUINT uiAttrName,
|
|
FLMINT64 * pi64Num)
|
|
{
|
|
RCODE rc = NE_XFLM_OK;
|
|
FLMUINT64 ui64Num;
|
|
FLMBOOL bNeg;
|
|
|
|
if( RC_BAD( rc = getAttributeValueNumber( (F_Db *)pDb,
|
|
uiAttrName, &ui64Num, &bNeg)))
|
|
{
|
|
return( rc);
|
|
}
|
|
|
|
return( convertToINT64( ui64Num, bNeg, pi64Num));
|
|
}
|
|
|
|
FINLINE RCODE FLMAPI getAttributeValueINT64(
|
|
IF_Db * pDb,
|
|
FLMUINT uiAttrName,
|
|
FLMINT64 * pi64Num,
|
|
FLMINT64 i64NotFoundDefault)
|
|
{
|
|
RCODE rc = NE_XFLM_OK;
|
|
|
|
if( RC_BAD( rc = getAttributeValueINT64(
|
|
pDb, uiAttrName, pi64Num)))
|
|
{
|
|
if( rc != NE_XFLM_DOM_NODE_NOT_FOUND)
|
|
{
|
|
return( rc);
|
|
}
|
|
|
|
*pi64Num = i64NotFoundDefault;
|
|
rc = NE_XFLM_OK;
|
|
}
|
|
|
|
return( rc);
|
|
}
|
|
|
|
FINLINE RCODE FLMAPI getAttributeValueUnicode(
|
|
IF_Db * pDb,
|
|
FLMUINT uiAttrName,
|
|
FLMUNICODE * puzValueBuffer,
|
|
FLMUINT uiBufferSize,
|
|
FLMUINT * puiCharsReturned = NULL,
|
|
FLMUINT * puiBufferBytesUsed = NULL)
|
|
{
|
|
return( getAttributeValueText( pDb, uiAttrName, XFLM_UNICODE_TEXT,
|
|
puzValueBuffer, uiBufferSize, puiCharsReturned, puiBufferBytesUsed));
|
|
}
|
|
|
|
RCODE FLMAPI getAttributeValueUnicode(
|
|
IF_Db * pDb,
|
|
FLMUINT uiAttrName,
|
|
FLMUNICODE ** ppuzValueBuffer);
|
|
|
|
RCODE FLMAPI getAttributeValueUnicode(
|
|
IF_Db * pDb,
|
|
FLMUINT uiAttrName,
|
|
F_DynaBuf * pDynaBuf);
|
|
|
|
RCODE FLMAPI getAttributeValueUTF8(
|
|
IF_Db * pDb,
|
|
FLMUINT uiAttrName,
|
|
FLMBYTE * pucValueBuffer,
|
|
FLMUINT uiBufferSize,
|
|
FLMUINT * puiCharsReturned = NULL,
|
|
FLMUINT * puiBufferBytesUsed = NULL)
|
|
{
|
|
return( getAttributeValueText( pDb, uiAttrName, XFLM_UTF8_TEXT,
|
|
pucValueBuffer, uiBufferSize, puiCharsReturned, puiBufferBytesUsed));
|
|
}
|
|
|
|
RCODE FLMAPI getAttributeValueUTF8(
|
|
IF_Db * pDb,
|
|
FLMUINT uiAttrNameId,
|
|
FLMBYTE ** ppszValueBuffer);
|
|
|
|
RCODE FLMAPI getAttributeValueUTF8(
|
|
IF_Db * pDb,
|
|
FLMUINT uiAttrName,
|
|
F_DynaBuf * pDynaBuf);
|
|
|
|
RCODE FLMAPI getAttributeValueBinary(
|
|
IF_Db * pDb,
|
|
FLMUINT uiAttrName,
|
|
void * pvValueBuffer,
|
|
FLMUINT uiBufferSize,
|
|
FLMUINT * puiValueLength);
|
|
|
|
RCODE FLMAPI getAttributeValueBinary(
|
|
IF_Db * pDb,
|
|
FLMUINT uiAttrName,
|
|
F_DynaBuf * pDynaBuf);
|
|
|
|
FINLINE RCODE FLMAPI setUINT(
|
|
IF_Db * pDb,
|
|
FLMUINT uiValue,
|
|
FLMUINT uiEncDefId = 0)
|
|
{
|
|
return( setNumber64( pDb, 0, uiValue, uiEncDefId));
|
|
}
|
|
|
|
FINLINE RCODE FLMAPI setUINT64(
|
|
IF_Db * pDb,
|
|
FLMUINT64 ui64Value,
|
|
FLMUINT uiEncDefId = 0)
|
|
{
|
|
return( setNumber64( pDb, 0, ui64Value, uiEncDefId));
|
|
}
|
|
|
|
FINLINE RCODE FLMAPI setINT(
|
|
IF_Db * pDb,
|
|
FLMINT iValue,
|
|
FLMUINT uiEncDefId = 0)
|
|
{
|
|
return( setNumber64( pDb, iValue, 0, uiEncDefId));
|
|
}
|
|
|
|
FINLINE RCODE FLMAPI setINT64(
|
|
IF_Db * pDb,
|
|
FLMINT64 i64Value,
|
|
FLMUINT uiEncDefId = 0)
|
|
{
|
|
return( setNumber64( pDb, i64Value, 0, uiEncDefId));
|
|
}
|
|
|
|
RCODE FLMAPI setMetaValue(
|
|
IF_Db * pDb,
|
|
FLMUINT64 ui64Value);
|
|
|
|
FINLINE RCODE FLMAPI setUnicode(
|
|
IF_Db * pDb,
|
|
const FLMUNICODE * puzValue,
|
|
FLMUINT uiValueLength = 0,
|
|
FLMBOOL bLast = TRUE,
|
|
FLMUINT uiEncDefId = 0)
|
|
{
|
|
F_Database * pDatabase = ((F_Db *)pDb)->m_pDatabase;
|
|
|
|
if( bLast && !pDatabase->m_pPendingInput)
|
|
{
|
|
return( setTextFastPath( (F_Db *)pDb, puzValue, uiValueLength,
|
|
XFLM_UNICODE_TEXT, uiEncDefId));
|
|
}
|
|
else
|
|
{
|
|
return( setTextStreaming( (F_Db *)pDb, puzValue,
|
|
uiValueLength, XFLM_UNICODE_TEXT, bLast, uiEncDefId));
|
|
}
|
|
}
|
|
|
|
FINLINE RCODE FLMAPI setUTF8(
|
|
IF_Db * pDb,
|
|
const FLMBYTE * pszValue,
|
|
FLMUINT uiValueLength = 0,
|
|
FLMBOOL bLast = TRUE,
|
|
FLMUINT uiEncDefId = 0)
|
|
{
|
|
F_Database * pDatabase = ((F_Db *)pDb)->m_pDatabase;
|
|
|
|
if( bLast && !pDatabase->m_pPendingInput)
|
|
{
|
|
return( setTextFastPath( (F_Db *)pDb, pszValue, uiValueLength,
|
|
XFLM_UTF8_TEXT, uiEncDefId));
|
|
}
|
|
else
|
|
{
|
|
return( setTextStreaming( (F_Db *)pDb, pszValue,
|
|
uiValueLength, XFLM_UTF8_TEXT, bLast, uiEncDefId));
|
|
}
|
|
}
|
|
|
|
FINLINE RCODE FLMAPI setBinary(
|
|
IF_Db * pDb,
|
|
const void * pvValue,
|
|
FLMUINT uiValueLength,
|
|
FLMBOOL bLast = TRUE,
|
|
FLMUINT uiEncDefId = 0)
|
|
{
|
|
F_Database * pDatabase = ((F_Db *)pDb)->m_pDatabase;
|
|
|
|
if( bLast && !pDatabase->m_pPendingInput)
|
|
{
|
|
return( setBinaryFastPath( (F_Db *)pDb, pvValue,
|
|
uiValueLength, uiEncDefId));
|
|
}
|
|
else
|
|
{
|
|
return( setBinaryStreaming( (F_Db *)pDb, pvValue, uiValueLength, bLast,
|
|
uiEncDefId));
|
|
}
|
|
}
|
|
|
|
FINLINE RCODE FLMAPI setAttributeValueUINT(
|
|
IF_Db * pDb,
|
|
FLMUINT uiAttrName,
|
|
FLMUINT uiValue,
|
|
FLMUINT uiEncDefId = 0)
|
|
{
|
|
return( setAttributeValueNumber( pDb, uiAttrName,
|
|
0, uiValue, uiEncDefId));
|
|
}
|
|
|
|
FINLINE RCODE FLMAPI setAttributeValueUINT64(
|
|
IF_Db * pDb,
|
|
FLMUINT uiAttrName,
|
|
FLMUINT64 ui64Value,
|
|
FLMUINT uiEncDefId = 0)
|
|
{
|
|
return( setAttributeValueNumber( pDb, uiAttrName,
|
|
0, ui64Value, uiEncDefId));
|
|
}
|
|
|
|
FINLINE RCODE FLMAPI setAttributeValueINT(
|
|
IF_Db * pDb,
|
|
FLMUINT uiAttrName,
|
|
FLMINT iValue,
|
|
FLMUINT uiEncDefId = 0)
|
|
{
|
|
return( setAttributeValueNumber( pDb, uiAttrName,
|
|
iValue, 0, uiEncDefId));
|
|
}
|
|
|
|
FINLINE RCODE FLMAPI setAttributeValueINT64(
|
|
IF_Db * pDb,
|
|
FLMUINT uiAttrName,
|
|
FLMINT64 i64Value,
|
|
FLMUINT uiEncDefId = 0)
|
|
{
|
|
return( setAttributeValueNumber( pDb, uiAttrName,
|
|
i64Value, 0, uiEncDefId));
|
|
}
|
|
|
|
RCODE FLMAPI setAttributeValueUnicode(
|
|
IF_Db * pDb,
|
|
FLMUINT uiAttrName,
|
|
const FLMUNICODE * puzValue,
|
|
FLMUINT uiEncDefId = 0);
|
|
|
|
RCODE FLMAPI setAttributeValueUTF8(
|
|
IF_Db * pDb,
|
|
FLMUINT uiAttrName,
|
|
const FLMBYTE * pszValue,
|
|
FLMUINT uiLength,
|
|
FLMUINT uiEncDefId = 0);
|
|
|
|
RCODE FLMAPI setAttributeValueBinary(
|
|
IF_Db * pDb,
|
|
FLMUINT uiAttrName,
|
|
const void * pvValue,
|
|
FLMUINT uiLength,
|
|
FLMUINT uiEncDefId = 0);
|
|
|
|
RCODE FLMAPI getDocumentNode(
|
|
IF_Db * pDb,
|
|
IF_DOMNode ** ppDocument);
|
|
|
|
RCODE FLMAPI getNextDocument(
|
|
IF_Db * pDb,
|
|
IF_DOMNode ** ppNextDocument);
|
|
|
|
RCODE FLMAPI getPreviousDocument(
|
|
IF_Db * pDb,
|
|
IF_DOMNode ** ppPrevDocument);
|
|
|
|
RCODE FLMAPI getParentNode(
|
|
IF_Db * pDb,
|
|
IF_DOMNode ** ppParent);
|
|
|
|
RCODE FLMAPI getFirstChild(
|
|
IF_Db * pDb,
|
|
IF_DOMNode ** ppFirstChild);
|
|
|
|
RCODE FLMAPI getLastChild(
|
|
IF_Db * pDb,
|
|
IF_DOMNode ** ppLastChild);
|
|
|
|
RCODE FLMAPI getNextSibling(
|
|
IF_Db * pDb,
|
|
IF_DOMNode ** ppNextSibling);
|
|
|
|
RCODE FLMAPI getPreviousSibling(
|
|
IF_Db * pDb,
|
|
IF_DOMNode ** ppPrevSibling);
|
|
|
|
RCODE FLMAPI getChild(
|
|
IF_Db * pDb,
|
|
eDomNodeType eNodeType,
|
|
IF_DOMNode ** ppChild);
|
|
|
|
RCODE FLMAPI getChildElement(
|
|
IF_Db * pDb,
|
|
FLMUINT uiElementNameId,
|
|
IF_DOMNode ** ppChild,
|
|
FLMUINT uiFlags = 0);
|
|
|
|
RCODE FLMAPI getSiblingElement(
|
|
IF_Db * pDb,
|
|
FLMUINT uiElementNameId,
|
|
FLMBOOL bNext,
|
|
IF_DOMNode ** ppSibling);
|
|
|
|
RCODE FLMAPI getAncestorElement(
|
|
IF_Db * pDb,
|
|
FLMUINT uiElementNameId,
|
|
IF_DOMNode ** ppAncestor);
|
|
|
|
RCODE FLMAPI getDescendantElement(
|
|
IF_Db * pDb,
|
|
FLMUINT uiElementNameId,
|
|
IF_DOMNode ** ppDescendant);
|
|
|
|
RCODE FLMAPI insertBefore(
|
|
IF_Db * pDb,
|
|
IF_DOMNode * pNewChild,
|
|
IF_DOMNode * pRefChild);
|
|
|
|
FINLINE RCODE FLMAPI getPrefix(
|
|
IF_Db * pDb,
|
|
FLMUNICODE * puzPrefixBuffer,
|
|
FLMUINT uiBufferSize,
|
|
FLMUINT * puiCharsReturned)
|
|
{
|
|
return( getPrefix( TRUE, pDb, (void *)puzPrefixBuffer, uiBufferSize,
|
|
puiCharsReturned));
|
|
}
|
|
|
|
FINLINE RCODE FLMAPI getPrefix(
|
|
IF_Db * pDb,
|
|
char * pszPrefixBuffer,
|
|
FLMUINT uiBufferSize,
|
|
FLMUINT * puiCharsReturned)
|
|
{
|
|
return( getPrefix( FALSE, pDb, (void *)pszPrefixBuffer, uiBufferSize,
|
|
puiCharsReturned));
|
|
}
|
|
|
|
RCODE FLMAPI getPrefixId(
|
|
IF_Db * pDb,
|
|
FLMUINT * puiPrefixId);
|
|
|
|
FINLINE RCODE FLMAPI setPrefix(
|
|
IF_Db * pDb,
|
|
const FLMUNICODE * puzPrefix)
|
|
{
|
|
return setPrefix( TRUE, pDb, (void *)puzPrefix);
|
|
}
|
|
|
|
FINLINE RCODE FLMAPI setPrefix(
|
|
IF_Db * pDb,
|
|
const char * pszPrefix)
|
|
{
|
|
return setPrefix( FALSE, pDb, (void *)pszPrefix);
|
|
}
|
|
|
|
RCODE FLMAPI setPrefixId(
|
|
IF_Db * pDb,
|
|
FLMUINT uiPrefixId);
|
|
|
|
FINLINE RCODE FLMAPI getNamespaceURI(
|
|
IF_Db * pDb,
|
|
FLMUNICODE * puzNamespaceURIBuffer,
|
|
FLMUINT uiBufferSize,
|
|
FLMUINT * puiCharsReturned)
|
|
{
|
|
return getNamespaceURI( TRUE, pDb,
|
|
(void *)puzNamespaceURIBuffer, uiBufferSize, puiCharsReturned);
|
|
}
|
|
|
|
FINLINE RCODE FLMAPI getNamespaceURI(
|
|
IF_Db * pDb,
|
|
char * pszNamespaceURIBuffer,
|
|
FLMUINT uiBufferSize,
|
|
FLMUINT * puiCharsReturned)
|
|
{
|
|
return getNamespaceURI( FALSE, pDb,
|
|
(void *)pszNamespaceURIBuffer, uiBufferSize, puiCharsReturned);
|
|
}
|
|
|
|
FINLINE RCODE FLMAPI getLocalName(
|
|
IF_Db * pDb,
|
|
FLMUNICODE * puzLocalNameBuffer,
|
|
FLMUINT uiBufferSize,
|
|
FLMUINT * puiCharsReturned)
|
|
{
|
|
return( getLocalName( TRUE, pDb, (void *)puzLocalNameBuffer,
|
|
uiBufferSize, puiCharsReturned));
|
|
}
|
|
|
|
FINLINE RCODE FLMAPI getLocalName(
|
|
IF_Db * pDb,
|
|
char * pszLocalNameBuffer,
|
|
FLMUINT uiBufferSize,
|
|
FLMUINT * puiCharsReturned)
|
|
{
|
|
return( getLocalName( FALSE, pDb, (void *)pszLocalNameBuffer, uiBufferSize,
|
|
puiCharsReturned));
|
|
}
|
|
|
|
RCODE FLMAPI getQualifiedName(
|
|
IF_Db * pDb,
|
|
FLMUNICODE * puzQualifiedNameBuffer,
|
|
FLMUINT uiBufferSize,
|
|
FLMUINT * puiCharsReturned);
|
|
|
|
RCODE FLMAPI getQualifiedName(
|
|
IF_Db * pDb,
|
|
char * pszQualifiedNameBuffer,
|
|
FLMUINT uiBufferSize,
|
|
FLMUINT * puiCharsReturned);
|
|
|
|
FINLINE RCODE FLMAPI getCollection(
|
|
IF_Db *, // pDb,
|
|
FLMUINT * puiCollection)
|
|
{
|
|
*puiCollection = m_pCachedNode->getCollection();
|
|
return( NE_XFLM_OK);
|
|
}
|
|
|
|
RCODE FLMAPI createAnnotation(
|
|
IF_Db * pDb,
|
|
IF_DOMNode ** ppAnnotation,
|
|
FLMUINT64 * pui64NodeId = NULL);
|
|
|
|
RCODE FLMAPI getAnnotation(
|
|
IF_Db * pDb,
|
|
IF_DOMNode ** ppAnnotation);
|
|
|
|
RCODE FLMAPI getAnnotationId(
|
|
IF_Db * pDb,
|
|
FLMUINT64 * pui64AnnotationId);
|
|
|
|
RCODE FLMAPI hasAnnotation(
|
|
IF_Db * pDb,
|
|
FLMBOOL * pbHasAnnotation);
|
|
|
|
FINLINE RCODE FLMAPI getIStream(
|
|
IF_Db * pDb,
|
|
IF_PosIStream ** ppIStream,
|
|
FLMUINT * puiDataType = NULL,
|
|
FLMUINT * puiDataLength = NULL)
|
|
{
|
|
return( getIStream( (F_Db *)pDb, NULL, ppIStream,
|
|
puiDataType, puiDataLength));
|
|
}
|
|
|
|
FINLINE RCODE FLMAPI getTextIStream(
|
|
IF_Db * pDb,
|
|
IF_PosIStream ** ppIStream,
|
|
FLMUINT * puiNumChars = NULL)
|
|
{
|
|
return( getTextIStream( (F_Db *)pDb, NULL, ppIStream, puiNumChars));
|
|
}
|
|
|
|
FLMUINT FLMAPI compareNode(
|
|
IF_DOMNode * pNode,
|
|
IF_Db * pDb1,
|
|
IF_Db * pDb2,
|
|
char * pszErrBuff,
|
|
FLMUINT uiErrBuffLen);
|
|
|
|
RCODE FLMAPI isDataLocalToNode(
|
|
IF_Db * pDb,
|
|
FLMBOOL * pbDataIsLocal);
|
|
|
|
// Public methods that are not part of the exposed public API in the IF_DOMNode interface
|
|
|
|
FINLINE FLMBOOL isNamespaceDecl( void)
|
|
{
|
|
if( getModeFlags() & FDOM_NAMESPACE_DECL)
|
|
{
|
|
return( TRUE);
|
|
}
|
|
|
|
return( FALSE);
|
|
}
|
|
|
|
RCODE FLMAPI setTextFastPath(
|
|
F_Db * pDb,
|
|
const void * pvValue,
|
|
FLMUINT uiNumBytesInBuffer,
|
|
eXFlmTextType eTextType,
|
|
FLMUINT uiEncDefId);
|
|
|
|
RCODE getNodeId(
|
|
F_Db * pDb,
|
|
FLMUINT64 * pui64NodeId,
|
|
FLMUINT * puiAttrNameId);
|
|
|
|
FINLINE FLMUINT64 getNodeId( void)
|
|
{
|
|
if( m_uiAttrNameId)
|
|
{
|
|
flmAssert( 0);
|
|
return( 0);
|
|
}
|
|
|
|
if( m_pCachedNode)
|
|
{
|
|
return( m_pCachedNode->getNodeId());
|
|
}
|
|
|
|
return( 0);
|
|
}
|
|
|
|
FINLINE FLMUINT64 getIxNodeId( void)
|
|
{
|
|
if( m_pCachedNode)
|
|
{
|
|
return( m_pCachedNode->getNodeId());
|
|
}
|
|
|
|
return( 0);
|
|
}
|
|
|
|
FINLINE FLMUINT getCollection( void)
|
|
{
|
|
if( m_pCachedNode)
|
|
{
|
|
return( m_pCachedNode->getCollection());
|
|
}
|
|
|
|
return( 0);
|
|
}
|
|
|
|
RCODE getIStream(
|
|
F_Db * pDb,
|
|
F_NodeBufferIStream * pStackStream,
|
|
IF_PosIStream ** ppIStream,
|
|
FLMUINT * puiDataType = NULL,
|
|
FLMUINT * puiDataLength = NULL);
|
|
|
|
RCODE getTextIStream(
|
|
F_Db * pDb,
|
|
F_NodeBufferIStream * pStackStream,
|
|
IF_PosIStream ** ppIStream,
|
|
FLMUINT * puiNumChars = NULL);
|
|
|
|
FINLINE FLMBOOL isQuarantined( void)
|
|
{
|
|
return( (getModeFlags() & FDOM_QUARANTINED)
|
|
? TRUE
|
|
: FALSE);
|
|
}
|
|
|
|
RCODE getAttributeValueNumber(
|
|
F_Db * pDb,
|
|
FLMUINT uiAttrName,
|
|
FLMUINT64 * pui64Num,
|
|
FLMBOOL * pbNeg);
|
|
|
|
RCODE getAttributeValueText(
|
|
IF_Db * pDb,
|
|
FLMUINT uiAttrName,
|
|
eXFlmTextType eTextType,
|
|
void * pvBuffer,
|
|
FLMUINT uiBufSize,
|
|
FLMUINT * puiCharsReturned,
|
|
FLMUINT * puiBufferBytesUsed);
|
|
|
|
RCODE setAttributeValueNumber(
|
|
IF_Db * pDb,
|
|
FLMUINT uiAttrName,
|
|
FLMINT64 i64Value,
|
|
FLMUINT64 ui64Value,
|
|
FLMUINT uiEncDefId);
|
|
|
|
RCODE deleteAttributes(
|
|
F_Db * pDb,
|
|
FLMUINT uiAttrToDelete,
|
|
FLMUINT uiFlags);
|
|
|
|
private:
|
|
|
|
// Methods
|
|
|
|
RCODE setTextStreaming(
|
|
F_Db * pDb,
|
|
const void * pvValue,
|
|
FLMUINT uiLength,
|
|
eXFlmTextType eTextType,
|
|
FLMBOOL bLast,
|
|
FLMUINT uiEncDefId = 0);
|
|
|
|
RCODE setBinaryStreaming(
|
|
IF_Db * pDb,
|
|
const void * pvValue,
|
|
FLMUINT uiLength,
|
|
FLMBOOL bLast,
|
|
FLMUINT uiEncDefId);
|
|
|
|
RCODE setBinaryFastPath(
|
|
IF_Db * pDb,
|
|
const void * pvValue,
|
|
FLMUINT uiLength,
|
|
FLMUINT uiEncDefId);
|
|
|
|
RCODE clearNodeValue(
|
|
F_Db * pDb);
|
|
|
|
FINLINE RCODE makeWriteCopy(
|
|
F_Db * pDb)
|
|
{
|
|
return( gv_XFlmSysData.pNodeCacheMgr->makeWriteCopy(
|
|
pDb, &m_pCachedNode));
|
|
}
|
|
|
|
RCODE canSetValue(
|
|
F_Db * pDb,
|
|
FLMUINT uiDataType);
|
|
|
|
RCODE isChildTypeValid(
|
|
eDomNodeType eChildNodeType);
|
|
|
|
RCODE isDescendantOf(
|
|
F_Db * pDb,
|
|
F_DOMNode * pAncestor,
|
|
FLMBOOL * pbDescendant);
|
|
|
|
RCODE getNumber64(
|
|
F_Db * pDb,
|
|
FLMUINT64 * pui64Num,
|
|
FLMBOOL * pbNeg);
|
|
|
|
RCODE storeTextAsNumber(
|
|
F_Db * pDb,
|
|
void * pvValue,
|
|
FLMUINT uiLength,
|
|
FLMUINT uiEncDefId = 0);
|
|
|
|
RCODE storeTextAsBinary(
|
|
F_Db * pDb,
|
|
const void * pvValue,
|
|
FLMUINT uiLength,
|
|
FLMUINT uiEncDefId = 0);
|
|
|
|
RCODE storeBinaryAsText(
|
|
F_Db * pDb,
|
|
const void * pvValue,
|
|
FLMUINT uiLength,
|
|
FLMUINT uiEncDefId = 0);
|
|
|
|
FINLINE RCODE syncFromDb(
|
|
F_Db * pDb)
|
|
{
|
|
F_CachedNode * pCachedNode = m_pCachedNode;
|
|
|
|
if( !pCachedNode)
|
|
{
|
|
return( RC_SET( NE_XFLM_DOM_NODE_DELETED));
|
|
}
|
|
else if( !pCachedNode->nodeLinkedToDatabase())
|
|
{
|
|
return( _syncFromDb( pDb));
|
|
}
|
|
else if( pDb->m_pDatabase != pCachedNode->getDatabase())
|
|
{
|
|
return( RC_SET_AND_ASSERT( NE_XFLM_ILLEGAL_OP));
|
|
}
|
|
else if( pCachedNode->isRightVersion( pDb->m_ui64CurrTransID) &&
|
|
!pCachedNode->nodePurged())
|
|
{
|
|
if( m_uiAttrNameId)
|
|
{
|
|
if( !pCachedNode->m_uiAttrCount ||
|
|
!pCachedNode->getAttribute( m_uiAttrNameId, NULL))
|
|
{
|
|
return( RC_SET( NE_XFLM_DOM_NODE_DELETED));
|
|
}
|
|
}
|
|
|
|
return( NE_XFLM_OK);
|
|
}
|
|
|
|
return( _syncFromDb( pDb));
|
|
}
|
|
|
|
RCODE _syncFromDb(
|
|
F_Db * pDb);
|
|
|
|
RCODE unlinkNode(
|
|
F_Db * pDb,
|
|
FLMUINT uiFlags);
|
|
|
|
RCODE addModeFlags(
|
|
F_Db * pDb,
|
|
FLMUINT uiFlags);
|
|
|
|
RCODE removeModeFlags(
|
|
F_Db * pDb,
|
|
FLMUINT uiFlags);
|
|
|
|
FINLINE FLMBOOL canHaveChildren( void)
|
|
{
|
|
|
|
if( m_pCachedNode)
|
|
{
|
|
eDomNodeType eNodeType = getNodeType();
|
|
|
|
return( (eNodeType == DOCUMENT_NODE ||
|
|
eNodeType == ELEMENT_NODE)
|
|
? TRUE
|
|
: FALSE);
|
|
}
|
|
|
|
return( FALSE);
|
|
}
|
|
|
|
RCODE getData(
|
|
F_Db * pDb,
|
|
FLMBYTE * pucBuffer,
|
|
FLMUINT * puiLength);
|
|
|
|
void addNodeToMRUList(
|
|
F_DOMNode * pNode);
|
|
|
|
void removeNodeFromMRUList(
|
|
F_DOMNode * pNode);
|
|
|
|
RCODE getNodeFromMRUList(
|
|
F_Db * pDb,
|
|
eDomNodeType eNodeType,
|
|
FLMUINT uiNameId,
|
|
F_DOMNode ** ppNode);
|
|
|
|
RCODE getNodeFromMRUListById(
|
|
F_Db * pDb,
|
|
FLMUINT64 ui64NodeId,
|
|
F_DOMNode ** ppNode);
|
|
|
|
RCODE getLocalName(
|
|
FLMBOOL bUnicode,
|
|
IF_Db * pDb,
|
|
void * pvLocalName,
|
|
FLMUINT uiBufSize,
|
|
FLMUINT * puiCharsReturned);
|
|
|
|
RCODE getPrefix(
|
|
FLMBOOL bUnicode,
|
|
IF_Db * pDb,
|
|
void * pvPrefix,
|
|
FLMUINT uiBufSize,
|
|
FLMUINT * puiCharsReturned);
|
|
|
|
RCODE setPrefix(
|
|
FLMBOOL bUnicode,
|
|
IF_Db * pDb,
|
|
void * pvPrefix);
|
|
|
|
FINLINE FLMUINT64 getDocumentId( void)
|
|
{
|
|
if( m_pCachedNode)
|
|
{
|
|
return( m_pCachedNode->getDocumentId());
|
|
}
|
|
|
|
flmAssert( 0);
|
|
return( 0);
|
|
}
|
|
|
|
FINLINE FLMBOOL isRootNode( void)
|
|
{
|
|
eDomNodeType eNodeType = getNodeType();
|
|
|
|
if( eNodeType == DOCUMENT_NODE ||
|
|
eNodeType == ELEMENT_NODE)
|
|
{
|
|
return( m_pCachedNode->isRootNode());
|
|
}
|
|
|
|
return( FALSE);
|
|
}
|
|
|
|
FINLINE FLMUINT64 getParentId( void)
|
|
{
|
|
if( !m_pCachedNode)
|
|
{
|
|
return( 0);
|
|
}
|
|
|
|
if( m_uiAttrNameId)
|
|
{
|
|
return( m_pCachedNode->getNodeId());
|
|
}
|
|
|
|
return( m_pCachedNode->getParentId());
|
|
}
|
|
|
|
FINLINE void setParentId(
|
|
FLMUINT64 ui64ParentId)
|
|
{
|
|
flmAssert( nodeUncommitted());
|
|
flmAssert( getNodeType() != ATTRIBUTE_NODE);
|
|
|
|
m_pCachedNode->setParentId( ui64ParentId);
|
|
}
|
|
|
|
FINLINE FLMUINT64 getFirstChildId( void)
|
|
{
|
|
flmAssert( getNodeType() != ATTRIBUTE_NODE);
|
|
|
|
if( m_pCachedNode)
|
|
{
|
|
return( m_pCachedNode->getFirstChildId());
|
|
}
|
|
|
|
return( 0);
|
|
}
|
|
|
|
FINLINE FLMUINT64 getLastChildId( void)
|
|
{
|
|
flmAssert( getNodeType() != ATTRIBUTE_NODE);
|
|
|
|
if( m_pCachedNode)
|
|
{
|
|
return( m_pCachedNode->getLastChildId());
|
|
}
|
|
|
|
return( 0);
|
|
}
|
|
|
|
FINLINE FLMUINT64 getPrevSibId( void)
|
|
{
|
|
flmAssert( getNodeType() != ATTRIBUTE_NODE);
|
|
|
|
if( m_pCachedNode)
|
|
{
|
|
return( m_pCachedNode->getPrevSibId());
|
|
}
|
|
|
|
return( 0);
|
|
}
|
|
|
|
FINLINE void setPrevSibId(
|
|
FLMUINT64 ui64PrevSibId)
|
|
{
|
|
flmAssert( nodeUncommitted());
|
|
flmAssert( getNodeType() != ATTRIBUTE_NODE);
|
|
|
|
m_pCachedNode->setPrevSibId( ui64PrevSibId);
|
|
}
|
|
|
|
FINLINE FLMUINT64 getNextSibId( void)
|
|
{
|
|
flmAssert( getNodeType() != ATTRIBUTE_NODE);
|
|
|
|
if( m_pCachedNode)
|
|
{
|
|
return( m_pCachedNode->getNextSibId());
|
|
}
|
|
|
|
return( 0);
|
|
}
|
|
|
|
FINLINE void setNextSibId(
|
|
FLMUINT64 ui64NextSibId)
|
|
{
|
|
flmAssert( nodeUncommitted());
|
|
flmAssert( getNodeType() != ATTRIBUTE_NODE);
|
|
|
|
m_pCachedNode->setNextSibId( ui64NextSibId);
|
|
}
|
|
|
|
FINLINE FLMUINT getDataChildCount( void)
|
|
{
|
|
flmAssert( getNodeType() == ELEMENT_NODE);
|
|
|
|
if( m_pCachedNode)
|
|
{
|
|
return( m_pCachedNode->getDataChildCount());
|
|
}
|
|
|
|
return( 0);
|
|
}
|
|
|
|
FINLINE void setDataChildCount(
|
|
FLMUINT uiDataChildCount)
|
|
{
|
|
flmAssert( nodeUncommitted());
|
|
flmAssert( getNodeType() == ELEMENT_NODE);
|
|
|
|
m_pCachedNode->setDataChildCount( uiDataChildCount);
|
|
}
|
|
|
|
FINLINE FLMUINT getModeFlags( void)
|
|
{
|
|
if( m_uiAttrNameId)
|
|
{
|
|
return( m_pCachedNode->getModeFlags( m_uiAttrNameId));
|
|
}
|
|
else if( m_pCachedNode)
|
|
{
|
|
return( m_pCachedNode->getModeFlags());
|
|
}
|
|
|
|
return( 0);
|
|
}
|
|
|
|
RCODE getNamespaceURI(
|
|
FLMBOOL bUnicode,
|
|
IF_Db * pDb,
|
|
void * pvNamespaceURI,
|
|
FLMUINT uiBufSize,
|
|
FLMUINT * puiCharsReturned);
|
|
|
|
RCODE setNumber64(
|
|
IF_Db * pDb,
|
|
FLMINT64 i64Value,
|
|
FLMUINT64 ui64Value,
|
|
FLMUINT uiEncDefId = 0);
|
|
|
|
RCODE setStorageValue(
|
|
F_Db * pDb,
|
|
void * pvValue,
|
|
FLMUINT uiValueLen,
|
|
FLMUINT uiEncDefId,
|
|
FLMBOOL bLast);
|
|
|
|
FINLINE void setBlkAddr(
|
|
FLMUINT32 ui32BlkAddr)
|
|
{
|
|
m_pCachedNode->setBlkAddr( ui32BlkAddr);
|
|
}
|
|
|
|
FINLINE void setOffsetIndex(
|
|
FLMUINT uiOffsetIndex)
|
|
{
|
|
m_pCachedNode->setOffsetIndex( uiOffsetIndex);
|
|
}
|
|
|
|
FINLINE FLMUINT getOffsetIndex( void)
|
|
{
|
|
return( m_pCachedNode->getOffsetIndex());
|
|
}
|
|
|
|
FINLINE FLMUINT32 getBlkAddr( void)
|
|
{
|
|
return( m_pCachedNode->getBlkAddr());
|
|
}
|
|
|
|
FINLINE void unsetNodeDirtyAndNew(
|
|
F_Db * pDb)
|
|
{
|
|
m_pCachedNode->unsetNodeDirtyAndNew( pDb);
|
|
}
|
|
|
|
FINLINE FLMUINT getPrefixId( void)
|
|
{
|
|
flmAssert( getNodeType() != ATTRIBUTE_NODE);
|
|
return( m_pCachedNode->getPrefixId());
|
|
}
|
|
|
|
FINLINE void setPrefixId(
|
|
FLMUINT uiPrefixId)
|
|
{
|
|
flmAssert( nodeUncommitted());
|
|
flmAssert( getNodeType() != ATTRIBUTE_NODE);
|
|
|
|
m_pCachedNode->setPrefixId( uiPrefixId);
|
|
}
|
|
|
|
FINLINE FLMUINT getNameId( void)
|
|
{
|
|
if( m_uiAttrNameId)
|
|
{
|
|
return( m_uiAttrNameId);
|
|
}
|
|
|
|
return( m_pCachedNode->getNameId());
|
|
}
|
|
|
|
FINLINE void setNameId(
|
|
FLMUINT uiNameId)
|
|
{
|
|
flmAssert( nodeUncommitted());
|
|
flmAssert( getNodeType() != ATTRIBUTE_NODE);
|
|
|
|
m_pCachedNode->setNameId( uiNameId);
|
|
}
|
|
|
|
FINLINE FLMUINT getDataType( void)
|
|
{
|
|
if( m_uiAttrNameId)
|
|
{
|
|
F_AttrItem * pAttrItem;
|
|
|
|
if( (pAttrItem = m_pCachedNode->getAttribute(
|
|
m_uiAttrNameId, NULL)) == NULL)
|
|
{
|
|
flmAssert( 0);
|
|
return( XFLM_UNKNOWN_TYPE);
|
|
}
|
|
|
|
return( pAttrItem->m_uiDataType);
|
|
}
|
|
|
|
return( m_pCachedNode->getDataType());
|
|
}
|
|
|
|
FINLINE void setDataType(
|
|
FLMUINT uiDataType)
|
|
{
|
|
flmAssert( nodeUncommitted());
|
|
flmAssert( getNodeType() != ATTRIBUTE_NODE);
|
|
|
|
m_pCachedNode->setDataType( uiDataType);
|
|
}
|
|
|
|
FINLINE FLMUINT getDataLength( void)
|
|
{
|
|
flmAssert( getNodeType() != ATTRIBUTE_NODE);
|
|
return( m_pCachedNode->getDataLength());
|
|
}
|
|
|
|
FINLINE void setDataLength(
|
|
FLMUINT uiDataLength)
|
|
{
|
|
flmAssert( nodeUncommitted());
|
|
flmAssert( getNodeType() != ATTRIBUTE_NODE);
|
|
|
|
m_pCachedNode->setDataLength( uiDataLength);
|
|
}
|
|
|
|
FINLINE FLMBYTE * getDataPtr( void)
|
|
{
|
|
flmAssert( getNodeType() != ATTRIBUTE_NODE);
|
|
return( m_pCachedNode->getDataPtr());
|
|
}
|
|
|
|
FINLINE FLMBOOL getQuickNumber64(
|
|
FLMUINT64 * pui64Num,
|
|
FLMBOOL * pbNeg)
|
|
{
|
|
flmAssert( getNodeType() != ATTRIBUTE_NODE);
|
|
return( m_pCachedNode->getQuickNumber64( pui64Num, pbNeg));
|
|
}
|
|
|
|
FINLINE FLMBOOL nodeIsDirty( void)
|
|
{
|
|
return( m_pCachedNode->nodeIsDirty());
|
|
}
|
|
|
|
FINLINE FLMBOOL nodeUncommitted( void)
|
|
{
|
|
return( m_pCachedNode->nodeUncommitted());
|
|
}
|
|
|
|
FINLINE FLMUINT getStreamUseCount( void)
|
|
{
|
|
return( m_pCachedNode->getStreamUseCount());
|
|
}
|
|
|
|
FINLINE FLMUINT64 getAnnotationId( void)
|
|
{
|
|
flmAssert( getNodeType() != ATTRIBUTE_NODE);
|
|
return( m_pCachedNode->getAnnotationId());
|
|
}
|
|
|
|
FINLINE void setAnnotationId(
|
|
FLMUINT64 ui64AnnotationId)
|
|
{
|
|
flmAssert( nodeUncommitted());
|
|
flmAssert( getNodeType() != ATTRIBUTE_NODE);
|
|
|
|
m_pCachedNode->setAnnotationId( ui64AnnotationId);
|
|
}
|
|
|
|
FINLINE void setLastChildId(
|
|
FLMUINT64 ui64LastChildId)
|
|
{
|
|
flmAssert( nodeUncommitted());
|
|
flmAssert( getNodeType() != ATTRIBUTE_NODE);
|
|
|
|
m_pCachedNode->setLastChildId( ui64LastChildId);
|
|
}
|
|
|
|
FINLINE void setFirstChildId(
|
|
FLMUINT64 ui64FirstChildId)
|
|
{
|
|
flmAssert( nodeUncommitted());
|
|
flmAssert( getNodeType() != ATTRIBUTE_NODE);
|
|
|
|
m_pCachedNode->setFirstChildId( ui64FirstChildId);
|
|
}
|
|
|
|
FINLINE FLMUINT getEncDefId( void)
|
|
{
|
|
flmAssert( getNodeType() != ATTRIBUTE_NODE);
|
|
return( m_pCachedNode->getEncDefId());
|
|
}
|
|
|
|
FINLINE F_Database * getDatabase( void)
|
|
{
|
|
if( m_pCachedNode)
|
|
{
|
|
return( m_pCachedNode->getDatabase());
|
|
}
|
|
|
|
return( NULL);
|
|
}
|
|
|
|
FINLINE RCODE openPendingInput(
|
|
F_Db * pDb,
|
|
FLMUINT uiNewDataType)
|
|
{
|
|
flmAssert( getNodeType() != ATTRIBUTE_NODE);
|
|
return( m_pCachedNode->openPendingInput( pDb, uiNewDataType));
|
|
}
|
|
|
|
FINLINE FLMBOOL findChildElm(
|
|
FLMUINT uiChildElmNameId,
|
|
FLMUINT * puiInsertPos)
|
|
{
|
|
flmAssert( getNodeType() != ATTRIBUTE_NODE);
|
|
return( m_pCachedNode->findChildElm( uiChildElmNameId, puiInsertPos));
|
|
}
|
|
|
|
FINLINE RCODE removeChildElm(
|
|
FLMUINT uiChildElmOffset)
|
|
{
|
|
flmAssert( getNodeType() != ATTRIBUTE_NODE);
|
|
return( m_pCachedNode->removeChildElm( uiChildElmOffset));
|
|
}
|
|
|
|
FINLINE FLMUINT getChildElmCount( void)
|
|
{
|
|
flmAssert( getNodeType() != ATTRIBUTE_NODE);
|
|
return( m_pCachedNode->getChildElmCount());
|
|
}
|
|
|
|
FINLINE FLMUINT64 getChildElmNodeId(
|
|
FLMUINT uiChildElmOffset)
|
|
{
|
|
flmAssert( getNodeType() != ATTRIBUTE_NODE);
|
|
return( m_pCachedNode->getChildElmNodeId( uiChildElmOffset));
|
|
}
|
|
|
|
FINLINE FLMUINT getChildElmNameId(
|
|
FLMUINT uiChildElmOffset)
|
|
{
|
|
flmAssert( getNodeType() != ATTRIBUTE_NODE);
|
|
return( m_pCachedNode->getChildElmNameId( uiChildElmOffset));
|
|
}
|
|
|
|
FINLINE FLMBOOL hasAttributes( void)
|
|
{
|
|
flmAssert( getNodeType() != ATTRIBUTE_NODE);
|
|
return( m_pCachedNode->hasAttributes());
|
|
}
|
|
|
|
FINLINE void setFlags(
|
|
FLMUINT uiFlags)
|
|
{
|
|
flmAssert( getNodeType() != ATTRIBUTE_NODE);
|
|
m_pCachedNode->setFlags( uiFlags);
|
|
}
|
|
|
|
FINLINE void unsetFlags(
|
|
FLMUINT uiFlags)
|
|
{
|
|
flmAssert( getNodeType() != ATTRIBUTE_NODE);
|
|
m_pCachedNode->unsetFlags( uiFlags);
|
|
}
|
|
|
|
FINLINE void setEncDefId(
|
|
FLMUINT uiEncDefId)
|
|
{
|
|
flmAssert( getNodeType() != ATTRIBUTE_NODE);
|
|
m_pCachedNode->setEncDefId( uiEncDefId);
|
|
}
|
|
|
|
FINLINE RCODE flushPendingInput(
|
|
F_Db * pDb,
|
|
FLMBOOL bLast)
|
|
{
|
|
flmAssert( getNodeType() != ATTRIBUTE_NODE);
|
|
return( m_pCachedNode->flushPendingInput( pDb, bLast));
|
|
}
|
|
|
|
FINLINE FLMUINT getDataBufSize( void)
|
|
{
|
|
flmAssert( getNodeType() != ATTRIBUTE_NODE);
|
|
return( m_pCachedNode->getDataBufSize());
|
|
}
|
|
|
|
FINLINE RCODE resizeDataBuffer(
|
|
FLMUINT uiSize,
|
|
FLMBOOL bMutexAlreadyLocked)
|
|
{
|
|
flmAssert( getNodeType() != ATTRIBUTE_NODE);
|
|
return( m_pCachedNode->resizeDataBuffer( uiSize, bMutexAlreadyLocked));
|
|
}
|
|
|
|
FINLINE RCODE headerToBuf(
|
|
FLMBOOL bFixedSizeHeader,
|
|
FLMBYTE * pucBuf,
|
|
FLMUINT * puiHeaderSize,
|
|
XFLM_NODE_INFO * pNodeInfo,
|
|
F_Db * pDb)
|
|
{
|
|
flmAssert( getNodeType() != ATTRIBUTE_NODE);
|
|
return( m_pCachedNode->headerToBuf( bFixedSizeHeader, pucBuf,
|
|
puiHeaderSize, pNodeInfo, pDb));
|
|
}
|
|
|
|
FINLINE FLMINT64 getQuickINT64( void)
|
|
{
|
|
flmAssert( getNodeType() != ATTRIBUTE_NODE);
|
|
return( m_pCachedNode->getQuickINT64());
|
|
}
|
|
|
|
FINLINE FLMUINT64 getQuickUINT64( void)
|
|
{
|
|
flmAssert( getNodeType() != ATTRIBUTE_NODE);
|
|
return( m_pCachedNode->getQuickUINT64());
|
|
}
|
|
|
|
FINLINE void setUINT64(
|
|
FLMUINT64 ui64Value)
|
|
{
|
|
flmAssert( getNodeType() != ATTRIBUTE_NODE);
|
|
m_pCachedNode->setUINT64( ui64Value);
|
|
}
|
|
|
|
FINLINE void setINT64(
|
|
FLMINT64 i64Value)
|
|
{
|
|
flmAssert( getNodeType() != ATTRIBUTE_NODE);
|
|
m_pCachedNode->setINT64( i64Value);
|
|
}
|
|
|
|
FINLINE FLMUINT64 getMetaValue( void)
|
|
{
|
|
flmAssert( getNodeType() != ATTRIBUTE_NODE);
|
|
return( m_pCachedNode->getMetaValue());
|
|
}
|
|
|
|
FINLINE void setMetaValue(
|
|
FLMUINT64 ui64Value)
|
|
{
|
|
flmAssert( getNodeType() != ATTRIBUTE_NODE);
|
|
m_pCachedNode->setMetaValue( ui64Value);
|
|
}
|
|
|
|
FINLINE RCODE checkAttrList( void)
|
|
{
|
|
if( !m_pCachedNode)
|
|
{
|
|
return( RC_SET( NE_XFLM_DOM_NODE_NOT_FOUND));
|
|
}
|
|
else if( m_pCachedNode->getNodeType() != ELEMENT_NODE)
|
|
{
|
|
return( RC_SET_AND_ASSERT( NE_XFLM_ILLEGAL_OP));
|
|
}
|
|
else if( !m_pCachedNode->m_uiAttrCount)
|
|
{
|
|
return( RC_SET( NE_XFLM_DOM_NODE_NOT_FOUND));
|
|
}
|
|
return( NE_XFLM_OK);
|
|
}
|
|
|
|
// Data
|
|
|
|
F_CachedNode * m_pCachedNode;
|
|
F_DOMNode * m_pNextInPool;
|
|
|
|
// Valid only if this is an attribute node
|
|
|
|
FLMUINT m_uiAttrNameId;
|
|
|
|
friend class F_Db;
|
|
friend class F_Database;
|
|
friend class F_BTreeIStream;
|
|
friend class F_NodeBufferIStream;
|
|
friend class F_Dict;
|
|
friend class F_XMLImport;
|
|
friend class F_NodePool;
|
|
friend class F_DbRebuild;
|
|
friend class F_Query;
|
|
friend class FSCollectionCursor;
|
|
friend class F_NodeCacheMgr;
|
|
friend class F_Rfl;
|
|
friend class F_CachedNode;
|
|
friend class F_OldNodeList;
|
|
friend class F_DbCheck;
|
|
friend class F_NodeInfo;
|
|
};
|
|
|
|
/*===========================================================================
|
|
Desc: Pool manager for DOM nodes
|
|
===========================================================================*/
|
|
class F_NodePool : public F_Object
|
|
{
|
|
public:
|
|
|
|
F_NodePool()
|
|
{
|
|
m_pFirstBTreeIStream = NULL;
|
|
m_hMutex = F_MUTEX_NULL;
|
|
}
|
|
|
|
~F_NodePool();
|
|
|
|
RCODE setup( void);
|
|
|
|
RCODE allocBTreeIStream(
|
|
F_BTreeIStream ** ppBTreeIStream);
|
|
|
|
void insertBTreeIStream(
|
|
F_BTreeIStream * pBTreeIStream);
|
|
|
|
private:
|
|
|
|
F_BTreeIStream * m_pFirstBTreeIStream;
|
|
F_MUTEX m_hMutex;
|
|
|
|
friend class F_DOMNode;
|
|
friend class F_BTreeIStream;
|
|
friend class F_NodeBufferIStream;
|
|
};
|
|
|
|
typedef struct
|
|
{
|
|
FLMUINT uiCollectionNum;
|
|
FLMUINT64 ui64HighestNodeIdFound;
|
|
FLMUINT64 ui64HighestNextNodeIdFound;
|
|
FLMUINT uiNumNextNodeIdsFound;
|
|
FLMUINT uiEncId;
|
|
} COLLECTION_INFO, * COLLECTION_INFO_p;
|
|
|
|
typedef struct Recov_Dict_Node * RECOV_DICT_NODE_p;
|
|
typedef struct Recov_Dict_Info * RECOV_DICT_INFO_p;
|
|
|
|
typedef struct Recov_Dict_Node
|
|
{
|
|
RECOV_DICT_NODE_p pNext;
|
|
F_DOMNode * pNode;
|
|
FLMUINT64 ui64NodeId;
|
|
FLMUINT uiElmOffset;
|
|
FLMBOOL bAdded;
|
|
FLMBOOL bGotFromDataCollection;
|
|
FLMUINT32 ui32BlkAddress;
|
|
} RECOV_DICT_NODE;
|
|
|
|
typedef struct Recov_Dict_Info
|
|
{
|
|
RECOV_DICT_NODE * pRecovNodes;
|
|
F_Pool * pPool;
|
|
} RECOV_DICT_INFO;
|
|
|
|
typedef struct RSIxKeyTag
|
|
{
|
|
FLMBYTE pucRSKeyBuf[ XFLM_MAX_KEY_SIZE];
|
|
FLMUINT uiRSKeyLen;
|
|
FLMBYTE pucRSDataBuf[ XFLM_MAX_KEY_SIZE];
|
|
FLMUINT uiRSDataLen;
|
|
} RS_IX_KEY;
|
|
|
|
/******************************************************************************
|
|
Desc:
|
|
******************************************************************************/
|
|
class F_KeyCollector : public F_Object
|
|
{
|
|
|
|
public:
|
|
|
|
F_KeyCollector(
|
|
F_DbCheck * pDbCheck)
|
|
{
|
|
m_pDbCheck = pDbCheck;
|
|
m_ui64TotalKeys = 0;
|
|
}
|
|
|
|
~F_KeyCollector(){}
|
|
|
|
RCODE addKey(
|
|
F_Db * pDb,
|
|
IXD * pIxd,
|
|
KREF_ENTRY * pKref);
|
|
|
|
FLMUINT64 getTotalKeys()
|
|
{
|
|
return m_ui64TotalKeys;
|
|
}
|
|
|
|
private:
|
|
|
|
F_DbCheck * m_pDbCheck;
|
|
FLMUINT64 m_ui64TotalKeys;
|
|
|
|
friend class F_DbCheck;
|
|
};
|
|
|
|
|
|
typedef struct
|
|
{
|
|
F_DOMNode * pNode; // DOM Node to examine to see if it contains
|
|
// dictionary information.
|
|
FLMUINT uiCollection; // Collection the node came from.
|
|
FLMUINT64 ui64NodeId; // NodeId of node.
|
|
} CHK_RECORD, * CHK_RECORD_p;
|
|
|
|
typedef struct
|
|
{
|
|
FLMUINT64 ui64BytesUsed;
|
|
FLMUINT64 ui64ElementCount;
|
|
FLMUINT64 ui64ContElementCount;
|
|
FLMUINT64 ui64ContElmBytes;
|
|
FLMUINT uiBlockCount;
|
|
FLMINT iErrCode;
|
|
FLMUINT uiNumErrors;
|
|
} BLOCK_INFO;
|
|
|
|
typedef struct
|
|
{
|
|
FLMUINT64 ui64KeyCount;
|
|
BLOCK_INFO BlockInfo;
|
|
} LEVEL_INFO;
|
|
|
|
typedef struct
|
|
{
|
|
FLMUINT uiLfNum;
|
|
eLFileType eLfType;
|
|
FLMUINT uiRootBlk;
|
|
FLMUINT uiNumLevels;
|
|
LEVEL_INFO * pLevelInfo;
|
|
} LF_HDR;
|
|
|
|
/******************************************************************************
|
|
Desc:
|
|
******************************************************************************/
|
|
typedef struct State_Info
|
|
{
|
|
F_Db * pDb;
|
|
FLMUINT32 ui32BlkAddress;
|
|
FLMUINT32 ui32NextBlkAddr;
|
|
FLMUINT32 ui32PrevBlkAddr;
|
|
FLMUINT32 ui32LastChildAddr;
|
|
FLMUINT uiElmLastFlag;
|
|
FLMUINT64 ui64KeyCount;
|
|
FLMUINT64 ui64KeyRefs;
|
|
FLMUINT uiBlkType;
|
|
FLMUINT uiLevel;
|
|
FLMUINT uiRootLevel;
|
|
F_COLLECTION * pCollection;
|
|
FLMUINT uiElmOffset;
|
|
FLMBYTE * pucElm;
|
|
FLMUINT uiElmLen;
|
|
FLMUINT uiElmKeyLenOffset; // New
|
|
FLMUINT uiElmKeyOffset; // New
|
|
FLMBYTE * pucElmKey;
|
|
FLMUINT uiElmKeyLen;
|
|
FLMUINT uiCurKeyLen; // Used in Rebuild...
|
|
FLMUINT uiElmDataLenOffset; // New
|
|
FLMUINT uiElmDataOffset; // uiElmRecOffset;
|
|
FLMUINT uiElmDataLen; // uiElmRecLen;
|
|
FLMBYTE * pucElmData; // pucElmRec;
|
|
FLMUINT uiElmCounts; // New
|
|
FLMUINT uiElmCountsOffset; // New
|
|
FLMUINT uiElmOADataLenOffset;
|
|
FLMUINT uiElmOADataLen;
|
|
FLMUINT64 ui64ElmNodeId;
|
|
FLMBOOL bValidKey;
|
|
F_BLK_HDR * pBlkHdr;
|
|
F_NodeVerifier * pNodeVerifier;
|
|
BLOCK_INFO BlkInfo;
|
|
F_BtResultSet * pNodeRS;
|
|
F_BtResultSet * pXRefRS;
|
|
FLMUINT uiCurrLf;
|
|
} STATE_INFO;
|
|
|
|
/******************************************************************************
|
|
Desc:
|
|
******************************************************************************/
|
|
class F_NodeVerifier : public F_Object
|
|
{
|
|
public:
|
|
|
|
F_NodeVerifier();
|
|
|
|
~F_NodeVerifier();
|
|
|
|
void Reset(
|
|
STATE_INFO * pStateInfo);
|
|
|
|
RCODE AddData(
|
|
FLMUINT64 ui64NodeId,
|
|
void * pucData,
|
|
FLMUINT uiDataLen);
|
|
|
|
RCODE finalize(
|
|
F_Db * pDb,
|
|
F_Dict * pDict,
|
|
FLMUINT uiCollection,
|
|
FLMUINT64 ui64NodeId,
|
|
FLMBOOL bSkipDOMLinkCheck,
|
|
FLMINT * piElmErrCodeRV);
|
|
|
|
FINLINE void setupNodeRS(
|
|
F_BtResultSet * pRS)
|
|
{
|
|
m_pRS = pRS;
|
|
}
|
|
|
|
FINLINE void setupXRefRS(
|
|
F_BtResultSet * pXRefRS)
|
|
|
|
{
|
|
m_pXRefRS = pXRefRS;
|
|
}
|
|
|
|
private:
|
|
|
|
RCODE verifyNameId(
|
|
F_Db * pDb,
|
|
eDomNodeType eNodeType,
|
|
FLMUINT uiNameId,
|
|
F_NameTable * pNameTable,
|
|
FLMINT * piErrCode);
|
|
|
|
RCODE verifyPrefixId(
|
|
F_Db * pDb,
|
|
FLMUINT uiPrefixId,
|
|
F_NameTable * pNameTable,
|
|
FLMINT * piErrCode);
|
|
|
|
RCODE checkForIndexes(
|
|
F_Db * pDb,
|
|
F_Dict * pDict,
|
|
FLMUINT uiCollection);
|
|
|
|
FLMBOOL m_bFinalizeCalled;
|
|
FLMBYTE * m_pucBuf;
|
|
FLMBYTE m_ucBuf[ MAX_DOM_HEADER_SIZE];
|
|
|
|
FLMUINT m_uiBufSize;
|
|
FLMUINT m_uiBytesInBuf;
|
|
FLMUINT m_uiOverallLength;
|
|
|
|
F_NODE_INFO m_nodeInfo;
|
|
|
|
F_BtResultSet * m_pRS;
|
|
F_BtResultSet * m_pXRefRS;
|
|
};
|
|
|
|
/******************************************************************************
|
|
Desc:
|
|
******************************************************************************/
|
|
typedef struct
|
|
{
|
|
F_NODE_INFO nodeInfo;
|
|
FLMUINT uiStorageFlags;
|
|
FLMUINT uiDataBufSize;
|
|
FLMBYTE * pucData;
|
|
FLMBOOL bUseFilename;
|
|
FLMBOOL bGotFromDataCollection;
|
|
FLMBOOL bProcessed;
|
|
FLMBYTE ucSortKey;
|
|
} REBUILD_NODE_INFO;
|
|
|
|
/******************************************************************************
|
|
Desc:
|
|
******************************************************************************/
|
|
class RebuildNodeInfoStack : public F_Object
|
|
{
|
|
public:
|
|
|
|
RebuildNodeInfoStack();
|
|
|
|
~RebuildNodeInfoStack();
|
|
|
|
RCODE setup( void);
|
|
|
|
RCODE push(
|
|
REBUILD_NODE_INFO * pRebuildNodeInfo);
|
|
|
|
RCODE pop(
|
|
REBUILD_NODE_INFO * pRebuildNodeInfo);
|
|
|
|
void reset( void);
|
|
|
|
private:
|
|
|
|
REBUILD_NODE_INFO * m_pStack;
|
|
FLMUINT m_uiStackSize;
|
|
FLMUINT m_uiNextPos;
|
|
FLMBOOL m_bSetupCalled;
|
|
};
|
|
|
|
/******************************************************************************
|
|
Desc:
|
|
******************************************************************************/
|
|
typedef struct
|
|
{
|
|
FLMUINT uiStartOfEntry;
|
|
FLMUINT uiEndOfEntry;
|
|
} BlkStruct;
|
|
|
|
/******************************************************************************
|
|
Desc: DbCheck object for verifying the condition of the database.
|
|
******************************************************************************/
|
|
class F_DbCheck : public F_Object
|
|
{
|
|
|
|
public:
|
|
F_DbCheck( void)
|
|
{
|
|
m_bSkipDOMLinkCheck = FALSE;
|
|
m_pXRefRS = NULL;
|
|
m_pDb = NULL;
|
|
m_pIxd = NULL;
|
|
m_pCollection = NULL;
|
|
m_pLFile = NULL;
|
|
m_pDbInfo = NULL;
|
|
m_pBtPool = NULL;
|
|
m_pResultSetDb = NULL;
|
|
m_pRandGen = NULL;
|
|
m_pDbCheckStatus = NULL;
|
|
f_memset( m_szResultSetDibName, 0, sizeof( m_szResultSetDibName));
|
|
m_bPhysicalCorrupt = FALSE;
|
|
m_bIndexCorrupt = FALSE;
|
|
m_LastStatusRc = NE_XFLM_OK;
|
|
m_uiFlags = 0;
|
|
m_bStartedUpdateTrans = FALSE;
|
|
m_puiIxArray = NULL;
|
|
m_pIxRSet = NULL;
|
|
m_bGetNextRSKey = FALSE;
|
|
f_memset( &m_IxKey1, 0, sizeof( m_IxKey1));
|
|
f_memset( &m_IxKey2, 0, sizeof( m_IxKey2));
|
|
m_pCurrRSKey = NULL;
|
|
m_pPrevRSKey = NULL;
|
|
m_pBlkEntries = NULL;
|
|
m_uiBlkEntryArraySize = 0;
|
|
}
|
|
|
|
~F_DbCheck();
|
|
|
|
RCODE dbCheck(
|
|
const char * pszDbFileName,
|
|
const char * pszDataDir,
|
|
const char * pszRflDir,
|
|
const char * pszPassword,
|
|
FLMUINT uiFlags,
|
|
IF_DbInfo ** ppDbInfo,
|
|
IF_DbCheckStatus * pDbCheck);
|
|
|
|
private:
|
|
|
|
FINLINE RCODE chkCallProgFunc( void)
|
|
{
|
|
if (m_pDbCheckStatus && RC_OK( m_LastStatusRc))
|
|
{
|
|
m_LastStatusRc = m_pDbCheckStatus->reportProgress( &m_Progress);
|
|
}
|
|
return( m_LastStatusRc);
|
|
}
|
|
|
|
RCODE chkReportError(
|
|
FLMINT iErrCode,
|
|
FLMUINT uiErrLocale,
|
|
FLMUINT uiErrLfNumber,
|
|
FLMUINT uiErrLfType,
|
|
FLMUINT uiErrBTreeLevel,
|
|
FLMUINT uiErrBlkAddress,
|
|
FLMUINT uiErrParentBlkAddress,
|
|
FLMUINT uiErrElmOffset,
|
|
FLMUINT64 ui64ErrNodeId);
|
|
|
|
FINLINE XFLM_PROGRESS_CHECK_INFO * getProgress( void)
|
|
{
|
|
return( &m_Progress);
|
|
}
|
|
|
|
RCODE getBtResultSet(
|
|
F_BtResultSet ** ppBtRSet);
|
|
|
|
RCODE createAndOpenResultSetDb( void);
|
|
|
|
RCODE closeAndDeleteResultSetDb( void);
|
|
|
|
RCODE getDictInfo( void);
|
|
|
|
RCODE verifyBlkChain(
|
|
BLOCK_INFO * pBlkInfo,
|
|
FLMUINT uiLocale,
|
|
FLMUINT uiFirstBlkAddr,
|
|
FLMUINT uiBlkType,
|
|
FLMBOOL * pbStartOverRV);
|
|
|
|
RCODE verifyLFHBlocks(
|
|
FLMBOOL * pbStartOverRV);
|
|
|
|
RCODE verifyAvailList(
|
|
FLMBOOL * pbStartOverRV);
|
|
|
|
RCODE blkRead(
|
|
FLMUINT uiBlkAddress,
|
|
F_BLK_HDR ** ppBlkHdr,
|
|
F_CachedBlock ** ppSCache,
|
|
FLMINT * piBlkErrCodeRV);
|
|
|
|
RCODE verifySubTree(
|
|
STATE_INFO * pParentState,
|
|
STATE_INFO * pStateInfo,
|
|
FLMUINT uiBlkAddress,
|
|
FLMBYTE ** ppucResetKey,
|
|
FLMUINT uiResetKeyLen,
|
|
FLMUINT64 ui64ResetNodeId);
|
|
|
|
RCODE buildIndexKeyList(
|
|
FLMUINT64 * pui64TotalKeys);
|
|
|
|
RCODE verifyBTrees(
|
|
FLMBOOL * pbStartOverRV);
|
|
|
|
RCODE setupLfTable();
|
|
|
|
RCODE setupIxInfo( void);
|
|
|
|
RCODE getLfInfo(
|
|
LF_HDR * pLogicalFile,
|
|
LFILE * pLFile);
|
|
|
|
RCODE verifyNodePointers(
|
|
STATE_INFO * pStateInfo,
|
|
FLMINT * piErrCode);
|
|
|
|
RCODE verifyDOChain(
|
|
STATE_INFO * pParentState,
|
|
FLMUINT uiBlkAddr,
|
|
FLMINT * piElmErrCode);
|
|
|
|
RCODE chkGetNextRSKey( void);
|
|
|
|
RCODE verifyIXRSet(
|
|
STATE_INFO * pStateInfo);
|
|
|
|
RCODE resolveIXMissingKey(
|
|
STATE_INFO * pStateInfo);
|
|
|
|
RCODE verifyComponentInDoc(
|
|
ICD * pIcd,
|
|
FLMUINT uiComponent,
|
|
F_DataVector * pKey,
|
|
FLMBOOL * pbInDoc);
|
|
|
|
RCODE getKeySource(
|
|
FLMBYTE * pucKey,
|
|
FLMUINT uiKeyLen,
|
|
FLMBOOL * pbKeyInDoc,
|
|
FLMBOOL * pbKeyInIndex);
|
|
|
|
RCODE resolveRSetMissingKey(
|
|
STATE_INFO * pStateInfo);
|
|
|
|
RCODE chkVerifyKeyExists(
|
|
FLMBYTE * pucKey,
|
|
FLMUINT uiKeyLen,
|
|
FLMBOOL * pbFoundRV);
|
|
|
|
RCODE addDelKeyRef(
|
|
FLMBYTE * pucKey,
|
|
FLMUINT uiKeyLen,
|
|
FLMBOOL bDelete);
|
|
|
|
RCODE reportIxError(
|
|
STATE_INFO * pStateInfo,
|
|
FLMINT iErrCode,
|
|
FLMBYTE * pucErrKey,
|
|
FLMUINT uiErrKeyLen,
|
|
FLMBOOL * pbFixErrRV);
|
|
|
|
RCODE startUpdate( void);
|
|
|
|
RCODE keyToVector(
|
|
FLMBYTE * pucKey,
|
|
FLMUINT uiKeyLen,
|
|
IF_DataVector ** ppKeyRV);
|
|
|
|
RCODE verifyIXRefs(
|
|
STATE_INFO * pStateInfo,
|
|
FLMUINT64 ui64ResetNodeId);
|
|
|
|
RCODE verifyBlockStructure(
|
|
FLMUINT uiBlockSize,
|
|
F_BTREE_BLK_HDR * pBlkHdr);
|
|
|
|
RCODE chkEndUpdate( void);
|
|
|
|
F_Db * m_pDb;
|
|
F_COLLECTION * m_pCollection;
|
|
IXD * m_pIxd;
|
|
LFILE * m_pLFile;
|
|
F_DbInfo * m_pDbInfo;
|
|
FLMBOOL m_bSkipDOMLinkCheck;
|
|
F_BtResultSet * m_pXRefRS;
|
|
F_BtPool * m_pBtPool;
|
|
IF_RandomGenerator * m_pRandGen;
|
|
char m_szResultSetDibName [F_PATH_MAX_SIZE];
|
|
F_Db * m_pResultSetDb;
|
|
IF_DbCheckStatus * m_pDbCheckStatus;
|
|
FLMBOOL m_bPhysicalCorrupt;
|
|
FLMBOOL m_bIndexCorrupt;
|
|
XFLM_PROGRESS_CHECK_INFO m_Progress;
|
|
RCODE m_LastStatusRc;
|
|
FLMUINT m_uiFlags;
|
|
FLMBOOL m_bStartedUpdateTrans;
|
|
FLMUINT * m_puiIxArray;
|
|
F_BtResultSet * m_pIxRSet;
|
|
FLMBOOL m_bGetNextRSKey;
|
|
RS_IX_KEY m_IxKey1;
|
|
RS_IX_KEY m_IxKey2;
|
|
RS_IX_KEY * m_pCurrRSKey;
|
|
RS_IX_KEY * m_pPrevRSKey;
|
|
BlkStruct * m_pBlkEntries;
|
|
FLMUINT m_uiBlkEntryArraySize;
|
|
friend class F_DbInfo;
|
|
friend class F_KeyCollector;
|
|
};
|
|
|
|
// Check Error Codes
|
|
|
|
/*
|
|
** WARNING: ANY CHANGES MADE TO THE CHECK ERROR CODE DEFINES MUST BE
|
|
** REFLECTED IN THE FlmCorruptStrings TABLE FOUND IN FLERRSTR.CPP
|
|
*/
|
|
#define FLM_BAD_CHAR 1
|
|
#define FLM_BAD_ASIAN_CHAR 2
|
|
#define FLM_BAD_CHAR_SET 3
|
|
#define FLM_BAD_TEXT_FIELD 4
|
|
#define FLM_BAD_NUMBER_FIELD 5
|
|
#define FLM_BAD_FIELD_TYPE 6
|
|
#define FLM_BAD_IX_DEF 7
|
|
#define FLM_MISSING_REQ_KEY_FIELD 8
|
|
#define FLM_BAD_TEXT_KEY_COLL_CHAR 9
|
|
#define FLM_BAD_TEXT_KEY_CASE_MARKER 10
|
|
#define FLM_BAD_NUMBER_KEY 11
|
|
#define FLM_BAD_BINARY_KEY 12
|
|
#define FLM_BAD_CONTEXT_KEY 13
|
|
#define FLM_BAD_KEY_FIELD_TYPE 14
|
|
//#define Not_Used_15 15
|
|
//#define Not_Used_16 16
|
|
//#define Not_Used_17 17
|
|
#define FLM_BAD_KEY_LEN 18
|
|
#define FLM_BAD_LFH_LIST_PTR 19
|
|
#define FLM_BAD_LFH_LIST_END 20
|
|
#define FLM_INCOMPLETE_NODE 21 // Not really an error. Part of a field has been split across entries
|
|
#define FLM_BAD_BLK_END 22
|
|
#define FLM_KEY_COUNT_MISMATCH 23
|
|
#define FLM_REF_COUNT_MISMATCH 24
|
|
#define FLM_BAD_CONTAINER_IN_KEY 25
|
|
#define FLM_BAD_BLK_HDR_ADDR 26
|
|
#define FLM_BAD_BLK_HDR_LEVEL 27
|
|
#define FLM_BAD_BLK_HDR_PREV 28
|
|
/*
|
|
** WARNING: ANY CHANGES MADE TO THE CHECK ERROR CODE DEFINES MUST BE
|
|
** REFLECTED IN THE FlmCorruptStrings TABLE FOUND IN FLERRSTR.CPP
|
|
*/
|
|
#define FLM_BAD_BLK_HDR_NEXT 29
|
|
#define FLM_BAD_BLK_HDR_TYPE 30
|
|
#define FLM_BAD_BLK_HDR_ROOT_BIT 31
|
|
#define FLM_BAD_BLK_HDR_BLK_END 32
|
|
#define FLM_BAD_BLK_HDR_LF_NUM 33
|
|
#define FLM_BAD_AVAIL_LIST_END 34
|
|
#define FLM_BAD_PREV_BLK_NEXT 35
|
|
#define FLM_BAD_FIRST_ELM_FLAG 36 // NOTE: This is only needed during rebuild
|
|
#define FLM_BAD_LAST_ELM_FLAG 37 // NOTE: This is only needed during rebuild
|
|
#define FLM_BAD_LEM 38
|
|
#define FLM_BAD_ELM_LEN 39
|
|
#define FLM_BAD_ELM_KEY_SIZE 40
|
|
#define FLM_BAD_ELM_KEY 41
|
|
#define FLM_BAD_ELM_KEY_ORDER 42
|
|
#define FLM_BAD_ELM_KEY_COMPRESS 43 // NOTE: 5.x keys are not compressed
|
|
#define FLM_BAD_CONT_ELM_KEY 44
|
|
#define FLM_NON_UNIQUE_FIRST_ELM_KEY 45
|
|
#define FLM_BAD_ELM_OFFSET 46
|
|
#define FLM_BAD_ELM_INVALID_LEVEL 47
|
|
#define FLM_BAD_ELM_FLD_NUM 48
|
|
#define FLM_BAD_ELM_FLD_LEN 49
|
|
#define FLM_BAD_ELM_FLD_TYPE 50
|
|
#define FLM_BAD_ELM_END 51
|
|
#define FLM_BAD_PARENT_KEY 52
|
|
#define FLM_BAD_ELM_DOMAIN_SEN 53
|
|
#define FLM_BAD_ELM_BASE_SEN 54
|
|
#define FLM_BAD_ELM_IX_REF 55
|
|
#define FLM_BAD_ELM_ONE_RUN_SEN 56
|
|
#define FLM_BAD_ELM_DELTA_SEN 57
|
|
#define FLM_BAD_ELM_DOMAIN 58
|
|
/*
|
|
** WARNING: ANY CHANGES MADE TO THE CHECK ERROR CODE DEFINES MUST BE
|
|
** REFLECTED IN THE FlmCorruptStrings TABLE FOUND IN FLERRSTR.CPP
|
|
*/
|
|
#define FLM_BAD_LAST_BLK_NEXT 59
|
|
#define FLM_BAD_FIELD_PTR 60
|
|
#define FLM_REBUILD_REC_EXISTS 61
|
|
#define FLM_REBUILD_KEY_NOT_UNIQUE 62
|
|
#define FLM_NON_UNIQUE_ELM_KEY_REF 63
|
|
#define FLM_OLD_VIEW 64
|
|
#define FLM_COULD_NOT_SYNC_BLK 65
|
|
#define FLM_IX_REF_REC_NOT_FOUND 66
|
|
#define FLM_IX_KEY_NOT_FOUND_IN_REC 67
|
|
#define FLM_KEY_NOT_IN_KEY_REFSET 68
|
|
#define FLM_BAD_BLK_CHECKSUM 69
|
|
#define FLM_BAD_LAST_DRN 70
|
|
#define FLM_BAD_FILE_SIZE 71
|
|
#define FLM_BAD_FIRST_LAST_ELM_FLAG 72
|
|
#define FLM_BAD_DATE_FIELD 73
|
|
#define FLM_BAD_TIME_FIELD 74
|
|
#define FLM_BAD_TMSTAMP_FIELD 75
|
|
#define FLM_BAD_DATE_KEY 76
|
|
#define FLM_BAD_TIME_KEY 77
|
|
#define FLM_BAD_TMSTAMP_KEY 78
|
|
#define FLM_BAD_BLOB_FIELD 79
|
|
|
|
/*
|
|
** WARNING: ANY CHANGES MADE TO THE CHECK ERROR CODE DEFINES MUST BE
|
|
** REFLECTED IN THE FlmCorruptStrings TABLE FOUND IN FLERRSTR.CPP
|
|
*/
|
|
|
|
#define FLM_BAD_PCODE_IXD_TBL 80
|
|
#define FLM_NODE_QUARANTINED 81
|
|
#define FLM_BAD_BLK_TYPE 82
|
|
#define FLM_BAD_ELEMENT_CHAIN 83
|
|
#define FLM_BAD_ELM_EXTRA_DATA 84
|
|
#define FLM_BAD_BLOCK_STRUCTURE 85
|
|
#define FLM_BAD_ROOT_PARENT 86
|
|
#define FLM_BAD_ROOT_LINK 87
|
|
#define FLM_BAD_PARENT_LINK 88
|
|
#define FLM_BAD_INVALID_ROOT 89
|
|
#define FLM_BAD_FIRST_CHILD_LINK 90
|
|
#define FLM_BAD_LAST_CHILD_LINK 91
|
|
#define FLM_BAD_PREV_SIBLING_LINK 92
|
|
#define FLM_BAD_NEXT_SIBLING_LINK 93
|
|
#define FLM_BAD_ANNOTATION_LINK 94
|
|
#define FLM_UNSUPPORTED_NODE_TYPE 95
|
|
#define FLM_BAD_INVALID_NAME_ID 96
|
|
#define FLM_BAD_INVALID_PREFIX_ID 97
|
|
#define FLM_BAD_DATA_BLOCK_COUNT 98
|
|
#define FLM_BAD_AVAIL_SIZE 99
|
|
#define FLM_BAD_NODE_TYPE 100
|
|
#define FLM_BAD_CHILD_ELM_COUNT 101
|
|
#define FLM_NUM_CORRUPT_ERRORS 101
|
|
|
|
/*
|
|
** WARNING: ANY CHANGES MADE TO THE CHECK ERROR CODE DEFINES MUST BE
|
|
** REFLECTED IN THE FlmCorruptStrings TABLE FOUND IN FLERRSTR.CPP
|
|
*/
|
|
|
|
class F_DbInfo : public IF_DbInfo
|
|
{
|
|
public:
|
|
|
|
F_DbInfo()
|
|
{
|
|
m_uiLogicalCorruptions = 0;
|
|
m_uiLogicalRepairs = 0;
|
|
m_ui64FileSize = 0;
|
|
m_uiNumIndexes = 0;
|
|
m_uiNumCollections = 0;
|
|
m_uiNumLogicalFiles = 0;
|
|
m_pLogicalFiles = NULL;
|
|
f_memset( &m_dbHdr, 0, sizeof( m_dbHdr));
|
|
f_memset( &m_AvailBlocks, 0, sizeof( m_AvailBlocks));
|
|
f_memset( &m_LFHBlocks, 0, sizeof( m_LFHBlocks));
|
|
}
|
|
|
|
virtual ~F_DbInfo()
|
|
{
|
|
freeLogicalFiles();
|
|
}
|
|
|
|
FINLINE void freeLogicalFiles( void)
|
|
{
|
|
FLMUINT uiLoop;
|
|
|
|
if (m_pLogicalFiles)
|
|
{
|
|
for (uiLoop = 0; uiLoop < m_uiNumLogicalFiles; uiLoop++)
|
|
{
|
|
if (m_pLogicalFiles [uiLoop].pLevelInfo)
|
|
{
|
|
f_free( &m_pLogicalFiles [uiLoop].pLevelInfo);
|
|
}
|
|
}
|
|
f_free( &m_pLogicalFiles);
|
|
}
|
|
m_uiNumLogicalFiles = 0;
|
|
m_uiNumIndexes = 0;
|
|
m_uiNumCollections = 0;
|
|
}
|
|
|
|
FINLINE FLMUINT FLMAPI getNumCollections( void)
|
|
{
|
|
return( m_uiNumCollections);
|
|
}
|
|
|
|
FINLINE FLMUINT FLMAPI getNumIndexes( void)
|
|
{
|
|
return( m_uiNumIndexes);
|
|
}
|
|
|
|
FINLINE FLMUINT FLMAPI getNumLogicalFiles( void)
|
|
{
|
|
return( m_uiNumLogicalFiles);
|
|
}
|
|
|
|
FINLINE FLMUINT64 FLMAPI getFileSize( void)
|
|
{
|
|
return( m_ui64FileSize);
|
|
}
|
|
|
|
FINLINE XFLM_DB_HDR * FLMAPI getDbHdr( void)
|
|
{
|
|
return( &m_dbHdr);
|
|
}
|
|
|
|
FINLINE void FLMAPI getAvailBlockStats(
|
|
FLMUINT64 * pui64BytesUsed,
|
|
FLMUINT * puiBlockCount,
|
|
FLMINT * piLastError,
|
|
FLMUINT * puiNumErrors)
|
|
{
|
|
*pui64BytesUsed = m_LFHBlocks.ui64BytesUsed;
|
|
*puiBlockCount = m_AvailBlocks.uiBlockCount;
|
|
*piLastError = m_AvailBlocks.iErrCode;
|
|
*puiNumErrors = m_AvailBlocks.uiNumErrors;
|
|
}
|
|
|
|
FINLINE void FLMAPI getLFHBlockStats(
|
|
FLMUINT64 * pui64BytesUsed,
|
|
FLMUINT * puiBlockCount,
|
|
FLMINT * piLastError,
|
|
FLMUINT * puiNumErrors)
|
|
{
|
|
*pui64BytesUsed = m_LFHBlocks.ui64BytesUsed;
|
|
*puiBlockCount = m_LFHBlocks.uiBlockCount;
|
|
*piLastError = m_LFHBlocks.iErrCode;
|
|
*puiNumErrors = m_LFHBlocks.uiNumErrors;
|
|
}
|
|
|
|
void FLMAPI getBTreeInfo(
|
|
FLMUINT uiNthLogicalFile,
|
|
FLMUINT * puiLfNum,
|
|
eLFileType * peLfType,
|
|
FLMUINT * puiRootBlkAddress,
|
|
FLMUINT * puiNumLevels);
|
|
|
|
void FLMAPI getBTreeBlockStats(
|
|
FLMUINT uiNthLogicalFile,
|
|
FLMUINT uiLevel,
|
|
FLMUINT64 * pui64KeyCount,
|
|
FLMUINT64 * pui64BytesUsed,
|
|
FLMUINT64 * pui64ElementCount,
|
|
FLMUINT64 * pui64ContElementCount,
|
|
FLMUINT64 * pui64ContElmBytes,
|
|
FLMUINT * puiBlockCount,
|
|
FLMINT * piLastError,
|
|
FLMUINT * puiNumErrors);
|
|
|
|
private:
|
|
|
|
FLMUINT m_uiLogicalCorruptions;
|
|
FLMUINT m_uiLogicalRepairs;
|
|
FLMUINT64 m_ui64FileSize;
|
|
FLMUINT m_uiNumIndexes;
|
|
FLMUINT m_uiNumCollections;
|
|
FLMUINT m_uiNumLogicalFiles;
|
|
LF_HDR * m_pLogicalFiles;
|
|
XFLM_DB_HDR m_dbHdr;
|
|
BLOCK_INFO m_AvailBlocks;
|
|
BLOCK_INFO m_LFHBlocks;
|
|
friend class F_DbCheck;
|
|
};
|
|
|
|
typedef struct
|
|
{
|
|
FLMUINT uiIndexNum;
|
|
FLMUINT uiCollection;
|
|
FLMUINT64 ui64DocId;
|
|
} DOC_IXD_XREF;
|
|
|
|
// Verifier Flags
|
|
|
|
#define CHK_NEXT_SIBLING_VERIFIED 0x0001
|
|
#define CHK_PREV_SIBLING_VERIFIED 0x0002
|
|
#define CHK_FIRST_CHILD_VERIFIED 0x0004
|
|
#define CHK_LAST_CHILD_VERIFIED 0x0008
|
|
#define CHK_PARENT_VERIFIED 0x0010
|
|
#define CHK_ANNOTATION_VERIFIED 0x0020
|
|
#define CHK_ROOT_VERIFIED 0x0040
|
|
|
|
// Bitmap field order
|
|
|
|
#define CHK_BM_ROOT_ID 0x0001
|
|
#define CHK_BM_PARENT_ID 0x0002
|
|
#define CHK_BM_PREV_SIBLING 0x0004
|
|
#define CHK_BM_NEXT_SIBLING 0x0008
|
|
#define CHK_BM_FIRST_CHILD 0x0010
|
|
#define CHK_BM_LAST_CHILD 0x0020
|
|
#define CHK_BM_ANNOTATION 0x0040
|
|
#define CHK_MAX_BM_ENTRIES 8
|
|
|
|
typedef struct
|
|
{
|
|
FLMUINT16 ui16Flags; // Verify Flags to record visits/verifies
|
|
FLMUINT16 ui16BitMap; // Holds a map of present fields
|
|
FLMUINT64 ui64NodeId;
|
|
} NODE_RS_HDR;
|
|
|
|
typedef struct
|
|
{
|
|
NODE_RS_HDR hdr;
|
|
FLMUINT64 ui64FieldArray[ CHK_MAX_BM_ENTRIES];
|
|
} NODE_RS_ENTRY;
|
|
|
|
#define REBUILD_BLK_SIZE (1024 * 50)
|
|
#define REBUILD_RSET_ENTRY_SIZE 21
|
|
|
|
/*=============================================================================
|
|
Desc: Class to rebuild a broken database.
|
|
=============================================================================*/
|
|
class F_DbRebuild : public F_Object
|
|
{
|
|
public:
|
|
|
|
// Constructor and Destructor
|
|
|
|
F_DbRebuild( void)
|
|
{
|
|
m_pDb = NULL;
|
|
m_pSFileHdl = NULL;
|
|
}
|
|
|
|
~F_DbRebuild()
|
|
{
|
|
}
|
|
|
|
RCODE dbRebuild(
|
|
const char * pszSourceDbPath,
|
|
const char * pszSourceDataDir,
|
|
const char * pszDestDbPath,
|
|
const char * pszDestDataDir,
|
|
const char * pszDestRflDir,
|
|
const char * pDictPath,
|
|
const char * pszPassword,
|
|
XFLM_CREATE_OPTS * pCreateOpts,
|
|
FLMUINT64 * pui64TotNodes,
|
|
FLMUINT64 * pui64NodesRecov,
|
|
FLMUINT64 * pui64QuarantinedNodes,
|
|
IF_DbRebuildStatus * pRebuildStatus);
|
|
|
|
FINLINE FLMUINT getBlockSize( void)
|
|
{
|
|
return( m_dbHdr.ui16BlockSize);
|
|
}
|
|
|
|
FINLINE RCODE reportStatus(
|
|
FLMBOOL bForce = FALSE)
|
|
{
|
|
RCODE rc = NE_XFLM_OK;
|
|
|
|
if( m_pRebuildStatus)
|
|
{
|
|
FLMUINT uiCurrentTime = FLM_GET_TIMER();
|
|
FLMUINT uiElapTime = FLM_ELAPSED_TIME( uiCurrentTime, m_uiLastStatusTime);
|
|
|
|
uiElapTime = FLM_TIMER_UNITS_TO_SECS( uiElapTime);
|
|
|
|
if( bForce || uiElapTime >= 1)
|
|
{
|
|
m_uiLastStatusTime = uiCurrentTime;
|
|
m_callbackData.bStartFlag = FALSE;
|
|
if( RC_BAD( rc = m_pRebuildStatus->reportRebuild( &m_callbackData)))
|
|
{
|
|
m_cbrc = rc;
|
|
goto Exit;
|
|
}
|
|
}
|
|
}
|
|
|
|
Exit:
|
|
|
|
return( rc);
|
|
}
|
|
|
|
private:
|
|
|
|
RCODE rebuildDatabase( void);
|
|
|
|
RCODE recoverNodes(
|
|
FLMBOOL bRecoverDictionary);
|
|
|
|
FINLINE FLMBYTE getRSetPrefix(
|
|
FLMUINT uiNameId)
|
|
{
|
|
if( uiNameId == ELM_PREFIX_TAG)
|
|
{
|
|
return( 1);
|
|
}
|
|
|
|
if( uiNameId == ELM_ATTRIBUTE_TAG)
|
|
{
|
|
return( 2);
|
|
}
|
|
|
|
if( uiNameId == ELM_ELEMENT_TAG)
|
|
{
|
|
return( 3);
|
|
}
|
|
|
|
if( uiNameId == ELM_COLLECTION_TAG)
|
|
{
|
|
return( 4);
|
|
}
|
|
|
|
return( 5);
|
|
}
|
|
|
|
FINLINE void buildRSetEntry(
|
|
FLMBYTE ucPrefix,
|
|
FLMUINT uiCollection,
|
|
FLMUINT64 ui64NodeId,
|
|
FLMUINT uiBlockAddr,
|
|
FLMUINT uiElmNumber,
|
|
FLMBYTE * pucBuffer)
|
|
{
|
|
pucBuffer[ 0] = ucPrefix;
|
|
|
|
f_UINT32ToBigEndian( (FLMUINT32)uiCollection, &pucBuffer[ 1]);
|
|
f_UINT64ToBigEndian( ui64NodeId, &pucBuffer[ 5]);
|
|
f_UINT32ToBigEndian( (FLMUINT32)uiBlockAddr, &pucBuffer[ 13]);
|
|
f_UINT32ToBigEndian( (FLMUINT32)uiElmNumber, &pucBuffer[ 17]);
|
|
}
|
|
|
|
FINLINE void extractRSetEntry(
|
|
FLMBYTE * pucBuffer,
|
|
FLMUINT * puiCollection,
|
|
FLMUINT64 * pui64NodeId,
|
|
FLMUINT * puiBlockAddr,
|
|
FLMUINT * puiElmNumber)
|
|
{
|
|
if( puiCollection)
|
|
{
|
|
*puiCollection = f_bigEndianToUINT32( &pucBuffer[ 1]);
|
|
}
|
|
|
|
if( pui64NodeId)
|
|
{
|
|
*pui64NodeId = f_bigEndianToUINT64( &pucBuffer[ 5]);
|
|
}
|
|
|
|
if( puiBlockAddr)
|
|
{
|
|
*puiBlockAddr = f_bigEndianToUINT32( &pucBuffer[ 13]);
|
|
}
|
|
|
|
if( puiElmNumber)
|
|
{
|
|
*puiElmNumber = f_bigEndianToUINT32( &pucBuffer[ 17]);
|
|
}
|
|
}
|
|
|
|
RCODE recoverTree(
|
|
F_RebuildNodeIStream * pIStream,
|
|
IF_ResultSet * pNonRootRSet,
|
|
F_DOMNode * pParentNode,
|
|
F_CachedNode * pRecovCachedNode,
|
|
FLMBYTE * pucNodeIV);
|
|
|
|
FINLINE RCODE reportCorruption(
|
|
FLMINT iErrCode,
|
|
FLMUINT uiErrBlkAddress,
|
|
FLMUINT uiErrElmOffset,
|
|
FLMUINT64 ui64ErrNodeId)
|
|
{
|
|
RCODE rc;
|
|
|
|
if( m_pRebuildStatus)
|
|
{
|
|
m_corruptInfo.iErrCode = iErrCode;
|
|
m_corruptInfo.uiErrBlkAddress = uiErrBlkAddress;
|
|
m_corruptInfo.uiErrElmOffset = uiErrElmOffset;
|
|
m_corruptInfo.ui64ErrNodeId = ui64ErrNodeId;
|
|
rc = m_pRebuildStatus->reportRebuildErr( &m_corruptInfo);
|
|
m_corruptInfo.iErrCode = 0;
|
|
return( rc);
|
|
}
|
|
|
|
return( NE_XFLM_OK);
|
|
}
|
|
|
|
RCODE determineBlkSize(
|
|
FLMUINT * puiBlkSizeRV);
|
|
|
|
F_Db * m_pDb;
|
|
F_SuperFileHdl * m_pSFileHdl;
|
|
IF_DbRebuildStatus * m_pRebuildStatus;
|
|
FLMBOOL m_bBadHeader;
|
|
FLMUINT m_uiLastStatusTime;
|
|
XFLM_DB_HDR m_dbHdr;
|
|
XFLM_CREATE_OPTS m_createOpts;
|
|
XFLM_REBUILD_INFO m_callbackData;
|
|
XFLM_CORRUPT_INFO m_corruptInfo;
|
|
RCODE m_cbrc;
|
|
|
|
friend class F_RebuildNodeIStream;
|
|
};
|
|
|
|
RCODE chkBlkRead(
|
|
F_DbInfo * pDbInfo,
|
|
FLMUINT uiBlkAddress,
|
|
F_BLK_HDR ** ppBlkHdr,
|
|
F_CachedBlock ** ppSCache,
|
|
FLMINT * piBlkErrCodeRV);
|
|
|
|
FLMINT flmCompareKeys(
|
|
FLMBYTE * pBuf1,
|
|
FLMUINT uiBuf1Len,
|
|
FLMBYTE * pBuf2,
|
|
FLMUINT uiBuf2Len);
|
|
|
|
void flmInitReadState(
|
|
STATE_INFO * pStateInfo,
|
|
FLMBOOL * pbStateInitialized,
|
|
FLMUINT uiVersionNum,
|
|
F_Db * pDb,
|
|
LF_HDR * pLogicalFile,
|
|
FLMUINT uiLevel,
|
|
FLMUINT uiBlkType,
|
|
FLMBYTE * pucKeyBuffer);
|
|
|
|
FLMINT flmVerifyBlockHeader(
|
|
STATE_INFO * pStateInfo,
|
|
BLOCK_INFO * pBlockInfoRV,
|
|
FLMUINT uiBlockSize,
|
|
FLMUINT uiExpNextBlkAddr,
|
|
FLMUINT uiExpPrevBlkAddr,
|
|
FLMBOOL bCheckEOF);
|
|
|
|
RCODE flmVerifyElement(
|
|
STATE_INFO * pStateInfo,
|
|
LFILE * pLFile,
|
|
IXD * pIxd,
|
|
FLMINT * piErrCode);
|
|
|
|
void getEntryInfo(
|
|
F_BTREE_BLK_HDR * pBlkHdr,
|
|
FLMUINT uiOffset,
|
|
FLMBYTE ** ppucElm,
|
|
FLMUINT * puiElmLen,
|
|
FLMUINT * puiElmKeyLen,
|
|
FLMUINT * puiElmDataLen,
|
|
FLMBYTE ** ppucElmKey,
|
|
FLMBYTE ** ppucElmData);
|
|
|
|
FINLINE RCODE F_NodeCacheMgr::allocDOMNode(
|
|
F_DOMNode ** ppDOMNode)
|
|
{
|
|
flmAssert( *ppDOMNode == NULL);
|
|
|
|
if( m_pFirstNode)
|
|
{
|
|
f_resetStackInfo( m_pFirstNode);
|
|
*ppDOMNode = m_pFirstNode;
|
|
m_pFirstNode = m_pFirstNode->m_pNextInPool;
|
|
(*ppDOMNode)->m_pNextInPool = NULL;
|
|
}
|
|
else
|
|
{
|
|
if( (*ppDOMNode = f_new F_DOMNode) == NULL)
|
|
{
|
|
return( RC_SET( NE_XFLM_MEM));
|
|
}
|
|
}
|
|
|
|
return( NE_XFLM_OK);
|
|
}
|
|
|
|
FINLINE RCODE F_NodeCacheMgr::makeWriteCopy(
|
|
F_Db * pDb,
|
|
F_CachedNode ** ppCachedNode)
|
|
{
|
|
F_CachedNode * pCachedNode = *ppCachedNode;
|
|
|
|
if( pCachedNode->getLowTransId() < pDb->m_ui64CurrTransID)
|
|
{
|
|
return( gv_XFlmSysData.pNodeCacheMgr->_makeWriteCopy(
|
|
pDb, ppCachedNode));
|
|
}
|
|
else if( pCachedNode->getStreamUseCount())
|
|
{
|
|
// The only thread that would be using this version of
|
|
// the node is the updater thread. It would be illegal
|
|
// for the updater thread to have an input stream going
|
|
// while trying to update this.
|
|
|
|
return( RC_SET_AND_ASSERT( NE_XFLM_ILLEGAL_OP));
|
|
}
|
|
|
|
return( NE_XFLM_OK);
|
|
}
|
|
|
|
/****************************************************************************
|
|
Desc:
|
|
*****************************************************************************/
|
|
class FLMEXP F_SuperFileClient : public IF_SuperFileClient
|
|
{
|
|
public:
|
|
|
|
F_SuperFileClient();
|
|
|
|
virtual ~F_SuperFileClient();
|
|
|
|
RCODE setup(
|
|
const char * pszCFileName,
|
|
const char * pszDataDir);
|
|
|
|
FLMUINT FLMAPI getFileNumber(
|
|
FLMUINT uiBlockAddr);
|
|
|
|
FLMUINT FLMAPI getFileOffset(
|
|
FLMUINT uiBlockAddr);
|
|
|
|
FLMUINT FLMAPI getBlockAddress(
|
|
FLMUINT uiFileNumber,
|
|
FLMUINT uiFileOffset);
|
|
|
|
RCODE FLMAPI getFilePath(
|
|
FLMUINT uiFileNumber,
|
|
char * pszPath);
|
|
|
|
static void bldSuperFileExtension(
|
|
FLMUINT uiFileNum,
|
|
char * pszFileExtension);
|
|
|
|
private:
|
|
|
|
char * m_pszCFileName;
|
|
char * m_pszDataFileBaseName;
|
|
FLMUINT m_uiExtOffset;
|
|
FLMUINT m_uiDataExtOffset;
|
|
};
|
|
|
|
#endif // FLAIMSYS_H
|