Permalink
Browse files

broke the API for tab completion into separate endpoints for package …

…IDs and package versions; fixed SQL connection string I accidentally changed
  • Loading branch information...
1 parent c401731 commit fffe9d3bbf1a057646e5b39a69142bb1f43c05d9 @half-ogre half-ogre committed Jun 4, 2012
@@ -101,7 +101,7 @@ public void WillPushTheCuratedFeedNameIntoTheViewBagAndShowTheCreateCuratedPacka
{
var controller = new TestableCuratedPackagesController();
controller.StubCuratedFeed.Name = "theCuratedFeedName";
- controller.StubPackageRegistrationByIdQry.Setup(stub => stub.Execute(It.IsAny<string>(), It.IsAny<bool>())).Returns((PackageRegistration)null);
+ controller.StubPackageRegistrationByIdQry.Setup(stub => stub.Execute(It.IsAny<string>(), It.IsAny<bool>(), It.IsAny<bool>())).Returns((PackageRegistration)null);
var result = controller.PostCuratedPackages("aFeedName", new CreateCuratedPackageRequest()) as ViewResult;
@@ -150,7 +150,7 @@ public void WillShowAnErrorWhenThePackageHasAlreadyBeenCurated()
var controller = new TestableCuratedPackagesController();
controller.StubCuratedFeed.Name = "theCuratedFeedName";
controller.StubCuratedFeed.Packages.Add(new CuratedPackage{ PackageRegistration = new PackageRegistration{ Key = 42 } });
- controller.StubPackageRegistrationByIdQry.Setup(stub => stub.Execute(It.IsAny<string>(), It.IsAny<bool>())).Returns((new PackageRegistration{ Key = 42 }));
+ controller.StubPackageRegistrationByIdQry.Setup(stub => stub.Execute(It.IsAny<string>(), It.IsAny<bool>(), It.IsAny<bool>())).Returns((new PackageRegistration { Key = 42 }));
var result = controller.PostCuratedPackages("theCuratedFeedName", new CreateCuratedPackageRequest()) as ViewResult;
@@ -168,7 +168,7 @@ public TestableCuratedPackagesController()
.Setup(stub => stub.Execute(It.IsAny<string>(), It.IsAny<bool>()))
.Returns(StubCuratedFeed);
StubPackageRegistrationByIdQry
- .Setup(stub => stub.Execute(It.IsAny<string>(), It.IsAny<bool>()))
+ .Setup(stub => stub.Execute(It.IsAny<string>(), It.IsAny<bool>(), It.IsAny<bool>()))
.Returns(StubPackageRegistration);
}
}
@@ -451,7 +451,7 @@ void WillRemoveTheCachedPackagesTabCompletionInfo()
nugetPackage.Object,
currentUser);
- stubCache.Verify(stub => stub.Remove(Constants.PackagesTabCompletionInfoCacheKey));
+ stubCache.Verify(stub => stub.Remove(Constants.PackageIdsCacheKey));
}
}
@@ -61,6 +61,16 @@ public partial class ApiController {
public System.Web.Mvc.ActionResult PublishPackage() {
return new T4MVC_ActionResult(Area, Name, ActionNames.PublishPackage);
}
+ [NonAction]
+ [GeneratedCode("T4MVC", "2.0"), DebuggerNonUserCode]
+ public System.Web.Mvc.ActionResult GetPackageIds() {
+ return new T4MVC_ActionResult(Area, Name, ActionNames.GetPackageIds);
+ }
+ [NonAction]
+ [GeneratedCode("T4MVC", "2.0"), DebuggerNonUserCode]
+ public System.Web.Mvc.ActionResult GetPackageVersions() {
+ return new T4MVC_ActionResult(Area, Name, ActionNames.GetPackageVersions);
+ }
[GeneratedCode("T4MVC", "2.0"), DebuggerNonUserCode]
public ApiController Actions { get { return MVC.Api; } }
@@ -81,7 +91,8 @@ public class ActionNamesClass {
public readonly string CreatePackagePost = "PushPackageApi";
public readonly string DeletePackage = "DeletePackageApi";
public readonly string PublishPackage = "PublishPackageApi";
- public readonly string GetPackagesTabCompletionInfo = "PackagesTabCompletionInfo";
+ public readonly string GetPackageIds = "PackageIDs";
+ public readonly string GetPackageVersions = "PackageVersions";
}
@@ -145,8 +156,17 @@ public class T4MVC_ApiController: NuGetGallery.ApiController {
return callInfo;
}
- public override System.Web.Mvc.ActionResult GetPackagesTabCompletionInfo() {
- var callInfo = new T4MVC_ActionResult(Area, Name, ActionNames.GetPackagesTabCompletionInfo);
+ public override System.Web.Mvc.ActionResult GetPackageIds(string partialId, bool? includePrerelease) {
+ var callInfo = new T4MVC_ActionResult(Area, Name, ActionNames.GetPackageIds);
+ callInfo.RouteValueDictionary.Add("partialId", partialId);
+ callInfo.RouteValueDictionary.Add("includePrerelease", includePrerelease);
+ return callInfo;
+ }
+
+ public override System.Web.Mvc.ActionResult GetPackageVersions(string id, bool? includePrerelease) {
+ var callInfo = new T4MVC_ActionResult(Area, Name, ActionNames.GetPackageVersions);
+ callInfo.RouteValueDictionary.Add("id", id);
+ callInfo.RouteValueDictionary.Add("includePrerelease", includePrerelease);
return callInfo;
}
@@ -200,9 +200,14 @@ public static void RegisterRoutes(RouteCollection routes)
// V2 routes
routes.MapRoute(
- "v2PackagesTabCompletionInfo",
- "api/v2/packages-tab-completion-info",
- MVC.Api.GetPackagesTabCompletionInfo());
+ "v2PackageIds",
+ "api/v2/package-ids",
+ MVC.Api.GetPackageIds());
+
+ routes.MapRoute(
+ "v2PackageVersions",
+ "api/v2/package-versions/{id}",
+ MVC.Api.GetPackageVersions());
routes.MapServiceRoute(
RouteName.V2ApiCuratedFeed,
View
@@ -29,6 +29,7 @@ public static class Constants
public const string UploadFileNameTemplate = "{0}{1}";
public const string UploadsFolderName = "uploads";
public const string NuGetCommandLinePackageId = "NuGet.CommandLine";
- public const string PackagesTabCompletionInfoCacheKey = "PackageTabCompletionInfo";
+ public const string PackageIdsCacheKey = "PackageIds";
+ public const string PackageVersionsCacheKeyFormat = "PackageVersions.{0}";
}
}
@@ -1,8 +1,10 @@
using System;
+using System.Collections.Generic;
using System.Globalization;
using System.IO;
using System.Linq;
using System.Net;
+using System.Runtime.Serialization;
using System.Web.Mvc;
using System.Web.UI;
using NuGet;
@@ -30,8 +32,8 @@ public partial class ApiController : AppController
[ActionName("GetPackageApi"), HttpGet]
public virtual ActionResult GetPackage(string id, string version)
{
- // if the version is null, the user is asking for the latest version. Presumably they don't want pre release versions.
- // The allow prerelease flag is ignored if both id and version are specified.
+ // if the version is null, the user is asking for the latest version. Presumably they don't want includePrerelease release versions.
+ // The allow prerelease flag is ignored if both partialId and version are specified.
var package = packageSvc.FindPackageByIdAndVersion(id, version, allowPrerelease: false);
if (package == null)
@@ -72,7 +74,7 @@ public virtual ActionResult VerifyPackageKey(string apiKey, string id, string ve
if (!String.IsNullOrEmpty(id))
{
- // If the id is present, then verify that the user has permission to push for the specific Id \ version combination.
+ // If the partialId is present, then verify that the user has permission to push for the specific Id \ version combination.
var package = packageSvc.FindPackageByIdAndVersion(id, version);
if (package == null)
return new HttpStatusCodeWithBodyResult(HttpStatusCode.NotFound, string.Format(CultureInfo.CurrentCulture, Strings.PackageWithIdAndVersionNotFound, id, version));
@@ -110,7 +112,7 @@ private ActionResult CreatePackageInternal(string apiKey)
var packageToPush = ReadPackageFromRequest();
- // Ensure that the user can push packages for this id.
+ // Ensure that the user can push packages for this partialId.
var packageRegistration = packageSvc.FindPackageRegistrationById(packageToPush.Id);
if (packageRegistration != null)
{
@@ -190,45 +192,93 @@ protected internal virtual IPackage ReadPackageFromRequest()
return new ZipPackage(stream);
}
- [ActionName("PackagesTabCompletionInfo"), HttpGet]
- public virtual ActionResult GetPackagesTabCompletionInfo()
- {
- var cache = GetService<ICache>();
- var packageRegistrations = cache.Get(Constants.PackagesTabCompletionInfoCacheKey) as PackageTabCompletionInfo[];
- if (packageRegistrations == null)
- {
- packageRegistrations = GetService<IAllPackageRegistrationsQuery>()
- .Execute()
- .ToArray()
- .Select(pr => new PackageTabCompletionInfo
- {
- Id = pr.Id,
- Versions = pr.Packages.Select(p => new VersionTabCompletionInfo
- {
- IsLatestStable = p.IsLatestStable,
- IsPrerelease = p.IsPrerelease,
- Version = p.Version
- }).ToArray()
- })
- .ToArray();
- cache.Add(Constants.PackagesTabCompletionInfoCacheKey, packageRegistrations);
- }
- return new JsonNetResult(packageRegistrations);
- }
-
- [Serializable]
- class PackageTabCompletionInfo
- {
- public string Id { get; set; }
- public VersionTabCompletionInfo[] Versions { get; set; }
- }
-
- [Serializable]
- class VersionTabCompletionInfo
- {
- public bool IsLatestStable { get; set; }
- public bool IsPrerelease { get; set; }
- public string Version { get; set; }
- }
+ [ActionName("PackageIDs"), HttpGet]
+ public virtual ActionResult GetPackageIds(
+ string partialId,
+ bool? includePrerelease)
+ {
+ var cache = GetService<ICache>();
+ var packageIds = cache.Get(Constants.PackageIdsCacheKey) as List<PackageId>;
+ if (packageIds == null)
+ {
+ packageIds = GetService<IAllPackageRegistrationsQuery>()
+ .Execute()
+ .Where(pr => pr.Packages.Any(p => p.Listed))
+ .OrderBy(pr => pr.DownloadCount)
+ .Select(pr => new PackageId
+ {
+ Id = pr.Id,
+ IsPrereleaseOnly = !pr.Packages.Any(p => p.IsLatestStable)
+ })
+ .ToList();
+ cache.Add(Constants.PackageIdsCacheKey, packageIds);
+ }
+ var query = packageIds.AsQueryable();
+ if (!includePrerelease.HasValue || !includePrerelease.Value)
+ query = query.Where(x => !x.IsPrereleaseOnly);
+ if (!string.IsNullOrWhiteSpace(partialId))
+ query = query.Where(x => x.Id.StartsWith(partialId, StringComparison.OrdinalIgnoreCase));
+ var result = query
+ .Take(30)
+ .Select(x => x.Id)
+ .ToArray();
+ return new JsonNetResult(result);
+ }
+
+ [ActionName("PackageVersions"), HttpGet]
+ public virtual ActionResult GetPackageVersions(
+ string id,
+ bool? includePrerelease)
+ {
+ if (string.IsNullOrWhiteSpace(id))
+ return new JsonNetResult(new string[] {});
+ var cache = GetService<ICache>();
+ var cacheKey = string.Format(Constants.PackageVersionsCacheKeyFormat, id);
+ var packageVersions = cache.Get(cacheKey) as PackageVersions;
+ if (packageVersions == null)
+ {
+ var packageRegistration = GetService<IPackageRegistrationByIdQuery>().Execute(
+ id,
+ includePackages: true,
+ includeOwners: false);
+ packageVersions = new PackageVersions
+ {
+ Id = packageRegistration.Id,
+ Versions = packageRegistration.Packages
+ .Select(p => new PackageVersion
+ {
+ Version = p.Version,
+ IsPrerelease = p.IsPrerelease
+ })
+ .ToList()
+ };
+ cache.Add(cacheKey, packageVersions);
+ }
+ var query = packageVersions.Versions.AsQueryable();
+ if (!includePrerelease.HasValue || !includePrerelease.Value)
+ query = query.Where(x => !x.IsPrerelease);
+ var result = query
+ .Select(x => x.Version)
+ .ToArray();
+ return new JsonNetResult(result);
+ }
+
+ class PackageId
+ {
+ public string Id { get; set; }
+ public bool IsPrereleaseOnly { get; set; }
+ }
+
+ class PackageVersions
+ {
+ public string Id { get; set; }
+ public List<PackageVersion> Versions { get; set; }
+ }
+
+ class PackageVersion
+ {
+ public bool IsPrerelease { get; set; }
+ public string Version { get; set; }
+ }
}
}
@@ -7,6 +7,7 @@ public interface IPackageRegistrationByIdQuery
{
PackageRegistration Execute(
string id,
+ bool includePackages = false,
bool includeOwners = true);
}
@@ -21,10 +22,14 @@ public PackageRegistrationByIdQuery(IEntitiesContext entities)
public PackageRegistration Execute(
string id,
+ bool includePackages = false,
bool includeOwners = true)
{
var qry = _entities.PackageRegistrations.AsQueryable();
+ if (includePackages)
+ qry = qry.Include(packageRegistration => packageRegistration.Packages);
+
if (includeOwners)
qry = qry.Include(packageRegistration => packageRegistration.Owners);
@@ -56,7 +56,8 @@ public Package CreatePackage(IPackage nugetPackage, User currentUser)
packageRegistrationRepo.CommitChanges();
packageFileSvc.SavePackageFile(package, stream);
tx.Complete();
- cache.Remove(Constants.PackagesTabCompletionInfoCacheKey);
+ cache.Remove(Constants.PackageIdsCacheKey);
+ cache.Remove(string.Format(Constants.PackageVersionsCacheKeyFormat, packageRegistration.Id));
}
}
View
@@ -26,7 +26,7 @@
<add key="Configuration:SiteRoot" value="http://nuget.org/" />
</appSettings>
<connectionStrings>
- <add name="NuGetGallery" connectionString="Data Source=(local);Initial Catalog=NuGetGallery;Integrated Security=SSPI" providerName="System.Data.SqlClient" />
+ <add name="NuGetGallery" connectionString="Data Source=.\SQLEXPRESS;Initial Catalog=NuGetGallery;Integrated Security=SSPI" providerName="System.Data.SqlClient" />
</connectionStrings>
<elmah>
<security allowRemoteAccess="true" />
View
@@ -133,6 +133,7 @@
<Reference Include="System.Data.Entity" />
<Reference Include="System.Data.Services" />
<Reference Include="System.Data.Services.Client" />
+ <Reference Include="System.Runtime.Serialization" />
<Reference Include="System.ServiceModel" />
<Reference Include="System.ServiceModel.Activation" />
<Reference Include="System.ServiceModel.Web" />

0 comments on commit fffe9d3

Please sign in to comment.