Example #1
0
        /// <summary>
        /// Script out the target database
        /// </summary>
        public void ScriptTarget()
        {
            try
            {
                //make sure we can run
                string error = null;
                if (RunOptions.Current.Connections.Targets.Count == 0)
                {
                    error = "Missing a valid target database";
                }
                if (error != null)
                {
                    Exit(error, false);
                }

                //Load the target database
                ScriptParser targetParser = LoadTargetDatabase(null);

                //generate new scripts
                RunOptions.Current.Logger.Log("Generating Scripts", OutputLevel.Reads);
                DifferenceSet differences = null;
                ScriptSet     scripts     = targetParser.Database.CreateScripts();

                //store the scripts
                ScriptManager.WriteScripts(scripts, differences);
            }
            catch (Exception ex)
            {
                Exit("Error: " + ex.Message, false);
            }

            Exit("Update Successful", true);
        }
Example #2
0
 /// <summary>
 /// Gets the differences between two sets.
 /// </summary>
 /// <param name="other">The other set of permissions to compare against.</param>
 /// <param name="differences">The set of differences to fill.</param>
 public void GetDifferences(PermissionSet other, DifferenceSet differences)
 {
     foreach (Name name in permissions.Keys)
     {
         if (IsDifferent(other, differences, name))
         {
             differences.Add(new Difference(DifferenceType.CreatedPermission, name), null);
         }
     }
 }
Example #3
0
        private bool IsDifferent(PermissionSet other, DifferenceSet differences, Name name)
        {
            if (!other.permissions.ContainsKey(name))
            {
                return(true);
            }

            foreach (SmallName account in permissions[name].Keys)
            {
                if (!other.permissions[name].ContainsKey(account))
                {
                    return(true);
                }

                foreach (SmallName grantType in permissions[name][account].Keys)
                {
                    SmallName permission      = permissions[name][account][grantType];
                    SmallName otherPermission = null;

                    bool granted = other.permissions[name][account].ContainsKey(grantType);
                    if (!granted && grantType == "exec" && other.permissions[name][account].ContainsKey("execute"))
                    {
                        granted         = true;
                        otherPermission = other.permissions[name][account]["execute"];
                    }
                    if (!granted && grantType == "execute" && other.permissions[name][account].ContainsKey("exec"))
                    {
                        granted         = true;
                        otherPermission = other.permissions[name][account]["exec"];
                    }
                    if (!granted)
                    {
                        return(true);
                    }

                    if (otherPermission == null)
                    {
                        otherPermission = other.permissions[name][account][grantType];
                    }

                    if (permission != otherPermission)
                    {
                        return(true);
                    }
                }
            }

            return(false);
        }
Example #4
0
        /// <summary>
        /// Gets the differences between this collection of items and another.
        /// </summary>
        /// <param name="other">The set of items to compare against.</param>
        /// <param name="dependencies">The dependencies for this collection.</param>
        /// <param name="otherDependencies">The dependencies for the other collection.</param>
        /// <param name="differences">The set of differences to fill.</param>
        public void GetDifferences(HashArray <T> other, DependencyCollection dependencies, DependencyCollection otherDependencies,
                                   DifferenceSet differences)
        {
            foreach (Item item in this)
            {
                Item       otherItem  = other == null ? null : other[item.Name];
                Difference difference = item.GetDifferences(otherItem, true);
                if (difference != null)
                {
                    differences.Add(difference, dependencies, otherDependencies);
                }
            }

            if (RunOptions.Current.FullyScripted && other != null)
            {
                foreach (Item otherItem in other)
                {
                    if (this[otherItem.Name] == null)
                    {
                        differences.Add(new Difference(DifferenceType.Removed, otherItem.Name), otherDependencies);
                    }
                }
            }
        }
Example #5
0
        /// <summary>
        /// The main functionality of the tool
        /// </summary>
        public void DoUpdate()
        {
            try
            {
                //make sure we can run
                string error = null;
                if (RunOptions.Current.Connections.Targets.Count == 0)
                {
                    error = "Missing a valid target database";
                }
                if (error != null)
                {
                    Exit(error, false);
                }

                //Load any reference database
                ScriptSet    referenceScripts = new ScriptSet();
                ScriptParser referenceParser  = new ScriptParser();
                foreach (ConnectionInfo connection in RunOptions.Current.Connections.References)
                {
                    switch (connection.Type)
                    {
                    case ConnectionType.Database:
                        ScriptManager.ParseDatabase(referenceParser, connection.Path);
                        ScriptManager.GetData(referenceParser.Database, RunOptions.Current.LoadData, connection.Path);
                        break;

                    case ConnectionType.Directory:
                        referenceScripts.Add(ScriptManager.LoadScripts(connection.Path));
                        referenceParser.RetrieveParsableObjects(referenceScripts);
                        break;

                    case ConnectionType.File:
                        referenceScripts.Add(ScriptManager.LoadScript(connection.Path));
                        referenceParser.RetrieveParsableObjects(referenceScripts);
                        break;

                    default:
                        throw new Exception(connection.Type.ToString());
                    }
                }

                //Load the target database
                ScriptParser targetParser = LoadTargetDatabase(referenceParser);

                //generate new scripts
                RunOptions.Current.Logger.Log("Calculating Differences", OutputLevel.Reads);
                DifferenceSet differences = null;
                if (referenceParser.Database.IsEmpty)
                {
                    referenceScripts = targetParser.Database.CreateDiffScripts(new Database());
                }
                else
                {
                    differences = referenceParser.Database.GetDifferences(targetParser.Database);
                    if (targetParser.Database.IsEmpty && differences.Count > 0)
                    {
                        Console.WriteLine("Creating database schema");
                    }
                    else
                    {
                        differences.Write(Console.Out);
                    }
                    referenceScripts.Add(referenceParser.Database.CreateDiffScripts(targetParser.Database, differences));
                }

                //Make sure everything runs in the right order
                referenceScripts.Sort();

                //store scripts if requested
                if (RunOptions.Current.ScriptOutputDirectory != "")
                {
                    ScriptManager.WriteScripts(referenceScripts, differences);
                }
                if (!string.IsNullOrEmpty(RunOptions.Current.DiffFile))
                {
                    ScriptManager.WriteDifferenceSummary(referenceParser.Database, targetParser.Database, differences);
                }

                //run the scripts
                if (!RunOptions.Current.Test && RunOptions.Current.Connections.References.Count > 0)
                {
                    if (RunOptions.Current.Connections.Targets.Count > 1)
                    {
                        throw new ApplicationException("Updating multiple targets is not supported");
                    }

                    ScriptManager.ExecuteScripts(referenceScripts, RunOptions.Current.Connections.Targets[0].Path);
                }
            }
            catch (Exception ex)
            {
                Exit("Error: " + ex.Message, false);
            }

            Exit("Update Successful", true);
        }
Example #6
0
        /// <summary>
        /// Gets the differences between this database and another.
        /// </summary>
        /// <param name="other">The other database.</param>
        /// <returns></returns>
        public DifferenceSet GetDifferences(Database other)
        {
            CalculateDependencies();
            other.CalculateDependencies();

            DifferenceSet differences = new DifferenceSet();

            //check table differences
            Tables.GetDifferences(other.Tables, dependencies, other.dependencies, differences);

            foreach (Table table in Tables)
            {
                Table otherTable = (Table)other.Tables[table.Name];
                table.Indexes.GetDifferences(otherTable == null ? null : otherTable.Indexes, dependencies, other.dependencies,
                                             differences);
                if (!table.Data.AreEqual(otherTable == null ? null : otherTable.Data))
                {
                    differences.Add(new Difference(DifferenceType.TableData, table.Data.Name, table.Name),
                                    otherTable == null ? null : dependencies);
                }
            }
            foreach (Table otherTable in other.Tables)
            {
                Table table = (Table)Tables[otherTable.Name];
                if (table == null)
                {
                    foreach (Index index in otherTable.Indexes)
                    {
                        differences.Add(new Difference(DifferenceType.Removed, index.Name, otherTable.Name), other.dependencies);
                    }
                }
            }

            //check constraint differences
            Constraints.GetDifferences(other.Constraints, dependencies, other.dependencies, differences);

            //deal with changing names...
            foreach (Constraint constraint in Constraints)
            {
                Table constrainedTable = other.Tables[constraint.ConstrainedTable];
                if (constrainedTable == null)
                {
                    continue;
                }

                if (constraint.Type == ConstraintType.Default)
                {
                    foreach (Name dependency in other.dependencies[constrainedTable.Name])
                    {
                        Constraint otherConstraint = other[dependency] as Constraint;
                        if (otherConstraint != null &&
                            otherConstraint.Type == ConstraintType.Default &&
                            constraint.ConstrainedTable == otherConstraint.ConstrainedTable &&
                            constraint.ColumnsEqual(otherConstraint) &&
                            constraint != otherConstraint
                            )
                        {
                            differences.Add(new Difference(DifferenceType.Removed, otherConstraint.Name), other.dependencies);
                            break;
                        }
                    }
                }
                else if (constraint.Type == ConstraintType.ForeignKey && other.Tables[constraint.ConstrainedTable] != null)
                {
                    foreach (Name dependency in other.dependencies[constrainedTable.Name])
                    {
                        Constraint otherConstraint = other[dependency] as Constraint;
                        if (otherConstraint != null &&
                            otherConstraint.Type == ConstraintType.ForeignKey &&
                            constraint.ConstrainedTable == otherConstraint.ConstrainedTable &&
                            constraint.ReferencedTable == otherConstraint.ReferencedTable &&
                            constraint.ColumnsEqual(otherConstraint) &&
                            constraint != otherConstraint
                            )
                        {
                            differences.Add(new Difference(DifferenceType.Removed, otherConstraint.Name), other.dependencies);
                            break;
                        }
                    }
                }
                else if (constraint.Type == ConstraintType.PrimaryKey && other.Tables[constraint.ConstrainedTable] != null)
                {
                    foreach (Name dependency in other.dependencies[constrainedTable.Name])
                    {
                        Constraint otherConstraint = other[dependency] as Constraint;
                        if (otherConstraint != null &&
                            otherConstraint.Type == ConstraintType.PrimaryKey &&
                            constraint.ConstrainedTable == otherConstraint.ConstrainedTable &&
                            constraint != otherConstraint
                            )
                        {
                            differences.Add(new Difference(DifferenceType.Removed, otherConstraint.Name), other.dependencies);
                            break;
                        }
                    }
                }
            }

            //check function differences
            Functions.GetDifferences(other.Functions, dependencies, other.dependencies, differences);

            //check fulltext catalog differences
            FulltextCatalogs.GetDifferences(other.FulltextCatalogs, dependencies, other.dependencies, differences);

            //check fulltext index differences
            FulltextIndexes.GetDifferences(other.FulltextIndexes, dependencies, other.dependencies, differences);

            //check procedure differences
            Procedures.GetDifferences(other.Procedures, dependencies, other.dependencies, differences);

            //check trigger differences
            Triggers.GetDifferences(other.Triggers, dependencies, other.dependencies, differences);

            //check trigger order differences
            TriggerOrder.GetDifferences(other.TriggerOrder, dependencies, other.dependencies, differences);

            //check view differences
            Views.GetDifferences(other.Views, dependencies, other.dependencies, differences);

            foreach (View view in Views)
            {
                View otherView = (View)other.Views[view.Name];
                view.Indexes.GetDifferences(otherView == null ? null : otherView.Indexes, dependencies, other.dependencies,
                                            differences);
            }

            foreach (View view in Views)
            {
                View otherView = (View)other.Views[view.Name];
                if (otherView != null)
                {
                    view.Indexes.GetDifferences(otherView.Indexes, dependencies, other.dependencies, differences);
                }
            }

            //check for new permissions
            Permissions.GetDifferences(other.Permissions, differences);

            return(differences);
        }
Example #7
0
        /// <summary>
        /// Generates the scripts required to turn another <see cref="Database"/> into a copy of this one.
        /// </summary>
        /// <param name="other">Another <see cref="Database"/>.</param>
        /// <param name="differences">The differences between these databases.</param>
        /// <returns></returns>
        public ScriptSet CreateDiffScripts(Database other, DifferenceSet differences)
        {
            ScriptSet scripts = new ScriptSet();

            foreach (Difference difference in differences)
            {
                Item adding   = null;
                Item removing = null;
                switch (difference.DifferenceType)
                {
                case DifferenceType.Created:
                    adding = this[difference.Item];
                    scripts.Add(adding.GenerateCreateScript());
                    scripts.Add(Permissions.GenerateCreateScript(adding));
                    break;

                case DifferenceType.CreatedPermission:
                    adding = this[difference.Item];
                    scripts.Add(Permissions.GenerateCreateScript(adding == null ? other[difference.Item] : adding));
                    break;

                case DifferenceType.Dependency:
                case DifferenceType.Modified:
                    adding   = this[difference.Item];
                    removing = other[difference.Item];
                    if (adding is Table && !((Table)adding).IsType)
                    {
                        scripts.Add(((Table)removing).GenerateSaveScript());
                        scripts.Add(((Table)adding).GenerateCreateScript());
                        scripts.Add(((Table)adding).GenerateRestoreScript(((Table)removing)));
                    }
                    else
                    {
                        scripts.Add(removing.GenerateDropScript());
                        if (adding != null)
                        {
                            scripts.Add(adding.GenerateCreateScript());
                        }
                    }

                    if (adding != null)
                    {
                        scripts.Add(Permissions.GenerateCreateScript(adding));
                    }
                    break;

                case DifferenceType.Removed:
                    removing = other[difference.Item];
                    if (removing is Table)
                    {
                        if (RunOptions.Current.FullyScripted)
                        {
                            scripts.Add(removing.GenerateDropScript());
                        }
                    }
                    else
                    {
                        scripts.Add(removing.GenerateDropScript());
                    }
                    break;

                case DifferenceType.TableData:
                    TableData newData  = Tables[difference.ParentItem].Data;
                    Table     oldTable = other.Tables[difference.ParentItem];
                    TableData oldData  = oldTable == null ? null : oldTable.Data;
                    scripts.Add(newData.GetDifferenceScript(oldData, difference.ParentItem));
                    break;

                default:
                    throw new ApplicationException(difference.DifferenceType.ToString());
                }
            }

            return(scripts);
        }