示例#1
0
/****************************************************************************
Desc : Return the status of the index (via C/S protocol)
****************************************************************************/
FSTATIC RCODE flmIndexStatusCS(
	FDB *					pDb,
	FLMUINT				uiIndexNum,
	FINDEX_STATUS *	pIndexStatus)
{
	RCODE					rc = FERR_OK;
	CS_CONTEXT *		pCSContext = pDb->pCSContext;
	FCL_WIRE				Wire( pCSContext, pDb);
	void *				pvMark = pCSContext->pool.poolMark();

	// Set the temporary pool

	Wire.setPool( &pCSContext->pool);

	// Send a request to do the update

	if (RC_BAD( rc = Wire.sendOp( FCS_OPCLASS_INDEX, 
		FCS_OP_INDEX_GET_STATUS)))
	{
		goto Exit;
	}

	if (RC_BAD( rc = Wire.sendNumber( WIRE_VALUE_INDEX_ID, uiIndexNum)))
	{
		goto Transmission_Error;
	}

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

	// Read the response

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

	if (RC_BAD( rc = Wire.getRCode()))
	{
		goto Exit;
	}

	if( RC_BAD( rc = fcsExtractIndexStatus( Wire.getHTD(), pIndexStatus)))
	{
		goto Exit;
	}

Exit:

	pCSContext->pool.poolReset( pvMark);
	return( rc);

Transmission_Error:
	pCSContext->bConnectionGood = FALSE;
	goto Exit;
}
示例#2
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);
}
示例#3
0
void CWorkspaceViewsDialog::CreateWidgets()
{
	static const QStringList header_labels = QStringList() << tr( "Name" ) << tr( "Type" ) << tr( "Value" );

	const std::string wname = mModel.RootWorkspace()->GetName();

	//	Create

	//	... Tree

	mViewsListWidget = new QListWidget( this );
	mViewsListWidget->setSelectionBehavior( QAbstractItemView::SelectRows );
	mViewsListWidget->setSelectionMode( QAbstractItemView::SingleSelection );
	mViewsListWidget->setSizePolicy( QSizePolicy::Expanding, QSizePolicy::MinimumExpanding );

	mMapsAsPlotsCheckBox = new QCheckBox( "Display maps as 3D plots" );


	//	... Help

	auto help = new CTextWidget;
	help->SetHelpProperties( "All views generated by the operations of workspace " + t2q( wname ), 0, 6, Qt::AlignCenter );
    auto help_group = CreateGroupBox( ELayoutType::Grid, { help }, "", nullptr, 6, 6, 6, 6, 6 );
    help_group->setSizePolicy( QSizePolicy::Expanding, QSizePolicy::Maximum );


	//	... Buttons

	mButtonBox = new QDialogButtonBox( this );
	mButtonBox->setObjectName( QString::fromUtf8( "mButtonBox" ) );
	mButtonBox->setOrientation( Qt::Horizontal );
	mButtonBox->setStandardButtons( QDialogButtonBox::Open | QDialogButtonBox::Cancel );
    mButtonBox->button( QDialogButtonBox::Open )->setDefault( true );


    QBoxLayout *main_l =
            LayoutWidgets( Qt::Vertical,
                            {
                                mViewsListWidget,
								mMapsAsPlotsCheckBox,
								help_group,
                                mButtonBox

                            }, this, 6, 6, 6, 6, 6 );                       Q_UNUSED( main_l );


    setWindowTitle( "Workspace Views - " + t2q( wname ) );

    //	Wrap up dimensions

    adjustSize();
	setMinimumWidth( width() );

	Wire();
}
void  CDataDisplayPropertiesDialog::CreateWidgets()
{
    //	Vector fields

    mNorthComponent = new QRadioButton( "North Component" );
    mEastComponent = new QRadioButton( "East Component" );
    mVectorBox = CreateGroupBox( ELayoutType::Vertical,
    {
        mNorthComponent,
        mEastComponent
    },
    "Vector Plot Component", nullptr );
    mVectorBox->setCheckable(true);
    mVectorBox->setChecked(false);


    //	... Help

    auto help = new CTextWidget;
    QString name = t2q( mFormula->GetName() );
    help->SetHelpProperties(
                "Edit the expression '" + name + "' display properties.\n"
                "Vector box is available only if a map operation has more than 1 data field.",
        0 , 6 );
    auto help_group = CreateGroupBox( ELayoutType::Grid, { help }, "", nullptr, 6, 6, 6, 6, 6 );
    help_group->setSizePolicy( QSizePolicy::Expanding, QSizePolicy::Maximum );

    //	... Buttons

    mButtonBox = new QDialogButtonBox( this );
    mButtonBox->setObjectName( QString::fromUtf8( "mButtonBox" ) );
    mButtonBox->setOrientation( Qt::Horizontal );
    mButtonBox->setStandardButtons( QDialogButtonBox::Ok | QDialogButtonBox::Cancel );
    mButtonBox->button( QDialogButtonBox::Ok )->setDefault( true );

	QBoxLayout *main_l =
		LayoutWidgets( Qt::Vertical,
		{
			mVectorBox,
			WidgetLine( this, Qt::Horizontal ),
			help_group,
			WidgetLine( this, Qt::Horizontal ),
			mButtonBox

		}, this, 6, 6, 6, 6, 6 );                       Q_UNUSED( main_l );


    //	Wrap up dimensions

    adjustSize();
    setMinimumWidth( width() );

    Wire();
}
示例#5
0
CurveHermite::CurveHermite(const Point& p1, const Point& p4, const Point& r1, const Point& r4, double precision,
                           int red, int green, int blue) : Curve(red, green, blue),
                           p1(p1), p4(p4), r1(r1), r4(r4), precision(precision)
{
    QList<Point> curvePoints;
    double increment = 1.0 / precision;

    for (double t = 0.0; t <= 1.0; t += increment) {
        curvePoints.append(Point(this->calculateCoordinate(t, this->p1.getX(), this->p4.getX(), this->r1.getX(), this->r4.getX()),
                                 this->calculateCoordinate(t, this->p1.getY(), this->p4.getY(), this->r1.getY(), this->r4.getY())));
    }

    for (int i = 0; i < (curvePoints.size() - 1); i++) {
        this->wires.append(Wire(curvePoints[i], curvePoints[i + 1],
                                red, green, blue));
    }

    this->wires.append(Wire(curvePoints[curvePoints.size() - 1], p4, red, green, blue));
    this->defineString();
    this->buildXmlRepresentation();
}
示例#6
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);
}
示例#7
0
void CActiveViewsDialog::CreateWidgets()
{
	static const QStringList header_labels = QStringList() << tr( "Name" ) << tr( "Type" ) << tr( "Value" );

	//	Create

	//	... Tree

	mViewsListWidget = new QListWidget( this );
	mViewsListWidget->setSelectionBehavior( QAbstractItemView::SelectRows );
	mViewsListWidget->setSelectionMode( QAbstractItemView::SingleSelection );
	mViewsListWidget->setSizePolicy( QSizePolicy::Expanding, QSizePolicy::MinimumExpanding );

	//	... Help

	auto help = new CTextWidget;
	help->SetHelpProperties( "Select a view from all view windows currently opened", 0, 6, Qt::AlignCenter );
    auto help_group = CreateGroupBox( ELayoutType::Grid, { help }, "", nullptr, 6, 6, 6, 6, 6 );
    help_group->setSizePolicy( QSizePolicy::Expanding, QSizePolicy::Maximum );


	//	... Buttons

	mCloseDialogButton = new QPushButton( "Done", this );
	mCloseWindowButton = new QPushButton( "Close", this );
	mSelectWindowButton = new QPushButton( "Select", this );

	auto *buttons = LayoutWidgets( Qt::Horizontal, { mSelectWindowButton, mCloseWindowButton, nullptr, mCloseDialogButton }, nullptr, 2, 2, 2, 2, 2 );

    QBoxLayout *main_l =
            LayoutWidgets( Qt::Vertical,
                            {
                                mViewsListWidget,
								help_group,
                                buttons

                            }, this, 6, 6, 6, 6, 6 );                       Q_UNUSED( main_l );


    setWindowTitle( "Active Views" );

    //	Wrap up dimensions

    adjustSize();
	setMinimumWidth( width() );

	Wire();
}
示例#8
0
void AddObjeto::handleAddWire()
{
    Point start(this->ui->wireframeXIni->text().toDouble(), this->ui->wireframeYIni->text().toDouble(), this->ui->wireframeZIni->text().toDouble());
    Point end(this->ui->wireframeXFinal->text().toDouble(), this->ui->wireframeYFinal->text().toDouble(), this->ui->wireframeZFinal->text().toDouble());

    this->wireframe_wires.append(Wire(start, end));

    this->ui->wireframeXIni->setText(this->ui->wireframeXFinal->text());
    this->ui->wireframeYIni->setText(this->ui->wireframeYFinal->text());
    this->ui->wireframeZIni->setText(this->ui->wireframeZFinal->text());

    this->ui->wireframeXFinal->clear();
    this->ui->wireframeYFinal->clear();
    this->ui->wireframeZFinal->clear();

    this->ui->arestasAdcionadas->insertItem(this->ui->arestasAdcionadas->count(),
                                            QString("[") + start.toString() + QString("] to [") + end.toString() + QString("]"));
}
示例#9
0
void  CEditTasksFileDialog::CreateWidgets()
{
    //	Text

	mTextEdit = new CTextWidget;
	mTextEdit->SetSizeHint( mTextEdit->sizeHint().width(), 2 * mTextEdit->sizeHint().height() );
	auto *content_l = LayoutWidgets( Qt::Vertical, { mTextEdit }, nullptr, 2, 2, 2, 2, 2 );


    //	... Help

    auto help = new CTextWidget;
	std::string help_str = mTaskName.empty() ? "Scheduled tasks configuration file." : mTaskName + " log file content.";
    help->SetHelpProperties( help_str.c_str(), 0 , 6 );
    auto help_group = CreateGroupBox( ELayoutType::Grid, { help }, "", nullptr, 6, 6, 6, 6, 6 );
    help_group->setSizePolicy( QSizePolicy::Expanding, QSizePolicy::Maximum );


    //	... Buttons

    mButtonBox = new QDialogButtonBox( this );
    mButtonBox->setObjectName( QString::fromUtf8( "mButtonBox" ) );
    mButtonBox->setOrientation( Qt::Horizontal );
    mButtonBox->setStandardButtons( QDialogButtonBox::Close );
    mButtonBox->button( QDialogButtonBox::Close )->setDefault( true );

    QBoxLayout *main_l =
            LayoutWidgets( Qt::Vertical,
                            {
								content_l,
								WidgetLine( nullptr, Qt::Horizontal ),
                                help_group,
                                mButtonBox

                            }, this, 6, 6, 6, 6, 6 );                       Q_UNUSED( main_l );


    //	Wrap up dimensions

    adjustSize();
    setMinimumWidth( width() );

   Wire();
}
示例#10
0
void LoginDialog::Create()
{
	// set up the layout
	QGridLayout *formGridLayout = new QGridLayout( this );

	mUserNameCombo = new QComboBox( this );
	mUserNameCombo->setEditable( true );

	// don't echo passwords
	mPasswordEdit = new QLineEdit( this );
	mPasswordEdit->setEchoMode( QLineEdit::Password );

	mUserNameLabel = new QLabel( this );
	mPasswordLabel = new QLabel( this );
	mUserNameLabel->setText( tr( "Username" ) );
	mUserNameLabel->setBuddy( mUserNameCombo );
	mPasswordLabel->setText( tr( "Password" ) );
	mPasswordLabel->setBuddy( mPasswordEdit );

	mButtons = new QDialogButtonBox( this );
	mButtons->addButton( QDialogButtonBox::Ok );
	mButtons->addButton( QDialogButtonBox::Cancel );
	mButtons->button( QDialogButtonBox::Ok )->setText( tr("Install") );
	mButtons->button( QDialogButtonBox::Cancel )->setText( tr("Abort") );

	//layout

	formGridLayout->addWidget( mUserNameLabel, 0, 0 );
	formGridLayout->addWidget( mUserNameCombo, 0, 1 );
	formGridLayout->addWidget( mPasswordLabel, 1, 0 );
	formGridLayout->addWidget( mPasswordEdit, 1, 1 );
	formGridLayout->addWidget( mButtons, 2, 0, 1, 2 );

	setLayout( formGridLayout );

	Wire();
}
示例#11
0
void CExportImageDialog::CreateWidgets( bool enable2D, bool enable3D )
{
    // Output type

	mExtensionCombo = new QComboBox;
    m2DCheck = new QCheckBox( "2D" );
    m3DCheck = new QCheckBox( "3D" );
    auto *output_type_group = CreateGroupBox( ELayoutType::Horizontal, { mExtensionCombo, nullptr, m2DCheck, m3DCheck }, "Image and File Type", nullptr, 6, 6, 6, 6, 6 );


    // Output file

    mOutputPathLineEdit2D = new QLineEdit();
    mOutputPathLineEdit2D->setReadOnly( true );
    mBrowseButton2D = new QPushButton( "Browse..." );
    mOutputPathLineEdit3D = new QLineEdit();
    mOutputPathLineEdit3D->setReadOnly( true );
    mBrowseButton3D = new QPushButton( "Browse..." );
	mBrowseButton2D->setToolTip( CActionInfo::FormatTip( "Select output file name and location." ).c_str() );
	mBrowseButton3D->setToolTip( CActionInfo::FormatTip( "Select output file name and location." ).c_str() );

    mOutputFileGroup2D = CreateGroupBox( ELayoutType::Horizontal, { mOutputPathLineEdit2D, mBrowseButton2D }, "2D Output File", nullptr, 6, 6, 6, 6, 6 );
    mOutputFileGroup3D = CreateGroupBox( ELayoutType::Horizontal, { mOutputPathLineEdit3D, mBrowseButton3D }, "3D Output File", nullptr, 6, 6, 6, 6, 6 );


    // Help

    auto help = new CTextWidget;
    help->SetHelpProperties( 
		"Select a file name and location. The extension will\n"
		"automatically be assigned according to the chosen image type."
         ,0 , 6, Qt::AlignCenter );
    auto help_group = CreateGroupBox( ELayoutType::Grid, { help }, "", nullptr, 6, 6, 6, 6, 6 );
    help_group->setSizePolicy( QSizePolicy::MinimumExpanding, QSizePolicy::Maximum );


    //	Buttons (Execute, Delay Execution, Cancel)

    mButtonBox = new QDialogButtonBox();
    mButtonBox->setObjectName( QString::fromUtf8( "mButtonBox" ) );
    mButtonBox->setOrientation( Qt::Horizontal );
    mButtonBox->setStandardButtons( QDialogButtonBox::Save | QDialogButtonBox::Cancel );    
	mSaveButton = mButtonBox->button( QDialogButtonBox::Save );
    mSaveButton->setDefault( false );

	mOutputFileGroup2D->setStyleSheet("QGroupBox { font-weight: bold; } ");
	mOutputFileGroup3D->setStyleSheet("QGroupBox { font-weight: bold; } ");
	output_type_group->setStyleSheet("QGroupBox { font-weight: bold; } ");


    //	All

    QBoxLayout *main_l =
            LayoutWidgets( Qt::Vertical,
                            {
								output_type_group,
                                mOutputFileGroup2D,
                                mOutputFileGroup3D,
								nullptr,
                                help_group,
                                mButtonBox

                            }, this, 6, 6, 6, 6, 6 );                       Q_UNUSED( main_l );


    Wire( enable2D, enable3D );
}
示例#12
0
/****************************************************************************
Desc : If the index was suspended, restart the background process that
		 will get the index up to date so that it will eventually be online.
		 Returns FERR_OK with no change if the index is already online.
Notes: An update transaction will be started if necessary.
****************************************************************************/
FLMEXP RCODE FLMAPI FlmIndexResume(
	HFDB			hDb,
	FLMUINT		uiIndexNum)
{
	RCODE				rc = FERR_OK;
	FDB *				pDb = (FDB *)hDb;
	IXD *				pIxd;
	FLMUINT 			uiLastContainerIndexed;
	FLMUINT 			uiLastDrnIndexed;
	FLMUINT 			uiOnlineTransId;
	FLMBOOL			bStartedTrans = FALSE;

	if( IsInCSMode( hDb))
	{
		fdbInitCS( pDb);

		CS_CONTEXT *		pCSContext = pDb->pCSContext;
		FCL_WIRE				Wire( pCSContext, pDb);

		if( !pCSContext->bConnectionGood)
		{
			rc = RC_SET( FERR_BAD_SERVER_CONNECTION);
			goto Transmission_Error;
		}

		if( RC_BAD( rc = Wire.sendOp(
			FCS_OPCLASS_INDEX, FCS_OP_INDEX_RESUME)))
		{
			goto Exit;
		}

		if (RC_BAD( rc = Wire.sendNumber( WIRE_VALUE_INDEX_ID, uiIndexNum)))
		{
			goto Transmission_Error;
		}

		// Send the "auto-online" flag (only needed for 
		// backwards compatibility)
		
		if (RC_BAD( rc = Wire.sendNumber( WIRE_VALUE_BOOLEAN, 1)))
		{
			goto Transmission_Error;
		}

		// Send a priority of high (only needed for
		// backwards compatibility)

		if (RC_BAD( rc = Wire.sendNumber( WIRE_VALUE_NUMBER1, 1)))
		{
			goto Transmission_Error;
		}

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

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

		if( RC_BAD( rc = Wire.getRCode()))
		{
			goto Exit;
		}

		goto Exit;

Transmission_Error:
		pCSContext->bConnectionGood = FALSE;
		goto Exit;
	}

	if (RC_BAD( rc = fdbInit( pDb, FLM_UPDATE_TRANS,
		FDB_TRANS_GOING_OK, FLM_AUTO_TRANS | FLM_NO_TIMEOUT, &bStartedTrans)))
	{
		goto Exit;
	}

	// See if the index is valid

	if( RC_BAD( rc = fdictGetIndex(
		pDb->pDict,
		pDb->pFile->bInLimitedMode,
		uiIndexNum, NULL, &pIxd, TRUE)))
	{
		goto Exit;
	}

	if( pIxd->uiFlags & IXD_UNIQUE)
	{
		// Can't suspend or resume unique indexes

		flmAssert( !(pIxd->uiFlags & (IXD_SUSPENDED | IXD_OFFLINE)));
		rc = RC_SET( FERR_ILLEGAL_OP);
		goto Exit;
	}

	if( !(pIxd->uiFlags & (IXD_SUSPENDED | IXD_OFFLINE)))
	{
		// Index is already on-line

		goto Exit;
	}

	// If we're in limited mode and this is an encrypted index,
	// it can't be resumed
	if (pDb->pFile->bInLimitedMode && pIxd->uiEncId)
	{
		rc = RC_SET( FERR_ENCRYPTION_UNAVAILABLE);
		goto Exit;
	}

	if( !(pIxd->uiFlags & IXD_SUSPENDED))
	{
		// Index is not suspended.  It is offline (see test
		// above), but a thread should already be building the 
		// index, or it better be in the start list.

#ifdef FLM_DEBUG
		if (flmBackgroundIndexGet( pDb->pFile, 
				uiIndexNum, FALSE) == NULL)
		{
			F_BKGND_IX *	pBackgroundIx;

			for( pBackgroundIx = pDb->pIxStartList;
					pBackgroundIx;
					pBackgroundIx = pBackgroundIx->pNext)
			{
				if( pBackgroundIx->indexStatus.uiIndexNum == uiIndexNum)
				{
					break;
				}
			}
			flmAssert( pBackgroundIx);
		}
#endif

		goto Exit;
	}

	// Better not have a background thread running, or it better be
	// in the stop list - because its state shows suspended.

#ifdef FLM_DEBUG
	if (flmBackgroundIndexGet( pDb->pFile, uiIndexNum, FALSE) != NULL)
	{
		F_BKGND_IX *	pBackgroundIx;

		for( pBackgroundIx = pDb->pIxStopList;
				pBackgroundIx;
				pBackgroundIx = pBackgroundIx->pNext)
		{
			if( pBackgroundIx->indexStatus.uiIndexNum == uiIndexNum)
			{
				break;
			}
		}
		flmAssert( pBackgroundIx);
	}
#endif

	// Get the tracker info

	if( RC_BAD( rc = flmGetIxTrackerInfo( pDb, uiIndexNum, 
		&uiLastContainerIndexed, &uiLastDrnIndexed, &uiOnlineTransId,
		NULL)))
	{
		goto Exit;
	}

	// Update the tracker info so that the index state will
	// be changed to "unsuspended."

	if( RC_BAD( rc = flmSetIxTrackerInfo( pDb, uiIndexNum, 
		uiLastContainerIndexed, uiLastDrnIndexed, 
		uiOnlineTransId, FALSE)))
	{
		goto Exit;
	}

	// Add an entry to the start list so that an indexing thread
	// will be started when this transaction commits.

	if( !(pDb->uiFlags & FDB_REPLAYING_RFL))
	{
		if( RC_BAD( rc = flmAddToStartList( pDb, uiIndexNum)))
		{
			goto Exit;
		}
	}

	// Create a new dictionary.

	if( !(pDb->uiFlags & FDB_UPDATED_DICTIONARY))
	{
		if( RC_BAD( rc = fdictCloneDict( pDb)))
		{
			goto Exit;
		}

		// Get a pointer to the new IXD

		if( RC_BAD( rc = fdictGetIndex(
			pDb->pDict,
			pDb->pFile->bInLimitedMode,
			uiIndexNum, NULL, &pIxd, TRUE)))
		{
			goto Exit;
		}
	}

	// Update the IXDs flags so that the current update
	// transaction will see the correct state of the index.
	// Old read transactions will continue to use a prior
	// version of the dictionary.

	pIxd->uiFlags &= ~IXD_SUSPENDED;
	pIxd->uiFlags |= IXD_OFFLINE;

	// Log the resume packet to the RFL

	if( RC_BAD( rc = pDb->pFile->pRfl->logIndexSuspendOrResume( 
		uiIndexNum, RFL_INDEX_RESUME_PACKET)))
	{
		goto Exit;
	}

Exit:

	if( bStartedTrans)
	{
		rc = flmEndAutoTrans( pDb, rc);
	}

	flmExit( FLM_INDEX_RESUME, pDb, rc);
	return( rc);
}
示例#13
0
/****************************************************************************
Desc : Suspend the selected index from doing any key updates on records
		 that are equal or higher than the next record ID value
		 in the container that the index references.  If the index is offline
		 then the background process will be suspended.  If the index is
		 online then it will be suspended.  If the index is already 
		 suspended FERR_OK will be returned.  A suspended index is not
		 persistant if the database goes down.  
Notes: An update transaction will be started if necessary.
****************************************************************************/
FLMEXP RCODE FLMAPI FlmIndexSuspend(
	HFDB			hDb,
	FLMUINT		uiIndexNum)
{
	RCODE			rc = FERR_OK;
	FDB *			pDb = (FDB *)hDb;
	IXD *			pIxd;
	FLMUINT		uiHighestRecId;
	FLMUINT		uiContainerNum;
	FLMBOOL		bSuspended;
	FLMBOOL		bStartedTrans = FALSE;
	LFILE *		pLFile;

	if( IsInCSMode( hDb))
	{
		fdbInitCS( pDb);

		CS_CONTEXT *		pCSContext = pDb->pCSContext;
		FCL_WIRE				Wire( pCSContext, pDb);

		if( !pCSContext->bConnectionGood)
		{
			rc = RC_SET( FERR_BAD_SERVER_CONNECTION);
			goto Transmission_Error;
		}

		if( RC_BAD( rc = Wire.sendOp(
			FCS_OPCLASS_INDEX, FCS_OP_INDEX_SUSPEND)))
		{
			goto Exit;
		}

		if (RC_BAD( rc = Wire.sendNumber( WIRE_VALUE_INDEX_ID, uiIndexNum)))
		{
			goto Transmission_Error;
		}

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

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

		if( RC_BAD( rc = Wire.getRCode()))
		{
			goto Exit;
		}

		goto Exit;

Transmission_Error:
		pCSContext->bConnectionGood = FALSE;
		goto Exit;
	}

	if (RC_BAD( rc = fdbInit( pDb, FLM_UPDATE_TRANS,
		FDB_TRANS_GOING_OK, FLM_AUTO_TRANS | FLM_NO_TIMEOUT, &bStartedTrans)))
	{
		goto Exit;
	}

	// See if the index is valid

	if( RC_BAD( rc = fdictGetIndex(
		pDb->pDict,
		pDb->pFile->bInLimitedMode,
		uiIndexNum, NULL, &pIxd, TRUE)))
	{
		goto Exit;
	}

	if( pIxd->uiFlags & IXD_UNIQUE)
	{
		// Can't suspend unique indexes
		rc = RC_SET( FERR_ILLEGAL_OP);
		goto Exit;
	}

	if( pIxd->uiFlags & IXD_SUSPENDED)
	{
		// Index is already suspended.
		goto Exit;
	}

	// Get the current index info from the tracker

	if( RC_BAD( rc = flmGetIxTrackerInfo( pDb,
		uiIndexNum, &uiContainerNum, &uiHighestRecId, NULL, &bSuspended)))
	{
		goto Exit;
	}
	flmAssert( !bSuspended);

	// Get information about the container(s) being indexed

	if( !(pIxd->uiFlags & IXD_OFFLINE))
	{
		if ((uiContainerNum = pIxd->uiContainerNum) == 0)
		{
			// The index was on-line and up-to-date.  For an index that
			// crosses all containers, we will suspend on the highest DRN of
			// the FLM_DATA_CONTAINER.

			uiContainerNum = FLM_DATA_CONTAINER;
		}

		if( RC_BAD( rc = fdictGetContainer( pDb->pDict, 
			uiContainerNum, &pLFile)))
		{
			goto Exit;
		}

		uiHighestRecId = 0;
		if( RC_BAD( rc = FSGetNextDrn( pDb, pLFile, FALSE, &uiHighestRecId)))
		{
			goto Exit;
		}

		// Decrement uiHighestRecId by 1 to correctly reflect the
		// last record that was indexed.

		flmAssert( uiHighestRecId != 0);
		uiHighestRecId--;
	}

	// There may be a background thread still assigned to the
	// index even though the index may be "on-line."  This is because
	// the background thread may have just commited a transaction that
	// transitioned the index from off-line to on-line, but the thread
	// has not yet exited (even though it will not do any more work
	// to update the index).  We want to wait for the thread to terminate
	// before our transaction is allowed to commit.  This is so that if
	// we immediately call resume, it won't find the yet-to-terminate
	// thread still running in the background.

	if( !(pDb->uiFlags & FDB_REPLAYING_RFL))
	{
		if( RC_BAD( rc = flmAddToStopList( pDb, uiIndexNum)))
		{
			goto Exit;
		}
	}

	flmAssert( uiContainerNum != 0xFFFFFFFF);

	if( RC_BAD( rc = flmSetIxTrackerInfo( pDb, 
		uiIndexNum, uiContainerNum, uiHighestRecId, 
		TRANS_ID_OFFLINE, TRUE)))
	{
		goto Exit;
	}

	// Create a new dictionary

	if( !(pDb->uiFlags & FDB_UPDATED_DICTIONARY))
	{
		if( RC_BAD( rc = fdictCloneDict( pDb)))
		{
			goto Exit;
		}

		// Get a pointer to the new IXD

		if( RC_BAD( rc = fdictGetIndex( pDb->pDict,
			pDb->pFile->bInLimitedMode,
			uiIndexNum, NULL, &pIxd, TRUE)))
		{
			goto Exit;
		}
	}

	// Update the IXDs flags so that the current update
	// transaction will see the correct state of the index.
	// Old read transactions will continue to use a prior
	// version of the dictionary.

	pIxd->uiFlags |= (IXD_SUSPENDED | IXD_OFFLINE);

	// Log the suspend packet to the RFL

	if( RC_BAD( rc = pDb->pFile->pRfl->logIndexSuspendOrResume( 
		uiIndexNum, RFL_INDEX_SUSPEND_PACKET)))
	{
		goto Exit;
	}

Exit:

	if( bStartedTrans)
	{
		rc = flmEndAutoTrans( pDb, rc);
	}

	flmExit( FLM_INDEX_SUSPEND, pDb, rc);
	return( rc);
}
示例#14
0
 void runTest() {
   CPPUNIT_ASSERT( Wire (10, 1) == Wire (10, 1) );
   CPPUNIT_ASSERT( !(Wire (1, 1) == Wire (2, 2)) );
   }
示例#15
0
/****************************************************************************
Desc : Return the number of the next index.  Pass in zero to get the
		 first index.
****************************************************************************/
FLMEXP RCODE FLMAPI FlmIndexGetNext(
	HFDB			hDb,
	FLMUINT *	puiIndexNum)
{
	RCODE			rc = FERR_OK;
	FDB *			pDb = (FDB *)hDb;
	FLMBOOL		bStartedAutoTrans = FALSE;
	IXD *			pIxd;

	flmAssert( puiIndexNum != NULL);

	if( IsInCSMode( hDb))
	{
		fdbInitCS( pDb);

		CS_CONTEXT *		pCSContext = pDb->pCSContext;
		FCL_WIRE				Wire( pCSContext, pDb);

		if( !pCSContext->bConnectionGood)
		{
			rc = RC_SET( FERR_BAD_SERVER_CONNECTION);
			goto Transmission_Error;
		}

		if( RC_BAD( rc = Wire.sendOp(
			FCS_OPCLASS_INDEX, FCS_OP_INDEX_GET_NEXT)))
		{
			goto Exit;
		}

		if (RC_BAD( rc = Wire.sendNumber( WIRE_VALUE_INDEX_ID, *puiIndexNum)))
		{
			goto Transmission_Error;
		}

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

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

		if( RC_BAD( rc = Wire.getRCode()))
		{
			goto Exit;
		}

		*puiIndexNum = Wire.getIndexId();
		goto Exit;

Transmission_Error:
		pCSContext->bConnectionGood = FALSE;
		goto Exit;
	}

	if( RC_BAD( rc = fdbInit( (FDB *)hDb, FLM_READ_TRANS,
							FDB_TRANS_GOING_OK, 0, &bStartedAutoTrans)))
	{
		goto Exit;
	}
	(void) fdictGetNextIXD( pDb->pDict, *puiIndexNum, &pIxd);
	if( pIxd && pIxd->uiIndexNum < FLM_RESERVED_TAG_NUMS)
	{
		*puiIndexNum = pIxd->uiIndexNum;
	}
	else
	{
		rc = RC_SET( FERR_EOF_HIT);
	}

Exit:

	if( bStartedAutoTrans)
	{
		rc = flmEndAutoTrans( pDb, rc);
	}
	flmExit( FLM_INDEX_GET_NEXT, pDb, rc);

	return( rc);
}
示例#16
0
/****************************************************************************
Desc : Returns the type of the current database transaction.
****************************************************************************/
FLMEXP RCODE FLMAPI FlmDbGetTransType(
	HFDB			hDb,
	FLMUINT *	puiTransTypeRV)
{
	RCODE		   rc = FERR_OK;
	FDB *			pDb = (FDB *)hDb;

	if (IsInCSMode( hDb))
	{
		fdbInitCS( pDb);

		CS_CONTEXT *	pCSContext = pDb->pCSContext;
		FCL_WIRE			Wire( pDb->pCSContext, pDb);

		// Send a request to get the transaction type.

		if( RC_BAD( rc = Wire.sendOp( 
			FCS_OPCLASS_TRANS, FCS_OP_TRANSACTION_GET_TYPE)))
		{
			goto Exit;
		}

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

		// Read the response.
	
		if (RC_BAD( rc = Wire.read()))
		{
			goto Transmission_Error;
		}
		
		*puiTransTypeRV = Wire.getTransType();
		rc = Wire.getRCode();
		goto Exit;

Transmission_Error:

		pCSContext->bConnectionGood = FALSE;
		goto Exit;
	}

	if (!pDb)
	{
		rc = RC_SET( FERR_BAD_HDL);
		goto Exit;
	}

	fdbUseCheck( pDb);
	pDb->uiInitNestLevel++;
	(void)flmResetDiag( pDb);

	// If the transaction is an internal transaction that is invisible to
	// the application, return FLM_NO_TRANS.  Application is not supposed
	// see invisible transactions.

	*puiTransTypeRV = (FLMUINT)(((pDb->uiTransType == FLM_NO_TRANS) ||
										  (pDb->uiFlags & FDB_INVISIBLE_TRANS))
										  			? (FLMUINT)FLM_NO_TRANS
													: pDb->uiTransType);

	// See if the database is being forced to close

	if( RC_BAD( rc = flmCheckDatabaseState( pDb)))
	{
		goto Exit;
	}

Exit:

	flmExit( FLM_DB_GET_TRANS_TYPE, pDb, rc);
	return( rc);
}
示例#17
0
/****************************************************************************
Desc:	Internal routine for doing updates via client/server
****************************************************************************/
FSTATIC RCODE flmDoUpdateCS(
	FDB *			pDb,
	FLMUINT		uiOp,
	FLMUINT		uiContainer,
	FLMUINT *	puiDrn,
	FlmRecord *	pRecord,
	FLMUINT		uiAutoTrans)
{
	RCODE		rc = FERR_OK;
	CS_CONTEXT *pCSContext = pDb->pCSContext;
	FCL_WIRE	Wire( pCSContext, pDb);
	
	// Send a request to do the update

	if (RC_BAD( rc = Wire.sendOp( FCS_OPCLASS_RECORD, uiOp)))
	{
		goto Exit;
	}

	if (uiContainer)
	{
		if (RC_BAD( rc = Wire.sendNumber( WIRE_VALUE_CONTAINER_ID, uiContainer)))
		{
			goto Transmission_Error;
		}
	}

	if (*puiDrn)
	{
		if (RC_BAD( rc = Wire.sendNumber( WIRE_VALUE_DRN, *puiDrn)))
		{
			goto Transmission_Error;
		}
	}

	if (pRecord)
	{
		if (RC_BAD( rc = Wire.sendRecord( WIRE_VALUE_RECORD, pRecord)))
		{
			goto Transmission_Error;
		}
	}

	if (uiAutoTrans)
	{
		if (RC_BAD( rc = Wire.sendNumber( WIRE_VALUE_AUTOTRANS, uiAutoTrans)))
		{
			goto Transmission_Error;
		}
	}

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

	// Read the response

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

	if (RC_BAD( rc = Wire.getRCode()))
	{
		goto Exit;
	}

	if (uiOp == FCS_OP_RECORD_ADD)
	{
		*puiDrn = Wire.getDrn();
	}

Exit:
	return( rc);

Transmission_Error:
	pCSContext->bConnectionGood = FALSE;
	goto Exit;
}
示例#18
0
Wire AddObjeto::getWire()
{
    Point start(this->ui->wireXIni_field->text().toDouble(), this->ui->wireYIni_field->text().toDouble(),   this->ui->wireZIni_field->text().toDouble());
    Point end(this->ui->wireXFinal_field->text().toDouble(), this->ui->wireYFinal_field->text().toDouble(), this->ui->wireZFinal_field->text().toDouble());
    return Wire(start, end, this->chosenObjectColor.red(), this->chosenObjectColor.green(), this->chosenObjectColor.blue());
}
示例#19
0
/****************************************************************************
Desc:		Returns the next DRN that record ADD would return.  The database
			must be in an existing update transaction.
****************************************************************************/
FLMEXP RCODE FLMAPI FlmReserveNextDrn(
	HFDB			hDb,
	FLMUINT		uiContainer,
	FLMUINT *	puiDrnRV)
{
	RCODE			rc;
	FDB *			pDb = (FDB *)hDb;
	LFILE *		pLFile;
	FLMBOOL		bIgnore;
	FLMUINT		uiDrn = 0;

	if (IsInCSMode( hDb))
	{
		fdbInitCS( pDb);

		CS_CONTEXT *	pCSContext = pDb->pCSContext;
		FCL_WIRE			Wire( pCSContext, pDb);

		// Send the request

		if( RC_BAD( rc = Wire.sendOp( 
			FCS_OPCLASS_RECORD, FCS_OP_RESERVE_NEXT_DRN)))
		{
			goto ExitCS;
		}

		if( uiContainer)
		{
			if (RC_BAD( rc = Wire.sendNumber(
				WIRE_VALUE_CONTAINER_ID, uiContainer)))
			{
				goto Transmission_Error;
			}
		}

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

		// Read the response

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

		if( RC_BAD( rc = Wire.getRCode()))
		{
			goto ExitCS;
		}

		*puiDrnRV = Wire.getDrn();
		goto ExitCS;

Transmission_Error:
		pCSContext->bConnectionGood = FALSE;
		goto ExitCS;
	}

	bIgnore = FALSE;					// Set to shut up compiler.

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

	if( pDb->uiFlags & FDB_COMMITTING_TRANS)
	{
		flmAssert( 0);
		rc = RC_SET( FERR_ILLEGAL_TRANS_OP);
		goto Exit;
	}

	if( RC_BAD( fdictGetContainer( pDb->pDict, uiContainer, &pLFile)))
	{
#ifdef FLM_DBG_LOG
		uiDrn = 0;
#endif
		goto Exit;
	}
	uiDrn = (FLMUINT) 0;					// Must initialize before call.
	if( RC_BAD( rc = FSGetNextDrn( pDb, pLFile, TRUE, &uiDrn)))
	{
#ifdef FLM_DBG_LOG
		uiDrn = 0;
#endif
		goto Exit;
	}

	*puiDrnRV = uiDrn;						// Set return value.

Exit:

	if (RC_OK( rc))
	{
		rc = pDb->pFile->pRfl->logUpdatePacket( 
			RFL_RESERVE_DRN_PACKET, uiContainer, *puiDrnRV, 0);
	}

	if( gv_FlmSysData.UpdateEvents.pEventCBList)
	{
		flmUpdEventCallback( pDb, F_EVENT_RESERVE_DRN, hDb, rc, *puiDrnRV,
								uiContainer, NULL, NULL);
	}

#ifdef FLM_DBG_LOG
	flmDbgLogUpdate( pDb->pFile->uiFFileId, pDb->LogHdr.uiCurrTransID,
			uiContainer, uiDrn, rc, "RDrn");
#endif

ExitCS:

	flmExit( FLM_RESERVE_NEXT_DRN, pDb, rc);

	return( rc);
}
示例#20
0
void Device::connectNeighbour(std::shared_ptr<Device> neighbour, int thisInterfaceId, int thisPortId, int neighbourInterfaceId, int neighbourPortId, bool isContinue) {
  networkInterfaces.at(thisInterfaceId).connectWire(Wire(neighbour, neighbourInterfaceId, neighbourPortId));
  if(isContinue) {
      neighbour->connectNeighbour(std::shared_ptr<Device>(this), neighbourInterfaceId, neighbourPortId, thisInterfaceId, thisPortId, false);
  }
}
示例#21
0
/****************************************************************************
Desc:	Starts a transaction.
****************************************************************************/
FLMEXP RCODE FLMAPI FlmDbTransBegin(
	HFDB			hDb,
	FLMUINT		uiTransType,
	FLMUINT		uiMaxLockWait,
	FLMBYTE *	pucHeader)
{
	RCODE			rc = FERR_OK;
	FLMBOOL		bIgnore;
	FLMUINT		uiFlags = FLM_GET_TRANS_FLAGS( uiTransType);
	FDB *			pDb = (FDB *)hDb;

	uiTransType = FLM_GET_TRANS_TYPE( uiTransType);

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

		if (!pDb->pCSContext->bConnectionGood)
		{
			rc = RC_SET( FERR_BAD_SERVER_CONNECTION);
		}
		else
		{
			if( RC_BAD( rc = Wire.doTransOp(
				FCS_OP_TRANSACTION_BEGIN, uiTransType, uiFlags,
				uiMaxLockWait, pucHeader)))
			{
				goto Exit;
			}
		}

		goto Exit;
	}

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

	// Verify the transaction type.

	if (( uiTransType != FLM_UPDATE_TRANS) &&
		 ( uiTransType != FLM_READ_TRANS))
	{
		rc = RC_SET( FERR_ILLEGAL_TRANS);
		goto Exit;
	}

	// Verify the transaction flags

	if( (uiFlags & FLM_DONT_KILL_TRANS) && uiTransType != FLM_READ_TRANS)
	{
		rc = RC_SET( FERR_ILLEGAL_TRANS);
		goto Exit;
	}

	// Can't start an update transaction on a database that
	// is locked in shared mode.

	if ((uiTransType == FLM_UPDATE_TRANS) &&
		 (pDb->uiFlags & FDB_FILE_LOCK_SHARED))
	{
		rc = RC_SET( FERR_PERMISSION);
		goto Exit;
	}

	// If the database has an invisible transaction going, abort it
	// before going any further - we don't want application transactions
	// to be nested under invisible transactions.  Application transactions
	// take precedence over invisible transactions.

	if ((pDb->uiTransType != FLM_NO_TRANS) &&
		 (pDb->uiFlags & FDB_INVISIBLE_TRANS))
	{
		if (RC_BAD( rc = flmAbortDbTrans( pDb)))
		{
			goto Exit;
		}
	}

	// If the database is not running a transaction, start one.
	// Otherwise, start a nested transaction - first verifying that
	// the transation type matches.

	if (pDb->uiTransType == FLM_NO_TRANS)
	{
		FLMUINT		uiBytesRead;

		if( pucHeader)
		{
			if( RC_BAD( rc = pDb->pSFileHdl->readBlock( 
				0, 2048, pucHeader, &uiBytesRead)))
			{
				goto Exit;
			}
		}

		if (RC_BAD( rc = flmBeginDbTrans( pDb, uiTransType, 
			uiMaxLockWait, uiFlags,
			pucHeader ? &pucHeader [16] : NULL)))
		{
			goto Exit;
		}
		pDb->bHadUpdOper = FALSE;
	}
	else
	{
		// Cannot nest transactions.

		rc = RC_SET( FERR_TRANS_ACTIVE);
		goto Exit;
	}

Exit:

	flmExit( FLM_DB_TRANS_BEGIN, pDb, rc);
	return( rc);
}
示例#22
0
/****************************************************************************
Desc:	Forces a checkpoint on the database.
****************************************************************************/
FLMEXP RCODE FLMAPI FlmDbCheckpoint(
	HFDB			hDb,
	FLMUINT		uiTimeout)
{
	RCODE			rc = FERR_OK;
	FDB *			pDb = (FDB *)hDb;
	FLMBOOL		bStartedTrans;

	bStartedTrans = FALSE;

	if (IsInCSMode( hDb))
	{
		fdbInitCS( pDb);

		CS_CONTEXT *		pCSContext = pDb->pCSContext;
		FCL_WIRE				Wire( pCSContext, pDb);

		if( !pCSContext->bConnectionGood)
		{
			rc = RC_SET( FERR_BAD_SERVER_CONNECTION);
			goto Transmission_Error;
		}

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

		if (RC_BAD( rc = Wire.sendNumber( WIRE_VALUE_FLAGS, uiTimeout)))
		{
			goto Transmission_Error;
		}

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

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

		if( RC_BAD( rc = Wire.getRCode()))
		{
			goto Exit;
		}

		goto Exit;

Transmission_Error:

		pCSContext->bConnectionGood = FALSE;
		goto Exit;
	}

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

	if (RC_BAD( rc = fdbInit( pDb, FLM_UPDATE_TRANS,
									  0, uiTimeout | FLM_AUTO_TRANS, &bStartedTrans)))
	{
		goto Exit;
	}

	// Commit the transaction, forcing it to be checkpointed.

	bStartedTrans = FALSE;
	pDb->bHadUpdOper = FALSE;
	if (RC_BAD( rc = flmCommitDbTrans( pDb, 0, TRUE)))
	{
		goto Exit;
	}
	
Exit:

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

	flmExit( FLM_DB_CHECKPOINT, pDb, rc);
	return( rc);
}
示例#23
0
/****************************************************************************
Desc: 	Retrieves the last commit sequence number of a database.
Notes: 	Whenever a transaction is committed, FLAIM increments the commit
		 	sequence number to indicate that the database has been modified.
			An application may use this routine to determine if the database
			has been modified.
****************************************************************************/
FLMEXP RCODE FLMAPI FlmDbGetCommitCnt(
	HFDB				hDb,
	FLMUINT *		puiCommitCount)
{
	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 commit count

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

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

		// Read the response.
	
		if (RC_BAD( rc = Wire.read()))
		{
			goto Transmission_Error;
		}
		*puiCommitCount = (FLMUINT)Wire.getCount();

		rc = Wire.getRCode();
		goto ExitCS;

Transmission_Error:

		pCSContext->bConnectionGood = FALSE;
		goto ExitCS;
	}

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

	// See if we have a transaction going which should be aborted.

	if (pDb->uiTransType != FLM_NO_TRANS)
	{
		if (flmCheckBadTrans( pDb))
		{
			rc = RC_SET( FERR_ABORT_TRANS);
			goto Exit;
		}
	}

	f_mutexLock( gv_FlmSysData.hShareMutex);
	*puiCommitCount = (FLMUINT)FB2UD(
			&pDb->pFile->ucLastCommittedLogHdr [LOG_COMMIT_COUNT]);
	f_mutexUnlock( gv_FlmSysData.hShareMutex);

Exit:
ExitCS:

	flmExit( FLM_DB_GET_COMMIT_CNT, pDb, rc);
	return( rc);
}