diff --git a/java/google/registry/rdap/RdapActionBase.java b/java/google/registry/rdap/RdapActionBase.java index 745e57298..d83118d1e 100644 --- a/java/google/registry/rdap/RdapActionBase.java +++ b/java/google/registry/rdap/RdapActionBase.java @@ -168,7 +168,9 @@ public abstract class RdapActionBase implements Runnable { * * @param clazz the type of resource to be queried * @param filterField the database field of interest - * @param partialStringQuery the details of the search string + * @param partialStringQuery the details of the search string; if there is no wildcard, an + * equality query is used; if there is a wildcard, a range query is used instead; there + * should not be a search suffix * @param resultSetMaxSize the maximum number of results to return * @return the results of the query */ @@ -177,12 +179,20 @@ public abstract class RdapActionBase implements Runnable { String filterField, RdapSearchPattern partialStringQuery, int resultSetMaxSize) { - checkArgument(partialStringQuery.getHasWildcard(), "search string doesn't have wildcard"); - return ofy().load() - .type(clazz) - .filter(filterField + " >=", partialStringQuery.getInitialString()) - .filter(filterField + " <", partialStringQuery.getNextInitialString()) - .filter("deletionTime", END_OF_TIME) - .limit(resultSetMaxSize); + if (!partialStringQuery.getHasWildcard()) { + return ofy().load() + .type(clazz) + .filter(filterField, partialStringQuery.getInitialString()) + .filter("deletionTime", END_OF_TIME) + .limit(resultSetMaxSize); + } else { + checkArgument(partialStringQuery.getSuffix() == null, "Unexpected search string suffix"); + return ofy().load() + .type(clazz) + .filter(filterField + " >=", partialStringQuery.getInitialString()) + .filter(filterField + " <", partialStringQuery.getNextInitialString()) + .filter("deletionTime", END_OF_TIME) + .limit(resultSetMaxSize); + } } } diff --git a/java/google/registry/rdap/RdapEntitySearchAction.java b/java/google/registry/rdap/RdapEntitySearchAction.java index 12ccf97b7..82270be6e 100644 --- a/java/google/registry/rdap/RdapEntitySearchAction.java +++ b/java/google/registry/rdap/RdapEntitySearchAction.java @@ -125,41 +125,29 @@ public class RdapEntitySearchAction extends RdapActionBase { */ private ImmutableList> searchByName(final RdapSearchPattern partialStringQuery, DateTime now) { - // Handle queries without a wildcard -- load by name, which may not be unique. - if (!partialStringQuery.getHasWildcard()) { - Registrar registrar = Registrar.loadByName(partialStringQuery.getInitialString()); - return makeSearchResults( - ofy().load() - .type(ContactResource.class) - .filter("searchName", partialStringQuery.getInitialString()) - .filter("deletionTime", END_OF_TIME) - .limit(rdapResultSetMaxSize) - .list(), - (registrar == null) - ? ImmutableList.of() : ImmutableList.of(registrar), - now); - // Handle queries with a wildcard, but no suffix. For contact resources, the deletion time will - // always be END_OF_TIME for non-deleted records; unlike domain resources, we don't need to - // worry about deletion times in the future. That allows us to use an equality query for the - // deletion time. - } else if (partialStringQuery.getSuffix() == null) { - return makeSearchResults( - ofy().load() - .type(ContactResource.class) - .filter("searchName >=", partialStringQuery.getInitialString()) - .filter("searchName <", partialStringQuery.getNextInitialString()) - .filter("deletionTime", END_OF_TIME) - .limit(rdapResultSetMaxSize) - .list(), - ImmutableList.copyOf(Registrar.loadByNameRange( - partialStringQuery.getInitialString(), - partialStringQuery.getNextInitialString(), - rdapResultSetMaxSize)), - now); // Don't allow suffixes in entity name search queries. - } else { + if (!partialStringQuery.getHasWildcard() && (partialStringQuery.getSuffix() != null)) { throw new UnprocessableEntityException("Suffixes not allowed in entity name searches"); } + // Get the registrar matches, depending on whether there's a wildcard. + ImmutableList registrarMatches; + if (!partialStringQuery.getHasWildcard()) { + Registrar registrar = Registrar.loadByName(partialStringQuery.getInitialString()); + registrarMatches = (registrar == null) + ? ImmutableList.of() + : ImmutableList.of(registrar); + } else { + registrarMatches = ImmutableList.copyOf(Registrar.loadByNameRange( + partialStringQuery.getInitialString(), + partialStringQuery.getNextInitialString(), + rdapResultSetMaxSize)); + } + // Get the contact matches and return the results. + return makeSearchResults( + queryUndeleted( + ContactResource.class, "searchName", partialStringQuery, rdapResultSetMaxSize).list(), + registrarMatches, + now); } /** Searches for entities by handle, returning a JSON array of entity info maps. */