/// <summary> /// Obsoletes the specified object /// </summary> public TData Obsolete(TData data, IPrincipal principal, TransactionMode mode) { if (data == null) { throw new ArgumentNullException(nameof(data)); } else if (data.Key == Guid.Empty) { throw new InvalidOperationException("Data missing key"); } PrePersistenceEventArgs <TData> preArgs = new PrePersistenceEventArgs <TData>(data); this.Obsoleting?.Invoke(this, preArgs); if (preArgs.Cancel) { this.m_tracer.TraceEvent(TraceEventType.Warning, 0, "Pre-Event handler indicates abort for {0}", data); return(data); } // Obsolete object using (var connection = m_configuration.Provider.GetWriteConnection()) { try { this.ThrowIfExceeded(); connection.Open(); using (IDbTransaction tx = connection.BeginTransaction()) try { //connection.Connection.Open(); this.m_tracer.TraceEvent(TraceEventType.Verbose, 0, "OBSOLETE {0}", data); data = this.Obsolete(connection, data, principal); if (mode == TransactionMode.Commit) { tx.Commit(); foreach (var itm in connection.CacheOnCommit) { ApplicationContext.Current.GetService <IDataCachingService>()?.Remove(itm.Key.Value); } } else { tx.Rollback(); } var args = new PostPersistenceEventArgs <TData>(data, principal) { Mode = mode }; this.Obsoleted?.Invoke(this, args); return(data); } catch (Exception e) { this.m_tracer.TraceEvent(TraceEventType.Error, 0, "Error : {0}", e); tx?.Rollback(); throw new DataPersistenceException(e.Message, e); } finally { } } finally { Interlocked.Decrement(ref m_currentRequests); } } }
/// <summary> /// Update the specified object /// </summary> /// <param name="storageData"></param> /// <param name="principal"></param> /// <param name="mode"></param> /// <returns></returns> public TData Update(TData data, IPrincipal principal, TransactionMode mode) { if (data == null) { throw new ArgumentNullException(nameof(data)); } else if (data.Key == Guid.Empty) { throw new InvalidOperationException("Data missing key"); } PrePersistenceEventArgs <TData> preArgs = new PrePersistenceEventArgs <TData>(data, principal); this.Updating?.Invoke(this, preArgs); if (preArgs.Cancel) { this.m_tracer.TraceEvent(TraceEventType.Warning, 0, "Pre-Event handler indicates abort update for {0}", data); return(data); } // Persist object using (var connection = m_configuration.Provider.GetWriteConnection()) { try { this.ThrowIfExceeded(); connection.Open(); using (IDbTransaction tx = connection.BeginTransaction()) try { //connection.Connection.Open(); this.m_tracer.TraceEvent(TraceEventType.Verbose, 0, "UPDATE {0}", data); data = this.Update(connection, data, principal); data.LoadState = LoadState.FullLoad; // We just persisted this so it is fully loaded if (mode == TransactionMode.Commit) { tx.Commit(); foreach (var itm in connection.CacheOnCommit) { ApplicationContext.Current.GetService <IDataCachingService>()?.Add(itm); } } else { tx.Rollback(); } var args = new PostPersistenceEventArgs <TData>(data, principal) { Mode = mode }; this.Updated?.Invoke(this, args); return(data); } catch (DbException e) { #if DEBUG this.m_tracer.TraceEvent(TraceEventType.Error, 0, "Error : {0} -- {1}", e, this.ObjectToString(data)); #else this.m_tracer.TraceEvent(TraceEventType.Error, 0, "Error : {0}", e.Message); #endif tx?.Rollback(); this.TranslateDbException(e); throw; } catch (Exception e) { #if DEBUG this.m_tracer.TraceEvent(TraceEventType.Error, 0, "Error : {0} -- {1}", e, this.ObjectToString(data)); #else this.m_tracer.TraceEvent(TraceEventType.Error, 0, "Error : {0}", e.Message); #endif tx?.Rollback(); // if the exception is key not found, we want the caller to know // so that a potential insert can take place if (e is KeyNotFoundException) { throw new KeyNotFoundException(e.Message, e); } // if the exception is anything else, we want to throw a data persistence exception throw new DataPersistenceException(e.Message, e); } finally { } } finally { Interlocked.Decrement(ref m_currentRequests); } } }
/// <summary> /// Inserts the specified data /// </summary> public TData Insert(TData data, IPrincipal principal, TransactionMode mode) { if (data == null) { throw new ArgumentNullException(nameof(data)); } PrePersistenceEventArgs <TData> preArgs = new PrePersistenceEventArgs <TData>(data, principal); this.Inserting?.Invoke(this, preArgs); if (preArgs.Cancel) { this.m_tracer.TraceEvent(TraceEventType.Warning, 0, "Pre-Event handler indicates abort insert for {0}", data); return(data); } // Persist object using (var connection = m_configuration.Provider.GetWriteConnection()) { try { this.ThrowIfExceeded(); connection.Open(); using (IDbTransaction tx = connection.BeginTransaction()) try { // Disable inserting duplicate classified objects var existing = data.TryGetExisting(connection, principal, true); if (existing != null) { if (m_configuration.AutoUpdateExisting) { this.m_tracer.TraceEvent(TraceEventType.Warning, 0, "INSERT WOULD RESULT IN DUPLICATE CLASSIFIER: UPDATING INSTEAD {0}", data); data = this.Update(connection, data, principal); } else { throw new DuplicateNameException(data.Key?.ToString()); } } else { this.m_tracer.TraceEvent(TraceEventType.Verbose, 0, "INSERT {0}", data); data = this.Insert(connection, data, principal); } data.LoadState = LoadState.FullLoad; // We just persisted so it is fully loaded if (mode == TransactionMode.Commit) { tx.Commit(); foreach (var itm in connection.CacheOnCommit) { ApplicationContext.Current.GetService <IDataCachingService>()?.Add(itm); } } else { tx.Rollback(); } var args = new PostPersistenceEventArgs <TData>(data, principal) { Mode = mode }; this.Inserted?.Invoke(this, args); return(data); } catch (DbException e) { #if DEBUG this.m_tracer.TraceEvent(TraceEventType.Error, 0, "Error : {0} -- {1}", e, this.ObjectToString(data)); #else this.m_tracer.TraceEvent(TraceEventType.Error, 0, "Error : {0}", e.Message); #endif tx?.Rollback(); this.TranslateDbException(e); throw; } catch (Exception e) { this.m_tracer.TraceEvent(TraceEventType.Error, 0, "Error : {0} -- {1}", e, this.ObjectToString(data)); tx?.Rollback(); throw new DataPersistenceException(e.Message, e); } finally { } } finally { Interlocked.Decrement(ref m_currentRequests); } } }
/// <summary> /// Obsoletes the specified object /// </summary> public TData Obsolete(TData data, IPrincipal principal, TransactionMode mode) { if (data == null) { throw new ArgumentNullException(nameof(data)); } else if (data.Key == Guid.Empty) { throw new InvalidOperationException("Data missing key"); } PrePersistenceEventArgs <TData> preArgs = new PrePersistenceEventArgs <TData>(data); this.Obsoleting?.Invoke(this, preArgs); if (preArgs.Cancel) { this.m_tracer.TraceEvent(TraceEventType.Warning, 0, "Pre-Event handler indicates abort for {0}", data); return(data); } // Obsolete object using (var connection = new ModelDataContext(m_configuration.ReadWriteConnectionString)) { DbTransaction tx = null; try { connection.Connection.Open(); tx = connection.Transaction = connection.Connection.BeginTransaction(); // Tracer if (m_configuration.TraceSql) { connection.Log = new LinqTraceWriter(); } this.m_tracer.TraceEvent(TraceEventType.Verbose, 0, "OBSOLETE {0}", data); data = this.Obsolete(connection, data, principal); connection.SubmitChanges(); if (mode == TransactionMode.Commit) { tx.Commit(); } else { tx.Rollback(); } var args = new PostPersistenceEventArgs <TData>(data, principal) { Mode = mode }; this.Obsoleted?.Invoke(this, args); return(data); } catch (Exception e) { this.m_tracer.TraceEvent(TraceEventType.Error, 0, "Error : {0}", e); tx?.Rollback(); throw new DataPersistenceException(e.Message, e); } finally { } } }
/// <summary> /// Inserts the specified data /// </summary> public TData Insert(TData data, IPrincipal principal, TransactionMode mode) { if (data == null) { throw new ArgumentNullException(nameof(data)); } PrePersistenceEventArgs <TData> preArgs = new PrePersistenceEventArgs <TData>(data, principal); this.Inserting?.Invoke(this, preArgs); if (preArgs.Cancel) { this.m_tracer.TraceEvent(TraceEventType.Warning, 0, "Pre-Event handler indicates abort insert for {0}", data); return(data); } // Persist object using (var connection = new ModelDataContext(m_configuration.ReadWriteConnectionString)) { DbTransaction tx = null; try { connection.Connection.Open(); connection.Transaction = tx = connection.Connection.BeginTransaction(); if (m_configuration.TraceSql) { connection.Log = new LinqTraceWriter(); } // Disable inserting duplicate classified objects var existing = data.TryGetExisting(connection, principal); if (existing != null) { if (m_configuration.AutoUpdateExisting) { this.m_tracer.TraceEvent(TraceEventType.Warning, 0, "INSERT WOULD RESULT IN DUPLICATE CLASSIFIER: UPDATING INSTEAD {0}", data); data = this.Update(connection, data, principal); } else { throw new DuplicateKeyException(data); } } else { this.m_tracer.TraceEvent(TraceEventType.Verbose, 0, "INSERT {0}", data); data = this.Insert(connection, data, principal); } connection.SubmitChanges(); if (mode == TransactionMode.Commit) { tx.Commit(); } else { tx.Rollback(); } var args = new PostPersistenceEventArgs <TData>(data, principal) { Mode = mode }; this.Inserted?.Invoke(this, args); return(data); } catch (Exception e) { this.m_tracer.TraceEvent(TraceEventType.Error, 0, "Error : {0}", e); tx?.Rollback(); throw new DataPersistenceException(e.Message, e); } finally { } } }
/// <summary> /// Obsoletes the specified storage data. /// </summary> /// <param name="storageData">The storage data.</param> /// <param name="principal">The principal.</param> /// <param name="mode">The mode.</param> /// <returns>TModel.</returns> public TModel Obsolete(TModel storageData, IPrincipal principal, TransactionMode mode) { if (storageData == null) { throw new ArgumentNullException(nameof(storageData), "Value cannot be null"); } if (!storageData.Key.HasValue || storageData.Key == Guid.Empty) { throw new InvalidOperationException("Data missing key"); } var prePersistenceEventArgs = new PrePersistenceEventArgs <TModel>(storageData); this.Obsoleting?.Invoke(this, prePersistenceEventArgs); if (prePersistenceEventArgs.Cancel) { traceSource.TraceEvent(TraceEventType.Warning, 0, $"Pre-event handler indicates abort for {storageData}"); return(storageData); } using (var connection = Configuration.Provider.GetWriteConnection()) { connection.Open(); using (var transaction = connection.BeginTransaction()) { try { this.traceSource.TraceEvent(TraceEventType.Verbose, 0, $"OBSOLETE {storageData}"); storageData = this.Obsolete(connection, storageData, principal); if (mode == TransactionMode.Commit) { transaction.Commit(); } else { transaction.Rollback(); } var args = new PostPersistenceEventArgs <TModel>(storageData, principal) { Mode = mode }; this.Obsoleted?.Invoke(this, args); return(storageData); } catch (Exception e) { traceSource.TraceEvent(TraceEventType.Error, 0, $"Error obsoleting: {storageData}"); transaction.Rollback(); throw new DataPersistenceException(e.Message, e); } } } }