Example #1
0
RCODE CSPDB::registerFieldArray(HFDB hFlaim, CS_FIELD_DEF *fieldTable, FLMINT count)
{
	RCODE				rc = FERR_OK;
	int 				i;

	// Begin a flaim transaction.
	rc = FlmDbTransBegin(hFlaim, FLM_UPDATE_TRANS, 255);
	if (RC_OK(rc))
	{
		for (i = 0; i < count; ++i)
		{
			FLMUINT		fieldId = fieldTable[i].id;
			rc = RegisterField(hFlaim, fieldTable[i].name, CSPTypeToFlaimType(fieldTable[i].type), &fieldId);
			if (RC_BAD(rc))
			{
				break;
			}
		}
		if (RC_OK(rc))
		{
	 		FlmDbTransCommit(hFlaim);
		}
		else
		{
			FlmDbTransAbort(hFlaim);
		}
	}
	return (rc);
} // CSPDB::registerFieldArray()
Example #2
0
RCODE CSPDB::registerIndexArray(HFDB hFlaim, CS_FIELD_DEF *indexTable, FLMINT count)
{
	RCODE				rc = FERR_OK;
	int					i;

	rc = FlmDbTransBegin(hFlaim, FLM_UPDATE_TRANS, 255);
	if (RC_OK(rc))
	{
		for (i = 0; i < count; ++i)
		{
			rc = AddIndex(hFlaim, indexTable[i].name, indexTable[i].id);
			if (RC_BAD(rc))
			{
				break;
			}
		}
		if (RC_OK(rc))
		{
	 		rc = FlmDbTransCommit(hFlaim);
		}
		else
		{
			rc = FlmDbTransAbort(hFlaim);
		}
	}

	return (rc);
} // CSPDB::registerIndexArray()
Example #3
0
/**
 * Method to connect to the store.
 * 
 * @param storePath The full path to the store to connect to.
 * @return HRESULT
 */
RCODE CSPStore::OpenStore( char *pStorePath)
{
	RCODE				rc = FERR_OK;
	char*				pDbPath;

	// Convert the path to current code page and then create the data base.
	pDbPath = setupDbPath(pStorePath);

	if (pDbPath)
	{

		rc = FlmDbOpen(
			pDbPath,
			NULL,
			NULL,			//default pRflDir
			0,
			NULL,
			&m_hFlaim);

		if (RC_OK(rc))
		{
			// Now setup the store.
			rc = m_pDB->initializeDB(m_hFlaim, false);
			if (RC_OK(rc))
			{
				m_connected = true;
			}
		}
	}
	return (rc);
} // CSPStore::OpenStore()
Example #4
0
RCODE CSPDB::initializeDB(HFDB hFlaim, FLMBOOL created)
{
	RCODE		rc = FERR_OK;
		
	if (!m_flaimInitialized)
	{
		SetupNameTable(hFlaim);
		if (RC_OK(rc))
		{
			if (created)
			{
				// Register the well know properties
				rc = registerFieldArray(hFlaim, propertyArray, sizeof(propertyArray) / sizeof(CS_FIELD_DEF));
				if (RC_OK(rc))
				{
					// Add the indexes
					rc = registerIndexArray(hFlaim, propertyArray, sizeof(propertyArray) / sizeof(CS_FIELD_DEF));
				}
			}
			m_flaimInitialized = true;
		}
	}

	return (rc);
} // CSPDB::initializeDB()
/********************************************************************
Desc: Checks to see if the user pressed ESCAPE to exit the loader.
		Also updates the total loaded counter on the screen.
*********************************************************************/
FLMUINT gigaSeeIfQuit( void)
{
	FLMUINT	uiChar = 0;;

	f_mutexLock( gv_hWindowMutex);
	gigaOutputUINT( TOTAL_LOADED_ROW, gv_uiTotalLoaded, TRUE);
	if (RC_OK( FTXWinTestKB( gv_pWindow)))
	{
		FTXWinInputChar( gv_pWindow, &uiChar);
		if (uiChar == FKB_ESCAPE)
		{
			uiChar = gigaGetInput(
							"ESCAPE pressed, quit? (ESC,Q,Y=Quit, other=continue): ",
							NULL, TRUE);
			switch (uiChar)
			{
				case 'Q':
				case 'q':
				case 'y':
				case 'Y':
					uiChar = FKB_ESCAPE;
					break;
				case FKB_ESCAPE:
					break;
				default:
					uiChar = 0;
					break;
			}
		}
		else if( uiChar == 'i' || uiChar == 'I')
		{
			HFDB			hDb;

			f_threadDestroy( &gv_pIxManagerThrd);
			if (RC_OK( FlmDbOpen( gv_szDibName, gv_szDataDir,
										gv_szRflDir, 0, NULL, &hDb)))
			{
				f_threadCreate( &gv_pIxManagerThrd,
					flstIndexManagerThread, "index_manager",
					F_DEFAULT_THREAD_GROUP, 0, (void *)hDb);
			}
		}
	}

	if (gv_bShutdown)
	{
		uiChar = FKB_ESCAPE;
	}
	
	f_mutexUnlock( gv_hWindowMutex);
	return( uiChar);
}
/****************************************************************************
Desc:
****************************************************************************/
RCODE FLMAPI f_rwlockAcquire(
	F_RWLOCK				hReadWriteLock,
	F_SEM					hSem,
	FLMBOOL				bWriter)
{
	RCODE					rc = NE_FLM_OK;
	F_RWLOCK_IMP *		pReadWriteLock = (F_RWLOCK_IMP *)hReadWriteLock;
	FLMBOOL				bMutexLocked = FALSE;
	
	f_mutexLock( pReadWriteLock->hMutex);
	bMutexLocked = TRUE;
	
	if( bWriter)
	{
		if( pReadWriteLock->iRefCnt != 0)
		{
			rc = f_notifyWait( pReadWriteLock->hMutex, hSem, (void *)((FLMINT)bWriter),
				&pReadWriteLock->pNotifyList); 
		}
		
		if( RC_OK( rc))
		{
			f_assert( !pReadWriteLock->iRefCnt);
			pReadWriteLock->iRefCnt = -1;
			pReadWriteLock->uiWriteThread = f_threadId();
		}
	}
	else
	{	 
		if( pReadWriteLock->iRefCnt < 0 || pReadWriteLock->pNotifyList)
		{
			rc = f_notifyWait( pReadWriteLock->hMutex, hSem, (void *)((FLMINT)bWriter), 
				&pReadWriteLock->pNotifyList); 
		}
		
		if( RC_OK( rc))
		{
			pReadWriteLock->iRefCnt++;
		}
	}
	
	f_assert( RC_BAD( rc) || pReadWriteLock->iRefCnt);
	
	if( bMutexLocked)
	{
		f_mutexUnlock( pReadWriteLock->hMutex);
	}
	
	return( rc);
}
/****************************************************************************
Desc:
****************************************************************************/
void F_IOBuffer::notifyComplete(
	RCODE					completionRc)
{
	f_assert( m_bPending);
	
	m_bPending = FALSE;
	m_bCompleted = TRUE;
	m_completionRc = completionRc;
	m_uiEndTime = FLM_GET_TIMER();
	m_uiElapsedTime = FLM_TIMER_UNITS_TO_MILLI( 
		FLM_ELAPSED_TIME( m_uiEndTime, m_uiStartTime));

	if( m_fnCompletion)
	{
		m_fnCompletion( this, m_pvData);
		m_fnCompletion = NULL;
		m_pvData = NULL;
	}

	if( m_pBufferMgr)
	{
		f_assert( m_eList == MGR_LIST_PENDING);
		f_mutexLock( m_pBufferMgr->m_hMutex);
		
		m_pBufferMgr->unlinkFromList( this);
		m_pBufferMgr->linkToList( &m_pBufferMgr->m_pFirstUsed, this);
		
		if( RC_OK( m_pBufferMgr->m_completionRc) && RC_BAD( completionRc))
		{
			m_pBufferMgr->m_completionRc = completionRc;
		}
		
		f_mutexUnlock( m_pBufferMgr->m_hMutex);		
	}
}
/****************************************************************************
Desc:	Event callback
*****************************************************************************/
void  IX_Event::catchEvent(
	eEventType	eEvent,
	IF_Db *		pDb,
	FLMUINT,		// uiThreadId,
	FLMUINT64,	// ui64TransID,
	FLMUINT		uiIndexOrCollection,
	FLMUINT64	ui64NodeId,
	RCODE			// rc
	)
{
	XFLM_INDEX_STATUS	ixStatus;
	FLMUINT				uiGMT;

	if (eEvent == XFLM_EVENT_INDEXING_PROGRESS && !ui64NodeId && pDb)
	{
		if (RC_OK( ((F_Db *)pDb)->indexStatus( uiIndexOrCollection, &ixStatus)))
		{
			f_timeGetSeconds( &uiGMT );

			f_mutexLock( m_pDispInfo->hScreenMutex);
			FTXWinPrintf( m_pDispInfo->pLogWin,
				"Index %u came on-line.  Elapsed time = %u second(s)\n",
				uiIndexOrCollection, uiGMT - (FLMUINT)ixStatus.ui32StartTime);
			f_mutexUnlock( m_pDispInfo->hScreenMutex);
		}
	}
}
Example #9
0
RCODE CSPDB::RegisterField(HFDB hFlaim, FLMUNICODE *pFieldName, FLMUINT flmType, FLMUINT* pFieldId)
{
	RCODE				rc = FERR_OK;
	FlmRecord			*pRec = NULL;
	void				*pvField = 0;

	pRec = new FlmRecord();
	if (pRec != NULL)
	{
		rc = pRec->insertLast(0, FLM_FIELD_TAG, FLM_TEXT_TYPE, &pvField);
		if (RC_OK(rc))
		{
			rc = pRec->setUnicode(pvField, (FLMUNICODE*)pFieldName);
			if (RC_OK(rc))
			{
				rc = pRec->insert(pvField, INSERT_LAST_CHILD, FLM_TYPE_TAG, FLM_TEXT_TYPE, &pvField);
				if (RC_OK(rc))
				{
					if (flmType != FLM_UNDEFINED_TYPE)
					{
						rc = pRec->setUnicode(pvField, (FLMUNICODE*)cs_flaim_type_name[flmType]);
						if (RC_OK(rc))
						{
							rc = FlmRecordAdd(hFlaim, FLM_DICT_CONTAINER, pFieldId, pRec, 0);
							if (RC_OK(rc))
							{
								rc = m_NameTable.addTag((FLMUNICODE*)pFieldName, 0, *pFieldId, 0, 0, TRUE);
							}
						}
					}
					else
					{
						rc = FERR_BAD_FIELD_TYPE;
					}
				}
			}
		}
		pRec->Release();
	}
	else
	{
		rc = FERR_MEM;
	}

	return (rc);
} // CSPDB::registerField()
Example #10
0
/****************************************************************************
Desc:	Adds a field path to the selection criteria of a given cursor.  A
		field path is the fully qualified context of a field within a record.
****************************************************************************/
FLMEXP RCODE FLMAPI FlmCursorAddFieldPath(
	HFCURSOR		hCursor,
	FLMUINT *	puiFldPath,
	FLMUINT		uiFlags)
{
	RCODE			rc = FERR_OK;
	FQNODE *		pTmpQNode;
	CURSOR *		pCursor = (CURSOR *)hCursor;

	if (!pCursor)
	{
		flmAssert( 0);
		rc = RC_SET( FERR_INVALID_PARM);
		goto Exit;
	}
	if (RC_BAD( rc = pCursor->rc))
	{
		goto Exit;
	}

	// If a read operation has already been performed on this query, no
	// selection criteria may be added.
	
	if (pCursor->bOptimized)
	{
		rc = RC_SET( FERR_ILLEGAL_OP);
		goto Exit;
	}
	
	if (!( pCursor->QTInfo.uiExpecting & FLM_Q_OPERAND))
	{
		rc = RC_SET( FERR_CURSOR_SYNTAX);
		goto Exit;
	}

	if (RC_OK( rc = flmCurMakeQNode( &pCursor->QueryPool, FLM_FLD_PATH,
									puiFldPath, 0, pCursor->QTInfo.uiFlags,
									&pTmpQNode)))
	{
		pTmpQNode->pQAtom->uiFlags |= uiFlags;
		pCursor->QTInfo.pCurAtomNode = pTmpQNode;
		if (pCursor->QTInfo.pCurOpNode)
		{
			flmCurLinkLastChild( pCursor->QTInfo.pCurOpNode,
										pCursor->QTInfo.pCurAtomNode);
		}
		pCursor->QTInfo.uiExpecting &= ~FLM_Q_OPERAND;
		pCursor->QTInfo.uiExpecting |= FLM_Q_OPERATOR;
	}

Exit:
	if (pCursor)
	{
		pCursor->rc = rc;
	}
	return( rc);
}
Example #11
0
RCODE CSPStore::CreateStore(char *pStorePath)
{
	RCODE			rc = FERR_OK;
	char*			pDbPath;
	
	// Create the path to the database.
	pDbPath = setupDbPath(pStorePath);

	if (pDbPath)
	{
		// Create the New Store.
		rc = FlmDbCreate(
			pDbPath,
			NULL,
			NULL,			//default pRflDir
			NULL,
			NULL,
			NULL,
			&m_hFlaim);

		if (RC_OK(rc))
		{
			// Now setup the store.
			rc = m_pDB->initializeDB(m_hFlaim, true);

			if (RC_OK(rc))
			{
				m_connected = true;
			}
			else 
			{
				FlmDbRemove(
					pDbPath,
					NULL,
					NULL,
					true);
			}
		}
	}

	return (rc);
} // CSPStore::CreateStore()
Example #12
0
CSPDB::CSPDB() :
	m_flaimInitialized(false)
{
	RCODE rc;
	// Make sure the Flaim library has been initialized.
	rc = FlmStartup();
	if (RC_OK(rc))
	{
		m_RefCount = 1;
	}
}
Example #13
0
/****************************************************************************
Desc:
****************************************************************************/
FSTATIC void _flmDbgLogFlush( void)
{
	FLMUINT			uiBytesToWrite;
	FLMUINT			uiBytesWritten;
	char *			pszBufPtr = g_pszLogBuf;
	FLMUINT			uiTotalToWrite = g_uiLogBufOffset;
	RCODE				rc = NE_SFLM_OK;
	FLMUINT			uiBufferSize = DBG_LOG_BUFFER_SIZE + 1024;

	while( uiTotalToWrite)
	{
		if( uiTotalToWrite > 0xFE00)
		{
			uiBytesToWrite = 0xFE00;
		}
		else
		{
			uiBytesToWrite = uiTotalToWrite;
		}

		if( RC_BAD( rc = g_pLogFile->SectorWrite(
			g_uiLogFileOffset, uiBytesToWrite,
			pszBufPtr, uiBufferSize, NULL, &uiBytesWritten, FALSE)))
		{
			goto Exit;
		}

		flmAssert( uiBytesToWrite == uiBytesWritten);
		g_uiLogFileOffset += uiBytesWritten;
		pszBufPtr += uiBytesWritten;
		uiBufferSize -= uiBytesWritten;
		uiTotalToWrite -= uiBytesWritten;
	}

	if (g_uiLogBufOffset & 0x1FF)
	{
		if (g_uiLogBufOffset > 512)
		{
			f_memcpy( g_pszLogBuf,
				&g_pszLogBuf [g_uiLogBufOffset & 0xFFFFFE00],
					512);
			g_uiLogBufOffset &= 0x1FF;
		}
		g_uiLogFileOffset -= g_uiLogBufOffset;
	}
	else
	{
		g_uiLogBufOffset = 0;
	}

Exit:

	flmAssert( RC_OK( rc));
}
Example #14
0
/****************************************************************************
Desc:
****************************************************************************/
FINLINE void FTKAPI F_DirHdl::currentItemPath(
	char *		pszPath)
{
	if( RC_OK( m_rc))
	{
		f_strcpy( pszPath, m_szDirectoryPath);
#ifdef FLM_RING_ZERO_NLM
		f_pathAppend( pszPath, currentItemName());
#else
		f_pathAppend( pszPath, m_szFileName);
#endif
	}
}
Example #15
0
/****************************************************************************
Desc:
****************************************************************************/
const char * FTKAPI F_DirHdl::currentItemName( void)
{
	const char *	pszName = NULL;
	
#ifndef FLM_RING_ZERO_NLM

	if( RC_OK( m_rc))
	{
		pszName = m_szFileName;
	}
	
#else

	FLMUINT			uiLength;

	if( RC_OK( m_rc))
	{
		if( !m_FindData.pCurrentItem)
		{
			return( NULL);
		}
		
		uiLength = sizeof( m_FindData.ucTempBuffer) - 1;
		if( m_FindData.pCurrentItem->DFileNameLength < uiLength)
		{
			uiLength = m_FindData.pCurrentItem->DFileNameLength;
		}
		
		f_strncpy( m_FindData.ucTempBuffer, 
			(const char *)m_FindData.pCurrentItem->DFileName, uiLength);
		m_FindData.ucTempBuffer[ uiLength] = 0;
		pszName = m_FindData.ucTempBuffer;
	}
	
#endif

	return( pszName);
}
Example #16
0
/****************************************************************************
Desc:	Aborts an active transaction.
****************************************************************************/
FLMEXP RCODE FLMAPI FlmDbTransAbort(
	HFDB			hDb)
{
	RCODE			rc;
	FDB *			pDb = (FDB *)hDb;
	FLMBOOL		bIgnore;

	if (IsInCSMode( hDb))
	{
		fdbInitCS( pDb);
		FCL_WIRE	Wire( pDb->pCSContext, pDb);
		if (!pDb->pCSContext->bConnectionGood)
		{
			rc = RC_SET( FERR_BAD_SERVER_CONNECTION);
		}
		else
		{
			rc = Wire.doTransOp( FCS_OP_TRANSACTION_ABORT, 0, 0, 0);
		}
		goto Exit;
	}

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

	// If there is an invisible transaction going, it should not be
	// abortable by an application.

	if ((pDb->uiTransType == FLM_NO_TRANS) ||
		 (pDb->uiFlags & FDB_INVISIBLE_TRANS))
	{
		rc = RC_SET( FERR_NO_TRANS_ACTIVE);
		goto Exit;
	}
	
	rc = flmAbortDbTrans( pDb);

Exit:

	if( RC_OK( rc))
	{
		rc = flmCheckDatabaseState( pDb);
	}

	flmExit( FLM_DB_TRANS_ABORT, pDb, rc);
	return( rc);
}
Example #17
0
/****************************************************************************
Desc:
****************************************************************************/
RCODE F_DbCheck::createAndOpenResultSetDb( void)
{
	RCODE					rc = NE_XFLM_OK;
	XFLM_CREATE_OPTS	createOpts;

	if (m_pResultSetDb)
	{
		if (RC_BAD( rc = closeAndDeleteResultSetDb()))
		{
			goto Exit;
		}
	}

	f_memset( &createOpts, 0, sizeof( XFLM_CREATE_OPTS));
	for (;;)
	{

		// Generate a random file name
		
		f_sprintf( m_szResultSetDibName,
					  "%d.db", (int)m_pRandGen->getUINT32( 100, 20000));
		
		if (RC_OK( rc = gv_pXFlmDbSystem->dbCreate( 
				m_szResultSetDibName, NULL, NULL, NULL, NULL, 
				&createOpts, TRUE, (IF_Db **)&m_pResultSetDb)))
		{
			break;
		}
		if (rc == NE_XFLM_FILE_EXISTS || rc == NE_FLM_IO_ACCESS_DENIED)
		{
			rc = NE_XFLM_OK;
		}
		else
		{
			goto Exit;
		}
	}

	// Shouldn't have an RFL object - don't want anything
	// logged by this database.
	
	flmAssert( !m_pResultSetDb->getDatabase()->m_pRfl);

Exit:

	return rc;
}
Example #18
0
/****************************************************************************
Desc:
****************************************************************************/
RCODE FTKAPI F_IOBufferMgr::waitForAllPendingIO( void)
{
	RCODE				rc = NE_FLM_OK;
	RCODE				tmpRc;
	F_IOBuffer *	pBuf;
	FLMBOOL			bMutexLocked = FALSE;

	f_mutexLock( m_hMutex);
	bMutexLocked = TRUE;
	
	while( (pBuf = m_pFirstPending) != NULL)
	{
		pBuf->AddRef();
		
		f_mutexUnlock( m_hMutex);
		bMutexLocked = FALSE;
		
		if( RC_BAD( tmpRc = pBuf->waitToComplete()))
		{
			if( RC_OK( m_completionRc))
			{
				f_mutexLock( m_hMutex);
				bMutexLocked = TRUE;
				m_completionRc = tmpRc;
			}
		}
		
		if( !bMutexLocked)
		{
			f_mutexLock( m_hMutex);
			bMutexLocked = TRUE;
		}

		pBuf->Release( TRUE);
		pBuf = NULL;
	}
	
	rc = m_completionRc;
	m_completionRc = NE_FLM_OK;
	
	if( bMutexLocked)
	{
		f_mutexUnlock( m_hMutex);
	}
	
	return( rc);
}
Example #19
0
/****************************************************************************
Desc:
****************************************************************************/
RCODE ArgList::expandFileArgs( 
	const char *		pszFilename)
{
	RCODE				rc = FERR_OK;
	char				token[64];
	IF_FileHdl *	pFileHdl = NULL;

	if( RC_BAD( rc = gv_FlmSysData.pFileSystem->openFile(
		pszFilename, FLM_IO_RDWR, &pFileHdl)))
	{
		goto Exit;
	}

	while( RC_OK( rc = getTokenFromFile(token, pFileHdl)))
	{
		if( token[0] == '@')
		{
			if( RC_BAD( rc = expandFileArgs( &token[1])))
			{
				goto Exit;
			}
		}
		else
		{
			flmAssert(*token);
			if( RC_BAD( rc = addArg( token)))
			{
				goto Exit;
			}
		}
	}
	
	if( rc == FERR_IO_END_OF_FILE)
	{
		rc = FERR_OK;
	}

Exit:

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

	return( rc);
}
Example #20
0
/****************************************************************************
Desc:	This code is common to all of the SetParam() functions
****************************************************************************/
RCODE F_IniFile::setParamCommon( 
	INI_LINE **		ppLine,
	const char *	pszParamName)
{
	RCODE				rc = NE_FLM_OK;
	INI_LINE *		pLine;

	if( RC_BAD( rc = m_pool.poolCalloc( 
		sizeof( INI_LINE), (void **)&pLine)))
	{
		goto Exit;
	}
	
	if( m_pLastLine)
	{
		m_pLastLine->pNext = pLine;
	}
	
	pLine->pPrev = m_pLastLine;
	m_pLastLine = pLine;
	
	if( !m_pFirstLine)
	{
		m_pFirstLine = pLine;
	}

	if( RC_BAD( rc = m_pool.poolAlloc( f_strlen(pszParamName)+1,
								(void **)&pLine->pszParamName)))
	{
		goto Exit;
	}

	f_strcpy( pLine->pszParamName, pszParamName);

Exit:

	if( RC_OK( rc))
	{
		*ppLine = pLine;
	}

	return( rc);
}
Example #21
0
/****************************************************************************
Desc:
****************************************************************************/
RCODE FLMAPI f_rwlockPromote(
	F_RWLOCK				hReadWriteLock,
	F_SEM					hSem)
{
	RCODE					rc = NE_FLM_OK;
	F_RWLOCK_IMP *		pReadWriteLock = (F_RWLOCK_IMP *)hReadWriteLock;
	FLMBOOL				bMutexLocked = FALSE;
	
	f_mutexLock( pReadWriteLock->hMutex);
	bMutexLocked = TRUE;
	
	if( pReadWriteLock->iRefCnt <= 0)
	{
		rc = RC_SET_AND_ASSERT( NE_FLM_ILLEGAL_OP);
		goto Exit;
	}
	
	pReadWriteLock->iRefCnt--;
		
	if( pReadWriteLock->iRefCnt != 0)
	{
		rc = f_notifyWait( pReadWriteLock->hMutex, hSem, (void *)TRUE, 
			&pReadWriteLock->pNotifyList); 
	}
	
	if( RC_OK( rc))
	{
		f_assert( !pReadWriteLock->iRefCnt);
		pReadWriteLock->iRefCnt = -1;
		pReadWriteLock->uiWriteThread = f_threadId();
	}

Exit:

	f_assert( RC_BAD( rc) || pReadWriteLock->iRefCnt);
	
	if( bMutexLocked)
	{
		f_mutexUnlock( pReadWriteLock->hMutex);
	}
	
	return( rc);
}
Example #22
0
/****************************************************************************
Desc:
****************************************************************************/
FLMUINT64 FTKAPI F_DirHdl::currentItemSize( void)
{
	FLMUINT64	ui64Size = 0;

	if( RC_OK( m_rc))
	{
#if defined( FLM_WIN)
		ui64Size = (((FLMUINT64)m_FindData.findBuffer.nFileSizeHigh) << 32) + 
						m_FindData.findBuffer.nFileSizeLow;
#elif defined( FLM_UNIX) || defined ( FLM_LIBC_NLM)
		ui64Size = m_FindData.FileStat.st_size;
#elif defined( FLM_RING_ZERO_NLM)
		char		szTmpPath[ F_PATH_MAX_SIZE];

		currentItemPath( szTmpPath);
		(void)f_getFileSysPtr()->getFileSize( szTmpPath, &ui64Size);
#endif
	}
	return( ui64Size);
}
Example #23
0
/****************************************************************************
Desc:
****************************************************************************/
void flmDbgLogInit( void)
{
	char	szLogPath[ 256];
	RCODE	rc	= NE_SFLM_OK;

	flmAssert( g_hDbgLogMutex == F_MUTEX_NULL);

	// Allocate a buffer for the log

	if (RC_BAD( rc = f_alloc( DBG_LOG_BUFFER_SIZE + 1024, &g_pszLogBuf)))
	{
		goto Exit;
	}

	// Create the mutex

	if (RC_BAD( rc = f_mutexCreate( &g_hDbgLogMutex)))
	{
		goto Exit;
	}

	// Build the file path

#ifdef FLM_NLM
	f_strcpy( szLogPath, "SYS:\\FLMDBG.LOG");
#else
	f_sprintf( szLogPath, "FLMDBG.LOG");
#endif

	// Create the file - truncate if it exists already.

	if( RC_BAD( rc = gv_SFlmSysData.pFileSystem->Create( szLogPath, 
		XFLM_IO_RDWR | XFLM_IO_SH_DENYNONE | XFLM_IO_DIRECT, &g_pLogFile)))
	{
		goto Exit;
	}

Exit:

	flmAssert( RC_OK( rc));
}
Example #24
0
/****************************************************************************
Desc:
****************************************************************************/
XFLXPC RCODE XFLAPI xflaim_DOMNode_hasAttribute(
	IF_DOMNode *	pThisNode,
	IF_Db *			pDb,
	FLMUINT32		ui32AttrNameId,
	FLMBOOL *		pbHasAttr)
{
	RCODE		rc;

	rc = pThisNode->hasAttribute( pDb, (FLMUINT)ui32AttrNameId, NULL);

	if (RC_OK( rc))
	{
		*pbHasAttr = TRUE;
	}
	else if (rc == NE_XFLM_DOM_NODE_NOT_FOUND)
	{
		*pbHasAttr = FALSE;
		rc = NE_XFLM_OK;
	}
	return( rc);
}
Example #25
0
FlmRecord * CSPStore::FindObject(FLMUNICODE *pId)
{
	RCODE			rc = FERR_OK;
	HFCURSOR		cursor = 0;
	FlmRecord	*pRec = NULL;
	FlmRecord	*pRWRec = NULL;
	FLMUINT		fieldId;
	FLMUINT		count;

	rc = NameToId(CS_Name_GUID, &fieldId);
	if (RC_OK(rc))
	{
		rc = FlmCursorInit(m_hFlaim, FLM_DATA_CONTAINER, &cursor);
		if (RC_OK(rc))
		{
			rc = FlmCursorAddField(cursor, fieldId, 0);
			if (RC_OK(rc))
			{
				rc = FlmCursorAddOp(cursor, FLM_EQ_OP, 0);
				if (RC_OK(rc))
				{
					rc = FlmCursorAddValue(cursor, FLM_UNICODE_VAL, pId, 0);
					if (RC_OK(rc))
					{
						rc = FlmCursorRecCount(cursor, &count);
						if (RC_OK(rc) && count != 0)
						{
							rc = FlmCursorNext(cursor, &pRec);
							if (RC_OK(rc))
							{
								pRWRec = pRec->copy();
								pRec->Release();
								pRec = NULL;
							}
						}
					}
				}
			}
			FlmCursorFree(&cursor);
		}
	}
	return (pRWRec);
} // CSPStore::FindObject()
Example #26
0
/*API~***********************************************************************
Area : TRANSACTION
Desc : Aborts an active transaction.
*END************************************************************************/
RCODE F_Db::transAbort( void)
{
	RCODE	rc = NE_XFLM_OK;

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

	rc = abortTrans();

Exit:

	if (RC_OK( rc))
	{
		rc = checkState( __FILE__, __LINE__);
	}

	return( rc);
}
Example #27
0
/****************************************************************************
Desc:		Thread that will build an index in the background.
			Caller will create a pDb to use.  This pDb must be
			freed at the conclusion of the routine.
****************************************************************************/
FSTATIC RCODE FLMAPI flmBackgroundIndexBuildThrd(
	IF_Thread *			pThread)
{
	RCODE					rc = FERR_OK;
	IXD *					pIxd;
	F_BKGND_IX * 		pBackgroundIx = (F_BKGND_IX *)pThread->getParm1();
	FLMBOOL				bStartedTrans;
	FLMBOOL				bDbInitialized;
	FLMUINT				uiContainerNum;
	FLMUINT				uiFirstDrn;
	FLMUINT				uiIndexNum;
	FDB *					pDb = NULL;
	FLMBOOL				bForcedShutdown = FALSE;
	FLMBOOL				bHitEnd;
	FINDEX_STATUS		savedIxStatus;
	FlmRecord *			pReusableRec = NULL;
	char					szMsg[ 128];
	FLMINT				iErrorLine = 0;
	FLMBOOL				bLimitedMode = FALSE;

	pThread->setThreadStatus( FLM_THREAD_STATUS_INITIALIZING);

	if( (pReusableRec = f_new FlmRecord) != NULL)
	{
		if( RC_BAD( pReusableRec->preallocSpace( 512, 1024 * 64)))
		{
			pReusableRec->Release();
			pReusableRec = NULL;
		}
	}

Loop_Again:

	rc = FERR_OK;
	uiIndexNum = pBackgroundIx->indexStatus.uiIndexNum;
	flmAssert( pThread->getThreadAppId() == uiIndexNum);
	bDbInitialized = FALSE;
	bStartedTrans = FALSE;
	pDb = NULL;

	// We could loop forever on flmOpenFile errors, check if we should exit.

	if( pThread->getShutdownFlag())
	{
		bForcedShutdown = TRUE;
		goto Exit;
	}

	if( RC_BAD( rc = flmOpenFile( pBackgroundIx->pFile,
		NULL, NULL, NULL, 0, TRUE, NULL, NULL,
		pBackgroundIx->pFile->pszDbPassword, &pDb)))
	{

		// If the file is being closed, this is not an error.

		if( pBackgroundIx->pFile->uiFlags & DBF_BEING_CLOSED)
		{
			bForcedShutdown = TRUE;
			rc = FERR_OK;
		}
		else
		{
			iErrorLine = (FLMINT)__LINE__;
		}
		goto Exit;
	}

	flmAssert( pDb->pSFileHdl);

	bDbInitialized = TRUE;
	if (RC_BAD( rc = fdbInit( pDb, FLM_NO_TRANS, 0, 0, &bStartedTrans)))
	{
		iErrorLine = (FLMINT)__LINE__;
		goto Exit;
	}
	flmAssert( !bStartedTrans);
	pDb->uiFlags |= FDB_BACKGROUND_INDEXING;

	for(;;)
	{
		// Set the thread's status

		pThread->setThreadStatus( FLM_THREAD_STATUS_RUNNING);

		// See if we should shut down. 

		if( pThread->getShutdownFlag())
		{
			bForcedShutdown = TRUE;
			break;
		}

		// Obtain the file lock

		flmAssert( !(pDb->uiFlags & FDB_HAS_FILE_LOCK));
		if( RC_BAD( rc = pDb->pFile->pFileLockObj->lock( pDb->hWaitSem,  
			TRUE, FLM_NO_TIMEOUT, FLM_BACKGROUND_LOCK_PRIORITY,
			pDb->pDbStats ? &pDb->pDbStats->LockStats : NULL)))
		{
			if( rc == FERR_IO_FILE_LOCK_ERR)
			{
				// This would only happen if we were signaled to shut down.
				// So, it's ok to exit

				flmAssert( pThread->getShutdownFlag());
				bForcedShutdown = TRUE;
				rc = FERR_OK;
			}
			else
			{
				iErrorLine = (FLMINT)__LINE__;
			}
			goto Exit;
		}

		// The lock needs to be marked as implicit so that flmCommitDbTrans
		// will unlock the file and allow the next update transaction to
		// begin before all writes are complete.

		pDb->uiFlags |= (FDB_HAS_FILE_LOCK | FDB_FILE_LOCK_IMPLICIT);

		// If there are higher priority waiters in the lock queue,
		// or we are being told to shut down, we want to relinquish.

		if( pThread->getShutdownFlag() ||
			pDb->pFile->pFileLockObj->haveHigherPriorityWaiter( 
				FLM_BACKGROUND_LOCK_PRIORITY))
		{
			if (RC_BAD( rc = pDb->pFile->pFileLockObj->unlock()))
			{
				iErrorLine = (FLMINT)__LINE__;
				goto Exit;
			}

			pDb->uiFlags &= ~(FDB_HAS_FILE_LOCK | FDB_FILE_LOCK_IMPLICIT);
			continue;
		}

		// Start an update transaction 

		if( RC_BAD( rc = flmBeginDbTrans( pDb, FLM_UPDATE_TRANS, FLM_NO_TIMEOUT, 
			FLM_DONT_POISON_CACHE)))
		{
			if( rc == FERR_IO_FILE_LOCK_ERR)
			{
				// This would only happen if we were signaled to shut down.
				// So, it's ok to exit

				flmAssert( pThread->getShutdownFlag());
				bForcedShutdown = TRUE;
				rc = FERR_OK;
			}
			else
			{
				iErrorLine = (FLMINT)__LINE__;
			}
			goto Exit;
		}
		bStartedTrans = TRUE;

		if( RC_BAD( rc = fdictGetIndex( pDb->pDict, pDb->pFile->bInLimitedMode,
			uiIndexNum, NULL, &pIxd, TRUE)))
		{
			// Index may have been deleted by another transaction, or
			// there may have been some other error.

			iErrorLine = (FLMINT)__LINE__;
			goto Exit;
		}

		// If we're running in limited mode, then we can't mess with encrypted
		// indexes.  On the other hand, since the index is marked as offline,
		// but not suspended, this thread has to exist, or else it will cause
		// all kinds of problems elsewhere.  So, in such a case, we will simply
		// sleep in an inifinite loop until the shutdown flag is set.
		// (We consider this acceptable becase running in limited mode is not
		// the norm, and Flaim probably won't be up for very long in this mode.)

		if( pDb->pFile->bInLimitedMode && pIxd->uiEncId)
		{
			bLimitedMode = TRUE;
			goto Exit;
		}

		// Look up the tracker info to determine where we need to being indexing

		if (RC_BAD( rc = flmGetIxTrackerInfo( pDb,
			pBackgroundIx->indexStatus.uiIndexNum, &uiContainerNum,
			&uiFirstDrn, NULL, &pBackgroundIx->indexStatus.bSuspended)))
		{
			iErrorLine = (FLMINT)__LINE__;
			goto Exit;
		}

		// If the index is suspended, this thread should have been
		// shut down.  The suspending thread will keep the database
		// locked until we exit.  So, if we have the database locked,
		// the index better not be suspended.

		flmAssert( !pBackgroundIx->indexStatus.bSuspended &&
			!(pIxd->uiFlags & IXD_SUSPENDED));

		if (pIxd->uiContainerNum)
		{
			uiContainerNum = pIxd->uiContainerNum;
			if( uiFirstDrn == DRN_LAST_MARKER)
			{
				goto Exit;
			}
		}
		else
		{
			if( uiFirstDrn == DRN_LAST_MARKER && uiContainerNum == 0xFFFFFFFF)
			{
				goto Exit;
			}
			else
			{
				// The container number from the tracker record
				// may not be a real container.
				// Determine what the next actual container number is.

				if (uiContainerNum != FLM_DATA_CONTAINER)
				{
					while( uiContainerNum < pDb->pDict->uiIttCnt)
					{
						ITT *	pItt = &pDb->pDict->pIttTbl [uiContainerNum];
						if (ITT_IS_CONTAINER( pItt))
						{
							break;
						}
						else
						{
							uiContainerNum++;
						}
					}

					if (uiContainerNum >= pDb->pDict->uiIttCnt)
					{
						uiContainerNum = FLM_DATA_CONTAINER;
					}
				}
			}
		}

		// Setup the DRN range we want to index.

		uiFirstDrn++;
		flmAssert( pIxd->uiLastDrnIndexed == uiFirstDrn - 1);

		// Set the thread's status

		pThread->setThreadStatus( "Indexing %u:%u", 
			(unsigned)uiContainerNum, (unsigned)uiFirstDrn);

		// Read and index up to the highest drn (or record higher than uiEndDrn)
		// or until time runs out.  The 500 is millisecs to take for the transaction.

		f_memcpy( &savedIxStatus, 
			&pBackgroundIx->indexStatus, sizeof( FINDEX_STATUS));

		if( RC_BAD( rc = flmIndexSetOfRecords( pDb,
			uiIndexNum, uiContainerNum, uiFirstDrn, DRN_LAST_MARKER,
			NULL, NULL, NULL, NULL,
			&pBackgroundIx->indexStatus, &bHitEnd, pThread, pReusableRec)))
		{
			// Lock the mutex while copying the saved index status back to
			// the main index status so that someone requesting the index status
			// won't see the status while the memcpy is in progress.

			f_mutexLock( gv_FlmSysData.hShareMutex);
			f_memcpy( &pBackgroundIx->indexStatus, 
				&savedIxStatus, sizeof( FINDEX_STATUS));
			f_mutexUnlock( gv_FlmSysData.hShareMutex);
			iErrorLine = (FLMINT)__LINE__;
			goto Exit;
		}

		if( pBackgroundIx->indexStatus.uiRecordsProcessed - 
			savedIxStatus.uiRecordsProcessed)
		{
			if( RC_BAD( rc = pDb->pFile->pRfl->logIndexSet( uiIndexNum,
						uiContainerNum, uiFirstDrn, 
						pBackgroundIx->indexStatus.uiLastRecordIdIndexed)))
			{
				iErrorLine = (FLMINT)__LINE__;
				goto Exit;
			}
		}

		// Commit the transaction (even if we didn't do any indexing work).

		if( RC_BAD( rc = flmCommitDbTrans( pDb, 0, FALSE)))
		{
			iErrorLine = (FLMINT)__LINE__;
			goto Exit;
		}

		bStartedTrans = FALSE;
		pBackgroundIx->indexStatus.uiTransactions++;

		if( bHitEnd)
		{
			// flmIndexSetOfRecords brought the index on-line

			if( gv_FlmSysData.UpdateEvents.pEventCBList)
			{
				flmDoEventCallback( F_EVENT_UPDATES, 
						F_EVENT_INDEXING_COMPLETE, (void *)uiIndexNum, 
						(void *)0);
			}

			// Log a message

			flmLogIndexingProgress( uiIndexNum, 0);
			break;
		}
	}

Exit:

	pThread->setThreadStatus( FLM_THREAD_STATUS_TERMINATING);

	if( bStartedTrans)
	{
		(void)flmAbortDbTrans( pDb);
		bStartedTrans = FALSE;
	}

	if( pDb && pDb->uiFlags & FDB_HAS_FILE_LOCK)
	{
		(void)pDb->pFile->pFileLockObj->unlock();
		pDb->uiFlags &= ~(FDB_HAS_FILE_LOCK | FDB_FILE_LOCK_IMPLICIT);
	}

	if( bDbInitialized)
	{
		fdbExit( pDb);
		bDbInitialized = FALSE;
	}

	if( pDb)
	{
		(void)FlmDbClose( (HFDB *) &pDb);
	}

	if( RC_BAD(rc) && !bForcedShutdown)
	{
		if (rc == FERR_MEM || rc == FERR_IO_DISK_FULL ||
			rc == FERR_MUST_WAIT_CHECKPOINT)
		{
			// Log the error

			f_sprintf( (char *)szMsg,
				"Background indexing thread %u (index %u)",
				(unsigned)pThread->getThreadId(), (unsigned)uiIndexNum);
			flmLogError( rc, (char *)szMsg, __FILE__, iErrorLine);

			// Sleep a half second and try again.

			pThread->sleep( 500);
			goto Loop_Again;
		}
		else
		{
			f_sprintf( (char *)szMsg,
				"Background indexing thread %u (index %u) -- unrecoverable error.",
				(unsigned)pThread->getThreadId(), (unsigned)uiIndexNum);
			flmLogError( rc, (char *)szMsg, __FILE__, iErrorLine);
		}
	}

	if( pReusableRec)
	{
		flmAssert( pReusableRec->getRefCount() == 1);
		pReusableRec->Release();
	}

	if( bLimitedMode)
	{
		flmAssert( RC_OK( rc));

		for (;;)
		{
			if( pThread->getShutdownFlag())
			{
				break;
			}

			pThread->sleep( 1000);
		}
	}

	// Set the thread's app ID to 0, so that it will not
	// be found now that the thread is terminating (we don't
	// want flmBackgroundIndexGet to find the thread).

	pThread->setThreadAppId( 0);

	// Free the background index structure

	f_mutexLock( gv_FlmSysData.hShareMutex);
	f_free( &pBackgroundIx);
	pThread->setParm1( NULL);
	f_mutexUnlock( gv_FlmSysData.hShareMutex);

	return( rc);
}
Example #28
0
/****************************************************************************
Desc:	Set a UTF8 value for a vector element.
****************************************************************************/
RCODE XFLAPI F_DataVector::setUTF8(
	FLMUINT				uiElementNumber,
	const FLMBYTE *	pszUTF8,
	FLMUINT				uiBytesInBuffer)
{
	RCODE			rc = NE_XFLM_OK;
	FLMBYTE *	pucDataPtr;
	FLMUINT		uiLen;
	FLMBYTE		ucTmpBuf [64];

	// A NULL or empty pszNative string is allowed - on those cases
	// just set the data type.

	if (pszUTF8 == NULL || *pszUTF8 == 0)
	{
		rc = storeValue( uiElementNumber, XFLM_TEXT_TYPE, NULL, 0);
		goto Exit;
	}

	// See if it will fit in our temporary buffer on the stack.

	uiLen = sizeof( ucTmpBuf);
	if (RC_OK( rc = flmUTF8ToStorage( 
		pszUTF8, uiBytesInBuffer, ucTmpBuf, &uiLen)))
	{
		if (RC_BAD( rc = storeValue( uiElementNumber,
								XFLM_TEXT_TYPE, ucTmpBuf, uiLen)))
		{
			goto Exit;
		}
	}
	else if (rc != NE_XFLM_CONV_DEST_OVERFLOW)
	{
		goto Exit;
	}
	else
	{
		// Determine the length needed.

		if (RC_BAD( rc = flmUTF8ToStorage( 
			pszUTF8, uiBytesInBuffer, NULL, &uiLen)))
		{
			goto Exit;
		}

		// Allocate space for it in the vector and get a pointer
		// back so we can then store it.

		if (RC_BAD( rc = storeValue( uiElementNumber,
								XFLM_TEXT_TYPE, NULL, uiLen, &pucDataPtr)))
		{
			goto Exit;
		}

		// Store it out to the space we just allocated.

		if (RC_BAD( rc = flmUTF8ToStorage( 
			pszUTF8, uiBytesInBuffer, pucDataPtr, &uiLen)))
		{
			goto Exit;
		}
	}

Exit:

	return( rc);
}
/****************************************************************************
Desc:		Read in the block or get it from the cache.
****************************************************************************/
RCODE F_BtreeRoot::readBlk(
    FLMUINT			uiBlkAddr,			// Blk address to read
    eDynRSetBlkTypes		eBlkType,			// Expected access type to read
    F_BtreeBlk **	ppBlk)				// (out) Return block
{
    RCODE			rc = NE_FLM_OK;
    FLMUINT		uiPos;
    FLMUINT		uiLRUValue = (FLMUINT)~0;
    FLMUINT		uiLRUPos = 0;
    F_BtreeBlk *	pNewBlk;

    for (uiPos = 0; uiPos < FBTREE_CACHE_BLKS; uiPos++)
    {
        if (m_CacheBlks[uiPos].uiBlkAddr == uiBlkAddr)
        {
            goto Exit;
        }

        // The ref count is used for pinning the block.

        if (m_CacheBlks[uiPos].pBlk &&
                m_CacheBlks[uiPos].pBlk->getRefCount() == 1 &&
                uiLRUValue > m_CacheBlks[uiPos].uiLRUValue)
        {
            uiLRUValue = m_CacheBlks[uiPos].uiLRUValue;
            uiLRUPos = uiPos;
        }

        // There better not be a hole by this point.

        flmAssert( m_CacheBlks[uiPos].pBlk != NULL);
    }
    uiPos = uiLRUPos;

    // Read from disk?

    flmAssert( m_pFileHdl != NULL);

    if (RC_BAD( rc = newCacheBlk( uiPos, &pNewBlk, eBlkType)))
    {
        goto Exit;
    }

    // Pick the LRU block and make that object do the reading
    // so it can reset all internals and get used to being a different blk.

    pNewBlk->blkAddr( uiBlkAddr);
    m_CacheBlks[uiPos].uiBlkAddr = uiBlkAddr;
    m_CacheBlks[uiPos].uiLRUValue = m_uiLRUCount++;

    if (RC_BAD( rc = pNewBlk->readBlk( m_pFileHdl, uiBlkAddr)))
    {

        // Release the block because the reset() changed the object type.
        // May hit the assert above.

        m_CacheBlks[uiPos].pBlk->Release();
        m_CacheBlks[uiPos].pBlk = NULL;
        goto Exit;
    }

Exit:

    if (RC_OK(rc))
    {
        *ppBlk = m_CacheBlks[uiPos].pBlk;
        m_CacheBlks[uiPos].uiLRUValue = m_uiLRUCount++;
    }
    return( rc);
}
/****************************************************************************
Desc:	Insert the entry into the btree - should be positioned
****************************************************************************/
RCODE F_BtreeRoot::insert(
    void *			pvEntry)
{
    RCODE				rc = NE_FLM_OK;
    FLMUINT			uiCurLevel;
    FLMBYTE			ucEntryBuf[FBTREE_MAX_LEVELS][DYNSSET_MAX_FIXED_ENTRY_SIZE];
    FLMUINT			uiNewBlkAddr;

    if (RC_OK( rc = m_BTStack[0]->insert( pvEntry)))
    {
        goto Exit;
    }

    // Failed to input at the left level.  Do block split(s).
    // This is an iterative and NOT a recursive split algorithm.
    // The debugging, and cases to test should be lots easier this way.

    f_memcpy( ucEntryBuf[0], pvEntry, m_uiEntrySize);
    uiCurLevel = 0;
    uiNewBlkAddr = FBTREE_END;
    for(;;)
    {

        // Split while adding the element.

        if (RC_BAD( rc = (m_BTStack[uiCurLevel])->split(
                             this,
                             ucEntryBuf[ uiCurLevel],
                             uiNewBlkAddr,
                             ucEntryBuf[ uiCurLevel+1],
                             &uiNewBlkAddr)))
        {
            goto Exit;
        }

        uiCurLevel++;
        flmAssert( uiCurLevel < m_uiLevels);

        if (RC_OK( rc = m_BTStack[uiCurLevel]->insertEntry(
                            ucEntryBuf[uiCurLevel], uiNewBlkAddr)))
        {
            goto Exit;
        }

        // Only returns NE_FLM_OK or FAILURE.

        // Root split?

        if (uiCurLevel + 1 == m_uiLevels)
        {
            flmAssert( m_uiLevels + 1 <= FBTREE_MAX_LEVELS);
            if (m_uiLevels + 1 > FBTREE_MAX_LEVELS)
            {
                rc = RC_SET( NE_FLM_BTREE_FULL);
                goto Exit;
            }

            // Need to split the root block.
            rc = ((F_BtreeRoot *)m_BTStack[uiCurLevel])->split(
                     ucEntryBuf[uiCurLevel], uiNewBlkAddr );
            break;
        }
    }

Exit:

    if (RC_OK(rc))
    {
        m_uiTotalEntries++;
    }
    return( rc);
}