Skip to content

Commit

Permalink
feat: Add the count aggregate function (#972)
Browse files Browse the repository at this point in the history
* Files copied over

* implementation of aggregate queries.

* Checkout index.ts previous version

* src seems to be error free

* optional parameters

* replace with recognized type

* protos generated

* old package.json

* aggregation query request

* Commit so I can revert

* Revert "aggregation query request"

This reverts commit 0f2bd32.

* Revert "Revert "aggregation query request""

This reverts commit 1733072.

* Added a parser

* Comment out filters

* Fixed parser

* Add info

* more tests, adding alias

* use deep strict equal instead

* Work on passing in buffered input.

* Convert to buffer

* Add alias

* Add the aggregate function

* change test descriptions

* Add a unit test

* Revert "Files copied over"

This reverts commit fe55548.

# Conflicts:
#	src/index.ts

* Revert "protos generated"

This reverts commit 1b21ec2.

* Eliminate comments

* Add new line

* Change upTo

* Change maximum name to upTo

* upTo relabelled from maximum

* remove import

* ran the linter

* improve code readability

* move self equals this

* change header

* Revert "change header"

This reverts commit b3ea976.

* Add a header

* change the unit test

* Architecture changes

* Getting closer

* Add the right parsing

* TODO message

* Remove and add array over for aggregate fields

* unit test and count function

* fix unit test as result of new changes

* linting fix

* Added a test for encoding using a count function

* lint fix

* removed upTo

* merge

* undid local changes to package.json

* 🦉 Updates from OwlBot post-processor

See https://github.com/googleapis/repo-automation-bots/blob/main/packages/owl-bot/README.md

* Update src/aggregate.ts

Co-authored-by: Ruy Adorno <ruyadorno@google.com>

* per reviewer

* refactor and rename some methods

* Add run method to aggregate query

* test update and return value change

* compare aggregate results

* createAggregationQuery

* linter and header fix

* TODOs

* 🦉 Updates from OwlBot post-processor

See https://github.com/googleapis/repo-automation-bots/blob/main/packages/owl-bot/README.md

* Remove autogenerated comment

* count aggregation with limit filter tests

* lint fix

* Commented functions and classes

Co-authored-by: Eric Schmidt <em.schmidt78@gmail.com>
Co-authored-by: Eric Schmidt <erschmid@google.com>
Co-authored-by: Owl Bot <gcf-owl-bot[bot]@users.noreply.github.com>
Co-authored-by: Ruy Adorno <ruyadorno@google.com>
Co-authored-by: Kristen O'Leary <kaoleary@google.com>
  • Loading branch information
6 people authored Jan 12, 2023
1 parent 6b2472b commit 76adfc6
Show file tree
Hide file tree
Showing 11 changed files with 415 additions and 30 deletions.
2 changes: 1 addition & 1 deletion protos/protos.d.ts

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion protos/protos.js

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

160 changes: 160 additions & 0 deletions src/aggregate.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,160 @@
// Copyright 2023 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
//
// https://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.

import {Query} from './index';
import {RunQueryOptions, RunQueryResponse} from './query';
import {RequestCallback} from './request';
const AGGREGATE_QUERY = Symbol('AGGREGATE_QUERY');

/**
* An AggregateQuery is a class that can be used to obtain results from an
* aggregate query request.
*
* @see {@link https://cloud.google.com/datastore/docs/aggregation-queries| Aggregation queries Reference}
*
* @class
*/
class AggregateQuery {
type = AGGREGATE_QUERY;
aggregations: Array<AggregateField>;
query: Query | undefined;

/**
* Build an AggregateQuery object.
*
* @param {Query} query
*/
constructor(query: Query) {
this.query = query;
this.aggregations = [];
}

/**
* Add a `count` aggregate query to the list of aggregations.
*
* @param {string} alias
* @returns {AggregateQuery}
*/
count(alias: string): AggregateQuery {
this.aggregations.push(AggregateField.count().alias(alias));
return this;
}

/**
* Add a custom aggregation to the list of aggregations.
*
* @param {AggregateField} aggregation
* @returns {AggregateQuery}
*/
addAggregation(aggregation: AggregateField): AggregateQuery {
this.aggregations.push(aggregation);
return this;
}

/**
* Add a list of custom aggregations to the list of aggregations.
*
* @param {AggregateField[]} aggregation
* @returns {AggregateQuery}
*/
addAggregations(aggregations: AggregateField[]): AggregateQuery {
for (const aggregation of aggregations) {
this.aggregations.push(aggregation);
}
return this;
}

/**
* Run the aggregation query and return the results.
*
* @param {RunQueryOptions | RequestCallback} [optionsOrCallback]
* @param {function} cb The callback function.
* @returns {void | Promise<RunQueryResponse>}
*/
run(
optionsOrCallback?: RunQueryOptions | RequestCallback,
cb?: RequestCallback
): void | Promise<RunQueryResponse> {
const options =
typeof optionsOrCallback === 'object' ? optionsOrCallback : {};
const callback =
typeof optionsOrCallback === 'function' ? optionsOrCallback : cb!;
const scope = this.query!.scope;
const runAggregationQuery = scope!.runAggregationQuery.bind(scope);
return runAggregationQuery(this, options, callback);
}

/**
* Get the proto for the list of aggregations.
*
*/
// eslint-disable-next-line
toProto(): any {
return this.aggregations.map(aggregation => aggregation.toProto());
}
}

/**
* An AggregateField is a class that contains data that defines an aggregation.
*
*/
abstract class AggregateField {
alias_?: string;

/**
* Gets a copy of the Count aggregate field.
*
* @returns {Count}
*/
static count(): Count {
return new Count();
}

/**
* Gets a copy of the Count aggregate field.
*
* @param {string} alias The label used in the results to describe this
* aggregate field when a query is run.
* @returns {AggregateField}
*/
alias(alias: string): AggregateField {
this.alias_ = alias;
return this;
}

/**
* Gets the proto for the aggregate field.
*
*/
// eslint-disable-next-line
abstract toProto(): any;
}

/**
* A Count is a class that contains data that defines a Count aggregation.
*
*/
class Count extends AggregateField {
// eslint-disable-next-line
/**
* Gets the proto for the count aggregate field.
*
*/
toProto(): any {
const count = Object.assign({});
return Object.assign({count}, this.alias_ ? {alias: this.alias_} : null);
}
}

export {AggregateField, AggregateQuery, AGGREGATE_QUERY};
12 changes: 12 additions & 0 deletions src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,7 @@ import {
import {Transaction} from './transaction';
import {promisifyAll} from '@google-cloud/promisify';
import {google} from '../protos/protos';
import {AggregateQuery} from './aggregate';

const {grpc} = new GrpcClient();

Expand Down Expand Up @@ -509,6 +510,15 @@ class Datastore extends DatastoreRequest {
this.auth = new GoogleAuth(this.options);
}

/**
* Create an aggregation query from a Query.
*
* @param {Query} query A Query object.
*/
createAggregationQuery(query: Query): AggregateQuery {
return new AggregateQuery(query);
}

/**
* Export entities from this project to a Google Cloud Storage bucket.
*
Expand Down Expand Up @@ -1797,10 +1807,12 @@ class Datastore extends DatastoreRequest {
*/
promisifyAll(Datastore, {
exclude: [
'createAggregationQuery',
'double',
'isDouble',
'geoPoint',
'getProjectId',
'getSharedQueryOptions',
'isGeoPoint',
'index',
'int',
Expand Down
3 changes: 3 additions & 0 deletions src/query.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ import {Entity} from './entity';
import {Transaction} from './transaction';
import {CallOptions} from 'google-gax';
import {RunQueryStreamOptions} from '../src/request';
import {AggregateField, AggregateQuery} from './aggregate';

export type Operator =
| '='
Expand Down Expand Up @@ -572,6 +573,8 @@ export interface RunQueryCallback {

export type RunQueryResponse = [Entity[], RunQueryInfo];

export type RunAggregateQueryResponse = any;

export interface RunQueryInfo {
endCursor?: string;
moreResults?:
Expand Down
Loading

0 comments on commit 76adfc6

Please sign in to comment.