Example #1
0
        private void buttonOk_Click(object sender, EventArgs e)
        {
            for (int i = this.Controls.Count - 1; i >= 0; i--)
            {
                Control control = this.Controls[i];
                control.Focus();
                if (!Validate())
                {
                    DialogResult = DialogResult.None;
                    return;
                }
            }

            if (_mapColumn == null)
            {
                Relationship[] relationshipPath = new Relationship[1] { (Relationship)comboBoxRelationship.SelectedItem };
                Column column = (Column)comboBoxMapColumn.SelectedItem;
                _mapColumn = new MapColumn(textBoxName.Text, true, relationshipPath, column, _parent.Columns.Length, column.IsNullable, column.DataType, column.CharacterMaximumLength);
                _mapColumn.Alias = textBoxAlias.Text;
                _mapColumn.AliasDisplay = textBoxAliasDisplay.Text;
            }
            else
            {
                _mapColumn.ForeignColumn = (Column)comboBoxMapColumn.SelectedItem;

                _mapColumn.Name = textBoxName.Text;
                _mapColumn.Alias = textBoxAlias.Text;
                _mapColumn.AliasDisplay = textBoxAliasDisplay.Text;
            }
        }
Example #2
0
        public bool NameValidate(MapColumn mapColumn, out string failReason)
        {
            failReason = "";
            /*Don't check items that are not enabled*/

            if (!mapColumn.Enabled)
            {
                return(true);
            }
            if (string.IsNullOrEmpty(mapColumn.Name))
            {
                failReason = "Name cannot be zero-length.";
                return(false);
            }
            if (mapColumn.Name.IndexOf(" ") >= 0)
            {
                failReason = "Name cannot have spaces.";
                return(false);
            }

            foreach (Column sibling in mapColumn.Parent.Columns)
            {
                if (sibling != this && sibling.Enabled && ArchAngel.Providers.Database.Helper.Script.StringsAreEqual(sibling.Name, Name, false))
                {
                    failReason = "Duplicate name: " + Name;
                    return(false);
                }
            }
            return(true);
        }
Example #3
0
 public string AliasDisplayDefault(MapColumn mapColumn)
 {
     if (mapColumn.RelationshipPath == null || mapColumn.ForeignColumn == null)
     {
         return("temp");
     }
     return(mapColumn.RelationshipPath[0].ForeignScriptObject.Alias + mapColumn.ForeignColumn.Alias);
 }
Example #4
0
        public string AliasDefault(MapColumn mapColumn)
        {
            if (mapColumn.RelationshipPath == null || mapColumn.ForeignColumn == null)
            {
                return("temp");
            }
            string alias = mapColumn.RelationshipPath[0].ForeignScriptObject.Alias + mapColumn.ForeignColumn.Alias;

            return(alias.Replace("_", ""));
        }
Example #5
0
        public FormMapColumn(ScriptObject parent, MapColumn mapColumn)
        {
            InitializeComponent();
            BackColor = Slyce.Common.Colors.BackgroundColor;

            _parent = parent;
            _mapColumn = mapColumn;
            ucHeading1.Text = "";
            Interfaces.Events.ShadeMainForm();
        }
Example #6
0
        public FormMapColumn(ScriptObject parent, MapColumn mapColumn)
        {
            InitializeComponent();
            this.BackColor = Slyce.Common.Colors.BackgroundColor;

            _parent = parent;
            _mapColumn = mapColumn;
            ucHeading1.Text = "";
            Controller.ShadeMainForm();
        }
Example #7
0
 public bool AliasPluralValidate(MapColumn mapColumn, out string failReason)
 {
     failReason = "";
     return(true);
 }
Example #8
0
 public virtual string AliasPluralDefault(MapColumn mapColumn)
 {
     return(ArchAngel.Providers.Database.Helper.Script.GetPlural(mapColumn.Alias));
 }
Example #9
0
        private void InitialUpdateMapColumns(IList<Model.Table> tables)
        {
            foreach (Model.Table table in tables)
            {
                foreach (ManyToOneRelationship manyToOneRelationship in table.ManyToOneRelationships)
                {
                    Column dataDisplayColumn = GetDataDisplayColumn((Model.Table)manyToOneRelationship.ForeignScriptObject);

                    if (dataDisplayColumn != null)
                    {
                        MapColumn mapColumn = new MapColumn(manyToOneRelationship.Name, false, new Relationship[] { manyToOneRelationship }, dataDisplayColumn, table.Columns.Length, manyToOneRelationship.PrimaryColumns[0].IsNullable || manyToOneRelationship.ForeignColumns[0].IsNullable, dataDisplayColumn.DataType, dataDisplayColumn.Size, dataDisplayColumn.Precision, dataDisplayColumn.Scale);
                        table.AddColumn(mapColumn);
                    }
                }
            }
        }
Example #10
0
 public string AliasDefault(MapColumn mapColumn)
 {
     if (mapColumn.RelationshipPath == null || mapColumn.ForeignColumn == null)
     {
         return "temp";
     }
     string alias = mapColumn.RelationshipPath[0].ForeignScriptObject.Alias + mapColumn.ForeignColumn.Alias;
     return alias.Replace("_", "");
 }
Example #11
0
        public static string GetSQLParentAlias(MapColumn mapColumn)
        {
            // TODO: Add in one to one support
            string parentName = mapColumn.Parent.Name;

            List<string> foreignTableNames = new List<string>();
            foreignTableNames.Add(parentName);

            Table table = (Table)mapColumn.Parent;
            foreach (MapColumn tempMapColumn in table.MapColumns)
            {
                foreignTableNames.Add(tempMapColumn.ForeignColumn.Parent.Name);

                if (tempMapColumn == mapColumn)
                {
                    break;
                }
            }

            int count = -1;
            foreach (string name in foreignTableNames)
            {
                if (name == mapColumn.ForeignColumn.Parent.Name)
                {
                    count++;
                }
            }

            if (count <= 0)
            {
                return GetSQLName(mapColumn.ForeignColumn.Parent.Name);
            }
            return GetSQLName(mapColumn.ForeignColumn.Parent.Name + "_" + count);
        }
Example #12
0
        public bool NameValidate(MapColumn mapColumn, out string failReason)
        {
            failReason = "";
            /*Don't check items that are not enabled*/

            if (!mapColumn.Enabled)
            {
                return true;
            }
            if (string.IsNullOrEmpty(mapColumn.Name))
            {
                failReason = "Name cannot be zero-length.";
                return false;
            }
            if (mapColumn.Name.IndexOf(" ") >= 0)
            {
                failReason = "Name cannot have spaces.";
                return false;
            }

            foreach (Column sibling in mapColumn.Parent.Columns)
            {
                if (sibling != this && sibling.Enabled && ArchAngel.Providers.Database.Helper.Script.StringsAreEqual(sibling.Name, Name, false))
                {
                    failReason = "Duplicate name: " + Name;
                    return false;
                }
            }
            return true;
        }
Example #13
0
 public bool AliasValidate(MapColumn mapColumn, out string failReason)
 {
     failReason = "";
     return true;
 }
Example #14
0
 public virtual string AliasPluralDefault(MapColumn mapColumn)
 {
     return ArchAngel.Providers.Database.Helper.Script.GetPlural(mapColumn.Alias);
 }
Example #15
0
 public string AliasDisplayDefault(MapColumn mapColumn)
 {
     if (mapColumn.RelationshipPath == null || mapColumn.ForeignColumn == null)
     {
         return "temp";
     }
     return mapColumn.RelationshipPath[0].ForeignScriptObject.Alias + mapColumn.ForeignColumn.Alias;
 }
Example #16
0
        /// <summary>
        /// Updates objects that have just been read from the database with any changes the user made, such as renaming.
        /// </summary>
        /// <param name="newDatabase"></param>
        /// <param name="oldDatabase"></param>
        /// <param name="processViews"></param>
        /// <param name="processStoredProcedures"></param>
        /// <param name="processTables"></param>
        /// <returns>Returns a description of any errors that occurred or alerts that the user needs to be aware of.</returns>
        private string UpdateScriptObjects(
            Model.Database newDatabase, 
            Model.Database oldDatabase,
            bool processTables,
            bool processViews,
            bool processStoredProcedures)
        {
            oldDatabase.SnapshotMode = true;

            StringBuilder sb = new StringBuilder(1000);

            #region Script Objects

            // Find old user defined script objects and add to new database
            ScriptObject[] userDefinedScriptObjects = GetUserDefinedScriptObjects(oldDatabase.AllScriptObjects);

            foreach (ScriptObject scriptObject in userDefinedScriptObjects)
            {
                newDatabase.AddScriptObject(scriptObject);
                Interfaces.Events.RaiseObjectBeingProcessedEvent(scriptObject.Name, "Script Object");
                //RaiseObjectBeingProcessedEvent(scriptObject.Name, "Script Object");
            }

            #endregion

            #region Force update of the cached ScriptObjects
            oldDatabase.ResetAllScriptObjects();
            ScriptObject[] ScriptObjects = oldDatabase.AllScriptObjects;
            newDatabase.SnapshotMode = true;
            newDatabase.ResetAllScriptObjects();
            #endregion

            #region Columns

            Interfaces.Events.RaiseObjectBeingProcessedEvent("", "Updating Columns");

            // Update new script objects with old columns
            foreach (ScriptObject newScriptObject in newDatabase.AllScriptObjects)
            {
                if ((newScriptObject.IsTable && !processTables) ||
                    (newScriptObject.IsStoredProcedure && !processStoredProcedures) ||
                    (newScriptObject.IsView && !processViews))
                {
                    continue;
                }
                // Find old script object if it exists
                ScriptObject oldScriptObject = Search.GetScriptObject(oldDatabase.AllScriptObjects, newScriptObject, newScriptObject.GetType(), false);

                if (oldScriptObject == null || oldScriptObject.IsUserDefined)
                {
                    continue;
                }
                // Find old user defined columns and add to script object
                Column[] userDefinedColumns = GetUserDefinedColumns(oldScriptObject.Columns);
                foreach (Column oldColumn in userDefinedColumns)
                {
                    if (oldColumn.GetType() == typeof(Column))
                    {
                        Interfaces.Events.RaiseObjectBeingProcessedEvent(oldColumn.Name, "Column");
                        //RaiseObjectBeingProcessedEvent(oldColumn.Name, "Column");
                        Column newColumn = new Column(oldColumn.Name, oldColumn.IsUserDefined, newScriptObject,
                            newScriptObject.Columns.Length, oldColumn.IsNullable, oldColumn.DataType, oldColumn.Size, oldColumn.InPrimaryKey,
                            oldColumn.IsIdentity, oldColumn.Default, oldColumn.ReadOnly, oldColumn.IsCalculated, oldColumn.Precision, oldColumn.Scale);

                        newColumn.Alias = oldColumn.Alias;
                        newColumn.AliasDisplay = oldColumn.AliasDisplay;
                        newScriptObject.AddColumn(newColumn);
                    }
                }

                if (newScriptObject.GetType() == typeof(Model.StoredProcedure) && oldScriptObject.Enabled)
                {
                    // Execute Stored Procedure if enabled and retrieve columns
                    FillStoredProcedureColumns((Model.StoredProcedure)newScriptObject);
                }
                foreach (string error in newScriptObject.Errors)
                {
                    sb.AppendLine(error);
                }
            }

            #endregion

            #region Map Columns

            Interfaces.Events.RaiseObjectBeingProcessedEvent("", "Updating Map Columns");

            // Update new script objects with old properties
            foreach (ScriptObject newScriptObject in newDatabase.AllScriptObjects)
            {
                if ((newScriptObject.IsTable && !processTables) ||
                    (newScriptObject.IsStoredProcedure && !processStoredProcedures) ||
                    (newScriptObject.IsView && !processViews))
                {
                    continue;
                }
                // Find old script object if it exists
                ScriptObject oldScriptObject = Search.GetScriptObject(oldDatabase.AllScriptObjects, newScriptObject, newScriptObject.GetType(), false);
                if (oldScriptObject == null)
                {
                    continue;
                }
                // Find old user defined columns and add to script object
                Column[] userDefinedColumns = GetUserDefinedColumns(oldScriptObject.Columns);
                foreach (Column oldColumn in userDefinedColumns)
                {
                    if (ModelTypes.MapColumn.IsInstanceOfType(oldColumn))
                    {
                        Interfaces.Events.RaiseObjectBeingProcessedEvent(oldColumn.Name, "Map Column");
                        //RaiseObjectBeingProcessedEvent(oldColumn.Name, "Map Column");
                        MapColumn oldMapColumn = (MapColumn)oldColumn;

                        // We insert a null RelationshipPath here. Don't worry, because we wire up the correct ones below in the region called 'Update Map Column Relationship Path and Foreign Column'
                        MapColumn newMapColumn = new MapColumn(oldMapColumn.Name, oldMapColumn.IsUserDefined,
                            null, null, newScriptObject.Columns.Length, oldMapColumn.IsNullable, oldMapColumn.DataType, oldMapColumn.Size, oldMapColumn.Precision, oldMapColumn.Scale);

                        newMapColumn.Alias = oldMapColumn.Alias;
                        newMapColumn.AliasDisplay = oldMapColumn.AliasDisplay;

                        if (oldMapColumn.RelationshipPath != null)
                        {
                            //foreach (Relationship rel in oldMapColumn.RelationshipPath)
                            //{
                            //    Relationship newRel = Search.GetRelationship(newScriptObject.Relationships, rel.Name, false);
                            //}
                        }
                        //newMapColumn.Parent = newScriptObject;
                        newScriptObject.AddColumn(newMapColumn);
                    }
                }
            }

            #endregion

            #region Key and Index

            ArchAngel.Interfaces.Events.RaiseObjectBeingProcessedEvent("", "Updating Keys and Indexes");

            if (processTables)
            {
                // Update new script objects with old properties
                foreach (Model.Table newTable in newDatabase.Tables)
                {
                    // Find old script object if it exists
                    Model.Table oldTable = Search.GetTable(oldDatabase.Tables, newTable, false);
                    if (oldTable == null)
                    {
                        continue;
                    }
                    // Find old user defined keys
                    Key[] userDefinedKeys = GetUserDefinedKeys(oldTable.Keys);

                    foreach (Key oldKey in userDefinedKeys)
                    {
                        Interfaces.Events.RaiseObjectBeingProcessedEvent(oldKey.Name, "User-Defined Key");
                        // TODO: Add new key
                        //Key newKey = new Key(oldKey.Name, oldKey.Alias, oldKey.IsUserDefined, oldKey.AliasDisplay, newScriptObject, newScriptObject.Keys.Length, oldKey.IsNullable, oldKey.DataType, oldKey.Size, oldKey.InPrimaryKey, oldKey.IsMap, oldKey.IsIdentity);
                        //newTable.AddKey(newKey);
                    }
                    // Find old user defined indexes
                    Index[] userDefinedIndexes = GetUserDefinedIndexes(oldTable.Indexes);

                    foreach (Index oldIndex in userDefinedIndexes)
                    {
                        Interfaces.Events.RaiseObjectBeingProcessedEvent(oldIndex.Name, "User-Defined Index");
                        // TODO: Add new index
                        //Index newIndex = new Index(oldIndex.Name, oldIndex.Alias, oldIndex.IsUserDefined, oldIndex.AliasDisplay, newScriptObject, newScriptObject.Indexs.Length, oldIndex.IsNullable, oldIndex.DataType, oldIndex.Size, oldIndex.InPrimaryIndex, oldIndex.IsMap, oldIndex.IsIdentity);
                        //newTable.AddIndex(newIndex);
                    }
                }
            }

            #endregion

            #region Filter

            Interfaces.Events.RaiseObjectBeingProcessedEvent("", "Updating Filters");

            // Update new script objects with old properties
            foreach (ScriptObject newScriptObject in newDatabase.AllScriptObjects)
            {
                if ((newScriptObject.IsTable && !processTables) ||
                    (newScriptObject.IsStoredProcedure && !processStoredProcedures) ||
                    (newScriptObject.IsView && !processViews))
                {
                    continue;
                }
                // Find old script object if it exists
                ScriptObject oldScriptObject = Search.GetScriptObject(oldDatabase.AllScriptObjects, newScriptObject, newScriptObject.GetType(), false);

                if (oldScriptObject == null || oldScriptObject.IsUserDefined)
                {
                    continue;
                }
                // Find old user defined filters
                Filter[] userDefinedFilters = GetUserDefinedFilters(oldScriptObject.Filters);

                foreach (Filter oldFilter in userDefinedFilters)
                {
                    Interfaces.Events.RaiseObjectBeingProcessedEvent(oldFilter.Name, "Filter");

                    Filter newFilter = new Filter(oldFilter.Name, oldFilter.IsUserDefined, newScriptObject, oldFilter.IsReturnTypeCollection, oldFilter.CreateStoredProcedure,
                        oldFilter.UseCustomWhere, oldFilter.CustomWhere, oldFilter.Key);

                    newFilter.Alias = oldFilter.Alias;
                    newFilter.Name = oldFilter.Name;
                    newFilter.CustomWhere = oldFilter.CustomWhere;
                    newFilter.CreateStoredProcedure = oldFilter.CreateStoredProcedure;
                    newFilter.Enabled = oldFilter.Enabled;
                    newFilter.IsReturnTypeCollection = oldFilter.IsReturnTypeCollection;

                    foreach (Filter.FilterColumn oldFilterColumn in oldFilter.FilterColumns)
                    {
                        Column newFilterColumnColumn = GetNewScriptBase(newDatabase.AllScriptObjects, oldFilter, oldFilterColumn.Column);

                        Filter.FilterColumn newFilterColumn = new Filter.FilterColumn(newFilterColumnColumn, oldFilterColumn.LogicalOperator, oldFilterColumn.CompareOperator, oldFilterColumn.Alias);
                        newFilter.AddFilterColumn(newFilterColumn);
                    }
                    foreach (Filter.OrderByColumn oldOrderByColumn in oldFilter.OrderByColumns)
                    {
                        Column newOrderByColumnColumn = GetNewScriptBase(newDatabase.AllScriptObjects, oldFilter, oldOrderByColumn.Column);

                        Filter.OrderByColumn newOrderByColumn = new Filter.OrderByColumn(newOrderByColumnColumn, oldOrderByColumn.SortOperator);
                        newFilter.AddOrderByColumn(newOrderByColumn);
                    }
                    newScriptObject.AddFilter(newFilter);
                }
            }

            #endregion

            #region Relationship

            Interfaces.Events.RaiseObjectBeingProcessedEvent("", "Updating Relationships");

            // Update new script objects with old properties
            foreach (ScriptObject newScriptObject in newDatabase.AllScriptObjects)
            {
                if ((newScriptObject.IsTable && !processTables) ||
                    (newScriptObject.IsStoredProcedure && !processStoredProcedures) ||
                    (newScriptObject.IsView && !processViews))
                {
                    continue;
                }
                // Find old script object if it exists
                ScriptObject oldScriptObject = Search.GetScriptObject(oldDatabase.AllScriptObjects, newScriptObject, newScriptObject.GetType(), false);

                if (oldScriptObject == null)// || oldScriptObject.IsUserDefined)
                {
                    continue;
                }
                // Find old user defined relationships
                Relationship[] userDefinedRelationships = GetUserDefinedRelationships(oldScriptObject.Relationships);

                foreach (Relationship oldRelationship in userDefinedRelationships)
                {
                    if (oldScriptObject.IsUserDefined)
                    {
                        oldScriptObject.RemoveRelationship(oldRelationship);
                    }
                    Interfaces.Events.RaiseObjectBeingProcessedEvent(oldRelationship.Name, "Relationship");

                    // Find relationship script objects in new database schema
                    ScriptObject newPrimaryScriptObject = GetNewScriptBase(newDatabase.AllScriptObjects, oldRelationship.PrimaryScriptObject);
                    ScriptObject newForeignScriptObject = GetNewScriptBase(newDatabase.AllScriptObjects, oldRelationship.ForeignScriptObject);

                    if (newPrimaryScriptObject == null || newForeignScriptObject == null)
                    {
                        // The corresponding ScriptObjects have been deleted, so remove the Relationship
                        // TODO: inform the user about Relationships that have been removed, and the reason.
                        continue;
                    }
                    // Find relationship columns in new databse schema
                    Column[] newPrimaryColumns = GetNewScriptBase(newDatabase.AllScriptObjects, oldRelationship, oldRelationship.PrimaryColumns);
                    Column[] newForeignColumns = GetNewScriptBase(newDatabase.AllScriptObjects, oldRelationship, oldRelationship.ForeignColumns);

                    if (oldRelationship.GetType() == typeof(OneToOneRelationship))
                    {
                        // Find relationship filter in new databse schema
                        Filter newFilter = GetNewScriptBase(newScriptObject, oldRelationship, oldRelationship.Filter);

                        OneToOneRelationship oldOneToOneRelationship = (OneToOneRelationship)oldRelationship;
                        OneToOneRelationship newRelationship = new OneToOneRelationship(oldOneToOneRelationship.Name, oldOneToOneRelationship.IsUserDefined,
                             newPrimaryScriptObject, newPrimaryColumns, newForeignScriptObject, newForeignColumns, newFilter, oldOneToOneRelationship.IsBase);

                        Relationship foreignRelationship = null;

                        if (oldScriptObject.IsUserDefined)
                        {
                            foreignRelationship = GetNewScriptBase(newDatabase.AllScriptObjects, oldRelationship.ForeignRelationship);
                        }
                        if (oldRelationship.ForeignScriptObject.IsUserDefined)
                        {
                            foreignRelationship = GetNewScriptBase(newDatabase.AllScriptObjects, oldRelationship.ForeignRelationship);
                        }
                        if (foreignRelationship != null)
                        {
                            newRelationship.ForeignRelationship = foreignRelationship;
                            foreignRelationship.ForeignRelationship = newRelationship;
                        }
                        newRelationship.Alias = oldOneToOneRelationship.Alias;
                        newScriptObject.AddRelationship(newRelationship);
                    }

                    if (oldRelationship.GetType() == typeof(OneToManyRelationship))
                    {
                        // Find relationship filter in new databse schema
                        Filter newFilter = GetNewScriptBase(newScriptObject, oldRelationship, oldRelationship.Filter);

                        OneToManyRelationship oldOneToManyRelationship = (OneToManyRelationship)oldRelationship;
                        OneToManyRelationship newRelationship = new OneToManyRelationship(oldOneToManyRelationship.Name, oldOneToManyRelationship.IsUserDefined,
                             newPrimaryScriptObject, newPrimaryColumns, newForeignScriptObject, newForeignColumns, newFilter);

                        newRelationship.Alias = oldOneToManyRelationship.Alias;
                        newScriptObject.AddRelationship(newRelationship);
                    }

                    if (oldRelationship.GetType() == typeof(ManyToOneRelationship))
                    {
                        // Find relationship filter in new databse schema
                        Filter newFilter = GetNewScriptBase(newScriptObject, oldRelationship, oldRelationship.Filter);

                        ManyToOneRelationship oldManyToOneRelationship = (ManyToOneRelationship)oldRelationship;
                        ManyToOneRelationship newRelationship = new ManyToOneRelationship(oldManyToOneRelationship.Name, oldManyToOneRelationship.IsUserDefined,
                             newPrimaryScriptObject, newPrimaryColumns, newForeignScriptObject, newForeignColumns, newFilter);

                        newRelationship.Alias = oldManyToOneRelationship.Alias;
                        newScriptObject.AddRelationship(newRelationship);
                    }

                    //if (oldRelationship.GetType() == typeof(ManyToManyRelationship))
                    //{
                    //    ManyToManyRelationship oldManyToManyRelationship = (ManyToManyRelationship)oldRelationship;
                    //}
                }
            }

            #endregion

            #region Update Foreign Relationship

            Interfaces.Events.RaiseObjectBeingProcessedEvent("", "Updating Foreign Relationships");

            foreach (ScriptObject newScriptObject in newDatabase.AllScriptObjects)
            {
                if ((newScriptObject.IsTable && !processTables) ||
                    (newScriptObject.IsStoredProcedure && !processStoredProcedures) ||
                    (newScriptObject.IsView && !processViews))
                {
                    continue;
                }
                // Find old script object if it exists
                ScriptObject oldScriptObject = Search.GetScriptObject(oldDatabase.AllScriptObjects, newScriptObject, newScriptObject.GetType(), false);

                if (oldScriptObject == null)// || oldScriptObject.IsUserDefined)
                {
                    continue;
                }
                // Hookup foreign relationships
                // Find old user defined relationships
                Relationship[] userDefinedRelationships = GetUserDefinedRelationships(oldScriptObject.Relationships);

                for (int relationshipCounter = userDefinedRelationships.Length - 1; relationshipCounter >= 0; relationshipCounter--)
                {
                    Relationship oldRelationship = userDefinedRelationships[relationshipCounter];

                    if (oldRelationship.GetType() == typeof(ManyToManyRelationship))
                    {
                        continue;
                    }
                    Interfaces.Events.RaiseObjectBeingProcessedEvent(oldRelationship.Name, "User-Defined Relationship");
                    ScriptObject newPrimaryScriptObject = GetNewScriptBase(newDatabase.AllScriptObjects, oldRelationship.PrimaryScriptObject);
                    ScriptObject newForeignScriptObject = GetNewScriptBase(newDatabase.AllScriptObjects, oldRelationship.ForeignScriptObject);

                    if (newPrimaryScriptObject == null || newForeignScriptObject == null)
                    {
                        // The corresponding ScriptObjects have been deleted, so remove the Relationship
                        // TODO: inform the user about Relationships that have been removed, and the reason.
                        continue;
                    }
                    Relationship newPrimaryRelationship = GetNewScriptBase(newPrimaryScriptObject, oldRelationship);
                    Relationship newForeignRelationship = GetNewScriptBase(newForeignScriptObject, oldRelationship.ForeignRelationship);

                    if (newPrimaryRelationship == null || newForeignRelationship == null)
                    {
                        // The corresponding ScriptObjects have been deleted, so remove the Relationship
                        // TODO: inform the user about Relationships that have been removed, and the reason.
                        continue;
                    }
                    newPrimaryRelationship.ForeignRelationship = newForeignRelationship;
                    newForeignRelationship.ForeignRelationship = newPrimaryRelationship;
                }
            }

            #endregion

            #region Create Many to Many Relationship

            ArchAngel.Interfaces.Events.RaiseObjectBeingProcessedEvent("", "Updating Many to Many Relationships");

            foreach (ScriptObject newScriptObject in newDatabase.AllScriptObjects)
            {
                if ((newScriptObject.IsTable && !processTables) ||
                    (newScriptObject.IsStoredProcedure && !processStoredProcedures) ||
                    (newScriptObject.IsView && !processViews))
                {
                    continue;
                }
                // Find old script object if it exists
                ScriptObject oldScriptObject = Search.GetScriptObject(oldDatabase.AllScriptObjects, newScriptObject, newScriptObject.GetType(), false);
                if (oldScriptObject == null)
                {
                    continue;
                }
                // Find old user defined relationships
                Relationship[] userDefinedRelationships = GetUserDefinedRelationships(oldScriptObject.Relationships);
                foreach (Relationship oldRelationship in userDefinedRelationships)
                {
                    // Add userdefined may to many relationships here as they are based on other relationships that must all be loaded
                    if (oldRelationship.GetType() == typeof(ManyToManyRelationship))
                    {
                        Interfaces.Events.RaiseObjectBeingProcessedEvent(oldRelationship.Name, "Many-To-Many Relationship");
                        //ScriptObject newPrimaryScriptObject = GetNewScriptBase(newDatabase.AllScriptObjects, oldRelationship, oldRelationship.PrimaryScriptObject);
                        //ScriptObject newForeignScriptObject = GetNewScriptBase(newDatabase.AllScriptObjects, oldRelationship, oldRelationship.ForeignScriptObject);
                        Filter newFilter = GetNewScriptBase(newScriptObject, oldRelationship, oldRelationship.Filter);

                        ManyToManyRelationship oldManyToManyRelationship = (ManyToManyRelationship)oldRelationship;

                        ScriptObject newIntermediateScriptObject = GetNewScriptBase(newDatabase.AllScriptObjects, oldManyToManyRelationship.IntermediateForeignScriptObject);

                        OneToManyRelationship newIntermediatePrimaryRelationship = (OneToManyRelationship)GetNewScriptBase(newScriptObject, oldManyToManyRelationship.IntermediatePrimaryRelationship);
                        ManyToOneRelationship newIntermediateForeignRelationship = (ManyToOneRelationship)GetNewScriptBase(newIntermediateScriptObject, oldManyToManyRelationship.IntermediateForeignRelationship);

                        ManyToManyRelationship newRelationship = new ManyToManyRelationship(oldManyToManyRelationship.Name, oldManyToManyRelationship.IsUserDefined,
                              newIntermediatePrimaryRelationship, newIntermediateForeignRelationship, newFilter);

                        newRelationship.Alias = oldManyToManyRelationship.Alias;
                        newScriptObject.AddRelationship(newRelationship);
                    }
                }
            }

            #endregion

            #region Update Remaining Properties

            // Update new script objects with old properties
            foreach (ScriptObject newScriptObject in newDatabase.AllScriptObjects)
            {
                if ((newScriptObject.IsTable && !processTables) ||
                    (newScriptObject.IsStoredProcedure && !processStoredProcedures) ||
                    (newScriptObject.IsView && !processViews))
                {
                    continue;
                }
                // Find old script object if it exists
                ScriptObject oldScriptObject = Search.GetScriptObject(oldDatabase.AllScriptObjects, newScriptObject, newScriptObject.GetType(), false);

                if (oldScriptObject == null)
                {
                    continue;
                }
                Interfaces.Events.RaiseObjectBeingProcessedEvent(oldScriptObject.Name, "Update Remaining Properties");

                // Update new script object
                newScriptObject.Enabled = oldScriptObject.Enabled;
                newScriptObject.Alias = oldScriptObject.Alias;
                newScriptObject.AliasPlural = oldScriptObject.AliasPlural;
                newScriptObject.Ex = oldScriptObject.Ex;

                // Update new columns with old properties
                foreach (Column newColumn in newScriptObject.Columns)
                {
                    // Find old column if it exists
                    Column oldColumn;

                    if (ModelTypes.MapColumn.IsInstanceOfType(newColumn))
                    {
                        // Lookup MapColumns by using Alias as well, otherwise we have a problem when multiple MapColumns link to the
                        // same foreign column.
                        oldColumn = Search.GetColumn(oldScriptObject.Columns, newColumn.Name, newColumn.Alias, false);
                    }
                    else
                    {
                        oldColumn = Search.GetColumn(oldScriptObject.Columns, newColumn.Name, false);
                    }
                    if (oldColumn == null)
                    {
                        continue;
                    }
                    // Update new column
                    newColumn.Enabled = oldColumn.Enabled;
                    newColumn.IsNullable = oldColumn.IsNullable;
                    newColumn.Alias = oldColumn.Alias;
                    newColumn.AliasDisplay = oldColumn.AliasDisplay;
                    newColumn.Ex = oldColumn.Ex;
                    newColumn.Parent = Search.GetScriptObject(newDatabase.AllScriptObjects, oldColumn.Parent, oldColumn.Parent.GetType(), false);
                }
                // TODO: the code below should be refactored to use the Search class instead of traversing the individual elements. Eg: Search.GetFilterColumns
                // This will reduce the amount of duplicate code.

                #region Update new filters with old properties
                foreach (Filter newFilter in newScriptObject.Filters)
                {
                    #region Find old filter if it exists
                    Filter oldFilter = Search.GetFilter(oldScriptObject.Filters, newFilter.Name, false);

                    if (oldFilter == null)
                    {
                        oldFilter = Search.GetFilter(oldScriptObject.Filters, newFilter);
                    }
                    if (oldFilter == null)
                    {
                        continue;
                    }
                    #endregion

                    SyncFilterProperties(sb, newFilter, oldFilter);
                }
                #endregion

                #region Update new relationships with old properties
                foreach (Relationship newRelationship in newScriptObject.Relationships)
                {
                    Relationship oldRelationship = Search.GetRelationship(oldScriptObject.Relationships, newRelationship.Name, false);
                    if (oldRelationship == null)
                    {
                        continue;
                    }

                    // Update new relationship
                    newRelationship.Enabled = oldRelationship.Enabled;
                    newRelationship.Alias = oldRelationship.Alias;
                    newRelationship.Ex = oldRelationship.Ex;
                }
                #endregion

                if (newScriptObject.GetType() == typeof(Model.Table))
                {
                    Model.Table oldTable = (Model.Table)oldScriptObject;
                    Model.Table newTable = (Model.Table)newScriptObject;

                    // Update new keys with old properties
                    foreach (Key newKey in newTable.Keys)
                    {
                        Key oldKey = Search.GetKey(oldTable.Keys, newKey.Name, false);
                        if (oldKey == null)
                        {
                            continue;
                        }

                        // Update new key
                        newKey.Enabled = oldKey.Enabled;
                        newKey.Alias = oldKey.Alias;
                        newKey.Ex = oldKey.Ex;
                    }

                    // Update new indexes with old properties
                    foreach (Index newIndex in newTable.Indexes)
                    {
                        Index oldIndex = Search.GetIndex(oldTable.Indexes, newIndex.Name, false);
                        if (oldIndex == null)
                        {
                            continue;
                        }

                        // Update new index
                        newIndex.Enabled = oldIndex.Enabled;
                        newIndex.Alias = oldIndex.Alias;
                        newIndex.Ex = oldIndex.Ex;
                    }
                }
            }

            #endregion

            #region Update Map Column Relationship Path and Foreign Column

            Interfaces.Events.RaiseObjectBeingProcessedEvent("", "Updating Map Columns Relationships");

            // Update new script objects with old properties
            foreach (ScriptObject newScriptObject in newDatabase.AllScriptObjects)
            {
                if ((newScriptObject.IsTable && !processTables) ||
                    (newScriptObject.IsStoredProcedure && !processStoredProcedures) ||
                    (newScriptObject.IsView && !processViews))
                {
                    continue;
                }
                // Find old script object if it exists
                ScriptObject oldScriptObject = Search.GetScriptObject(oldDatabase.AllScriptObjects, newScriptObject, newScriptObject.GetType(), false);
                if (oldScriptObject == null)
                {
                    continue;
                }
                // Find old user defined columns and add to script object
                Column[] userDefinedColumns = GetUserDefinedColumns(oldScriptObject.Columns);

                //foreach (Column oldColumn in userDefinedColumns)
                for (int columnCounter = userDefinedColumns.Length - 1; columnCounter >= 0; columnCounter--)
                {
                    Column oldColumn = userDefinedColumns[columnCounter];

                    if (ModelTypes.MapColumn.IsInstanceOfType(oldColumn))
                    {
                        //ArchAngel.Interfaces.ProjectHelper.RaiseObjectBeingProcessedEvent(oldColumn.Name, "User-Defined Column");
                        MapColumn oldMapColumn = (MapColumn)oldColumn;

                        // Find foreign column's parent in new database schema
                        ScriptObject newForeignScriptObject = null;

                        if (oldMapColumn.ForeignColumn != null)
                        {
                            newForeignScriptObject = GetNewScriptBase(newDatabase.AllScriptObjects, oldMapColumn.ForeignColumn.Parent);
                        }
                        else
                        {
                            oldScriptObject.RemoveColumn(oldColumn);
                            continue;
                        }

                        // Find foreign column in new database schema
                        Column newForeignColumn = GetNewScriptBase(newDatabase.AllScriptObjects, oldMapColumn, oldMapColumn.ForeignColumn);

                        Relationship[] newRelationshipPath = new Relationship[oldMapColumn.RelationshipPath.Length];
                        for (int i = 0; i < oldMapColumn.RelationshipPath.Length; i++)
                        {
                            Relationship newRelationship = GetNewScriptBase(newScriptObject, oldMapColumn.RelationshipPath[i]);
                            newRelationshipPath[i] = newRelationship;
                        }

                        MapColumn newMapColumn = (MapColumn)Search.GetColumn(newScriptObject.Columns, oldMapColumn.Name, oldMapColumn.Alias);
                        newMapColumn.RelationshipPath = newRelationshipPath;
                        newMapColumn.ForeignColumn = newForeignColumn;
                    }
                }
            }

            #endregion

            newDatabase.SnapshotMode = false;
            oldDatabase.SnapshotMode = false;
            return sb.ToString();
        }
        public override bool IsValid(bool deepCheck, out string failReason)
        {
            bool isValid = true;

            failReason = "";
            string tempFailReason;

            if (!Enabled)
            {
                return(true);
            }
            if (!AliasValidate(this, out tempFailReason))
            {
                isValid     = false;
                failReason += string.Format("{1}.Alias: {0}\n", tempFailReason, Name);
            }
            if (!AliasPluralValidate(this, out tempFailReason))
            {
                isValid     = false;
                failReason += string.Format("{1}.AliasPlural: {0}\n", tempFailReason, Name);
            }
            if (!Filter.IsReturnTypeCollection)
            {
                isValid     = false;
                failReason += "Primary filter needs to return a collection, not a single object.";
            }
            if (ForeignRelationship.Filter.IsReturnTypeCollection)
            {
                isValid     = false;
                failReason += "Foreign filter needs to return a single object, not a collection.";
            }
            if (!IsValidFilter(this, out tempFailReason) || !IsValidFilter(ForeignRelationship, out tempFailReason))
            {
                isValid     = false;
                failReason += tempFailReason;
            }
            if (!Filter.IsValid(false, out tempFailReason))
            {
                isValid     = false;
                failReason += "Primary filter is invalid: " + tempFailReason;
            }
            if (!ForeignRelationship.Filter.IsValid(false, out tempFailReason))
            {
                isValid     = false;
                failReason += "Foreign filter is invalid: " + tempFailReason;
            }
            // Ensure that MapColumns aren't used to map back to their parent ScriptObject
            for (int i = 0; i < PrimaryColumns.Length; i++)
            {
                if (MapColumnType.IsInstanceOfType(PrimaryColumns[i]))
                {
                    MapColumn primaryCol = (MapColumn)PrimaryColumns[i];
                    Column    foreignCol = ForeignColumns[i];

                    if (primaryCol.ForeignColumn.Parent.Name == foreignCol.Parent.Name)
                    {
                        isValid     = false;
                        failReason += string.Format("A MapColumn cannot be joined to its parent: {0} [{1}.{2}]{3}", primaryCol.Alias, primaryCol.Parent.Name, primaryCol.Name, Environment.NewLine);
                    }
                }
            }
            // Ensure that the filter's column count equals the number of primary columns
            if (Filter.FilterColumns.Length != PrimaryColumns.Length)
            {
                isValid     = false;
                failReason += "Count of Filter's columns doesn't number of joined columns." + Environment.NewLine;
            }
            //foreach (Column primaryColumn in this.PrimaryColumns)
            //{
            //    if (MapColumnType.IsInstanceOfType(primaryColumn))
            //    {
            //        if /*(primaryColumn.Parent == this.ForeignScriptObject)*/(primaryColumn.Parent == this.PrimaryScriptObject)
            //        {
            //            isValid = false;
            //            failReason += string.Format("A MapColumn cannot be joined to its parent: {0} [{1}.{2}]{3}", primaryColumn.Alias, primaryColumn.Parent.Name, primaryColumn.Name, Environment.NewLine);
            //        }
            //    }
            //}
            //foreach (ManyToOneRelationship rel in this.Parent.ManyToOneRelationships)
            //{
            //    if (rel == this || !rel.Enabled)
            //    {
            //        continue;
            //    }
            //    if (rel.Name == this.Name || rel.Alias == this.Alias || rel.AliasPlural == this.AliasPlural)
            //    {
            //        isValid = false;
            //        failReason += "Duplicate named relationship.";
            //    }
            //    if (rel.ForeignColumns.Length == this.ForeignColumns.Length)
            //    {
            //        bool sameColumns = true;

            //        foreach (Column foreignColumn in rel.ForeignColumns)
            //        {
            //            foreach (Column column in this.ForeignColumns)
            //            {
            //                if (foreignColumn != column)
            //                {
            //                    sameColumns = false;
            //                    break;
            //                }
            //            }
            //            if (!sameColumns)
            //            {
            //                break;
            //            }
            //        }
            //        if (sameColumns)
            //        {
            //            isValid = false;
            //            failReason += "Duplicate relationship.";
            //        }
            //    }
            //}
            if (deepCheck)
            {
                /*Check inner objects*/
                if (Filter != null && !Filter.IsValid(deepCheck, out tempFailReason))
                {
                    isValid     = false;
                    failReason += string.Format("{0}.Filter: {1}\n", Name, tempFailReason);
                }

                foreach (IUserOption userOption in Ex)
                {
                    if (!userOption.IsValid(deepCheck, out tempFailReason))
                    {
                        isValid     = false;
                        failReason += string.Format("{0}.UserOption: {1}\n", Name, tempFailReason);
                    }
                }
            }
            return(isValid);
        }