Skip to content

Commit

Permalink
feat: COUNT API added
Browse files Browse the repository at this point in the history
  • Loading branch information
dconeybe committed Mar 3, 2022
1 parent 9a2382c commit d8fe0ed
Show file tree
Hide file tree
Showing 6 changed files with 252 additions and 0 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
/*
* Copyright 2022 Google LLC
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package com.google.cloud.firestore;

import static com.google.cloud.firestore.AggregateField.count;

import java.util.Objects;

public class AggregateDemo {

public static void Demo1_CountOfDocumentsInACollection(Firestore db) throws Exception {
Query query = db.collection("games").document("halo").collection("players");
AggregateSnapshot snapshot = query.aggregate(count()).get().get();
assertEqual(snapshot.get(count()), 5_000_000);
}

public static void Demo2_LimitNumberOfDocumentsScannedWithLimit(Firestore db) throws Exception {
// Limit the work / documents scanned by restricting underlying query.
Query query = db.collection("games").document("halo").collection("players").limit(1000);
AggregateSnapshot snapshot = query.aggregate(count()).get().get();
assertEqual(snapshot.get(count()), 1000);
}

public static void Demo3_LimitNumberOfDocumentsScannedWithUpTo(Firestore db) throws Exception {
// Limit the work / documents scanned by specifying upTo on the aggregation.
Query query = db.collection("games").document("halo").collection("players");
AggregateSnapshot snapshot = query.aggregate(count().upTo(1000)).get().get();
assertEqual(snapshot.get(count()), 1000);
}

private static void assertEqual(Long num1, Long num2) {
if (!Objects.equals(num1, num2)) {
throw new AssertionError("num1!=num2");
}
}

private static void assertEqual(Long num1, int num2) {
assertEqual(num1, Long.valueOf(num2));
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
/*
* Copyright 2022 Google LLC
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package com.google.cloud.firestore;

import java.util.Objects;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;

public abstract class AggregateField {

private AggregateField() {}

@Nonnull
public static CountAggregateField count() {
return new CountAggregateField();
}

@Override
public abstract boolean equals(Object obj);

@Override
public abstract int hashCode();

@Override
public abstract String toString();

public static final class CountAggregateField extends AggregateField {

@Nullable private Integer upTo;

CountAggregateField() {}

CountAggregateField(@Nullable Integer upTo) {
this.upTo = upTo;
}

public CountAggregateField upTo(int upTo) {
if (upTo < 0) {
throw new IllegalArgumentException("upTo==" + upTo);
}
return new CountAggregateField(upTo);
}

@Override
public boolean equals(Object obj) {
if (obj == null || obj.getClass() != this.getClass()) {
return false;
}
CountAggregateField other = (CountAggregateField) obj;
return Objects.equals(upTo, other.upTo);
}

@Override
public int hashCode() {
return Objects.hash("COUNT", upTo);
}

@Override
public String toString() {
if (upTo == null) {
return "COUNT";
} else {
return "COUNT(upTo=" + upTo + ")";
}
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
/*
* Copyright 2022 Google LLC
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package com.google.cloud.firestore;

import com.google.api.core.ApiFuture;
import java.util.concurrent.Executor;
import javax.annotation.Nonnull;

public interface AggregateQuery {

@Nonnull
Query getQuery();

@Nonnull
ApiFuture<AggregateQuerySnapshot> get();

@Nonnull
ListenerRegistration addSnapshotListener(@Nonnull EventListener<AggregateQuerySnapshot> listener);

@Nonnull
ListenerRegistration addSnapshotListener(
@Nonnull Executor executor, @Nonnull EventListener<AggregateQuerySnapshot> listener);

@Override
int hashCode();

@Override
boolean equals(Object obj);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
/*
* Copyright 2022 Google LLC
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package com.google.cloud.firestore;

import javax.annotation.Nonnull;

public interface AggregateQuerySnapshot extends AggregateSnapshot {

@Nonnull
AggregateQuery getQuery();
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
/*
* Copyright 2022 Google LLC
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package com.google.cloud.firestore;

import com.google.cloud.Timestamp;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;

public interface AggregateSnapshot {

@Nonnull
Timestamp getReadTime();

@Nullable
Long get(@Nonnull AggregateField.CountAggregateField field);

@Override
boolean equals(Object obj);

@Override
int hashCode();
}
Original file line number Diff line number Diff line change
Expand Up @@ -1741,6 +1741,19 @@ private boolean isRetryableError(Throwable throwable) {
return false;
}

@Nonnull
public AggregateQuery aggregate(@Nonnull AggregateField field) {
throw new RuntimeException("not implemented");
}

// A convenience method for just getting the count of a query.
// This method also helps with visibility of the "count" feature, since "aggregate" is
// less obvious what you can do with it.
@Nonnull
public AggregateQuery count() {
return aggregate(AggregateField.count());
}

/**
* Returns true if this Query is equal to the provided object.
*
Expand Down

0 comments on commit d8fe0ed

Please sign in to comment.