[mapguide-commits] r10149 - in branches/4.0/MgDev/Server/RepositoryAdmin: . app app/Commands

svn_mapguide at osgeo.org svn_mapguide at osgeo.org
Thu Jun 12 05:00:33 PDT 2025


Author: jng
Date: 2025-06-12 05:00:32 -0700 (Thu, 12 Jun 2025)
New Revision: 10149

Added:
   branches/4.0/MgDev/Server/RepositoryAdmin/app/
   branches/4.0/MgDev/Server/RepositoryAdmin/app/Commands/
   branches/4.0/MgDev/Server/RepositoryAdmin/app/Commands/App.cs
   branches/4.0/MgDev/Server/RepositoryAdmin/app/Commands/BackupCommand.cs
   branches/4.0/MgDev/Server/RepositoryAdmin/app/Commands/BaseCommand.cs
   branches/4.0/MgDev/Server/RepositoryAdmin/app/Commands/CommandException.cs
   branches/4.0/MgDev/Server/RepositoryAdmin/app/Commands/ICommonCommand.cs
   branches/4.0/MgDev/Server/RepositoryAdmin/app/Commands/RestoreCommand.cs
   branches/4.0/MgDev/Server/RepositoryAdmin/app/MapGuide.RepositoryAdmin.csproj
   branches/4.0/MgDev/Server/RepositoryAdmin/app/Program.cs
   branches/4.0/MgDev/Server/RepositoryAdmin/app/Strings.Designer.cs
   branches/4.0/MgDev/Server/RepositoryAdmin/app/Strings.resx
Log:
#2879: Implement the beginnings of a replacement repository admin app. 

The original PHP scripts is merely a glorified wrapper over 3 existing tools:

 - db_archive
 - db_checkpoint
 - db_recover

With some file move/copy routines. Our replacement is pretty much the same thing, except it's now a .net console app.

.net is not only multi-platform now, but also supports single-file publishing which is great as we can produce self-contained binaries on both Windows and Linux, simplifying the packaging story as a result.

This commit implements the cold backup part of the app, which uses db_archive to obtain listing of files to copy to the given backup directory.

Index: branches/4.0/MgDev/Server/RepositoryAdmin/app
===================================================================
--- branches/4.0/MgDev/Server/RepositoryAdmin/app	2025-06-05 14:39:58 UTC (rev 10148)
+++ branches/4.0/MgDev/Server/RepositoryAdmin/app	2025-06-12 12:00:32 UTC (rev 10149)

Property changes on: branches/4.0/MgDev/Server/RepositoryAdmin/app
___________________________________________________________________
Added: svn:ignore
## -0,0 +1,3 ##
+bin
+obj
+.vs
Added: branches/4.0/MgDev/Server/RepositoryAdmin/app/Commands/App.cs
===================================================================
--- branches/4.0/MgDev/Server/RepositoryAdmin/app/Commands/App.cs	                        (rev 0)
+++ branches/4.0/MgDev/Server/RepositoryAdmin/app/Commands/App.cs	2025-06-12 12:00:32 UTC (rev 10149)
@@ -0,0 +1,158 @@
+
+using System.Diagnostics;
+
+namespace MapGuide.RepositoryAdmin.Commands;
+
+public class App(ICommonCommand cmd,
+                 TextWriter stdout,
+                 TextWriter stderr,
+                 FileInfo dbArchive,
+                 FileInfo dbCheckpoint,
+                 FileInfo dbRecover)
+{
+    public void Stdout(string msg) => stdout.WriteLine(msg);
+
+    public void Stderr(string msg) => stderr.WriteLine(msg);
+
+    private IEnumerable<string> GetDatabaseFiles(string homeDir)
+    {
+        var proc = new Process
+        {
+            StartInfo = new ProcessStartInfo
+            {
+                FileName = dbArchive.FullName,
+                Arguments = $"-sv -h \"{homeDir}\"",
+                UseShellExecute = false,
+                RedirectStandardOutput = true,
+                CreateNoWindow = true,
+                WorkingDirectory = dbArchive.DirectoryName
+            }
+        };
+        proc.Start();
+        while (!proc.StandardOutput.EndOfStream)
+        {
+            var line = proc.StandardOutput.ReadLine();
+            if (line != null)
+                yield return line;
+        }
+    }
+
+    private void TransferDatabaseFiles(DirectoryInfo outDir)
+    {
+        var files = GetDatabaseFiles(cmd.InputPath.FullName);
+        foreach (var f in files)
+        {
+            var fi = new FileInfo(Path.Combine(cmd.InputPath.FullName, f));
+            TransferFile(outDir, fi);
+        }
+    }
+
+    private IEnumerable<string> GetLogFiles(string homeDir, bool unusedFilesOnly = false)
+    {
+        var proc = new Process
+        {
+            StartInfo = new ProcessStartInfo
+            {
+                FileName = dbArchive.FullName,
+                Arguments = unusedFilesOnly ? $"-v -h \"{homeDir}\"" : $"-lv -h \"{homeDir}\"",
+                UseShellExecute = false,
+                RedirectStandardOutput = true,
+                CreateNoWindow = true,
+                WorkingDirectory = dbArchive.DirectoryName
+            }
+        };
+        proc.Start();
+        while (!proc.StandardOutput.EndOfStream)
+        {
+            var line = proc.StandardOutput.ReadLine();
+            if (line != null)
+                yield return line;
+        }
+    }
+
+    private void TransferFiles(DirectoryInfo outDir, IList<string> fileName, int index = 0, bool moveFile = false)
+    {
+        if (fileName.Count - index <= 0)
+            throw new CommandException(Strings.IDS_ERR_DATABASE_OR_LOG_FILE_NOT_FOUND);
+
+        for (int i = index; i < fileName.Count; i++)
+        {
+            var f = new FileInfo(Path.Combine(cmd.InputPath.FullName, fileName[i]));
+            this.TransferFile(outDir, f, moveFile);
+        }
+    }
+
+    private void TransferLogFiles(DirectoryInfo outDir)
+    {
+        List<string>? logFiles = null;
+        int? numUnusedFiles = null;
+        switch (cmd)
+        {
+            case BackupCommand bk:
+                {
+                    var unusedFiles = this.GetLogFiles(cmd.InputPath.FullName, true).ToList();
+                    logFiles = this.GetLogFiles(cmd.InputPath.FullName, false).ToList();
+                    numUnusedFiles = unusedFiles.Count;
+                    
+                    if (bk.IncrementalLevel != BackupCommand.MIN_INCREMENTAL_LEVEL && numUnusedFiles > 0)
+                    {
+                        this.TransferFiles(outDir, unusedFiles, 0, true);
+                    }
+                }
+                break;
+            case RestoreCommand rs:
+                {
+                    logFiles = this.GetLogFiles(cmd.InputPath.FullName, false).ToList();
+                    numUnusedFiles = 0;
+                }
+                break;
+            default:
+                throw new CommandException(Strings.IDS_ERR_INVALID_OPERATION);
+        }
+
+        if (logFiles != null && numUnusedFiles.HasValue)
+        {
+            this.TransferFiles(outDir, logFiles, numUnusedFiles.Value, false);
+        }
+    }
+
+    internal int BackupOfflineRepositories()
+    {
+        stdout.WriteLine(Strings.IDS_PROGRESS_BACKING_UP_OFFLINE_REPOSITORY);
+
+        var outDir = cmd.OutputPath.CreateSubdirectory("LastColdBackup");
+        TransferDatabaseFiles(outDir);
+        TransferLogFiles(outDir);
+
+        return 0;
+    }
+
+    private void TransferFile(DirectoryInfo outDir, FileInfo file, bool move = false, bool overwrite = true)
+    {
+        var dest = Path.Combine(outDir.FullName, file.Name);
+        switch (cmd)
+        {
+            case BackupCommand bk:
+                stdout.WriteLine("\t" + string.Format(Strings.IDS_PROGRESS_ARCHIVING_FILE, file.Name));
+                break;
+            case RestoreCommand rs:
+                stdout.WriteLine("\t" + string.Format(Strings.IDS_PROGRESS_RECOVERING_FILE, file.Name));
+                break;
+        }
+
+        if (move)
+        {
+            file.MoveTo(dest, overwrite);
+        }
+        else
+        {
+            file.CopyTo(dest, overwrite);
+        }
+    
+    }
+
+    internal int BackupOnlineRepositories()
+    {
+        return 0;
+    }
+}

Added: branches/4.0/MgDev/Server/RepositoryAdmin/app/Commands/BackupCommand.cs
===================================================================
--- branches/4.0/MgDev/Server/RepositoryAdmin/app/Commands/BackupCommand.cs	                        (rev 0)
+++ branches/4.0/MgDev/Server/RepositoryAdmin/app/Commands/BackupCommand.cs	2025-06-12 12:00:32 UTC (rev 10149)
@@ -0,0 +1,50 @@
+using CommandLine;
+
+namespace MapGuide.RepositoryAdmin.Commands;
+
+[Verb("backup", HelpText = "VerbHelp_Backup", ResourceType = typeof(Strings))]
+public class BackupCommand : BaseCommand
+{
+    [Option('l', "incremental-level", Required = true)]
+    public required int IncrementalLevel { get; set; }
+
+    [Option('i', "input-path", Required = true, HelpText = "ArgHelp_Backup_InputPath", ResourceType = typeof(Strings))]
+    public override required DirectoryInfo InputPath { get; set; }
+
+    [Option('o', "output-path", Required = true, HelpText = "ArgHelp_Backup_OutputPath", ResourceType = typeof(Strings))]
+    public override required DirectoryInfo OutputPath { get; set; }
+
+    public const int MIN_INCREMENTAL_LEVEL = 0;
+    public const int MAX_INCREMENTAL_LEVEL = 10;
+
+    protected override int ExecuteCore(App app)
+    {
+        if (!InputPath.Exists)
+        {
+            app.Stderr(string.Format(Strings.IDS_ERR_DIRECTORY_NOT_FOUND, InputPath));
+            return 1;
+        }
+        if (!OutputPath.Exists)
+        {
+            OutputPath.Create();
+        }
+        if (IncrementalLevel < MIN_INCREMENTAL_LEVEL || IncrementalLevel > MAX_INCREMENTAL_LEVEL)
+        {
+            app.Stderr(string.Format(Strings.IDS_ERR_ARGUMENT_OUT_OF_RANGE, IncrementalLevel));
+            return 1;
+        }
+
+        //tools.Stdout($"Incremental level: {IncrementalLevel}");
+        //tools.Stdout($"Input path: {InputPath}");
+        //tools.Stdout($"Output path: {OutputPath}");
+
+        if (IncrementalLevel == 0)
+        {
+            return app.BackupOfflineRepositories();
+        }
+        else
+        {
+            return app.BackupOnlineRepositories();
+        }
+    }
+}
\ No newline at end of file

Added: branches/4.0/MgDev/Server/RepositoryAdmin/app/Commands/BaseCommand.cs
===================================================================
--- branches/4.0/MgDev/Server/RepositoryAdmin/app/Commands/BaseCommand.cs	                        (rev 0)
+++ branches/4.0/MgDev/Server/RepositoryAdmin/app/Commands/BaseCommand.cs	2025-06-12 12:00:32 UTC (rev 10149)
@@ -0,0 +1,77 @@
+using CommandLine;
+
+namespace MapGuide.RepositoryAdmin.Commands;
+
+public abstract class BaseCommand : ICommonCommand
+{
+    [Option('b', "bin-path", Required = false, HelpText = "ArgHelp_Common_BinPath", ResourceType = typeof(Strings))]
+    public DirectoryInfo? BinPath { get; set; }
+
+    public abstract required DirectoryInfo InputPath { get; set; }
+
+    public abstract required DirectoryInfo OutputPath { get; set; }
+
+    public int Execute(TextWriter stdout, TextWriter stderr)
+    {
+        var dir = BinPath ?? new DirectoryInfo("../bin");
+        if (!dir.Exists)
+        {
+            stderr.WriteLine(string.Format(Strings.IDS_ERR_DIRECTORY_NOT_FOUND, dir.FullName));
+            return 1;
+        }
+
+        FileInfo? dbArchive = null;
+        FileInfo? dbCheckpoint = null;
+        FileInfo? dbRecover = null;
+
+        foreach (var f in dir.EnumerateFiles())
+        {
+            switch  (f.Name.ToLower())
+            {
+                case string s when s.StartsWith("db_archive"):
+                    dbArchive = f;
+                    break;
+                case string s when s.StartsWith("db_checkpoint"):
+                    dbCheckpoint = f;
+                    break;
+                case string s when s.StartsWith("db_recover"):
+                    dbRecover = f;
+                    break;
+            }
+        }
+
+        stdout.WriteLine(string.Format(Strings.IDS_PROGRESS_CHECKING_TOOLS, dir.FullName));
+
+        if (dbArchive == null || !dbArchive.Exists)
+        {
+            stderr.WriteLine(string.Format(Strings.IDS_ERR_FILE_NOT_FOUND, "db_archive"));
+            return 1;
+        }
+        if (dbCheckpoint == null || !dbCheckpoint.Exists)
+        {
+            stderr.WriteLine(string.Format(Strings.IDS_ERR_FILE_NOT_FOUND, "db_checkpoint"));
+            return 1;
+        }
+        if (dbRecover == null || !dbRecover.Exists)
+        {
+            stderr.WriteLine(string.Format(Strings.IDS_ERR_FILE_NOT_FOUND, "db_recover"));
+            return 1;
+        }
+
+        try
+        {
+            var app = new App(this, stdout, stderr, dbArchive, dbCheckpoint, dbRecover);
+            var res = ExecuteCore(app);
+            stdout.WriteLine(Strings.IDS_PROGRESS_OPERATION_SUCCEEDED);
+            return res;
+        }
+        catch (CommandException ex)
+        {
+            stderr.WriteLine(ex.Message);
+            stderr.WriteLine(Strings.IDS_PROGRESS_OPERATION_FAILED);
+            return 1;
+        }
+    }
+
+    protected abstract int ExecuteCore(App app);
+}
\ No newline at end of file

Added: branches/4.0/MgDev/Server/RepositoryAdmin/app/Commands/CommandException.cs
===================================================================
--- branches/4.0/MgDev/Server/RepositoryAdmin/app/Commands/CommandException.cs	                        (rev 0)
+++ branches/4.0/MgDev/Server/RepositoryAdmin/app/Commands/CommandException.cs	2025-06-12 12:00:32 UTC (rev 10149)
@@ -0,0 +1,13 @@
+namespace MapGuide.RepositoryAdmin.Commands;
+
+
+[Serializable]
+public class CommandException : Exception
+{
+	public CommandException() { }
+	public CommandException(string message) : base(message) { }
+	public CommandException(string message, Exception inner) : base(message, inner) { }
+	protected CommandException(
+	  System.Runtime.Serialization.SerializationInfo info,
+	  System.Runtime.Serialization.StreamingContext context) : base(info, context) { }
+}

Added: branches/4.0/MgDev/Server/RepositoryAdmin/app/Commands/ICommonCommand.cs
===================================================================
--- branches/4.0/MgDev/Server/RepositoryAdmin/app/Commands/ICommonCommand.cs	                        (rev 0)
+++ branches/4.0/MgDev/Server/RepositoryAdmin/app/Commands/ICommonCommand.cs	2025-06-12 12:00:32 UTC (rev 10149)
@@ -0,0 +1,9 @@
+namespace MapGuide.RepositoryAdmin.Commands;
+
+public interface ICommonCommand
+{
+    DirectoryInfo InputPath { get; }
+
+
+    DirectoryInfo OutputPath { get; }
+}

Added: branches/4.0/MgDev/Server/RepositoryAdmin/app/Commands/RestoreCommand.cs
===================================================================
--- branches/4.0/MgDev/Server/RepositoryAdmin/app/Commands/RestoreCommand.cs	                        (rev 0)
+++ branches/4.0/MgDev/Server/RepositoryAdmin/app/Commands/RestoreCommand.cs	2025-06-12 12:00:32 UTC (rev 10149)
@@ -0,0 +1,32 @@
+using CommandLine;
+
+namespace MapGuide.RepositoryAdmin.Commands;
+
+[Verb("restore", HelpText = "VerbHelp_Restore", ResourceType = typeof(Strings))]
+public class RestoreCommand : BaseCommand, ICommonCommand
+{
+    [Option('i', "input-path", Required = true, HelpText = "ArgHelp_Restore_InputPath", ResourceType = typeof(Strings))]
+    public override required DirectoryInfo InputPath { get; set; }
+
+    [Option('o', "output-path", Required = true, HelpText = "ArgHelp_Restore_OutputPath", ResourceType = typeof(Strings))]
+    public override required DirectoryInfo OutputPath { get; set; }
+
+    protected override int ExecuteCore(App app)
+    {
+        if (!InputPath.Exists)
+        {
+            app.Stderr(string.Format(Strings.IDS_ERR_DIRECTORY_NOT_FOUND, InputPath));
+            return 1;
+        }
+        if (!OutputPath.Exists)
+        {
+            app.Stderr(string.Format(Strings.IDS_ERR_DIRECTORY_NOT_FOUND, OutputPath));
+            return 1;
+        }
+
+        app.Stdout($"Input path: {InputPath}");
+        app.Stdout($"Output path: {OutputPath}");
+
+        return 0;
+    }
+}

Added: branches/4.0/MgDev/Server/RepositoryAdmin/app/MapGuide.RepositoryAdmin.csproj
===================================================================
--- branches/4.0/MgDev/Server/RepositoryAdmin/app/MapGuide.RepositoryAdmin.csproj	                        (rev 0)
+++ branches/4.0/MgDev/Server/RepositoryAdmin/app/MapGuide.RepositoryAdmin.csproj	2025-06-12 12:00:32 UTC (rev 10149)
@@ -0,0 +1,29 @@
+<Project Sdk="Microsoft.NET.Sdk">
+
+  <PropertyGroup>
+    <OutputType>Exe</OutputType>
+    <TargetFramework>net9.0</TargetFramework>
+    <ImplicitUsings>enable</ImplicitUsings>
+    <Nullable>enable</Nullable>
+  </PropertyGroup>
+
+  <ItemGroup>
+    <PackageReference Include="CommandLineParser" Version="2.9.1" />
+  </ItemGroup>
+
+  <ItemGroup>
+    <Compile Update="Strings.Designer.cs">
+      <DesignTime>True</DesignTime>
+      <AutoGen>True</AutoGen>
+      <DependentUpon>Strings.resx</DependentUpon>
+    </Compile>
+  </ItemGroup>
+
+  <ItemGroup>
+    <EmbeddedResource Update="Strings.resx">
+      <Generator>PublicResXFileCodeGenerator</Generator>
+      <LastGenOutput>Strings.Designer.cs</LastGenOutput>
+    </EmbeddedResource>
+  </ItemGroup>
+
+</Project>

Added: branches/4.0/MgDev/Server/RepositoryAdmin/app/Program.cs
===================================================================
--- branches/4.0/MgDev/Server/RepositoryAdmin/app/Program.cs	                        (rev 0)
+++ branches/4.0/MgDev/Server/RepositoryAdmin/app/Program.cs	2025-06-12 12:00:32 UTC (rev 10149)
@@ -0,0 +1,19 @@
+using CommandLine;
+using MapGuide.RepositoryAdmin.Commands;
+using System.Reflection;
+
+var commandTypes = Assembly.GetExecutingAssembly()
+    .GetTypes()
+    .Where(t => typeof(BaseCommand).IsAssignableFrom(t) && t.GetCustomAttribute<VerbAttribute>() != null && !t.IsAbstract)
+    .ToArray();
+
+Parser.Default
+    .ParseArguments(args, commandTypes)
+    .WithParsed(opts =>
+    {
+        Environment.ExitCode = ((BaseCommand)opts).Execute(Console.Out, Console.Error);
+    })
+    .WithNotParsed(err =>
+    {
+        Environment.ExitCode = 1;
+    });
\ No newline at end of file

Added: branches/4.0/MgDev/Server/RepositoryAdmin/app/Strings.Designer.cs
===================================================================
--- branches/4.0/MgDev/Server/RepositoryAdmin/app/Strings.Designer.cs	                        (rev 0)
+++ branches/4.0/MgDev/Server/RepositoryAdmin/app/Strings.Designer.cs	2025-06-12 12:00:32 UTC (rev 10149)
@@ -0,0 +1,378 @@
+//------------------------------------------------------------------------------
+// <auto-generated>
+//     This code was generated by a tool.
+//     Runtime Version:4.0.30319.42000
+//
+//     Changes to this file may cause incorrect behavior and will be lost if
+//     the code is regenerated.
+// </auto-generated>
+//------------------------------------------------------------------------------
+
+namespace MapGuide.RepositoryAdmin {
+    using System;
+    
+    
+    /// <summary>
+    ///   A strongly-typed resource class, for looking up localized strings, etc.
+    /// </summary>
+    // This class was auto-generated by the StronglyTypedResourceBuilder
+    // class via a tool like ResGen or Visual Studio.
+    // To add or remove a member, edit your .ResX file then rerun ResGen
+    // with the /str option, or rebuild your VS project.
+    [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "17.0.0.0")]
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
+    [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
+    public class Strings {
+        
+        private static global::System.Resources.ResourceManager resourceMan;
+        
+        private static global::System.Globalization.CultureInfo resourceCulture;
+        
+        [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
+        internal Strings() {
+        }
+        
+        /// <summary>
+        ///   Returns the cached ResourceManager instance used by this class.
+        /// </summary>
+        [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
+        public static global::System.Resources.ResourceManager ResourceManager {
+            get {
+                if (object.ReferenceEquals(resourceMan, null)) {
+                    global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("MapGuide.RepositoryAdmin.Strings", typeof(Strings).Assembly);
+                    resourceMan = temp;
+                }
+                return resourceMan;
+            }
+        }
+        
+        /// <summary>
+        ///   Overrides the current thread's CurrentUICulture property for all
+        ///   resource lookups using this strongly typed resource class.
+        /// </summary>
+        [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
+        public static global::System.Globalization.CultureInfo Culture {
+            get {
+                return resourceCulture;
+            }
+            set {
+                resourceCulture = value;
+            }
+        }
+        
+        /// <summary>
+        ///   Looks up a localized string similar to Path to the source location from where the repository is backed up.
+        /// </summary>
+        public static string ArgHelp_Backup_InputPath {
+            get {
+                return ResourceManager.GetString("ArgHelp_Backup_InputPath", resourceCulture);
+            }
+        }
+        
+        /// <summary>
+        ///   Looks up a localized string similar to Path to the destination location to where the repository is backed up. For offline (cold) backups, repositories are archived to a time-stamped sub-directory. For online (hot) backups, repositories are acrhived to the 'CurrentHotBackup' or a time-stamped sub-directory when taking an incremental or full snapshot respectively.
+        /// </summary>
+        public static string ArgHelp_Backup_OutputPath {
+            get {
+                return ResourceManager.GetString("ArgHelp_Backup_OutputPath", resourceCulture);
+            }
+        }
+        
+        /// <summary>
+        ///   Looks up a localized string similar to Path to the MapGuide Server binaries. Defaults to ../bin if not specified.
+        /// </summary>
+        public static string ArgHelp_Common_BinPath {
+            get {
+                return ResourceManager.GetString("ArgHelp_Common_BinPath", resourceCulture);
+            }
+        }
+        
+        /// <summary>
+        ///   Looks up a localized string similar to Path to the source location from where the repository is restored.
+        /// </summary>
+        public static string ArgHelp_Restore_InputPath {
+            get {
+                return ResourceManager.GetString("ArgHelp_Restore_InputPath", resourceCulture);
+            }
+        }
+        
+        /// <summary>
+        ///   Looks up a localized string similar to Path to the destination location to where the repository is restored.
+        /// </summary>
+        public static string ArgHelp_Restore_OutputPath {
+            get {
+                return ResourceManager.GetString("ArgHelp_Restore_OutputPath", resourceCulture);
+            }
+        }
+        
+        /// <summary>
+        ///   Looks up a localized string similar to Argument out of range: {0}.
+        /// </summary>
+        public static string IDS_ERR_ARGUMENT_OUT_OF_RANGE {
+            get {
+                return ResourceManager.GetString("IDS_ERR_ARGUMENT_OUT_OF_RANGE", resourceCulture);
+            }
+        }
+        
+        /// <summary>
+        ///   Looks up a localized string similar to Database or log file not found..
+        /// </summary>
+        public static string IDS_ERR_DATABASE_OR_LOG_FILE_NOT_FOUND {
+            get {
+                return ResourceManager.GetString("IDS_ERR_DATABASE_OR_LOG_FILE_NOT_FOUND", resourceCulture);
+            }
+        }
+        
+        /// <summary>
+        ///   Looks up a localized string similar to A date and/or time error occurred..
+        /// </summary>
+        public static string IDS_ERR_DATE_TIME {
+            get {
+                return ResourceManager.GetString("IDS_ERR_DATE_TIME", resourceCulture);
+            }
+        }
+        
+        /// <summary>
+        ///   Looks up a localized string similar to Directory not found: "{0}".
+        /// </summary>
+        public static string IDS_ERR_DIRECTORY_NOT_FOUND {
+            get {
+                return ResourceManager.GetString("IDS_ERR_DIRECTORY_NOT_FOUND", resourceCulture);
+            }
+        }
+        
+        /// <summary>
+        ///   Looks up a localized string similar to File not found: "{0}".
+        /// </summary>
+        public static string IDS_ERR_FILE_NOT_FOUND {
+            get {
+                return ResourceManager.GetString("IDS_ERR_FILE_NOT_FOUND", resourceCulture);
+            }
+        }
+        
+        /// <summary>
+        ///   Looks up a localized string similar to Invalid argument: {0}.
+        /// </summary>
+        public static string IDS_ERR_INVALID_ARGUMENT {
+            get {
+                return ResourceManager.GetString("IDS_ERR_INVALID_ARGUMENT", resourceCulture);
+            }
+        }
+        
+        /// <summary>
+        ///   Looks up a localized string similar to Invalid operation..
+        /// </summary>
+        public static string IDS_ERR_INVALID_OPERATION {
+            get {
+                return ResourceManager.GetString("IDS_ERR_INVALID_OPERATION", resourceCulture);
+            }
+        }
+        
+        /// <summary>
+        ///   Looks up a localized string similar to Unable to clean up log files..
+        /// </summary>
+        public static string IDS_ERR_UNABLE_TO_CLEAN_UP_LOG_FILES {
+            get {
+                return ResourceManager.GetString("IDS_ERR_UNABLE_TO_CLEAN_UP_LOG_FILES", resourceCulture);
+            }
+        }
+        
+        /// <summary>
+        ///   Looks up a localized string similar to Unable to copy file "{0}" to "{1}".
+        /// </summary>
+        public static string IDS_ERR_UNABLE_TO_COPY_FILE {
+            get {
+                return ResourceManager.GetString("IDS_ERR_UNABLE_TO_COPY_FILE", resourceCulture);
+            }
+        }
+        
+        /// <summary>
+        ///   Looks up a localized string similar to Unable to create directory: "{1}".
+        /// </summary>
+        public static string IDS_ERR_UNABLE_TO_CREATE_DIRECTORY {
+            get {
+                return ResourceManager.GetString("IDS_ERR_UNABLE_TO_CREATE_DIRECTORY", resourceCulture);
+            }
+        }
+        
+        /// <summary>
+        ///   Looks up a localized string similar to Unable to delete directory: "{0}".
+        /// </summary>
+        public static string IDS_ERR_UNABLE_TO_DELETE_DIRECTORY {
+            get {
+                return ResourceManager.GetString("IDS_ERR_UNABLE_TO_DELETE_DIRECTORY", resourceCulture);
+            }
+        }
+        
+        /// <summary>
+        ///   Looks up a localized string similar to Unable to delete file: "{0}".
+        /// </summary>
+        public static string IDS_ERR_UNABLE_TO_DELETE_FILE {
+            get {
+                return ResourceManager.GetString("IDS_ERR_UNABLE_TO_DELETE_FILE", resourceCulture);
+            }
+        }
+        
+        /// <summary>
+        ///   Looks up a localized string similar to Unable to execute program: {0}.
+        /// </summary>
+        public static string IDS_ERR_UNABLE_TO_EXECUTE_PROGRAM {
+            get {
+                return ResourceManager.GetString("IDS_ERR_UNABLE_TO_EXECUTE_PROGRAM", resourceCulture);
+            }
+        }
+        
+        /// <summary>
+        ///   Looks up a localized string similar to Unable to move file "{0}" to "{1}".
+        /// </summary>
+        public static string IDS_ERR_UNABLE_TO_MOVE_FILE {
+            get {
+                return ResourceManager.GetString("IDS_ERR_UNABLE_TO_MOVE_FILE", resourceCulture);
+            }
+        }
+        
+        /// <summary>
+        ///   Looks up a localized string similar to Unable to perform checkpoint..
+        /// </summary>
+        public static string IDS_ERR_UNABLE_TO_PERFORM_CHECKPOINT {
+            get {
+                return ResourceManager.GetString("IDS_ERR_UNABLE_TO_PERFORM_CHECKPOINT", resourceCulture);
+            }
+        }
+        
+        /// <summary>
+        ///   Looks up a localized string similar to Unable to perform recovery..
+        /// </summary>
+        public static string IDS_ERR_UNABLE_TO_PERFORM_RECOVERY {
+            get {
+                return ResourceManager.GetString("IDS_ERR_UNABLE_TO_PERFORM_RECOVERY", resourceCulture);
+            }
+        }
+        
+        /// <summary>
+        ///   Looks up a localized string similar to Unable to rename directory "{0}" to "{1}".
+        /// </summary>
+        public static string IDS_ERR_UNABLE_TO_RENAME_DIRECTORY {
+            get {
+                return ResourceManager.GetString("IDS_ERR_UNABLE_TO_RENAME_DIRECTORY", resourceCulture);
+            }
+        }
+        
+        /// <summary>
+        ///   Looks up a localized string similar to Unable to retrieve database files..
+        /// </summary>
+        public static string IDS_ERR_UNABLE_TO_RETRIEVE_DATABASE_FILES {
+            get {
+                return ResourceManager.GetString("IDS_ERR_UNABLE_TO_RETRIEVE_DATABASE_FILES", resourceCulture);
+            }
+        }
+        
+        /// <summary>
+        ///   Looks up a localized string similar to Unable to retrieve log files..
+        /// </summary>
+        public static string IDS_ERR_UNABLE_TO_RETRIEVE_LOG_FILES {
+            get {
+                return ResourceManager.GetString("IDS_ERR_UNABLE_TO_RETRIEVE_LOG_FILES", resourceCulture);
+            }
+        }
+        
+        /// <summary>
+        ///   Looks up a localized string similar to An unclassified exception occurred..
+        /// </summary>
+        public static string IDS_ERR_UNCLASSIFIED {
+            get {
+                return ResourceManager.GetString("IDS_ERR_UNCLASSIFIED", resourceCulture);
+            }
+        }
+        
+        /// <summary>
+        ///   Looks up a localized string similar to Archiving file: "{0}".
+        /// </summary>
+        public static string IDS_PROGRESS_ARCHIVING_FILE {
+            get {
+                return ResourceManager.GetString("IDS_PROGRESS_ARCHIVING_FILE", resourceCulture);
+            }
+        }
+        
+        /// <summary>
+        ///   Looks up a localized string similar to Backing up offline (cold) repository ....
+        /// </summary>
+        public static string IDS_PROGRESS_BACKING_UP_OFFLINE_REPOSITORY {
+            get {
+                return ResourceManager.GetString("IDS_PROGRESS_BACKING_UP_OFFLINE_REPOSITORY", resourceCulture);
+            }
+        }
+        
+        /// <summary>
+        ///   Looks up a localized string similar to Backing up online (hot) repository ....
+        /// </summary>
+        public static string IDS_PROGRESS_BACKING_UP_ONLINE_REPOSITORY {
+            get {
+                return ResourceManager.GetString("IDS_PROGRESS_BACKING_UP_ONLINE_REPOSITORY", resourceCulture);
+            }
+        }
+        
+        /// <summary>
+        ///   Looks up a localized string similar to Checking for required tools in {0}.
+        /// </summary>
+        public static string IDS_PROGRESS_CHECKING_TOOLS {
+            get {
+                return ResourceManager.GetString("IDS_PROGRESS_CHECKING_TOOLS", resourceCulture);
+            }
+        }
+        
+        /// <summary>
+        ///   Looks up a localized string similar to Operation failed!.
+        /// </summary>
+        public static string IDS_PROGRESS_OPERATION_FAILED {
+            get {
+                return ResourceManager.GetString("IDS_PROGRESS_OPERATION_FAILED", resourceCulture);
+            }
+        }
+        
+        /// <summary>
+        ///   Looks up a localized string similar to Operation succeeded!.
+        /// </summary>
+        public static string IDS_PROGRESS_OPERATION_SUCCEEDED {
+            get {
+                return ResourceManager.GetString("IDS_PROGRESS_OPERATION_SUCCEEDED", resourceCulture);
+            }
+        }
+        
+        /// <summary>
+        ///   Looks up a localized string similar to Recovering file: "{0}".
+        /// </summary>
+        public static string IDS_PROGRESS_RECOVERING_FILE {
+            get {
+                return ResourceManager.GetString("IDS_PROGRESS_RECOVERING_FILE", resourceCulture);
+            }
+        }
+        
+        /// <summary>
+        ///   Looks up a localized string similar to Restoring backup repository ....
+        /// </summary>
+        public static string IDS_PROGRESS_RESTORING_BACKUP_REPOSITORY {
+            get {
+                return ResourceManager.GetString("IDS_PROGRESS_RESTORING_BACKUP_REPOSITORY", resourceCulture);
+            }
+        }
+        
+        /// <summary>
+        ///   Looks up a localized string similar to Perform a hot or cold backup of the repository.
+        /// </summary>
+        public static string VerbHelp_Backup {
+            get {
+                return ResourceManager.GetString("VerbHelp_Backup", resourceCulture);
+            }
+        }
+        
+        /// <summary>
+        ///   Looks up a localized string similar to Perform a restore from a repository backup.
+        /// </summary>
+        public static string VerbHelp_Restore {
+            get {
+                return ResourceManager.GetString("VerbHelp_Restore", resourceCulture);
+            }
+        }
+    }
+}

Added: branches/4.0/MgDev/Server/RepositoryAdmin/app/Strings.resx
===================================================================
--- branches/4.0/MgDev/Server/RepositoryAdmin/app/Strings.resx	                        (rev 0)
+++ branches/4.0/MgDev/Server/RepositoryAdmin/app/Strings.resx	2025-06-12 12:00:32 UTC (rev 10149)
@@ -0,0 +1,225 @@
+<?xml version="1.0" encoding="utf-8"?>
+<root>
+  <!-- 
+    Microsoft ResX Schema 
+    
+    Version 2.0
+    
+    The primary goals of this format is to allow a simple XML format 
+    that is mostly human readable. The generation and parsing of the 
+    various data types are done through the TypeConverter classes 
+    associated with the data types.
+    
+    Example:
+    
+    ... ado.net/XML headers & schema ...
+    <resheader name="resmimetype">text/microsoft-resx</resheader>
+    <resheader name="version">2.0</resheader>
+    <resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
+    <resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
+    <data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
+    <data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
+    <data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
+        <value>[base64 mime encoded serialized .NET Framework object]</value>
+    </data>
+    <data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
+        <value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
+        <comment>This is a comment</comment>
+    </data>
+                
+    There are any number of "resheader" rows that contain simple 
+    name/value pairs.
+    
+    Each data row contains a name, and value. The row also contains a 
+    type or mimetype. Type corresponds to a .NET class that support 
+    text/value conversion through the TypeConverter architecture. 
+    Classes that don't support this are serialized and stored with the 
+    mimetype set.
+    
+    The mimetype is used for serialized objects, and tells the 
+    ResXResourceReader how to depersist the object. This is currently not 
+    extensible. For a given mimetype the value must be set accordingly:
+    
+    Note - application/x-microsoft.net.object.binary.base64 is the format 
+    that the ResXResourceWriter will generate, however the reader can 
+    read any of the formats listed below.
+    
+    mimetype: application/x-microsoft.net.object.binary.base64
+    value   : The object must be serialized with 
+            : System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
+            : and then encoded with base64 encoding.
+    
+    mimetype: application/x-microsoft.net.object.soap.base64
+    value   : The object must be serialized with 
+            : System.Runtime.Serialization.Formatters.Soap.SoapFormatter
+            : and then encoded with base64 encoding.
+
+    mimetype: application/x-microsoft.net.object.bytearray.base64
+    value   : The object must be serialized into a byte array 
+            : using a System.ComponentModel.TypeConverter
+            : and then encoded with base64 encoding.
+    -->
+  <xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
+    <xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
+    <xsd:element name="root" msdata:IsDataSet="true">
+      <xsd:complexType>
+        <xsd:choice maxOccurs="unbounded">
+          <xsd:element name="metadata">
+            <xsd:complexType>
+              <xsd:sequence>
+                <xsd:element name="value" type="xsd:string" minOccurs="0" />
+              </xsd:sequence>
+              <xsd:attribute name="name" use="required" type="xsd:string" />
+              <xsd:attribute name="type" type="xsd:string" />
+              <xsd:attribute name="mimetype" type="xsd:string" />
+              <xsd:attribute ref="xml:space" />
+            </xsd:complexType>
+          </xsd:element>
+          <xsd:element name="assembly">
+            <xsd:complexType>
+              <xsd:attribute name="alias" type="xsd:string" />
+              <xsd:attribute name="name" type="xsd:string" />
+            </xsd:complexType>
+          </xsd:element>
+          <xsd:element name="data">
+            <xsd:complexType>
+              <xsd:sequence>
+                <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
+                <xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
+              </xsd:sequence>
+              <xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
+              <xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
+              <xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
+              <xsd:attribute ref="xml:space" />
+            </xsd:complexType>
+          </xsd:element>
+          <xsd:element name="resheader">
+            <xsd:complexType>
+              <xsd:sequence>
+                <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
+              </xsd:sequence>
+              <xsd:attribute name="name" type="xsd:string" use="required" />
+            </xsd:complexType>
+          </xsd:element>
+        </xsd:choice>
+      </xsd:complexType>
+    </xsd:element>
+  </xsd:schema>
+  <resheader name="resmimetype">
+    <value>text/microsoft-resx</value>
+  </resheader>
+  <resheader name="version">
+    <value>2.0</value>
+  </resheader>
+  <resheader name="reader">
+    <value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
+  </resheader>
+  <resheader name="writer">
+    <value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
+  </resheader>
+  <data name="ArgHelp_Backup_InputPath" xml:space="preserve">
+    <value>Path to the source location from where the repository is backed up</value>
+  </data>
+  <data name="ArgHelp_Backup_OutputPath" xml:space="preserve">
+    <value>Path to the destination location to where the repository is backed up. For offline (cold) backups, repositories are archived to a time-stamped sub-directory. For online (hot) backups, repositories are acrhived to the 'CurrentHotBackup' or a time-stamped sub-directory when taking an incremental or full snapshot respectively</value>
+  </data>
+  <data name="ArgHelp_Common_BinPath" xml:space="preserve">
+    <value>Path to the MapGuide Server binaries. Defaults to ../bin if not specified</value>
+  </data>
+  <data name="ArgHelp_Restore_InputPath" xml:space="preserve">
+    <value>Path to the source location from where the repository is restored</value>
+  </data>
+  <data name="ArgHelp_Restore_OutputPath" xml:space="preserve">
+    <value>Path to the destination location to where the repository is restored</value>
+  </data>
+  <data name="IDS_ERR_ARGUMENT_OUT_OF_RANGE" xml:space="preserve">
+    <value>Argument out of range: {0}</value>
+  </data>
+  <data name="IDS_ERR_DATABASE_OR_LOG_FILE_NOT_FOUND" xml:space="preserve">
+    <value>Database or log file not found.</value>
+  </data>
+  <data name="IDS_ERR_DATE_TIME" xml:space="preserve">
+    <value>A date and/or time error occurred.</value>
+  </data>
+  <data name="IDS_ERR_DIRECTORY_NOT_FOUND" xml:space="preserve">
+    <value>Directory not found: "{0}"</value>
+  </data>
+  <data name="IDS_ERR_FILE_NOT_FOUND" xml:space="preserve">
+    <value>File not found: "{0}"</value>
+  </data>
+  <data name="IDS_ERR_INVALID_ARGUMENT" xml:space="preserve">
+    <value>Invalid argument: {0}</value>
+  </data>
+  <data name="IDS_ERR_INVALID_OPERATION" xml:space="preserve">
+    <value>Invalid operation.</value>
+  </data>
+  <data name="IDS_ERR_UNABLE_TO_CLEAN_UP_LOG_FILES" xml:space="preserve">
+    <value>Unable to clean up log files.</value>
+  </data>
+  <data name="IDS_ERR_UNABLE_TO_COPY_FILE" xml:space="preserve">
+    <value>Unable to copy file "{0}" to "{1}"</value>
+  </data>
+  <data name="IDS_ERR_UNABLE_TO_CREATE_DIRECTORY" xml:space="preserve">
+    <value>Unable to create directory: "{1}"</value>
+  </data>
+  <data name="IDS_ERR_UNABLE_TO_DELETE_DIRECTORY" xml:space="preserve">
+    <value>Unable to delete directory: "{0}"</value>
+  </data>
+  <data name="IDS_ERR_UNABLE_TO_DELETE_FILE" xml:space="preserve">
+    <value>Unable to delete file: "{0}"</value>
+  </data>
+  <data name="IDS_ERR_UNABLE_TO_EXECUTE_PROGRAM" xml:space="preserve">
+    <value>Unable to execute program: {0}</value>
+  </data>
+  <data name="IDS_ERR_UNABLE_TO_MOVE_FILE" xml:space="preserve">
+    <value>Unable to move file "{0}" to "{1}"</value>
+  </data>
+  <data name="IDS_ERR_UNABLE_TO_PERFORM_CHECKPOINT" xml:space="preserve">
+    <value>Unable to perform checkpoint.</value>
+  </data>
+  <data name="IDS_ERR_UNABLE_TO_PERFORM_RECOVERY" xml:space="preserve">
+    <value>Unable to perform recovery.</value>
+  </data>
+  <data name="IDS_ERR_UNABLE_TO_RENAME_DIRECTORY" xml:space="preserve">
+    <value>Unable to rename directory "{0}" to "{1}"</value>
+  </data>
+  <data name="IDS_ERR_UNABLE_TO_RETRIEVE_DATABASE_FILES" xml:space="preserve">
+    <value>Unable to retrieve database files.</value>
+  </data>
+  <data name="IDS_ERR_UNABLE_TO_RETRIEVE_LOG_FILES" xml:space="preserve">
+    <value>Unable to retrieve log files.</value>
+  </data>
+  <data name="IDS_ERR_UNCLASSIFIED" xml:space="preserve">
+    <value>An unclassified exception occurred.</value>
+  </data>
+  <data name="IDS_PROGRESS_ARCHIVING_FILE" xml:space="preserve">
+    <value>Archiving file: "{0}"</value>
+  </data>
+  <data name="IDS_PROGRESS_BACKING_UP_OFFLINE_REPOSITORY" xml:space="preserve">
+    <value>Backing up offline (cold) repository ...</value>
+  </data>
+  <data name="IDS_PROGRESS_BACKING_UP_ONLINE_REPOSITORY" xml:space="preserve">
+    <value>Backing up online (hot) repository ...</value>
+  </data>
+  <data name="IDS_PROGRESS_CHECKING_TOOLS" xml:space="preserve">
+    <value>Checking for required tools in {0}</value>
+  </data>
+  <data name="IDS_PROGRESS_OPERATION_FAILED" xml:space="preserve">
+    <value>Operation failed!</value>
+  </data>
+  <data name="IDS_PROGRESS_OPERATION_SUCCEEDED" xml:space="preserve">
+    <value>Operation succeeded!</value>
+  </data>
+  <data name="IDS_PROGRESS_RECOVERING_FILE" xml:space="preserve">
+    <value>Recovering file: "{0}"</value>
+  </data>
+  <data name="IDS_PROGRESS_RESTORING_BACKUP_REPOSITORY" xml:space="preserve">
+    <value>Restoring backup repository ...</value>
+  </data>
+  <data name="VerbHelp_Backup" xml:space="preserve">
+    <value>Perform a hot or cold backup of the repository</value>
+  </data>
+  <data name="VerbHelp_Restore" xml:space="preserve">
+    <value>Perform a restore from a repository backup</value>
+  </data>
+</root>
\ No newline at end of file



More information about the mapguide-commits mailing list