google-cloud-firestore 2.7.2 → 2.15.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/AUTHENTICATION.md +8 -26
- data/CHANGELOG.md +69 -0
- data/LOGGING.md +1 -1
- data/lib/google/cloud/firestore/aggregate_query.rb +285 -0
- data/lib/google/cloud/firestore/aggregate_query_snapshot.rb +145 -0
- data/lib/google/cloud/firestore/bulk_commit_batch.rb +73 -0
- data/lib/google/cloud/firestore/bulk_writer.rb +558 -0
- data/lib/google/cloud/firestore/bulk_writer_exception.rb +40 -0
- data/lib/google/cloud/firestore/bulk_writer_operation.rb +126 -0
- data/lib/google/cloud/firestore/bulk_writer_scheduler.rb +164 -0
- data/lib/google/cloud/firestore/client.rb +161 -10
- data/lib/google/cloud/firestore/collection_group.rb +20 -4
- data/lib/google/cloud/firestore/collection_reference.rb +17 -2
- data/lib/google/cloud/firestore/collection_reference_list.rb +4 -3
- data/lib/google/cloud/firestore/convert.rb +6 -7
- data/lib/google/cloud/firestore/document_reference/list.rb +5 -3
- data/lib/google/cloud/firestore/document_reference.rb +20 -3
- data/lib/google/cloud/firestore/document_snapshot.rb +1 -1
- data/lib/google/cloud/firestore/errors.rb +60 -0
- data/lib/google/cloud/firestore/filter.rb +326 -0
- data/lib/google/cloud/firestore/promise/future.rb +97 -0
- data/lib/google/cloud/firestore/query.rb +112 -89
- data/lib/google/cloud/firestore/rate_limiter.rb +80 -0
- data/lib/google/cloud/firestore/service.rb +74 -23
- data/lib/google/cloud/firestore/transaction.rb +57 -4
- data/lib/google/cloud/firestore/version.rb +1 -1
- data/lib/google/cloud/firestore.rb +17 -7
- data/lib/google-cloud-firestore.rb +45 -8
- metadata +17 -146
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 16163a09797c60820b760bb85283dc3ab8532aacc329dbdf0e8672ab7b8e4066
|
4
|
+
data.tar.gz: a502101923eaeffb2b8ca9112134ffc14e8971970509cb9f34e5263c5889a791
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 06e1cb717e9ccdb4560f66d38af4845610aaed131557956d5dea7c86a97169c7f7af979e956ef53a7ac3ce36f19ade87c3a00a7f568bcdc2ea82aaf77dfafb77
|
7
|
+
data.tar.gz: 388eb390a647550643bdce6c1a0b57bcb98fa9ad63fdb24808971dafeac3342ac6a0943bc86103d892b9a4e572746ec01ddf167f9629ff29df768bedcc606c59
|
data/AUTHENTICATION.md
CHANGED
@@ -124,15 +124,6 @@ To configure your system for this, simply:
|
|
124
124
|
**NOTE:** This is _not_ recommended for running in production. The Cloud SDK
|
125
125
|
*should* only be used during development.
|
126
126
|
|
127
|
-
[gce-how-to]: https://cloud.google.com/compute/docs/authentication#using
|
128
|
-
[dev-console]: https://console.cloud.google.com/project
|
129
|
-
|
130
|
-
[enable-apis]: https://raw.githubusercontent.com/GoogleCloudPlatform/gcloud-common/master/authentication/enable-apis.png
|
131
|
-
|
132
|
-
[create-new-service-account]: https://raw.githubusercontent.com/GoogleCloudPlatform/gcloud-common/master/authentication/create-new-service-account.png
|
133
|
-
[create-new-service-account-existing-keys]: https://raw.githubusercontent.com/GoogleCloudPlatform/gcloud-common/master/authentication/create-new-service-account-existing-keys.png
|
134
|
-
[reuse-service-account]: https://raw.githubusercontent.com/GoogleCloudPlatform/gcloud-common/master/authentication/reuse-service-account.png
|
135
|
-
|
136
127
|
## Creating a Service Account
|
137
128
|
|
138
129
|
Google Cloud requires a **Project ID** and **Service Account Credentials** to
|
@@ -143,31 +134,22 @@ If you are not running this client within [Google Cloud Platform
|
|
143
134
|
environments](#google-cloud-platform-environments), you need a Google
|
144
135
|
Developers service account.
|
145
136
|
|
146
|
-
1. Visit the [Google
|
137
|
+
1. Visit the [Google Cloud Console](https://console.cloud.google.com/project).
|
147
138
|
1. Create a new project or click on an existing project.
|
148
|
-
1. Activate the
|
139
|
+
1. Activate the menu in the upper left and select **APIs & Services**. From
|
149
140
|
here, you will enable the APIs that your application requires.
|
150
141
|
|
151
|
-
![Enable the APIs that your application requires][enable-apis]
|
152
|
-
|
153
142
|
*Note: You may need to enable billing in order to use these services.*
|
154
143
|
|
155
144
|
1. Select **Credentials** from the side navigation.
|
156
145
|
|
157
|
-
|
158
|
-
|
159
|
-
![Create a new service account][create-new-service-account]
|
160
|
-
|
161
|
-
![Create a new service account With Existing Keys][create-new-service-account-existing-keys]
|
162
|
-
|
163
|
-
Find the "Add credentials" drop down and select "Service account" to be
|
164
|
-
guided through downloading a new JSON key file.
|
165
|
-
|
166
|
-
If you want to re-use an existing service account, you can easily generate a
|
167
|
-
new key file. Just select the account you wish to re-use, and click "Generate
|
168
|
-
new JSON key":
|
146
|
+
Find the "Create credentials" drop down near the top of the page, and select
|
147
|
+
"Service account" to be guided through downloading a new JSON key file.
|
169
148
|
|
170
|
-
|
149
|
+
If you want to re-use an existing service account, you can easily generate
|
150
|
+
a new key file. Just select the account you wish to re-use click the pencil
|
151
|
+
tool on the right side to edit the service account, select the **Keys** tab,
|
152
|
+
and then select **Add Key**.
|
171
153
|
|
172
154
|
The key file you download will be used by this library to authenticate API
|
173
155
|
requests and should be stored in a secure location.
|
data/CHANGELOG.md
CHANGED
@@ -1,5 +1,74 @@
|
|
1
1
|
# Release History
|
2
2
|
|
3
|
+
### 2.15.0 (2024-03-07)
|
4
|
+
|
5
|
+
#### Features
|
6
|
+
|
7
|
+
* Update minimum supported Ruby version to 2.7 ([#25298](https://github.com/googleapis/google-cloud-ruby/issues/25298))
|
8
|
+
|
9
|
+
### 2.14.0 (2024-01-31)
|
10
|
+
|
11
|
+
#### Features
|
12
|
+
|
13
|
+
* Support sum & avg aggregate functions ([#23446](https://github.com/googleapis/google-cloud-ruby/issues/23446))
|
14
|
+
|
15
|
+
### 2.13.1 (2023-06-16)
|
16
|
+
|
17
|
+
#### Documentation
|
18
|
+
|
19
|
+
* Fixed broken links in authentication documentation ([#21619](https://github.com/googleapis/google-cloud-ruby/issues/21619))
|
20
|
+
|
21
|
+
### 2.13.0 (2023-05-10)
|
22
|
+
|
23
|
+
#### Features
|
24
|
+
|
25
|
+
* Added support for bulk writer ([#21426](https://github.com/googleapis/google-cloud-ruby/issues/21426))
|
26
|
+
|
27
|
+
### 2.12.0 (2023-04-20)
|
28
|
+
|
29
|
+
#### Features
|
30
|
+
|
31
|
+
* Add support for OR query ([#20920](https://github.com/googleapis/google-cloud-ruby/issues/20920))
|
32
|
+
|
33
|
+
### 2.11.0 (2023-02-23)
|
34
|
+
|
35
|
+
#### Features
|
36
|
+
|
37
|
+
* Support REST transport ([#20446](https://github.com/googleapis/google-cloud-ruby/issues/20446))
|
38
|
+
|
39
|
+
### 2.10.1 (2023-02-16)
|
40
|
+
|
41
|
+
#### Bug Fixes
|
42
|
+
|
43
|
+
* update version of firestore-v1 in gemspec ([#20433](https://github.com/googleapis/google-cloud-ruby/issues/20433))
|
44
|
+
|
45
|
+
### 2.10.0 (2023-02-09)
|
46
|
+
|
47
|
+
#### Features
|
48
|
+
|
49
|
+
* Added support for multiple databases ([#20029](https://github.com/googleapis/google-cloud-ruby/issues/20029))
|
50
|
+
|
51
|
+
### 2.9.1 (2023-02-03)
|
52
|
+
|
53
|
+
#### Bug Fixes
|
54
|
+
|
55
|
+
* Change "aggregate_alias" to optional param ([#20082](https://github.com/googleapis/google-cloud-ruby/issues/20082))
|
56
|
+
|
57
|
+
### 2.9.0 (2023-01-26)
|
58
|
+
|
59
|
+
#### Features
|
60
|
+
|
61
|
+
* Added support for read time ([#19851](https://github.com/googleapis/google-cloud-ruby/issues/19851))
|
62
|
+
|
63
|
+
### 2.8.0 (2023-01-05)
|
64
|
+
|
65
|
+
#### Features
|
66
|
+
|
67
|
+
* Support query count for Firestore ([#19457](https://github.com/googleapis/google-cloud-ruby/issues/19457))
|
68
|
+
#### Bug Fixes
|
69
|
+
|
70
|
+
* Add support for merging null field in a document ([#19918](https://github.com/googleapis/google-cloud-ruby/issues/19918))
|
71
|
+
|
3
72
|
### 2.7.2 (2022-08-24)
|
4
73
|
|
5
74
|
#### Documentation
|
data/LOGGING.md
CHANGED
@@ -3,7 +3,7 @@
|
|
3
3
|
To enable logging for this library, set the logger for the underlying
|
4
4
|
[gRPC](https://github.com/grpc/grpc/tree/master/src/ruby) library. The logger
|
5
5
|
that you set may be a Ruby stdlib
|
6
|
-
[`Logger`](https://ruby-doc.org/
|
6
|
+
[`Logger`](https://ruby-doc.org/current/stdlibs/logger/Logger.html) as
|
7
7
|
shown below, or a
|
8
8
|
[`Google::Cloud::Logging::Logger`](https://googleapis.dev/ruby/google-cloud-logging/latest)
|
9
9
|
that will write logs to [Stackdriver
|
@@ -0,0 +1,285 @@
|
|
1
|
+
# Copyright 2022 Google LLC
|
2
|
+
#
|
3
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
4
|
+
# you may not use this file except in compliance with the License.
|
5
|
+
# You may obtain a copy of the License at
|
6
|
+
#
|
7
|
+
# https://www.apache.org/licenses/LICENSE-2.0
|
8
|
+
#
|
9
|
+
# Unless required by applicable law or agreed to in writing, software
|
10
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
11
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
12
|
+
# See the License for the specific language governing permissions and
|
13
|
+
# limitations under the License.
|
14
|
+
|
15
|
+
require "google/cloud/firestore/v1"
|
16
|
+
require "google/cloud/firestore/aggregate_query_snapshot"
|
17
|
+
|
18
|
+
module Google
|
19
|
+
module Cloud
|
20
|
+
module Firestore
|
21
|
+
##
|
22
|
+
# # AggregateQuery
|
23
|
+
#
|
24
|
+
# An aggregate query can be used to fetch aggregate values (ex: count) for a query
|
25
|
+
#
|
26
|
+
# Instances of this class are immutable. All methods that refine the aggregate query
|
27
|
+
# return new instances.
|
28
|
+
#
|
29
|
+
# @example
|
30
|
+
# require "google/cloud/firestore"
|
31
|
+
#
|
32
|
+
# firestore = Google::Cloud::Firestore.new
|
33
|
+
#
|
34
|
+
# query = firestore.col "cities"
|
35
|
+
#
|
36
|
+
# # Create an aggregate query
|
37
|
+
# aggregate_query = query.aggregate_query
|
38
|
+
# .add_count
|
39
|
+
#
|
40
|
+
# aggregate_query.get do |aggregate_snapshot|
|
41
|
+
# puts aggregate_snapshot.get
|
42
|
+
# end
|
43
|
+
#
|
44
|
+
# @example Alias an aggregate query
|
45
|
+
# require "google/cloud/firestore"
|
46
|
+
#
|
47
|
+
# firestore = Google::Cloud::Firestore.new
|
48
|
+
#
|
49
|
+
# # Create a query
|
50
|
+
# query = firestore.col "cities"
|
51
|
+
#
|
52
|
+
# # Create an aggregate query
|
53
|
+
# aggregate_query = query.aggregate_query
|
54
|
+
# .add_count aggregate_alias: 'total_cities'
|
55
|
+
#
|
56
|
+
# aggregate_query.get do |aggregate_snapshot|
|
57
|
+
# puts aggregate_snapshot.get('total_cities')
|
58
|
+
# end
|
59
|
+
#
|
60
|
+
class AggregateQuery
|
61
|
+
##
|
62
|
+
# @private The firestore client object.
|
63
|
+
attr_accessor :client
|
64
|
+
|
65
|
+
##
|
66
|
+
# @private The type for limit queries.
|
67
|
+
attr_reader :parent_path
|
68
|
+
|
69
|
+
##
|
70
|
+
# @private The Google::Cloud::Firestore::Query object.
|
71
|
+
attr_reader :query
|
72
|
+
|
73
|
+
##
|
74
|
+
# @private Object of type
|
75
|
+
# Google::Cloud::Firestore::V1::StructuredAggregationQuery
|
76
|
+
attr_reader :grpc
|
77
|
+
|
78
|
+
# @private
|
79
|
+
DEFAULT_COUNT_ALIAS = "count".freeze
|
80
|
+
|
81
|
+
# @private
|
82
|
+
DEFAULT_SUM_ALIAS = "sum".freeze
|
83
|
+
|
84
|
+
# @private
|
85
|
+
DEFAULT_AVG_ALIAS = "avg".freeze
|
86
|
+
|
87
|
+
##
|
88
|
+
# @private Creates a new AggregateQuery
|
89
|
+
def initialize query, parent_path, client
|
90
|
+
@query = query
|
91
|
+
@parent_path = parent_path
|
92
|
+
@client = client
|
93
|
+
@grpc = Google::Cloud::Firestore::V1::StructuredAggregationQuery.new(
|
94
|
+
structured_query: @query.query,
|
95
|
+
aggregations: []
|
96
|
+
)
|
97
|
+
end
|
98
|
+
|
99
|
+
##
|
100
|
+
# Adds a count aggregate.
|
101
|
+
#
|
102
|
+
# @param aggregate_alias [String] Alias to refer to the aggregate. Optional
|
103
|
+
#
|
104
|
+
# @return [AggregateQuery] A new aggregate query with the added count aggregate.
|
105
|
+
#
|
106
|
+
# @example
|
107
|
+
# require "google/cloud/firestore"
|
108
|
+
#
|
109
|
+
# firestore = Google::Cloud::Firestore.new
|
110
|
+
#
|
111
|
+
# query = firestore.col "cities"
|
112
|
+
#
|
113
|
+
# # Create an aggregate query
|
114
|
+
# aggregate_query = query.aggregate_query
|
115
|
+
# .add_count
|
116
|
+
#
|
117
|
+
# aggregate_query.get do |aggregate_snapshot|
|
118
|
+
# puts aggregate_snapshot.get
|
119
|
+
# end
|
120
|
+
#
|
121
|
+
def add_count aggregate_alias: nil
|
122
|
+
aggregate_alias ||= DEFAULT_COUNT_ALIAS
|
123
|
+
new_aggregate = Google::Cloud::Firestore::V1::StructuredAggregationQuery::Aggregation.new(
|
124
|
+
count: Google::Cloud::Firestore::V1::StructuredAggregationQuery::Aggregation::Count.new,
|
125
|
+
alias: aggregate_alias
|
126
|
+
)
|
127
|
+
|
128
|
+
start new_aggregate
|
129
|
+
end
|
130
|
+
|
131
|
+
##
|
132
|
+
# Adds a sum aggregate.
|
133
|
+
#
|
134
|
+
# @param field [String] The field to sum by
|
135
|
+
# @param aggregate_alias [String] Alias to refer to the aggregate
|
136
|
+
#
|
137
|
+
# @return [AggregateQuery] A new aggregate query with the added sum aggregate.
|
138
|
+
#
|
139
|
+
# @example
|
140
|
+
# require "google/cloud/firestore"
|
141
|
+
#
|
142
|
+
# firestore = Google::Cloud::Firestore.new
|
143
|
+
#
|
144
|
+
# query = firestore.col "cities"
|
145
|
+
#
|
146
|
+
# # Create an aggregate query
|
147
|
+
# aggregate_query = query.aggregate_query
|
148
|
+
# .add_sum("population")
|
149
|
+
#
|
150
|
+
# aggregate_query.get do |aggregate_snapshot|
|
151
|
+
# puts aggregate_snapshot.get
|
152
|
+
# end
|
153
|
+
#
|
154
|
+
def add_sum field, aggregate_alias: nil
|
155
|
+
aggregate_alias ||= DEFAULT_SUM_ALIAS
|
156
|
+
field = FieldPath.parse field unless field.is_a? FieldPath
|
157
|
+
new_aggregate = Google::Cloud::Firestore::V1::StructuredAggregationQuery::Aggregation.new(
|
158
|
+
sum: Google::Cloud::Firestore::V1::StructuredAggregationQuery::Aggregation::Sum.new(
|
159
|
+
field: Google::Cloud::Firestore::V1::StructuredQuery::FieldReference.new(
|
160
|
+
field_path: field.formatted_string
|
161
|
+
)
|
162
|
+
),
|
163
|
+
alias: aggregate_alias
|
164
|
+
)
|
165
|
+
|
166
|
+
start new_aggregate
|
167
|
+
end
|
168
|
+
|
169
|
+
##
|
170
|
+
# Adds an average aggregate.
|
171
|
+
#
|
172
|
+
# @param field [String] The field to apply average on
|
173
|
+
# @param aggregate_alias [String] Alias to refer to the aggregate
|
174
|
+
#
|
175
|
+
# @return [AggregateQuery] A new aggregate query with the added average aggregate.
|
176
|
+
#
|
177
|
+
# @example
|
178
|
+
# require "google/cloud/firestore"
|
179
|
+
#
|
180
|
+
# firestore = Google::Cloud::Firestore.new
|
181
|
+
#
|
182
|
+
# query = firestore.col "cities"
|
183
|
+
#
|
184
|
+
# # Create an aggregate query
|
185
|
+
# aggregate_query = query.aggregate_query
|
186
|
+
# .add_avg("population")
|
187
|
+
#
|
188
|
+
# aggregate_query.get do |aggregate_snapshot|
|
189
|
+
# puts aggregate_snapshot.get
|
190
|
+
# end
|
191
|
+
#
|
192
|
+
def add_avg field, aggregate_alias: nil
|
193
|
+
aggregate_alias ||= DEFAULT_AVG_ALIAS
|
194
|
+
field = FieldPath.parse field unless field.is_a? FieldPath
|
195
|
+
new_aggregate = Google::Cloud::Firestore::V1::StructuredAggregationQuery::Aggregation.new(
|
196
|
+
avg: Google::Cloud::Firestore::V1::StructuredAggregationQuery::Aggregation::Avg.new(
|
197
|
+
field: Google::Cloud::Firestore::V1::StructuredQuery::FieldReference.new(
|
198
|
+
field_path: field.formatted_string
|
199
|
+
)
|
200
|
+
),
|
201
|
+
alias: aggregate_alias
|
202
|
+
)
|
203
|
+
|
204
|
+
start new_aggregate
|
205
|
+
end
|
206
|
+
|
207
|
+
##
|
208
|
+
# @private
|
209
|
+
def start new_aggregate
|
210
|
+
combined_aggregates = [].concat(grpc.aggregations).push(new_aggregate)
|
211
|
+
new_grpc = Google::Cloud::Firestore::V1::StructuredAggregationQuery.new(
|
212
|
+
structured_query: @query.query,
|
213
|
+
aggregations: combined_aggregates
|
214
|
+
)
|
215
|
+
self.class.new(@query, @parent_path, @client).tap do |aq|
|
216
|
+
aq.instance_variable_set :@grpc, new_grpc
|
217
|
+
end
|
218
|
+
end
|
219
|
+
|
220
|
+
##
|
221
|
+
# Retrieves aggregate snapshot for the query.
|
222
|
+
#
|
223
|
+
# @yield [snapshot] The block for accessing the aggregate query snapshots.
|
224
|
+
# @yieldparam [AggregateQuerySnapshot] An aggregate query snapshot.
|
225
|
+
#
|
226
|
+
# @return [Enumerator<AggregateQuerySnapshot>] A list of aggregate query snapshots.
|
227
|
+
#
|
228
|
+
# @example
|
229
|
+
# require "google/cloud/firestore"
|
230
|
+
#
|
231
|
+
# firestore = Google::Cloud::Firestore.new
|
232
|
+
#
|
233
|
+
# query = firestore.col "cities"
|
234
|
+
#
|
235
|
+
# # Create an aggregate query
|
236
|
+
# aggregate_query = query.aggregate_query
|
237
|
+
# .add_count
|
238
|
+
#
|
239
|
+
# aggregate_query.get do |aggregate_snapshot|
|
240
|
+
# puts aggregate_snapshot.get
|
241
|
+
# end
|
242
|
+
#
|
243
|
+
def get
|
244
|
+
ensure_service!
|
245
|
+
|
246
|
+
return enum_for :get unless block_given?
|
247
|
+
|
248
|
+
responses = service.run_aggregate_query @parent_path, @grpc
|
249
|
+
responses.each do |response|
|
250
|
+
next if response.result.nil?
|
251
|
+
yield AggregateQuerySnapshot.from_run_aggregate_query_response response
|
252
|
+
end
|
253
|
+
end
|
254
|
+
|
255
|
+
##
|
256
|
+
# @private
|
257
|
+
def to_grpc
|
258
|
+
@grpc
|
259
|
+
end
|
260
|
+
|
261
|
+
protected
|
262
|
+
|
263
|
+
##
|
264
|
+
# @private Raise an error unless a database is available.
|
265
|
+
def ensure_client!
|
266
|
+
raise "Must have active connection to service" unless client
|
267
|
+
end
|
268
|
+
|
269
|
+
##
|
270
|
+
# @private Raise an error unless an active connection to the service
|
271
|
+
# is available.
|
272
|
+
def ensure_service!
|
273
|
+
raise "Must have active connection to service" unless service
|
274
|
+
end
|
275
|
+
|
276
|
+
##
|
277
|
+
# @private The Service object.
|
278
|
+
def service
|
279
|
+
ensure_client!
|
280
|
+
client.service
|
281
|
+
end
|
282
|
+
end
|
283
|
+
end
|
284
|
+
end
|
285
|
+
end
|
@@ -0,0 +1,145 @@
|
|
1
|
+
# Copyright 2022 Google LLC
|
2
|
+
#
|
3
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
4
|
+
# you may not use this file except in compliance with the License.
|
5
|
+
# You may obtain a copy of the License at
|
6
|
+
#
|
7
|
+
# https://www.apache.org/licenses/LICENSE-2.0
|
8
|
+
#
|
9
|
+
# Unless required by applicable law or agreed to in writing, software
|
10
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
11
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
12
|
+
# See the License for the specific language governing permissions and
|
13
|
+
# limitations under the License.
|
14
|
+
|
15
|
+
|
16
|
+
module Google
|
17
|
+
module Cloud
|
18
|
+
module Firestore
|
19
|
+
##
|
20
|
+
# # AggregateQuerySnapshot
|
21
|
+
#
|
22
|
+
# An aggregate query snapshot object is an immutable representation for
|
23
|
+
# an aggregate query result.
|
24
|
+
#
|
25
|
+
# @example
|
26
|
+
# require "google/cloud/firestore"
|
27
|
+
#
|
28
|
+
# firestore = Google::Cloud::Firestore.new
|
29
|
+
#
|
30
|
+
# query = firestore.col "cities"
|
31
|
+
#
|
32
|
+
# # Create an aggregate query
|
33
|
+
# aggregate_query = query.aggregate_query
|
34
|
+
# .add_count
|
35
|
+
#
|
36
|
+
# aggregate_query.get do |aggregate_snapshot|
|
37
|
+
# puts aggregate_snapshot.get
|
38
|
+
# end
|
39
|
+
# @return [Integer] The aggregate value.
|
40
|
+
#
|
41
|
+
# @example Alias an aggregate query
|
42
|
+
# require "google/cloud/firestore"
|
43
|
+
#
|
44
|
+
# firestore = Google::Cloud::Firestore.new
|
45
|
+
#
|
46
|
+
# query = firestore.col "cities"
|
47
|
+
#
|
48
|
+
# # Create an aggregate query
|
49
|
+
# aggregate_query = query.aggregate_query
|
50
|
+
# .add_count aggregate_alias: 'total'
|
51
|
+
#
|
52
|
+
# aggregate_query.get do |aggregate_snapshot|
|
53
|
+
# puts aggregate_snapshot.get('total')
|
54
|
+
# end
|
55
|
+
class AggregateQuerySnapshot
|
56
|
+
##
|
57
|
+
# @private Object of type [Hash{String => Object}]
|
58
|
+
#
|
59
|
+
# String can have the following values:
|
60
|
+
# - an aggregate literal "sum", "avg", or "count"
|
61
|
+
# - a custom aggregate alias
|
62
|
+
# Object can have the following types:
|
63
|
+
# - Integer
|
64
|
+
# - Float
|
65
|
+
# - nil
|
66
|
+
# - NaN
|
67
|
+
attr_reader :aggregate_fields
|
68
|
+
|
69
|
+
##
|
70
|
+
# Retrieves the aggregate data.
|
71
|
+
#
|
72
|
+
# @param aggregate_alias [String] The alias used to access
|
73
|
+
# the aggregate value. For an AggregateQuery with a
|
74
|
+
# single aggregate field, this parameter can be omitted.
|
75
|
+
#
|
76
|
+
# @return [Integer, Float, nil, NaN] The aggregate value.
|
77
|
+
# Returns `nil` if the aggregate_alias does not exist.
|
78
|
+
# Returns `NaN` if the aggregate field contains one or more NaN values.
|
79
|
+
#
|
80
|
+
# @example
|
81
|
+
# require "google/cloud/firestore"
|
82
|
+
#
|
83
|
+
# firestore = Google::Cloud::Firestore.new
|
84
|
+
#
|
85
|
+
# query = firestore.col "cities"
|
86
|
+
#
|
87
|
+
# # Create an aggregate query
|
88
|
+
# aggregate_query = query.aggregate_query
|
89
|
+
# .add_count
|
90
|
+
#
|
91
|
+
# aggregate_query.get do |aggregate_snapshot|
|
92
|
+
# puts aggregate_snapshot.get
|
93
|
+
# end
|
94
|
+
# @return [Integer] The aggregate value.
|
95
|
+
#
|
96
|
+
# @example Alias an aggregate query
|
97
|
+
# require "google/cloud/firestore"
|
98
|
+
#
|
99
|
+
# firestore = Google::Cloud::Firestore.new
|
100
|
+
#
|
101
|
+
# query = firestore.col "cities"
|
102
|
+
#
|
103
|
+
# # Create an aggregate query
|
104
|
+
# aggregate_query = query.aggregate_query
|
105
|
+
# .add_count aggregate_alias: 'total'
|
106
|
+
#
|
107
|
+
# aggregate_query.get do |aggregate_snapshot|
|
108
|
+
# puts aggregate_snapshot.get('total')
|
109
|
+
# end
|
110
|
+
def get aggregate_alias = nil
|
111
|
+
if @aggregate_fields.count > 1 && aggregate_alias.nil?
|
112
|
+
raise ArgumentError, "Required param aggregate_alias for AggregateQuery with multiple aggregate fields"
|
113
|
+
end
|
114
|
+
aggregate_alias ||= @aggregate_fields.keys.first
|
115
|
+
@aggregate_fields[aggregate_alias]
|
116
|
+
end
|
117
|
+
|
118
|
+
##
|
119
|
+
# @private New AggregateQuerySnapshot from a
|
120
|
+
# Google::Cloud::Firestore::V1::RunAggregationQueryResponse object.
|
121
|
+
def self.from_run_aggregate_query_response response
|
122
|
+
# rubocop:disable Style/MapToHash
|
123
|
+
aggregate_fields = response
|
124
|
+
.result
|
125
|
+
.aggregate_fields
|
126
|
+
.map do |aggregate_alias, value| # convert from protobuf to ruby map
|
127
|
+
if value.has_integer_value?
|
128
|
+
[aggregate_alias, value.integer_value]
|
129
|
+
elsif value.has_double_value?
|
130
|
+
[aggregate_alias, value.double_value]
|
131
|
+
elsif value.has_null_value?
|
132
|
+
[aggregate_alias, nil]
|
133
|
+
end
|
134
|
+
end
|
135
|
+
.to_h
|
136
|
+
# rubocop:enable Style/MapToHash
|
137
|
+
|
138
|
+
new.tap do |s|
|
139
|
+
s.instance_variable_set :@aggregate_fields, aggregate_fields
|
140
|
+
end
|
141
|
+
end
|
142
|
+
end
|
143
|
+
end
|
144
|
+
end
|
145
|
+
end
|
@@ -0,0 +1,73 @@
|
|
1
|
+
# Copyright 2023 Google LLC
|
2
|
+
#
|
3
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
4
|
+
# you may not use this file except in compliance with the License.
|
5
|
+
# You may obtain a copy of the License at
|
6
|
+
#
|
7
|
+
# https://www.apache.org/licenses/LICENSE-2.0
|
8
|
+
#
|
9
|
+
# Unless required by applicable law or agreed to in writing, software
|
10
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
11
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
12
|
+
# See the License for the specific language governing permissions and
|
13
|
+
# limitations under the License.
|
14
|
+
|
15
|
+
|
16
|
+
module Google
|
17
|
+
module Cloud
|
18
|
+
module Firestore
|
19
|
+
##
|
20
|
+
#
|
21
|
+
# @private Accumulate write operations to be sent in a batch. Use this for higher
|
22
|
+
# volumes (e.g., via `BulkWriter`) and when the order of operations
|
23
|
+
# within a given batch is unimportant.
|
24
|
+
#
|
25
|
+
# Because the order in which individual write operations are applied to the database
|
26
|
+
# is not guaranteed, `batch_write` RPCs can never contain multiple operations
|
27
|
+
# to the same document. In practice, the BulkWriter class handle this case.
|
28
|
+
#
|
29
|
+
class BulkCommitBatch
|
30
|
+
attr_reader :operations
|
31
|
+
|
32
|
+
##
|
33
|
+
# Initialize the object
|
34
|
+
def initialize service, operations
|
35
|
+
@service = service
|
36
|
+
@operations = operations
|
37
|
+
end
|
38
|
+
|
39
|
+
##
|
40
|
+
# Updates the operation based on the result received from the API request.
|
41
|
+
#
|
42
|
+
# @param [Google::Cloud::Firestore::V1::BatchWriteResponse] responses
|
43
|
+
#
|
44
|
+
# @return [nil]
|
45
|
+
#
|
46
|
+
def parse_results responses
|
47
|
+
@operations.zip responses.write_results, responses.status do |operation, write_result, status|
|
48
|
+
begin
|
49
|
+
status&.code&.zero? ? operation.on_success(write_result) : operation.on_failure(status)
|
50
|
+
rescue StandardError
|
51
|
+
# TODO: Log the error while parsing response
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
##
|
57
|
+
# Makes the BatchWrite API request with all the operations in the batch and
|
58
|
+
# parses the results for each operation.
|
59
|
+
#
|
60
|
+
# @return [nil]
|
61
|
+
#
|
62
|
+
def commit
|
63
|
+
begin
|
64
|
+
responses = @service.batch_write @operations.map(&:write)
|
65
|
+
parse_results responses
|
66
|
+
rescue StandardError => e
|
67
|
+
raise BulkCommitBatchError, e
|
68
|
+
end
|
69
|
+
end
|
70
|
+
end
|
71
|
+
end
|
72
|
+
end
|
73
|
+
end
|