Exemple #1
0
        /// <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);
        }
Exemple #2
0
        /// <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);
        }