/// <summary> /// Extract the information from the supplied exception /// and stores the information as a new ErrorLog /// </summary> public static ErrorLog Logg <T>(Exception e, bool suppressMessage = false) { if (ExceptionHandler.HasCaught(e)) { return(ExceptionHandler.GetErrorLog(e) as ErrorLog); } var error = new ErrorLog { UserName = DwarfContext <T> .GetConfiguration().UserService.CurrentUser != null ? DwarfContext <T> .GetConfiguration().UserService.CurrentUser.UserName : "", TimeStamp = DateTime.Now, Message = e.Message, Type = e.GetType().ToString(), StackTrace = e.StackTrace, Exception = e, }; if (e.InnerException != null) { error.InnerException = Logg <T>(e.InnerException, suppressMessage); } DwarfContext <T> .GetDatabase().Insert <T, ErrorLog>(error); if (!suppressMessage) { ExceptionHandler.Logg(error); } return(error); }
/// <summary> /// See base /// </summary> public void Delete() { if (!IsSaved) { return; } try { DbContextHelper <T> .BeginOperation(); OnBeforeDeleteInternal(); OnBeforeDelete(); DwarfContext <T> .GetDatabase().Delete(this); DbContextHelper <T> .FinalizeOperation(false); OnAfterDeleteInternal(); OnAfterDelete(); } catch (Exception e) { DbContextHelper <T> .FinalizeOperation(true); DwarfContext <T> .GetConfiguration().ErrorLogService.Logg(e); throw; } finally { DbContextHelper <T> .EndOperation(); } }
private void OnBeforeDeleteInternal() { //We want to persist all the Inverse OneToManyCollection upon deletion. Let's remove all lists that doesn't //need persistance first (all objects therein will be deleted in the database via delete cascades anyways) foreach (var pi in DwarfHelper.GetOneToManyProperties(this)) { var propertyAtt = OneToManyAttribute.GetAttribute(pi.ContainedProperty); if (propertyAtt == null) { throw new NullReferenceException(pi.Name + " is missing the OneToMany attribute..."); } if (!propertyAtt.IsInverse) { continue; } var obj = (IDwarfList)pi.GetValue(this); var owningProp = oneToManyAlternateKeys.ContainsKey(pi.Name) ? oneToManyAlternateKeys[pi.Name] : GetType().Name; obj.Cast <IDwarf>().ForEachX(x => PropertyHelper.SetValue(x, owningProp, null)); obj.SaveAllInternal <T>(); } if (DbContextHelper <T> .DbContext.IsAuditLoggingSuspended || DwarfContext <T> .GetConfiguration().AuditLogService == null) { return; } var traces = (from ep in DwarfHelper.GetDBProperties(GetType()).Where(x => !x.Name.Equals("Id")) let oldValue = originalValues[ep.Name] where oldValue != null && (oldValue is string? !string.IsNullOrEmpty(oldValue.ToString()) : true) select new AuditLogEventTrace { PropertyName = ep.Name, OriginalValue = oldValue }).ToArray(); var collectionTraces = (from ep in DwarfHelper.GetGemListProperties(GetType()) let oldValue = (IGemList)ep.GetValue(this) where oldValue != null && oldValue.Count > 0 select new AuditLogEventTrace { PropertyName = ep.Name, OriginalValue = oldValue }).ToArray(); var many2ManyTraces = (from ep in DwarfHelper.GetManyToManyProperties(GetType()) let oldValue = ep.GetValue(this) where oldValue != null && ((IList)oldValue).Count > 0 select new AuditLogEventTrace { PropertyName = ep.Name, OriginalValue = oldValue }).ToArray(); DwarfContext <T> .GetConfiguration().AuditLogService.Logg(this, AuditLogTypes.Deleted, traces.Union(collectionTraces).Union(many2ManyTraces).ToArray()); }
/// <summary> /// Stores an AuditLog object for the ongoing transaction /// </summary> public static IAuditLog Logg <T>(IDwarf obj, AuditLogTypes auditLogType, params AuditLogEventTrace[] auditUpdateEvents) { var type = DwarfHelper.DeProxyfy(obj); if (type.Implements <IAuditLogless>() || type.Implements <IAuditLog>()) { return(null); } var al = new AuditLog { ClassType = type.Name, AuditLogType = auditLogType, UserName = DwarfContext <T> .GetConfiguration().UserService.CurrentUser != null ? DwarfContext <T> .GetConfiguration().UserService.CurrentUser.UserName : string.Empty, TimeStamp = DateTime.Now, ObjectValue = obj.ToString(), }; if (!type.Implements <ICompositeId>()) { al.ObjectId = obj.Id.ToString(); } else { foreach (var ep in DwarfHelper.GetPKProperties(type)) { al.ObjectId += string.Format("[{0}: {1}]", ep.Name, ep.GetValue(obj)); } } if (auditLogType != AuditLogTypes.Created) { al.AuditDetails = "<?xml version=\"1.0\"?><Properties>"; foreach (var auditUpdateEvent in auditUpdateEvents) { al.AuditDetails += auditUpdateEvent.ToXml().ToString(); } al.AuditDetails += "</Properties>"; } DwarfContext <T> .GetDatabase().Insert <T, AuditLog>(al); return(al); }
private void CreateAuditLog(AuditLogTypes auditLogType, IEnumerable <AuditLogEventTrace> propertyTraces) { if (DbContextHelper <T> .DbContext.IsAuditLoggingSuspended || DwarfContext <T> .GetConfiguration().AuditLogService == null) { return; } if (auditLogType == AuditLogTypes.Updated) { var traces = propertyTraces.Union(CreateTraceEventsForManyToMany()).ToArray(); if (traces.Length > 0) { DwarfContext <T> .GetConfiguration().AuditLogService.Logg(this, auditLogType, traces); } } else if (auditLogType == AuditLogTypes.Created) { DwarfContext <T> .GetConfiguration().AuditLogService.Logg(this, auditLogType); } }
internal static IEnumerable <Type> GetValidTypes <T>() { var baseType = DeProxyfy(typeof(T)); if (baseType != typeof(T)) { throw new InvalidOperationException("T is a proxy class... Looks like you need to specify the complete namespace"); } var typeList = baseType.Assembly.GetTypes().Where(type => type.Implements <IDwarf>() && !type.IsAbstract).ToList(); if (DwarfContext <T> .GetConfiguration().AuditLogService is AuditLogService <T> ) { typeList.Add(typeof(AuditLog)); } if (DwarfContext <T> .GetConfiguration().ErrorLogService is ErrorLogService <T> ) { typeList.Add(typeof(ErrorLog)); } return(typeList); }
/// <summary> /// Deletes a ManyToMany relationship /// </summary> private static void DeleteManyToMany(IDwarf owner, IDwarf child, string alternateTableName = null) { try { DbContextHelper <T> .BeginOperation(); DwarfContext <T> .GetDatabase().DeleteManyToMany <T>(owner, child, alternateTableName); DbContextHelper <T> .FinalizeOperation(false); } catch (Exception e) { DbContextHelper <T> .FinalizeOperation(true); DwarfContext <T> .GetConfiguration().ErrorLogService.Logg(e); throw; } finally { DbContextHelper <T> .EndOperation(); } }
/// <summary> /// A quick way to insert a lot of objects at the same time. No audit logs are created though /// </summary> protected static void BulkInsert(IEnumerable <T> objects) { try { DbContextHelper <T> .BeginOperation(); DwarfContext <T> .GetDatabase().BulkInsert(objects); DbContextHelper <T> .FinalizeOperation(false); } catch (Exception e) { DbContextHelper <T> .FinalizeOperation(true); DwarfContext <T> .GetConfiguration().ErrorLogService.Logg(e); throw; } finally { DbContextHelper <T> .EndOperation(); } }
public static IDwarfConfiguration GetConfiguration <T>() { return(DwarfContext <T> .GetConfiguration()); }
/// <summary> /// See base /// </summary> public void Save() { if (isDeleted) { return; } try { DbContextHelper <T> .BeginOperation(); if (!Id.HasValue) { Id = internallyProvidedCustomId.HasValue ? internallyProvidedCustomId : Guid.NewGuid(); } OnBeforeSave(); var faultyForeignKeys = FaultyForeignKeys(this).ToList(); if (faultyForeignKeys.Count > 0) { DbContextHelper <T> .RegisterInvalidObject(this, faultyForeignKeys); DbContextHelper <T> .FinalizeOperation(false); return; } else { DbContextHelper <T> .UnRegisterInvalidObject(this); } var auditLogType = AuditLogTypes.Updated; var traces = CreateTraceEventsForProperties(); if (IsSaved) { if (traces.Length > 0) //IsDirty { DwarfContext <T> .GetDatabase().Update(this, traces.Select(x => PropertyHelper.GetProperty <T>(x.PropertyName))); } } else { auditLogType = AuditLogTypes.Created; DwarfContext <T> .GetDatabase().Insert <T, T>(this, Id); } CreateAuditLog(auditLogType, traces); PersistOneToManyCollections(); PersistManyToManyCollections(); OnAfterSave(); DbContextHelper <T> .FinalizeOperation(false); OnAfterSaveInternal(); } catch (Exception e) { DbContextHelper <T> .FinalizeOperation(true); DwarfContext <T> .GetConfiguration().ErrorLogService.Logg(e); throw; } finally { DbContextHelper <T> .EndOperation(); } }
private static object RecreateValue <T>(PropertyInfo pi, string value) { if (pi.PropertyType.Implements <ICollection>()) { if (pi.PropertyType.IsGenericType && pi.PropertyType.GetGenericArguments()[0].Implements <IDwarf>()) { var innerType = pi.PropertyType.GetGenericArguments()[0]; var list = new List <IDwarf>(); if (string.IsNullOrEmpty(value)) { return(list); } var ids = value.Split(new[] { ";" }, StringSplitOptions.RemoveEmptyEntries); foreach (var id in ids) { var guid = Guid.Parse(id); var obj = innerType.FindMethodRecursively("Load", new[] { typeof(Guid) }).Invoke(null, new object[] { guid }); if (obj == null) { var log = DwarfContext <T> .GetConfiguration().AuditLogService.LoadAllReferencing(guid).FirstOrDefault(x => x.AuditLogType == AuditLogTypes.Deleted); if (log == null) { continue; } obj = Activator.CreateInstance(innerType); log.InjectTraceValues <T>(obj); ((IDwarf)obj).Id = guid; } list.Add((IDwarf)obj); } return(list); } else { var sr = new StringReader(value); var reader = XmlReader.Create(sr); return(new XmlSerializer(pi.PropertyType).Deserialize(reader)); } } if (string.IsNullOrEmpty(value)) { return(value); } if (pi.PropertyType.Implements <IDwarf>()) { var id = Guid.Parse(value); var obj = pi.PropertyType.FindMethodRecursively("Load", new[] { typeof(Guid) }).Invoke(null, new object[] { id }); //Might be deleted... try to locate the deleted event and recreate the object if (obj == null) { var ev = DwarfContext <T> .GetConfiguration().AuditLogService.LoadAllReferencing(id).FirstOrDefault(x => x.AuditLogType == AuditLogTypes.Deleted); if (ev != null) { obj = Activator.CreateInstance(pi.PropertyType); ev.InjectTraceValues <T>(obj); } } return(obj); } if (pi.PropertyType.Implements <IGem>()) { return(pi.PropertyType.FindMethodRecursively("Load", new[] { typeof(object) }).Invoke(null, new object[] { value })); } if (pi.PropertyType.IsEnum()) { return(Enum.Parse(pi.PropertyType.GetTrueEnumType(), value)); } var type = (pi.PropertyType.IsNullable() && pi.PropertyType != typeof(string)) ? (pi.PropertyType.IsGenericType ? pi.PropertyType.GetGenericArguments()[0] : pi.PropertyType) : pi.PropertyType; return(Convert.ChangeType(value, type)); }