Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

dev合并到master #1

Merged
merged 5 commits into from
Mar 20, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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