从文本文件获取变量并处理多个数据库恢复
Getting variables from a text file and process mulitple database restores
我有一个 C# webform 应用程序需要从文本文件中读取数据库名称变量并处理恢复。我希望应用程序一个一个地恢复数据库,因为这个过程是敏感的。该文本文件最多可包含 10 个数据库以在一晚内恢复。单独读取数据库名称变量并为每个变量处理恢复的最佳方法是什么?我有大量的恢复代码,所以我想 运行 我的应用程序一次用于一个数据库,然后再次用于另一个数据库,然后再次用于另一个数据库,等等。我不需要我的代码 运行 很快,因为我有几个小时来完成恢复。
文本文件中的变量看起来像这样:
dbName:"dbName"
ServerToRestoreTo:"Server/instance"
dbName:"dbName2"
ServerToRestoreTo:"Server/instance2"
...
...
...
... up to 10 dbName and ServerToRestoreTo
此外,我仍在处理文本文件的结构,因此我愿意接受有关这部分的建议。
这是一种方法:维护一个单独的文件来跟踪您已经恢复的数据库。然后从主列表中选择第一个在 'RestoredDatabases.txt' 文件中没有条目的数据库。
更新
我创建了一个 class 来存储文本文件中的数据库信息,以及一个可以调用的方法,该方法将从您的文件结构中填充此 class 的列表。
首先,这里有一个 class 表示可以从文件读取或写入文件的数据库。 注意: 我覆盖了 ToString()
方法,因此它在您提到的相同文件结构中写入文本,并且我实现了 Equals
以允许在列表之间轻松比较对象。
private class LogFileDatabase
{
public const string NamePrefix = "dbName:";
public const string ServerPrefix = "ServerToRestoreTo:";
public string DbName { get; set; }
public string Server { get; set; }
public override string ToString()
{
return string.Format("{0}\"{1}\"{2}{3}\"{4}\"",
NamePrefix, DbName, Environment.NewLine, ServerPrefix, Server);
}
public override bool Equals(object obj)
{
if (ReferenceEquals(null, obj)) return false;
if (ReferenceEquals(this, obj)) return true;
if (obj.GetType() != this.GetType()) return false;
return Equals((LogFileDatabase) obj);
}
private bool Equals(LogFileDatabase other)
{
return (string.Equals(DbName, other.DbName) &&
string.Equals(Server, other.Server));
}
public override int GetHashCode()
{
unchecked
{
return ((DbName != null ? DbName.GetHashCode() : 0) * 397) ^
(Server != null ? Server.GetHashCode() : 0);
}
}
}
接下来,我编写了一个方法来读取一个文本文件,解析它以获取数据库和服务器名称,以及 return 上述 LogFileDatabase
个对象的列表:
private static IEnumerable<LogFileDatabase> GetDatabasesFromLog(string logPath)
{
if (logPath == null) throw new ArgumentNullException("logPath");
if (!File.Exists(logPath))
{
throw new FileNotFoundException(
string.Format("logPath does not exist: {0}", logPath));
}
var databasesFromLog = new List<LogFileDatabase>();
var fileLines = File.ReadAllLines(logPath)
.Where(line => !string.IsNullOrWhiteSpace(line));
var logFileDb = new LogFileDatabase();
foreach (var fileLine in fileLines)
{
var dbNameIndex = fileLine.IndexOf(LogFileDatabase.NamePrefix);
if (dbNameIndex > -1)
{
logFileDb.DbName = fileLine.Substring(
dbNameIndex + LogFileDatabase.NamePrefix.Length).Replace("\"", "");
continue;
}
var serverIndex = fileLine.IndexOf(LogFileDatabase.ServerPrefix);
if (serverIndex == -1) continue;
logFileDb.Server = fileLine.Substring(
serverIndex + LogFileDatabase.ServerPrefix.Length).Replace("\"", "");
databasesFromLog.Add(logFileDb);
logFileDb = new LogFileDatabase();
}
return databasesFromLog;
}
最后,这里举例说明如何使用class和方法读取数据库文件,还原第一个不存在于还原的数据库文件中的数据库,然后写入名称还原的数据库到新文件:
public static void Main()
{
// The file containing all databases to restore
string databasesToRestore = "c:\program\settings\DatabasesToRestore.txt";
// A file that will contain the names of databases that have already been restored
string restoredDatabases = "c:\program\workingDir\RestoredDatabases.txt";
if (File.Exists(databasesToRestore))
{
// Ensure restored databases file exists
if (!File.Exists(restoredDatabases))
{ using (var tmp = File.Create(restoredDatabases)) { } }
LogFileDatabase databaseToRestore =
GetDatabasesFromLog(databasesToRestore)
.Except(GetDatabasesFromLog(restoredDatabases))
.FirstOrDefault();
if (databaseToRestore != null)
{
// Call retore database code here, restoring `databaseToRestore`
RestoreDbToServer(databaseToRestore.DbName, databaseToRestore.Server);
// Write the name of the database we just restored
// to our 'restoredDatabases` file
File.AppendAllLines(restoredDatabases,
new List<string> {databaseToRestore.ToString()});
}
else
{
// There are no databases left to restore,
// so we can delete our `restoredDatabases` file now.
// But be careful - this means when you run the program again,
// it will start restoring the first database.
File.Delete(restoredDatabases);
}
}
}
我有一个 C# webform 应用程序需要从文本文件中读取数据库名称变量并处理恢复。我希望应用程序一个一个地恢复数据库,因为这个过程是敏感的。该文本文件最多可包含 10 个数据库以在一晚内恢复。单独读取数据库名称变量并为每个变量处理恢复的最佳方法是什么?我有大量的恢复代码,所以我想 运行 我的应用程序一次用于一个数据库,然后再次用于另一个数据库,然后再次用于另一个数据库,等等。我不需要我的代码 运行 很快,因为我有几个小时来完成恢复。
文本文件中的变量看起来像这样:
dbName:"dbName"
ServerToRestoreTo:"Server/instance"
dbName:"dbName2"
ServerToRestoreTo:"Server/instance2"
...
...
...
... up to 10 dbName and ServerToRestoreTo
此外,我仍在处理文本文件的结构,因此我愿意接受有关这部分的建议。
这是一种方法:维护一个单独的文件来跟踪您已经恢复的数据库。然后从主列表中选择第一个在 'RestoredDatabases.txt' 文件中没有条目的数据库。
更新
我创建了一个 class 来存储文本文件中的数据库信息,以及一个可以调用的方法,该方法将从您的文件结构中填充此 class 的列表。
首先,这里有一个 class 表示可以从文件读取或写入文件的数据库。 注意: 我覆盖了 ToString()
方法,因此它在您提到的相同文件结构中写入文本,并且我实现了 Equals
以允许在列表之间轻松比较对象。
private class LogFileDatabase
{
public const string NamePrefix = "dbName:";
public const string ServerPrefix = "ServerToRestoreTo:";
public string DbName { get; set; }
public string Server { get; set; }
public override string ToString()
{
return string.Format("{0}\"{1}\"{2}{3}\"{4}\"",
NamePrefix, DbName, Environment.NewLine, ServerPrefix, Server);
}
public override bool Equals(object obj)
{
if (ReferenceEquals(null, obj)) return false;
if (ReferenceEquals(this, obj)) return true;
if (obj.GetType() != this.GetType()) return false;
return Equals((LogFileDatabase) obj);
}
private bool Equals(LogFileDatabase other)
{
return (string.Equals(DbName, other.DbName) &&
string.Equals(Server, other.Server));
}
public override int GetHashCode()
{
unchecked
{
return ((DbName != null ? DbName.GetHashCode() : 0) * 397) ^
(Server != null ? Server.GetHashCode() : 0);
}
}
}
接下来,我编写了一个方法来读取一个文本文件,解析它以获取数据库和服务器名称,以及 return 上述 LogFileDatabase
个对象的列表:
private static IEnumerable<LogFileDatabase> GetDatabasesFromLog(string logPath)
{
if (logPath == null) throw new ArgumentNullException("logPath");
if (!File.Exists(logPath))
{
throw new FileNotFoundException(
string.Format("logPath does not exist: {0}", logPath));
}
var databasesFromLog = new List<LogFileDatabase>();
var fileLines = File.ReadAllLines(logPath)
.Where(line => !string.IsNullOrWhiteSpace(line));
var logFileDb = new LogFileDatabase();
foreach (var fileLine in fileLines)
{
var dbNameIndex = fileLine.IndexOf(LogFileDatabase.NamePrefix);
if (dbNameIndex > -1)
{
logFileDb.DbName = fileLine.Substring(
dbNameIndex + LogFileDatabase.NamePrefix.Length).Replace("\"", "");
continue;
}
var serverIndex = fileLine.IndexOf(LogFileDatabase.ServerPrefix);
if (serverIndex == -1) continue;
logFileDb.Server = fileLine.Substring(
serverIndex + LogFileDatabase.ServerPrefix.Length).Replace("\"", "");
databasesFromLog.Add(logFileDb);
logFileDb = new LogFileDatabase();
}
return databasesFromLog;
}
最后,这里举例说明如何使用class和方法读取数据库文件,还原第一个不存在于还原的数据库文件中的数据库,然后写入名称还原的数据库到新文件:
public static void Main()
{
// The file containing all databases to restore
string databasesToRestore = "c:\program\settings\DatabasesToRestore.txt";
// A file that will contain the names of databases that have already been restored
string restoredDatabases = "c:\program\workingDir\RestoredDatabases.txt";
if (File.Exists(databasesToRestore))
{
// Ensure restored databases file exists
if (!File.Exists(restoredDatabases))
{ using (var tmp = File.Create(restoredDatabases)) { } }
LogFileDatabase databaseToRestore =
GetDatabasesFromLog(databasesToRestore)
.Except(GetDatabasesFromLog(restoredDatabases))
.FirstOrDefault();
if (databaseToRestore != null)
{
// Call retore database code here, restoring `databaseToRestore`
RestoreDbToServer(databaseToRestore.DbName, databaseToRestore.Server);
// Write the name of the database we just restored
// to our 'restoredDatabases` file
File.AppendAllLines(restoredDatabases,
new List<string> {databaseToRestore.ToString()});
}
else
{
// There are no databases left to restore,
// so we can delete our `restoredDatabases` file now.
// But be careful - this means when you run the program again,
// it will start restoring the first database.
File.Delete(restoredDatabases);
}
}
}