/////////////////////////////////////////////////////////// // NotifySubscriber.cs // Implementation of Class NotifySubscriber // CSLA type: Editable Root // 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; namespace GZTW.AyaNova.BLL { /// /// A user who is subscribing to notification events /// [Serializable] public class NotifySubscriber : BusinessBase { #region Attributes private bool bReadOnly; private Guid mID; private Guid mUserID; private SmartDate mCreated; private SmartDate mModified; private bool mActive; private Guid mCreator; private Guid mModifier; //Child collections private NotifySubscriptions mSubscriptions; #endregion #region Constructor /// /// Private constructor to prevent direct instantiation /// private NotifySubscriber() { //Set to read / write initially so that properties //can be set bReadOnly=false; //New ID mID = Guid.NewGuid(); Active=true; mSubscriptions=NotifySubscriptions.NewItems(); //Set record history to defaults mCreated = new SmartDate(DBUtil.CurrentWorkingDateTime); mModified=new SmartDate(); mCreator=Guid.Empty; mModifier=Guid.Empty; } #endregion #region Business properties /// /// Get internal id number Read only property because it's set internally, not /// externally /// public Guid ID { get { return mID; } } /// /// Get User id Read only property because it's set on creation / fetch, not /// externally /// public Guid UserID { get { return mUserID; } } /// /// Get created date /// /// /// public string Created { get { return mCreated.ToString(); } } /// /// Get modified date /// /// /// public string Modified { get { return mModified.ToString(); } } /// /// Get user record ID of person who created this record /// /// /// public Guid Creator { get { return mCreator; } } /// /// Get user ID of person who modified this record /// /// /// public Guid Modifier { get { return mModifier; } } /// /// Get /set active status of NotifySubscriber /// public bool Active { get { return mActive; } set { if(bReadOnly) ThrowSetError(); else { if(mActive!=value) { mActive = value; MarkDirty(); } } } } /// /// Collection of Subscriptions selected for this subscriber /// public NotifySubscriptions Subscriptions { get { return mSubscriptions; } } /// /// Throw an error when a read only user /// tries to set a property /// (this should normally never be called unless someone is using the developer api since the UI /// should prevent it from happening initially) /// private void ThrowSetError() { throw new System.Security.SecurityException ( string.Format ( LocalizedTextTable.GetLocalizedTextDirect("Error.Security.NotAuthorizedToChange"), LocalizedTextTable.GetLocalizedTextDirect("O.Notification") ) ); } #endregion #region System.object overrides /// /// /// /// public override string ToString() { return "NotifySubscriber" + mID.ToString(); } /// /// /// /// /// public override bool Equals(Object obj) { if ( obj == null || GetType ( ) != obj.GetType ( ) ) return false; NotifySubscriber c=(NotifySubscriber)obj; return mID==c.mID; } /// /// /// /// public override int GetHashCode() { return ("NotifySubscriber"+mID).GetHashCode(); } #endregion #region Static methods /// /// Fetch existing NotifySubscriber /// for indicated user ID. /// /// If one doesn't exist it will automatically be created. /// /// NotifySubscriber public static NotifySubscriber GetItem(Guid _UserID) { if(AyaBizUtils.Right("Object.Notification")>(int)SecurityLevelTypes.NoAccess) { NotifySubscriber ns= (NotifySubscriber)DataPortal.Fetch(new Criteria(_UserID)); //If there is an existing record it's UserID value will not be empty so return it if(ns.UserID!=Guid.Empty) return ns; else { //No existing record, so make a new object and return it to be saved later ns= new NotifySubscriber(); ns.mUserID=_UserID; return ns; } } else throw new System.Security.SecurityException( string.Format( LocalizedTextTable.GetLocalizedTextDirect("Error.Security.NotAuthorizedToRetrieve"), LocalizedTextTable.GetLocalizedTextDirect("O.Notification"))); } /// /// Delete NotifySubscriber for indicated user /// /// NotifySubscriber UserID public static void DeleteItem(Guid _UserID) { if(AyaBizUtils.Right("Object.Notification")>(int)SecurityLevelTypes.ReadWrite) DataPortal.Delete(new Criteria(_UserID)); else throw new System.Security.SecurityException( string.Format( LocalizedTextTable.GetLocalizedTextDirect("Error.Security.NotAuthorizedToDelete"), LocalizedTextTable.GetLocalizedTextDirect("O.Notification"))); } #endregion #region DAL DATA ACCESS #region Fetch /// /// protected override void DataPortal_Fetch(object Criteria) { //set to false to load items initially bReadOnly=false; Criteria crit = (Criteria)Criteria; SafeDataReader dr = null; try { dr=DBUtil.GetReaderFromSQLString("SELECT * FROM aNotifySubscriber WHERE aUserID=@ID;",crit.UserID); //NOTE: this is done a little differently here //we want to handle the fact that there may not be a notification subscriber //record for this user already by creating one. //the call to getitem will never fail this way, if there is no existing record fetched //it will just create one and return that instead if(dr.Read()) { //Standard fields mUserID=crit.UserID; mCreated=DBUtil.ToLocal(dr.GetSmartDate("aCreated")); mModified=DBUtil.ToLocal(dr.GetSmartDate("aModified")); mCreator=dr.GetGuid("aCreator"); mModifier=dr.GetGuid("aModifier"); //NotifySubscriber fields mActive=dr.GetBoolean("AACTIVE"); if(dr!=null) dr.Close(); //Load child collection objects //Rates dr=DBUtil.GetReaderFromSQLString( "SELECT * " + "FROM aNotifySubscription WHERE aUserID=@ID;" ,crit.UserID); mSubscriptions = NotifySubscriptions.GetItems(dr); if(dr!=null) dr.Close(); } else//indicate failure to read by setting UserID to empty mUserID=Guid.Empty; } finally { if(dr!=null) dr.Close(); } MarkOld(); //Get access rights level bReadOnly=AyaBizUtils.Right("Object.Notification")<(int)SecurityLevelTypes.ReadWrite; } #endregion fetch #region Update /// /// Called by DataPortal to delete/add/update data into the database /// protected override void DataPortal_Update() { //Probably not necessary to check this, if it turns out to be //then a custom check needs to be done because the main id field is called //"UserID", not "ID" // // If not a new record, check if record was modified // //by another user since original retrieval: // if(!IsNew) // DBUtil.CheckSafeToUpdate(this.mModified.Date,this.mID,"aNotifySubscriber"); // #region Delete if(IsDeleted) { if(!IsNew) { //Delete object and child objects DBCommandWrapper cmDelete = DBUtil.GetCommandFromSQL("DELETE FROM aNotifySubscriber WHERE aUserID = @UserID;"); cmDelete.AddInParameter("@UserID",DbType.Guid,this.mUserID); DBCommandWrapper cmDeleteChildren = DBUtil.GetCommandFromSQL("DELETE FROM aNotifySubscription WHERE aUserID = @UserID;"); cmDeleteChildren.AddInParameter("@UserID",DbType.Guid,mUserID); using (IDbConnection connection = DBUtil.DB.GetConnection()) { connection.Open(); IDbTransaction transaction = connection.BeginTransaction(); try { DBUtil.DB.ExecuteNonQuery(cmDelete, transaction); DBUtil.DB.ExecuteNonQuery(cmDeleteChildren, transaction); // Commit the transaction transaction.Commit(); } catch { // Rollback transaction transaction.Rollback(); throw; } finally { connection.Close(); } } //----------------------------- } MarkNew(); return; } #endregion #region Add / Update //get modification time temporarily, if update succeeds then //set to this time System.DateTime dtModified = DBUtil.CurrentWorkingDateTime; DBCommandWrapper cm = null; if(IsNew)//Add or update? cm=DBUtil.GetCommandFromSQL( "INSERT INTO aNotifySubscriber (aUserID, AACTIVE, aCreated,aModified,aCreator,aModifier) " + "VALUES (@UserID,@Active,@Created,@Modified,@CurrentUserID,@CurrentUserID)" ); else cm=DBUtil.GetCommandFromSQL( "UPDATE aNotifySubscriber SET AACTIVE=@Active, aModifier=@CurrentUserID, " + "aModified=@Modified WHERE " + "aUserID=@UserID" ); cm.AddInParameter("@UserID",DbType.Guid,mUserID); cm.AddInParameter("@Active",DbType.Boolean, mActive); //Standard fields cm.AddInParameter("@CurrentUserID",DbType.Guid, CurrentUserID); cm.AddInParameter("@Created",DbType.DateTime, DBUtil.ToUTC(mCreated).DBValue); cm.AddInParameter("@Modified",DbType.DateTime, DBUtil.ToUTC(dtModified)); using (IDbConnection connection = DBUtil.DB.GetConnection()) { connection.Open(); IDbTransaction transaction = connection.BeginTransaction(); try { DBUtil.DB.ExecuteNonQuery(cm, transaction); //Update child objects mSubscriptions.Update(this,transaction); MarkOld();//db is now synched with object // Commit the transaction transaction.Commit(); } catch { // Rollback transaction transaction.Rollback(); throw; } finally { connection.Close(); } //Successful update so //change modification time to match this.mModified.Date=dtModified; } #endregion } #endregion update #region Delete /// /// Remove a NotifySubscriber record from the database /// /// protected override void DataPortal_Delete(object Criteria) { Criteria crit = (Criteria)Criteria; //Delete object and child objects DBCommandWrapper cmDelete = DBUtil.GetCommandFromSQL("DELETE FROM aNotifySubscriber WHERE aUserID = @UserID;"); cmDelete.AddInParameter("@UserID",DbType.Guid,crit.UserID); DBCommandWrapper cmDeleteChildren = DBUtil.GetCommandFromSQL("DELETE FROM aNotifySubscription WHERE aUserID = @UserID;"); cmDeleteChildren.AddInParameter("@UserID",DbType.Guid,crit.UserID); using (IDbConnection connection = DBUtil.DB.GetConnection()) { connection.Open(); IDbTransaction transaction = connection.BeginTransaction(); try { DBUtil.DB.ExecuteNonQuery(cmDelete, transaction); //call shared delete on subscriptions collection //to ensure notifyeventofinterest get's it's subscriber //count updated properly //and to ensure that any pending events for this subscriber are //removed as well NotifySubscriptions.DeleteItems(crit.UserID,transaction); // Commit the transaction transaction.Commit(); } catch { // Rollback transaction transaction.Rollback(); throw; } finally { connection.Close(); } } } #endregion delete #endregion #region Override IsValid / IsDirty //Override base class version if there are child objects /// /// /// public override bool IsValid { get { return base.IsValid && this.mSubscriptions.IsValid; } } /// /// /// public override bool IsDirty { get { return base.IsDirty || this.mSubscriptions.IsDirty; } } #endregion #region criteria /// /// Criteria for identifying existing object /// [Serializable] private class Criteria { public Guid UserID; public Criteria(Guid _UserID) { UserID=_UserID; } } #endregion }//end NotifySubscriber }//end namespace GZTW.AyaNova.BLL