/// <summary>
        /// Visits the given <paramref name="addReferenceNode"/>.
        /// </summary>
        /// <param name="addReferenceNode"></param>
        public override void Visit(IAddReferenceNode addReferenceNode)
        {
            if(string.IsNullOrEmpty(addReferenceNode.Name))
                addReferenceNode.Name = Environment.GetAnonymousIdentifier();

            base.Visit(addReferenceNode);
        }
        /// <summary>
        /// Visits the given <paramref name="addReferenceNode"/>.
        /// </summary>
        /// <param name="addReferenceNode"></param>
        public override void Visit(IAddReferenceNode addReferenceNode)
        {
            if(!Environment.IsAnonymousIdentifier(addReferenceNode.Name))
                return;

            ITableDefinition table = Environment.Schema.GetTable(addReferenceNode.FkTable);
            if(table == null)
                throw new MdlCompilerException(
                    string.Format(MdlCompilerResources.CouldNotResolveFkTableForAddReference, addReferenceNode.FkTable), 
                    addReferenceNode.Location);

            IReferenceDefinition reference = table.GetReference(addReferenceNode.Name);
            if(reference == null)
                throw new MdlCompilerException(
                    string.Format(MdlCompilerResources.CouldNotResolveReferenceDefinition, addReferenceNode.Name,
                        addReferenceNode.FkTable, addReferenceNode.PkTable),
                    addReferenceNode.Location);

            //
            // Remove reference
            table.RemoveReference(addReferenceNode.Name);

            //
            // Rename
            addReferenceNode.Name = reference.Name = namingStrategy.GetReferenceName(reference);

            //
            // And readd
            table.AddReference(reference);
        }
 /// <summary>
 /// Visits the given <paramref name="addReferenceNode"/>.
 /// </summary>
 /// <param name="addReferenceNode"></param>
 public override void Visit(IAddReferenceNode addReferenceNode)
 {
     if(IsImmediateChildOf<IColumnNode>(addReferenceNode))
         MoveNodeTo(addReferenceNode, addReferenceNode.Parent.Parent.Parent);
     else if(IsImmediateChildOf<IAddTableNode>(addReferenceNode) || IsImmediateChildOf<IAlterTableNode>(addReferenceNode))
         MoveNodeTo(addReferenceNode, addReferenceNode.Parent.Parent);
 }
        /// <summary>
        /// Visits the given <paramref name="addReferenceNode"/>.
        /// </summary>
        /// <param name="addReferenceNode"></param>
        public override void Visit(IAddReferenceNode addReferenceNode)
        {
            TextWriter.Write("alter table {0} add constraint {1} foreign key ({2}) references {3} ({4})",
                Platform.Dialect.EscapeIdentifier(addReferenceNode.FkTable), 
                Platform.Dialect.EscapeIdentifier(addReferenceNode.Name),
                Join(", ", EscapeIdentifiers(addReferenceNode.FkColumns)),
                Platform.Dialect.EscapeIdentifier(addReferenceNode.PkTable),
                Join(", ", EscapeIdentifiers(addReferenceNode.PkColumns)));

            if(addReferenceNode.OnUpdate.HasValue)
            {
                var onUpdate = GetReferenceCascadeAction(addReferenceNode.OnUpdate.Value);
                TextWriter.Write(" on update {0}", onUpdate);
            } // if

            if(addReferenceNode.OnDelete.HasValue)
            {
                var onDelete = GetReferenceCascadeAction(addReferenceNode.OnDelete.Value);
                TextWriter.Write(" on delete {0}", onDelete);
            } // if

            TextWriter.WriteLine(";");
        }
 /// <summary>
 /// Visits the given <paramref name="addReferenceNode"/>.
 /// </summary>
 /// <param name="addReferenceNode"></param>
 public override void Visit(IAddReferenceNode addReferenceNode)
 {
     Visit(addReferenceNode.ChildNodes);
 }
        /// <summary>
        ///  Visits the given <paramref name="addReferenceNode" />.
        /// </summary>
        /// <param name="addReferenceNode"></param>
        public override void Visit(IAddReferenceNode addReferenceNode)
        {
            textWriter.Write("add reference {0}", GetIdentifier(addReferenceNode.Name));

            WriteProperties(addReferenceNode);
            VisitBlock(addReferenceNode);
        }
        private void BindForeignKeyTable(IAddReferenceNode addReferenceNode, IReferenceDefinition reference)
        {
            // If the parent of IAddReferenceNode is either IAddTableNode or IAlterTableNode,
            // ForeignKeyTable is the binding for that node
            if(addReferenceNode.Parent is IAddTableNode || addReferenceNode.PkColumns is IAlterTableNode)
            {
                addReferenceNode.FkTable = reference.FkTable = 
                    Environment.Schema.GetTable(((ITableNode)addReferenceNode.Parent).Name).Name;
                return;
            } // if

            //
            // If parent is IAddColumnNode or IAlterColumnNode, we just move on level higher 
            // and do basically the same
            if(addReferenceNode.Parent is IAddColumnNode || addReferenceNode.PkColumns is IAlterColumnNode)
            {
                addReferenceNode.FkTable = reference.FkTable =
                    Environment.Schema.GetTable(((ITableNode)addReferenceNode.Parent.Parent).Name).Name;
                return;
            } // if

            //
            // If foreign key table is explicitly specified in properties, use that
            if(addReferenceNode.Properties[MdlSyntax.FkTable] != null)
            {
                ITableDefinition fkTable =
                    Environment.Schema.GetTable(AstNodePropertyUtil.AsString(addReferenceNode.Properties[MdlSyntax.FkTable].Value));
                addReferenceNode.FkTable = reference.FkTable = fkTable.Name;

                return;
            } // if

            throw CreateMdlCompilerException(MdlCompilerResources.CouldNotResolveFkTableForAddReference,
                addReferenceNode.Name);
        }
        private void BindForeignKeyColumns(IAddReferenceNode addReferenceNode, IReferenceDefinition reference)
        {
            //
            // If the parent of IAddReferenceNode is an IAddColumnNode or IAlterColumnNode, that column becomes the fk column
            if(addReferenceNode.Parent is IAddColumnNode || addReferenceNode.Parent is IAlterColumnNode)
            {
                string fkColumn = 
                    Environment.Schema.GetTable(reference.FkTable).GetColumn(((IAddColumnNode)addReferenceNode.Parent).Name).Name;
                
                addReferenceNode.FkColumns.Add(fkColumn);
                reference.FkColumns.Add(fkColumn);
                
                return;
            } // if

            //
            // fk-column must be explicitly specified
            if(addReferenceNode.Properties[MdlSyntax.FkColumn] != null)
            {
                //
                // FK table is already bound here
                IColumnDefinition fkColumn =
                    Environment.Schema.GetTable(reference.FkTable).GetColumn(
                        AstNodePropertyUtil.AsString(addReferenceNode.Properties[MdlSyntax.FkColumn].Value));
                
                addReferenceNode.FkColumns.Add(fkColumn.Name);
                reference.FkColumns.Add(fkColumn.Name);

                return;
            } // if

            //
            // If we have fk-columns specified
            if(addReferenceNode.Properties[MdlSyntax.FkColumns] != null)
            {
                IListAstNodePropertyValue list =
                    (IListAstNodePropertyValue)addReferenceNode.Properties[MdlSyntax.FkColumns].Value;
                foreach(IAstNodePropertyValue value in list.Items)
                {
                    string fkColumnName = ((IStringAstNodePropertyValue)value).Value;

                    //
                    // FK table is already bound here
                    IColumnDefinition fkColumn =
                        Environment.Schema.GetTable(reference.FkTable).GetColumn(fkColumnName);

                    addReferenceNode.FkColumns.Add(fkColumn.Name);
                    reference.FkColumns.Add(fkColumn.Name);
                } // foreach

                return;
            } // if

            throw CreateMdlCompilerException(MdlCompilerResources.CouldNotResolveFkColumnForAddReference, addReferenceNode.Name);
        }
        private void BindPrimaryKeyTable(IAddReferenceNode addReferenceNode, IReferenceDefinition reference)
        {
            if(addReferenceNode.Properties[MdlSyntax.PkTable] != null)
            {
                string pkTableName = AstNodePropertyUtil.AsString(addReferenceNode.Properties[MdlSyntax.PkTable].Value);
                ITableDefinition pkTable =
                    Environment.Schema.GetTable(pkTableName);

                if(pkTable == null)
                    throw new MigrationException(string.Format("Could not resolve Primary Key table '{0}'",  pkTableName));

                addReferenceNode.PkTable = pkTable.Name;
                reference.PkTable = pkTable.Name;

                return;
            } // if

            throw CreateMdlCompilerException(MdlCompilerResources.CouldNotResolvePkTableForAddReference, 
                addReferenceNode.Name);
        }
        private void BindPrimaryKeyColumns(IAddReferenceNode addReferenceNode, IReferenceDefinition reference)
        {
            //
            // Presence of "pk-column" means we're referencing only one column.
            if(addReferenceNode.Properties[MdlSyntax.PkColumn] != null)
            {
                //
                // Primary key table must already be bound, so we can use just that.
                IColumnDefinition pkColumn =
                    Environment.Schema.GetTable(reference.PkTable).GetColumn(
                        AstNodePropertyUtil.AsString(addReferenceNode.Properties[MdlSyntax.PkColumn].Value));
                
                addReferenceNode.PkColumns.Add(pkColumn.Name);
                reference.PkColumns.Add(pkColumn.Name);
            } // if
            else
            {
                //
                // Neither pk-column nor pk-columns were specified, so we assume
                // that this is a reference to the primary key of the pk-table
                var pkColumns = Environment.Schema.GetTable(reference.PkTable).GetPrimaryKeyColumns();
                if(pkColumns == null)
                    throw new MigrationException(string.Format("Table '{0}' has not Primary Key defined", reference.PkTable));

                if(pkColumns.Length > 1)
                    throw new MigrationException(
                        string.Format("Table '{0}' has Composite Primary Key defined. You have to explicitly specify 'pk-column` property", 
                            reference.PkTable));
                
                addReferenceNode.PkColumns.Add(pkColumns[0].Name);
                reference.PkColumns.Add(pkColumns[0].Name);
            }
        }
        /// <summary>
        /// Visits the given <paramref name="addReferenceNode"/>.
        /// </summary>
        /// <param name="addReferenceNode"></param>
        public override void Visit(IAddReferenceNode addReferenceNode)
        {
            ReferenceDefinition reference = new ReferenceDefinition(addReferenceNode.Name);

            BindForeignKeyTable(addReferenceNode, reference);
            BindForeignKeyColumns(addReferenceNode, reference);

            BindPrimaryKeyTable(addReferenceNode, reference);
            BindPrimaryKeyColumns(addReferenceNode, reference);

            if(addReferenceNode.Properties["on-update"] != null)
            {
                var onUpdate = AstNodePropertyUtil.AsString(addReferenceNode.Properties["on-update"].Value);
                addReferenceNode.OnUpdate = (ReferenceCascadeAction)Enum.Parse(
                    typeof(ReferenceCascadeAction),
                    onUpdate,
                    true);
            } // if

            if(addReferenceNode.Properties["on-delete"] != null)
            {
                var onDelete = AstNodePropertyUtil.AsString(addReferenceNode.Properties["on-delete"].Value);
                addReferenceNode.OnDelete = (ReferenceCascadeAction)Enum.Parse(
                    typeof(ReferenceCascadeAction),
                    onDelete,
                    true);
            } // if

            ITableDefinition table = Environment.Schema.GetTable(reference.FkTable);
            table.AddReference(reference);
        }
Пример #12
0
        /// <summary>
        /// 
        /// </summary>
        /// <param name="reference"></param>
        /// <param name="addReferenceNode"></param>
        private static void CopyProperties(IReferenceDefinition reference, IAddReferenceNode addReferenceNode)
        {
            if(!string.IsNullOrEmpty(reference.PkTable))
                AddProperty(addReferenceNode, MdlSyntax.PkTable, reference.PkTable);

            if(reference.PkColumns.Count == 1)
                AddProperty(addReferenceNode, MdlSyntax.PkColumn, reference.PkColumns[0]);
            else
                AddListProperty(addReferenceNode, MdlSyntax.PkColumns,
                    Algorithms.Convert<string, IAstNodePropertyValue>(reference.PkColumns, 
                        delegate(string input) { return new StringAstNodePropertyValue(input); }));

            if(!string.IsNullOrEmpty(reference.FkTable))
                AddProperty(addReferenceNode, MdlSyntax.FkTable, reference.FkTable);

            if(reference.FkColumns.Count == 1)
                AddProperty(addReferenceNode, MdlSyntax.FkColumn, reference.FkColumns[0]);
            else
                AddListProperty(addReferenceNode, MdlSyntax.FkColumns,
                    Algorithms.Convert<string, IAstNodePropertyValue>(reference.FkColumns,
                        delegate(string input) { return new StringAstNodePropertyValue(input); }));
        }