/// <summary> /// Begin transaction and open the ObjectServer in the specified path/filename /// </summary> /// <param name="serverFilename"></param> /// <param name="serverProfile"></param> /// <returns></returns> public static ObjectServerWithTransaction BeginOpenServer(string serverFilename, Preferences preferences) { ObjectServerWithTransaction r = RollbackAll(serverFilename, preferences, false); if (r != null) { if (r.Transaction == null) { string serverRootPath = Path.GetDirectoryName(serverFilename); if (string.IsNullOrEmpty(serverRootPath)) { serverRootPath = System.Environment.CurrentDirectory; } TransactionRoot root = TransactionRoot.BeginRoot(serverRootPath); root.Server = r; r.Transaction = root; root.Begin(true); } } else { string serverRootPath = Path.GetDirectoryName(serverFilename); if (string.IsNullOrEmpty(serverRootPath)) { serverRootPath = System.Environment.CurrentDirectory; } TransactionRoot root = TransactionRoot.BeginRoot(serverRootPath); root.IsDisposing = true; r = new Sop.ObjectServerWithTransaction(serverFilename, root, preferences); ITransactionLogger trans = root.Begin(true); trans.IsDisposing = true; } return(r); }
public static ITransactionLogger Begin(TransactionRoot rootTrans, Sop.ObjectServerWithTransaction server, bool ownsRoot) { rootTrans.Server = server; server.Transaction = rootTrans; var t = (TransactionBase)rootTrans.Begin(ownsRoot); return(t); }
/// <summary> /// Rollback uncomitted transactions. /// NOTE: this should be invoked upon restart so uncommited transaction(s) /// when program quits in previous run can be rolled back. /// </summary> /// <param name="serverFilename"> </param> /// <param name="serverProfile"> </param> /// <param name="createOpenObjectServerIfNoRollbackLog"> </param> public static Sop.ObjectServerWithTransaction RollbackAll(string serverFilename, Preferences preferences, bool createOpenObjectServerIfNoRollbackLog) { if (string.IsNullOrEmpty(serverFilename)) { throw new ArgumentNullException("serverFilename"); } if (!Sop.Utility.Utility.HasRequiredDirectoryAccess(serverFilename)) { throw new InvalidOperationException( string.Format("Not enough rights/access on directory containing file '{0}'.", serverFilename)); } string serverRootPath = System.IO.Path.GetDirectoryName(serverFilename); if (string.IsNullOrEmpty(serverRootPath)) { serverRootPath = System.Environment.CurrentDirectory; } string[] appendLogs = null; if (preferences != null && preferences.MemoryExtenderMode) { if (Sop.Utility.Utility.FileExists(serverFilename)) { Sop.Utility.Utility.FileDelete(serverFilename); Sop.Utility.Utility.FileDelete(string.Format("{0}.{1}", serverFilename, ObjectServer.DataInfExtensionLiteral)); } } //** NOTE: ProcessUpdateLog needs to be done ahead of RollbackAll as the latter //** removes backup files which are used by the former //** rollback all pending transaction updates... ProcessUpdateLog(serverRootPath, true); //** Rollback (delete) root trans created DB objects... if (TransactionRoot.RollbackAll(serverRootPath)) { /** AppendLogxx.txt * Grow d:\Sopbin\Sop\File.dta 1050624 2096 */ appendLogs = Directory.GetFiles(serverRootPath, string.Format("{0}*.txt", AppendLogLiteral)); } #region Process append logs if (appendLogs != null && (createOpenObjectServerIfNoRollbackLog || appendLogs.Length > 0)) { if (Sop.Utility.Utility.FileExists(serverFilename)) { var r = new ObjectServerWithTransaction(serverFilename, null, preferences); r.Open(); foreach (string s in appendLogs) { ITransactionLogger trans = Transaction.BeginWithNewRoot(r); //** open the file and do restore for each backed up entry using (var sr = new StreamReader(s)) { while (sr.Peek() >= 0) { string l = sr.ReadLine(); if (l.StartsWith(GrowToken)) { int i1 = l.LastIndexOf(' '); int i2 = l.LastIndexOf(' ', i1 - 1); string s2 = l.Substring(i2, i1 - i2); long address; if (long.TryParse(s2, out address)) { string fName = l.Substring(GrowToken.Length, i2 - GrowToken.Length); var f = (OnDisk.File.IFile)r.GetFile(fName); if (f != null) { var dbi = new DeletedBlockInfo(); dbi.StartBlockAddress = address; int segmentSize; if (int.TryParse(l.Substring(i1), out segmentSize)) { dbi.EndBlockAddress = dbi.StartBlockAddress + segmentSize; if (f.DeletedCollections != null) { f.DeletedCollections.Transaction = trans; f.DeletedCollections.Add(dbi); } } } } } } } r.Flush(); trans.Commit(); //** remove the Backup log file, we're done rolling back and it's no longer needed Sop.Utility.Utility.FileDelete(s); } r.Dispose(); //return r; } else { foreach (string s in appendLogs) { Sop.Utility.Utility.FileDelete(s); } } } #endregion return(null); }
public static ITransactionLogger Begin(TransactionRoot rootTrans, Sop.ObjectServerWithTransaction server) { return(Begin(rootTrans, server, false)); }
/// <summary> /// Begin a Root Transaction on Server & /// Begin a nested Transaction for use on Collections. /// </summary> /// <param name="server"></param> /// <returns></returns> public static ITransactionLogger BeginWithNewRoot(Sop.ObjectServerWithTransaction server) { TransactionRoot root = TransactionRoot.BeginRoot(server.Path); return(Begin(root, server, true)); }