Quintiq file version 2.0 
 | 
#parent: #root 
 | 
StaticMethod DoFinalizeDatasetCopyDelete (LibOpt_Task task, Boolean iserrorhandling) as stream[Void] 
 | 
{ 
 | 
  Description: 
 | 
  [* 
 | 
    This method checks for all datasets that are created by `task` if the `DeleteCondition` of the `LibOpt_DatasetCopyConditional` is satisfied. If so, the dataset is deleted.  
 | 
    This method assumes for all newly created datasets that any memory only dataset is online and that any standalone dataset is offline.  
 | 
    This method can be called right before an error. Therefore, don't start any reactive transactions in the parts of this method that can be reached when `iserrorhandling` is `true`. 
 | 
  *] 
 | 
  TextBody: 
 | 
  [* 
 | 
    // evr3 Jun-30-2020 (created) 
 | 
    previousdeletecondition := stream[Void]::Success(); 
 | 
    snapshots := selectsortedset( task, 
 | 
                                  SnapshotComponent.Children.astype( LibOpt_SnapshotReplannableCopyDataset ),  
 | 
                                  snapshot,  
 | 
                                  not snapshot.IsDatasetDeletedByOptimizer()  
 | 
                                  and not snapshot.HasFailedToCreateDataset() 
 | 
                                  and not snapshot.HasExecutedDoFinalizeDatasetCopyDelete(),  
 | 
                                  // The DeleteCondition of a LibOpt_DatasetCopyOnAnyDownstreamCopy uses the HasToBeDeleted and IsDatasetDeletedByOptimizer attributes of 
 | 
                                  // the snapshots that are created after the LibOpt_DatasetCopyOnAnyDownstreamCopy 
 | 
                                  // By sorting on SequenceNr, it is ensured that the HasToBeDeleted and IsDatasetDeletedByOptimizer attributes of the newest components are updated first.  
 | 
                                  -snapshot.SequenceNr() 
 | 
                                  ); 
 | 
     
 | 
    traverse( snapshots, Elements, snapshot ) 
 | 
    { 
 | 
      datasetcopyconditional := snapshot.DatasetCopyConditional(); 
 | 
      // The AE can modify the DeleteCondition method himself. This means that a user error might occur there.  
 | 
      // If there is an error in this method and if DatasetCopyDelete is called with iserrorhandling := false,  
 | 
      // then this error will be logged below the dataset copy snapshot and the dataset won't be deleted.  
 | 
      // The optimizer will then continue executing as if nothing happened.  
 | 
       
 | 
      // If an error occurs when DatasetCopyDelete is called with iserrorhandling := true, 
 | 
      // then this error will be logged below the SnapshotComponent.  
 | 
      // The current transaction will then be rolled back and the optimizer iteration will be aborted.  
 | 
      if( not isnull( datasetcopyconditional ) )  
 | 
      { 
 | 
        if( not task.Run().InOneTransaction() and not iserrorhandling ) 
 | 
        { 
 | 
          hastodeletedataset := previousdeletecondition->|datasetcopyconditional->DeleteCondition( task ); 
 | 
          previousdeletecondition := datasetcopyconditional->DeleteConditionPostProcessing( snapshot, hastodeletedataset )->IgnoreException() 
 | 
                                     ->|hastodeletedataset->Exception()->LibOpt_SnapshotError::ReadAndThrow( task, snapshot ); 
 | 
        } 
 | 
        else 
 | 
        {     
 | 
          hastodeletedataset := datasetcopyconditional.DeleteCondition( task ); 
 | 
          datasetcopyconditional.DeleteConditionPostProcessing( snapshot, hastodeletedataset ); 
 | 
        } 
 | 
      } 
 | 
    } 
 | 
     
 | 
    // We return a chain of streams. 
 | 
    // This ensures that stream::Success() will only be emitted when all dataset copies have been handled. 
 | 
    return previousdeletecondition; 
 | 
  *] 
 | 
  InterfaceProperties { Accessibility: 'Module' } 
 | 
} 
 |