public static void ValidateEtlFragment(AstEtlFragmentNode etlFragment) { var graph = new TransformationGraph(etlFragment.Transformations); AstTransformationNode root = null; foreach (var rootNode in graph.RootNodes) { if (!(rootNode.Item is AstSourceTransformationNode)) { if (root != null) { MessageEngine.Trace(etlFragment, Severity.Error, "V0120", "Etl Fragments cannot have more than one root node with InputPaths"); } root = rootNode.Item; } } AstTransformationNode leaf = null; foreach (var leafNode in graph.LeafNodes) { if (!(leafNode.Item is AstDestinationNode)) { if (leaf != null) { MessageEngine.Trace(etlFragment, Severity.Error, "V0121", "Etl Fragments cannot have more than one leaf node with OutputPaths"); } leaf = leafNode.Item; } } }
public static void ProcessEtlFragments(SymbolTable symbolTable) ////HashSet<AstEtlRootNode> astEtlRootNodes) { var snapshotSymbolTable = new List<IReferenceableItem>(symbolTable); foreach (var astNamedNode in snapshotSymbolTable) { var fragmentReference = astNamedNode as AstEtlFragmentReferenceNode; if (fragmentReference != null && astNamedNode.FirstThisOrParent<ITemplate>() == null) { AstLowererValidation.ValidateEtlFragment(fragmentReference.EtlFragment); AstLowererValidation.ValidateEtlFragmentReference(fragmentReference); var clonedFragment = fragmentReference.EtlFragment.Clone() as AstEtlFragmentNode; var fragmentGraph = new TransformationGraph(clonedFragment.Transformations); GraphNode<AstTransformationNode> sourceNode = fragmentGraph.RootNodes.FirstOrDefault(node => !(node.Item is AstSourceTransformationNode)); GraphNode<AstTransformationNode> sinkNode = fragmentGraph.RootNodes.FirstOrDefault(node => !(node.Item is AstSourceTransformationNode)); Utility.Replace(fragmentReference, clonedFragment.Transformations); var etlGraph = new TransformationGraph(Utility.GetParentTransformationCollection(fragmentReference)); if (sourceNode != null) { GraphNode<AstTransformationNode> etlSourceNode = etlGraph.FindNode(sourceNode.Item); AstSingleInTransformationNode source = etlSourceNode.Item as AstSingleInTransformationNode; if (source != null && etlSourceNode.IncomingEdges.Count == 1) { source.InputPath = new AstDataflowMappedInputPathNode(source); if (fragmentReference.InputPath != null) { source.InputPath.OutputPath = fragmentReference.InputPath.OutputPath; } else if (etlSourceNode.IncomingEdges.Count == 1 && etlSourceNode.IncomingEdges[0].Source.Item.PreferredOutputPath != null) { source.InputPath.OutputPath = etlSourceNode.IncomingEdges[0].Source.Item.PreferredOutputPath; } else { MessageEngine.Trace(fragmentReference, Severity.Error, "V0136", "Cannot find output path to bind to the root node of Etl Fragment {0}", fragmentReference.Name); } foreach (var inputMapping in fragmentReference.Inputs) { var currentMapping = new AstDataflowColumnMappingNode(source.InputPath) { SourceName = inputMapping.SourcePathColumnName, TargetName = inputMapping.DestinationPathColumnName, }; source.InputPath.Mappings.Add(currentMapping); } } } if (sinkNode != null) { GraphNode<AstTransformationNode> etlSinkNode = etlGraph.FindNode(sinkNode.Item); if (etlSinkNode.OutgoingEdges.Count > 1) { MessageEngine.Trace(fragmentReference, Severity.Error, "V0136", "Sink nodes of Etl Fragment {0} can only have a single outgoing edge", fragmentReference.Name); } if (etlSinkNode.OutgoingEdges.Count > 0) { AstSingleInTransformationNode successor = etlSinkNode.OutgoingEdges[0].Sink.Item as AstSingleInTransformationNode; if (successor != null) { ProcessSuccessor(fragmentReference, clonedFragment, etlSinkNode, successor); } } } } } }
public static void ProcessEtlFragments(SymbolTable symbolTable) ////HashSet<AstEtlRootNode> astEtlRootNodes) { var snapshotSymbolTable = new List <IReferenceableItem>(symbolTable); foreach (var astNamedNode in snapshotSymbolTable) { var fragmentReference = astNamedNode as AstEtlFragmentReferenceNode; if (fragmentReference != null && astNamedNode.FirstThisOrParent <ITemplate>() == null) { AstLowererValidation.ValidateEtlFragment(fragmentReference.EtlFragment); AstLowererValidation.ValidateEtlFragmentReference(fragmentReference); var clonedFragment = fragmentReference.EtlFragment.Clone() as AstEtlFragmentNode; var fragmentGraph = new TransformationGraph(clonedFragment.Transformations); GraphNode <AstTransformationNode> sourceNode = fragmentGraph.RootNodes.FirstOrDefault(node => !(node.Item is AstSourceTransformationNode)); GraphNode <AstTransformationNode> sinkNode = fragmentGraph.RootNodes.FirstOrDefault(node => !(node.Item is AstSourceTransformationNode)); Utility.Replace(fragmentReference, clonedFragment.Transformations); var etlGraph = new TransformationGraph(Utility.GetParentTransformationCollection(fragmentReference)); if (sourceNode != null) { GraphNode <AstTransformationNode> etlSourceNode = etlGraph.FindNode(sourceNode.Item); AstSingleInTransformationNode source = etlSourceNode.Item as AstSingleInTransformationNode; if (source != null && etlSourceNode.IncomingEdges.Count == 1) { source.InputPath = new AstDataflowMappedInputPathNode(source); if (fragmentReference.InputPath != null) { source.InputPath.OutputPath = fragmentReference.InputPath.OutputPath; } else if (etlSourceNode.IncomingEdges.Count == 1 && etlSourceNode.IncomingEdges[0].Source.Item.PreferredOutputPath != null) { source.InputPath.OutputPath = etlSourceNode.IncomingEdges[0].Source.Item.PreferredOutputPath; } else { MessageEngine.Trace(fragmentReference, Severity.Error, "V0136", "Cannot find output path to bind to the root node of Etl Fragment {0}", fragmentReference.Name); } foreach (var inputMapping in fragmentReference.Inputs) { var currentMapping = new AstDataflowColumnMappingNode(source.InputPath) { SourceName = inputMapping.SourcePathColumnName, TargetName = inputMapping.DestinationPathColumnName, }; source.InputPath.Mappings.Add(currentMapping); } } } if (sinkNode != null) { GraphNode <AstTransformationNode> etlSinkNode = etlGraph.FindNode(sinkNode.Item); if (etlSinkNode.OutgoingEdges.Count > 1) { MessageEngine.Trace(fragmentReference, Severity.Error, "V0136", "Sink nodes of Etl Fragment {0} can only have a single outgoing edge", fragmentReference.Name); } if (etlSinkNode.OutgoingEdges.Count > 0) { AstSingleInTransformationNode successor = etlSinkNode.OutgoingEdges[0].Sink.Item as AstSingleInTransformationNode; if (successor != null) { ProcessSuccessor(fragmentReference, clonedFragment, etlSinkNode, successor); } } } } } }