private int PrepBuildAndScripts(string buildZipFileName, string buildRequestedBy, bool forceCustomDacpac)
        {
            ThreadedExecution.buildZipFileName = buildZipFileName;
            this.buildRequestedBy = buildRequestedBy;

            //Looks like we're good to go... extract the build Zip file (.sbm) into a working folder...

            if (!forceCustomDacpac)
            {
                ExtractAndLoadBuildFile(ThreadedExecution.buildZipFileName, out ThreadedExecution.buildData);
                if (buildData == null)
                {
                    var msg = new LogMsg()
                    {
                        Message = "Unable to procees. SqlSyncBuild data object is null, Returning error code: " + (int)ExecutionReturn.NullBuildData,
                        LogType = LogType.Error
                    };
                    WriteToLog(msg);
                    return((int)ExecutionReturn.NullBuildData);
                }
                else
                {
                    //Load up the batched scripts into a shared object so that we can conserve memory
                    ThreadedExecution.batchColl = SqlBuildHelper.LoadAndBatchSqlScripts(ThreadedExecution.buildData, this.projectFilePath);
                }
            }
            return(0);
        }
        public SqlBuildHelper CreateSqlBuildHelperAccessor(SqlSyncBuildData buildData)
        {
            SqlBuildHelper target = new SqlBuildHelper(this.connData);


            //Set fields
            BackgroundWorker bg = new BackgroundWorker();

            bg.WorkerReportsProgress      = true;
            bg.WorkerSupportsCancellation = true;
            target.bgWorker = bg;

            target.buildData = buildData;

            string logFile = this.GetTrulyUniqueFile();

            this.tempFiles.Add(logFile);
            target.scriptLogFileName = logFile;

            SqlSyncBuildData buildHist = CreateSqlSyncSqlBuildDataObject();

            target.buildHistoryData = buildHist;

            this.projectFileName = this.GetTrulyUniqueFile();
            this.tempFiles.Add(projectFileName);
            target.projectFileName = projectFileName;

            this.buildHistoryXmlFile = this.GetTrulyUniqueFile();
            this.tempFiles.Add(buildHistoryXmlFile);
            target.buildHistoryXmlFile = buildHistoryXmlFile;

            return(target);
        }
        public SqlBuildHelper SetSqlBuildHelperValues(SqlBuildHelper sbh, SqlSyncBuildData buildData)
        {
            BackgroundWorker bg = new BackgroundWorker();

            bg.WorkerReportsProgress      = true;
            bg.WorkerSupportsCancellation = true;
            sbh.bgWorker = bg;

            sbh.buildData = buildData;

            string logFile = this.GetTrulyUniqueFile();

            sbh.scriptLogFileName = logFile;

            SqlSyncBuildData buildHist = CreateSqlSyncSqlBuildDataObject();

            sbh.buildHistoryData = buildHist;

            this.projectFileName = this.GetTrulyUniqueFile();
            sbh.projectFileName  = projectFileName;

            this.buildHistoryXmlFile = this.GetTrulyUniqueFile();
            sbh.buildHistoryXmlFile  = buildHistoryXmlFile;
            return(sbh);
        }
        public void CalculateBuildPackageSHA1_CompareMethodologyTest()
        {
            //Set up directory and files...
            string projectFileExtractionPath = Path.GetTempPath() + Guid.NewGuid().ToString() + "\\";

            if (!Directory.Exists(projectFileExtractionPath))
            {
                Directory.CreateDirectory(projectFileExtractionPath);
            }

            string file1 = "File1.sql";

            File.WriteAllText(projectFileExtractionPath + file1, Properties.Resources.CreateDatabaseScript);

            string file2 = "File2.sql";

            File.WriteAllText(projectFileExtractionPath + file2, Properties.Resources.CreateTestTablesScript);

            string file3 = "File3.sql";

            File.WriteAllText(projectFileExtractionPath + file3, Properties.Resources.LoggingTable);


            SqlSyncBuildData buildData = SqlBuildFileHelper.CreateShellSqlSyncBuildDataObject();

            SqlSyncBuildData.ScriptRow row1 = buildData.Script.NewScriptRow();
            row1.BuildOrder           = 1;
            row1.FileName             = file1;
            row1.StripTransactionText = true;

            SqlSyncBuildData.ScriptRow row2 = buildData.Script.NewScriptRow();
            row2.BuildOrder           = 2;
            row2.FileName             = file2;
            row2.StripTransactionText = true;

            SqlSyncBuildData.ScriptRow row3 = buildData.Script.NewScriptRow();
            row3.BuildOrder           = 3;
            row3.FileName             = file3;
            row3.StripTransactionText = true;

            buildData.Script.Rows.Add(row1);
            buildData.Script.Rows.Add(row2);
            buildData.Script.Rows.Add(row3);


            string fromPath = SqlBuildFileHelper.CalculateBuildPackageSHA1SignatureFromPath(projectFileExtractionPath, buildData);


            ScriptBatchCollection batch = SqlBuildHelper.LoadAndBatchSqlScripts(buildData, projectFileExtractionPath);
            string fromBatch            = SqlBuildFileHelper.CalculateBuildPackageSHA1SignatureFromBatchCollection(batch);

            if (Directory.Exists(projectFileExtractionPath))
            {
                Directory.Delete(projectFileExtractionPath, true);
            }

            Assert.AreEqual(fromPath, fromBatch);
        }
        public PagingDataSource <T> GetPagingDataSource <T>(string withSql, OrderPagingQuery <T> query,
                                                            string tableName = "TResult") where T : class
        {
            string    pageSql   = SqlBuildHelper.BuildPageSql(withSql, query, tableName);
            string    countSql  = SqlBuildHelper.BuildCountSql(withSql, tableName);
            IList <T> pagedList = Database.SqlQuery <T>(pageSql).ToList();
            int       count     = Database.SqlQuery <int>(countSql).FirstOrDefault();
            var       result    = new PagingDataSource <T>(pagedList, query, count);

            return(result);
        }
Example #6
0
        internal static List <string> BatchAndSaveScripts(string masterScript, string workingPath)
        {
            string tmp;
            string fileName;
            Regex  regNewLine    = new Regex("\r\n", RegexOptions.Compiled);
            Regex  regDupeSpaces = new Regex(" {2,}", RegexOptions.Compiled);
            var    invalidChars  = Path.GetInvalidFileNameChars();
            int    counter       = 0;


            List <string> files = new List <string>();

            log.LogInformation("Parsing our master update script into batch scripts");
            var batched = SqlBuildHelper.ReadBatchFromScriptText(masterScript, true, false);

            foreach (var script in batched)
            {
                if (script.Trim().Length == 0)
                {
                    continue;
                }
                counter++;

                //Clean up to make a "nicer" file name
                tmp = regNewLine.Replace(script, " ", 1);
                tmp = new string(tmp.Where(x => !invalidChars.Contains(x)).ToArray()).Replace(";", "").Replace("SET XACT_ABORT ON", "").Trim();
                tmp = counter.ToString().PadLeft(4, '0') + "_" + ((tmp.Length > 50) ? tmp.Substring(0, 50) : tmp);
                if (tmp.IndexOf('(') > -1)
                {
                    tmp = tmp.Substring(0, tmp.IndexOf('('));
                }
                while (tmp.EndsWith('.') || tmp.EndsWith('\''))
                {
                    tmp = tmp.Substring(0, tmp.Length - 1);
                }
                tmp = regDupeSpaces.Replace(tmp, " ");

                fileName = Path.Combine(workingPath, tmp.Trim() + ".sql");
                File.WriteAllText(fileName, script);

                files.Add(fileName);
            }
            return(files);
        }
 public static void ValidateReviewCheckSum(SqlSyncBuildData sqlSyncBuildData, string baseDirectory)
 {
     foreach (SqlSyncBuildData.ScriptRow scriptRow in sqlSyncBuildData.Script)
     {
         var codeReview = from cr in sqlSyncBuildData.CodeReview
                          where cr.ScriptId == scriptRow.ScriptId
                          select cr;
         if (codeReview.Any())
         {
             string[] batch      = SqlBuildHelper.ReadBatchFromScriptFile(baseDirectory + scriptRow.FileName, false, true);
             string   scriptText = String.Join("", batch);
             foreach (var crRow in codeReview)
             {
                 if (!ValidateReviewCheckSum(crRow, scriptText))
                 {
                     crRow.ReviewStatus = (short)CodeReviewStatus.OutOfDate;
                 }
             }
         }
     }
     sqlSyncBuildData.AcceptChanges();
 }
Example #8
0
        public void ProcessBuildTest_RollbackWithThreeRetries()
        {
            Initialization init = GetInitializationObject();

            init.TableLockingLoopCount = 10000000;
            SqlSyncBuildData buildData = init.CreateSqlSyncSqlBuildDataObject();

            init.AddScriptForProcessBuild(ref buildData, true, 1);

            SqlBuildHelper  target  = init.CreateSqlBuildHelper(buildData);
            SqlBuildRunData runData = init.GetSqlBuildRunData_TransactionalNotTrial(buildData);

            BackgroundWorker      bgWorker        = init.GetBackgroundWorker();
            DoWorkEventArgs       e               = new DoWorkEventArgs(null);
            string                serverName      = init.serverName;
            bool                  isMultiDbRun    = false;
            ScriptBatchCollection scriptBatchColl = init.GetScriptBatchCollectionForProcessBuild();
            int allowableTimeoutRetries           = 3;

            Thread THRInfinite = null;

            try
            {
                THRInfinite = new Thread(new ParameterizedThreadStart(StartInfiniteLockingThread));
                THRInfinite.Start(init);

                string expected = BuildItemStatus.RolledBackAfterRetries;
                SqlSyncBuildData.BuildRow actual;
                actual = target.ProcessBuild(runData, bgWorker, e, serverName, isMultiDbRun, scriptBatchColl, allowableTimeoutRetries);
                Assert.AreEqual(expected, actual.FinalStatus);
            }
            finally
            {
                if (THRInfinite != null)
                {
                    THRInfinite.Interrupt();
                }
            }
        }
Example #9
0
        public void ProcessBuildTest_CommitWithRetriesNotUsed()
        {
            Initialization   init      = GetInitializationObject();
            SqlSyncBuildData buildData = init.CreateSqlSyncSqlBuildDataObject();

            init.AddScriptForProcessBuild(ref buildData, true, 20);

            SqlBuildHelper        target          = init.CreateSqlBuildHelper(buildData);
            SqlBuildRunData       runData         = init.GetSqlBuildRunData_TransactionalNotTrial(buildData);
            BackgroundWorker      bgWorker        = init.GetBackgroundWorker();
            DoWorkEventArgs       e               = new DoWorkEventArgs(null);
            string                serverName      = init.serverName;
            bool                  isMultiDbRun    = false;
            ScriptBatchCollection scriptBatchColl = init.GetScriptBatchCollectionForProcessBuild();
            int allowableTimeoutRetries           = 3;

            string expected = BuildItemStatus.Committed;

            SqlSyncBuildData.BuildRow actual;
            actual = target.ProcessBuild(runData, bgWorker, e, serverName, isMultiDbRun, scriptBatchColl, allowableTimeoutRetries);
            Assert.AreEqual(expected, actual.FinalStatus);
        }
        public void CalculateScriptSHA1_CompareResults()
        {
            string script = @"/* 
Source Server:	localhost\sqlexpress
Source Db:	SqlBuildTest_SyncTest1
Process Date:	7/21/2014 1:36:55 PM
Object Scripted:dbo.SyncTestTable
Object Type:	Table
Scripted By:	mmckechn
Include Permissions: True
Script as ALTER: True
Script PK with Table:False
*/
SET ANSI_NULLS ON
GO


SET QUOTED_IDENTIFIER ON
GO


IF NOT EXISTS (SELECT * FROM sys.objects WHERE object_id = OBJECT_ID(N'[dbo].[SyncTestTable]') AND type in (N'U'))
BEGIN
CREATE TABLE [dbo].[SyncTestTable](
	[ColumnTable1] [varchar](50) COLLATE SQL_Latin1_General_CP1_CI_AS NULL,
	[ColumnTable2] [varchar](50) COLLATE SQL_Latin1_General_CP1_CI_AS NULL
) ON [PRIMARY]
END
";

            string[] arrScripts = SqlBuildHelper.ReadBatchFromScriptText(script, true, false).ToArray();
            string   hashFromArray;

            SqlBuildFileHelper.GetSHA1Hash(arrScripts, out hashFromArray);
            string hashFromString = SqlBuildFileHelper.GetSHA1Hash(script.ClearTrailingCarriageReturn());

            Assert.AreEqual(hashFromString, hashFromArray);
        }
        public void CalculateBuildPackageSHA1_CompareMethodologyTest_OrderCheckingWithTransactionsToRemove()
        {
            //Set up directory and files...
            string projectFileExtractionPath = Path.GetTempPath() + Guid.NewGuid().ToString() + "\\";

            if (!Directory.Exists(projectFileExtractionPath))
            {
                Directory.CreateDirectory(projectFileExtractionPath);
            }

            string file1 = "File1.sql";

            File.WriteAllText(projectFileExtractionPath + file1, @"This is My script
with my 
COMMIT TRANS
test");

            string file2 = "File2.sql";

            File.WriteAllText(projectFileExtractionPath + file2, Properties.Resources.CreateTestTablesScript);

            string file3 = "File3.sql";

            File.WriteAllText(projectFileExtractionPath + file3, @"This is another test that has
--ROLLBACK TRANSACTION
where the 
BEGIN TRAN
needs to be removed");


            SqlSyncBuildData buildData = SqlBuildFileHelper.CreateShellSqlSyncBuildDataObject();

            SqlSyncBuildData.ScriptRow row1 = buildData.Script.NewScriptRow();
            row1.BuildOrder           = 1;
            row1.FileName             = file1;
            row1.StripTransactionText = true;

            SqlSyncBuildData.ScriptRow row2 = buildData.Script.NewScriptRow();
            row2.BuildOrder           = 2;
            row2.FileName             = file2;
            row2.StripTransactionText = true;

            SqlSyncBuildData.ScriptRow row3 = buildData.Script.NewScriptRow();
            row3.BuildOrder           = 3;
            row3.FileName             = file3;
            row3.StripTransactionText = true;

            buildData.Script.Rows.Add(row1);
            buildData.Script.Rows.Add(row2);
            buildData.Script.Rows.Add(row3);


            string fromPath123 = SqlBuildFileHelper.CalculateBuildPackageSHA1SignatureFromPath(projectFileExtractionPath, buildData);

            ScriptBatchCollection batch = SqlBuildHelper.LoadAndBatchSqlScripts(buildData, projectFileExtractionPath);
            string fromBatch123         = SqlBuildFileHelper.CalculateBuildPackageSHA1SignatureFromBatchCollection(batch);

            buildData.Script[0].BuildOrder = 2;
            buildData.Script[1].BuildOrder = 1;
            buildData.Script[2].BuildOrder = 3;
            buildData.AcceptChanges();

            string fromPath213 = SqlBuildFileHelper.CalculateBuildPackageSHA1SignatureFromPath(projectFileExtractionPath, buildData);

            batch = SqlBuildHelper.LoadAndBatchSqlScripts(buildData, projectFileExtractionPath);
            string fromBatch213 = SqlBuildFileHelper.CalculateBuildPackageSHA1SignatureFromBatchCollection(batch);


            if (Directory.Exists(projectFileExtractionPath))
            {
                Directory.Delete(projectFileExtractionPath, true);
            }

            Assert.AreEqual(fromPath123, fromBatch123);
            Assert.AreEqual(fromPath213, fromBatch213);
            Assert.AreNotEqual(fromPath123, fromBatch213);
            Assert.AreNotEqual(fromPath213, fromBatch123);
        }
        public SqlSyncBuildData.BuildRow GetRunBuildRow(SqlBuildHelper sqlBuildHelper)
        {
            SqlSyncBuildData histData = sqlBuildHelper.buildHistoryData;

            return(histData.Build.NewBuildRow());
        }
        public SqlBuildHelper CreateSqlBuildHelper_Basic()
        {
            SqlBuildHelper helper = new SqlBuildHelper(this.connData);

            return(SetSqlBuildHelperValues(helper, null));
        }
        public SqlBuildHelper CreateSqlBuildHelper_NonTransactional(SqlSyncBuildData buildData, bool withScriptLog)
        {
            SqlBuildHelper helper = new SqlBuildHelper(this.connData, withScriptLog, string.Empty, false);

            return(SetSqlBuildHelperValues(helper, buildData));
        }
        public SqlBuildHelper CreateSqlBuildHelper(SqlSyncBuildData buildData)
        {
            SqlBuildHelper helper = new SqlBuildHelper(this.connData);

            return(SetSqlBuildHelperValues(helper, buildData));
        }
Example #16
0
        private bool ProcessSyncronizationPackages(IEnumerable <string> sbmPackages, ConnectionData toUpdate, bool runAsTrial, bool continueOnFailure)
        {
            log.LogInformation($"Starting synchronization of {toUpdate.DatabaseName} with {sbmPackages.Count()} packages...");

            string projFileName     = string.Empty;
            string projectFilePath  = string.Empty;
            string workingDirectory = string.Empty;
            string result           = string.Empty;

            foreach (var sbmPackageName in sbmPackages)
            {
                log.LogInformation($"Synchronization run for {Path.GetFileName(sbmPackageName)}");
                //Unzip and read the package
                SqlSyncBuildData buildData;
                if (!SqlBuildFileHelper.ExtractSqlBuildZipFile(sbmPackageName, ref workingDirectory, ref projectFilePath,
                                                               ref projFileName,
                                                               out result))
                {
                    PushInfo(string.Format("Unable to extract build file {0}. See log for details", sbmPackageName));
                    return(false);
                }

                if (!SqlBuildFileHelper.LoadSqlBuildProjectFile(out buildData, projFileName, false))
                {
                    PushInfo(string.Format("Unable to load build file {0}. See log for details", sbmPackageName));
                    return(false);
                }

                //set the build data for a new run
                foreach (SqlSyncBuildData.ScriptRow scriptRow in buildData.Script)
                {
                    scriptRow.Database          = "placeholder";
                    scriptRow.AllowMultipleRuns = true;
                }

                List <DatabaseOverride> lstOverride = new List <DatabaseOverride>();
                lstOverride.Add(new DatabaseOverride()
                {
                    DefaultDbTarget  = "placeholder",
                    OverrideDbTarget = toUpdate.DatabaseName,
                });

                //Set the run meta-data
                SqlSync.SqlBuild.SqlBuildRunData runData = new SqlBuildRunData()
                {
                    BuildData        = buildData,
                    BuildType        = BuildType.Other,
                    BuildDescription = new Random().Next(int.MinValue, int.MaxValue).ToString(),
                    //assign random build description
                    StartIndex              = -1000, //make sure start a the beginning
                    ProjectFileName         = projFileName,
                    IsTrial                 = runAsTrial,
                    BuildFileName           = sbmPackageName,
                    IsTransactional         = true,
                    TargetDatabaseOverrides = lstOverride
                };

                //Execute the package
                SqlBuildHelper helper = new SqlBuildHelper(toUpdate, false, string.Empty, runData.IsTransactional);
                helper.BuildCommittedEvent     += new BuildCommittedEventHandler(helper_BuildCommittedEvent);
                helper.BuildErrorRollBackEvent += new EventHandler(helper_BuildErrorRollBackEvent);
                BackgroundWorker bg = new BackgroundWorker()
                {
                    WorkerReportsProgress      = true,
                    WorkerSupportsCancellation = true
                };
                DoWorkEventArgs e = new DoWorkEventArgs(null);

                PushInfo(string.Format("Applying {0}", Path.GetFileName(sbmPackageName)));
                helper.ProcessBuild(runData, 0, bg, e);

                if (lastBuildSuccessful)
                {
                    string message = string.Format("Successfully applied {0}", Path.GetFileName(sbmPackageName));
                    PushInfo(message);
                    log.LogInformation(message);
                }
                else
                {
                    string message = string.Format("Failed to apply {0}", Path.GetFileName(sbmPackageName));
                    PushInfo(message);
                    log.LogInformation(message);
                    if (!continueOnFailure)
                    {
                        PushInfo("Cancelling sync.");
                        return(false);
                    }
                    else
                    {
                        PushInfo("Continue On Failure set. Continuing sync process...");
                    }
                }
            }
            return(true);
        }
        public static ScriptStatusType DetermineScriptRunStatus(SqlSyncBuildData.ScriptRow row, ConnectionData connData, string projectFilePath, bool checkForChanges, List <DatabaseOverride> overrides, out DateTime commitDate, out DateTime serverChangeDate)
        {
            string targetDatabase = ConnectionHelper.GetTargetDatabase(row.Database, overrides);

            //Update the routine (sp and functions) change date cache
            if (DatabaseObjectChangeDates.Servers[connData.SQLServerName][targetDatabase].LastRefreshTime < DateTime.Now.AddSeconds(-30))
            {
                //InfoHelper.DatabaseRoutineChangeDates = InfoHelper.GetRoutineChangeDates(connData, this.targetDatabaseOverrideCtrl1.GetOverrideData());
                InfoHelper.UpdateRoutineAndViewChangeDates(connData, overrides);
            }
            bool preRun      = false;
            bool hashChanged = false;
            //Determine icon
            string scriptHash     = string.Empty;
            string scriptTextHash = string.Empty;

            commitDate       = DateTime.MinValue;
            serverChangeDate = DateTime.MinValue;
            // preRun = (committedScriptView.Find(row.ScriptId) > -1 || helper.HasBlockingSqlLog(new Guid(row.ScriptId), this.data, targetDatabase, out scriptHash, out scriptTextHash) == true);
            preRun = (SqlBuildHelper.HasBlockingSqlLog(new Guid(row.ScriptId), connData, targetDatabase, out scriptHash, out scriptTextHash, out commitDate) == true);
            //Check that the file exists
            if (!File.Exists(Path.Combine(projectFilePath, row.FileName)))
            {
                return(ScriptStatusType.FileMissing);
            }

            //Get the latest hash from the Db only (don't care if the build file is out of date!)
            if (preRun && checkForChanges)
            {
                if (scriptHash == string.Empty || scriptTextHash == string.Empty)
                {
                    SqlBuildHelper.HasBlockingSqlLog(new Guid(row.ScriptId), connData, targetDatabase, out scriptHash, out scriptTextHash, out commitDate);
                }

                /*If the scriptHash is STILL empty, then the file and the Db are out of sync.
                 *	This could be due to a Db refresh, in which case we'll mark it as changed
                 *	by default
                 */
                if (scriptHash != string.Empty || scriptTextHash != string.Empty)
                {
                    string fileTextHash;
                    string fileHash;
                    SqlBuildFileHelper.GetSHA1Hash(Path.Combine(projectFilePath, row.FileName), out fileHash, out fileTextHash, row.StripTransactionText);
                    if (fileHash != scriptHash && fileTextHash != scriptHash && fileHash != scriptTextHash && fileTextHash != scriptTextHash)
                    {
                        if (fileHash == SqlBuildFileHelper.FileMissing)
                        {
                            return(ScriptStatusType.FileMissing);
                        }
                        hashChanged = true;
                    }
                }
                else
                {
                    hashChanged = true;
                }
            }
            string routineName = row.FileName.Substring(0, row.FileName.Length - 4).ToLower();

            if (row.FileName.EndsWith(DbObjectType.Trigger, StringComparison.CurrentCultureIgnoreCase) && routineName.IndexOf(" - ") > -1)
            {
                routineName = routineName.Split(new char[] { '-' })[1].Trim();
            }

            if (!preRun) //not run at all
            {
                commitDate = (row.IsDateModifiedNull() || row.DateModified < new DateTime(1980, 1, 1)) ? row.DateAdded : row.DateModified;

                if (row.FileName.EndsWith(DbObjectType.StoredProcedure, StringComparison.CurrentCultureIgnoreCase) ||
                    row.FileName.EndsWith(DbObjectType.UserDefinedFunction, StringComparison.CurrentCultureIgnoreCase) ||
                    row.FileName.EndsWith(DbObjectType.View, StringComparison.CurrentCultureIgnoreCase) ||
                    row.FileName.EndsWith(DbObjectType.Table, StringComparison.CurrentCultureIgnoreCase) ||
                    row.FileName.EndsWith(DbObjectType.Trigger, StringComparison.CurrentCultureIgnoreCase))
                {
                    serverChangeDate = DatabaseObjectChangeDates.Servers[connData.SQLServerName][targetDatabase][routineName];

                    if (commitDate < serverChangeDate)
                    {
                        return(ScriptStatusType.NotRunButOlderVersion); // question mark
                    }
                }

                return(ScriptStatusType.NotRun);
            }
            else
            {
                if (row.AllowMultipleRuns == false) //(committedScriptView.Find(row.ScriptId) > -1 || helper.HasBlockingSqlLog(new Guid(row.ScriptId),this.data,row.Database) == true))
                {
                    if (!hashChanged)
                    {
                        return(ScriptStatusType.Locked); // "locked"
                    }
                    else
                    {
                        return(ScriptStatusType.ChangedSinceCommit); //the caution icon!
                    }
                }
                else
                {
                    if (!hashChanged) //if "OK" from a SBM status, need to check the DB next for SP's and Functions
                    {
                        if (row.FileName.EndsWith(DbObjectType.StoredProcedure, StringComparison.CurrentCultureIgnoreCase) ||
                            row.FileName.EndsWith(DbObjectType.UserDefinedFunction, StringComparison.CurrentCultureIgnoreCase) ||
                            row.FileName.EndsWith(DbObjectType.View, StringComparison.CurrentCultureIgnoreCase) ||
                            row.FileName.EndsWith(DbObjectType.Table, StringComparison.CurrentCultureIgnoreCase) ||
                            row.FileName.EndsWith(DbObjectType.Trigger, StringComparison.CurrentCultureIgnoreCase))
                        {
                            serverChangeDate = DatabaseObjectChangeDates.Servers[connData.SQLServerName][targetDatabase][routineName];

                            //Add in 5 second threshold
                            if (commitDate.Ticks + 50000000 < serverChangeDate.Ticks)
                            {
                                return(ScriptStatusType.ServerChange); // magnifying glass
                            }
                            //if the serverChangeDate here is MinValue, it means that the routine is not in this DB, therefore, we need to set as not run.
                            if (serverChangeDate == DateTime.MinValue)
                            {
                                return(ScriptStatusType.NotRun); //"gray server icon"
                            }
                        }
                        return(ScriptStatusType.UpToDate); //green "OK"
                    }
                    else
                    {
                        return(ScriptStatusType.ChangedSinceCommit); //the caution icon!
                    }
                }
            }
        }
Example #18
0
        /// <summary>
        /// Performs the database scripts execution against the specified server/ database settings
        /// </summary>
        /// <param name="serverName">Name of the SQL server to target</param>
        /// <param name="overrides">List of database override settings to use in execution</param>
        /// <returns></returns>
        internal async Task <int> RunDatabaseBuild()
        {
            this.returnValue = (int)RunnerReturn.BuildResultInconclusive;

            ConnectionData   connData         = null;
            BackgroundWorker bg               = null;
            DoWorkEventArgs  e                = null;
            SqlBuildRunData  runData          = new SqlBuildRunData();
            string           targetDatabase   = overrides[0].OverrideDbTarget;
            string           loggingDirectory = Path.Combine(ThreadedExecution.WorkingDirectory, server, targetDatabase);

            try
            {
                //Start setting properties on the object that contains the run configuration data.
                runData.BuildType = "Other";
                if (!string.IsNullOrEmpty(cmdArgs.Description))
                {
                    runData.BuildDescription = cmdArgs.Description;
                }
                else
                {
                    runData.BuildDescription = "Threaded Multi-Database. Run ID:" + ThreadedExecution.RunID;
                }

                runData.IsTrial                 = this.isTrial;
                runData.RunScriptOnly           = false;
                runData.TargetDatabaseOverrides = overrides;
                runData.Server          = this.server;
                runData.IsTransactional = cmdArgs.Transactional;
                if (this.cmdArgs.LogToDatabaseName.Length > 0)
                {
                    runData.LogToDatabaseName = this.cmdArgs.LogToDatabaseName;
                }

                runData.PlatinumDacPacFileName = cmdArgs.DacPacArgs.PlatinumDacpac;
                runData.BuildRevision          = cmdArgs.BuildRevision;
                runData.DefaultScriptTimeout   = cmdArgs.DefaultScriptTimeout;
                runData.AllowObjectDelete      = cmdArgs.AllowObjectDelete;


                //Initilize the logging directory for this run
                if (!Directory.Exists(loggingDirectory))
                {
                    Directory.CreateDirectory(loggingDirectory);
                }

                if (forceCustomDacpac)
                {
                    runData.ForceCustomDacpac = true;
                    //This will set the BuildData and BuildFileName and ProjectFileName properties on runData
                    var status = DacPacHelper.UpdateBuildRunDataForDacPacSync(ref runData, server, targetDatabase, this.authType, this.username, this.password, loggingDirectory, cmdArgs.BuildRevision, cmdArgs.DefaultScriptTimeout, cmdArgs.AllowObjectDelete);
                    switch (status)
                    {
                    case DacpacDeltasStatus.Success:
                        //nothing to do
                        break;

                    case DacpacDeltasStatus.InSync:
                    case DacpacDeltasStatus.OnlyPostDeployment:
                        log.LogInformation($"Target database {targetDatabase} is already in sync with {cmdArgs.DacPacArgs.PlatinumDacpac}. Nothing to do!");
                        this.returnValue = (int)RunnerReturn.DacpacDatabasesInSync;
                        break;

                    default:
                        log.LogError($"Error creating custom dacpac and scripts for {targetDatabase}. No update was performed");
                        this.returnValue = (int)RunnerReturn.PackageCreationError;
                        return((int)RunnerReturn.PackageCreationError);;
                    }
                }
                else
                {
                    runData.ForceCustomDacpac = false;
                    //Get a full copy of the build data to work with (avoid threading sync issues)
                    SqlSyncBuildData buildData = new SqlSyncBuildData();

                    string xml = "<?xml version=\"1.0\" standalone=\"yes\"?>\r\n" + ThreadedExecution.BuildData.GetXml();
                    using (StringReader sr = new StringReader(xml))
                    {
                        buildData.ReadXml(sr);
                    }
                    //Clear out any existing ComittedScript data.. just log what is relevent to this run.
                    buildData.CommittedScript.Clear();


                    runData.BuildData       = buildData;
                    runData.ProjectFileName = Path.Combine(loggingDirectory, Path.GetFileName(ThreadedExecution.ProjectFileName));
                    runData.BuildFileName   = ThreadedExecution.BuildZipFileName;
                }



                //Create a connection object.. all we need is the server here, the DB will be filled in at execution time
                connData = new ConnectionData(server, "");
                if (this.cmdArgs.AuthenticationArgs.UserName.Length > 0 && this.cmdArgs.AuthenticationArgs.Password.Length > 0)
                {
                    connData.UserId   = cmdArgs.AuthenticationArgs.UserName;
                    connData.Password = cmdArgs.AuthenticationArgs.Password;
                }
                connData.AuthenticationType = this.cmdArgs.AuthenticationArgs.AuthenticationType;

                //Set the log file name
                string logFile = Path.Combine(loggingDirectory, "ExecutionLog.log");

                //Create the objects that will handle the event communication back.
                bg = new BackgroundWorker();
                //bg.ProgressChanged += Bg_ProgressChanged;
                bg.WorkerReportsProgress = true;
                e = new DoWorkEventArgs(null);
            }
            catch (Exception exe)
            {
                log.LogError(exe, $"Error Initializing run for {this.TargetTag}");
                WriteErrorLog(loggingDirectory, exe.ToString());
                this.returnValue = (int)ExecutionReturn.RunInitializationError;
                return((int)ExecutionReturn.RunInitializationError);;
            }

            log.LogDebug("Initializing run for " + this.TargetTag + ". Starting \"ProcessBuild\"");

            try
            {
                //Initilize the run helper object and kick it off.
                SqlBuildHelper helper = new SqlBuildHelper(connData, true, string.Empty, cmdArgs.Transactional); //don't need an "external" log for this, it's all external!
                helper.BuildCommittedEvent              += new BuildCommittedEventHandler(helper_BuildCommittedEvent);
                helper.BuildErrorRollBackEvent          += new EventHandler(helper_BuildErrorRollBackEvent);
                helper.BuildSuccessTrialRolledBackEvent += new EventHandler(helper_BuildSuccessTrialRolledBackEvent);
                await Task.Run(() =>
                {
                    helper.ProcessBuild(runData, bg, e, ThreadedExecution.BatchColl, this.buildRequestedBy, cmdArgs.TimeoutRetryCount);
                });
            }
            catch (Exception exe)
            {
                log.LogError("Error Processing run for " + this.TargetTag, exe);
                WriteErrorLog(loggingDirectory, exe.ToString());
                this.returnValue = (int)ExecutionReturn.ProcessBuildError;
                return((int)ExecutionReturn.ProcessBuildError);;
            }
            return(0);
        }