diff --git a/.gitignore b/.gitignore index 6f27111..b4be0b9 100644 --- a/.gitignore +++ b/.gitignore @@ -3,4 +3,6 @@ obj _ReSharper* *.user *.suo -*.resharper* \ No newline at end of file +*.resharper* +Output/ +[Pp]ackages/* \ No newline at end of file diff --git a/DataFresh.Common/AssemblyInfo.cs b/DataFresh.Common/AssemblyInfo.cs index 9f89a32..79861e1 100644 --- a/DataFresh.Common/AssemblyInfo.cs +++ b/DataFresh.Common/AssemblyInfo.cs @@ -1,11 +1,10 @@ using System.Reflection; -using System.Runtime.CompilerServices; - -// -// General Information about an assembly is controlled through the following -// set of attributes. Change these attribute values to modify the information -// associated with an assembly. -// + +// +// General Information about an assembly is controlled through the following +// set of attributes. Change these attribute values to modify the information +// associated with an assembly. +// [assembly: AssemblyTitle("")] [assembly: AssemblyDescription("")] [assembly: AssemblyConfiguration("")] @@ -13,46 +12,46 @@ [assembly: AssemblyProduct("")] [assembly: AssemblyCopyright("")] [assembly: AssemblyTrademark("")] -[assembly: AssemblyCulture("")] - -// -// Version information for an assembly consists of the following four values: -// -// Major Version -// Minor Version -// Build Number -// Revision -// -// You can specify all the values or you can default the Revision and Build Numbers -// by using the '*' as shown below: - -[assembly: AssemblyVersion("1.0.*")] - -// -// In order to sign your assembly you must specify a key to use. Refer to the -// Microsoft .NET Framework documentation for more information on assembly signing. -// -// Use the attributes below to control which key is used for signing. -// -// Notes: -// (*) If no key is specified, the assembly is not signed. -// (*) KeyName refers to a key that has been installed in the Crypto Service -// Provider (CSP) on your machine. KeyFile refers to a file which contains -// a key. -// (*) If the KeyFile and the KeyName values are both specified, the -// following processing occurs: -// (1) If the KeyName can be found in the CSP, that key is used. -// (2) If the KeyName does not exist and the KeyFile does exist, the key -// in the KeyFile is installed into the CSP and used. -// (*) In order to create a KeyFile, you can use the sn.exe (Strong Name) utility. -// When specifying the KeyFile, the location of the KeyFile should be -// relative to the project output directory which is -// %Project Directory%\obj\. For example, if your KeyFile is -// located in the project directory, you would specify the AssemblyKeyFile -// attribute as [assembly: AssemblyKeyFile("..\\..\\mykey.snk")] -// (*) Delay Signing is an advanced option - see the Microsoft .NET Framework -// documentation for more information on this. -// +[assembly: AssemblyCulture("")] + +// +// Version information for an assembly consists of the following four values: +// +// Major Version +// Minor Version +// Build Number +// Revision +// +// You can specify all the values or you can default the Revision and Build Numbers +// by using the '*' as shown below: + +[assembly: AssemblyVersion("1.0.*")] + +// +// In order to sign your assembly you must specify a key to use. Refer to the +// Microsoft .NET Framework documentation for more information on assembly signing. +// +// Use the attributes below to control which key is used for signing. +// +// Notes: +// (*) If no key is specified, the assembly is not signed. +// (*) KeyName refers to a key that has been installed in the Crypto Service +// Provider (CSP) on your machine. KeyFile refers to a file which contains +// a key. +// (*) If the KeyFile and the KeyName values are both specified, the +// following processing occurs: +// (1) If the KeyName can be found in the CSP, that key is used. +// (2) If the KeyName does not exist and the KeyFile does exist, the key +// in the KeyFile is installed into the CSP and used. +// (*) In order to create a KeyFile, you can use the sn.exe (Strong Name) utility. +// When specifying the KeyFile, the location of the KeyFile should be +// relative to the project output directory which is +// %Project Directory%\obj\. For example, if your KeyFile is +// located in the project directory, you would specify the AssemblyKeyFile +// attribute as [assembly: AssemblyKeyFile("..\\..\\mykey.snk")] +// (*) Delay Signing is an advanced option - see the Microsoft .NET Framework +// documentation for more information on this. +// [assembly: AssemblyDelaySign(false)] [assembly: AssemblyKeyFile("")] [assembly: AssemblyKeyName("")] diff --git a/DataFresh.Common/DataFresh.Common.csproj b/DataFresh.Common/DataFresh.Common.csproj index 7f4e12d..0f28634 100644 --- a/DataFresh.Common/DataFresh.Common.csproj +++ b/DataFresh.Common/DataFresh.Common.csproj @@ -1,119 +1,99 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + Local + 7.10.6030 + 2.0 + {0BAA8852-1597-43BB-AF78-BABA707D4D86} + Debug + AnyCPU + + + DataFresh.Common + + JScript + Grid + IE50 + false + Library + DataFresh.Common + OnBuildSuccess + + + + v4.7.2 + + + 0.0 + + + + bin\Debug\ + false + 285212672 + false + + DEBUG;TRACE + + true + 4096 + false + + false + false + false + false + 4 + full + prompt + false + + + bin\Release\ + false + 285212672 + false + + TRACE + + false + 4096 + false + + true + false + false + false + 4 + none + prompt + false + + + + System + + + System.Data + + + System.XML + + + + + Code + + + + + + + + + + + + + + \ No newline at end of file diff --git a/DataFresh/AssemblyInfo.cs b/DataFresh/AssemblyInfo.cs index 6be57f4..5b92d94 100644 --- a/DataFresh/AssemblyInfo.cs +++ b/DataFresh/AssemblyInfo.cs @@ -1,4 +1,3 @@ using System.Reflection; -[assembly: AssemblyVersion("1.0.0.0")] -[assembly: AssemblyTitleAttribute("dataFresh")] -[assembly: DataFresh.AssemblyResourceEncrpytion(false)] +[assembly: AssemblyVersion("2.0.0.0")] +[assembly: AssemblyTitle("dataFresh")] \ No newline at end of file diff --git a/DataFresh/DataFresh.csproj b/DataFresh/DataFresh.csproj index 5b817ee..24c291f 100644 --- a/DataFresh/DataFresh.csproj +++ b/DataFresh/DataFresh.csproj @@ -1,132 +1,107 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + Local + 7.10.3077 + 2.0 + {05438358-2120-4D97-974E-ACF80F7EA6F7} + Debug + AnyCPU + + + DataFresh + + JScript + Grid + IE50 + false + Library + DataFresh + OnBuildSuccess + + + + v4.7.2 + + + 0.0 + + + + bin\Debug\ + false + 285212672 + false + + DEBUG;TRACE + + true + 4096 + false + + false + false + false + false + 4 + full + prompt + false + + + bin\Release\ + false + 285212672 + false + + TRACE + + true + 4096 + false + + true + false + false + false + 4 + full + prompt + false + + + + System + + + System.Data + + + System.XML + + + + + Code + + + Code + + + Code + + + Code + + + Code + + + + + + + + + + \ No newline at end of file diff --git a/DataFresh/DataFreshConsole.cs b/DataFresh/DataFreshConsole.cs index 6bc4fbd..b349213 100644 --- a/DataFresh/DataFreshConsole.cs +++ b/DataFresh/DataFreshConsole.cs @@ -1,40 +1,43 @@ -// EntropyZero dataFresh Copyright (C) 2007 EntropyZero Consulting, LLC. -// Please visit us on the web: http://blogs.ent0.com/ -// -// This library is free software; you can redistribute it and/or modify -// it under the terms of the GNU Lesser General Public License as -// published by the Free Software Foundation; either version 2.1 of the -// License, or (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, but -// WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to: -// Free Software Foundation, Inc., -// 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - +// EntropyZero dataFresh Copyright (C) 2007 EntropyZero Consulting, LLC. +// Please visit us on the web: http://blogs.ent0.com/ +// +// This library is free software; you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as +// published by the Free Software Foundation; either version 2.1 of the +// License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, but +// WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to: +// Free Software Foundation, Inc., +// 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + using System; using System.Collections.Specialized; -using System.IO; using System.Text; namespace DataFresh { public class DataFreshConsole { - private StringBuilder results = new StringBuilder(); - - public NameValueCollection arguments = new NameValueCollection(); - public string connectionString = string.Empty; + readonly StringBuilder results = new StringBuilder(); - public string Results + public DataFreshConsole() { - get { return results.ToString(); } + ConnectionString = string.Empty; + Arguments = new NameValueCollection(); } + public string Results => results.ToString(); + + public NameValueCollection Arguments { get; } + + public string ConnectionString { get; set; } + public void Start(string[] args) { ConsoleWrite("DataFresh provided by Entropy Zero Consulting"); @@ -45,55 +48,26 @@ public void Start(string[] args) return; } - for (int i = 0; i < args.Length; i = i + 2) - { - this.arguments.Add(args[i].Replace("-", ""), args[i + 1]); - //ConsoleWrite(args[i] + ": " +args[i+1]); - } + for (var i = 0; i < args.Length; i += 2) + Arguments.Add(args[i].Replace("-", ""), args[i + 1]); - if (!CheckForRequiredArguments(this.arguments)) + if (!CheckForRequiredArguments(Arguments)) { return; } - connectionString = string.Format(@"user id={0};password={1};Initial Catalog={2};Data Source={3};", - this.arguments["u"], - this.arguments["p"], - this.arguments["d"], - this.arguments["s"]); - - SqlDataFresh dataFresh = new SqlDataFresh(connectionString, true); + ConnectionString = + $@"user id={Arguments["u"]};password={Arguments["p"]};Initial Catalog={Arguments["d"]};Data Source={Arguments["s"]};"; - string snapshotPath = this.arguments["sp"]; + var dataFresh = new SqlDataFresh(ConnectionString, true); - if (snapshotPath != null) - { - snapshotPath = snapshotPath.Replace("\"", ""); - if (!snapshotPath.EndsWith(@"\")) - { - snapshotPath += @"\"; - } - - ConsoleWrite("snapshotPath = {0}", snapshotPath); - string fullPath = Path.GetFullPath(snapshotPath); - ConsoleWrite("fullPath = {0}", fullPath); - dataFresh.SnapshotPath = new DirectoryInfo(snapshotPath); - } - - string command = this.arguments["c"].ToUpper(); + var command = Arguments["c"].ToUpper(); switch (command) { case "PREPARE": - bool ignoreSnapshot = false; - string ignoreSnapshotArgument = arguments["ignoresnapshot"]; - if(ignoreSnapshotArgument != null) - { - if(ignoreSnapshotArgument == "1") - { - ignoreSnapshot = true; - } - } - dataFresh.PrepareDatabaseforDataFresh(!ignoreSnapshot); + var ignoreSnapshotArgument = Arguments["ignoresnapshot"]; + var ignoreSnapshot = (ignoreSnapshotArgument != null && ignoreSnapshotArgument == "1"); + dataFresh.PrepareDatabaseForDataFresh(!ignoreSnapshot); break; case "REFRESH": dataFresh.RefreshTheDatabase(); @@ -107,8 +81,8 @@ public void Start(string[] args) case "SNAPSHOT": dataFresh.CreateSnapshot(); break; - case "FOO": - //no nothing + case "FOO": + //no nothing break; default: ConsoleWrite("Command '{0}' was not recognized", command); @@ -116,7 +90,7 @@ public void Start(string[] args) } } - private void ConsoleWrite(string message, params object[] args) + void ConsoleWrite(string message, params object[] args) { results.AppendFormat(message, args); results.AppendFormat(Environment.NewLine); @@ -124,27 +98,22 @@ private void ConsoleWrite(string message, params object[] args) Console.Out.WriteLine(message, args); } - private bool CheckForRequiredArguments(NameValueCollection myArgs) + bool CheckForRequiredArguments(NameValueCollection myArgs) { - if ( - myArgs == null || - myArgs["c"] == null || - myArgs["s"] == null || - myArgs["d"] == null || - myArgs["u"] == null || - myArgs["p"] == null - ) - { - ConsoleWrite("Missing required arguments."); - WriteUsage(); - return false; - } - return true; + if (myArgs?["c"] != null + && myArgs["s"] != null + && myArgs["d"] != null + && myArgs["u"] != null + && myArgs["p"] != null) return true; + + ConsoleWrite("Missing required arguments."); + WriteUsage(); + return false; } - private void WriteUsage() + void WriteUsage() { - string usageText = @" + const string usageText = @" Usage: DataFreshUtil.exe @@ -156,7 +125,6 @@ private void WriteUsage() Options: - -sp specify path on server where snapshot files are located -ignoresnapshot 1: ignore snapshot during prepare 0: (default) will create snapshot @@ -174,7 +142,7 @@ SNAPSHOT create a snapshot of your database public static DataFreshConsole Execute(string command, string username, string password, string server, string database, params string[] options) { - string[] args = new string[] + var args = new[] { "-c", command, "-u", username, @@ -185,12 +153,12 @@ public static DataFreshConsole Execute(string command, string username, string p if (options != null && options.Length > 1) { - string argsString = string.Join("|", args); - string optionsString = string.Join("|", options); + var argsString = string.Join("|", args); + var optionsString = string.Join("|", options); args = string.Format(argsString + "|" + optionsString).Split('|'); } - DataFreshConsole console = new DataFreshConsole(); + var console = new DataFreshConsole(); console.Start(args); return console; } diff --git a/DataFresh/IDataFresh.cs b/DataFresh/IDataFresh.cs index a030e17..f2c05bd 100644 --- a/DataFresh/IDataFresh.cs +++ b/DataFresh/IDataFresh.cs @@ -16,8 +16,6 @@ // Free Software Foundation, Inc., // 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -using System.IO; - namespace DataFresh { public interface IDataFresh @@ -25,7 +23,7 @@ public interface IDataFresh /// /// prepare the database to use the dataFresh library /// - void PrepareDatabaseforDataFresh(); + void PrepareDatabaseForDataFresh(); /// /// refresh the database to a known state @@ -47,19 +45,5 @@ public interface IDataFresh /// refresh the database ignoring the dataFresh change tracking table. /// void RefreshTheEntireDatabase(); - - /// - /// create snapshot of database - /// - void CreateSnapshot(); - - /// - /// location on the server where the snapshot files are located - /// - DirectoryInfo SnapshotPath - { - get; - set; - } } } \ No newline at end of file diff --git a/DataFresh/ResourceManagement.cs b/DataFresh/ResourceManagement.cs deleted file mode 100644 index d800bac..0000000 --- a/DataFresh/ResourceManagement.cs +++ /dev/null @@ -1,148 +0,0 @@ -// EntropyZero dataFresh Copyright (C) 2007 EntropyZero Consulting, LLC. -// Please visit us on the web: http://blogs.ent0.com/ -// -// This library is free software; you can redistribute it and/or modify -// it under the terms of the GNU Lesser General Public License as -// published by the Free Software Foundation; either version 2.1 of the -// License, or (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, but -// WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to: -// Free Software Foundation, Inc., -// 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - -using System; -using System.IO; -using System.Reflection; -using System.Security.Cryptography; - -namespace DataFresh -{ - [AttributeUsage(AttributeTargets.Assembly)] - public class AssemblyResourceEncrpytion : Attribute - { - private bool enryptionEnabled; - private string enryptionKey = "nopassword"; - - public AssemblyResourceEncrpytion() - { - enryptionEnabled = true; - } - - public AssemblyResourceEncrpytion(bool enabled) - { - enryptionEnabled = enabled; - } - - public virtual bool Enabled - { - get - { - return enryptionEnabled; - } - set - { - enryptionEnabled = value; - } - } - - public virtual string Key - { - get - { - return enryptionKey; - } - } - } - - public class ResourceManagement - { - public static bool EncryptionEnabled - { - get - { - object[] customAttributes = Assembly.GetCallingAssembly().GetCustomAttributes(typeof(AssemblyResourceEncrpytion), false); - if(customAttributes != null && customAttributes.Length > 0) - { - AssemblyResourceEncrpytion enc = (AssemblyResourceEncrpytion) customAttributes[0]; - return enc.Enabled; - } - return false; - } - } - - public static string EncryptionKey - { - get - { - object[] customAttributes = Assembly.GetCallingAssembly().GetCustomAttributes(typeof(AssemblyResourceEncrpytion), false); - if(customAttributes != null && customAttributes.Length > 0) - { - AssemblyResourceEncrpytion enc = (AssemblyResourceEncrpytion) customAttributes[0]; - return enc.Key; - } - throw new Exception("Encryption key was not set!"); - } - } - - public static string GetDecryptedResource(string name) - { - byte[] dec = GetDecryptedResourceBytes(name); - string decStr = new MemoryStream(dec).ToString(); - return decStr; - } - - public static StreamReader GetDecryptedResourceStream(string name) - { - StreamReader reader = new StreamReader(new MemoryStream(GetDecryptedResourceBytes(name))); - return reader; - } - - public static byte[] GetDecryptedResourceBytes(string name) - { - Stream stream = Assembly.GetExecutingAssembly().GetManifestResourceStream(name); - int length = (int)stream.Length; - byte[] bytes = new byte[length]; - stream.Read(bytes, 0, length); - if(EncryptionEnabled) - { - return Decrypt(bytes, EncryptionKey); - } - else - { - return bytes; - } - } - - public static byte[] Decrypt(byte[] cipherData, byte[] Key, byte[] IV) - { - MemoryStream ms = new MemoryStream(); - Rijndael alg = Rijndael.Create(); - alg.Key = Key; - alg.IV = IV; - CryptoStream cs = new CryptoStream(ms, alg.CreateDecryptor(), CryptoStreamMode.Write); - cs.Write(cipherData, 0, cipherData.Length); - cs.Flush(); - cs.Close(); - byte[] decryptedData = ms.ToArray(); - return decryptedData; - } - - public static byte[] Decrypt(byte[] cipherData, string Password) - { - PasswordDeriveBytes pdb = new PasswordDeriveBytes(Password, - new byte[] - { - 0x49, 0x76, 0x61, 0x6e, 0x20, 0x4d, 0x65, 0x64, 0x76, 0x65, 0x64, - 0x65, 0x76 - }); - - return Decrypt(cipherData, pdb.GetBytes(32), pdb.GetBytes(16)); - } - } -} diff --git a/DataFresh/Resources/PrepareDataFresh.sql b/DataFresh/Resources/PrepareDataFresh.sql deleted file mode 100644 index 9c49153..0000000 --- a/DataFresh/Resources/PrepareDataFresh.sql +++ /dev/null @@ -1,280 +0,0 @@ -IF EXISTS (SELECT * FROM [DBO].SYSOBJECTS WHERE ID = Object_ID(N'[DBO].[df_ChangedTableDataRefresh]') AND OBJECTPROPERTY(ID, N'IsProcedure') = 1) - DROP PROCEDURE [dbo].[df_ChangedTableDataRefresh] -GO - -IF EXISTS (SELECT * FROM [DBO].SYSOBJECTS WHERE ID = Object_ID(N'[DBO].[df_ChangeTrackingTriggerCreate]') AND OBJECTPROPERTY(ID, N'IsProcedure') = 1) - DROP PROCEDURE [dbo].[df_ChangeTrackingTriggerCreate] -GO - -IF EXISTS (SELECT * FROM [DBO].SYSOBJECTS WHERE ID = Object_ID(N'[DBO].[df_ChangeTrackingTriggerRemove]') AND OBJECTPROPERTY(ID, N'IsProcedure') = 1) - DROP PROCEDURE [dbo].[df_ChangeTrackingTriggerRemove] -GO - -IF EXISTS (SELECT * FROM [DBO].SYSOBJECTS WHERE ID = Object_ID(N'[DBO].[df_TableDataExtract]') AND OBJECTPROPERTY(ID, N'IsProcedure') = 1) - DROP PROCEDURE [dbo].[df_TableDataExtract] -GO - -IF EXISTS (SELECT * FROM [DBO].SYSOBJECTS WHERE ID = Object_ID(N'[DBO].[df_TableDataImport]') AND OBJECTPROPERTY(ID, N'IsProcedure') = 1) - DROP PROCEDURE [dbo].[df_TableDataImport] -GO - -IF NOT EXISTS (SELECT * FROM dbo.sysobjects WHERE id = object_id(N'[dbo].[df_ChangeTracking]') and OBJECTPROPERTY(id, N'IsUserTable') = 1) - CREATE TABLE [dbo].[df_ChangeTracking] - ( - [TABLENAME] sysname - ) -GO - -CREATE PROCEDURE dbo.[df_ChangedTableDataRefresh] -( - @BasePath NVARCHAR(512) -) -AS - - DECLARE @sql NVARCHAR(4000) - DECLARE @TableName VARCHAR(255) - - SELECT DISTINCT TableName INTO #ChangedTables FROM df_ChangeTracking - - TRUNCATE TABLE df_ChangeTracking - - DECLARE Table_Cursor INSENSITIVE SCROLL CURSOR FOR - SELECT [tablename] from #ChangedTables - UNION - SELECT DISTINCT - OBJECT_NAME(fkeyid) AS Referenced_Table - FROM - sysreferences sr - INNER JOIN #ChangedTables ct ON sr.rkeyid = OBJECT_ID(ct.tablename) - - OPEN Table_Cursor - - -- Deactivate Constrains for tables referencing changed tables - FETCH NEXT FROM Table_Cursor INTO @TableName - - WHILE (@@Fetch_Status = 0) - BEGIN - SET @sql = N'Alter Table [' + @TableName + '] NOCHECK CONSTRAINT ALL' - EXEC sp_executesql @sql - - FETCH NEXT FROM Table_Cursor INTO @TableName - END - - -- Delete All data from Changed Tables and Refill - DECLARE ChangedTable_Cursor CURSOR FOR - SELECT [tablename] FROM #ChangedTables WHERE tablename not in('df_ChangeTracking', 'dr_DeltaVersion') - - OPEN ChangedTable_Cursor - FETCH NEXT FROM ChangedTable_Cursor INTO @TableName - WHILE (@@Fetch_Status = 0) - BEGIN - PRINT @TableName - SET @sql = N'DELETE [' + @TableName + ']; DELETE df_ChangeTracking WHERE TableName=''' + @TableName + '''' - EXEC sp_executesql @sql - - SET @sql = N'IF(SELECT COUNT(*) FROM INFORMATION_SCHEMA.TABLES WHERE table_name = ''' + @TableName + ''' AND IDENT_SEED(TABLE_NAME) IS NOT NULL) > 0 - BEGIN - DBCC CHECKIDENT ([' + @TableName + '], RESEED, 0) - END' - - EXEC sp_executesql @sql - - - SET @sql = N'BULK INSERT [' + @TableName + '] - FROM ''' + @BasePath + @TableName + '.df'' - WITH - ( - KEEPIDENTITY, - KEEPNULLS, - DATAFILETYPE=''native'' - )' - EXEC sp_executesql @sql - - FETCH NEXT FROM ChangedTable_Cursor INTO @TableName - END - CLOSE ChangedTable_Cursor - DEALLOCATE ChangedTable_Cursor - - -- ReEnable Constrants for All Tables - FETCH FIRST FROM Table_Cursor INTO @TableName - WHILE (@@Fetch_Status = 0) - BEGIN - SET @sql = N'Alter Table [' + @TableName + '] CHECK CONSTRAINT ALL' - EXEC sp_executesql @sql - - FETCH NEXT FROM Table_Cursor INTO @TableName - END - CLOSE Table_Cursor - DEALLOCATE Table_Cursor -GO - - -CREATE PROCEDURE dbo.[df_ChangeTrackingTriggerCreate] -AS - - IF NOT EXISTS (SELECT * FROM dbo.sysobjects WHERE id = object_id(N'[dbo].[df_ChangeTracking]') and OBJECTPROPERTY(id, N'IsUserTable') = 1) - CREATE TABLE [df_ChangeTracking] - ( - [TABLENAME] sysname - ) - - DECLARE @sql NVARCHAR(4000) - DECLARE @TableName VARCHAR(255) - - DECLARE Table_Cursor CURSOR FOR - SELECT [table_name] FROM information_schema.tables WHERE table_type = 'BASE TABLE' - - OPEN Table_Cursor - FETCH NEXT FROM Table_Cursor INTO @TableName - - WHILE (@@Fetch_Status = 0) - BEGIN - SET @sql = N'IF EXISTS (SELECT * FROM dbo.SYSOBJECTS WHERE ID = Object_ID(N''[dbo].[trig_df_ChangeTracking_' + @TableName + ']'') AND OBJECTPROPERTY(ID, N''IsTrigger'') = 1) - DROP TRIGGER [dbo].[trig_df_ChangeTracking_' + @TableName + ']' - EXEC sp_executesql @sql - - SET @sql = N'CREATE TRIGGER [dbo].[trig_df_ChangeTracking_' + @TableName + '] on [' + @TableName + '] for insert, update, delete - as - SET NOCOUNT ON - INSERT INTO df_ChangeTracking (tablename) VALUES (''' + @TableName + ''') - SET NOCOUNT OFF' - - EXEC sp_executesql @sql - - FETCH NEXT FROM Table_Cursor INTO @TableName - - END - CLOSE Table_Cursor - DEALLOCATE Table_Cursor - -GO - -CREATE PROCEDURE dbo.[df_TableDataExtract] -( - @BasePath NVARCHAR(512) -) -AS - - DECLARE @MkDirCmd NVARCHAR(4000) - - SET @MkDirCmd = N'MKDIR "' + @BASEPATH + '"' - EXEC master.dbo.xp_cmdshell @MkDirCmd, no_output - - DECLARE @CMD NVARCHAR(4000) - - DECLARE Table_Cursor CURSOR FOR - SELECT N'bcp "' + DB_NAME() + '.dbo.[' + Table_Name + ']" out "' + @BasePath + Table_Name + '.df" -n -k -E -C 1252 -S ' + @@ServerName + ' -T' FROM Information_Schema.tables WHERE table_type = 'BASE TABLE' - - OPEN Table_Cursor - FETCH NEXT FROM Table_Cursor INTO @CMD - - WHILE (@@Fetch_Status = 0) - BEGIN - EXEC master.dbo.xp_cmdshell @CMD, no_output - FETCH NEXT FROM Table_Cursor INTO @CMD - END - - CLOSE Table_Cursor - Deallocate Table_Cursor - -GO - -CREATE PROCEDURE dbo.[df_TableDataImport] -( - @BasePath NVARCHAR(512) -) -AS - - DECLARE @sql NVARCHAR(4000) - DECLARE @TableName VARCHAR(255) - - SELECT Table_Name as TableName INTO #UserTables FROM Information_Schema.tables WHERE table_type = 'BASE TABLE' - - DECLARE Table_Cursor INSENSITIVE SCROLL CURSOR FOR - SELECT [tablename] FROM #UserTables - - OPEN Table_Cursor - - -- Deactivate Constrains for tables referencing changed tables - FETCH NEXT FROM Table_Cursor INTO @TableName - - WHILE (@@Fetch_Status = 0) - BEGIN - SET @sql = N'Alter Table [' + @TableName + '] NOCHECK CONSTRAINT ALL' - EXEC sp_executesql @sql - - FETCH NEXT FROM Table_Cursor INTO @TableName - END - - -- Delete All data from Changed Tables and Refill - DECLARE UserTable_Cursor CURSOR FOR - SELECT [tablename] FROM #UserTables WHERE tablename not in ('df_ChangeTracking', 'dr_DeltaVersion') - - OPEN UserTable_Cursor - - FETCH NEXT FROM UserTable_Cursor INTO @TableName - WHILE (@@Fetch_Status = 0) - BEGIN - PRINT @TableName - SET @sql = N'DELETE [' + @TableName + ']' - EXEC sp_executesql @sql - - SET @sql = N'BULK INSERT [' + @TableName + '] - FROM ''' + @BasePath + @TableName + '.df'' - WITH - ( - KEEPIDENTITY, - KEEPNULLS, - DATAFILETYPE=''native'' - )' - EXEC sp_executesql @sql - - FETCH NEXT FROM UserTable_Cursor INTO @TableName - - END - CLOSE UserTable_Cursor - DEALLOCATE UserTable_Cursor - - -- ReEnable Constrants for All Tables - FETCH FIRST FROM Table_Cursor INTO @TableName - WHILE (@@Fetch_Status = 0) - BEGIN - SET @sql = N'Alter Table [' + @TableName + '] CHECK CONSTRAINT ALL' - EXEC sp_executesql @sql - - FETCH NEXT FROM Table_Cursor INTO @TableName - END - - CLOSE Table_Cursor - DEALLOCATE Table_Cursor - -GO - -CREATE PROCEDURE dbo.[df_ChangeTrackingTriggerRemove] -AS - DECLARE @sql NVARCHAR(4000) - DECLARE @TableName VARCHAR(255) - - DECLARE Table_Cursor CURSOR FOR - SELECT [table_name] FROM information_schema.tables WHERE table_type = 'BASE TABLE' - - OPEN Table_Cursor - FETCH NEXT FROM Table_Cursor INTO @TableName - - WHILE (@@Fetch_Status = 0) - BEGIN - SET @sql = N'IF EXISTS (SELECT * FROM DBO.SYSOBJECTS WHERE ID = Object_ID(N''[dbo].[trig_df_ChangeTracking_' + @TableName + ']'') AND OBJECTPROPERTY(ID, N''IsTrigger'') = 1) - DROP TRIGGER [dbo].[trig_df_ChangeTracking_' + @TableName + ']' - - EXEC sp_executesql @sql - - FETCH NEXT FROM Table_Cursor INTO @TableName - - END - CLOSE Table_Cursor - DEALLOCATE Table_Cursor - - IF EXISTS (SELECT * FROM dbo.sysobjects WHERE id = object_id(N'[dbo].[df_ChangeTracking]') and OBJECTPROPERTY(id, N'IsUserTable') = 1) - DROP TABLE [dbo].[df_ChangeTracking] - -GO \ No newline at end of file diff --git a/DataFresh/Resources/RemoveDataFresh.sql b/DataFresh/Resources/RemoveDataFresh.sql deleted file mode 100644 index bf75522..0000000 --- a/DataFresh/Resources/RemoveDataFresh.sql +++ /dev/null @@ -1,27 +0,0 @@ -IF EXISTS (SELECT * FROM [DBO].SYSOBJECTS WHERE ID = Object_ID(N'[DBO].[df_ChangeTrackingTriggerRemove]') AND OBJECTPROPERTY(ID, N'IsProcedure') = 1) - EXEC df_ChangeTrackingTriggerRemove -GO - -IF EXISTS (SELECT * FROM [DBO].SYSOBJECTS WHERE ID = Object_ID(N'[DBO].[df_ChangedTableDataRefresh]') AND OBJECTPROPERTY(ID, N'IsProcedure') = 1) - DROP PROCEDURE [dbo].[df_ChangedTableDataRefresh] -GO - -IF EXISTS (SELECT * FROM [DBO].SYSOBJECTS WHERE ID = Object_ID(N'[DBO].[df_ChangeTrackingTriggerCreate]') AND OBJECTPROPERTY(ID, N'IsProcedure') = 1) - DROP PROCEDURE [dbo].[df_ChangeTrackingTriggerCreate] -GO - -IF EXISTS (SELECT * FROM [DBO].SYSOBJECTS WHERE ID = Object_ID(N'[DBO].[df_ChangeTrackingTriggerRemove]') AND OBJECTPROPERTY(ID, N'IsProcedure') = 1) - DROP PROCEDURE [dbo].[df_ChangeTrackingTriggerRemove] -GO - -IF EXISTS (SELECT * FROM [DBO].SYSOBJECTS WHERE ID = Object_ID(N'[DBO].[df_TableDataExtract]') AND OBJECTPROPERTY(ID, N'IsProcedure') = 1) - DROP PROCEDURE [dbo].[df_TableDataExtract] -GO - -IF EXISTS (SELECT * FROM [DBO].SYSOBJECTS WHERE ID = Object_ID(N'[DBO].[df_TableDataImport]') AND OBJECTPROPERTY(ID, N'IsProcedure') = 1) - DROP PROCEDURE [dbo].[df_TableDataImport] -GO - -IF EXISTS (SELECT * FROM [DBO].SYSOBJECTS WHERE ID = Object_ID(N'[DBO].[df_ChangeTracking]') AND OBJECTPROPERTY(ID, N'IsTable') = 1) - DROP TABLE [dbo].[df_ChangeTracking] -GO \ No newline at end of file diff --git a/DataFresh/SqlDataFresh.cs b/DataFresh/SqlDataFresh.cs index 930aeee..68114c7 100644 --- a/DataFresh/SqlDataFresh.cs +++ b/DataFresh/SqlDataFresh.cs @@ -1,28 +1,30 @@ -// EntropyZero dataFresh Copyright (C) 2007 EntropyZero Consulting, LLC. -// Please visit us on the web: http://blogs.ent0.com/ -// -// This library is free software; you can redistribute it and/or modify -// it under the terms of the GNU Lesser General Public License as -// published by the Free Software Foundation; either version 2.1 of the -// License, or (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, but -// WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to: -// Free Software Foundation, Inc., -// 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - +// EntropyZero dataFresh Copyright (C) 2007 EntropyZero Consulting, LLC. +// Please visit us on the web: http://blogs.ent0.com/ +// +// This library is free software; you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as +// published by the Free Software Foundation; either version 2.1 of the +// License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, but +// WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to: +// Free Software Foundation, Inc., +// 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + using System; +using System.Collections.Generic; using System.Data.SqlClient; -using System.IO; +using System.Diagnostics; +using System.Linq; using System.Text; namespace DataFresh -{ +{ /// /// dataFresh by Entropy Zero Consulting is a library that will enable /// the test driven developer to build a test harness that will refresh @@ -30,248 +32,412 @@ namespace DataFresh /// public class SqlDataFresh : IDataFresh { - #region Member Variables - - private string connectionString = null; - private DirectoryInfo snapshotPath = null; - - private string PrepareScriptResourceName = "DataFresh.Resources.PrepareDataFresh.sql"; - private string RemoveScriptResourceName = "DataFresh.Resources.RemoveDataFresh.sql"; - - public string PrepareProcedureName = "df_ChangeTrackingTriggerCreate"; - public string RefreshProcedureName = "df_ChangedTableDataRefresh"; - public string ExtractProcedureName = "df_TableDataExtract"; - public string ImportProcedureName = "df_TableDataImport"; - public string ChangeTrackingTableName = "df_ChangeTracking"; - - private bool verbose = false; - - #endregion + readonly string connectionString; + public const string ChangeTrackingTableName = "df_ChangeTracking"; + const string SnapshotTableSuffix = "__backup"; + + sealed class TableMetadata + { + public string Schema { get; set; } + public string Name { get; set; } + } - #region Public Methods + readonly bool verbose; + readonly string databaseName; public SqlDataFresh(string connectionString) { this.connectionString = connectionString; + var connectionBuilder = new SqlConnectionStringBuilder(connectionString); + databaseName = connectionBuilder.InitialCatalog; } public SqlDataFresh(string connectionString, bool verbose) + : this(connectionString) { - this.connectionString = connectionString; this.verbose = verbose; } - public bool TableExists(string tableName) + public void PrepareDatabaseForDataFresh() { - int tableCount = Int32.Parse(ExecuteScalar(string.Format("SELECT COUNT(TABLE_NAME) FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME='{0}'", tableName)).ToString()); - return (tableCount > 0); + PrepareDatabaseForDataFresh(true); } - public bool ProcedureExists(string procedureName) - { - int procedureCount = Int32.Parse(ExecuteScalar(string.Format("SELECT COUNT(ROUTINE_NAME) FROM INFORMATION_SCHEMA.ROUTINES WHERE ROUTINE_NAME='{0}'", procedureName)).ToString()); - return (procedureCount > 0); + public void PrepareDatabaseForDataFresh(bool createSnapshot) + { + var mode = createSnapshot ? "(with snapshot creation)" : string.Empty; + Execute($"Prepare database{mode}", () => + { + PrepareDataFresh(); + + if (createSnapshot) + CreateSnapshot(); + }); } - #endregion + public void CreateSnapshot() + { + GuardDatabaseIsPrepared(); + Execute("Create snapshot", () => + { + var allTables = GetAllTables(); + PerformBulkBackup(allTables); + }); + } - #region IDataFresh Members + void PrepareDataFresh() + { + Execute("Prepare DataFresh", () => + { + var allTables = GetAllTables(); + + ExecuteNonQuery(@" + IF OBJECT_ID(N'[dbo].[df_ChangeTracking]', N'U') IS NOT NULL + BEGIN + DROP TABLE [dbo].[df_ChangeTracking] + END; + + CREATE TABLE [dbo].[df_ChangeTracking] ([TableSchema] SYSNAME, [TableName] SYSNAME)" + ); + + ExecuteForEach(allTables, t => $@" + IF OBJECT_ID(N'[{t.Schema}].[trig_df_ChangeTracking_{t.Name}]') IS NOT NULL + BEGIN + DROP TRIGGER [{t.Schema}].[trig_df_ChangeTracking_{t.Name}] + END; + + EXEC (N'CREATE TRIGGER [{t.Schema}].[trig_df_ChangeTracking_{t.Name}] ON [{t.Schema}].[{t.Name}] + FOR INSERT, UPDATE, DELETE + AS + SET NOCOUNT ON + INSERT INTO df_ChangeTracking (TableSchema, TableName) VALUES (''{t.Schema}'', ''{t.Name}'') + SET NOCOUNT OFF');" + ); + }); + } - /// - /// prepare the database to use the dataFresh library - /// - public void PrepareDatabaseforDataFresh() + public void RemoveDataFreshFromDatabase() { - PrepareDatabaseforDataFresh(true); + Execute("Remove DataFresh", () => + { + var allTables = GetAllTables(); + + ExecuteForEach(allTables, t => $@" + IF (OBJECT_ID(N'[{t.Schema}].[trig_df_ChangeTracking_{t.Name}]') IS NOT NULL) + BEGIN + DROP TRIGGER [{t.Schema}].[trig_df_ChangeTracking_{t.Name}] + END; + + IF OBJECT_ID (N'[{t.Schema}].[{t.Name}{SnapshotTableSuffix}]', N'U') IS NOT NULL + BEGIN + DROP TABLE [{t.Schema}].[{t.Name}{SnapshotTableSuffix}]; + END;" + ); + + ExecuteNonQuery(@" + IF OBJECT_ID (N'[dbo].[df_ChangeTracking]', N'U') IS NOT NULL + DROP TABLE [dbo].[df_ChangeTracking]" + ); + }); } - public void PrepareDatabaseforDataFresh(bool createSnapshot) + public void RefreshTheDatabase() + { + GuardDatabaseIsPrepared(); + Execute("Refresh", () => + { + var changedAndReferencedTables = GetChangedAndReferencedTables(); + var changedTables = GetChangedTables(); + + ExecuteNonQuery($"TRUNCATE TABLE [dbo].[{ChangeTrackingTableName}]"); + + ExecuteForEach(changedAndReferencedTables, t => + $"ALTER TABLE [{t.Schema}].[{t.Name}] NOCHECK CONSTRAINT ALL;" + ); + + ExecuteForEach(changedTables, t => $@" + DELETE [{t.Schema}].[{t.Name}]; + DELETE FROM df_ChangeTracking WHERE TableName='{t.Name}' and TableSchema='{t.Schema}'; + + IF (SELECT COUNT(*) FROM INFORMATION_SCHEMA.TABLES + WHERE table_schema = '{t.Schema}' AND table_name = '{t.Name}' + AND IDENT_SEED(TABLE_NAME) IS NOT NULL) > 0 + BEGIN + DBCC CHECKIDENT([{t.Schema}.{t.Name}], RESEED, 0) + END" + ); + + PerformBulkRestore(changedTables); + + ExecuteForEach(changedAndReferencedTables, t => + $"ALTER TABLE [{t.Schema}].[{t.Name}] CHECK CONSTRAINT ALL;" + ); + }); + } + + public void RefreshTheEntireDatabase() { - DateTime before = DateTime.Now; - ConsoleWrite("PrepareDatabaseforDataFresh Started"); - RunSqlScript(ResourceManagement.GetDecryptedResourceStream(PrepareScriptResourceName)); + GuardDatabaseIsPrepared(); + Execute("Refresh (entire)", () => + { + var allTables = GetAllTables(); + var changedTables = GetChangedTables(); + ExecuteNonQuery($"TRUNCATE TABLE [dbo].[{ChangeTrackingTableName}]"); - ExecuteNonQuery("exec " + PrepareProcedureName); + ExecuteForEach(allTables, t => + $"ALTER TABLE [{t.Schema}].[{t.Name}] NOCHECK CONSTRAINT ALL;" + ); - if(createSnapshot) - { - CreateSnapshot(); - } - ConsoleWrite("PrepareDatabaseforDataFresh Complete : " + (DateTime.Now - before)); + ExecuteForEach(changedTables, t => + $"DELETE FROM [{t.Schema}].[{t.Name}]" + ); + + PerformBulkRestore(changedTables); + + ExecuteForEach(allTables, t => + $"ALTER TABLE [{t.Schema}].[{t.Name}] CHECK CONSTRAINT ALL;" + ); + }); } - /// - /// remove the dataFresh objects from a database - /// - public void RemoveDataFreshFromDatabase() + public bool HasDatabaseBeenModified() { - DateTime before = DateTime.Now; - ConsoleWrite("RemoveDataFreshFromDatabase Started"); - RunSqlScript(ResourceManagement.GetDecryptedResourceStream(RemoveScriptResourceName)); - ConsoleWrite("RemoveDataFreshFromDatabase Complete : " + (DateTime.Now - before)); + GuardDatabaseIsPrepared(); + var sql = + $@"SELECT COUNT(*) FROM {ChangeTrackingTableName} + WHERE TableName <> 'ChangeTrackingTableName' + AND TableName NOT LIKE '%{SnapshotTableSuffix}'"; + var ret = Convert.ToInt32(ExecuteScalar(sql)); + return ret > 0; } - /// - /// refresh the database to a known state - /// - public void RefreshTheDatabase() + public void RunStatements(IEnumerable statements) { - DateTime before = DateTime.Now; - ConsoleWrite("RefreshTheDatabase Started"); - if (!ProcedureExists(RefreshProcedureName)) + var cb = new StringBuilder(); + const int maxLength = 6000; + var currentLength = 0; + foreach (var statement in statements) { - throw new SqlDataFreshException("DataFresh procedure not found. Please prepare the database."); + if (currentLength + statement.Length > maxLength) + Flush(); + + currentLength += statement.Length; + cb.Append(statement); } - ExecuteNonQuery(string.Format("exec {0} '{1}'", RefreshProcedureName, SnapshotPath.FullName)); - ConsoleWrite("RefreshTheDatabase Complete : " + (DateTime.Now - before)); - } - /// - /// refresh the database ignoring the dataFresh change tracking table. - /// - public void RefreshTheEntireDatabase() - { - DateTime before = DateTime.Now; - ConsoleWrite("RefreshTheEntireDatabase Started"); - if (!ProcedureExists(ImportProcedureName)) + if (currentLength > 0) + Flush(); + + void Flush() { - throw new SqlDataFreshException("DataFresh procedure not found. Please prepare the database."); + ExecuteNonQuery(cb.ToString()); + cb.Clear(); + currentLength = 0; } - ExecuteNonQuery(string.Format("exec {0} '{1}'", ImportProcedureName, SnapshotPath.FullName)); - ConsoleWrite("RefreshTheEntireDatabase Complete : " + (DateTime.Now - before)); } - /// - /// create snapshot of database - /// - public void CreateSnapshot() + void PerformBulkBackup(IReadOnlyCollection tables) { - DateTime before = DateTime.Now; - ConsoleWrite("CreateSnapshot Started"); - if (!ProcedureExists(ExtractProcedureName)) - { - throw new SqlDataFreshException("DataFresh procedure not found. Please prepare the database."); - } - ExecuteNonQuery(string.Format("exec {0} '{1}'", ExtractProcedureName, SnapshotPath.FullName)); - ConsoleWrite("CreateSnapshot Complete : " + (DateTime.Now - before)); + PerformBulkOperation(tables, backup: true); } - /// - /// determine if the database has been modified - /// - /// true if modified. - public bool HasDatabaseBeenModified() + void PerformBulkRestore(IReadOnlyCollection tables) { - if (!TableExists(ChangeTrackingTableName)) - { - throw new SqlDataFreshException("DataFresh procedure not found. Please prepare the database."); - } + PerformBulkOperation(tables, backup: false); + } - string sql = string.Format(@"SELECT COUNT(*) FROM {0} WHERE TableName <> '{0}'", ChangeTrackingTableName); - int ret = Convert.ToInt32(ExecuteScalar(sql)); - return ret > 0; + void PerformBulkOperation(IReadOnlyCollection tables, bool backup) + { + var destinationSuffix = backup ? SnapshotTableSuffix : string.Empty; + var sourceSuffix = backup ? string.Empty : SnapshotTableSuffix; + + if (backup) + { + ExecuteForEach(tables, t => + { + var sourceTable = $"[{t.Schema}].[{t.Name}{sourceSuffix}]"; + var destinationTable = $"[{t.Schema}].[{t.Name}{destinationSuffix}]"; + + return $@" + IF OBJECT_ID (N'{destinationTable}', N'U') IS NULL BEGIN + SELECT * INTO {destinationTable} FROM {sourceTable} WHERE 1=2 END + ELSE BEGIN + TRUNCATE TABLE {destinationTable} + END;"; + }); + } + + foreach (var table in tables) + { + var sourceTable = $"[{table.Schema}].[{table.Name}{sourceSuffix}]"; + var destinationTable = $"[{table.Schema}].[{table.Name}{destinationSuffix}]"; + + CopyTable(connectionString, sourceTable, destinationTable); + } } - /// - /// location on the server where the snapshot files are located - /// - public DirectoryInfo SnapshotPath + static void CopyTable(string dbConnectionString, string sourceTable, string destinationTable) { - get + using (var sourceConnection = new SqlConnection(dbConnectionString)) { - if (snapshotPath == null) + sourceConnection.Open(); + var commandSourceData = new SqlCommand($"SELECT * FROM {sourceTable};", sourceConnection); + var reader = commandSourceData.ExecuteReader(); + + using (var destinationConnection = new SqlConnection(dbConnectionString)) { - return GetSnapshopPath(); + destinationConnection.Open(); + + using (var bulkCopy = new SqlBulkCopy(destinationConnection)) + { + bulkCopy.DestinationTableName = destinationTable; + try + { + bulkCopy.WriteToServer(reader); + } + catch (Exception ex) + { + Console.WriteLine(ex.Message); + } + finally + { + reader.Close(); + } + } } - return snapshotPath; - } - set - { - snapshotPath = CheckForIllegalCharsAndAppendTrailingSlash(value); } } - #endregion - - #region Private Methods - - private static DirectoryInfo CheckForIllegalCharsAndAppendTrailingSlash(DirectoryInfo value) - { - if(value == null) - { - return null; - } - string path = value.FullName; - path = path.Replace("\"", ""); - if(!path.EndsWith(@"\")) - { - path += @"\"; - } - return new DirectoryInfo(path); - } - - private object ExecuteScalar(string sql) + object ExecuteScalar(string sql) { - using (SqlConnection conn = new SqlConnection(connectionString)) + using (var conn = new SqlConnection(connectionString)) { - sql = sql + " --dataProfilerIgnore"; - SqlCommand cmd = new SqlCommand(sql, conn); - cmd.CommandTimeout = 1200; + sql += " --dataProfilerIgnore"; + var cmd = new SqlCommand(sql, conn) { CommandTimeout = 1200 }; conn.Open(); return cmd.ExecuteScalar(); } } - private void ExecuteNonQuery(string sql) + void ExecuteNonQuery(string sql) { - using (SqlConnection conn = new SqlConnection(connectionString)) + using (var conn = new SqlConnection(connectionString)) { - sql = sql + " --dataProfilerIgnore"; - SqlCommand cmd = new SqlCommand(sql, conn); - cmd.CommandTimeout = 1200; - conn.Open(); - cmd.ExecuteNonQuery(); + conn.Open(); + sql += " --dataProfilerIgnore"; + using (var cmd = new SqlCommand(sql, conn) { CommandTimeout = 1200 }) + cmd.ExecuteNonQuery(); } } - private DirectoryInfo GetSnapshopPath() + void ConsoleWrite(string message) { - string dbName = (string) ExecuteScalar("SELECT DB_Name()"); - string mdfFilePath = Path.GetDirectoryName(ExecuteScalar("select filename from sysfiles where filename like '%.MDF%'").ToString().Trim()); - return new DirectoryInfo(string.Format(@"{0}\Snapshot_{1}\", mdfFilePath, dbName)); + if (verbose) + Console.Out.WriteLine(message); } - private void RunSqlScript(StreamReader reader) + void Execute(string actionName, Action action) { - string line = ""; - StringBuilder cmd = new StringBuilder(); - while ((line = reader.ReadLine()) != null) - { - if (line.Trim().ToLower().Equals("go")) - { - ExecuteNonQuery(cmd.ToString()); - cmd.Length = 0; - } - else - { - cmd.Append(line); - cmd.Append(Environment.NewLine); - } - } - if (cmd.ToString().Trim().Length > 0) + var stopWatch = new Stopwatch(); + ConsoleWrite($"{actionName} for {databaseName} started"); + stopWatch.Start(); + try { - ExecuteNonQuery(cmd.ToString()); + action(); + } + finally + { + stopWatch.Stop(); + ConsoleWrite($"{actionName} for {databaseName} complete: {stopWatch.Elapsed}"); } } - private void ConsoleWrite(string message) + void ExecuteForEach(IEnumerable tables, Func func) { - if(this.verbose) + RunStatements(tables.Select(func)); + } + + IReadOnlyCollection SelectTables(string sql) + { + var tables = new List(); + using (var conn = new SqlConnection(connectionString)) { - Console.Out.WriteLine(message); + conn.Open(); + using (var cmd = new SqlCommand(sql, conn)) + using (var reader = cmd.ExecuteReader()) + { + while (reader.Read()) + { + tables.Add(new TableMetadata + { + Schema = reader.GetString(0), + Name = reader.GetString(1) + }); + } + } } + return tables; + } + + void GuardDatabaseIsPrepared() + { + if (!TableExists(ChangeTrackingTableName)) + throw new SqlDataFreshException( + $"DataFresh table ({ChangeTrackingTableName}) not found. Please prepare the database."); + } + + IReadOnlyCollection GetAllTables() + { + var sql = + $@"SELECT table_schema, table_name + FROM Information_Schema.tables + WHERE table_type = 'BASE TABLE' + AND table_name NOT IN ('df_ChangeTracking', 'dr_DeltaVersion') + AND table_name NOT LIKE '%{SnapshotTableSuffix}'"; + + var tables = SelectTables(sql); + return tables; } - #endregion + IReadOnlyCollection GetChangedTables() + { + var sql = + $@"SELECT DISTINCT TableSchema, TableName + FROM df_ChangeTracking + WHERE TableName NOT IN ('df_ChangeTracking', 'dr_DeltaVersion') + AND TableName NOT LIKE '%{SnapshotTableSuffix}'"; + + var tables = SelectTables(sql); + return tables; + } + + IReadOnlyCollection GetChangedAndReferencedTables() + { + var sql = $@" + SELECT DISTINCT x.TableSchema, x.TableName + FROM ( + SELECT DISTINCT TableSchema, TableName + FROM df_ChangeTracking + UNION + SELECT DISTINCT + OBJECT_SCHEMA_NAME(fkeyid) AS TableSchema, + OBJECT_NAME(fkeyid) AS TableName + FROM sysreferences sr + INNER JOIN df_ChangeTracking ct ON sr.rkeyid = OBJECT_ID(ct.TableName) + ) x + WHERE x.TableName NOT IN ('df_ChangeTracking', 'dr_DeltaVersion') + AND x.TableName NOT LIKE '%{SnapshotTableSuffix}' + "; + + var tables = SelectTables(sql); + return tables; + } + + public bool TableExists(string tableName) + { + var tableCount = int.Parse(ExecuteScalar( + $"SELECT COUNT(TABLE_NAME) FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME='{tableName}'").ToString()); + return (tableCount > 0); + } } } \ No newline at end of file diff --git a/DataFreshUtil/AssemblyInfo.cs b/DataFreshUtil/AssemblyInfo.cs index 700e112..7219c01 100644 --- a/DataFreshUtil/AssemblyInfo.cs +++ b/DataFreshUtil/AssemblyInfo.cs @@ -1,5 +1,4 @@ using System.Reflection; -[assembly: AssemblyVersionAttribute("1.0.0.0")] +[assembly: AssemblyVersionAttribute("2.0.0.0")] [assembly: AssemblyTitleAttribute("dataFresh Console Utility")] - diff --git a/DataFreshUtil/DataFreshUtil.csproj b/DataFreshUtil/DataFreshUtil.csproj index 7b6e37b..d2d5664 100644 --- a/DataFreshUtil/DataFreshUtil.csproj +++ b/DataFreshUtil/DataFreshUtil.csproj @@ -1,109 +1,105 @@ - - - - - - - - - - - - - - - - - - - - - - - - + + + + Local + 7.10.6030 + 2.0 + {D1044AB1-AB58-42E3-A37B-4099116982A5} + Debug + AnyCPU + App.ico + + DataFreshUtil + + JScript + Grid + IE50 + false + Exe + DataFreshUtil + OnBuildSuccess + + + + v4.7.2 + + + 0.0 + + + + bin\Debug\ + false + 285212672 + false + + DEBUG;TRACE + + true + 4096 + false + + false + false + false + false + 4 + full + prompt + false + + + bin\Release\ + false + 285212672 + false + + TRACE + + false + 4096 + false + + true + false + false + false + 4 + none + prompt + false + + + + DataFresh + {05438358-2120-4D97-974E-ACF80F7EA6F7} + {FAE04EC0-301F-11D3-BF4B-00C04F79EFBC} + + + System + + + System.Data + + + System.XML + + + + + Code + + + Code + + + + + + + + + + + + \ No newline at end of file diff --git a/DataFreshUtil/EntryPoint.cs b/DataFreshUtil/EntryPoint.cs index 3abcf8c..63f2ebb 100644 --- a/DataFreshUtil/EntryPoint.cs +++ b/DataFreshUtil/EntryPoint.cs @@ -1,30 +1,30 @@ -// EntropyZero dataFresh Copyright (C) 2007 EntropyZero Consulting, LLC. -// Please visit us on the web: http://blogs.ent0.com/ -// -// This library is free software; you can redistribute it and/or modify -// it under the terms of the GNU Lesser General Public License as -// published by the Free Software Foundation; either version 2.1 of the -// License, or (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, but -// WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to: -// Free Software Foundation, Inc., -// 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - +// EntropyZero dataFresh Copyright (C) 2007 EntropyZero Consulting, LLC. +// Please visit us on the web: http://blogs.ent0.com/ +// +// This library is free software; you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as +// published by the Free Software Foundation; either version 2.1 of the +// License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, but +// WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to: +// Free Software Foundation, Inc., +// 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + using DataFresh; namespace DataFreshUtil { - public class EntryPoint + static class EntryPoint { public static void Main(string[] args) { - DataFreshConsole console = new DataFreshConsole(); + var console = new DataFreshConsole(); console.Start(args); } } diff --git a/DataFreshUtil/app.config b/DataFreshUtil/app.config new file mode 100644 index 0000000..05d8b24 --- /dev/null +++ b/DataFreshUtil/app.config @@ -0,0 +1,3 @@ + + + diff --git a/EntropyZero DataFresh Solution.sln b/EntropyZero DataFresh Solution.sln index 8a9727a..04af4f1 100644 --- a/EntropyZero DataFresh Solution.sln +++ b/EntropyZero DataFresh Solution.sln @@ -1,51 +1,43 @@ -Microsoft Visual Studio Solution File, Format Version 8.00 -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "DataFresh", "DataFresh\DataFresh.csproj", "{05438358-2120-4D97-974E-ACF80F7EA6F7}" - ProjectSection(ProjectDependencies) = postProject - EndProjectSection -EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "TestHarnessExample", "TestHarnessExample\TestHarnessExample.csproj", "{D688D8F0-3CDE-4C39-BF81-ED8C210C8F8E}" - ProjectSection(ProjectDependencies) = postProject - EndProjectSection -EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Testing.DataFresh", "Testing.DataFresh\Testing.DataFresh.csproj", "{3E910EED-904F-4A52-A611-9278B682EFD3}" - ProjectSection(ProjectDependencies) = postProject - EndProjectSection -EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "DataFreshUtil", "DataFreshUtil\DataFreshUtil.csproj", "{D1044AB1-AB58-42E3-A37B-4099116982A5}" - ProjectSection(ProjectDependencies) = postProject - EndProjectSection -EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "DataFresh.Common", "DataFresh.Common\DataFresh.Common.csproj", "{0BAA8852-1597-43BB-AF78-BABA707D4D86}" - ProjectSection(ProjectDependencies) = postProject - EndProjectSection -EndProject -Global - GlobalSection(SolutionConfiguration) = preSolution - Debug = Debug - Release = Release - EndGlobalSection - GlobalSection(ProjectConfiguration) = postSolution - {05438358-2120-4D97-974E-ACF80F7EA6F7}.Debug.ActiveCfg = Debug|.NET - {05438358-2120-4D97-974E-ACF80F7EA6F7}.Debug.Build.0 = Debug|.NET - {05438358-2120-4D97-974E-ACF80F7EA6F7}.Release.ActiveCfg = Release|.NET - {05438358-2120-4D97-974E-ACF80F7EA6F7}.Release.Build.0 = Release|.NET - {D688D8F0-3CDE-4C39-BF81-ED8C210C8F8E}.Debug.ActiveCfg = Debug|.NET - {D688D8F0-3CDE-4C39-BF81-ED8C210C8F8E}.Debug.Build.0 = Debug|.NET - {D688D8F0-3CDE-4C39-BF81-ED8C210C8F8E}.Release.ActiveCfg = Release|.NET - {D688D8F0-3CDE-4C39-BF81-ED8C210C8F8E}.Release.Build.0 = Release|.NET - {3E910EED-904F-4A52-A611-9278B682EFD3}.Debug.ActiveCfg = Debug|.NET - {3E910EED-904F-4A52-A611-9278B682EFD3}.Debug.Build.0 = Debug|.NET - {3E910EED-904F-4A52-A611-9278B682EFD3}.Release.ActiveCfg = Release|.NET - {3E910EED-904F-4A52-A611-9278B682EFD3}.Release.Build.0 = Release|.NET - {D1044AB1-AB58-42E3-A37B-4099116982A5}.Debug.ActiveCfg = Debug|.NET - {D1044AB1-AB58-42E3-A37B-4099116982A5}.Debug.Build.0 = Debug|.NET - {D1044AB1-AB58-42E3-A37B-4099116982A5}.Release.ActiveCfg = Release|.NET - {D1044AB1-AB58-42E3-A37B-4099116982A5}.Release.Build.0 = Release|.NET - {0BAA8852-1597-43BB-AF78-BABA707D4D86}.Debug.ActiveCfg = Debug|.NET - {0BAA8852-1597-43BB-AF78-BABA707D4D86}.Release.ActiveCfg = Release|.NET - EndGlobalSection - GlobalSection(ExtensibilityGlobals) = postSolution - EndGlobalSection - GlobalSection(ExtensibilityAddIns) = postSolution - EndGlobalSection -EndGlobal +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio 14 +VisualStudioVersion = 14.0.25123.0 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "DataFresh", "DataFresh\DataFresh.csproj", "{05438358-2120-4D97-974E-ACF80F7EA6F7}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "TestHarnessExample", "TestHarnessExample\TestHarnessExample.csproj", "{D688D8F0-3CDE-4C39-BF81-ED8C210C8F8E}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Testing.DataFresh", "Testing.DataFresh\Testing.DataFresh.csproj", "{3E910EED-904F-4A52-A611-9278B682EFD3}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "DataFreshUtil", "DataFreshUtil\DataFreshUtil.csproj", "{D1044AB1-AB58-42E3-A37B-4099116982A5}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "DataFresh.Common", "DataFresh.Common\DataFresh.Common.csproj", "{0BAA8852-1597-43BB-AF78-BABA707D4D86}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {05438358-2120-4D97-974E-ACF80F7EA6F7}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {05438358-2120-4D97-974E-ACF80F7EA6F7}.Debug|Any CPU.Build.0 = Debug|Any CPU + {05438358-2120-4D97-974E-ACF80F7EA6F7}.Release|Any CPU.ActiveCfg = Release|Any CPU + {05438358-2120-4D97-974E-ACF80F7EA6F7}.Release|Any CPU.Build.0 = Release|Any CPU + {D688D8F0-3CDE-4C39-BF81-ED8C210C8F8E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {D688D8F0-3CDE-4C39-BF81-ED8C210C8F8E}.Debug|Any CPU.Build.0 = Debug|Any CPU + {D688D8F0-3CDE-4C39-BF81-ED8C210C8F8E}.Release|Any CPU.ActiveCfg = Release|Any CPU + {D688D8F0-3CDE-4C39-BF81-ED8C210C8F8E}.Release|Any CPU.Build.0 = Release|Any CPU + {3E910EED-904F-4A52-A611-9278B682EFD3}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {3E910EED-904F-4A52-A611-9278B682EFD3}.Debug|Any CPU.Build.0 = Debug|Any CPU + {3E910EED-904F-4A52-A611-9278B682EFD3}.Release|Any CPU.ActiveCfg = Release|Any CPU + {3E910EED-904F-4A52-A611-9278B682EFD3}.Release|Any CPU.Build.0 = Release|Any CPU + {D1044AB1-AB58-42E3-A37B-4099116982A5}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {D1044AB1-AB58-42E3-A37B-4099116982A5}.Debug|Any CPU.Build.0 = Debug|Any CPU + {D1044AB1-AB58-42E3-A37B-4099116982A5}.Release|Any CPU.ActiveCfg = Release|Any CPU + {D1044AB1-AB58-42E3-A37B-4099116982A5}.Release|Any CPU.Build.0 = Release|Any CPU + {0BAA8852-1597-43BB-AF78-BABA707D4D86}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {0BAA8852-1597-43BB-AF78-BABA707D4D86}.Release|Any CPU.ActiveCfg = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection +EndGlobal diff --git a/EntropyZero DataFresh Solution.sln.DotSettings b/EntropyZero DataFresh Solution.sln.DotSettings new file mode 100644 index 0000000..241eb00 --- /dev/null +++ b/EntropyZero DataFresh Solution.sln.DotSettings @@ -0,0 +1,17 @@ + + True + True + True + True + True + True + True + True + True + True + True + True + True + True + True + True \ No newline at end of file diff --git a/TODO.txt b/TODO.txt index 3a02287..eb824c4 100644 --- a/TODO.txt +++ b/TODO.txt @@ -1,3 +1,2 @@ 1) Fix unit tests to create DatafreshSample DB automatically -2) Clean up scripts in Sample Project -3) Update to VS2008! \ No newline at end of file +2) Clean up scripts in Sample Project \ No newline at end of file diff --git a/TestConnectionStrings.xml b/TestConnectionStrings.xml new file mode 100644 index 0000000..e553df7 --- /dev/null +++ b/TestConnectionStrings.xml @@ -0,0 +1,10 @@ + + + tf_user + 1234 + localhost + false + + user id={0};password={1};Initial Catalog=master;Server={2};pooling={3}; + user id={0};password={1};Initial Catalog=DataFreshSample;Server={2};pooling={3}; + \ No newline at end of file diff --git a/TestHarnessExample/Scripts/Clean Database.bat b/TestHarnessExample/Scripts/Clean Database.bat deleted file mode 100644 index 42bebd1..0000000 --- a/TestHarnessExample/Scripts/Clean Database.bat +++ /dev/null @@ -1,3 +0,0 @@ -DataFreshUtil.exe -s 127.0.0.1 -u test -p test -d DataFreshSample -c REMOVE - -pause \ No newline at end of file diff --git a/TestHarnessExample/Scripts/Clean Database.ps1 b/TestHarnessExample/Scripts/Clean Database.ps1 new file mode 100644 index 0000000..85ac61b --- /dev/null +++ b/TestHarnessExample/Scripts/Clean Database.ps1 @@ -0,0 +1,6 @@ +Import-Module $PSScriptRoot\CredentialReader.psm1 + +$creds = Get-Credentials +.\DataFreshUtil.exe -s $creds.Server -u $creds.UserId -p $creds.Password -d DataFreshSample -c REMOVE + +pause \ No newline at end of file diff --git a/TestHarnessExample/Scripts/Create Database.bat b/TestHarnessExample/Scripts/Create Database.bat deleted file mode 100644 index 152f83c..0000000 --- a/TestHarnessExample/Scripts/Create Database.bat +++ /dev/null @@ -1,5 +0,0 @@ -osql.exe -S 127.0.0.1 -U test -P test -d DataFreshSample -i database.sql - -DataFreshUtil.exe -s 127.0.0.1 -u test -p test -d DataFreshSample -c PREPARE - -pause \ No newline at end of file diff --git a/TestHarnessExample/Scripts/Create Database.ps1 b/TestHarnessExample/Scripts/Create Database.ps1 new file mode 100644 index 0000000..f3f7f66 --- /dev/null +++ b/TestHarnessExample/Scripts/Create Database.ps1 @@ -0,0 +1,9 @@ +Import-Module $PSScriptRoot\CredentialReader.psm1 + +$creds = Get-Credentials + +osql.exe -S $creds.Server -U $creds.UserId -P $creds.Password -d DataFreshSample -i $PSScriptRoot\database.sql + +.\DataFreshUtil.exe -s $creds.Server -u $creds.UserId -p $creds.Password -d DataFreshSample -c PREPARE + +pause \ No newline at end of file diff --git a/TestHarnessExample/Scripts/CredentialReader.psm1 b/TestHarnessExample/Scripts/CredentialReader.psm1 new file mode 100644 index 0000000..361a3b7 --- /dev/null +++ b/TestHarnessExample/Scripts/CredentialReader.psm1 @@ -0,0 +1,11 @@ +function Get-Credentials() { + + $rootXml = (Select-Xml -Path "$PSScriptRoot\..\..\TestConnectionStrings.xml" -XPath "/connectionStrings").Node + + $credentialObject = New-Object -TypeName PSObject + $credentialObject | Add-Member -MemberType NoteProperty -Name UserId -TypeName String -Value (Select-Xml -Node $rootXml -XPath "properties/userId").Node.InnerText + $credentialObject | Add-Member -MemberType NoteProperty -Name Password -TypeName String -Value (Select-Xml -Node $rootXml -XPath "properties/password").Node.InnerText + $credentialObject | Add-Member -MemberType NoteProperty -Name Server -TypeName String -Value (Select-Xml -Node $rootXml -XPath "properties/server").Node.InnerText + + $credentialObject +} \ No newline at end of file diff --git a/TestHarnessExample/Scripts/DataFresh Usage.bat b/TestHarnessExample/Scripts/DataFresh Usage.bat deleted file mode 100644 index 94f05ca..0000000 --- a/TestHarnessExample/Scripts/DataFresh Usage.bat +++ /dev/null @@ -1,2 +0,0 @@ -DataFreshUtil.exe -pause \ No newline at end of file diff --git a/TestHarnessExample/Scripts/Prepare Database.bat b/TestHarnessExample/Scripts/Prepare Database.bat deleted file mode 100644 index 1f1e74f..0000000 --- a/TestHarnessExample/Scripts/Prepare Database.bat +++ /dev/null @@ -1,3 +0,0 @@ -DataFreshUtil.exe -s 127.0.0.1 -u test -p test -d DataFreshSample -c PREPARE - -pause \ No newline at end of file diff --git a/TestHarnessExample/Scripts/Prepare Database.ps1 b/TestHarnessExample/Scripts/Prepare Database.ps1 new file mode 100644 index 0000000..59f1a53 --- /dev/null +++ b/TestHarnessExample/Scripts/Prepare Database.ps1 @@ -0,0 +1,6 @@ +Import-Module $PSScriptRoot\CredentialReader.psm1 + +$creds = Get-Credentials +.\DataFreshUtil.exe -s $creds.Server -u $creds.UserId -p $creds.Password -d DataFreshSample -c PREPARE + +pause \ No newline at end of file diff --git a/TestHarnessExample/Scripts/Refresh Database.bat b/TestHarnessExample/Scripts/Refresh Database.bat deleted file mode 100644 index 122dddb..0000000 --- a/TestHarnessExample/Scripts/Refresh Database.bat +++ /dev/null @@ -1,3 +0,0 @@ -DataFreshUtil.exe -s 127.0.0.1 -u test -p test -d DataFreshSample -c REFRESH - -pause \ No newline at end of file diff --git a/TestHarnessExample/Scripts/Refresh Database.ps1 b/TestHarnessExample/Scripts/Refresh Database.ps1 new file mode 100644 index 0000000..db80fb6 --- /dev/null +++ b/TestHarnessExample/Scripts/Refresh Database.ps1 @@ -0,0 +1,6 @@ +Import-Module $PSScriptRoot\CredentialReader.psm1 + +$creds = Get-Credentials +.\DataFreshUtil.exe -s $creds.Server -u $creds.UserId -p $creds.Password -d DataFreshSample -c REFRESH + +pause \ No newline at end of file diff --git a/TestHarnessExample/Scripts/Refresh Entire Database.bat b/TestHarnessExample/Scripts/Refresh Entire Database.bat deleted file mode 100644 index 3a73942..0000000 --- a/TestHarnessExample/Scripts/Refresh Entire Database.bat +++ /dev/null @@ -1,3 +0,0 @@ -DataFreshUtil.exe -s 127.0.0.1 -u test -p test -d DataFreshSample -c FORCEREFRESH - -pause \ No newline at end of file diff --git a/TestHarnessExample/Scripts/Refresh Entire Database.ps1 b/TestHarnessExample/Scripts/Refresh Entire Database.ps1 new file mode 100644 index 0000000..bbafa14 --- /dev/null +++ b/TestHarnessExample/Scripts/Refresh Entire Database.ps1 @@ -0,0 +1,6 @@ +Import-Module $PSScriptRoot\CredentialReader.psm1 + +$creds = Get-Credentials +.\DataFreshUtil.exe -s $creds.Server -u $creds.UserId -p $creds.Password -d DataFreshSample -c FORCEREFRESH + +pause \ No newline at end of file diff --git a/TestHarnessExample/TestFixtureBase.cs b/TestHarnessExample/TestFixtureBase.cs index a2b847c..4c81fd8 100644 --- a/TestHarnessExample/TestFixtureBase.cs +++ b/TestHarnessExample/TestFixtureBase.cs @@ -1,18 +1,29 @@ using System; using System.Data.SqlClient; +using System.Xml; using DataFresh; using NUnit.Framework; +using System.IO; namespace TestHarnessExample { public class TestFixtureBase { - public static SqlDataFresh dataFresh = null; - public static string connectionString = "user id=test;password=test;Initial Catalog=DataFreshSample;Data Source=(local);"; + public static SqlDataFresh dataFresh = null; + public readonly string connectionString; public TestFixtureBase() { - if(dataFresh == null) + var doc = new XmlDocument(); + doc.Load(Path.Combine(Path.GetDirectoryName(GetType().Assembly.Location), @"..\..\..\TestConnectionStrings.xml")); + connectionString = + String.Format(doc.SelectSingleNode("/connectionStrings/sqlDataFreshSampleConnectionStringTemplate").InnerText, + doc.SelectSingleNode("/connectionStrings/properties/userId").InnerText, + doc.SelectSingleNode("/connectionStrings/properties/password").InnerText, + doc.SelectSingleNode("/connectionStrings/properties/server").InnerText, + doc.SelectSingleNode("/connectionStrings/properties/pooling").InnerText); + + if (dataFresh == null) { dataFresh = new SqlDataFresh(connectionString); } @@ -40,21 +51,21 @@ public void TearDown() #region Data Access Helpers - public static void ExecuteNonQuery(string sql) + public void ExecuteNonQuery(string sql) { - using (SqlConnection conn = new SqlConnection(connectionString)) + using (var conn = new SqlConnection(connectionString)) { - SqlCommand cmd = new SqlCommand(sql, conn); + var cmd = new SqlCommand(sql, conn); conn.Open(); cmd.ExecuteNonQuery(); } } - public static object ExecuteScalar(string sql) + public object ExecuteScalar(string sql) { - using (SqlConnection conn = new SqlConnection(connectionString)) + using (var conn = new SqlConnection(connectionString)) { - SqlCommand cmd = new SqlCommand(sql, conn); + var cmd = new SqlCommand(sql, conn); conn.Open(); return cmd.ExecuteScalar(); } diff --git a/TestHarnessExample/TestHarnessExample.csproj b/TestHarnessExample/TestHarnessExample.csproj index ae24df0..3f582c8 100644 --- a/TestHarnessExample/TestHarnessExample.csproj +++ b/TestHarnessExample/TestHarnessExample.csproj @@ -1,147 +1,127 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + Local + 7.10.3077 + 2.0 + {D688D8F0-3CDE-4C39-BF81-ED8C210C8F8E} + Debug + AnyCPU + + + TestHarnessExample + + JScript + Grid + IE50 + false + Library + TestHarnessExample + OnBuildSuccess + + + + v4.7.2 + + + 0.0 + + + + + + bin\Debug\ + false + 285212672 + false + + DEBUG;TRACE + + true + 4096 + false + + false + false + false + false + 4 + full + prompt + false + + + bin\Release\ + false + 285212672 + false + + TRACE + + true + 4096 + false + + true + false + false + false + 4 + full + prompt + false + + + + DataFresh + {05438358-2120-4D97-974E-ACF80F7EA6F7} + {FAE04EC0-301F-11D3-BF4B-00C04F79EFBC} + + + ..\packages\NUnit.3.11.0\lib\net45\nunit.framework.dll + + + System + + + System.Data + + + System.XML + + + + + Code + + + Code + + + Code + + + + + + + + + + + + + + + + + + + This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}. + + + + + \ No newline at end of file diff --git a/TestHarnessExample/packages.config b/TestHarnessExample/packages.config new file mode 100644 index 0000000..247616d --- /dev/null +++ b/TestHarnessExample/packages.config @@ -0,0 +1,5 @@ + + + + + \ No newline at end of file diff --git a/Testing.DataFresh/DataFreshConsoleTester.cs b/Testing.DataFresh/DataFreshConsoleTester.cs index 24c1728..8c06804 100644 --- a/Testing.DataFresh/DataFreshConsoleTester.cs +++ b/Testing.DataFresh/DataFreshConsoleTester.cs @@ -1,11 +1,26 @@ +using System; using DataFresh; using NUnit.Framework; - +using System.IO; + namespace Testing.DataFresh { [TestFixture] public class DataFreshConsoleTester - { + { + readonly string userId; + readonly string password; + readonly string server; + + public DataFreshConsoleTester() + { + var doc = new System.Xml.XmlDocument(); + doc.Load(Path.Combine(Path.GetDirectoryName(GetType().Assembly.Location) ?? string.Empty, @"..\..\..\TestConnectionStrings.xml")); + userId = doc.SelectSingleNode("/connectionStrings/properties/userId")?.InnerText; + password = doc.SelectSingleNode("/connectionStrings/properties/password")?.InnerText; + server = doc.SelectSingleNode("/connectionStrings/properties/server")?.InnerText; + } + [SetUp] public void Setup() { @@ -21,95 +36,94 @@ public void TearDown() [Test] public void NoArgs() { - string[] args = new string[] {}; - DataFreshConsole console = new DataFreshConsole(); - console.Start(args); + var args = new string[] { }; + var console = new DataFreshConsole(); + Assert.DoesNotThrow(() => console.Start(args)); } [Test] public void BlankArgs() { - string[] args = new string[] {"", ""}; - DataFreshConsole console = new DataFreshConsole(); - console.Start(args); + var args = new[] { "", "" }; + var console = new DataFreshConsole(); + Assert.DoesNotThrow(() => console.Start(args)); } [Test] public void BadCommand() { - DataFreshConsole console = ExecuteDataFreshConsole("BADCOMMAND"); - Assert.IsTrue(console.Results.ToString().IndexOf("Command 'BADCOMMAND' was not recognized") > -1); + var console = ExecuteDataFreshConsole("BADCOMMAND"); + StringAssert.Contains("Command 'BADCOMMAND' was not recognized", console.Results); } [Test] public void PrepareCommand() { - DataFreshConsole console = ExecuteDataFreshConsole("PREPARE"); + Assert.DoesNotThrow(() => ExecuteDataFreshConsole("PREPARE")); } [Test] public void PrepareCommandIgnoreSnapshot() { - DataFreshConsole console = ExecuteDataFreshConsole("PREPARE", "-ignoresnapshot", "1"); - + Assert.DoesNotThrow(() => ExecuteDataFreshConsole("PREPARE", "-ignoresnapshot", "1")); } [Test] public void RefreshCommand() { - ExecuteDataFreshConsole("REFRESH"); + Assert.DoesNotThrow(() => ExecuteDataFreshConsole("REFRESH")); } - [Test, ExpectedException(typeof (SqlDataFreshException))] + [Test] public void RefreshWithoutPrepareCommand() { - ExecuteDataFreshConsole("REMOVE"); - ExecuteDataFreshConsole("REFRESH"); + ExecuteDataFreshConsole("REMOVE"); + Assert.Throws(() => ExecuteDataFreshConsole("REFRESH")); } [Test] public void CheckResults() { - DataFreshConsole console = ExecuteDataFreshConsole("REFRESH"); - Assert.IsTrue(console.Results.ToString().IndexOf("Entropy Zero") > -1); + var console = ExecuteDataFreshConsole("REFRESH"); + Assert.IsTrue(console.Results.IndexOf("Entropy Zero", StringComparison.Ordinal) > -1); } [Test] public void PassServerInstanceNameCheckConnectionString() { - string serverInstance = @"localhost\dev"; - DataFreshConsole console = DataFreshConsole.Execute("FOO", "test", "test", serverInstance, "DataFreshSample"); - Assert.AreEqual(5, console.arguments.Keys.Count); - Assert.AreEqual(serverInstance, console.arguments["s"]); - string expectedConnectionString = @"user id=test;password=test;Initial Catalog=DataFreshSample;Data Source=localhost\dev;"; - Assert.AreEqual(expectedConnectionString, console.connectionString); + const string serverInstance = @"localhost\dev"; + var console = DataFreshConsole.Execute("FOO", "test", "test", serverInstance, "DataFreshSample"); + Assert.AreEqual(5, console.Arguments.Keys.Count); + Assert.AreEqual(serverInstance, console.Arguments["s"]); + const string expectedConnectionString = @"user id=test;password=test;Initial Catalog=DataFreshSample;Data Source=localhost\dev;"; + Assert.AreEqual(expectedConnectionString, console.ConnectionString); } [Test] public void PassServerNameCheckConnectionString() { - string serverInstance = @"localhost"; - DataFreshConsole console = DataFreshConsole.Execute("FOO", "test", "test", serverInstance, "DataFreshSample"); - Assert.AreEqual(5, console.arguments.Keys.Count); - Assert.AreEqual(serverInstance, console.arguments["s"]); - string expectedConnectionString = @"user id=test;password=test;Initial Catalog=DataFreshSample;Data Source=localhost;"; - Assert.AreEqual(expectedConnectionString, console.connectionString); - } - + const string serverInstance = @"localhost"; + var console = DataFreshConsole.Execute("FOO", "test", "test", serverInstance, "DataFreshSample"); + Assert.AreEqual(5, console.Arguments.Keys.Count); + Assert.AreEqual(serverInstance, console.Arguments["s"]); + const string expectedConnectionString = @"user id=test;password=test;Initial Catalog=DataFreshSample;Data Source=localhost;"; + Assert.AreEqual(expectedConnectionString, console.ConnectionString); + } + [Test] public void CheckSnapshotPath() - { - //-sp "${CCNetWorkingDirectory}\Web Harmony Solution\Database\Baseline\BaselineData"" - //-sp '${CCNetWorkingDirectory}\Web Harmony Solution\Database\Baseline\BaselineData' - string snapshotPath = @"c:\temp"; - DataFreshConsole console = DataFreshConsole.Execute("FOO", "test", "test", "localhost", "DataFreshSample", "-sp", snapshotPath); - Assert.AreEqual(6, console.arguments.Keys.Count); - Assert.AreEqual(snapshotPath, console.arguments["sp"]); + { + //-sp "${CCNetWorkingDirectory}\Web Harmony Solution\Database\Baseline\BaselineData"" + //-sp '${CCNetWorkingDirectory}\Web Harmony Solution\Database\Baseline\BaselineData' + const string snapshotPath = @"c:\temp"; + var console = DataFreshConsole.Execute("FOO", "test", "test", "localhost", "DataFreshSample", "-sp", snapshotPath); + Assert.AreEqual(6, console.Arguments.Keys.Count); + Assert.AreEqual(snapshotPath, console.Arguments["sp"]); } - private static DataFreshConsole ExecuteDataFreshConsole(string command, params string[] options) + DataFreshConsole ExecuteDataFreshConsole(string command, params string[] options) { - DataFreshConsole console = DataFreshConsole.Execute(command, "test", "test", "localhost", "DataFreshSample", options); + var console = DataFreshConsole.Execute(command, userId, password, server, "DataFreshSample", options); return console; } } diff --git a/Testing.DataFresh/SqlDataFreshTester.cs b/Testing.DataFresh/SqlDataFreshTester.cs index dd1e243..1eeb6a3 100644 --- a/Testing.DataFresh/SqlDataFreshTester.cs +++ b/Testing.DataFresh/SqlDataFreshTester.cs @@ -9,109 +9,44 @@ namespace Testing.DataFresh [TestFixture] public class SqlDataFreshTester : TestFixtureBase { - [Test, ExpectedException(typeof (InvalidOperationException), "The ConnectionString property has not been initialized.")] - public void PrepDatabaseforDataFresh_NoConnectionString() - { - SqlDataFresh dataFresh = new SqlDataFresh(null); - dataFresh.PrepareDatabaseforDataFresh(); - } - [Test] - public void Encrypt() + public void PrepDatabaseForDataFresh_NoConnectionString() { -// string key = "pass@word1"; -// -// string enc = ResourceManagement.Encrypt("test", key); -// Assert.AreEqual("test", ResourceManagement.Decrypt(enc, key)); - -// ResourceManagement.Encrypt(@"C:\development\dataFresh\DataFresh\Resources\PrepareDataFresh.sql", -// @"C:\development\dataFresh\DataFresh\Resources\PrepareDataFresh.sql.enc", key); - -// byte[] dec = ResourceManagement.GetDecryptedResourceBytes("DataFresh.Resources.PrepareDataFresh.sql.enc"); -// string decStr = System.Text.Encoding.ASCII.GetString(dec); -// Console.Out.WriteLine("decStr = {0}", decStr); - -// string str = ResourceManagement.GetDecryptedResource("DataFresh.Resources.PrepareDataFresh.sql"); -// Console.Out.WriteLine("str = {0}", str); + var dataFresh = new SqlDataFresh(null); + Assert.Throws(() => dataFresh.PrepareDatabaseForDataFresh(), "The ConnectionString property has not been initialized."); } - + [Test] public void RemoveDataFresh() { - SqlDataFresh dataFresh = new SqlDataFresh(connectionString); + var dataFresh = new SqlDataFresh(connectionString); dataFresh.RemoveDataFreshFromDatabase(); - Assert.IsFalse(dataFresh.TableExists(dataFresh.ChangeTrackingTableName)); - Assert.IsFalse(dataFresh.ProcedureExists(dataFresh.ExtractProcedureName)); - Assert.IsFalse(dataFresh.ProcedureExists(dataFresh.ImportProcedureName)); - Assert.IsFalse(dataFresh.ProcedureExists(dataFresh.PrepareProcedureName)); - Assert.IsFalse(dataFresh.ProcedureExists(dataFresh.RefreshProcedureName)); - } - + Assert.IsFalse(dataFresh.TableExists(SqlDataFresh.ChangeTrackingTableName)); + } + [Test] - public void PrepDatabaseforDataFresh() + public void PrepDatabaseForDataFresh() { - SqlDataFresh dataFresh = new SqlDataFresh(connectionString); + var dataFresh = new SqlDataFresh(connectionString); dataFresh.RemoveDataFreshFromDatabase(); - Assert.IsFalse(dataFresh.TableExists(dataFresh.ChangeTrackingTableName)); - Assert.IsFalse(dataFresh.ProcedureExists(dataFresh.ExtractProcedureName)); - Assert.IsFalse(dataFresh.ProcedureExists(dataFresh.ImportProcedureName)); - Assert.IsFalse(dataFresh.ProcedureExists(dataFresh.PrepareProcedureName)); - Assert.IsFalse(dataFresh.ProcedureExists(dataFresh.RefreshProcedureName)); - - dataFresh.PrepareDatabaseforDataFresh(); - Assert.IsTrue(dataFresh.TableExists(dataFresh.ChangeTrackingTableName)); - Assert.IsTrue(dataFresh.ProcedureExists(dataFresh.ExtractProcedureName)); - Assert.IsTrue(dataFresh.ProcedureExists(dataFresh.ImportProcedureName)); - Assert.IsTrue(dataFresh.ProcedureExists(dataFresh.PrepareProcedureName)); - Assert.IsTrue(dataFresh.ProcedureExists(dataFresh.RefreshProcedureName)); - } + Assert.IsFalse(dataFresh.TableExists(SqlDataFresh.ChangeTrackingTableName)); - [Test] - public void SnapshopPath_ManualOverride() - { - SqlDataFresh dataFresh = new SqlDataFresh(connectionString); - DirectoryInfo tempPath = new DirectoryInfo(Path.GetTempPath()); - dataFresh.SnapshotPath = tempPath; - Console.Out.WriteLine("dataFresh.SnapshotPath.FullName = {0}", dataFresh.SnapshotPath.FullName); - Assert.AreEqual(tempPath.FullName, dataFresh.SnapshotPath.FullName); - } - - [Test] - public void SnapshopPath_ManualOverrideTrailingBackslash() - { - SqlDataFresh dataFresh = new SqlDataFresh(connectionString); - string tempPath = @"c:\temp\folder"; - dataFresh.SnapshotPath = new DirectoryInfo(tempPath); - Assert.AreEqual(@"c:\temp\folder\", dataFresh.SnapshotPath.FullName); - } - - [Test] - public void SnapshopPath_Resetting() - { - SqlDataFresh dataFresh = new SqlDataFresh(connectionString); - dataFresh.SnapshotPath = null; - Assert.IsTrue(dataFresh.SnapshotPath.FullName.IndexOf("Snapshot_DataFreshSample") > -1); - } - - [Test] - public void SnapshopPath() - { - SqlDataFresh dataFresh = new SqlDataFresh(connectionString); - Assert.IsTrue(dataFresh.SnapshotPath.FullName.IndexOf("Snapshot_DataFreshSample") > -1); + dataFresh.PrepareDatabaseForDataFresh(); + Assert.IsTrue(dataFresh.TableExists(SqlDataFresh.ChangeTrackingTableName)); } [Test] public void IdentityReseedDuringRefresh() { InitializeTheDatabase(); - SqlDataFresh dataFresh = new SqlDataFresh(connectionString); - dataFresh.PrepareDatabaseforDataFresh(true); - int id = Convert.ToInt32(ExecuteScalar("insert into author (lastname, firstname) values ('brockey', 'mike'); select @@identity;")); + var dataFresh = new SqlDataFresh(connectionString); + dataFresh.PrepareDatabaseForDataFresh(); + var id = Convert.ToInt32(ExecuteScalar("insert into author (lastname, firstname) values ('brockey', 'mike'); select @@identity;")); Assert.AreEqual(6, id); dataFresh.RefreshTheDatabase(); - int id2 = Convert.ToInt32(ExecuteScalar("insert into author (lastname, firstname) values ('brockey', 'mike'); select @@identity;")); + var id2 = Convert.ToInt32(ExecuteScalar("insert into author (lastname, firstname) values ('brockey', 'mike'); select @@identity;")); Assert.AreEqual(6, id2); } @@ -119,14 +54,14 @@ public void IdentityReseedDuringRefresh() public void IdentityReseedDuringRefresh_TableWithNoRows() { InitializeTheDatabase(); - SqlDataFresh dataFresh = new SqlDataFresh(connectionString); - dataFresh.PrepareDatabaseforDataFresh(true); - int id = Convert.ToInt32(ExecuteScalar("insert into movie (title) values ('mike brockey takes over the world'); select @@identity;")); + var dataFresh = new SqlDataFresh(connectionString); + dataFresh.PrepareDatabaseForDataFresh(); + var id = Convert.ToInt32(ExecuteScalar("insert into movie (title) values ('mike brockey takes over the world'); select @@identity;")); Assert.AreEqual(1, id); dataFresh.RefreshTheDatabase(); - int id2 = Convert.ToInt32(ExecuteScalar("insert into movie (title) values ('mike brockey takes over the world'); select @@identity;")); + var id2 = Convert.ToInt32(ExecuteScalar("insert into movie (title) values ('mike brockey takes over the world'); select @@identity;")); Assert.AreEqual(1, id2); - int id3 = Convert.ToInt32(ExecuteScalar("insert into movie (title) values ('mike brockey takes over the world 2'); select @@identity;")); + var id3 = Convert.ToInt32(ExecuteScalar("insert into movie (title) values ('mike brockey takes over the world 2'); select @@identity;")); Assert.AreEqual(2, id3); } @@ -134,30 +69,30 @@ public void IdentityReseedDuringRefresh_TableWithNoRows() public void IdentityReseedDuringRefresh_TableWithNoRows2() { InitializeTheDatabase(); - SqlDataFresh dataFresh = new SqlDataFresh(connectionString); + var dataFresh = new SqlDataFresh(connectionString); dataFresh.RemoveDataFreshFromDatabase(); - dataFresh.PrepareDatabaseforDataFresh(true); + dataFresh.PrepareDatabaseForDataFresh(); ExecuteNonQuery("insert into movie2 (movieid, title) values (1, 'mike brockey takes over the world');"); - dataFresh.RefreshTheDatabase(); - } - + Assert.DoesNotThrow(() => dataFresh.RefreshTheDatabase()); + } + [Test] public void IdentityReseedWorksWithTablesThatUseReservedWords() { InitializeTheDatabase(); - SqlDataFresh dataFresh = new SqlDataFresh(connectionString); + var dataFresh = new SqlDataFresh(connectionString); dataFresh.RemoveDataFreshFromDatabase(); - dataFresh.PrepareDatabaseforDataFresh(true); + dataFresh.PrepareDatabaseForDataFresh(); ExecuteNonQuery("insert into [check] (title) values ('mike brockey takes over the world');"); - dataFresh.RefreshTheDatabase(); - } - + Assert.DoesNotThrow(() => dataFresh.RefreshTheDatabase()); + } + [Test] public void RefreshTheDatabaseSpeedTests() { - SqlDataFresh dataFresh = new SqlDataFresh(connectionString, true); + var dataFresh = new SqlDataFresh(connectionString, true); dataFresh.RemoveDataFreshFromDatabase(); - dataFresh.PrepareDatabaseforDataFresh(true); + dataFresh.PrepareDatabaseForDataFresh(); ExecuteNonQuery("insert into author (lastname, firstname) values ('brockey', 'mike');"); dataFresh.RefreshTheDatabase(); ExecuteNonQuery("insert into author (lastname, firstname) values ('brockey', 'mike');"); @@ -297,28 +232,29 @@ public void RefreshTheDatabaseSpeedTests() ExecuteNonQuery("insert into author (lastname, firstname) values ('brockey', 'mike');"); dataFresh.RefreshTheDatabase(); ExecuteNonQuery("insert into author (lastname, firstname) values ('brockey', 'mike');"); - dataFresh.RefreshTheDatabase(); + Assert.DoesNotThrow(() => dataFresh.RefreshTheDatabase()); } [Test] public void ShouldNotRefreshDeltaRunnerTable() { InitializeTheDatabase(); - SqlDataFresh dataFresh = new SqlDataFresh(connectionString); + var dataFresh = new SqlDataFresh(connectionString); dataFresh.RemoveDataFreshFromDatabase(); - dataFresh.PrepareDatabaseforDataFresh(true); + dataFresh.PrepareDatabaseForDataFresh(); ExecuteNonQuery("insert into [dr_deltaversion] ([latestdelta], [hash], [filename]) values (99, 'blah-hash', 'whatever file');"); Assert.AreEqual(1, ExecuteScalar("select count(*) from [dr_deltaversion] where [filename] = 'whatever file'")); dataFresh.RefreshTheDatabase(); Assert.AreEqual(1, ExecuteScalar("select count(*) from [dr_deltaversion] where [filename] = 'whatever file'")); } - private void InitializeTheDatabase() - { - SqlDeltaRunner deltaRunner = new SqlDeltaRunner(connectionString, new DirectoryInfo(deltaPath).FullName, true); + void InitializeTheDatabase() + { + var binDir = Path.GetDirectoryName(GetType().Assembly.Location) ?? string.Empty; + var deltaRunner = new SqlDeltaRunner(connectionString, Path.Combine(binDir, deltaPath), true); deltaRunner.PrepareForDeltaRunner(); - deltaRunner.AddSqlFile(new FileInfo(Path.Combine(databaseFilesPath, "Database.sql")),SqlFileExecutionOption.ExecuteBeforeDeltas); - deltaRunner.AddSqlFile(new FileInfo(Path.Combine(databaseFilesPath, "Setup.sql")),SqlFileExecutionOption.ExecuteAfterDeltas); + deltaRunner.AddSqlFile(new FileInfo(Path.Combine(binDir, databaseFilesPath, "Database.sql")), SqlFileExecutionOption.ExecuteBeforeDeltas); + deltaRunner.AddSqlFile(new FileInfo(Path.Combine(binDir, databaseFilesPath, "Setup.sql")), SqlFileExecutionOption.ExecuteAfterDeltas); deltaRunner.ApplyDeltas(); } } diff --git a/Testing.DataFresh/TestFixtureBase.cs b/Testing.DataFresh/TestFixtureBase.cs index 8d4d218..10fb675 100644 --- a/Testing.DataFresh/TestFixtureBase.cs +++ b/Testing.DataFresh/TestFixtureBase.cs @@ -7,36 +7,54 @@ namespace Testing.DataFresh { public class TestFixtureBase { - public static string connectionString = "user id=test;password=test;Initial Catalog=DataFreshSample;Data Source=(local);pooling=false;"; - public static string connectionStringMaster = "user id=test;password=test;Initial Catalog=Master;Data Source=(local);pooling=false;"; - public static string databaseFilesPath = @"..\..\Database Files\"; - public static string deltaPath = @"..\..\Database Files\Deltas"; - + public readonly string connectionString; + public readonly string connectionStringMaster; + public static string databaseFilesPath = @"..\..\Database Files"; + public static string deltaPath = @"..\..\Database Files\Deltas"; + + public TestFixtureBase() + { + var doc = new System.Xml.XmlDocument(); + doc.Load(Path.Combine(Path.GetDirectoryName(GetType().Assembly.Location) ?? string.Empty, @"..\..\..\TestConnectionStrings.xml")); + connectionString = connectionString = + string.Format(doc.SelectSingleNode("/connectionStrings/sqlDataFreshSampleConnectionStringTemplate")?.InnerText ?? string.Empty, + doc.SelectSingleNode("/connectionStrings/properties/userId")?.InnerText, + doc.SelectSingleNode("/connectionStrings/properties/password")?.InnerText, + doc.SelectSingleNode("/connectionStrings/properties/server")?.InnerText, + doc.SelectSingleNode("/connectionStrings/properties/pooling")?.InnerText); + connectionStringMaster = + string.Format(doc.SelectSingleNode("/connectionStrings/sqlMasterDatabaseConnectionStringTemplate")?.InnerText ?? string.Empty, + doc.SelectSingleNode("/connectionStrings/properties/userId")?.InnerText, + doc.SelectSingleNode("/connectionStrings/properties/password")?.InnerText, + doc.SelectSingleNode("/connectionStrings/properties/server")?.InnerText, + doc.SelectSingleNode("/connectionStrings/properties/pooling")?.InnerText); + } + [SetUp] public void SetUp() { SqlDeltaRunner.CreateDatabase("DataFreshSample", connectionStringMaster, true); DeltaRunnerInstance.ApplyDeltas(); - } - + } + public SqlDeltaRunner DeltaRunnerInstance { get - { - SqlDeltaRunner deltaRunner = new SqlDeltaRunner(connectionString, deltaPath, true); + { + var binDir = Path.GetDirectoryName(GetType().Assembly.Location) ?? string.Empty; + var deltaRunner = new SqlDeltaRunner(connectionString, Path.Combine(binDir, deltaPath), true); deltaRunner.PrepareForDeltaRunner(); - deltaRunner.AddSqlFile(new FileInfo(Path.Combine(databaseFilesPath, "database.sql")),SqlFileExecutionOption.ExecuteBeforeDeltas); - deltaRunner.AddSqlFile(new FileInfo(Path.Combine(databaseFilesPath, "setup.sql")),SqlFileExecutionOption.ExecuteAfterDeltas); + deltaRunner.AddSqlFile(new FileInfo(Path.Combine(binDir, databaseFilesPath, "database.sql")), SqlFileExecutionOption.ExecuteBeforeDeltas); + deltaRunner.AddSqlFile(new FileInfo(Path.Combine(binDir, databaseFilesPath, "setup.sql")), SqlFileExecutionOption.ExecuteAfterDeltas); return deltaRunner; } - } - + } + public void ExecuteNonQuery(string sql) { - using (SqlConnection conn = new SqlConnection(connectionString)) + using (var conn = new SqlConnection(connectionString)) { - SqlCommand cmd = new SqlCommand(sql, conn); - cmd.CommandTimeout = 1200; + var cmd = new SqlCommand(sql, conn) { CommandTimeout = 1200 }; conn.Open(); cmd.ExecuteNonQuery(); } @@ -44,10 +62,9 @@ public void ExecuteNonQuery(string sql) public object ExecuteScalar(string sql) { - using (SqlConnection conn = new SqlConnection(connectionString)) + using (var conn = new SqlConnection(connectionString)) { - SqlCommand cmd = new SqlCommand(sql, conn); - cmd.CommandTimeout = 1200; + var cmd = new SqlCommand(sql, conn) { CommandTimeout = 1200 }; conn.Open(); return cmd.ExecuteScalar(); } diff --git a/Testing.DataFresh/Testing.DataFresh.csproj b/Testing.DataFresh/Testing.DataFresh.csproj index c344754..b76389b 100644 --- a/Testing.DataFresh/Testing.DataFresh.csproj +++ b/Testing.DataFresh/Testing.DataFresh.csproj @@ -1,132 +1,128 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + Local + 7.10.6030 + 2.0 + {3E910EED-904F-4A52-A611-9278B682EFD3} + Debug + AnyCPU + + + Testing.DataFresh + + JScript + Grid + IE50 + false + Library + Testing.DataFresh + OnBuildSuccess + + + + v4.7.2 + + + 0.0 + + + + + + bin\Debug\ + false + 285212672 + false + + DEBUG;TRACE + + true + 4096 + false + + false + false + false + false + 4 + full + prompt + false + + + bin\Release\ + false + 285212672 + false + + TRACE + + true + 4096 + false + + true + false + false + false + 4 + full + prompt + false + + + + DataFresh + {05438358-2120-4D97-974E-ACF80F7EA6F7} + {FAE04EC0-301F-11D3-BF4B-00C04F79EFBC} + + + deltaRunner + ..\DataFresh.Common\Assemblies\deltaRunner.dll + + + ..\packages\NUnit.3.11.0\lib\net45\nunit.framework.dll + + + System + + + System.Data + + + System.XML + + + + + Code + + + Code + + + Code + + + + + + + + + + + + + + + + This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}. + + + + + \ No newline at end of file diff --git a/Testing.DataFresh/packages.config b/Testing.DataFresh/packages.config new file mode 100644 index 0000000..247616d --- /dev/null +++ b/Testing.DataFresh/packages.config @@ -0,0 +1,5 @@ + + + + + \ No newline at end of file