Пример #1
0
/****************************************************************************
Desc:
****************************************************************************/
RCODE TestBase::openTestState(
	const char *		pszDibName)
{
	RCODE					rc = FERR_OK;
	CREATE_OPTS			createOpts;

	if( RC_BAD( rc = gv_FlmSysData.pFileSystem->doesFileExist( pszDibName)))
	{
		// Create the database

		f_memset( &createOpts, 0, sizeof( CREATE_OPTS));
		
		if( RC_BAD( rc = FlmDbCreate( pszDibName, 
			NULL, NULL, NULL, NULL, &createOpts, &m_hDb)))
		{
			goto Exit;
		}
	}
	else
	{
		// Open the existing database

		if( RC_BAD( rc = FlmDbOpen( pszDibName, NULL, NULL, 
			0, NULL, &m_hDb)))
		{
			goto Exit;
		}
	}

Exit:

	return( rc);
}
Пример #2
0
/****************************************************************************
Desc:
****************************************************************************/
void FlagSet::init( 
	FLMBYTE **		ppucElemArray,
	FLMUINT			uiNumElems)
{
	reset();
	
	if( RC_BAD( f_alloc( sizeof( FLMBYTE *) * uiNumElems,
										&m_ppucElemArray)))
	{
		flmAssert( 0);
	}
	
	if( RC_BAD( f_alloc( sizeof( FLMBOOL) * uiNumElems,
										&m_pbFlagArray)))
	{
		flmAssert( 0);
	}
	
	f_memset( m_pbFlagArray, 0, sizeof( FLMBOOL) * uiNumElems);
	
	for( FLMUINT uiLoop = 0; uiLoop < uiNumElems; uiLoop++)
	{
		if( RC_BAD( f_alloc( f_strlen( (char *)ppucElemArray[ uiLoop]) + 1,
				&m_ppucElemArray[ uiLoop])))
		{
			flmAssert( 0);
		}
		
		f_strcpy( (char *)m_ppucElemArray[uiLoop], (char *)ppucElemArray[uiLoop]);
	}
	
	m_uiNumElems = uiNumElems;
}
Пример #3
0
/****************************************************************************
Desc:
****************************************************************************/
RCODE TestBase::initCleanTestState( 
	const char * 	pszDibName)
{
	RCODE				rc = FERR_OK;
	CREATE_OPTS		createOpts;

	// Create the database
	
	f_memset( &createOpts, 0, sizeof( CREATE_OPTS));
	
	if ( RC_BAD( rc = FlmDbCreate( pszDibName, 
		NULL, NULL, NULL, NULL, &createOpts, &m_hDb)))
	{
		if( rc == FERR_FILE_EXISTS)
		{
			if( RC_BAD( rc = FlmDbRemove( pszDibName,
				NULL, NULL, TRUE)))
			{
				goto Exit;
			}
		}

		if( RC_BAD( rc = FlmDbCreate( pszDibName, 
			NULL, NULL, NULL, NULL, &createOpts, &m_hDb)))
		{
			goto Exit;
		}
	}

Exit:

	return( rc);
}
Пример #4
0
/****************************************************************************
Desc:
****************************************************************************/
RCODE ArgList::expandArgs(
	char ** 		ppszArgs,
	FLMUINT 		uiNumArgs)
{
	RCODE			rc = FERR_OK;
	FLMUINT		uiLoop;

	for( uiLoop = 0; uiLoop < uiNumArgs; uiLoop++)
	{
		if( ppszArgs[uiLoop][0] == '@')
		{
			if( RC_BAD( rc = expandFileArgs( &ppszArgs[uiLoop][ 1])))
			{
				goto Exit;
			}
		}
		else
		{
			if( RC_BAD( rc = addArg( ppszArgs[ uiLoop])))
			{
				goto Exit;
			}
		}
	}
	
Exit:

	return( rc);
}
Пример #5
0
/****************************************************************************
Desc:
****************************************************************************/
FlagSet::FlagSet( 
	const FlagSet&		fs)
{
	if( RC_BAD( f_alloc( sizeof( FLMBYTE *) * fs.m_uiNumElems,
										&m_ppucElemArray)))
	{
		flmAssert( 0);
	}
	
	if( RC_BAD( f_alloc( sizeof( FLMBOOL) * fs.m_uiNumElems,
										&m_pbFlagArray)))
	{
		flmAssert( 0);
	}
	
	f_memset( m_pbFlagArray, 0, sizeof( FLMBOOL) * fs.m_uiNumElems);
	
	for( FLMUINT uiLoop = 0; uiLoop < fs.m_uiNumElems; uiLoop++)
	{
		if( RC_BAD( f_alloc( f_strlen( (char *)fs.m_ppucElemArray[uiLoop]) + 1,
				&m_ppucElemArray[ uiLoop])))
		{
			flmAssert( 0);
		}
		
		f_strcpy( (char *)m_ppucElemArray[uiLoop], 
					 (char *)fs.m_ppucElemArray[uiLoop]);
	}
	
	m_uiNumElems = fs.m_uiNumElems;
}
Пример #6
0
/****************************************************************************
Desc:
****************************************************************************/
RCODE ArgList::addArg( 
	const char *	pszArg)
{
	RCODE		rc = FERR_OK;

	if( m_uiNumEntries >= m_uiCapacity)
	{
		if( RC_BAD( rc = resize()))
		{
			goto Exit;
		}
	}

	if( RC_BAD( rc = f_alloc( f_strlen( pszArg) + 1,
		&m_ppszArgs[ m_uiNumEntries])))
	{
		goto Exit;
	}

	f_strcpy( m_ppszArgs[ m_uiNumEntries++], pszArg);

Exit:

	return( rc);
}
Пример #7
0
/****************************************************************************
Desc:
****************************************************************************/
RCODE IFlmTestLogger::appendString( 
	const char *		pszString)
{
	RCODE				rc = FERR_OK;
	char *			pszTemp = NULL;

	if ( RC_BAD( rc = f_alloc( f_strlen( pszString) + 3, &pszTemp)))
	{
		goto Exit;
	}

	f_sprintf( pszTemp, "%s\n", pszString);

	if( RC_BAD( rc = f_filecat( m_szFilename, pszString)))
	{
		goto Exit;
	}

Exit:

	if ( pszTemp)
	{
		f_free( &pszTemp);
	}

	return rc;
}
Пример #8
0
/****************************************************************************
Desc:
****************************************************************************/
RCODE ArgList::resize( void)
{
	RCODE			rc = FERR_OK;
	FLMUINT		uiLoop;
	char **		ppszTemp = NULL;

	if( RC_BAD( rc = f_alloc( m_uiCapacity * GROW_FACTOR * sizeof(char*), 
		&ppszTemp)))
	{
		goto Exit;
	}

	m_uiCapacity *= GROW_FACTOR;
	
	for( uiLoop = 0; uiLoop < m_uiNumEntries; uiLoop++)
	{
		if( RC_BAD( rc = f_alloc( f_strlen( m_ppszArgs[ uiLoop]) + 1, 
			&ppszTemp[ uiLoop])))
		{
			f_free( &ppszTemp);
			goto Exit;
		}
		
		f_strcpy( ppszTemp[uiLoop], m_ppszArgs[uiLoop]);
	}

	f_free( &m_ppszArgs);
	m_ppszArgs = ppszTemp;

Exit:

	return( rc);
}
Пример #9
0
/****************************************************************************
Desc:	Checks if the current database has any UNIQUE indexes that need 
		to checked. Also does duplicate processing for the record.
****************************************************************************/
RCODE F_Db::processDupKeys(
	F_INDEX *	pIndex)
{
	RCODE	rc = NE_SFLM_OK;
	
	//  Sort and remove duplicates

	if (m_uiKrefCount > 1)
	{
		if (RC_BAD( rc = krefQuickSort( this, pIndex, m_pKrefTbl,
									0, m_uiKrefCount - 1)))
		{
			goto Exit;
		}
		if (RC_BAD( rc = krefKillDups( this, pIndex,
										m_pKrefTbl, &m_uiKrefCount)))
		{
			goto Exit;
		}
	}
	
Exit:

	return( rc);
}
Пример #10
0
/***************************************************************************
Desc:	This routine verifies the LFH blocks.
*****************************************************************************/
RCODE F_DbCheck::verifyLFHBlocks(
	FLMBOOL *	pbStartOverRV)
{
	RCODE	rc = NE_XFLM_OK;

	m_Progress.ui32LfNumber = 0;
	m_Progress.ui32LfType = 0;
	m_Progress.i32CheckPhase = XFLM_CHECK_LFH_BLOCKS;
	m_Progress.bStartFlag = TRUE;
	if (RC_BAD( rc = chkCallProgFunc()))
	{
		goto Exit;
	}
	m_Progress.bStartFlag = FALSE;

	f_yieldCPU();

	// Go through the LFH blocks.

	if (RC_BAD( rc = verifyBlkChain( 
			&m_pDbInfo->m_LFHBlocks, XFLM_LOCALE_LFH_LIST,
			(FLMUINT)m_pDb->m_pDatabase->m_lastCommittedDbHdr.ui32FirstLFBlkAddr,
			BT_LFH_BLK, pbStartOverRV)) ||
		 *pbStartOverRV)
	{
		goto Exit;
	}

Exit:

	return( rc);
}
Пример #11
0
/****************************************************************************
Desc:	Compose a key buffer from the vector's components.
****************************************************************************/
RCODE XFLAPI F_DataVector::outputKey(
	IF_Db *			ifpDb,
	FLMUINT			uiIndexNum,
	FLMUINT,			// uiMatchFlags,	//VISIT: Need to remove this from the interface.
	FLMBYTE *		pucKeyBuf,
	FLMUINT			uiKeyBufSize,
	FLMUINT *		puiKeyLen)
{
	RCODE	rc = NE_XFLM_OK;
	IXD *	pIxd;

	if (RC_BAD( rc = ((F_Db *)ifpDb)->m_pDict->getIndex( uiIndexNum, NULL, &pIxd, TRUE)))
	{
		goto Exit;
	}

	if (RC_BAD( rc = outputKey( pIxd, XFLM_MATCH_IDS | XFLM_MATCH_DOC_ID, pucKeyBuf,
								uiKeyBufSize, puiKeyLen, 0)))
	{
		goto Exit;
	}

Exit:

	return( rc);
}
Пример #12
0
/****************************************************************************
Desc:	Set a FLMUINT64 value for a vector element.
****************************************************************************/
RCODE XFLAPI F_DataVector::setUINT64(
	FLMUINT		uiElementNumber,
	FLMUINT64	ui64Num)
{
	RCODE		rc = NE_XFLM_OK;
	FLMBYTE	ucStorageBuf [FLM_MAX_NUM_BUF_SIZE];
	FLMUINT	uiStorageLen;

	uiStorageLen = sizeof( ucStorageBuf);
	if (RC_BAD( rc = flmNumber64ToStorage( ui64Num,
							&uiStorageLen, ucStorageBuf, FALSE, FALSE)))
	{
		goto Exit;
	}

	if (RC_BAD( rc = storeValue( uiElementNumber,
		XFLM_NUMBER_TYPE, ucStorageBuf, uiStorageLen)))
	{
		goto Exit;
	}

Exit:

	return( rc);
}
Пример #13
0
/****************************************************************************
Desc:	Reinsert all entries given a new root block.
		Caller will release 'this'.  Used ONLY for building the first
		ROOT and two leaves of the tree.
****************************************************************************/
RCODE F_BtreeLeaf::split(
    F_BtreeRoot *	pNewRoot)		// New Non-leaf root
{
    RCODE				rc = NE_FLM_OK;
    FLMBYTE *		pucEntry;
    FLMUINT			uiPos;
    FLMUINT			uiEntryCount = entryCount();
    FLMUINT			uiMid = (uiEntryCount + 1) >> 1;

    if (RC_BAD( rc = pNewRoot->setupTree( ENTRY_POS(uiMid),
                                          ACCESS_BTREE_LEAF, NULL, NULL)))
    {
        goto Exit;
    }

    for (uiPos = 0; uiPos < uiEntryCount; uiPos++)
    {
        pucEntry = ENTRY_POS( uiPos);
        if ((rc = pNewRoot->search( pucEntry)) != NE_FLM_NOT_FOUND)
        {
            rc = RC_SET_AND_ASSERT( NE_FLM_FAILURE);
            goto Exit;
        }

        if (RC_BAD( rc = pNewRoot->insert( pucEntry)))
        {
            goto Exit;
        }
    }

Exit:

    return( rc);
}
Пример #14
0
/****************************************************************************
Desc:
****************************************************************************/
RCODE FLMAPI f_rwlockCreate(
	F_RWLOCK *			phReadWriteLock)
{
	RCODE					rc = NE_FLM_OK;
	F_RWLOCK_IMP *		pReadWriteLock = NULL;
	
	if( RC_BAD( rc = f_calloc( sizeof( F_RWLOCK_IMP), &pReadWriteLock)))
	{
		goto Exit;
	}
	
	pReadWriteLock->hMutex = F_MUTEX_NULL;
	
	if( RC_BAD( rc = f_mutexCreate( &pReadWriteLock->hMutex)))
	{
		goto Exit;
	}
	
	*phReadWriteLock = (F_RWLOCK)pReadWriteLock;
	pReadWriteLock = NULL;
	
Exit:

	if( pReadWriteLock)
	{
		f_rwlockDestroy( (F_RWLOCK *)&pReadWriteLock);
	}
	
	return( rc);
}
Пример #15
0
/****************************************************************************
Desc:
****************************************************************************/
RCODE F_FSRestore::openBackupSet( void)
{
	RCODE			rc = NE_SFLM_OK;

	flmAssert( m_bSetupCalled);
	flmAssert( !m_pMultiFileHdl);
	
	if( RC_BAD( rc = FlmAllocMultiFileHdl( &m_pMultiFileHdl)))
	{
		goto Exit;
	}

	if( RC_BAD( rc = m_pMultiFileHdl->openFile( m_szBackupSetPath)))
	{
		m_pMultiFileHdl->Release();
		m_pMultiFileHdl = NULL;
		goto Exit;
	}

	m_ui64Offset = 0;
	m_bOpen = TRUE;

Exit:

	return( rc);
}
Пример #16
0
/***************************************************************************
Desc:	This routine reads the header information in a FLAIM database,
		verifies the password, and returns the file header and log
		header information.
*****************************************************************************/
RCODE flmGetHdrInfo(
	F_SuperFileHdl *	pSFileHdl,
	XFLM_DB_HDR *		pDbHdr,
	FLMUINT32 *			pui32CalcCRC)
{
	RCODE				rc = NE_XFLM_OK;
	IF_FileHdl *	pCFileHdl = NULL;

	if( RC_BAD( rc = pSFileHdl->getFileHdl( 0, FALSE, &pCFileHdl)))
	{
		goto Exit;
	}

	if( RC_BAD( rc = flmReadAndVerifyHdrInfo( NULL, pCFileHdl, 
		pDbHdr, pui32CalcCRC)))
	{
		goto Exit;
	}

Exit:

	if( pCFileHdl)
	{
		pCFileHdl->Release();
	}

	return( rc);
}
Пример #17
0
/****************************************************************************
Desc: This routine allocates a new F_Database object and links it
		into its hash buckets.
		NOTE: This routine assumes that the global mutex has already
		been locked. It may unlock it temporarily if there is an error,
		but will always relock it before exiting.
****************************************************************************/
RCODE F_DbSystem::allocDatabase(
	const char *	pszDbPath,
	const char *	pszDataDir,
	FLMBOOL			bTempDb,
	F_Database **	ppDatabase)
{
	RCODE				rc = NE_XFLM_OK;
	F_Database *	pDatabase = NULL;

	if ((pDatabase = f_new F_Database( bTempDb)) == NULL)
	{
		rc = RC_SET( NE_XFLM_MEM);
		goto Exit;
	}

	if (RC_BAD( rc = pDatabase->setupDatabase( pszDbPath, pszDataDir)))
	{
		goto Exit;
	}

	*ppDatabase = pDatabase;

Exit:

	if (RC_BAD( rc))
	{
		if (pDatabase)
		{
			pDatabase->freeDatabase();
		}
	}
	return( rc);
}
Пример #18
0
/****************************************************************************
Desc:	See if any F_INDEX structures need indexing in the background.
****************************************************************************/
RCODE F_Db::startBackgroundIndexing( void)
{
	RCODE			rc = NE_SFLM_OK;
	FLMBOOL		bStartedTrans = FALSE;
	FLMUINT		uiIndexNum;
	F_INDEX *	pIndex;

	if (RC_BAD( rc = checkState( __FILE__, __LINE__)))
	{
		goto Exit;
	}

	if (m_eTransType != SFLM_NO_TRANS)
	{
		if (!okToCommitTrans())
		{
			rc = RC_SET( NE_SFLM_ABORT_TRANS);
			goto Exit;
		}
	}
	else
	{

		// Need to have at least a read transaction going.

		if (RC_BAD( rc = beginTrans( SFLM_READ_TRANS)))
		{
			goto Exit;
		}
		bStartedTrans = TRUE;
	}

	for (uiIndexNum = 1, pIndex = m_pDict->m_pIndexTbl;
		  uiIndexNum <= m_pDict->m_uiHighestIndexNum;
		  uiIndexNum++, pIndex++)
	{

		// Restart any indexes that are off-line but not suspended

		if ((pIndex->uiFlags & (IXD_OFFLINE | IXD_SUSPENDED)) == IXD_OFFLINE)
		{
			flmAssert( flmBackgroundIndexGet( m_pDatabase,
									uiIndexNum, FALSE) == NULL);

			if (RC_BAD( rc = startIndexBuild( uiIndexNum)))
			{
				goto Exit;
			}
		}
	}

Exit:

	if (bStartedTrans)
	{
		(void)abortTrans();
	}

	return( rc);
}
Пример #19
0
/****************************************************************************
Desc:
****************************************************************************/
RCODE F_IOBufferMgr::setupBufferMgr(
	FLMUINT			uiMaxBuffers,
	FLMUINT			uiMaxBytes,
	FLMBOOL			bReuseBuffers)
{
	RCODE				rc = NE_FLM_OK;
	
	f_assert( uiMaxBuffers);
	f_assert( uiMaxBytes);
	
	if( RC_BAD( rc = f_mutexCreate( &m_hMutex)))
	{
		goto Exit;
	}
	
#if !defined( FLM_UNIX) && !defined( FLM_NLM)
	if( RC_BAD( rc = f_semCreate( &m_hAvailSem)))
	{
		goto Exit;
	}
#endif
	
	m_uiMaxBuffers = uiMaxBuffers;
	m_uiMaxBufferBytes = uiMaxBytes;
	m_bReuseBuffers = bReuseBuffers;
	
Exit:

	return( rc);
}
Пример #20
0
/***************************************************************************
Desc:	This routine reads through the blocks in the AVAIL list and verifies
		that we don't have a loop or some other corruption in the list.
*****************************************************************************/
RCODE F_DbCheck::verifyAvailList(
	FLMBOOL *	pbStartOverRV)
{
	RCODE		rc = NE_XFLM_OK;

	m_Progress.ui32LfNumber = 0;
	m_Progress.ui32LfType = 0;
	m_Progress.i32CheckPhase = XFLM_CHECK_AVAIL_BLOCKS;
	m_Progress.bStartFlag = TRUE;
	if (RC_BAD( rc = chkCallProgFunc()))
	{
		goto Exit;
	}
	m_Progress.bStartFlag = FALSE;

	f_yieldCPU();
 
	if (RC_BAD( rc = verifyBlkChain( &m_pDbInfo->m_AvailBlocks,
								XFLM_LOCALE_AVAIL_LIST,
								m_pDb->m_uiFirstAvailBlkAddr,
								BT_FREE, pbStartOverRV)) ||
		 *pbStartOverRV)
	{
		goto Exit;
	}

Exit:

	return( rc);
}
Пример #21
0
/****************************************************************************
Desc:	Stores a new value for the specified name (or creates a new name/value
	   pair) in the list of INI_STRUCTs
****************************************************************************/
RCODE FTKAPI F_IniFile::setParam(
	const char *	pszParamName,
	const char *	pszParamVal)
{
	RCODE				rc = NE_FLM_OK;
	INI_LINE *		pLine;

	f_assert( m_bReady);

	// If the parameter exists in the list, just store the new value.
	// Othewise, create a new INI_LINE and add it to the list
	
	pLine = findParam( pszParamName);
	if( !pLine)
	{
		if( RC_BAD( rc = setParamCommon( &pLine, pszParamName)))
		{
			goto Exit;
		}
	}

	if( RC_BAD( rc = toAscii( &pLine->pszParamValue, pszParamVal)))
	{
		goto Exit;
	}
	
Exit:

	return( rc);
}
Пример #22
0
/****************************************************************************
Desc: Recover a database on startup.
****************************************************************************/
RCODE F_Database::doRecover(
	F_Db *					pDb,
	IF_RestoreClient *	pRestoreObj,
	IF_RestoreStatus *	pRestoreStatus)
{
	RCODE				rc = NE_XFLM_OK;
	XFLM_DB_HDR *	pLastCommittedDbHdr;

	// At this point, m_lastCommittedDbHdr contains the header
	// that was read from disk, which will be the state of the
	// header as of the last completed checkpoint.  Therefore,
	// we copy it into m_checkpointDbHdr.

	pLastCommittedDbHdr = &m_lastCommittedDbHdr;
	f_memcpy( &m_checkpointDbHdr, pLastCommittedDbHdr, sizeof( XFLM_DB_HDR));

	// Do a physical rollback on the database to restore the last
	// checkpoint.

	if (RC_BAD( rc = pDb->physRollback(
							(FLMUINT)pLastCommittedDbHdr->ui32RblEOF,
							(FLMUINT)pLastCommittedDbHdr->ui32RblFirstCPBlkAddr,
							TRUE,
							pLastCommittedDbHdr->ui64RflLastCPTransID)))
	{
		goto Exit;
	}
	pLastCommittedDbHdr->ui32RblFirstCPBlkAddr = 0;
	pLastCommittedDbHdr->ui32RblEOF = (FLMUINT32)m_uiBlockSize;
	if (RC_BAD( rc = writeDbHdr( pDb->m_pDbStats, pDb->m_pSFileHdl,
								pLastCommittedDbHdr,
								&m_checkpointDbHdr, TRUE)))
	{
		goto Exit;
	}

	// Set uiFirstLogCPBlkAddress to zero to indicate that no
	// physical blocks have been logged for the current checkpoint.
	// The above call to flmPhysRollback will have set the log header
	// to the same thing.

	m_uiFirstLogCPBlkAddress = 0;

	// Set the checkpointDbHdr to be the same as the log header

	f_memcpy( &m_checkpointDbHdr, pLastCommittedDbHdr, sizeof( XFLM_DB_HDR));

	// Open roll forward log and redo the transactions that
	// occurred since the last checkpoint, if any.

	if( RC_BAD( rc = m_pRfl->recover( pDb, pRestoreObj, pRestoreStatus)))
	{
		goto Exit;
	}

Exit:

	return( rc);
}
Пример #23
0
RCODE FTKAPI F_DirHdl::next( void)
{
	char					szFoundPath[ F_PATH_MAX_SIZE];
	char					szDummyPath[ F_PATH_MAX_SIZE];
	FLMUINT				uiSearchAttributes;
	FLMUINT				uiFoundAttrib;
	IF_FileSystem *	pFileSystem = f_getFileSysPtr();

	if( RC_BAD( m_rc))
	{
		goto Exit;
	}

	uiSearchAttributes =
		F_IO_FA_NORMAL | F_IO_FA_RDONLY | F_IO_FA_ARCHIVE | F_IO_FA_DIRECTORY;

	for( ;;)
	{
		if( m_bFirstTime)
		{
			m_bFirstTime = FALSE;

			if( RC_BAD( m_rc = f_fileFindFirst( m_szDirectoryPath, 
				uiSearchAttributes, &m_FindData, szFoundPath, &uiFoundAttrib)))
			{
				goto Exit;
			}
			
			m_bFindOpen = TRUE;
			m_uiAttrib = uiFoundAttrib;
		}
		else
		{
			if( RC_BAD( m_rc = f_fileFindNext( &m_FindData, 
				szFoundPath, &uiFoundAttrib)))
			{
				goto Exit;
			}
			
			m_uiAttrib = uiFoundAttrib;
		}

		if( RC_BAD( m_rc = pFileSystem->pathReduce( szFoundPath, 
			szDummyPath, m_szFileName)))
		{
			goto Exit;
		}

		if( pFileSystem->doesFileMatch( m_szFileName, m_szPattern))
		{
			break;
		}
	}

Exit:

	return( m_rc);
}
Пример #24
0
/****************************************************************************
Desc : Retrieves the current transaction number of a database
Notes: This routine should only be called only from within an update
		 transaction since read transactions are not assigned a transaction
		 number.
****************************************************************************/
FLMEXP RCODE FLMAPI FlmDbGetTransId(
	HFDB				hDb,
	FLMUINT *		puiTrNumRV)
{
	RCODE			rc = FERR_OK;
	FDB *			pDb = (FDB *)hDb;
	FLMBOOL		bIgnore;

	if (IsInCSMode( hDb))
	{
		fdbInitCS( pDb);
		
		CS_CONTEXT *	pCSContext = pDb->pCSContext;
		FCL_WIRE			Wire( pCSContext, pDb);

		// Send a request to get the transaction ID.

		if (RC_BAD( rc = Wire.sendOp(
			FCS_OPCLASS_DATABASE, FCS_OP_GET_TRANS_ID)))
		{
			goto Exit;
		}

		if (RC_BAD( rc = Wire.sendTerminate()))
		{
			goto Transmission_Error;
		}

		// Read the response
	
		if (RC_BAD( rc = Wire.read()))
		{
			goto Transmission_Error;
		}
		*puiTrNumRV = Wire.getTransId();

		rc = Wire.getRCode();
		goto Exit;

Transmission_Error:

		pCSContext->bConnectionGood = FALSE;
		goto Exit;
	}

	if (RC_BAD( rc = fdbInit( pDb, FLM_UPDATE_TRANS,
										FDB_TRANS_GOING_OK, 0, &bIgnore)))
	{
		goto Exit;
	}

	*puiTrNumRV = pDb->LogHdr.uiCurrTransID;

Exit:

	flmExit( FLM_DB_GET_TRANS_ID, pDb, rc);
	return( rc);
}
Пример #25
0
/****************************************************************************
Desc:	Make sure the vector array is allocated at least up to the element
		number that is passed in.
****************************************************************************/
RCODE F_DataVector::allocVectorArray(
	FLMUINT	uiElementNumber)
{
	RCODE	rc = NE_XFLM_OK;

	if (uiElementNumber >= m_uiNumElements)
	{

		// May need to allocate a new vector array

		if (uiElementNumber >= m_uiVectorArraySize)
		{
			FLMUINT					uiNewArraySize = uiElementNumber + 32;
			F_VECTOR_ELEMENT *	pNewVector;

			if (m_pVectorElements == &m_VectorArray [0])
			{
				if (RC_BAD( rc = f_alloc( uiNewArraySize * sizeof( F_VECTOR_ELEMENT),
											&pNewVector)))
				{
					goto Exit;
				}
				if (m_uiNumElements)
				{
					f_memcpy( pNewVector, m_pVectorElements,
						m_uiNumElements * sizeof( F_VECTOR_ELEMENT));
				}
			}
			else
			{
				pNewVector = m_pVectorElements;

				if (RC_BAD( rc = f_realloc( uiNewArraySize * sizeof( F_VECTOR_ELEMENT),
											&pNewVector)))
				{
					goto Exit;
				}

			}
			m_pVectorElements = pNewVector;
			m_uiVectorArraySize = uiNewArraySize;
		}

		// Initialized everything between the old last element and
		// the new element, including the new element, to zeroes.

		f_memset( &m_pVectorElements [m_uiNumElements], 0,
			sizeof( F_VECTOR_ELEMENT) *
			(uiElementNumber - m_uiNumElements + 1));

		m_uiNumElements = uiElementNumber + 1;
	}

Exit:

	return( rc);
}
Пример #26
0
/****************************************************************************
Desc: This routine obtains exclusive access to a database by creating
		a .lck file.  FLAIM holds the .lck file open as long as the database
		is open.  When the database is finally closed, it deletes the .lck
		file.  This is only used for 3.x databases.
****************************************************************************/
RCODE flmCreateLckFile(
	const char *	pszFilePath,
	IF_FileHdl **	ppLockFileHdlRV)
{
	RCODE				rc = NE_XFLM_OK;
	char				szLockPath [F_PATH_MAX_SIZE];
	char				szDbBaseName [F_FILENAME_SIZE];
	char *			pszFileExt;
	IF_FileHdl *	pLockFileHdl = NULL;
	char				szFilePathStr[ F_PATH_MAX_SIZE];

	if( RC_BAD( rc = gv_XFlmSysData.pFileSystem->pathToStorageString( 
		pszFilePath, szFilePathStr)))
	{
		goto Exit;
	}

	// Extract the 8.3 name and put a .lck extension on it to create
	// the full path for the .lck file.

	if (RC_BAD( rc = gv_XFlmSysData.pFileSystem->pathReduce( 
		szFilePathStr, szLockPath, szDbBaseName)))
	{
		goto Exit;
	}
	pszFileExt = &szDbBaseName [0];
	while ((*pszFileExt) && (*pszFileExt != '.'))
		pszFileExt++;
	f_strcpy( pszFileExt, ".lck");

	if( RC_BAD( rc = gv_XFlmSysData.pFileSystem->pathAppend( 
		szLockPath, szDbBaseName)))
	{
		goto Exit;
	}
	
	if( RC_BAD( rc = gv_XFlmSysData.pFileSystem->createLockFile( 
		szLockPath, &pLockFileHdl)))
	{
		goto Exit;
	}

	*ppLockFileHdlRV = (IF_FileHdl *)pLockFileHdl;
	pLockFileHdl = NULL;
	
Exit:

	if (pLockFileHdl)
	{
		(void)pLockFileHdl->closeFile();
		pLockFileHdl->Release();
		pLockFileHdl = NULL;
	}
	
	return( rc);
}
Пример #27
0
/******************************************************************
Desc:	Implements the addChar function of the DynamicBuffer class
*******************************************************************/
RCODE F_DynamicBuffer::addChar(
	char			ucCharacter)
{
	RCODE			rc = FERR_OK;

	if (!m_bSetup)
	{
		flmAssert( 0);
		rc = RC_SET( FERR_FAILURE);
		goto Exit;

	}

	f_mutexLock( m_hMutex);

	// Is there room for just one more character plus a terminator?
	if ((m_uiBuffSize - m_uiUsedChars) > 1)
	{
		m_pucBuffer[ m_uiUsedChars++] = ucCharacter;
		m_pucBuffer[ m_uiUsedChars] = 0;
	}
	else
	{
		// Allocate a new buffer or increase the size of the existing one.
		if( !m_uiBuffSize)
		{
			if( RC_BAD( rc = f_alloc( 50, &m_pucBuffer)))
			{
				goto Exit;
			}
			m_uiBuffSize = 50;
		}
		else
		{
			if( RC_BAD( rc = f_realloc( m_uiBuffSize + 50,  &m_pucBuffer)))
			{
				goto Exit;
			}
			m_uiBuffSize += 50;
		}


		m_pucBuffer[ m_uiUsedChars++] = ucCharacter;
		m_pucBuffer[ m_uiUsedChars] = 0;
	}

Exit:

	if ( m_bSetup)
	{
		f_mutexUnlock( m_hMutex);
	}

	return( rc);
}
Пример #28
0
/****************************************************************************
Desc:	Setup two child blocks for a root block.
****************************************************************************/
RCODE F_BtreeRoot::setupTree(
    FLMBYTE *		pucMidEntry,		// If !NULL entry to insert into root.
    eDynRSetBlkTypes		eBlkType,			// Leaf or non-leaf
    F_BtreeBlk **	ppLeftBlk,			// (out)
    F_BtreeBlk **	ppRightBlk)			// (out)
{
    RCODE			rc = NE_FLM_OK;
    F_BtreeBlk *	pLeftBlk = NULL;
    F_BtreeBlk *	pRightBlk = NULL;

    if (RC_BAD( rc = newBlk( &pLeftBlk, eBlkType)))
    {
        goto Exit;
    }

    if (RC_BAD( rc = newBlk( &pRightBlk, eBlkType)))
    {
        goto Exit;
    }

    if (eBlkType == ACCESS_BTREE_NON_LEAF)
    {
        ((F_BtreeNonLeaf *)pRightBlk)->lemBlk( lemBlk());
    }

    // Fix up the linkages

    pLeftBlk->nextBlk( pRightBlk->blkAddr());
    pRightBlk->prevBlk( pLeftBlk->blkAddr());
    lemBlk( pRightBlk->blkAddr());

    if (pucMidEntry)
    {

        // Add the midentry to the root block.  Search to position and insert.

        searchEntry( pucMidEntry);
        insertEntry( pucMidEntry, pLeftBlk->blkAddr());
    }
    m_uiLevels++;

    if (ppLeftBlk)
    {
        *ppLeftBlk = pLeftBlk;
    }
    if (ppRightBlk)
    {
        *ppRightBlk = pRightBlk;
    }

Exit:

    return( rc);
}
Пример #29
0
/****************************************************************************
Desc:	Set auto turn off keep RFL flag.
****************************************************************************/
RCODE XFLAPI F_Db::setAutoTurnOffKeepRflFlag(
	FLMBOOL	bAutoTurnOff
	)
{
	RCODE		rc = NE_XFLM_OK;
	FLMBOOL	bStartedTrans = FALSE;

	// See if the database is being forced to close

	if (RC_BAD( rc = checkState( __FILE__, __LINE__)))
	{
		goto Exit;
	}

	// Start an update transaction.  Must not already be one going.

	if (m_eTransType != XFLM_NO_TRANS)
	{
		rc = RC_SET( NE_XFLM_TRANS_ACTIVE);
		goto Exit;
	}

	if (RC_BAD( rc = beginTrans( XFLM_UPDATE_TRANS)))
	{
		goto Exit;
	}
	bStartedTrans = TRUE;

	// Change the uncommitted log header

	m_pDatabase->m_uncommittedDbHdr.ui8RflAutoTurnOffKeep =
							(FLMUINT8)(bAutoTurnOff
										 ? (FLMUINT8)1
										 : (FLMUINT8)0);

	// Commit the transaction.

	bStartedTrans = FALSE;
	if (RC_BAD( rc = commitTrans( 0, FALSE)))
	{
		goto Exit;
	}

Exit:

	if (bStartedTrans)
	{
		abortTrans();
	}

	return( rc);
}
Пример #30
0
/***************************************************************************
Desc:
*****************************************************************************/
RCODE F_Database::startMaintThread( void)
{
	RCODE			rc = NE_SFLM_OK;
	char			szThreadName[ F_PATH_MAX_SIZE];
	char			szBaseName[ 32];

	flmAssert( !m_pMaintThrd);
	flmAssert( m_hMaintSem == F_SEM_NULL);

	// Generate the thread name

	if( RC_BAD( rc = gv_SFlmSysData.pFileSystem->pathReduce( 
		m_pszDbPath, szThreadName, szBaseName)))
	{
		goto Exit;
	}

	f_sprintf( (char *)szThreadName, "Maintenance (%s)", (char *)szBaseName);

	// Create the maintenance semaphore

	if( RC_BAD( rc = f_semCreate( &m_hMaintSem)))
	{
		goto Exit;
	}

	// Start the thread.

	if( RC_BAD( rc = gv_SFlmSysData.pThreadMgr->createThread( &m_pMaintThrd,
		F_Database::maintenanceThread, szThreadName,
		0, 0, this, NULL, 32000)))
	{
		goto Exit;
	}

	// Signal the thread to check for any queued work

	f_semSignal( m_hMaintSem);

Exit:

	if( RC_BAD( rc))
	{
		if( m_hMaintSem != F_SEM_NULL)
		{
			f_semDestroy( &m_hMaintSem);
		}
	}

	return( rc);
}