/// <summary> /// Reload the User Defaults if called on the server. /// /// </summary> /// <returns>void</returns> public static void ReloadCachedUserDefaultsOnServer() { TRemote.MSysMan.Maintenance.UserDefaults.WebConnectors.ReloadUserDefaults(Ict.Petra.Shared.UserInfo.GUserInfo.UserID, out UUserDefaultsDataTable); UUserDefaults = new DataView(UUserDefaultsDataTable); UUserDefaults.Sort = SUserDefaultsTable.GetDefaultCodeDBName(); }
public static void UpdateUserDefaultsOnClient(String AUserName, SUserDefaultsTable AChangedUserDefaultsDT) { String ChangedUserDefaultCodes; String ChangedUserDefaultValues; String ChangedUserDefaultModIds; Int16 Counter; ChangedUserDefaultCodes = ""; ChangedUserDefaultValues = ""; ChangedUserDefaultModIds = ""; if (AChangedUserDefaultsDT != null) { for (Counter = 0; Counter <= AChangedUserDefaultsDT.Rows.Count - 1; Counter += 1) { ChangedUserDefaultCodes = ChangedUserDefaultCodes + RemotingConstants.GCLIENTTASKPARAMETER_SEPARATOR + AChangedUserDefaultsDT[Counter].DefaultCode; ChangedUserDefaultValues = ChangedUserDefaultValues + RemotingConstants.GCLIENTTASKPARAMETER_SEPARATOR + AChangedUserDefaultsDT[Counter].DefaultValue; ChangedUserDefaultModIds = ChangedUserDefaultModIds + RemotingConstants.GCLIENTTASKPARAMETER_SEPARATOR + AChangedUserDefaultsDT[Counter].ModificationId; } if (ChangedUserDefaultCodes != "") { // Strip off leading GCLIENTTASKPARAMETER_SEPARATOR ChangedUserDefaultCodes = ChangedUserDefaultCodes.Substring(1, ChangedUserDefaultCodes.Length - 1); ChangedUserDefaultValues = ChangedUserDefaultValues.Substring(1, ChangedUserDefaultValues.Length - 1); ChangedUserDefaultModIds = ChangedUserDefaultModIds.Substring(1, ChangedUserDefaultModIds.Length - 1); UpdateUserDefaultsOnClient(AUserName, ChangedUserDefaultCodes, ChangedUserDefaultValues, ChangedUserDefaultModIds, false); } } }
public static String GetUserDefault(String AKey, String ADefaultValue, TDataBase ADataBase = null) { String ReturnValue = ""; TDataBase db = DBAccess.Connect("GetUserDefault", ADataBase); TDBTransaction ReadTransaction = new TDBTransaction(); db.ReadTransaction(ref ReadTransaction, delegate { if (!SUserDefaultsAccess.Exists(UserInfo.GetUserInfo().UserID, AKey, ReadTransaction)) { ReturnValue = ADefaultValue; } else { SUserDefaultsTable DT = SUserDefaultsAccess.LoadByPrimaryKey(UserInfo.GetUserInfo().UserID, AKey, ReadTransaction); ReturnValue = DT[0].DefaultValue; } }); if (ADataBase == null) { db.CloseDBConnection(); } return(ReturnValue); }
/// <summary> /// todoComment /// </summary> /// <param name="AKey"></param> /// <param name="AValue"></param> public static void SetUserDefault(String AKey, String AValue) { Int32 FoundInRow; DataRowView Tmp; FoundInRow = UUserDefaults.Find(AKey); if (FoundInRow != -1) { // User default found if (AValue != UUserDefaults[FoundInRow][SUserDefaultsTable.GetDefaultValueDBName()].ToString()) { // Update only if the value is actually different UUserDefaults[FoundInRow][SUserDefaultsTable.GetDefaultValueDBName()] = AValue; } } else { // User default not found, add it to the user defaults table Tmp = UUserDefaults.AddNew(); Tmp[SUserDefaultsTable.GetUserIdDBName()] = Ict.Petra.Shared.UserInfo.GUserInfo.UserID; Tmp[SUserDefaultsTable.GetDefaultCodeDBName()] = AKey; Tmp[SUserDefaultsTable.GetDefaultValueDBName()] = AValue; Tmp.EndEdit(); } }
/// <summary> /// initialise static variables /// </summary> public static void InitUserDefaults() { TRemote.MSysMan.Maintenance.UserDefaults.WebConnectors.GetUserDefaults(Ict.Petra.Shared.UserInfo.GUserInfo.UserID, out UUserDefaultsDataTable); UUserDefaults = new DataView(UUserDefaultsDataTable); UUserDefaults.Sort = SUserDefaultsTable.GetDefaultCodeDBName(); FIsInitialised = true; }
public static void InitializeUnit() { UReadWriteLock = new System.Threading.ReaderWriterLock(); UTableCached = false; UUserDefaultsDS = new DataSet(); UUserDefaultsDS.Tables.Add(new SUserDefaultsTable(USERDEFAULTSDT_NAME)); UUserDefaultsDT = (SUserDefaultsTable)UUserDefaultsDS.Tables[USERDEFAULTSDT_NAME]; UUserDefaultsDV = new DataView(UUserDefaultsDT); UUserDefaultsDV.Sort = SUserDefaultsTable.GetDefaultCodeDBName(); }
/// <summary> /// Update the server-side-held UserDefaults for this session of the same user and then the client-side-held /// UserDefaults, too. /// </summary> public static void ReloadCachedUserDefaultsOnServerAndClient() { // TLogging.Log("ReloadCachedUserDefaultsOnServerAndClient got called"); // First update the server-side-held UserDefaults for this session of the same user... TRemote.MSysMan.Maintenance.UserDefaults.WebConnectors.ReloadUserDefaults(UserInfo.GUserInfo.UserID, out UUserDefaultsDataTable); // ...then the client-side-held UserDefaults, too! UUserDefaults = new DataView(UUserDefaultsDataTable); UUserDefaults.Sort = SUserDefaultsTable.GetDefaultCodeDBName(); }
public static void SetDefault(String AKey, object AValue, Boolean ASendUpdateInfoToClient = true, TDataBase ADataBase = null) { SUserDefaultsTable UserDefaultsDataTable; TDataBase db = DBAccess.Connect("LoadUserDefaultsTable", ADataBase); TDBTransaction WriteTransaction = new TDBTransaction(); bool SubmitOK = false; db.WriteTransaction(ref WriteTransaction, ref SubmitOK, delegate { LoadUserDefaultsTable(UserInfo.GetUserInfo().UserID, out UserDefaultsDataTable, db); DataView view = new DataView(UserDefaultsDataTable); view.Sort = SUserDefaultsTable.GetDefaultCodeDBName(); int FoundInRow = view.Find(AKey); if (FoundInRow != -1) { // User default found if (AValue.ToString() != view[FoundInRow][SUserDefaultsTable.GetDefaultValueDBName()].ToString()) { // Update only if the value is actually different view[FoundInRow][SUserDefaultsTable.GetDefaultValueDBName()] = AValue.ToString(); SubmitOK = true; } } else { // User default not found, add it to the user defaults table SUserDefaultsRow row = UserDefaultsDataTable.NewRowTyped(); row.UserId = UserInfo.GetUserInfo().UserID; row.DefaultCode = AKey; row.DefaultValue = AValue.ToString(); UserDefaultsDataTable.Rows.Add(row); FoundInRow = view.Find(AKey); SubmitOK = true; } if (SubmitOK) { SUserDefaultsAccess.SubmitChanges(UserDefaultsDataTable, WriteTransaction); if (ASendUpdateInfoToClient) { UpdateUserDefaultsOnClient(UserInfo.GetUserInfo().UserID, AKey, AValue.ToString(), view[FoundInRow][SUserDefaultsTable.GetModificationIdDBName()].ToString()); } } }); }
/// <summary> /// Refreshes a UserDefault in the local Cache that has been updated on the /// Server side or in the DB. /// /// @comment This is needed for the case where several PetraClient instances of /// the same Petra User are running and they are updating the same UserDefault. /// On detecting such a 'collision', the PetraServer queues a ClientTask to /// refresh the specific UserDefault in the local Cache, and the /// TClientTaskInstance.Execute background thread then invokes this function. /// /// </summary> /// <param name="AChangedUserDefaultCode">UserDefault Code to update</param> /// <param name="AChangedUserDefaultValue">Changed UserDefault Value</param> /// <param name="AChangedUserDefaultModId">ModificationID of the changed UserDefault /// DataRow /// </param> /// <returns>void</returns> public static void RefreshCachedUserDefault(String AChangedUserDefaultCode, String AChangedUserDefaultValue, String AChangedUserDefaultModId) { // TLogging.Log('Refreshing DefaultCode ''' + AChangedUserDefaultCode + ''' with Value: ''' + AChangedUserDefaultValue + ''''); // Split String into String Array String[] ChangedUserDefaultCodes = AChangedUserDefaultCode.Split(new Char[] { RemotingConstants.GCLIENTTASKPARAMETER_SEPARATOR[0] }); String[] ChangedUserDefaultValues = AChangedUserDefaultValue.Split(new Char[] { RemotingConstants.GCLIENTTASKPARAMETER_SEPARATOR[0] }); String[] ChangedUserDefaultModIds = AChangedUserDefaultModId.Split(new Char[] { RemotingConstants.GCLIENTTASKPARAMETER_SEPARATOR[0] }); for (Int16 Counter = 0; Counter <= ChangedUserDefaultCodes.Length - 1; Counter += 1) { // TLogging.Log('Refreshing UserDefault ''' + ChangedUserDefaultCodes[Counter] + ''' with value ''' + ChangedUserDefaultValues[Counter] + ''' (ModificationID: ''' + ChangedUserDefaultModIds[Counter] + ''''); Int32 FoundInRow = UUserDefaults.Find(ChangedUserDefaultCodes[Counter]); if (FoundInRow != -1) { // User default found // TLogging.Log('Existing UserDefault ''' + // UUserDefaults.Item[FoundInRow].Item[SUserDefaultsTable.GetDefaultCodeDBName].ToString + ''' with value ''' + // UUserDefaults.Item[FoundInRow].Item[SUserDefaultsTable.GetDefaultValueDBName].ToString + ''' (ModificationID: ''' + // UUserDefaults.Item[FoundInRow].Item[SUserDefaultsTable.GetModificationIDDBName].ToString + ''''); if (ChangedUserDefaultValues[Counter] != UUserDefaults[FoundInRow][SUserDefaultsTable.GetDefaultValueDBName()].ToString()) { // Update only if the value is actually different UUserDefaults[FoundInRow][SUserDefaultsTable.GetDefaultValueDBName()] = ChangedUserDefaultValues[Counter]; } UUserDefaults[FoundInRow][SUserDefaultsTable.GetModificationIdDBName()] = Convert.ToDateTime(ChangedUserDefaultModIds[Counter]); // Mark this refreshed UserDefault as unchanged UUserDefaults[FoundInRow].Row.AcceptChanges(); } else { // User default not found, add it to the user defaults table // TLogging.Log('UserDefault doesn''t exist yet > creating new one'); DataRowView Tmp = UUserDefaults.AddNew(); Tmp[SUserDefaultsTable.GetUserIdDBName()] = Ict.Petra.Shared.UserInfo.GUserInfo.UserID; Tmp[SUserDefaultsTable.GetDefaultCodeDBName()] = ChangedUserDefaultCodes[Counter]; Tmp[SUserDefaultsTable.GetDefaultValueDBName()] = ChangedUserDefaultValues[Counter]; Tmp[SUserDefaultsTable.GetModificationIdDBName()] = ChangedUserDefaultModIds[Counter]; Tmp.EndEdit(); // Mark this refreshed UserDefault as unchanged Tmp.Row.AcceptChanges(); // TLogging.Log('UserDefault: new Row added, RowState: ' + Enum(Tmp.Row.RowState).ToString("G")); } } }
public static Boolean LoadUserDefaultsTable(String AUserName, out SUserDefaultsTable AUserDefaultsDataTable, TDataBase ADataBase = null) { Boolean ReturnValue = false; TDataBase db = DBAccess.Connect("LoadUserDefaultsTable", ADataBase); TDBTransaction ReadTransaction = null; bool NewTransaction = false; try { ReadTransaction = db.GetNewOrExistingTransaction(IsolationLevel.ReadCommitted, out NewTransaction); if (SUserDefaultsAccess.CountViaSUser(AUserName, ReadTransaction) != 0) { AUserDefaultsDataTable = SUserDefaultsAccess.LoadViaSUser(AUserName, null, ReadTransaction, StringHelper.InitStrArr(new string[] { "ORDER BY", SUserDefaultsTable.GetDefaultCodeDBName() }), 0, 0); AUserDefaultsDataTable.AcceptChanges(); } else { AUserDefaultsDataTable = new SUserDefaultsTable(); } ReturnValue = true; } finally { if (NewTransaction && (ReadTransaction != null)) { ReadTransaction.Rollback(); TLogging.LogAtLevel(9, "TUserDefaults.LoadUserDefaultsTable: rolled back own transaction."); } } if (ADataBase == null) { db.CloseDBConnection(); } return(ReturnValue); }
/// <summary> /// todoComment /// </summary> /// <param name="AKey"></param> /// <param name="ADefaultValue"></param> /// <returns></returns> public static String GetUserDefault(String AKey, String ADefaultValue) { String ReturnValue; Int32 FoundInRow; ReturnValue = ""; FoundInRow = UUserDefaults.Find(AKey); if (FoundInRow != -1) { // User default found ReturnValue = (UUserDefaults[FoundInRow][SUserDefaultsTable.GetDefaultValueDBName()]).ToString(); } else { // User default not found, return default value ReturnValue = ADefaultValue; } return(ReturnValue); }
/// <summary> /// Reload the User Defaults. /// Causes TUserDefaults to reload the cached User Defaults Table /// /// </summary> /// <returns>void</returns> public static void ReloadCachedUserDefaults() { // TLogging.Log("ReloadCachedUserDefaults got called"); SUserDefaultsTable TempUserDefaultsDataTable; DataSet UserDefaultsDS; // TODO 1 : ReaderWriterLock // reload user defaults from server TRemote.MSysMan.Maintenance.UserDefaults.WebConnectors.GetUserDefaults(Ict.Petra.Shared.UserInfo.GUserInfo.UserID, out TempUserDefaultsDataTable); // merge the current table with the one requested from the server so that client changes are not lost UserDefaultsDS = new DataSet(); UserDefaultsDS.Tables.Add(UUserDefaultsDataTable); UserDefaultsDS.Merge((DataTable)TempUserDefaultsDataTable, true, MissingSchemaAction.Ignore); UUserDefaultsDataTable = (SUserDefaultsTable)UserDefaultsDS.Tables[SUserDefaultsTable.GetTableName()]; UUserDefaults = new DataView(UUserDefaultsDataTable); UUserDefaults.Sort = SUserDefaultsTable.GetDefaultCodeDBName(); UserDefaultsDS.Tables.Remove(UUserDefaultsDataTable); // remove table again (otherwise problems when called a second time) }
public static void GetUserDefaults(String AUserName, out SUserDefaultsTable AUserDefaultsDataTable) { LoadUserDefaultsTable(AUserName, out AUserDefaultsDataTable); }
/// <summary> /// Refreshes a UserDefault in the local Cache that has been updated on the /// Server side or in the DB. /// /// @comment This is needed for the case where several PetraClient instances of /// the same Petra User are running and they are updating the same UserDefault. /// On detecting such a 'collision', the PetraServer queues a ClientTask to /// refresh the specific UserDefault in the local Cache, and the /// TClientTaskInstance.Execute background thread then invokes this function. /// /// </summary> /// <param name="AChangedUserDefaultCode">UserDefault Code to update</param> /// <param name="AChangedUserDefaultValue">Changed UserDefault Value</param> /// <param name="AChangedUserDefaultModId">ModificationID of the changed UserDefault /// DataRow /// </param> /// <param name="AClientID">The Client ID that requested the refreshing (-1 if none was specified).</param> /// <returns>void</returns> public static void RefreshCachedUserDefault(String AChangedUserDefaultCode, String AChangedUserDefaultValue, String AChangedUserDefaultModId, int AClientID) { // Split String into String Array String[] ChangedUserDefaultCodes = AChangedUserDefaultCode.Split(new Char[] { RemotingConstants.GCLIENTTASKPARAMETER_SEPARATOR[0] }); String[] ChangedUserDefaultValues = AChangedUserDefaultValue.Split(new Char[] { RemotingConstants.GCLIENTTASKPARAMETER_SEPARATOR[0] }); String[] ChangedUserDefaultModIds = AChangedUserDefaultModId.Split(new Char[] { RemotingConstants.GCLIENTTASKPARAMETER_SEPARATOR[0] }); // TLogging.Log("Refreshing User Default with DefaultCode '" + AChangedUserDefaultCode + "' with Value: '" + // AChangedUserDefaultValue + "'"); if ((AClientID == -1) || (AClientID == UserInfo.GUserInfo.ProcessID)) { for (Int16 Counter = 0; Counter <= ChangedUserDefaultCodes.Length - 1; Counter += 1) { // TLogging.Log("Refreshing single UserDefault '" + ChangedUserDefaultCodes[Counter].ToString() + "' with value '" + // ChangedUserDefaultValues[Counter] + "' (ModificationID: '" + // ChangedUserDefaultModIds[Counter].ToString() + "' (was sent from the same user session of this user on server)"); Int32 FoundInRow = UUserDefaults.Find(ChangedUserDefaultCodes[Counter]); if (FoundInRow != -1) { // User default found // TLogging.Log('Existing UserDefault ''' + // UUserDefaults.Item[FoundInRow].Item[SUserDefaultsTable.GetDefaultCodeDBName].ToString + ''' with value ''' + // UUserDefaults.Item[FoundInRow].Item[SUserDefaultsTable.GetDefaultValueDBName].ToString + ''' (ModificationID: ''' + // UUserDefaults.Item[FoundInRow].Item[SUserDefaultsTable.GetModificationIDDBName].ToString + ''''); if (ChangedUserDefaultValues[Counter] != UUserDefaults[FoundInRow][SUserDefaultsTable.GetDefaultValueDBName()].ToString()) { // Update only if the value is actually different UUserDefaults[FoundInRow][SUserDefaultsTable.GetDefaultValueDBName()] = ChangedUserDefaultValues[Counter]; } UUserDefaults[FoundInRow][SUserDefaultsTable.GetModificationIdDBName()] = Convert.ToDateTime( ChangedUserDefaultModIds[Counter]); // Mark this refreshed UserDefault as unchanged UUserDefaults[FoundInRow].Row.AcceptChanges(); } else { // User default not found, add it to the user defaults table // TLogging.Log('UserDefault doesn''t exist yet > creating new one'); DataRowView Tmp = UUserDefaults.AddNew(); Tmp[SUserDefaultsTable.GetUserIdDBName()] = Ict.Petra.Shared.UserInfo.GUserInfo.UserID; Tmp[SUserDefaultsTable.GetDefaultCodeDBName()] = ChangedUserDefaultCodes[Counter]; Tmp[SUserDefaultsTable.GetDefaultValueDBName()] = ChangedUserDefaultValues[Counter]; Tmp[SUserDefaultsTable.GetModificationIdDBName()] = ChangedUserDefaultModIds[Counter]; Tmp.EndEdit(); // Mark this refreshed UserDefault as unchanged Tmp.Row.AcceptChanges(); // TLogging.Log('UserDefault: new Row added, RowState: ' + Enum(Tmp.Row.RowState).ToString("G")); } } } else { // TLogging.Log("Refreshing ALL UserDefaults because the request for the refreshing of SINGLE user default was sent " + // "from a DIFFERENT user session of THIS user on the server [hence we need to first update the server-side-held " + // "UserDefaults for THIS session of the same user, and then the client-side-held UserDefaults, too])"); ReloadCachedUserDefaultsOnServerAndClient(); } }
public static void GetUserDefaults(String AUserName, out SUserDefaultsTable AUserDefaultsDataTable) { TLogging.LogAtLevel(7, "TUserDefaults.GetUserDefaults called."); if (UUserDefaultsDT == null) { // Initialisation needs to be done once! InitializeUnit(); } if (((AUserName == UserInfo.GUserInfo.UserID) && ((!UTableCached))) || (AUserName != UserInfo.GUserInfo.UserID)) { LoadUserDefaultsTable(AUserName, true, out AUserDefaultsDataTable); UTableCached = true; } try { try { TLogging.LogAtLevel(7, "TUserDefaults.GetUserDefaults waiting for a ReaderLock..."); /* Try to get a read lock on the cache table [We don't specify a timeout because (1) reading an emptied cache would lead to problems (it is emptied before the DB queries are issued), (2) reading the DB tables into the cached table *should be fairly quick] */ UReadWriteLock.AcquireReaderLock(SharedConstants.THREADING_WAIT_INFINITE); TLogging.LogAtLevel(7, "TUserDefaults.GetUserDefaults grabbed a ReaderLock."); AUserDefaultsDataTable = UUserDefaultsDT; } finally { // Release read lock on the cache table UReadWriteLock.ReleaseReaderLock(); TLogging.LogAtLevel(7, "TUserDefaults.GetUserDefaults released the ReaderLock."); } } catch (Exception exp) { TLogging.LogAtLevel(7, "Exception in TUserDefaults.GetUserDefaults: " + exp.ToString()); throw; } }
public static Boolean LoadUserDefaultsTable(String AUserName, Boolean AMergeChangesToServerSideCache, out SUserDefaultsTable AUserDefaultsDataTable) { Boolean ReturnValue; TDBTransaction ReadTransaction; Boolean NewTransaction = false; Boolean ReaderLockWasHeld; Boolean WriteLockTakenOut; LockCookie UpgradeLockCookie = new LockCookie(); TLogging.LogAtLevel(9, "TUserDefaults.LoadUserDefaultsTable called in the AppDomain " + Thread.GetDomain().FriendlyName + '.'); WriteLockTakenOut = false; ReaderLockWasHeld = false; try { try { try { ReadTransaction = DBAccess.GDBAccessObj.GetNewOrExistingTransaction(IsolationLevel.ReadCommitted, TEnforceIsolationLevel.eilMinimum, out NewTransaction); if (SUserDefaultsAccess.CountViaSUser(AUserName, ReadTransaction) != 0) { AUserDefaultsDataTable = SUserDefaultsAccess.LoadViaSUser(AUserName, null, ReadTransaction, StringHelper.InitStrArr(new string[] { "ORDER BY", SUserDefaultsTable.GetDefaultCodeDBName() }), 0, 0); AUserDefaultsDataTable.AcceptChanges(); } else { AUserDefaultsDataTable = new SUserDefaultsTable(); } } finally { if (NewTransaction) { DBAccess.GDBAccessObj.CommitTransaction(); TLogging.LogAtLevel(9, "TUserDefaults.LoadUserDefaultsTable: committed own transaction."); } } if ((AUserName == UserInfo.GUserInfo.UserID) && (AMergeChangesToServerSideCache)) { /* * The UserDefaults were (re)loaded for the current user --> update * internal cache (modified UserDefaults in the cache will be replaced * with values from the DB, deleted UserDefaults in the cache will be * recreated from the DB, added UserDefaults in the cache will be * unaffected). */ MergeChanges(UUserDefaultsDT, AUserDefaultsDataTable); UUserDefaultsDT.AcceptChanges(); } ReturnValue = true; } finally { if (WriteLockTakenOut) { if (!ReaderLockWasHeld) { // Other threads are now free to obtain a read lock on the cache table. UReadWriteLock.ReleaseWriterLock(); TLogging.LogAtLevel(7, "TUserDefaults.LoadUserDefaultsTable released the WriterLock."); } else { TLogging.LogAtLevel(7, "TUserDefaults.ReloadUserDefaults waiting for downgrading to a ReaderLock..."); // Downgrade from a WriterLock to a ReaderLock again! UReadWriteLock.DowngradeFromWriterLock(ref UpgradeLockCookie); TLogging.LogAtLevel(7, "TUserDefaults.ReloadUserDefaults downgraded to a ReaderLock."); } } } } catch (Exception) { throw; } return ReturnValue; }
/// <summary> /// Reload the User Defaults. /// Causes TUserDefaults to reload the cached User Defaults Table /// /// </summary> /// <returns>void</returns> public static void ReloadCachedUserDefaults() { MessageBox.Show("in ReloadCachedUserDefaults"); SUserDefaultsTable TempUserDefaultsDataTable; DataSet UserDefaultsDS; // TODO 1 : ReaderWriterLock // reload user defaults from server TRemote.MSysMan.Maintenance.UserDefaults.WebConnectors.GetUserDefaults(Ict.Petra.Shared.UserInfo.GUserInfo.UserID, out TempUserDefaultsDataTable); // merge the current table with the one requested from the server so that client changes are not lost UserDefaultsDS = new DataSet(); UserDefaultsDS.Tables.Add(UUserDefaultsDataTable); UserDefaultsDS.Merge((DataTable)TempUserDefaultsDataTable, true, MissingSchemaAction.Ignore); UUserDefaultsDataTable = (SUserDefaultsTable)UserDefaultsDS.Tables[SUserDefaultsTable.GetTableName()]; UUserDefaults = new DataView(UUserDefaultsDataTable); UUserDefaults.Sort = SUserDefaultsTable.GetDefaultCodeDBName(); UserDefaultsDS.Tables.Remove(UUserDefaultsDataTable); // remove table again (otherwise problems when called a second time) }
public static void MergeChanges(SUserDefaultsTable ADestinationDT, SUserDefaultsTable ASourceDT) { Int16 Counter; SUserDefaultsRow UpdateRow; SUserDefaultsRow AddedRow; if (ADestinationDT == null) { throw new System.ArgumentException("ADestinationDT must not be nil"); } if (ASourceDT == null) { throw new System.ArgumentException("ASourceDT must not be nil"); } // DataColumn[] PrimaryKeyColumns = ASourceDT.PrimaryKey; for (Counter = 0; Counter <= ASourceDT.Rows.Count - 1; Counter += 1) { // TLogging.Log('MergeChanges: working on Row #' + Counter.ToString + ' (DefaultCode: ''' + ASourceDT[Counter].DefaultCode + ''''); // for Counter2 := 0 to Length(PrimaryKeyColumns) 1 do // begin // PrimaryKeyObj[Counter2] := ASourceDT.Rows[Counter].Item[PrimaryKeyColumns[Counter2]] as TObject; // TLogging.Log('CopyModificationIDsOver: working on Row #' + Counter.ToString + '. PrimaryKeyObj[' + Counter2.ToString + ']: ' + PrimaryKeyObj[Counter2].ToString); // end; UpdateRow = (SUserDefaultsRow)ADestinationDT.Rows.Find(new object[] { ASourceDT[Counter].UserId, ASourceDT[Counter].DefaultCode }); if (UpdateRow != null) { // avoid checking for DefaultValue if it is NULL // see bug http:bugs.om.org/petra/show_bug.cgi?id=741 if ((ASourceDT[Counter].IsDefaultValueNull() != ((SUserDefaultsRow)UpdateRow).IsDefaultValueNull()) || ASourceDT[Counter].IsDefaultValueNull() || (ASourceDT[Counter].DefaultValue != ((SUserDefaultsRow)UpdateRow).DefaultValue)) { // TLogging.Log('MergeChanges: copying Data over for Row #' + Counter.ToString + ' (DefaultCode: ''' + ASourceDT[Counter].DefaultCode + ''''); ADestinationDT.Rows.Remove(UpdateRow); AddedRow = ADestinationDT.NewRowTyped(false); AddedRow.ItemArray = ASourceDT[Counter].ItemArray; ADestinationDT.Rows.Add(AddedRow); // Mark row as no longer being new AddedRow.AcceptChanges(); // Mark row as beeing changed AddedRow.DefaultValue = AddedRow.DefaultValue + ' '; AddedRow.AcceptChanges(); AddedRow.DefaultValue = AddedRow.DefaultValue.Substring(0, AddedRow.DefaultValue.Length - 1); } } else { // TLogging.Log('MergeChanges: Row #' + Counter.ToString + ': no matching Row in ADestinationDT found > creating new one!'); AddedRow = ADestinationDT.NewRowTyped(false); AddedRow.ItemArray = ASourceDT[Counter].ItemArray; ADestinationDT.Rows.Add(AddedRow); } } }
public static void ReloadUserDefaults(String AUserName, out SUserDefaultsTable AUserDefaultsDataTable) { ReloadUserDefaults(AUserName, true, out AUserDefaultsDataTable); }
public static void ReloadUserDefaults(String AUserName, Boolean AMergeChangesToServerSideCache, out SUserDefaultsTable AUserDefaultsDataTable) { LoadUserDefaultsTable(AUserName, AMergeChangesToServerSideCache, out AUserDefaultsDataTable); }
public static void SaveUserDefaults(String AUserName, ref SUserDefaultsTable AUserDefaultsDataTable) { Int16 Counter; SUserDefaultsRow UserDefaultServerSideRow; if ((AUserDefaultsDataTable != null) && (AUserDefaultsDataTable.Rows.Count > 0)) { TLogging.LogAtLevel(8, "TUserDefaults.SaveUserDefaultsFromClientSide: Saving " + (AUserDefaultsDataTable.Rows.Count).ToString() + " User Defaults..."); TLogging.LogAtLevel(8, "TUserDefaults.SaveUserDefaultsFromClientSide: Row[0] --- UserId: " + AUserDefaultsDataTable[0].UserId + "; DefaultCode: " + AUserDefaultsDataTable[0].DefaultCode + "; DefaultValue: '" + AUserDefaultsDataTable[0].DefaultValue + "'"); if (AUserName == UserInfo.GUserInfo.UserID) { // Update the serverside copy of the UserDefaults with what was submitted from the Client. TLogging.LogAtLevel(7, "TUserDefaults.SaveUserDefaultsFromClientSide waiting for a WriterLock..."); // Prevent other threads from obtaining a read lock on the cache table while we are merging the cache table! UReadWriteLock.AcquireWriterLock(SharedConstants.THREADING_WAIT_INFINITE); TLogging.LogAtLevel(7, "TUserDefaults.SaveUserDefaultsFromClientSide grabbed a WriterLock..."); try { try { /* * The UserDefaults were submitted from the Client side for the current * user --> update internal cache (modified UserDefaults in the cache * will be replaced with values from the Client side, deleted * UserDefaults in the cache will be recreated from the Client side, * added UserDefaults in the cache will be unaffected). */ TLogging.LogAtLevel(7, "Before merge: UUserDefaultsDT.Rows.Count: " + UUserDefaultsDT.Rows.Count.ToString()); if (TLogging.DL >= 7) { DataTable TmpChangesDT = UUserDefaultsDT.GetChangesTyped(); if (TmpChangesDT != null) { Console.WriteLine("Before merge: UUserDefaultsDT Changed Rows: " + TmpChangesDT.Rows.Count.ToString()); } } MergeChanges(UUserDefaultsDT, AUserDefaultsDataTable); TLogging.LogAtLevel(7, "After merge: UUserDefaultsDT.Rows.Count: " + UUserDefaultsDT.Rows.Count.ToString()); if (TLogging.DL >= 7) { DataTable TmpChangesDT = UUserDefaultsDT.GetChangesTyped(); if (TmpChangesDT != null) { Console.WriteLine("After merge: UUserDefaultsDT Changed Rows: " + TmpChangesDT.Rows.Count.ToString()); } } int TmpRow = UUserDefaultsDV.Find("MailroomLastPerson"); if (TLogging.DL >= 7) { if (TmpRow != -1) { Console.WriteLine("MailroomLastPerson value: '" + UUserDefaultsDV[TmpRow][SUserDefaultsTable.GetDefaultValueDBName()].ToString() + "'"); } } // User Defaults were submitted from the Client side for any user but // the current user > just save the (now updated) serverside copy // of the UserDefaults. TLogging.LogAtLevel( 7, "TUserDefaults.SaveUserDefaultsFromClientSide: merged changed data from the Client side into the Server-side UserDefaults cache; saving the Server-side UserDefaults cache now."); SaveUserDefaultsFromServerSide(false); /* * Take over changed ModificationIDs (they get changed when existing * UserDefaults are saved. They need to be communicated back to the Client * to allow the Client to update a previously changed UserDefault again!). * This is done by taking them over from the server-side DT into the DT * that got passed in from the Client. */ for (Counter = 0; Counter <= AUserDefaultsDataTable.Rows.Count - 1; Counter += 1) { UserDefaultServerSideRow = (SUserDefaultsRow)UUserDefaultsDT.Rows.Find(new object[] { AUserDefaultsDataTable[Counter].UserId, AUserDefaultsDataTable[Counter].DefaultCode }); if (UserDefaultServerSideRow != null) { if (!AUserDefaultsDataTable[Counter].IsModificationIdNull()) { AUserDefaultsDataTable[Counter].ModificationId = UserDefaultServerSideRow.ModificationId; } } } } catch (Exception Exp) { TLogging.Log("Exception occured in TMaintenanceUserDefaults.SaveUserDefaultsFromClientSide: " + Exp.ToString()); throw; } } finally { // Other threads are now free to obtain a read lock on the cache table. UReadWriteLock.ReleaseWriterLock(); TLogging.LogAtLevel(7, "TUserDefaults.SaveUserDefaultsFromClientSide released the WriterLock."); } } else { // User Defaults were submitted from the Client side for any user but the current user TUserDefaults.SaveUserDefaultsTable(AUserName, ref AUserDefaultsDataTable, null); } } else { } }
public static void SaveUserDefaultsTable(String AUserName, ref SUserDefaultsTable AUserDefaultsDataTable, TDBTransaction AWriteTransaction) { SaveUserDefaultsTable(AUserName, ref AUserDefaultsDataTable, AWriteTransaction, true); }
public static void SaveUserDefaultsTable(String AUserName, ref SUserDefaultsTable AUserDefaultsDataTable, TDBTransaction AWriteTransaction, Boolean ASendUpdateInfoToClient) { Boolean NewTransaction = false; Boolean SubmissionOK = false; TDBTransaction WriteTransaction; Int32 SavingAttempts = 0; SUserDefaultsTable ChangedUserDefaultsDT; SUserDefaultsTable ChangedUserDefaults2DT; SUserDefaultsTable RefreshedUserDefaultsDataTable = null; if ((AUserDefaultsDataTable != null) && (AUserDefaultsDataTable.Rows.Count > 0)) { ChangedUserDefaultsDT = AUserDefaultsDataTable.GetChangesTyped(); if ((ChangedUserDefaultsDT != null) && (ChangedUserDefaultsDT.Rows.Count > 0)) { if (TLogging.DebugLevel >= 8) { TLogging.Log( "TUserDefaults.SaveUserDefaultsTable: Saving " + (ChangedUserDefaultsDT.Rows.Count).ToString() + " User Defaults..."); TLogging.Log("TUserDefaults.SaveUserDefaultsTable: Row[0] --- UserId: " + ChangedUserDefaultsDT[0].UserId + "; DefaultCode: " + ChangedUserDefaultsDT[0].DefaultCode + "; DefaultValue: " + ChangedUserDefaultsDT[0].DefaultValue); } if (AWriteTransaction == null) { WriteTransaction = DBAccess.GDBAccessObj.GetNewOrExistingTransaction(IsolationLevel.ReadCommitted, TEnforceIsolationLevel.eilMinimum, out NewTransaction); } else { WriteTransaction = AWriteTransaction; } try { do { try { SUserDefaultsAccess.SubmitChanges(AUserDefaultsDataTable, WriteTransaction); SubmissionOK = true; SavingAttempts = SavingAttempts + 1; } catch (EDBConcurrencyException) { TLogging.LogAtLevel( 8, "TMaintenanceUserDefaults.SaveUserDefaultsTable: EDBConcurrencyException occured --> refreshing cached UserDefaults with UserDefaults from the DB!"); // The same user has saved the same UserDefault after we have read it in // (this can only happen if the same user is logged in twice). // > Read in the UserDefaults for this user again and merge them // into the ones that are to be submitted, notify the Client to // reload the UserDefaults and start submitting again! ReloadUserDefaults(UserInfo.GUserInfo.UserID, false, out RefreshedUserDefaultsDataTable); DataUtilities.CopyModificationIDsOver(ChangedUserDefaultsDT, RefreshedUserDefaultsDataTable); DataUtilities.CopyModificationIDsOver(AUserDefaultsDataTable, ChangedUserDefaultsDT); SavingAttempts = SavingAttempts + 1; ASendUpdateInfoToClient = true; } catch (Exception Exp) { if (TLogging.DL >= 8) { TLogging.Log("TMaintenanceUserDefaults.SaveUserDefaultsTable: Exception occured: " + Exp.ToString()); } throw; } } while (!((SavingAttempts > 1) || SubmissionOK)); TLogging.LogAtLevel(8, "TMaintenanceUserDefaults.SaveUserDefaultsTable: after saving."); TLogging.LogAtLevel( 8, "TMaintenanceUserDefaults.SaveUserDefaultsTable: ChangedUserDefaultsDT.Rows.Count: " + ChangedUserDefaultsDT.Rows.Count.ToString()); ChangedUserDefaults2DT = AUserDefaultsDataTable.GetChangesTyped(); // Tell the Client the updated UserDefaults (needed for the ModificationIDs) if (ASendUpdateInfoToClient) { TLogging.LogAtLevel(8, "TMaintenanceUserDefaults.SaveUserDefaultsTable: ASendUpdateInfoToClient = true"); UpdateUserDefaultsOnClient(AUserName, ChangedUserDefaults2DT); } else { foreach (DataRow ChangedUDDR in ChangedUserDefaults2DT.Rows) { // If a new UserDefault has been INSERTed into the DB Table, inform other Clients about that if (ChangedUDDR.RowState == DataRowState.Added) { TLogging.LogAtLevel( 8, "TMaintenanceUserDefaults.SaveUserDefaultsTable: new UserDefault has been INSERTed - inform other Clients.."); ASendUpdateInfoToClient = true; break; } } if (ASendUpdateInfoToClient) { // CopyModificationIDsOver(ChangedUserDefaultsDT, AUserDefaultsDataTable); TLogging.LogAtLevel(8, "TMaintenanceUserDefaults.SaveUserDefaultsTable: informing other Clients!"); UpdateUserDefaultsOnClient(AUserName, ChangedUserDefaults2DT); } } // We have no unsaved changes anymore AUserDefaultsDataTable.AcceptChanges(); TLogging.LogAtLevel(8, "TMaintenanceUserDefaults.SaveUserDefaultsTable: after AcceptChanges."); if (NewTransaction) { DBAccess.GDBAccessObj.CommitTransaction(); } TLogging.LogAtLevel(8, "TMaintenanceUserDefaults.SaveUserDefaultsTable: committed own transaction."); } catch (Exception Exp) { TLogging.LogAtLevel(8, "TMaintenanceUserDefaults.SaveUserDefaultsTable: Exception occured: " + Exp.ToString()); if (NewTransaction) { DBAccess.GDBAccessObj.RollbackTransaction(); TLogging.LogAtLevel(8, "TMaintenanceUserDefaults.SaveUserDefaultsTable: rolled back own transaction."); } throw; } TLogging.LogAtLevel(8, "TMaintenanceUserDefaults.SaveUserDefaultsTable: Done!"); } else { // nothing to save! TLogging.LogAtLevel(8, "TMaintenanceUserDefaults.SaveUserDefaultsTable: nothing to save: no changes!"); } } else { // nothing to save! TLogging.LogAtLevel(8, "TMaintenanceUserDefaults.SaveUserDefaultsTable: nothing to save: no UserDefaults in memory!"); } }