private static void BrowseTables(Table table, DatabaseDictionary <TableID, Table> seenTables, DatabaseDictionary <TableID, Table> notSeen, List <Table> cluster) { cluster.Add(table); notSeen.Remove(table); seenTables.Add(table, table); foreach (var reference in table.References.Concat(table.ReferencedBy)) { if (seenTables.ContainsKey(reference) || !SchemaID.SchemaEquals(reference.Schema, table.Schema)) { continue; } else { BrowseTables(reference, seenTables, notSeen, cluster); } } }
public override void Execute(Database database, IIssueCollector issueCollector, IProviderCollection providers) { foreach (var schema in database.Schemas) { if (!schema.Tables.Any(t => t.ForeignKeys.Count > 0)) { Issue s = new Issue(this, Severity.Critical); s.Name = "No Foreign Keys"; s.Description = new Description("The schema '{0}' has no foreign keys", schema.SchemaName); s.Context = new SchemaContext(schema); issueCollector.ReportIssue(s); continue; } DatabaseDictionary <TableID, Table> seenTables = DictionaryFactory.CreateTableID <Table>(); DatabaseDictionary <TableID, Table> notSeen = DictionaryFactory.CreateTableID <Table>(); foreach (var t in schema.Tables) { notSeen.Add(t, t); } List <List <Table> > clusters = new List <List <Table> >(); while (notSeen.Count > 0) { var table = notSeen.First().Value; var cluster = new List <Table>(schema.Tables.Count); BrowseTables(table, seenTables, notSeen, cluster); clusters.Add(cluster); } foreach (var cluster in clusters) { if (cluster.Count == 1) { Issue issue = new Issue(this, this.DefaultSeverity.Value) { Context = new TableContext(cluster[0]), Name = "Table Island", Description = new Description("Table {0} does not reference anything and is not referenced by anything", cluster[0]), }; issueCollector.ReportIssue(issue); } else { if (cluster.Count > schema.Tables.Count * this.MaxFractionTables.Value / 100f || schema.Tables.Count > this.MaxTableIslandCount.Value) { continue; } string tableList = String.Join(", ", cluster.Select(c => c.TableName)); if (tableList.Length > 20) { tableList = tableList.Substring(0, 20) + "..."; } Issue issue = new Issue(this, LargeTableIslandSeverity.Value) { Context = IssueContext.Create(cluster), Name = "Table Island", Description = new Description("There is a table island containing {0} tables: {1}", cluster.Count, tableList), ExtendedDescription = new Description("Tables: {0}", cluster), }; issueCollector.ReportIssue(issue); } } } }
public override void Execute(Database database, IProviderCollection providers) { double damping = 0.85; DatabaseDictionary <TableID, DoubleWrapper> ranks = DictionaryFactory.CreateTableID <DoubleWrapper>(); DatabaseDictionary <TableID, DoubleWrapper> rankCalculator = DictionaryFactory.CreateTableID <DoubleWrapper>(); DatabaseDictionary <TableID, Table[]> neighborMatrix = DictionaryFactory.CreateTableID <Table[]>(); var initialRank = 1f / database.Tables.Count; foreach (var table in database.Tables) { ranks.Add(table, new DoubleWrapper { Value = 1 }); var referencedBy = new List <Table>(); foreach (var fkTable in table.ReferencedBy) { foreach (var foreignKey in fkTable.ForeignKeys) { if (foreignKey.PKTable.Equals(table)) { referencedBy.Add(fkTable); } } } neighborMatrix.Add(table, referencedBy.ToArray()); } foreach (var tableID in ranks.Keys) { rankCalculator[tableID] = new DoubleWrapper { Value = 0 }; ranks[tableID] = new DoubleWrapper { Value = 0 }; } for (int i = 0; i < 100; i++) { double error = 0; foreach (var tableID in ranks.Keys) { double value = 0; var references = neighborMatrix[tableID]; foreach (var reference in references) { var referenceRank = ranks[reference]; value += referenceRank.Value / reference.ForeignKeys.Count; } double newRank; rankCalculator[tableID].Value = newRank = value * damping + initialRank * (1 - damping); error += Math.Abs(ranks[tableID].Value - newRank); } { var tmp = rankCalculator; rankCalculator = ranks; ranks = tmp; } if (error < 0.001) { break; } } double sum = 0; foreach (var key in ranks.Keys) { sum += ranks[key].Value; } foreach (var key in ranks.Keys) { _ranks[key] = ranks[key].Value / sum * 100; } }