Пример #1
0
 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);
         }
     }
 }
Пример #2
0
        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);
                    }
                }
            }
        }
Пример #3
0
        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;
            }
        }