Skip to content

Commit

Permalink
Merge pull request #1 from NewLifeX/dev
Browse files Browse the repository at this point in the history
dev合并到master
  • Loading branch information
qaz734913414 authored Mar 20, 2022
2 parents 3cbac4b + e648d56 commit 57eb25a
Show file tree
Hide file tree
Showing 7 changed files with 213 additions and 6 deletions.
2 changes: 1 addition & 1 deletion Test/Test.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@
<Folder Include="Model\" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="NewLife.Stardust" Version="2.0.2022.309" />
<PackageReference Include="NewLife.Stardust" Version="2.0.2022.319-beta0414" />
<PackageReference Include="Oracle.ManagedDataAccess.Core" Version="3.21.50" />
<PackageReference Include="System.Data.SqlClient" Version="4.8.3" />
</ItemGroup>
Expand Down
159 changes: 159 additions & 0 deletions XCode/DataAccessLayer/Database/SqlServer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
using System.Collections.Generic;
using System.Data;
using System.Data.Common;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Text;
Expand Down Expand Up @@ -1013,6 +1014,37 @@ public virtual String IndexSql
#endregion

#region 数据定义
public override Object SetSchema(DDLSchema schema, params Object[] values)
{
var dbname = "";
var file = "";
var recoverDir = "";
switch (schema)
{
case DDLSchema.BackupDatabase:
if (values != null)
{
if (values.Length > 0)
dbname = values[0] as String;
if (values.Length > 1)
file = values[1] as String;
}
return Backup(dbname, file, false);
case DDLSchema.RestoreDatabase:
if (values != null)
{
if (values.Length > 0)
file = values[0] as String;
if (values.Length > 1)
recoverDir = values[1] as String;
}
return Restore(file, recoverDir, true);
default:
break;
}
return base.SetSchema(schema, values);
}

public override String CreateDatabaseSQL(String dbname, String file)
{
var dp = (Database as SqlServer).DataPath;
Expand Down Expand Up @@ -1096,6 +1128,132 @@ protected override Boolean DatabaseExist(String dbname)
// return session.Execute(String.Format("Drop Database {0}", FormatName(databaseName))) > 0;
//}

/// <summary>备份文件到目标文件</summary>
/// <param name="dbname"></param>
/// <param name="bakfile"></param>
/// <param name="compressed"></param>
public override String Backup(String dbname, String bakfile, Boolean compressed)
{

var name = dbname;
if (name.IsNullOrEmpty())
{
name = Database.DatabaseName;
}

var bf = bakfile;
if (bf.IsNullOrEmpty())
{
var ext = Path.GetExtension(bakfile);
if (ext.IsNullOrEmpty()) ext = ".bak";

if (compressed)
bf = $"{name}{ext}";
else
bf = $"{name}_{DateTime.Now:yyyyMMddHHmmss}{ext}";
}
if (!Path.IsPathRooted(bf)) bf = NewLife.Setting.Current.BackupPath.CombinePath(bf).GetBasePath();

bf = bf.EnsureDirectory(true);

WriteLog("{0}备份SqlServer数据库 {1} 到 {2}", Database.ConnName, name, bf);

var sw = Stopwatch.StartNew();

// 删除已有文件
if (File.Exists(bf)) File.Delete(bf);

base.Database.CreateSession().Execute($"USE master;BACKUP DATABASE {name} TO disk = '{bf}'");

// 压缩
WriteLog("备份文件大小:{0:n0}字节", bf.AsFile().Length);
if (compressed)
{
var zipfile = Path.ChangeExtension(bf, "zip");
if (bakfile.IsNullOrEmpty()) zipfile = zipfile.TrimEnd(".zip") + $"_{DateTime.Now:yyyyMMddHHmmss}.zip";

var fi = bf.AsFile();
fi.Compress(zipfile);
WriteLog("压缩后大小:{0:n0}字节,{1}", zipfile.AsFile().Length, zipfile);

// 删除未备份
File.Delete(bf);

bf = zipfile;
}

sw.Stop();
WriteLog("备份完成,耗时{0:n0}ms", sw.ElapsedMilliseconds);

return bf;
}

/// <summary>还原备份文件到目标数据库</summary>
/// <param name="bakfile"></param>
/// <param name="recoverDir"></param>
/// <param name="replace"></param>
/// <param name="compressed"></param>
public String Restore(String bakfile,string recoverDir, Boolean replace = true, Boolean compressed = false)
{
var session = base.Database.CreateSession();
var result = "";
if (compressed)
{
return result;
}
if (bakfile.IsNullOrEmpty())
{
return result;
}

if (recoverDir.IsNullOrEmpty())
{
var sql = "select filename from sysfiles";
var dt = session.Query(sql).Tables[0];
if (dt.Rows.Count < 1)
{
return result;
}
else
{
recoverDir = Path.GetDirectoryName(dt.Rows[0][0].ToString());
}
}


WriteLog("{0}还原SqlServer数据库 备份文件为{1}", Database.ConnName, bakfile);

var sw = Stopwatch.StartNew();


var headInfo = session.Query($"RESTORE HEADERONLY FROM DISK = '{bakfile}'").Tables[0];
var fileInfo = session.Query($"RESTORE FILELISTONLY from disk= N'{bakfile}'").Tables[0];
if (headInfo.Rows.Count < 1)
{
return result;
}
else
{
var databaseName = headInfo.Rows[0]["DatabaseName"];
var dataName = fileInfo.Rows[0]["LogicalName"];
var logName = fileInfo.Rows[1]["LogicalName"];
var stopConnect = $"ALTER DATABASE {databaseName} SET OFFLINE WITH ROLLBACK IMMEDIATE";
var restorSql = $@"RESTORE DATABASE {databaseName} from disk= N'{bakfile}'
WITH NOUNLOAD,
{(replace ? "REPLACE," : "")}
MOVE '{dataName}' TO '{Path.Combine(recoverDir, string.Concat(databaseName, ".mdf"))}',
MOVE '{logName}' TO '{Path.Combine(recoverDir, string.Concat(databaseName, ".ldf"))}';";
session.Execute(stopConnect);
session.Execute(restorSql);
result = "ok";
}

sw.Stop();
WriteLog("还原完成,耗时{0:n0}ms", sw.ElapsedMilliseconds);

return result;
}

public override String TableExistSQL(IDataTable table) => $"select * from sysobjects where xtype='U' and name='{table.TableName}'";

/// <summary>使用数据架构确定数据表是否存在,因为使用系统视图可能没有权限</summary>
Expand Down Expand Up @@ -1275,6 +1433,7 @@ public override String DropDatabaseSQL(String dbname)
sb.AppendFormat("Drop Database {0}", Database.FormatName(dbname));
return sb.ToString();
}

#endregion

/// <summary>数据类型映射</summary>
Expand Down
2 changes: 1 addition & 1 deletion XCode/DataAccessLayer/MetaData/DDLSchema.cs
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ public enum DDLSchema
BackupDatabase,

///// <summary>还原数据库</summary>
//RestoreDatabase,
RestoreDatabase,

/// <summary>收缩数据库</summary>
CompactDatabase
Expand Down
2 changes: 1 addition & 1 deletion XCode/XCode.csproj
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
<Project Sdk="Microsoft.NET.Sdk" ToolsVersion="Current">
<PropertyGroup>
<TargetFrameworks>netstandard2.1</TargetFrameworks>
<TargetFrameworks>net5.0;net6.0</TargetFrameworks>
<AssemblyName>XCode</AssemblyName>
<RootNamespace>XCode</RootNamespace>
<AssemblyTitle>NewLife数据中间件</AssemblyTitle>
Expand Down
2 changes: 1 addition & 1 deletion XCodeTool/XCodeTool.csproj
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFrameworks>netcoreapp3.1;net5.0;net6.0</TargetFrameworks>
<TargetFrameworks>net5.0;net6.0</TargetFrameworks>
<AssemblyName>xcodetool</AssemblyName>
<RootNamespace>XCode</RootNamespace>
<AssemblyTitle>数据中间件工具</AssemblyTitle>
Expand Down
48 changes: 48 additions & 0 deletions XUnitTest.XCode/DataAccessLayer/SqlServerTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -318,5 +318,53 @@ public void PositiveAndNegative()
XTrace.WriteLine("tableNames: {0}", tableNames.Join());
Assert.DoesNotContain(table.TableName, tableNames);
}

[Fact]
public void Backup()
{
DAL.AddConnStr("bakSqlServer", "Data Source=.;Initial Catalog=Test2;user id=sa;password=1", null, "SqlServer");
var dal = DAL.Create("bakSqlServer");
var meta = dal.Db.CreateMetaData();

var file1 = meta.SetSchema(DDLSchema.BackupDatabase) as String;
Assert.NotEmpty(file1);
Assert.True(File.Exists(file1));
File.Delete(file1);

var dbname = "AO_Test";
var file2 = meta.SetSchema(DDLSchema.BackupDatabase, dbname) as String;
Assert.NotEmpty(file2);
Assert.Contains(dbname, file2);
Assert.True(File.Exists(file2));
File.Delete(file2);

var file = $"bak_{Rand.NextString(8)}.bak";
var file4 = meta.SetSchema(DDLSchema.BackupDatabase, dbname, file) as String;
Assert.NotEmpty(file4);
Assert.Equal(file, Path.GetFileName(file4));
Assert.True(File.Exists(file4));
File.Delete(file4);
}

[Fact]
public void Restore()
{
DAL.AddConnStr("restoreSqlServer", "Data Source=.;Initial Catalog=master;user id=sa;password=1", null, "SqlServer");
var dal = DAL.Create("restoreSqlServer");
var meta = dal.Db.CreateMetaData();

var result = meta.SetSchema(DDLSchema.RestoreDatabase) as String;
Assert.Empty(result);

var result2 = meta.SetSchema(DDLSchema.RestoreDatabase, "C:\\bak_bvi93mq5.bak") as String;
Assert.NotEmpty(result2);
Assert.Equal("ok", result2);


var result3 = meta.SetSchema(DDLSchema.RestoreDatabase, "C:\\bak_bvi93mq5.bak", "D:\\Program Files (x86)\\Microsoft SQL Server\\MSSQL10_50.MSSQLSERVER\\MSSQL\\DATA") as String;
Assert.NotEmpty(result3);
Assert.Equal("ok", result3);

}
}
}
4 changes: 2 additions & 2 deletions XUnitTest.XCode/XUnitTest.XCode.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -96,9 +96,9 @@
</None>
</ItemGroup>
<ItemGroup>
<PackageReference Include="Microsoft.Data.SqlClient" Version="4.1.0" />
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.1.0" />
<PackageReference Include="NewLife.UnitTest" Version="1.0.2022.319-beta1053" />
<PackageReference Include="NewLife.UnitTest" Version="1.0.2022.319" />
<PackageReference Include="System.Data.SqlClient" Version="4.8.3" />
<PackageReference Include="xunit" Version="2.4.1" />
<PackageReference Include="xunit.runner.visualstudio" Version="2.4.3">
<PrivateAssets>all</PrivateAssets>
Expand Down

0 comments on commit 57eb25a

Please sign in to comment.