protected override Expression VisitBinary(BinaryExpression node)
        {
            // Change equality comparisons on Version to normalized comparisons on NormalizedVersion
            if (node.NodeType == ExpressionType.Equal)
            {
                // Figure out which side is the target
                ConstantExpression constSide = (node.Left as ConstantExpression) ?? (node.Right as ConstantExpression);
                if (constSide != null && constSide.Type == typeof(string))
                {
                    MemberExpression memberSide = (node.Right as MemberExpression) ?? (node.Left as MemberExpression);
                    if (memberSide != null && memberSide.Member == _versionMember)
                    {
                        // We have a "Package.Version == <constant>" expression!

                        // Transform the constant version into a normalized version
                        string newVersion = NuGetVersionNormalizer.Normalize((string)constSide.Value);

                        // Create a new expression that checks the new constant against NormalizedVersion instead
                        return(Expression.MakeBinary(
                                   ExpressionType.Equal,
                                   left: Expression.Constant(newVersion),
                                   right: Expression.MakeMemberAccess(memberSide.Expression, _normalizedVersionMember)));
                    }
                }
            }
            return(node);
        }
 public override string GetPath()
 {
     return(String.Format(
                "{0}/{1}",
                Id.ToLowerInvariant(),
                NuGetVersionNormalizer.Normalize(Version).ToLowerInvariant()));
 }
Пример #3
0
        public override void ExecuteCommand()
        {
            WithConnection((c, db) =>
            {
                Log.Trace("Collecting list of packages...");
                var packages = db.Query <Package>(@"
                    SELECT pr.Id, p.[Key], p.Version
                    FROM Packages p
                        INNER JOIN PackageRegistrations pr ON pr.[Key] = p.PackageRegistrationKey
                    WHERE p.NormalizedVersion IS NULL")
                               .ToList();
                Log.Trace("Collected {0} packages", packages.Count);

                DataTable output;
                int count = 0;
                WithTableType(c, "Temp_NormalizePackageVersionsInputType", "PackageKey int, NormalizedVersion nvarchar(64)", () =>
                {
                    // Build a table to hold the new data
                    var updateTable = new DataTable();
                    updateTable.Columns.Add(new DataColumn("PackageKey", typeof(int)));
                    updateTable.Columns.Add(new DataColumn("NormalizedVersion", typeof(string)));
                    foreach (var package in packages)
                    {
                        string normalized = NuGetVersionNormalizer.Normalize(package.Version);
                        var row           = updateTable.NewRow();
                        row.SetField("PackageKey", package.Key);
                        row.SetField("NormalizedVersion", normalized);
                        updateTable.Rows.Add(row);
                    }

                    // Run the query with the table parameter
                    var cmd         = c.CreateCommand();
                    cmd.CommandType = CommandType.Text;
                    cmd.CommandText = WhatIf ? WhatIfQuery : CommitQuery;
                    cmd.Parameters.Add(new SqlParameter("@updateTable", SqlDbType.Structured)
                    {
                        TypeName = "Temp_NormalizePackageVersionsInputType",
                        Value    = updateTable
                    });
                    Log.Trace("Updating Database...");
                    var reader = cmd.ExecuteReader();
                    Log.Trace("Database Update Complete");

                    // Load the results into a datatable and render them
                    output = new DataTable();
                    output.Load(reader);
                    foreach (var row in output.Rows.Cast <DataRow>())
                    {
                        string version    = row.Field <string>("Version");
                        string normalized = row.Field <string>("NormalizedVersion");
                        if (!String.Equals(version, normalized, StringComparison.Ordinal))
                        {
                            count++;
                        }
                    }
                    Log.Info("Updated {0} packages", count);
                });
            });
        }
        private static Tuple <Target, string> ExtractComparison(BinaryExpression binExpr)
        {
            // p => <constant> == p.<property>
            if (binExpr.NodeType != ExpressionType.Equal)
            {
                return(null);
            }

            // Get the two sides, we don't care which side is left and which is right.
            ConstantExpression constSide = (binExpr.Left as ConstantExpression) ?? (binExpr.Right as ConstantExpression);

            if (constSide == null || constSide.Type != typeof(string))
            {
                return(null);
            }

            MemberExpression memberSide = (binExpr.Right as MemberExpression) ?? (binExpr.Left as MemberExpression);

            if (memberSide == null)
            {
                // That did not work... This may be Web API OData wrapping our expression
                UnaryExpression temp = binExpr.Left as UnaryExpression;
                if (temp != null)
                {
                    memberSide = temp.Operand as MemberExpression;
                }

                // Not found - for real.
                if (memberSide == null)
                {
                    return(null);
                }
            }

            // Check if it's a known member comparison
            if (memberSide.Member == NormalizedVersionMember)
            {
                return(Tuple.Create(Target.Version, (string)constSide.Value));
            }
            else if (memberSide.Member == VersionMember)
            {
                return(Tuple.Create(Target.Version, NuGetVersionNormalizer.Normalize((string)constSide.Value)));
            }
            else if (memberSide.Member == IdMember)
            {
                return(Tuple.Create(Target.Id, (string)constSide.Value));
            }

            return(null);
        }
Пример #5
0
            private static Tuple <Target, string> ExtractComparison(MethodCallExpression outerWhere)
            {
                // We expect to see an expression that looks like this:
                //  Queryable.Where(<nested expression>, p => <constant> == p.<property>);
                var arg = Unquote(outerWhere.Arguments[1]);

                if (arg.NodeType != ExpressionType.Lambda)
                {
                    return(null);
                }
                var lambda = arg as LambdaExpression; // p => <constant> == p.<property>

                if (lambda.Body.NodeType != ExpressionType.Equal)
                {
                    return(null);
                }
                var binExpr = lambda.Body as BinaryExpression; // <constant> == p.<property>

                // Get the two sides, we don't care which side is left and which is right.
                ConstantExpression constSide = (binExpr.Left as ConstantExpression) ?? (binExpr.Right as ConstantExpression);

                if (constSide == null || constSide.Type != typeof(string))
                {
                    return(null);
                }
                MemberExpression memberSide = (binExpr.Right as MemberExpression) ?? (binExpr.Left as MemberExpression);

                if (memberSide == null)
                {
                    return(null);
                }

                // Check if it's a known member comparison
                if (memberSide.Member == _normalizedVersionMember)
                {
                    return(Tuple.Create(Target.Version, (string)constSide.Value));
                }
                else if (memberSide.Member == _versionMember)
                {
                    return(Tuple.Create(Target.Version, NuGetVersionNormalizer.Normalize((string)constSide.Value)));
                }
                else if (memberSide.Member == _idMember)
                {
                    return(Tuple.Create(Target.Id, (string)constSide.Value));
                }
                return(null);
            }
Пример #6
0
        public override void ExecuteCommand()
        {
            using (var sqlConnection = new SqlConnection(ConnectionString.ConnectionString))
                using (var dbExecutor = new SqlExecutor(sqlConnection))
                {
                    sqlConnection.Open();

                    // Query for packages
                    Log.Info("Gathering list of packages...");
                    var packages = dbExecutor.Query <PackageSummary>(@"
                    SELECT p.[Key], p.PackageRegistrationKey, r.Id, p.Version, p.Hash, p.LastUpdated, p.Published, p.Listed, p.IsLatestStable
                    FROM   Packages p
                    INNER JOIN PackageRegistrations r ON p.PackageRegistrationKey = r.[Key]");

                    // Group by Id and and SemVer
                    Log.Info("Grouping by Package ID and Actual Version...");
                    var groups = packages.GroupBy(p => new { p.Id, Version = NuGetVersionNormalizer.Normalize(p.Version) });

                    // Find any groups with more than one entry
                    Log.Info("Finding Duplicates...");
                    var dups = groups.Where(g => g.Count() > 1);

                    // Print them out
                    int dupsUnlistedCount = 0;
                    int latestCount       = 0;
                    foreach (var dup in dups)
                    {
                        ProcessDuplicate(dup.Key.Id, dup.Key.Version, dup.ToList(), ref dupsUnlistedCount, ref latestCount);
                    }
                    var totalDupes = dups.Count();
                    Log.Info("Found {0} Packages with duplicates.", totalDupes);
                    Log.Info(" {0} of them have no listed duplicates.", dupsUnlistedCount);
                    Log.Info(" {0} of them have multiple listed duplicates.", totalDupes - dupsUnlistedCount);
                    if (latestCount > 0)
                    {
                        Log.Warn(" {0} of them are the latest version of the relevant package", latestCount);
                    }
                    else
                    {
                        Log.Info(" NONE of them are the latest version of the relevant package");
                    }
                }
        }
Пример #7
0
 public override string GetPath()
 {
     return($"{Id}/{NuGetVersionNormalizer.Normalize(Version)}"
            .ToLowerInvariant());
 }