mirror of
https://github.com/google/nomulus.git
synced 2025-07-08 20:23:24 +02:00
Convert CountDomainsCommand to tm (#1092)
* Convert CountDomainsCommand to tm As part of this, implement "select count(*)" queries in the QueryComposer. * Replaced kludgy trick for objectify count
This commit is contained in:
parent
48732c51e8
commit
4657be21b7
7 changed files with 54 additions and 16 deletions
|
@ -413,5 +413,10 @@ public class DatastoreTransactionManager implements TransactionManager {
|
||||||
public Stream<T> stream() {
|
public Stream<T> stream() {
|
||||||
return Streams.stream(buildQuery());
|
return Streams.stream(buildQuery());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public long count() {
|
||||||
|
return buildQuery().count();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -41,11 +41,11 @@ public class CriteriaQueryBuilder<T> {
|
||||||
}
|
}
|
||||||
|
|
||||||
private final CriteriaQuery<T> query;
|
private final CriteriaQuery<T> query;
|
||||||
private final Root<T> root;
|
private final Root<?> root;
|
||||||
private final ImmutableList.Builder<Predicate> predicates = new ImmutableList.Builder<>();
|
private final ImmutableList.Builder<Predicate> predicates = new ImmutableList.Builder<>();
|
||||||
private final ImmutableList.Builder<Order> orders = new ImmutableList.Builder<>();
|
private final ImmutableList.Builder<Order> orders = new ImmutableList.Builder<>();
|
||||||
|
|
||||||
private CriteriaQueryBuilder(CriteriaQuery<T> query, Root<T> root) {
|
private CriteriaQueryBuilder(CriteriaQuery<T> query, Root<?> root) {
|
||||||
this.query = query;
|
this.query = query;
|
||||||
this.root = root;
|
this.root = root;
|
||||||
}
|
}
|
||||||
|
@ -106,4 +106,13 @@ public class CriteriaQueryBuilder<T> {
|
||||||
query = query.select(root);
|
query = query.select(root);
|
||||||
return new CriteriaQueryBuilder<>(query, root);
|
return new CriteriaQueryBuilder<>(query, root);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** Creates a "count" query for the table for the class. */
|
||||||
|
public static <T> CriteriaQueryBuilder<Long> createCount(EntityManager em, Class<T> clazz) {
|
||||||
|
CriteriaBuilder builder = em.getCriteriaBuilder();
|
||||||
|
CriteriaQuery<Long> query = builder.createQuery(Long.class);
|
||||||
|
Root<T> root = query.from(clazz);
|
||||||
|
query = query.select(builder.count(root));
|
||||||
|
return new CriteriaQueryBuilder<>(query, root);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -700,7 +700,10 @@ public class JpaTransactionManagerImpl implements JpaTransactionManager {
|
||||||
|
|
||||||
private TypedQuery<T> buildQuery() {
|
private TypedQuery<T> buildQuery() {
|
||||||
CriteriaQueryBuilder<T> queryBuilder = CriteriaQueryBuilder.create(em, entityClass);
|
CriteriaQueryBuilder<T> queryBuilder = CriteriaQueryBuilder.create(em, entityClass);
|
||||||
|
return addCriteria(queryBuilder);
|
||||||
|
}
|
||||||
|
|
||||||
|
private <U> TypedQuery<U> addCriteria(CriteriaQueryBuilder<U> queryBuilder) {
|
||||||
for (WhereClause<?> pred : predicates) {
|
for (WhereClause<?> pred : predicates) {
|
||||||
pred.addToCriteriaQueryBuilder(queryBuilder);
|
pred.addToCriteriaQueryBuilder(queryBuilder);
|
||||||
}
|
}
|
||||||
|
@ -727,5 +730,11 @@ public class JpaTransactionManagerImpl implements JpaTransactionManager {
|
||||||
public Stream<T> stream() {
|
public Stream<T> stream() {
|
||||||
return buildQuery().getResultStream();
|
return buildQuery().getResultStream();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public long count() {
|
||||||
|
CriteriaQueryBuilder<Long> queryBuilder = CriteriaQueryBuilder.createCount(em, entityClass);
|
||||||
|
return addCriteria(queryBuilder).getSingleResult();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -88,6 +88,9 @@ public abstract class QueryComposer<T> {
|
||||||
/** Returns the results of the query as a stream. */
|
/** Returns the results of the query as a stream. */
|
||||||
public abstract Stream<T> stream();
|
public abstract Stream<T> stream();
|
||||||
|
|
||||||
|
/** Returns the number of results of the query. */
|
||||||
|
public abstract long count();
|
||||||
|
|
||||||
// We have to wrap the CriteriaQueryBuilder predicate factories in our own functions because at
|
// We have to wrap the CriteriaQueryBuilder predicate factories in our own functions because at
|
||||||
// the point where we pass them to the Comparator constructor, the compiler can't determine which
|
// the point where we pass them to the Comparator constructor, the compiler can't determine which
|
||||||
// of the overloads to use since there is no "value" object for context.
|
// of the overloads to use since there is no "value" object for context.
|
||||||
|
|
|
@ -14,12 +14,13 @@
|
||||||
|
|
||||||
package google.registry.tools;
|
package google.registry.tools;
|
||||||
|
|
||||||
import static google.registry.model.ofy.ObjectifyService.ofy;
|
|
||||||
import static google.registry.model.registry.Registries.assertTldsExist;
|
import static google.registry.model.registry.Registries.assertTldsExist;
|
||||||
|
import static google.registry.persistence.transaction.QueryComposer.Comparator;
|
||||||
|
import static google.registry.persistence.transaction.TransactionManagerFactory.tm;
|
||||||
|
import static google.registry.persistence.transaction.TransactionManagerUtil.transactIfJpaTm;
|
||||||
|
|
||||||
import com.beust.jcommander.Parameter;
|
import com.beust.jcommander.Parameter;
|
||||||
import com.beust.jcommander.Parameters;
|
import com.beust.jcommander.Parameters;
|
||||||
import com.google.common.collect.Iterables;
|
|
||||||
import google.registry.model.domain.DomainBase;
|
import google.registry.model.domain.DomainBase;
|
||||||
import google.registry.util.Clock;
|
import google.registry.util.Clock;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
@ -45,14 +46,12 @@ final class CountDomainsCommand implements CommandWithRemoteApi {
|
||||||
.forEach(tld -> System.out.printf("%s,%d\n", tld, getCountForTld(tld, now)));
|
.forEach(tld -> System.out.printf("%s,%d\n", tld, getCountForTld(tld, now)));
|
||||||
}
|
}
|
||||||
|
|
||||||
private int getCountForTld(String tld, DateTime now) {
|
private long getCountForTld(String tld, DateTime now) {
|
||||||
return Iterables.size(
|
return transactIfJpaTm(
|
||||||
ofy()
|
() ->
|
||||||
.load()
|
tm().createQueryComposer(DomainBase.class)
|
||||||
.type(DomainBase.class)
|
.where("tld", Comparator.EQ, tld)
|
||||||
.filter("tld", tld)
|
.where("deletionTime", Comparator.GT, now)
|
||||||
.filter("deletionTime >", now)
|
.count());
|
||||||
.chunkAll()
|
|
||||||
.keys());
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -111,6 +111,17 @@ public class QueryComposerTest {
|
||||||
.isEqualTo(alpha);
|
.isEqualTo(alpha);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestOfyAndSql
|
||||||
|
public void testCount() {
|
||||||
|
assertThat(
|
||||||
|
transactIfJpaTm(
|
||||||
|
() ->
|
||||||
|
tm().createQueryComposer(TestEntity.class)
|
||||||
|
.where("name", Comparator.GTE, "bravo")
|
||||||
|
.count()))
|
||||||
|
.isEqualTo(2L);
|
||||||
|
}
|
||||||
|
|
||||||
@TestOfyAndSql
|
@TestOfyAndSql
|
||||||
public void testGetSingleResult() {
|
public void testGetSingleResult() {
|
||||||
assertThat(
|
assertThat(
|
||||||
|
|
|
@ -19,12 +19,14 @@ import static google.registry.testing.DatabaseHelper.persistActiveDomain;
|
||||||
import static google.registry.testing.DatabaseHelper.persistDeletedDomain;
|
import static google.registry.testing.DatabaseHelper.persistDeletedDomain;
|
||||||
|
|
||||||
import google.registry.model.ofy.Ofy;
|
import google.registry.model.ofy.Ofy;
|
||||||
|
import google.registry.testing.DualDatabaseTest;
|
||||||
import google.registry.testing.InjectExtension;
|
import google.registry.testing.InjectExtension;
|
||||||
|
import google.registry.testing.TestOfyAndSql;
|
||||||
import org.junit.jupiter.api.BeforeEach;
|
import org.junit.jupiter.api.BeforeEach;
|
||||||
import org.junit.jupiter.api.Test;
|
|
||||||
import org.junit.jupiter.api.extension.RegisterExtension;
|
import org.junit.jupiter.api.extension.RegisterExtension;
|
||||||
|
|
||||||
/** Unit tests for {@link CountDomainsCommand}. */
|
/** Unit tests for {@link CountDomainsCommand}. */
|
||||||
|
@DualDatabaseTest
|
||||||
public class CountDomainsCommandTest extends CommandTestCase<CountDomainsCommand> {
|
public class CountDomainsCommandTest extends CommandTestCase<CountDomainsCommand> {
|
||||||
|
|
||||||
@RegisterExtension public final InjectExtension inject = new InjectExtension();
|
@RegisterExtension public final InjectExtension inject = new InjectExtension();
|
||||||
|
@ -36,7 +38,7 @@ public class CountDomainsCommandTest extends CommandTestCase<CountDomainsCommand
|
||||||
createTlds("foo", "bar", "baz", "qux");
|
createTlds("foo", "bar", "baz", "qux");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@TestOfyAndSql
|
||||||
void testSuccess_singleTld() throws Exception {
|
void testSuccess_singleTld() throws Exception {
|
||||||
for (int i = 0; i < 51; i++) {
|
for (int i = 0; i < 51; i++) {
|
||||||
persistActiveDomain(String.format("test-%d.foo", i));
|
persistActiveDomain(String.format("test-%d.foo", i));
|
||||||
|
@ -48,7 +50,7 @@ public class CountDomainsCommandTest extends CommandTestCase<CountDomainsCommand
|
||||||
assertStdoutIs("foo,51\n");
|
assertStdoutIs("foo,51\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@TestOfyAndSql
|
||||||
void testSuccess_multipleTlds() throws Exception {
|
void testSuccess_multipleTlds() throws Exception {
|
||||||
for (int i = 0; i < 29; i++) {
|
for (int i = 0; i < 29; i++) {
|
||||||
persistActiveDomain(String.format("test-%d.foo", i));
|
persistActiveDomain(String.format("test-%d.foo", i));
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue