/// <summary> /// Get routines like stored procedures and functions /// </summary> /// <param name="result">data analysis result</param> /// <returns>routine dictionary</returns> protected IReadOnlyDictionary <string, IRoutine> GetRoutines(IDatabaseAnalysisResult result) { var routineCollection = this.ExecuteReader( "GetRoutines", reader => { var routines = new Dictionary <string, IRoutine>(StringComparer.OrdinalIgnoreCase); var resolver = this.ResolverFactory.GetResolver <IRoutine>(); while (reader.Read()) { var routine = resolver.Resolve(); routine.SchemaName = GetData <string>(reader, "ROUTINE_SCHEMA"); routine.RoutineName = GetData <string>(reader, "ROUTINE_NAME"); routine.RoutineType = GetData <string>(reader, "ROUTINE_TYPE"); routine.DataTypeName = GetData <string>(reader, "DATA_TYPE"); routine.StringSize = GetData <int?>(reader, "CHARACTER_MAXIMUM_LENGTH"); routine.NumericPrecision = GetData <int?>(reader, "NUMERIC_PRECISION"); routine.NumericScale = GetData <int?>(reader, "NUMERIC_SCALE"); routine.SoruceCode = GetData <string>(reader, "ROUTINE_DEFINITION"); routine.DisplayName = GetDisplayName(routine.SchemaName, routine.RoutineName); routines.Add(routine.DisplayName, routine); } return(routines); }); var collection = new Dictionary <string, Dictionary <string, IRoutine> >(StringComparer.OrdinalIgnoreCase); Dictionary <string, IRoutine> currentRoutines; foreach (var pair in routineCollection) { var typeName = pair.Value.RoutineType; if (!collection.TryGetValue(typeName, out currentRoutines)) { currentRoutines = new Dictionary <string, IRoutine>(StringComparer.OrdinalIgnoreCase); collection.Add(typeName, currentRoutines); } currentRoutines.Add(pair.Key, pair.Value); } if (collection.TryGetValue("PROCEDURE", out currentRoutines)) { result.StoredProcedures = currentRoutines; } if (collection.TryGetValue("FUNCTION", out currentRoutines)) { result.Functions = currentRoutines; } return(routineCollection); }
/// <summary> /// Format output /// </summary> /// <param name="title">document title</param> /// <param name="analysisResult">analysis result</param> /// <param name="outputSteram">output stream</param> public void Format(string title, IDatabaseAnalysisResult analysisResult, Stream outputSteram) { analysisResult.Title = title; var engine = engineLoader.Value; engine.Model = analysisResult; engine.Execute(); using (var writer = new StreamWriter(outputSteram)) { writer.Write(engine.Buffer.ToString()); } engine.Buffer.Clear(); }
/// <summary> /// Get table or view by display name /// </summary> /// <param name="result">analysis result</param> /// <param name="displayName">display name</param> /// <returns>table or view if found</returns> private static IBaseContainer GetContainer(IDatabaseAnalysisResult result, string displayName) { ITable table; if ((result.Tables != null) && result.Tables.TryGetValue(displayName, out table)) { return(table); } IView view; if ((result.Views != null) && result.Views.TryGetValue(displayName, out view)) { return(view); } return(null); }
/// <summary> /// Update references /// </summary> /// <param name="result">database analysis result</param> /// <param name="routines">routine collection</param> protected void UpdateReferences(IDatabaseAnalysisResult result, IReadOnlyDictionary <string, IRoutine> routines) { var resolver = this.ResolverFactory.GetResolver <IReference>(); // process foreign key references foreach (var table in result.Tables.Values) { if (!table.ForeignKeys.IsReadOnlyNullOrEmpty()) { foreach (var foreignKey in table.ForeignKeys) { var referencedTable = foreignKey.Table; if (referencedTable.References == null) { referencedTable.References = new SortedList <string, IReference>(); } var reference = resolver.Resolve(); reference.EntityDisplayName = table.DisplayName; reference.EntitySchema = table.SchemaName; reference.EntityName = table.Name; reference.EntityType = TableTypeShortName; var referenceKey = GetReferenceKey(reference); referencedTable.References[referenceKey] = reference; } } } // process cross entity references this.ExecuteReader <object>( "GetReferences", reader => { while (reader.Read()) { var referenceShema = GetData <string>(reader, "REFERENCE_ENTITY_SCHEMA"); var referenceName = GetData <string>(reader, "REFERENCE_ENTITY_NAME"); var referenceType = GetData <string>(reader, "REFERENCE_ENTITY_TYPE"); var referenceDisplayName = GetDisplayName(referenceShema, referenceName); var reference = resolver.Resolve(); reference.EntityDisplayName = GetDisplayName(referenceShema, referenceName); reference.EntitySchema = GetData <string>(reader, "REFERENCE_ENTITY_SCHEMA"); reference.EntityName = GetData <string>(reader, "REFERENCE_ENTITY_NAME"); reference.EntityType = GetData <string>(reader, "REFERENCE_ENTITY_TYPE"); var referenceKey = GetReferenceKey(reference); switch (referenceType.ToUpperInvariant()) { case TableTypeShortName: ITable table; if (result.Tables.IsReadOnlyNullOrEmpty() || !result.Tables.TryGetValue(referenceDisplayName, out table)) { var errorMessage = string.Format( CultureInfo.InvariantCulture, "Could not find table \"{0}\" while building reference for \"{1}\"", referenceDisplayName, reference.EntityDisplayName); throw new ApplicationException(errorMessage); } if (table.References == null) { table.References = new SortedList <string, IReference>(); } table.References[referenceKey] = reference; break; case ProcedureTypeShortName: case FunctionTypeShortName: IRoutine routine; if (routines.IsReadOnlyNullOrEmpty() || !routines.TryGetValue(referenceDisplayName, out routine)) { var errorMessage = string.Format( CultureInfo.InvariantCulture, "Could not find routine \"{0}\" while building reference for \"{1}\"", referenceDisplayName, reference.EntityDisplayName); throw new ApplicationException(errorMessage); } if (routine.References == null) { routine.References = new SortedList <string, IReference>(); } routine.References[referenceKey] = reference; break; } } return(null); }); }
protected void UpdateViewColumnUsage(IDatabaseAnalysisResult result) { this.ExecuteReader <object>( "GetViewColumnUsage", reader => { var referenceResolver = this.ResolverFactory.GetResolver <IReference>(); var containerNames = new HashSet <string>(StringComparer.OrdinalIgnoreCase); IView view = null; List <IColumn> externalColumns = null; while (reader.Read()) { var viewSchema = GetData <string>(reader, "VIEW_SCHEMA"); var viewName = GetData <string>(reader, "VIEW_NAME"); var columnName = GetData <string>(reader, "COLUMN_NAME"); var tableSchema = GetData <string>(reader, "TABLE_SCHEMA"); var tableName = GetData <string>(reader, "TABLE_NAME"); if ((view == null) || !view.SchemaName.Equals(viewSchema, StringComparison.OrdinalIgnoreCase) || !view.Name.Equals(viewName, StringComparison.OrdinalIgnoreCase)) { var viewDisplayName = GetDisplayName(viewSchema, viewName); if ((result.Views == null) || !result.Views.TryGetValue(viewDisplayName, out view)) { var errorMessage = string.Format( CultureInfo.InvariantCulture, "Could not found view \"{0}\" for usage updating", viewDisplayName); throw new ApplicationException(errorMessage); } containerNames.Clear(); externalColumns = new List <IColumn>(); view.ExternalColumns = externalColumns; } var containerDisplayName = GetDisplayName(tableSchema, tableName); var container = GetContainer(result, containerDisplayName); if (container == null) { var errorMessage = string.Format( CultureInfo.InvariantCulture, "Could not found container \"{0}\" during usage updating for view \"{1}\"", containerDisplayName, view.DisplayName); throw new ApplicationException(errorMessage); } var externalColumn = container.Columns.FirstOrDefault(c => c.Name.Equals(columnName, StringComparison.OrdinalIgnoreCase)); if (externalColumn == null) { var errorMessage = string.Format( CultureInfo.InvariantCulture, "Could not found column \"{0}\" in container \"{1}\" during usage updating for view \"{2}\"", columnName, containerDisplayName, view.DisplayName); throw new ApplicationException(errorMessage); } externalColumns.Add(externalColumn); if (!containerNames.Contains(containerDisplayName)) { var reference = referenceResolver.Resolve(); reference.EntityDisplayName = view.DisplayName; reference.EntitySchema = view.SchemaName; reference.EntityName = view.Name; reference.EntityType = "View"; var referenceKey = GetReferenceKey(reference); if (container.References == null) { container.References = new SortedList <string, IReference>(StringComparer.OrdinalIgnoreCase); } container.References[referenceKey] = reference; containerNames.Add(containerDisplayName); } } return(null); }); }