PrintMessage() 공개 정적인 메소드

public static PrintMessage ( string v ) : void
v string
리턴 void
예제 #1
0
 internal void Vacuum()
 {
     Printer.PrintMessage("Running vacuum command.");
     EnableWAL = false;
     ExecuteDirect("PRAGMA main.page_size = 4096;");
     ExecuteDirect("PRAGMA main.cache_size = 10240;");
     ExecuteDirect("PRAGMA temp_store = MEMORY;");
     ExecuteDirect("PRAGMA threads = 2;");
     ExecuteDirect("VACUUM");
     EnableWAL = true;
 }
예제 #2
0
        private static void PrintAllOptions(string[] args, Parser parser, Printer.PrinterStream printerStream)
        {
            // We didn't hit a verb, print the base options and then all the plugin ones
            printerStream.WriteLine((new Options()).GetUsage());
            printerStream.Flush();

            foreach (var pluginOptionsAndAssemblies in PluginOptionsAndAssemblies)
            {
                System.Reflection.MethodInfo helpOption = GetHelpMethod(pluginOptionsAndAssemblies.Item1);
                if (helpOption != null)
                {
                    printerStream.WriteLine();
                    printerStream.WriteLine(helpOption.Invoke(pluginOptionsAndAssemblies.Item1, new object[0]));
                }
                else
                {
                    Printer.PrintMessage("Warning - plugin #b#{0}## does not have built-in help.", pluginOptionsAndAssemblies.Item2.GetName().Name);
                }
            }
        }
예제 #3
0
        private bool Upgrade(bool headless)
        {
            RefreshPartialPath();
            if (Configuration.Version < LocalDBVersion)
            {
                Printer.PrintMessage("Upgrading local cache DB from version v{0} to v{1}", Configuration.Version, LocalDBVersion);
            }
            else
            {
                if (!headless && !UniquenessCheck())
                {
                    SetUniqueData();
                }
                return(true);
            }
            PrepareTables();
            DeleteAll <CachedRecords>();
            if (!UniquenessCheck())
            {
                SetUniqueData();
            }
            if (Configuration.Version < 5)
            {
                Configuration config = Configuration;
                config.Version = LocalDBVersion;
                try
                {
                    var fs = LoadFileTimes();
                    ReplaceFileTimes(fs);
                    BeginTransaction();
                    Update(config);
                    Commit();
                    ExecuteDirect("VACUUM");
                    return(true);
                }
                catch
                {
                    Rollback();
                    return(false);
                }
            }
            else if (Configuration.Version == 2)
            {
                Configuration config = Configuration;
                config.Version = LocalDBVersion;
                try
                {
                    BeginTransaction();
                    Update(config);
                    RefreshLocalTimes = true;
                    Commit();
                    return(true);
                }
                catch
                {
                    Rollback();
                    return(false);
                }
            }

            Configuration cconfig = Configuration;

            cconfig.Version = LocalDBVersion;
            try
            {
                BeginTransaction();
                Update(cconfig);
                Commit();
                return(true);
            }
            catch
            {
                Rollback();
                return(false);
            }
        }
예제 #4
0
        static void Main(string[] args)
        {
            Versionr.Utilities.Misc.StartTimer();
            try
            {
                string         workingDirectoryPath = Environment.CurrentDirectory;
                var            printerStream        = new Printer.PrinterStream();
                var            nullstream           = new System.IO.MemoryStream();
                VersionOptions initalOpts           = new VersionOptions();

                CommandLine.Parser silentparser = new CommandLine.Parser(new Action <ParserSettings>(
                                                                             (ParserSettings p) => { p.CaseSensitive = true; p.IgnoreUnknownArguments = false; p.HelpWriter = new System.IO.StreamWriter(nullstream); p.MutuallyExclusive = true; }));
                CommandLine.Parser parser = new CommandLine.Parser(new Action <ParserSettings>(
                                                                       (ParserSettings p) => { p.CaseSensitive = true; p.IgnoreUnknownArguments = false; p.HelpWriter = printerStream; p.MutuallyExclusive = true; }));

                if (args.Length >= 1 && args[0] == "--version" && parser.ParseArguments(args, initalOpts) && initalOpts.Version)
                {
                    Printer.WriteLineMessage("#b#Versionr## v{0} #q#{1}{2}", System.Reflection.Assembly.GetCallingAssembly().GetName().Version, Utilities.MultiArchPInvoke.IsX64 ? "x64" : "x86", Utilities.MultiArchPInvoke.IsRunningOnMono ? " (using Mono runtime)" : "");
                    Printer.WriteLineMessage("#q#- A less hateful version control system.");
                    Printer.PushIndent();
                    Printer.WriteLineMessage("\n#b#Core version: {0}\n", Area.CoreVersion);
                    foreach (var x in Area.ComponentVersions)
                    {
                        Printer.WriteLineMessage("{0}: #b#{1}", x.Item1, x.Item2);
                    }
                    Printer.PopIndent();
                    Printer.WriteLineMessage("\n#b#Plugins:\n");
                    Printer.PushIndent();
                    foreach (var plugin in PluginCache.Plugins)
                    {
                        Printer.WriteLineMessage("#b#{1}## ({2}) #q#{0}", Path.GetFileName(plugin.Assembly.Location), plugin.Attributes.Name, plugin.Assembly.GetName().Version);
                    }
                    Printer.PopIndent();
                    Printer.RestoreDefaults();
                    return;
                }


                if (args.Length == 0)
                {
                    PrintAllOptions(args, parser, printerStream);
                    printerStream.Flush();
                    Printer.PrintMessage("\n#e#Error## - missing command.");
                    Printer.RestoreDefaults();
                    Environment.Exit(CommandLine.Parser.DefaultExitCodeFail);
                }

                // We will attempt to parse the commandline first
                object options             = null;
                string invokedVerb         = string.Empty;
                object invokedVerbInstance = null;
                object activatedPlugin     = null;
                foreach (object pluginOptions in PluginOptions)
                {
                    if (silentparser.ParseArguments(args, pluginOptions,
                                                    (verb, success, subOptions) =>
                    {
                        if (subOptions != null)
                        {
                            invokedVerb = verb;
                            activatedPlugin = pluginOptions;
                        }
                        invokedVerbInstance = subOptions;
                    }))
                    {
                        options = pluginOptions;
                        break;
                    }
                    if (invokedVerb != string.Empty)
                    {
                        break;
                    }
                }

                if (options == null)
                {
                    if (invokedVerb != string.Empty && activatedPlugin != null)
                    {
                        // First, does the option object even support help?
                        System.Reflection.MethodInfo helpOptionVerb = GetVerbHelpMethod(activatedPlugin);
                        if (helpOptionVerb != null)
                        {
                            // We hit a verb, but the commandline parser is unhappy at us, re-run the parse
                            parser.ParseArguments(args, activatedPlugin, (verb, success, subOptions) => { });
                        }
                        else
                        {
                            if (invokedVerbInstance is VerbOptionBase)
                            {
                                printerStream.WriteLine(((VerbOptionBase)invokedVerbInstance).GetUsage());
                            }
                            else
                            {
                                Printer.PrintMessage("Warning - verb #b#{0}##: command is malformed and cannot be parsed.", invokedVerb);
                                Printer.PrintMessage("No help method defined on verb object.", invokedVerb);
                            }
                        }
                    }
                    else
                    {
                        PrintAllOptions(args, parser, printerStream);
                    }


                    printerStream.Flush();
                    Printer.RestoreDefaults();
                    Environment.Exit(CommandLine.Parser.DefaultExitCodeFail);
                }

                if (!string.IsNullOrEmpty((invokedVerbInstance as VerbOptionBase).Logfile))
                {
                    Printer.OpenLog((invokedVerbInstance as VerbOptionBase).Logfile);
                }

                Console.CancelKeyPress += Console_CancelKeyPress;

                try
                {
                    System.Diagnostics.Stopwatch sw = new System.Diagnostics.Stopwatch();
                    sw.Start();
                    // because lewis broke 'lg' on purpose
                    if (args.Count() > 0 && args[0] == "lg" && invokedVerbInstance is Commands.LogVerbOptions)
                    {
                        ((Commands.LogVerbOptions)invokedVerbInstance).Jrunting = true;
                    }
                    int  bmc = 1;
                    bool bm  = false;
                    if (invokedVerbInstance is VerbOptionBase)
                    {
                        bm  = ((VerbOptionBase)invokedVerbInstance).Benchmark;
                        bmc = ((VerbOptionBase)invokedVerbInstance).BMC;
                    }
                    for (int i = 0; i < (bm ? bmc : 1); i++)
                    {
                        Commands.BaseCommand command     = ((VerbOptionBase)invokedVerbInstance).GetCommand();
                        VerbOptionBase       baseOptions = invokedVerbInstance as VerbOptionBase;
                        if (baseOptions != null)
                        {
                            Printer.NoColours = baseOptions.NoColours;
                        }
                        bool result = command.Run(new System.IO.DirectoryInfo(workingDirectoryPath), invokedVerbInstance);
                        if (!result)
                        {
                            printerStream.Flush();
                            Printer.RestoreDefaults();
                            Environment.Exit(2);
                        }
                    }
                    if (bm)
                    {
                        Printer.PrintMessage("\nOperation took #b#{0}## ms.", sw.ElapsedMilliseconds);
                    }
                    printerStream.Flush();
                    Printer.RestoreDefaults();
                    return;
                }
                catch (Exception e)
                {
                    printerStream.Flush();
                    System.Console.WriteLine("Error processing action:\n{0}", e.ToString());
                    Printer.RestoreDefaults();
                    Environment.Exit(20);
                }
                Printer.RestoreDefaults();
            }
            catch
            {
                Environment.Exit(100);
            }

            return;
        }
예제 #5
0
        private List <Record> Consolidate(List <Record> baseList, List <Alteration> alterations, List <Record> deletions)
        {
            System.Diagnostics.Stopwatch sw = new System.Diagnostics.Stopwatch();
            sw.Start();
            Dictionary <long, Record> records = new Dictionary <long, Record>();

            foreach (var x in baseList)
            {
                records[x.Id] = x;
            }

#if FULL_CONSOLIDATE_DEBUG
            Printer.PrintMessage("Initial Snapshot Contains: ");
            foreach (var x in baseList)
            {
                Printer.PrintMessage("Initial: ({2}) {0} - {1}", x.CanonicalName, x.UniqueIdentifier, x.Id);
            }
#endif

            List <long> pending = new List <long>();
            CacheRecords(alterations.Select(x => x.NewRecord).Where(x => x.HasValue).Select(x => x.Value));
            foreach (var x in alterations.Select(x => x).Reverse())
            {
                Objects.Record rec = null;
                switch (x.Type)
                {
                case AlterationType.Add:
                case AlterationType.Copy:
                {
                    var record = GetCachedRecord(x.NewRecord.Value);
#if FULL_CONSOLIDATE_DEBUG
                    Printer.PrintMessage("Add: ({2}) {0} - {1}", record.CanonicalName, record.UniqueIdentifier, record.Id);
                    if (records.ContainsKey(record.Id))
                    {
                        Printer.PrintMessage(" (error, already present)");
                    }
#endif
                    records[record.Id] = record;
                    break;
                }

                case AlterationType.Move:
                {
                    var record = GetCachedRecord(x.NewRecord.Value);
                    if (deletions != null)
                    {
                        rec = Get <Objects.Record>(x.PriorRecord);
                        rec.CanonicalName = Get <Objects.ObjectName>(rec.CanonicalNameId).CanonicalName;
                        deletions.Add(rec);
                    }
#if FULL_CONSOLIDATE_DEBUG
                    rec = Get <Objects.Record>(x.PriorRecord);
                    rec.CanonicalName = Get <Objects.ObjectName>(rec.CanonicalNameId).CanonicalName;
                    Printer.PrintMessage("Move (from): ({2}) {0} - {1}", rec.CanonicalName, rec.UniqueIdentifier, rec.Id);
                    if (!records.ContainsKey(rec.Id))
                    {
                        Printer.PrintMessage(" (error, not present)");
                    }
                    Printer.PrintMessage("Move (to): ({2}) {0} - {1}", record.CanonicalName, record.UniqueIdentifier, record.Id);
                    if (records.ContainsKey(record.Id))
                    {
                        Printer.PrintMessage(" (error, already present)");
                    }
#endif
                    if (!records.Remove(x.PriorRecord.Value))
                    {
                        throw new Exception("Consistency constraint invalid!");
                    }
                    records[record.Id] = record;
                    break;
                }

                case AlterationType.Update:
                {
                    var record = GetCachedRecord(x.NewRecord.Value);
#if FULL_CONSOLIDATE_DEBUG
                    rec = Get <Objects.Record>(x.PriorRecord);
                    rec.CanonicalName = Get <Objects.ObjectName>(rec.CanonicalNameId).CanonicalName;
                    Printer.PrintMessage("Update (from): ({2}) {0} - {1}", rec.CanonicalName, rec.UniqueIdentifier, rec.Id);
                    if (!records.ContainsKey(rec.Id))
                    {
                        Printer.PrintMessage(" (error, not present)");
                    }
                    Printer.PrintMessage("Update (to): ({2}) {0} - {1}", record.CanonicalName, record.UniqueIdentifier, record.Id);
                    if (records.ContainsKey(record.Id))
                    {
                        Printer.PrintMessage(" (error, already present)");
                    }
#endif
                    if (!records.Remove(x.PriorRecord.Value))
                    {
                        throw new Exception();
                    }
                    records[record.Id] = record;
                    break;
                }

                case AlterationType.Discard:
                    break;

                case AlterationType.Delete:
                    if (deletions != null)
                    {
                        rec = Get <Objects.Record>(x.PriorRecord);
                        rec.CanonicalName = Get <Objects.ObjectName>(rec.CanonicalNameId).CanonicalName;
                        deletions.Add(rec);
                    }
#if FULL_CONSOLIDATE_DEBUG
                    rec = Get <Objects.Record>(x.PriorRecord);
                    rec.CanonicalName = Get <Objects.ObjectName>(rec.CanonicalNameId).CanonicalName;
                    Printer.PrintMessage("Delete: ({2}) {0} - {1}", rec.CanonicalName, rec.UniqueIdentifier, rec.Id);
                    if (!records.ContainsKey(rec.Id))
                    {
                        Printer.PrintMessage(" (error, not present)");
                    }
#endif
                    if (!records.Remove(x.PriorRecord.Value))
                    {
                        throw new Exception("Consistency constraint invalid!");
                    }
                    break;

                default:
                    throw new Exception();
                }
            }
            var result = records.Select(x => x.Value).ToList();
#if DEBUG
            HashSet <string> namecheck = new HashSet <string>();
            foreach (var x in result)
            {
                if (namecheck.Contains(x.CanonicalName))
                {
                    throw new Exception("Inconsistency in internal state!");
                }
                namecheck.Add(x.CanonicalName);
            }
#endif
            return(result);
        }
예제 #6
0
        private void RunConsistencyCheck()
        {
            Printer.PrintMessage(" - Upgrading database - running full consistency check.");
            var objNames = Table <ObjectName>().ToList();
            Dictionary <long, long>   nameMapping = new Dictionary <long, long>();
            Dictionary <string, long> nameIndexes = new Dictionary <string, long>();

            DropTable <ObjectName>();
            DropTable <RecordRef>();
            CreateTable <ObjectName>();
            int duplicateObjs = 0;

            foreach (var x in objNames)
            {
                if (nameIndexes.ContainsKey(x.CanonicalName))
                {
                    nameMapping[x.NameId] = nameIndexes[x.CanonicalName];
                    duplicateObjs++;
                }
                else
                {
                    ObjectName oname = new ObjectName()
                    {
                        CanonicalName = x.CanonicalName
                    };
                    Insert(oname);
                    nameMapping[x.NameId]        = oname.NameId;
                    nameIndexes[x.CanonicalName] = oname.NameId;
                }
            }
            foreach (var x in Table <Record>().ToList())
            {
                x.CanonicalNameId = nameMapping[x.CanonicalNameId];
                Update(x);
            }
            Printer.PrintMessage(" - Cleaned {0} duplicate canonical names.", duplicateObjs);
            CreateTable <RecordRef>();
            Dictionary <Tuple <string, long, DateTime>, Record> records = new Dictionary <Tuple <string, long, DateTime>, Record>();

            foreach (var x in Table <Objects.Record>().ToList())
            {
                var key = new Tuple <string, long, DateTime>(x.UniqueIdentifier, x.CanonicalNameId, x.ModificationTime);
                if (records.ContainsKey(key))
                {
                    var other = records[key];
                    Printer.PrintDiagnostics("Found duplicate records {0} ==> {1}", x.Id, other.Id);
                    Printer.PrintDiagnostics(" - UID: {0}", x.UniqueIdentifier);
                    Printer.PrintDiagnostics(" - Time: {0}", x.ModificationTime);
                    Printer.PrintDiagnostics(" - Name: {0}", Get <ObjectName>(x.CanonicalNameId).CanonicalName);

                    int updates = 0;
                    foreach (var s in Table <Alteration>().Where(z => z.PriorRecord == x.Id || z.NewRecord == x.Id))
                    {
                        if (s.NewRecord.HasValue && s.NewRecord.Value == x.Id)
                        {
                            s.NewRecord = other.Id;
                        }
                        if (s.PriorRecord.HasValue && s.PriorRecord.Value == x.Id)
                        {
                            s.PriorRecord = other.Id;
                        }
                        Update(s);
                        updates++;
                    }
                    Delete(x);
                    Printer.PrintDiagnostics("Deleted record and updated {0} links.", updates);
                }
                else
                {
                    records[key] = x;
                }
            }
            int missingParents = 0;
            int bonusDeletions = 0;

            HashSet <long> allRecordIDs = new HashSet <long>();
            var            allRecords   = Table <Objects.Record>().ToList();

            foreach (var x in allRecords)
            {
                allRecordIDs.Add(x.Id);
            }
            foreach (var x in allRecords)
            {
                if (x.Parent.HasValue && !allRecordIDs.Contains(x.Parent.Value))
                {
                    missingParents++;
                    x.Parent = null;
                    Update(x);
                }
            }
            Printer.PrintDiagnostics("Removed {0} phantom record parents.", missingParents);


            foreach (var x in Table <Objects.Version>().ToList())
            {
                x.Snapshot = null;
                Update(x);
                var            alterations = Table <Objects.Alteration>().Where(z => z.Owner == x.AlterationList);
                HashSet <long> moveAdds    = new HashSet <long>();
                HashSet <long> moveDeletes = new HashSet <long>();
                foreach (var s in alterations)
                {
                    if (s.Type == AlterationType.Move)
                    {
                        moveAdds.Add(s.NewRecord.Value);
                        moveDeletes.Add(s.PriorRecord.Value);
                    }
                    if (s.Type == AlterationType.Delete)
                    {
                        if (Find <Record>(s.PriorRecord.Value) == null)
                        {
                            bonusDeletions++;
                            Delete(s);
                        }
                    }
                }
                foreach (var s in alterations)
                {
                    if (s.Type == AlterationType.Add && moveAdds.Contains(s.NewRecord.Value))
                    {
                        Delete(s);
                        Printer.PrintDiagnostics("Cleaned up extra add in v{0} for \"{1}\"", x.ShortName, Get <ObjectName>(Get <Record>(s.NewRecord.Value).CanonicalNameId).CanonicalName);
                    }
                    if (s.Type == AlterationType.Delete && moveDeletes.Contains(s.PriorRecord.Value))
                    {
                        Delete(s);
                        Printer.PrintDiagnostics("Cleaned up extra delete in v{0} for \"{1}\"", x.ShortName, Get <ObjectName>(Get <Record>(s.PriorRecord.Value).CanonicalNameId).CanonicalName);
                    }
                }
            }
            if (bonusDeletions >= 0)
            {
                Printer.PrintDiagnostics("Erased {0} unreconcilable deletions.", bonusDeletions);
            }
        }
예제 #7
0
        private WorkspaceDB(string path, SQLite.SQLiteOpenFlags flags, LocalDB localDB) : base(path, flags)
        {
            Printer.PrintDiagnostics("Metadata DB Open.");
            EnableWAL     = true;
            LocalDatabase = localDB;

            if (ExecuteScalar <string>("SELECT name FROM sqlite_master WHERE type = 'table' AND name = 'FormatInfo';") != "FormatInfo")
            {
                CreateTable <Objects.FormatInfo>();
            }
            if (flags.HasFlag(SQLite.SQLiteOpenFlags.Create))
            {
                ExecuteDirect("PRAGMA main.page_size = 4096;");
                ExecuteDirect("PRAGMA main.cache_size = 10240;");
                ExecuteDirect("PRAGMA temp_store = MEMORY;");
                ExecuteDirect("PRAGMA threads = 2;");
                EnableWAL = true;
                PrepareTables();
                return;
            }

            if (!ValidForUpgrade)
            {
                return;
            }

            if (Format.InternalFormat < InternalDBVersion)
            {
                try
                {
                    var fmt         = Format;
                    int priorFormat = fmt.InternalFormat;

                    if (priorFormat < 42)
                    {
                        ExecuteDirect("DROP TABLE Annotation");
                        ExecuteDirect("DROP TABLE AnnotationJournal");
                        ExecuteDirect("DROP TABLE TagJournal");
                        ExecuteDirect("DROP TABLE Tag");
                    }
                    BeginExclusive(true);
                    Printer.PrintMessage("Updating workspace database version from v{0} to v{1}", Format.InternalFormat, InternalDBVersion);
                    PrepareTables();
                    if (priorFormat < 42)
                    {
                        RunConsistencyCheck();
                    }
                    if (priorFormat < 33)
                    {
                        foreach (var x in Table <Record>().ToList())
                        {
                            if (x.Parent.HasValue)
                            {
                                Record rp = Find <Record>(x.Parent.Value);
                                if (rp == null)
                                {
                                    Printer.PrintMessage("Found missing parent for record ID {0} - parent ID: {1}, attempting to fix.", x.Id, x.Parent.Value);
                                    Printer.PrintMessage(" - Record {0} - {1}", Find <ObjectName>(x.CanonicalNameId).CanonicalName, x.Fingerprint);

                                    var alterations     = Query <Alteration>("SELECT * from Alteration where Alteration.NewRecord = ?", x.Id);
                                    var possibleParents = alterations.Where(z => z.PriorRecord.HasValue).Select(z => z.PriorRecord.Value).Distinct().ToList();

                                    Printer.PrintMessage(" - Found {0} possible parents for this record.", possibleParents.Count);
                                    if (possibleParents.Count == 1)
                                    {
                                        Printer.PrintMessage(" - Updating parent record to ID {0}", possibleParents[0]);
                                        x.Parent = possibleParents[0];
                                    }
                                    else
                                    {
                                        if (possibleParents.Count > 0)
                                        {
                                            Printer.PrintMessage(" - Data is ambiguous, removing parent record.");
                                        }
                                        else
                                        {
                                            Printer.PrintMessage(" - No parents found, removing parent record.");
                                        }
                                        x.Parent = null;
                                    }
                                    Update(x);
                                }
                            }
                        }
                    }
                    if (priorFormat < 32)
                    {
                        int count = 0;
                        foreach (var x in Table <Objects.Version>())
                        {
                            if (x.Message != null && x.Message.StartsWith("Automatic merge of"))
                            {
                                var mergeInfos = Table <MergeInfo>().Where(y => y.DestinationVersion == x.ID).ToList();
                                if (mergeInfos.Count == 1)
                                {
                                    mergeInfos[0].Type = MergeType.Automatic;
                                    Update(mergeInfos[0]);
                                    count++;
                                }
                            }
                        }
                        Printer.PrintMessage("Updated #b#{0}## merge info records.", count);
                    }
                    if (priorFormat < 31)
                    {
                        Dictionary <long, Record> recordMap = new Dictionary <long, Record>();
                        foreach (var x in Table <Record>().ToList())
                        {
                            recordMap[x.Id] = x;
                        }

                        foreach (var x in Table <Record>().ToList())
                        {
                            if (x.Parent.HasValue && !recordMap.ContainsKey(x.Parent.Value))
                            {
                                x.Parent = null;
                                Update(x);
                            }
                        }
                    }
                    if (priorFormat < 30)
                    {
                        foreach (var x in Table <Objects.Version>().ToList())
                        {
                            x.Snapshot = null;
                            Update(x);
                            var alterations = Table <Objects.Alteration>().Where(z => z.Owner == x.AlterationList);
                            Dictionary <long, bool> moveDeletes = new Dictionary <long, bool>();
                            HashSet <long>          deletions   = new HashSet <long>();
                            int counter = 0;
                            foreach (var s in alterations)
                            {
                                if (s.Type == AlterationType.Move)
                                {
                                    if (moveDeletes.ContainsKey(s.PriorRecord.Value))
                                    {
                                        moveDeletes[s.PriorRecord.Value] = false;
                                    }
                                    else
                                    {
                                        moveDeletes[s.PriorRecord.Value] = true;
                                    }
                                }
                            }
                            foreach (var s in alterations)
                            {
                                if (s.Type == AlterationType.Move)
                                {
                                    if (moveDeletes[s.PriorRecord.Value] == false)
                                    {
                                        s.Type = AlterationType.Copy;
                                        Update(s);
                                        deletions.Add(s.PriorRecord.Value);
                                        counter++;
                                    }
                                }
                            }
                            foreach (var s in deletions)
                            {
                                Alteration alt = new Alteration()
                                {
                                    PriorRecord = s, Type = AlterationType.Delete, Owner = x.AlterationList
                                };
                                Insert(alt);
                            }
                            if (counter > 0)
                            {
                                Printer.PrintDiagnostics("Version {0} had {1} multiple-moves that have been fixed.", x.ShortName, counter);
                            }
                        }
                    }
                    if (priorFormat < 30)
                    {
                        foreach (var x in Table <Objects.Version>().ToList())
                        {
                            x.Snapshot = null;
                            Update(x);
                            var alterations = Table <Objects.Alteration>().Where(z => z.Owner == x.AlterationList);
                            HashSet <Tuple <AlterationType, long?, long?> > duplicateAlterations = new HashSet <Tuple <AlterationType, long?, long?> >();
                            int counter = 0;
                            foreach (var s in alterations)
                            {
                                var key = new Tuple <AlterationType, long?, long?>(s.Type, s.NewRecord, s.PriorRecord);
                                if (duplicateAlterations.Contains(key))
                                {
                                    Delete(s);
                                    counter++;
                                }
                                else
                                {
                                    duplicateAlterations.Add(key);
                                }
                            }
                            if (counter > 0)
                            {
                                Printer.PrintDiagnostics("Version {0} had {1} duplicated alterations that have been fixed.", x.ShortName, counter);
                            }
                        }
                    }

                    DropTable <Objects.FormatInfo>();
                    fmt.InternalFormat = InternalDBVersion;
                    CreateTable <Objects.FormatInfo>();
                    Insert(fmt);

                    Commit();

                    Vacuum();
                }
                catch (Exception e)
                {
                    Rollback();
                    Printer.PrintError("Couldn't update DB: {0}", e.ToString());
                }
                PrepareTables();
            }
        }