/// <summary> /// Updates this record with data from the specified <see cref="ActivityDataLog" />. /// </summary> /// <param name="dataLog">The <see cref="ActivityDataLog" /> containing the log data.</param> internal void Update(ActivityDataLog dataLog) { foreach (var newValue in ExtractValues(dataLog, true)) { Values[newValue.Key] = newValue.Value; } }
private static object GetPropertyValue(ActivityDataLog dataLog, PropertyInfo property, DataLogPropertyAttribute dataLogAttribute) { if (dataLogAttribute.MaxLength == 0 || dataLogAttribute.MaxLength < -1) { throw new DataLoggerMockException("Data log attribute max length must be a positive number or -1 (for unlimited)."); } // If it's a string, we might need some special handling if (property.PropertyType == typeof(string)) { string value = property.GetValue(dataLog) as string ?? string.Empty; // If there is a maximum length specified and the value exceeds that length... if (dataLogAttribute.MaxLength > 0 && value.Length > dataLogAttribute.MaxLength) { // If trunctation is allowed, truncate the value and return if (dataLogAttribute.TruncationAllowed) { return(value.Substring(0, dataLogAttribute.MaxLength)); } else { // The value exceeds the maximum length, but truncation is not allowed. throw new DataLoggerMockException($"Value of property '{property.Name}' exceeds the max length, and truncation is not allowed."); } } } return(property.GetValue(dataLog)); }
/// <summary> /// Creates a <see cref="LogTableDefinition" /> for the specified <see cref="ActivityDataLog" /> object. /// </summary> /// <param name="dataLog">The <see cref="ActivityDataLog" /> object.</param> /// <returns>A <see cref="LogTableDefinition" /> for the specified <see cref="ActivityDataLog" />.</returns> /// <exception cref="ArgumentNullException"><paramref name="dataLog" /> is null.</exception> public static LogTableDefinition BuildTableDefinition(ActivityDataLog dataLog) { if (dataLog == null) { throw new ArgumentNullException(nameof(dataLog)); } LogTableDefinition definition = new LogTableDefinition(dataLog.TableName); foreach (DataLogPropertyInfo dataLogProperty in GetDataLogProperties(dataLog)) { switch (dataLogProperty.Name) { // Special cases for base class properties case nameof(ActivityDataLog.RecordId): definition.Add(new LogTableColumn(definition.PrimaryKey, "uniqueidentifier", false)); break; case nameof(ActivityDataLog.SessionId): definition.Add(new LogTableColumn(dataLogProperty.Name, "varchar(50)", false)); break; case nameof(ActivityDataLog.ActivityExecutionId): definition.Add(new LogTableColumn(dataLogProperty.Name, "uniqueidentifier", false)); break; default: definition.Add(new LogTableColumn(dataLogProperty.PropertyInfo, dataLogProperty.MaxLength, true)); break; } } return(definition); }
/// <summary> /// Initializes a new instance of the <see cref="DataLoggerMockTable" /> class. /// </summary> /// <param name="dataLog">The initial <see cref="ActivityDataLog" /> to insert into the table.</param> internal DataLoggerMockTable(ActivityDataLog dataLog) { TableName = dataLog.TableName; LogType = dataLog.GetType(); Records = new Dictionary <Guid, DataLoggerMockRecord>(); Add(dataLog); }
private static Dictionary <string, object> ExtractValues(ActivityDataLog dataLog, bool updateOnly) { Dictionary <string, object> values = new Dictionary <string, object>(); Type dataLogType = dataLog.GetType(); var properties = from property in dataLogType.GetProperties() let dataLogAttribute = property.GetCustomAttribute <DataLogPropertyAttribute>() where dataLogAttribute != null orderby dataLogAttribute.Order select new { Property = property, Attribute = dataLogAttribute }; foreach (var value in properties) { if (!updateOnly || value.Attribute.IncludeInUpdates) { if (value.Property.Name == "RecordId") { values.Add(dataLog.TableName + "Id", value.Property.GetValue(dataLog)); } else { values.Add(value.Property.Name, GetPropertyValue(dataLog, value.Property, value.Attribute)); } } } return(values); }
private void ValidateType(ActivityDataLog dataLog) { Type currentLogType = dataLog.GetType(); if (currentLogType != LogType) { throw new DataLoggerMockException($"The {TableName} table received a record of type '{currentLogType}' but expected records of type '{LogType}'."); } }
/// <summary> /// Updates an existing log record using data from the specified <see cref="ActivityDataLog" />. /// </summary> /// <param name="dataLog">The <see cref="ActivityDataLog" />.</param> /// <returns><c>true</c> if update was successful, <c>false</c> otherwise.</returns> /// <exception cref="ArgumentNullException"><paramref name="dataLog" /> is null.</exception> public bool Update(ActivityDataLog dataLog) { if (dataLog == null) { throw new ArgumentNullException(nameof(dataLog)); } LogTableDefinition table = DataLogTranslator.BuildTableDefinition(dataLog); LogTableRecord record = DataLogTranslator.BuildUpdateRecord(dataLog); return(Update(table, record)); }
/// <summary> /// Asynchronously updates an existing log record using data from the specified <see cref="ActivityDataLog" />. /// </summary> /// <param name="dataLog">The <see cref="ActivityDataLog" />.</param> /// <exception cref="ArgumentNullException"><paramref name="dataLog" /> is null.</exception> public void UpdateAsync(ActivityDataLog dataLog) { if (dataLog == null) { throw new ArgumentNullException(nameof(dataLog)); } LogTableDefinition table = DataLogTranslator.BuildTableDefinition(dataLog); LogTableRecord record = DataLogTranslator.BuildUpdateRecord(dataLog); Task.Factory.StartNew(() => Update(table, record)); }
/// <summary> /// Adds a new data log record to this table. /// </summary> /// <param name="dataLog">The <see cref="ActivityDataLog" /> to add.</param> internal void Add(ActivityDataLog dataLog) { ValidateType(dataLog); if (Records.ContainsKey(dataLog.RecordId)) { throw new DataLoggerMockException(string.Format("The {0} table received a record with a duplicate key.", TableName)); } Records.Add(dataLog.RecordId, new DataLoggerMockRecord(dataLog)); DataUpdated?.Invoke(this, EventArgs.Empty); }
/// <summary> /// Updates the specified data log in this table. /// </summary> /// <param name="dataLog">The <see cref="ActivityDataLog" /> to update.</param> internal void Update(ActivityDataLog dataLog) { ValidateType(dataLog); if (!Records.ContainsKey(dataLog.RecordId)) { throw new DataLoggerMockException($"The {TableName} table received an Update command for a record that does not exist."); } Records[dataLog.RecordId].Update(dataLog); DataUpdated?.Invoke(this, EventArgs.Empty); }
/// <summary> /// Updates an existing log record using data from the specified <see cref="ActivityDataLog" />. /// </summary> /// <param name="dataLog">The <see cref="ActivityDataLog" />.</param> /// <returns><c>true</c> if update was successful, <c>false</c> otherwise.</returns> /// <exception cref="ArgumentNullException"><paramref name="dataLog" /> is null.</exception> /// <exception cref="DataLoggerMockException">An issue with the data log was detected.</exception> public bool Update(ActivityDataLog dataLog) { if (dataLog == null) { throw new ArgumentNullException(nameof(dataLog)); } if (Tables.ContainsKey(dataLog.TableName)) { Tables[dataLog.TableName].Update(dataLog); } else { throw new DataLoggerMockException($"Received an Update command for non-existent table '{dataLog.TableName}'."); } return(true); }
/// <summary> /// Submits the specified <see cref="ActivityDataLog" /> as a new log record. /// </summary> /// <param name="dataLog">The <see cref="ActivityDataLog" />.</param> /// <returns><c>true</c> if submission was successful, <c>false</c> otherwise.</returns> /// <exception cref="ArgumentNullException"><paramref name="dataLog" /> is null.</exception> /// <exception cref="DataLoggerMockException">An issue with the data log was detected.</exception> public bool Submit(ActivityDataLog dataLog) { if (dataLog == null) { throw new ArgumentNullException(nameof(dataLog)); } if (Tables.ContainsKey(dataLog.TableName)) { Tables[dataLog.TableName].Add(dataLog); } else { DataLoggerMockTable newTable = new DataLoggerMockTable(dataLog); Tables.Add(dataLog.TableName, newTable); TableAdded?.Invoke(this, new DataLoggerMockTableEventArgs(newTable)); } return(true); }
private static LogTableRecord BuildRecord(ActivityDataLog dataLog, bool insert) { if (dataLog == null) { throw new ArgumentNullException(nameof(dataLog)); } // Build the table definition so that we can use the primary key LogTableDefinition tableDefinition = new LogTableDefinition(dataLog.TableName); LogTableRecord record = new LogTableRecord(); foreach (DataLogPropertyInfo dataLogProperty in GetDataLogProperties(dataLog)) { bool isPrimaryKey = dataLogProperty.Name.Equals(nameof(ActivityDataLog.RecordId)); if (insert || dataLogProperty.IncludeInUpdates || isPrimaryKey) { // Special case: change "RecordId" to the primary key name string columnName = isPrimaryKey ? tableDefinition.PrimaryKey : dataLogProperty.Name; record.Add(columnName, GetPropertyValue(dataLogProperty, dataLog)); } } return(record); }
public bool Update(ActivityDataLog dataLog) => _dataLoggerMock.Update(dataLog);
/// <summary> /// Initializes a new instance of the <see cref="DataLoggerMockRecord" /> class. /// </summary> /// <param name="dataLog">The <see cref="ActivityDataLog" /> containing the log data.</param> internal DataLoggerMockRecord(ActivityDataLog dataLog) { Values = ExtractValues(dataLog, false); }
/// <summary> /// Builds a <see cref="LogTableRecord" /> for an update operation from the specified <see cref="ActivityDataLog" /> object. /// </summary> /// <param name="dataLog">The <see cref="ActivityDataLog" /> object.</param> /// <returns>A <see cref="LogTableRecord" /> for an update operation from the specified <see cref="ActivityDataLog" />.</returns> /// <exception cref="ArgumentNullException"><paramref name="dataLog" /> is null.</exception> /// <exception cref="InvalidOperationException"><paramref name="dataLog" /> contains data that exceeds the maximum allowable length and cannot be truncated.</exception> public static LogTableRecord BuildUpdateRecord(ActivityDataLog dataLog) { return(BuildRecord(dataLog, false)); }
/// <summary> /// Builds a <see cref="LogTableRecord" /> for an insert operation from the specified <see cref="ActivityDataLog" /> object. /// </summary> /// <param name="dataLog">The <see cref="ActivityDataLog" /> object.</param> /// <returns>A <see cref="LogTableRecord" /> for an insert operation from the specified <see cref="ActivityDataLog" />.</returns> /// <exception cref="ArgumentNullException"><paramref name="dataLog" /> is null.</exception> /// <exception cref="InvalidOperationException"><paramref name="dataLog" /> contains data that exceeds the maximum allowable length and cannot be truncated.</exception> public static LogTableRecord BuildInsertRecord(ActivityDataLog dataLog) { return(BuildRecord(dataLog, true)); }
/// <summary> /// Submits the specified <see cref="ActivityDataLog" /> as a new log record. /// </summary> /// <param name="dataLog">The <see cref="ActivityDataLog" />.</param> /// <returns><c>true</c> if submission was successful; an exception is thrown otherwise.</returns> /// <exception cref="ArgumentNullException"><paramref name="dataLog" /> is null.</exception> /// <exception cref="DataLoggerMockException">An issue with the data log was detected.</exception> public bool Submit(ActivityDataLog dataLog) { return(_dataLoggerMock.Submit(dataLog)); }
/// <summary> /// Updates an existing log record using data from the specified <see cref="ActivityDataLog" />. /// </summary> /// <param name="dataLog">The <see cref="ActivityDataLog" />.</param> /// <returns><c>true</c> if update was successful; an exception is thrown otherwise.</returns> /// <exception cref="ArgumentNullException"><paramref name="dataLog" /> is null.</exception> /// <exception cref="DataLoggerMockException">An issue with the data log was detected.</exception> public bool Update(ActivityDataLog dataLog) { return(_dataLoggerMock.Update(dataLog)); }
// Reroute all IDataLogger calls to the mock public bool Submit(ActivityDataLog dataLog) => _dataLoggerMock.Submit(dataLog);
public void UpdateAsync(ActivityDataLog dataLog) => _dataLoggerMock.UpdateAsync(dataLog);
/// <summary> /// Submits the specified <see cref="ActivityDataLog" /> as a new log record. /// (This mock does not make an async call.) /// </summary> /// <param name="dataLog">The <see cref="ActivityDataLog" />.</param> /// <exception cref="ArgumentNullException"><paramref name="dataLog" /> is null.</exception> /// <exception cref="DataLoggerMockException">An issue with the data log was detected.</exception> public void SubmitAsync(ActivityDataLog dataLog) { Submit(dataLog); }
public void SubmitAsync(ActivityDataLog dataLog) => _dataLoggerMock.SubmitAsync(dataLog);
/// <summary> /// Updates an existing log record using data from the specified <see cref="ActivityDataLog" />. /// (This mock does not make an async call.) /// </summary> /// <param name="dataLog">The <see cref="ActivityDataLog" />.</param> /// <exception cref="ArgumentNullException"><paramref name="dataLog" /> is null.</exception> /// <exception cref="DataLoggerMockException">An issue with the data log was detected.</exception> public void UpdateAsync(ActivityDataLog dataLog) { Update(dataLog); }