Files
ayanova7/source/bizobjects/AyaLib/GZTW.AyaNova.BLL/NotifyEventOfInterestFetcher.cs
2018-06-29 19:47:36 +00:00

362 lines
11 KiB
C#

///////////////////////////////////////////////////////////
// Bool.cs
// Implementation of Class NotifyEventOfInterestFetcher
// CSLA type: Read-only object
// Created on: 04-Oct-2005
// Object design: John
// Coded: John 04-Oct-2005
///////////////////////////////////////////////////////////
using System;
using System.Data;
using CSLA.Data;
using GZTW.Data;
using CSLA;
using System.Threading;
using CSLA.Security;
using System.Collections;
namespace GZTW.AyaNova.BLL
{
#pragma warning disable 1591
/// <summary>
/// Used for determining if an event is of interest for notification purposes
/// </summary>
[Serializable,System.ComponentModel.EditorBrowsable(System.ComponentModel.EditorBrowsableState.Never)]
public class NotifyEventOfInterestFetcher : ReadOnlyBase
{
// Create a logger for use in this class
//private static readonly log4net.ILog log = log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);
#region Attributes
private bool mInterested=false;
#endregion
#region Constructor
/// <summary>
/// Private constructor to prevent direct instantiation
/// </summary>
private NotifyEventOfInterestFetcher()
{
}
#endregion
#region Business properties
public bool Interested
{
get
{
return mInterested;
}
}
#endregion
#region System.Object overrides
#endregion
#region Static methods
/// <summary>
/// Load a fetcher for event
/// </summary>
/// <param name="RootObjectType"></param>
/// <param name="EventType"></param>
/// <param name="GuidValue"></param>
/// <returns></returns>
private static NotifyEventOfInterestFetcher GetItem(RootObjectTypes RootObjectType, int EventType, Guid GuidValue)//case 1964 added guidvalue
{
////case 1039 //log.Debug("NotifyEventOfInterestFetcher.GetItem(" + RootObjectType.ToString() + " Event ID: " + EventType.ToString() + ")");
return (NotifyEventOfInterestFetcher)DataPortal.Fetch(new Criteria( RootObjectType, EventType, GuidValue));
}
/// <summary>
/// Check to see if there is interest in the event and object specified
/// </summary>
/// <param name="RootObjectType"></param>
/// <param name="EventType"></param>
/// <param name="GuidValue"></param>
/// <returns></returns>
public static bool IsEventInteresting(RootObjectTypes RootObjectType, int EventType, Guid GuidValue)
{
NotifyEventOfInterestFetcher neif= NotifyEventOfInterestFetcher.GetItem(RootObjectType,EventType, GuidValue);
return neif.Interested;
}
/// <summary>
/// Called internally by the NotifySubscription class when a user deletes or creates a
/// notification subscription.
///
/// This ensures that the EventOfInterest table is kept up to date with subscriptions
/// </summary>
/// <param name="RootObjectType"></param>
/// <param name="EventType"></param>
/// <param name="Subscribe"></param>
/// <param name="GuidValue">Optional event specific data</param>
internal static void Subscribe(RootObjectTypes RootObjectType,int EventType, Guid GuidValue, bool Subscribe)
{
EventOfInterestManager.Subscribe(RootObjectType, EventType, GuidValue, Subscribe);
}
#endregion
#region DAL DATA ACCESS
///
/// <param Bool="Criteria"></param>
protected override void DataPortal_Fetch(object Criteria)
{
Criteria crit = (Criteria)Criteria;
//
SafeDataReader dr = null;
try
{
//bugbug: This is not checking with guid value included so
//the result is random and could be false negative if there is another with same type and event but different guid
DBCommandWrapper dbCommandWrapper = DBUtil.DB.GetSqlStringCommandWrapper(
"SELECT aSubscriberCount FROM aNotifyEventOfInterest " +
"WHERE (aRootObjectType = @RootObjectType) " +
"AND (aEventType = @EventType) " +
(crit.GuidValue == Guid.Empty ? "" : "AND (aGuidValue = @GuidValue)")//case 1964
);
dbCommandWrapper.AddInParameter("@RootObjectType",DbType.Int16,(int)crit.RootObjectType);
dbCommandWrapper.AddInParameter("@EventType",DbType.Int16,crit.EventType);
//case 1964
if (crit.GuidValue != Guid.Empty)
dbCommandWrapper.AddInParameter("@GuidValue", DbType.Guid, crit.GuidValue);
dr = new SafeDataReader(DBUtil.DB.ExecuteReader(dbCommandWrapper));
if(dr.Read())
{
//*******************************************
//Are there more than zero subscribers to this event?
if(dr.GetInt32("aSubscriberCount")<1)
this.mInterested=false;//Nope
else//There is at least one subscriber so yes, there is interest
this.mInterested=true;
//*******************************************
}
else//couldn't read the record, probably no one has subscribed yet so no, there is no interest in the event
this.mInterested=false;
}
finally
{
if(dr!=null) dr.Close();
}
}
#endregion
#region criteria
/// <summary>
/// Criteria for identifying existing object
/// </summary>
[Serializable]
private class Criteria
{
public RootObjectTypes RootObjectType;
public int EventType;
//case 1964
public Guid GuidValue;
public Criteria(RootObjectTypes _RootObject, int _EventType, Guid _GuidValue)
{
RootObjectType=_RootObject;
EventType=_EventType;
//case 1964
GuidValue = _GuidValue;
}
}
#endregion
#region Add events of interest / update subscriber count
/// <summary>
/// Add events of interest / update subscriber count
/// </summary>
[Serializable, System.ComponentModel.Browsable(false)]
public class EventOfInterestManager//DO_NOT_OBFUSCATE
{
bool _Subscribe=false;
RootObjectTypes _RootObjectType;
int _EventType;
Guid _GuidValue;
public EventOfInterestManager(RootObjectTypes RootObjectType,int EventType, Guid GuidValue, bool Subscribe)
{
_Subscribe=Subscribe;
_RootObjectType=RootObjectType;
_EventType=EventType;
_GuidValue=GuidValue;
}
public static void Subscribe(RootObjectTypes RootObjectType,int EventType, Guid GuidValue, bool Subscribe)
{
DataPortal.Update(new EventOfInterestManager(RootObjectType, EventType, GuidValue, Subscribe));
}
public void DataPortal_Update()
{
//This method must be rock solid or there could be inconsistent values
//in notifyevent causing event's to be Processed un-neccessarily or
//worse event's to not be Processed because it appears there is non interest
//in them due to an invalid "balance" in the subscriber count.
//Start a transaction here and locklevel=System.Data.IsolationLevel.Serializable
using (IDbConnection connection = DBUtil.DB.GetConnection())
{
connection.Open();
IDbTransaction transaction = connection.BeginTransaction(System.Data.IsolationLevel.Serializable);
SmartDate mCreated = new SmartDate(DBUtil.CurrentWorkingDateTime);
int nCurrentCount=0;
bool nRecordExists=false;
SafeDataReader dr = null;
DBCommandWrapper cm = null;
try
{
DBCommandWrapper dbCommandWrapper = DBUtil.DB.GetSqlStringCommandWrapper(
"SELECT aSubscriberCount, aCreated FROM aNotifyEventOfInterest " +
"WHERE (aRootObjectType = @RootObjectType) " +
"AND (aEventType = @EventType) " +
(_GuidValue==Guid.Empty?"":"AND (aGuidValue = @GuidValue)")
);
dbCommandWrapper.AddInParameter("@RootObjectType",DbType.Int16,(int)_RootObjectType);
dbCommandWrapper.AddInParameter("@EventType",DbType.Int16,_EventType);
if(_GuidValue!=Guid.Empty)
dbCommandWrapper.AddInParameter("@GuidValue",DbType.Guid,_GuidValue);
dr = new SafeDataReader(DBUtil.DB.ExecuteReader(dbCommandWrapper,transaction));
if(dr.Read())
{
//*******************************************
nCurrentCount=dr.GetInt32("aSubscriberCount");
mCreated=DBUtil.ToLocal(dr.GetSmartDate("aCreated"));
nRecordExists=true;
//*******************************************
}
dr.Close();
//If they are unsubscribing and there is no current record for this event of interest
//then just bail. This shouldnt' happen unless there is something funky going on
//but covers all eventualities just in case
if(!_Subscribe && !nRecordExists)
{
throw(new ApplicationException(
"INTERNAL ERROR: EventOfInterestManager - error attempting an unsubscribe.\r\n" +
"No matching record in NotifyEventOfInterest table.\r\n" +
"Please report this error immediately to AyaNova support for analysis."));
}
//If there is an existing record then update it
if(nRecordExists)
{
//set the current count to what it *should* be
if(_Subscribe)
nCurrentCount++;
else
nCurrentCount--;
//Just to cover our bases, there shouldn't really be less than zero subscribers
if(nCurrentCount < 0) nCurrentCount=0;
//Update database
cm=DBUtil.GetCommandFromSQL(
"UPDATE aNotifyEventOfInterest SET aSubscriberCount=@SubscriberCount, aModified=@Modified, " +
"aModifier=@CurrentUserID " +
"WHERE (aRootObjectType = @RootObjectType) " +
"AND (aEventType = @EventType)"+
(_GuidValue==Guid.Empty?"":"AND (aGuidValue = @GuidValue)"));
if(_GuidValue!=Guid.Empty)
cm.AddInParameter("@GuidValue",DbType.Guid,_GuidValue);
}
else
{
nCurrentCount=1;
//add a new event of interest and set it to count 1
cm=DBUtil.GetCommandFromSQL(
"INSERT INTO aNotifyEventOfInterest (aRootObjectType, aEventType, aGuidValue, aSubscriberCount, " +
"aCreated, aModified, aCreator,aModifier) " +
"VALUES (@RootObjectType,@EventType, @GuidValue, @SubscriberCount, " +
"@Created, @Modified, @CurrentUserID,@CurrentUserID)"
);
cm.AddInParameter("@GuidValue",DbType.Guid,_GuidValue);
}
cm.AddInParameter("@RootObjectType",DbType.Int16,(int)_RootObjectType);
cm.AddInParameter("@EventType",DbType.Int16,_EventType);
cm.AddInParameter("@SubscriberCount",DbType.Int32,nCurrentCount);
//Standard fields
cm.AddInParameter("@CurrentUserID",DbType.Guid, User.CurrentThreadUserID);
cm.AddInParameter("@Created",DbType.DateTime, DBUtil.ToUTC(mCreated.Date));
cm.AddInParameter("@Modified", DbType.DateTime, DBUtil.ToUTC(DBUtil.CurrentWorkingDateTime));
DBUtil.DB.ExecuteNonQuery(cm,transaction);
transaction.Commit();
}
catch
{
// Rollback transaction
transaction.Rollback();
throw;
}
finally
{
if(dr!=null) dr.Close();
connection.Close();
}
}//end of using block
}//end of dataportal_update method
}//end of inner EventOfInterestManager class
#endregion add events of interest / update subscriber count
}//end of Outer NotifyEventOfInterestFetcherClass
#pragma warning restore 1591
}//end Namespace