/// <summary> /// Serialise a <see cref="UserTrackingRecord" /> ready for persistence. /// </summary> /// <param name="userTrackingRecord"> /// The original <see cref="UserTrackingRecord" /> to serialise. /// </param> /// <returns> /// Modified copy of the <see cref="UserTrackingRecord" /> containing /// with serialised data. /// </returns> private static SerialisableUserTrackingRecord buildSerialisableUserTrackingRecord(UserTrackingRecord userTrackingRecord) { SerialisableUserTrackingRecord serialisableUserTrackingRecord = new SerialisableUserTrackingRecord(); serialisableUserTrackingRecord.ActivityType = userTrackingRecord.ActivityType; serialisableUserTrackingRecord.Annotations.AddRange(userTrackingRecord.Annotations); serialisableUserTrackingRecord.ContextGuid = userTrackingRecord.ContextGuid; serialisableUserTrackingRecord.EventDateTime = userTrackingRecord.EventDateTime; serialisableUserTrackingRecord.EventOrder = userTrackingRecord.EventOrder; serialisableUserTrackingRecord.ParentContextGuid = userTrackingRecord.ParentContextGuid; serialisableUserTrackingRecord.QualifiedName = userTrackingRecord.QualifiedName; serialisableUserTrackingRecord.UserDataKey = userTrackingRecord.UserDataKey; if (userTrackingRecord.Body != null) { for (int i = 0; i < userTrackingRecord.Body.Count; i++) { serialisableUserTrackingRecord.Body.Add(buildSerialisableTrackingDataItem(userTrackingRecord.Body[i])); } } if (userTrackingRecord.EventArgs != null) { serialisableUserTrackingRecord.EventArgs = buildSerialisableData(userTrackingRecord.EventArgs); } if (userTrackingRecord.UserData != null) { serialisableUserTrackingRecord.UserData = buildSerialisableData(userTrackingRecord.UserData); } return(serialisableUserTrackingRecord); }
/// <summary> /// Inserts a batch of user tracking records, returning them /// as an <see cref="IDictionary{TKey,TValue}" /> indexed by their /// unique identifiers. /// </summary> /// <param name="workflowInstanceSummary"> /// A <see cref="WorkflowInstanceSummary" /> representing a workflow instance /// aInt64 with all its type information. /// </param> /// <param name="userTrackingRecords"> /// An <see cref="IList{T}" /> containing a batch of user tracking /// records to be inserted into the tracking store. /// </param> /// <returns> /// An <see cref="IDictionary{TKey,TValue}" /> containing the inserted /// records and indexed by their unique identifiers. /// </returns> protected override IDictionary <Int64, SerialisableUserTrackingRecord> InsertUserTrackingRecordBatch( WorkflowInstanceSummary workflowInstanceSummary, IList <SerialisableUserTrackingRecord> userTrackingRecords) { if (userTrackingRecords.Count == 0 || userTrackingRecords.Count > UserTrackingBatchSize) { throw new ArgumentOutOfRangeException("userTrackingRecords"); } Dictionary <Int64, SerialisableUserTrackingRecord> userTrackingRecordsById = new Dictionary <Int64, SerialisableUserTrackingRecord>(); using (OracleCommand oracleCommand = (OracleCommand)CreateCommand("WORKFLOW_TRACKING_PKG.InsertUserTrackingRecord", CommandType.StoredProcedure)) { Int64[] workflowInstanceIds = new Int64[userTrackingRecords.Count]; Int64?[] activityInstanceIds = new Int64?[userTrackingRecords.Count]; String[] activityIdentifiers = new String[userTrackingRecords.Count]; String[] qualifiedNames = new String[userTrackingRecords.Count]; Guid[] contextGuids = new Guid[userTrackingRecords.Count]; Guid[] parentContextGuids = new Guid[userTrackingRecords.Count]; DateTime[] eventDateTimes = new DateTime[userTrackingRecords.Count]; Int32[] eventOrders = new Int32[userTrackingRecords.Count]; String[] userDataKeys = new String[userTrackingRecords.Count]; String[] userDataTypeNames = new String[userTrackingRecords.Count]; String[] userDataAssemblyNames = new String[userTrackingRecords.Count]; String[] userDataStrings = new String[userTrackingRecords.Count]; Byte[][] userDataBlobs = new Byte[userTrackingRecords.Count][]; Boolean[] userDataNonSerialisables = new Boolean[userTrackingRecords.Count]; for (Int32 i = 0; i < userTrackingRecords.Count; i++) { SerialisableUserTrackingRecord userTrackingRecord = userTrackingRecords[i]; workflowInstanceIds[i] = (Int64)workflowInstanceSummary.InternalId; activityIdentifiers[i] = BuildActivityIdentifier(userTrackingRecord); activityInstanceIds[i] = FindActivityInstanceInternalId(activityIdentifiers[i]); qualifiedNames[i] = userTrackingRecord.QualifiedName; contextGuids[i] = userTrackingRecord.ContextGuid; parentContextGuids[i] = userTrackingRecord.ParentContextGuid; eventDateTimes[i] = userTrackingRecord.EventDateTime; eventOrders[i] = userTrackingRecord.EventOrder; userDataKeys[i] = userTrackingRecord.UserDataKey; userDataTypeNames[i] = userTrackingRecord.UserData.Type.FullName; userDataAssemblyNames[i] = userTrackingRecord.UserData.Type.Assembly.FullName; userDataStrings[i] = userTrackingRecord.UserData.StringData; userDataBlobs[i] = userTrackingRecord.UserData.SerialisedData; userDataNonSerialisables[i] = userTrackingRecord.UserData.NonSerialisable; } oracleCommand.ArrayBindCount = userTrackingRecords.Count; AddParameter(oracleCommand, "p_WORKFLOW_INSTANCE_ID", workflowInstanceIds, AdoDbType.Int64); OracleParameter activityInstanceId = (OracleParameter)AddParameter( oracleCommand, "p_ACTIVITY_INSTANCE_ID", activityInstanceIds, AdoDbType.Int64, ParameterDirection.InputOutput); AddParameter(oracleCommand, "p_QUALIFIED_NAME", qualifiedNames, AdoDbType.String); AddParameter(oracleCommand, "p_CONTEXT_GUID", contextGuids, AdoDbType.Guid); AddParameter(oracleCommand, "p_PARENT_CONTEXT_GUID", parentContextGuids, AdoDbType.Guid); AddParameter(oracleCommand, "p_EVENT_DATE_TIME", eventDateTimes, AdoDbType.DateTime); AddParameter(oracleCommand, "p_EVENT_ORDER", eventOrders, AdoDbType.Int32); AddParameter(oracleCommand, "p_USER_DATA_KEY", userDataKeys, AdoDbType.String); AddParameter(oracleCommand, "p_USER_DATA_TYPE_NAME", userDataTypeNames, AdoDbType.String); AddParameter(oracleCommand, "p_USER_DATA_ASSEMBLY_NAME", userDataAssemblyNames, AdoDbType.String); AddParameter(oracleCommand, "p_USER_DATA_STR", userDataStrings, AdoDbType.String); AddParameter(oracleCommand, "p_USER_DATA_BLOB", userDataBlobs, AdoDbType.Binary); AddParameter(oracleCommand, "p_USER_DATA_NON_SERIALISABLE", userDataNonSerialisables, AdoDbType.Boolean); OracleParameter userEventId = (OracleParameter)AddParameter( oracleCommand, "p_USER_EVENT_ID", AdoDbType.Int64, ParameterDirection.Output); oracleCommand.ExecuteNonQuery(); Int64[] populatedActivityInstanceIds = (Int64[])activityInstanceId.Value; Int64[] userEventIds = (Int64[])userEventId.Value; for (Int32 i = 0; i < userTrackingRecords.Count; i++) { UpdateActivityInstanceInternalId(activityIdentifiers[i], populatedActivityInstanceIds[i]); userTrackingRecordsById.Add(userEventIds[i], userTrackingRecords[i]); } } return(userTrackingRecordsById); }
///<summary> ///Commits the list of work items by using the specified <see cref="T:System.Transactions.Transaction"></see> object. ///</summary> /// ///<param name="items">The work items to be committed.</param> ///<param name="transaction">The <see cref="T:System.Transactions.Transaction"></see> associated with the pending work.</param> public void Commit(Transaction transaction, ICollection items) { TraceHelper.Trace(); try { using (ITrackingChannelResourceAccessor resourceAccessor = CreateAccessor(resourceProvider, transaction)) { if (this.workflowInstanceSummary == null) { this.workflowInstanceSummary = resourceAccessor.InsertOrGetWorkflowInstance(buildWorkflowInstanceSummary()); } List <SerialisableActivityTrackingRecord> activityTrackingRecords = new List <SerialisableActivityTrackingRecord>(); List <SerialisableUserTrackingRecord> userTrackingRecords = new List <SerialisableUserTrackingRecord>(); List <SerialisableWorkflowChangeRecord> workflowChangeRecords = new List <SerialisableWorkflowChangeRecord>(); List <SerialisableWorkflowTrackingRecord> workflowTrackingRecords = new List <SerialisableWorkflowTrackingRecord>(); // group each type of tracking record ready for processing foreach (object itemToCommit in items) { if (!(itemToCommit is TrackingRecord)) { continue; } SerialisableActivityTrackingRecord activityTrackingRecord = itemToCommit as SerialisableActivityTrackingRecord; if (activityTrackingRecord != null) { activityTrackingRecords.Add(activityTrackingRecord); continue; } SerialisableUserTrackingRecord userTrackingRecord = itemToCommit as SerialisableUserTrackingRecord; if (userTrackingRecord != null) { userTrackingRecords.Add(userTrackingRecord); continue; } SerialisableWorkflowChangeRecord workflowChangeRecord = itemToCommit as SerialisableWorkflowChangeRecord; if (workflowChangeRecord != null) { workflowChangeRecords.Add(workflowChangeRecord); continue; } SerialisableWorkflowTrackingRecord workflowTrackingRecord = itemToCommit as SerialisableWorkflowTrackingRecord; if (workflowTrackingRecord != null) { workflowTrackingRecords.Add(workflowTrackingRecord); continue; } } // send each category of record off to the resource accessor if (activityTrackingRecords.Count > 0) { resourceAccessor.InsertTrackingRecords(this.workflowInstanceSummary, activityTrackingRecords); } if (userTrackingRecords.Count > 0) { resourceAccessor.InsertTrackingRecords(this.workflowInstanceSummary, userTrackingRecords); } if (workflowTrackingRecords.Count > 0) { resourceAccessor.InsertTrackingRecords(this.workflowInstanceSummary, workflowTrackingRecords); } if (workflowChangeRecords.Count > 0) { resourceAccessor.InsertTrackingRecords(this.workflowInstanceSummary, workflowChangeRecords); } } } catch (Exception e) { string errorMessage = RM.Get_Error_TrackingChannelException(e.ToString()); TraceHelper.Trace(errorMessage); throw new TrackingException(errorMessage, e); } }