google-cloud-firestore 2.7.2 → 2.15.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (30) hide show
  1. checksums.yaml +4 -4
  2. data/AUTHENTICATION.md +8 -26
  3. data/CHANGELOG.md +69 -0
  4. data/LOGGING.md +1 -1
  5. data/lib/google/cloud/firestore/aggregate_query.rb +285 -0
  6. data/lib/google/cloud/firestore/aggregate_query_snapshot.rb +145 -0
  7. data/lib/google/cloud/firestore/bulk_commit_batch.rb +73 -0
  8. data/lib/google/cloud/firestore/bulk_writer.rb +558 -0
  9. data/lib/google/cloud/firestore/bulk_writer_exception.rb +40 -0
  10. data/lib/google/cloud/firestore/bulk_writer_operation.rb +126 -0
  11. data/lib/google/cloud/firestore/bulk_writer_scheduler.rb +164 -0
  12. data/lib/google/cloud/firestore/client.rb +161 -10
  13. data/lib/google/cloud/firestore/collection_group.rb +20 -4
  14. data/lib/google/cloud/firestore/collection_reference.rb +17 -2
  15. data/lib/google/cloud/firestore/collection_reference_list.rb +4 -3
  16. data/lib/google/cloud/firestore/convert.rb +6 -7
  17. data/lib/google/cloud/firestore/document_reference/list.rb +5 -3
  18. data/lib/google/cloud/firestore/document_reference.rb +20 -3
  19. data/lib/google/cloud/firestore/document_snapshot.rb +1 -1
  20. data/lib/google/cloud/firestore/errors.rb +60 -0
  21. data/lib/google/cloud/firestore/filter.rb +326 -0
  22. data/lib/google/cloud/firestore/promise/future.rb +97 -0
  23. data/lib/google/cloud/firestore/query.rb +112 -89
  24. data/lib/google/cloud/firestore/rate_limiter.rb +80 -0
  25. data/lib/google/cloud/firestore/service.rb +74 -23
  26. data/lib/google/cloud/firestore/transaction.rb +57 -4
  27. data/lib/google/cloud/firestore/version.rb +1 -1
  28. data/lib/google/cloud/firestore.rb +17 -7
  29. data/lib/google-cloud-firestore.rb +45 -8
  30. metadata +17 -146
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 0cb9b1838e2d0de1dd7a122b6395a7506e1c9ffdc237edc88ece03b38902694d
4
- data.tar.gz: 92cd04357a9295dec00b34c748cf0e1a9b7f44165915d41e8dac3b5eff40ef84
3
+ metadata.gz: 16163a09797c60820b760bb85283dc3ab8532aacc329dbdf0e8672ab7b8e4066
4
+ data.tar.gz: a502101923eaeffb2b8ca9112134ffc14e8971970509cb9f34e5263c5889a791
5
5
  SHA512:
6
- metadata.gz: 3fc0b6e13ba161fc579a969fdf3848621d8aaf45bdd6e64fa5ad2dc2a4d4efd4a934034724f03f7bdc7b2fb50a4976ea3c3fb6dbc99576ef274bbf435e1d0e02
7
- data.tar.gz: 465c31a8a2a581f90107b305d0d465e4e8c4da368c5b00651075b45031708a38e47e3e7a2deae8bacae32b8f8779ca164b68a5a99dfec1f6d0832d1f70d67089
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 Developers Console][dev-console].
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 slide-out navigation tray and select **API Manager**. From
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
- You should see a screen like one of the following.
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
- ![Re-use an existing service account][reuse-service-account]
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/stdlib/libdoc/logger/rdoc/Logger.html) as
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