Skip to content

Commit e2cb6a1

Browse files
committed
update the firestore-client with datastore from client
1 parent e9759c7 commit e2cb6a1

File tree

4 files changed

+86
-36
lines changed

4 files changed

+86
-36
lines changed

packages/firestore/src/api/aggregate.ts

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ import { AggregateField, AggregateQuerySnapshot } from '../lite-api/aggregate';
2121
import { cast } from '../util/input_validation';
2222

2323
import { ensureFirestoreConfigured, Firestore } from './database';
24+
import { ExpUserDataWriter } from './reference_impl';
2425

2526
export {
2627
AggregateField,
@@ -45,5 +46,6 @@ export function getCountFromServer(
4546
): Promise<AggregateQuerySnapshot<{ count: AggregateField<number> }>> {
4647
const firestore = cast(query.firestore, Firestore);
4748
const client = ensureFirestoreConfigured(firestore);
48-
return firestoreClientRunCountQuery(client, query);
49+
const userDataWriter = new ExpUserDataWriter(firestore);
50+
return firestoreClientRunCountQuery(client, query, userDataWriter);
4951
}
Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
/**
2+
* @license
3+
* Copyright 2022 Google LLC
4+
*
5+
* Licensed under the Apache License, Version 2.0 (the "License");
6+
* you may not use this file except in compliance with the License.
7+
* You may obtain a copy of the License at
8+
*
9+
* http://www.apache.org/licenses/LICENSE-2.0
10+
*
11+
* Unless required by applicable law or agreed to in writing, software
12+
* distributed under the License is distributed on an "AS IS" BASIS,
13+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
* See the License for the specific language governing permissions and
15+
* limitations under the License.
16+
*/
17+
18+
import { AbstractUserDataWriter, Query } from '../api';
19+
import { AggregateField, AggregateQuerySnapshot } from '../lite-api/aggregate';
20+
import { Value } from '../protos/firestore_proto_api';
21+
import { Datastore, invokeRunAggregationQueryRpc } from '../remote/datastore';
22+
import { hardAssert } from '../util/assert';
23+
24+
/**
25+
* CountQueryRunner encapsulates the logic needed to run the count aggregation
26+
* queries.
27+
*/
28+
export class CountQueryRunner<T> {
29+
constructor(
30+
private readonly query: Query<unknown>,
31+
private readonly datastore: Datastore,
32+
private readonly userDataWriter: AbstractUserDataWriter
33+
) {}
34+
35+
run(): Promise<AggregateQuerySnapshot<{ count: AggregateField<number> }>> {
36+
return invokeRunAggregationQueryRpc(this.datastore, this.query._query).then(
37+
result => {
38+
hardAssert(
39+
result[0] !== undefined,
40+
'Aggregation fields are missing from result.'
41+
);
42+
43+
const counts = Object.entries(result[0])
44+
.filter(([key, value]) => key === 'count_alias')
45+
.map(([key, value]) =>
46+
this.userDataWriter.convertValue(value as Value)
47+
);
48+
49+
const countValue = counts[0];
50+
51+
hardAssert(
52+
typeof countValue === 'number',
53+
'Count aggregate field value is not a number: ' + countValue
54+
);
55+
56+
return Promise.resolve(
57+
new AggregateQuerySnapshot<{ count: AggregateField<number> }>(
58+
this.query,
59+
{
60+
count: countValue
61+
}
62+
)
63+
);
64+
}
65+
);
66+
}
67+
}

packages/firestore/src/core/firestore_client.ts

Lines changed: 14 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -16,18 +16,17 @@
1616
*/
1717

1818
import { GetOptions } from '@firebase/firestore-types';
19-
19+
import { AbstractUserDataWriter } from '../api';
20+
import {
21+
AggregateField,
22+
AggregateQuerySnapshot
23+
} from '../api/aggregate';
2024
import { LoadBundleTask } from '../api/bundle';
2125
import {
2226
CredentialChangeListener,
2327
CredentialsProvider
2428
} from '../api/credentials';
2529
import { User } from '../auth/user';
26-
import {
27-
AggregateField,
28-
AggregateQuerySnapshot,
29-
getCount
30-
} from '../lite-api/aggregate';
3130
import { Query as LiteQuery } from '../lite-api/reference';
3231
import { LocalStore } from '../local/local_store';
3332
import {
@@ -68,6 +67,7 @@ import {
6867
OfflineComponentProvider,
6968
OnlineComponentProvider
7069
} from './component_provider';
70+
import { CountQueryRunner } from './count_query_runner';
7171
import { DatabaseId, DatabaseInfo } from './database_info';
7272
import {
7373
addSnapshotsInSyncListener,
@@ -510,7 +510,8 @@ export function firestoreClientTransaction<T>(
510510

511511
export function firestoreClientRunCountQuery(
512512
client: FirestoreClient,
513-
query: LiteQuery<unknown>
513+
query: LiteQuery<unknown>,
514+
userDataWriter: AbstractUserDataWriter
514515
): Promise<AggregateQuerySnapshot<{ count: AggregateField<number> }>> {
515516
const deferred = new Deferred<
516517
AggregateQuerySnapshot<{ count: AggregateField<number> }>
@@ -526,7 +527,12 @@ export function firestoreClientRunCountQuery(
526527
)
527528
);
528529
} else {
529-
const result = await getCount(query);
530+
const datastore = await getDatastore(client);
531+
const result = new CountQueryRunner(
532+
query,
533+
datastore,
534+
userDataWriter
535+
).run();
530536
deferred.resolve(result);
531537
}
532538
} catch (e) {

packages/firestore/src/lite-api/aggregate.ts

Lines changed: 2 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -16,10 +16,7 @@
1616
*/
1717

1818
import { deepEqual } from '@firebase/util';
19-
20-
import { Value } from '../protos/firestore_proto_api';
21-
import { invokeRunAggregationQueryRpc } from '../remote/datastore';
22-
import { hardAssert } from '../util/assert';
19+
import { CountQueryRunner } from '../core/count_query_runner';
2320
import { cast } from '../util/input_validation';
2421

2522
import { getDatastore } from './components';
@@ -108,29 +105,7 @@ export function getCount(
108105
const firestore = cast(query.firestore, Firestore);
109106
const datastore = getDatastore(firestore);
110107
const userDataWriter = new LiteUserDataWriter(firestore);
111-
return invokeRunAggregationQueryRpc(datastore, query._query).then(result => {
112-
hardAssert(
113-
result[0] !== undefined,
114-
'Aggregation fields are missing from result.'
115-
);
116-
117-
const counts = Object.entries(result[0])
118-
.filter(([key, value]) => key === 'count_alias')
119-
.map(([key, value]) => userDataWriter.convertValue(value as Value));
120-
121-
const countValue = counts[0];
122-
123-
hardAssert(
124-
typeof countValue === 'number',
125-
'Count aggregate field value is not a number: ' + countValue
126-
);
127-
128-
return Promise.resolve(
129-
new AggregateQuerySnapshot<{ count: AggregateField<number> }>(query, {
130-
count: countValue
131-
})
132-
);
133-
});
108+
return new CountQueryRunner(query, datastore, userDataWriter).run();
134109
}
135110

136111
/**

0 commit comments

Comments
 (0)