// Executes the select command and returns a reference to an IFeatureReader. // During execution an attempt is made to place a lock on each feature. If // there are conflicts the conflicts are reported and made available to the // user via a lock conflict reader. The user retrieves the lock conflict // reader when executing the function "GetLockConflicts()". // NOTE: The current implementation is a work-around due some timing issues as // explained: When using DBI to apply a lock on an object the lock is // actually applied only when the object is fetched via the procedure // dbi_fetch. In this command the fetching of the object is delayed until // the user actually queries the feature reader. That means that locks // are applied at that time. As a result the feature reader should have a // method to retrieve the lock conflicts because this object documents // them. This is not the case. Therefore, until a better solution is found // the work-around is to have two passes for the execution of the command: // the first one actually locks the objects and provides lock conflict // information whereas the second pass prepares the feature reader for the // user to retrieve the requested data. FdoIFeatureReader* FdoRdbmsSelectCommand::ExecuteWithLock() { FdoFilter *tempFilter = NULL; FdoIdentifier *tempClassName = NULL; FdoIAcquireLock *acquireLockCmd = NULL; // If a lock conflict reader already exists dispose it. FDO_SAFE_RELEASE(mLockConflictReader); // Create the command to lock the objects, set the command parameters // and execute it. acquireLockCmd = (FdoIAcquireLock *) mConn->CreateCommand( FdoCommandType_AcquireLock); tempClassName = GetFeatureClassName(); acquireLockCmd->SetFeatureClassName(tempClassName); tempClassName->Release(); tempFilter = GetFilter(); acquireLockCmd->SetFilter(tempFilter); acquireLockCmd->SetLockStrategy(mLockStrategy); acquireLockCmd->SetLockType(mLockType); mLockConflictReader = (FdoRdbmsLockConflictReader *)acquireLockCmd->Execute(); acquireLockCmd->Release(); acquireLockCmd = NULL; // Get the data as requested by the user. return (Execute()); }
/// <summary>Executes the select command and returns a reference to an FdoIDataReader.</summary> /// <returns>Returns the feature reader.</returns> FdoIDataReader* FdoCommonSelectAggregatesCommand::Execute () { FdoString* class_name; class_name = FdoPtr<FdoIdentifier> (GetFeatureClassName ())->GetName (); FdoPtr<FdoIConnection> conn = (FdoIConnection*)GetConnection (); //we will need a vanilla select command to get the features //the user would like to work with (given class and FdoFilter) FdoPtr <FdoISelect> selectCmd = (FdoISelect*)conn->CreateCommand(FdoCommandType_Select); selectCmd->SetFeatureClassName(class_name); selectCmd->SetFilter(mFilter); // Get other relevant info: FdoPtr<FdoIdentifierCollection> selectedIds = GetPropertyNames(); FdoPtr<FdoClassDefinition> originalClassDef = FdoCommonSchemaUtil::GetLogicalClassDefinition(conn, class_name, NULL); // Create and return the data reader: FdoPtr<FdoIDataReader> dataReader = new FdoCommonDataReader(conn, selectCmd, originalClassDef, selectedIds, m_bDistinct, m_OrderingIds, m_eOrderingOption); return FDO_SAFE_ADDREF(dataReader.p); }
FdoRdbmsLockConflictReader *FdoRdbmsAcquireLock::ExecuteLockRequest () // +--------------------------------------------------------------------------- // | The function executes the requested lock operation. // +--------------------------------------------------------------------------- { FdoRdbmsLockConflictReader *conflictReader = NULL; // get class name, filter // get table name sql filter // start transaction // get lock conflicts // acquire lock // Declare and initialize all necessary local variables. bool filter_modified = FALSE, transaction_started = FALSE, class_name_modified = FALSE; FdoFilter *fdo_filter = NULL; FdoIdentifier *class_name = NULL, *temp_class_name = NULL, *modified_class_name = NULL; FdoITransaction *fdo_i_transaction = NULL; char *tableName; char *sqlFilter; int execution_status; try { // Get the current class name. The class name can come in any of the // following structures: // // just a class name (like "testClass") // <class_name>.<property>[.<property>] // <schema>:<class_name> (like "LockTests:testClass") // // At the end of the process a usable class name is available. class_name = GetFeatureClassName(); req_class_name = LockUtility::GetClassName(class_name, &class_name_modified); // The request is executed only, if the connection and the class support // locking. If this is not the case issue an error. if (!LockUtility::IsLockSupported(fdo_rdbms_connection, req_class_name)) throw FdoCommandException::Create( LockUtility::GetExceptionMessage( LockUtility::LOCK_SUPPORT_ERROR, req_class_name->GetName(), L"FdoIAcquireLock")); if ((class_name_modified) && (this->GetFilterRef() != NULL)) { temp_class_name = FdoRdbmsFilterUtil::ConvertFilterToMainClass(class_name, this->GetFilterRef()); temp_class_name->Release(); filter_modified = TRUE; } // if (class_name_modified) ... execution_status = LockUtility::ProcessLockRequest(fdo_rdbms_connection, FdoPtr<FdoRdbmsFilterProcessor>(FdoPtr<FdoRdbmsConnection>((FdoRdbmsConnection*)GetConnection())->GetFilterProcessor()), class_name, req_class_name, class_name_modified, GetFilter(), &tableName, &sqlFilter); if (!execution_status) throw FdoCommandException::Create( LockUtility::GetExceptionMessage( LockUtility::LOCK_REQUEST_PROCESSING_ERROR)); // Start a transaction to cover the following modifications. They may // have to be rolled back depending on the execution status of the pro- // cedure applying the lock. Don't start a transaction if there is one // already active. FdoLockType lockType = GetLockType(); if (!fdo_rdbms_connection->GetIsTransactionStarted()) { if (lockType == FdoLockType_Transaction) throw FdoCommandException::Create( LockUtility::GetExceptionMessage( LockUtility::LOCK_ACTIVE_TRANSACTION_ERROR)); if ((fdo_i_transaction = fdo_rdbms_connection->BeginTransaction()) == NULL) { if ((class_name_modified ) && (filter_modified ) && (this->GetFilterRef() != NULL) ) FdoRdbmsFilterUtil::ConvertFilterToObjectClass( class_name, this->GetFilterRef()); if ((class_name_modified) && (req_class_name != NULL)) req_class_name->Release(); req_class_name = NULL; class_name->Release(); class_name = NULL; if (fdo_filter != NULL) { fdo_filter->Release(); fdo_filter = NULL; } // if (fdo_filter != NULL) ... return conflictReader; } // if ((fdo_i_transaction = ... transaction_started = TRUE; } // if (!fdo_rdbms_connection->GetIsTransactionStarted()) ... execution_status = FdoPtr<FdoRdbmsLockManager>(fdo_rdbms_connection->GetLockManager())->AcquireLock(LockUtility::ConvertString(tableName), LockUtility::ConvertString(sqlFilter), (FdoString *)NULL, FdoLockType_Transaction); FdoRdbmsLockConflictQueryHandler *lockConflictQuery = FdoPtr<FdoRdbmsLockManager>(fdo_rdbms_connection->GetLockManager())->LockConflictQuery(LockUtility::ConvertString(tableName), LockUtility::ConvertString(sqlFilter)); if (lockType != FdoLockType_Transaction) { execution_status = FdoPtr<FdoRdbmsLockManager>(fdo_rdbms_connection->GetLockManager())->AcquireLock(LockUtility::ConvertString(tableName), LockUtility::ConvertString(sqlFilter), lockConflictQuery->GetConflictDbObject(), lockType); // If a transaction was started, it has to be handled: it is rolled back // if the execution of the lock request fails, committed otherwise. if (!execution_status) { if (transaction_started) { fdo_i_transaction->Rollback(); fdo_i_transaction->Release(); } } else { if (transaction_started) { fdo_i_transaction->Commit(); fdo_i_transaction->Release(); } } } // Finally, create a lock conflict reader. if (execution_status) conflictReader = new FdoRdbmsLockConflictReader(fdo_rdbms_connection, lockConflictQuery, req_class_name); // If the filter was modified, set it back. if ((class_name_modified ) && (filter_modified ) && (this->GetFilterRef() != NULL) ) FdoRdbmsFilterUtil::ConvertFilterToObjectClass(class_name, this->GetFilterRef()); // Do some cleaning up and return the execution status back to the calling // routine. if ((class_name_modified) && (modified_class_name != NULL)) modified_class_name->Release(); modified_class_name = NULL; class_name->Release(); class_name = NULL; if (fdo_filter != NULL) {fdo_filter->Release(); fdo_filter = NULL;} return conflictReader; } // try ... catch ( ... ) { if (fdo_i_transaction != NULL) { fdo_i_transaction->Rollback(); fdo_i_transaction->Release(); } // if (fdo_i_transaction != NULL) if ((class_name_modified ) && (filter_modified ) && (this->GetFilterRef() != NULL) ) FdoRdbmsFilterUtil::ConvertFilterToObjectClass(class_name, this->GetFilterRef()); if ((class_name_modified) && (modified_class_name != NULL)) modified_class_name->Release(); modified_class_name = NULL; if (class_name != NULL) { class_name->Release(); class_name = NULL; } if (fdo_filter != NULL) { fdo_filter->Release(); fdo_filter = NULL; } throw; } // catch ( ... ) ... } // ExecuteLockRequest ()