google-cloud-firestore 2.7.1 → 2.8.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: f45d22f61cfd606f0a800da541058804c823a60d38896e77aac5ca72b01b34f4
4
- data.tar.gz: 320a237aa81d52be3add1144de0d0bee460eb90786f4ab878e93ad79fd2c862f
3
+ metadata.gz: 389203f8e3c58b6e61e856d294ae723f1b9101119d36172a5a503408bab5e629
4
+ data.tar.gz: e1cfa1b4c701550f80da65ee573e83bea391cd1fd1cb7e605b215b91facbba05
5
5
  SHA512:
6
- metadata.gz: d56c986ef8914c7b486d5c4877e4fdd681051b2203332f9a83278365826438353df177a3fb4a80bb9a11b8c33b6b190dd97e475c1de2273d11f759e01f2d7daa
7
- data.tar.gz: b2916ce31ded50b667377bbc397356153cffeeff1a8c3f4ef71426211f5c1ed9ffe5ab53a319355d9ecbccf5079e1dd0617bc11e1c42f2009d1444d19ee840e1
6
+ metadata.gz: adcda0a3707c9e0c1055fef937e46c6080db4960ac86a9572780d495722c9a0cdfb39ab07c0d6134c51584c18e43661e06d7c167b1bcf03c773adfdf52bda85a
7
+ data.tar.gz: 9649e1d619412c0e7786f2e78e47dcb0913c0bd989ca95bab358c9c0a8bd8bd7a1047abba62268a4114a6a2b935446f69987ba86bbf922a8b30193d7ea165d3a
data/CHANGELOG.md CHANGED
@@ -1,5 +1,20 @@
1
1
  # Release History
2
2
 
3
+ ### 2.8.0 (2023-01-05)
4
+
5
+ #### Features
6
+
7
+ * Support query count for Firestore ([#19457](https://github.com/googleapis/google-cloud-ruby/issues/19457))
8
+ #### Bug Fixes
9
+
10
+ * Add support for merging null field in a document ([#19918](https://github.com/googleapis/google-cloud-ruby/issues/19918))
11
+
12
+ ### 2.7.2 (2022-08-24)
13
+
14
+ #### Documentation
15
+
16
+ * fix firestore emulator guide ([#19045](https://github.com/googleapis/google-cloud-ruby/issues/19045))
17
+
3
18
  ### 2.7.1 (2022-07-15)
4
19
 
5
20
  #### Bug Fixes
data/EMULATOR.md CHANGED
@@ -2,19 +2,21 @@
2
2
 
3
3
  To develop and test your application locally, you can use the [Google Cloud
4
4
  Firestore
5
- Emulator](https://cloud.google.com/firestore/docs/security/test-rules-emulator#install_the_emulator),
6
- which provides local emulation of the production Google Cloud Firestore
7
- environment. You can start the Google Cloud Firestore emulator using the
8
- [`firebase` command-line tool](https://firebase.google.com/docs/cli/).
5
+ Emulator](https://cloud.google.com/sdk/gcloud/reference/beta/emulators/firestore/),
6
+ which provides local emulation of the production Google Cloud Firestore
7
+ environment. You can start the Google Cloud Firestore emulator using
8
+ the `gcloud` command-line tool.
9
+
10
+ `gcloud beta emulators firestore start --host-port=0.0.0.0:8080`
9
11
 
10
12
  When you run the Cloud Firestore emulator you will see a message similar to the
11
13
  following printed:
12
14
 
13
15
  ```
14
- $ firebase serve --only firestore
15
- API endpoint: http://[::1]:8080
16
- API endpoint: http://127.0.0.1:8080
17
- Dev App Server is now running.
16
+ If you are using a library that supports the FIRESTORE_EMULATOR_HOST
17
+ environment variable, run:
18
+
19
+ export FIRESTORE_EMULATOR_HOST=localhost:8080
18
20
  ```
19
21
 
20
22
  Now you can connect to the emulator using the `FIRESTORE_EMULATOR_HOST`
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,202 @@
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('count')
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::V1::StructuredQuery object.
71
+ attr_reader :query
72
+
73
+ ##
74
+ # @private Array of Google::Cloud::Firestore::V1::StructuredAggregationQuery::Aggregation objects
75
+ attr_reader :aggregates
76
+
77
+ ##
78
+ # @private Creates a new AggregateQuery
79
+ def initialize query, parent_path, client, aggregates: []
80
+ @query = query
81
+ @parent_path = parent_path
82
+ @aggregates = aggregates
83
+ @client = client
84
+ end
85
+
86
+ ##
87
+ # Adds a count aggregate.
88
+ #
89
+ # @param [aggregate_alias] Alias to refer to the aggregate. Optional
90
+ #
91
+ # @return [AggregateQuery] A new aggregate query with the added count aggregate.
92
+ #
93
+ # @example
94
+ # require "google/cloud/firestore"
95
+ #
96
+ # firestore = Google::Cloud::Firestore.new
97
+ #
98
+ # query = firestore.col "cities"
99
+ #
100
+ # # Create an aggregate query
101
+ # aggregate_query = query.aggregate_query
102
+ # .add_count
103
+ #
104
+ # aggregate_query.get do |aggregate_snapshot|
105
+ # puts aggregate_snapshot.get('count')
106
+ # end
107
+ #
108
+ def add_count aggregate_alias: nil
109
+ aggregate_alias ||= ALIASES[:count]
110
+ new_aggregates = @aggregates.dup
111
+ new_aggregates << StructuredAggregationQuery::Aggregation.new(
112
+ count: StructuredAggregationQuery::Aggregation::Count.new,
113
+ alias: aggregate_alias
114
+ )
115
+ AggregateQuery.start query, new_aggregates, parent_path, client
116
+ end
117
+
118
+ ##
119
+ # Retrieves aggregate snapshot for the query.
120
+ #
121
+ # @yield [snapshot] The block for accessing the aggregate query snapshots.
122
+ # @yieldparam [AggregateQuerySnapshot] An aggregate query snapshot.
123
+ #
124
+ # @return [Enumerator<AggregateQuerySnapshot>] A list of aggregate query snapshots.
125
+ #
126
+ # @example
127
+ # require "google/cloud/firestore"
128
+ #
129
+ # firestore = Google::Cloud::Firestore.new
130
+ #
131
+ # query = firestore.col "cities"
132
+ #
133
+ # # Create an aggregate query
134
+ # aggregate_query = query.aggregate_query
135
+ # .add_count
136
+ #
137
+ # aggregate_query.get do |aggregate_snapshot|
138
+ # puts aggregate_snapshot.get('count')
139
+ # end
140
+ #
141
+ def get
142
+ ensure_service!
143
+
144
+ return enum_for :get unless block_given?
145
+
146
+ responses = service.run_aggregate_query @parent_path, structured_aggregation_query
147
+ responses.each do |response|
148
+ next if response.result.nil?
149
+ yield AggregateQuerySnapshot.from_run_aggregate_query_response response
150
+ end
151
+ end
152
+
153
+ ##
154
+ # @private Creates a Google::Cloud::Firestore::V1::StructuredAggregationQuery object
155
+ def structured_aggregation_query
156
+ StructuredAggregationQuery.new(
157
+ structured_query: @query,
158
+ aggregations: @aggregates
159
+ )
160
+ end
161
+
162
+ ##
163
+ # @private Start a new AggregateQuery.
164
+ def self.start query, aggregates, parent_path, client
165
+ new query, parent_path, client, aggregates: aggregates
166
+ end
167
+
168
+ protected
169
+
170
+ ##
171
+ # @private
172
+ StructuredAggregationQuery = Google::Cloud::Firestore::V1::StructuredAggregationQuery
173
+
174
+ ##
175
+ # @private
176
+ ALIASES = {
177
+ count: "count"
178
+ }.freeze
179
+
180
+ ##
181
+ # @private Raise an error unless a database is available.
182
+ def ensure_client!
183
+ raise "Must have active connection to service" unless client
184
+ end
185
+
186
+ ##
187
+ # @private Raise an error unless an active connection to the service
188
+ # is available.
189
+ def ensure_service!
190
+ raise "Must have active connection to service" unless service
191
+ end
192
+
193
+ ##
194
+ # @private The Service object.
195
+ def service
196
+ ensure_client!
197
+ client.service
198
+ end
199
+ end
200
+ end
201
+ end
202
+ end
@@ -0,0 +1,85 @@
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('count')
38
+ # end
39
+ #
40
+ class AggregateQuerySnapshot
41
+ ##
42
+ # Retrieves the aggregate data.
43
+ #
44
+ # @param [String] aggregate_alias The alias used
45
+ # to access the aggregate value. For count, the
46
+ # default value is "count".
47
+ #
48
+ # @return [Integer] The aggregate value.
49
+ #
50
+ # @example
51
+ # require "google/cloud/firestore"
52
+ #
53
+ # firestore = Google::Cloud::Firestore.new
54
+ #
55
+ # query = firestore.col "cities"
56
+ #
57
+ # # Create an aggregate query
58
+ # aggregate_query = query.aggregate_query
59
+ # .add_count
60
+ #
61
+ # aggregate_query.get do |aggregate_snapshot|
62
+ # puts aggregate_snapshot.get('count')
63
+ # end
64
+ def get aggregate_alias
65
+ @aggregate_fields[aggregate_alias]
66
+ end
67
+
68
+ ##
69
+ # @private New AggregateQuerySnapshot from a
70
+ # Google::Cloud::Firestore::V1::RunAggregationQueryResponse object.
71
+ def self.from_run_aggregate_query_response response
72
+ aggregate_fields = response
73
+ .result
74
+ .aggregate_fields
75
+ .to_h # convert from protobuf to ruby map
76
+ .transform_values { |v| v[:integer_value] }
77
+
78
+ new.tap do |s|
79
+ s.instance_variable_set :@aggregate_fields, aggregate_fields
80
+ end
81
+ end
82
+ end
83
+ end
84
+ end
85
+ end
@@ -498,7 +498,6 @@ module Google
498
498
  dup_hash = dup_hash[field]
499
499
  end
500
500
  prev_hash[last_field] = dup_hash
501
- prev_hash.delete_if { |_k, v| v.nil? }
502
501
  ret_hash
503
502
  end
504
503
 
@@ -17,6 +17,7 @@ require "google/cloud/firestore/v1"
17
17
  require "google/cloud/firestore/document_snapshot"
18
18
  require "google/cloud/firestore/query_listener"
19
19
  require "google/cloud/firestore/convert"
20
+ require "google/cloud/firestore/aggregate_query"
20
21
  require "json"
21
22
 
22
23
  module Google
@@ -940,6 +941,26 @@ module Google
940
941
  end
941
942
  alias run get
942
943
 
944
+ ##
945
+ # Creates an AggregateQuery object for the query.
946
+ #
947
+ # @return [AggregateQuery] New empty aggregate query.
948
+ #
949
+ # @example
950
+ # require "google/cloud/firestore"
951
+ #
952
+ # firestore = Google::Cloud::Firestore.new
953
+ #
954
+ # # Get a collection reference
955
+ # query = firestore.col "cities"
956
+ #
957
+ # # Create an aggregate query
958
+ # aggregate_query = query.aggregate_query
959
+ #
960
+ def aggregate_query
961
+ AggregateQuery.new query, parent_path, client
962
+ end
963
+
943
964
  ##
944
965
  # Listen to this query for changes.
945
966
  #
@@ -124,6 +124,21 @@ module Google
124
124
  firestore.run_query run_query_req, call_options(parent: database_path)
125
125
  end
126
126
 
127
+ ##
128
+ # Returns Google::Cloud::Firestore::V1::RunAggregationQueryResponse
129
+ def run_aggregate_query parent, structured_aggregation_query, transaction: nil
130
+ request = Google::Cloud::Firestore::V1::RunAggregationQueryRequest.new(
131
+ parent: parent,
132
+ structured_aggregation_query: structured_aggregation_query
133
+ )
134
+ if transaction.is_a? String
135
+ request.transaction = transaction
136
+ elsif transaction
137
+ request.new_transaction = transaction
138
+ end
139
+ firestore.run_aggregation_query request
140
+ end
141
+
127
142
  def listen enum
128
143
  firestore.listen enum, call_options(parent: database_path)
129
144
  end
@@ -269,6 +269,45 @@ module Google
269
269
  end
270
270
  alias run get
271
271
 
272
+ ##
273
+ # Retrieves aggregate query snapshots for the given value. Valid values can be
274
+ # a string representing either a document or a collection of documents,
275
+ # a document reference object, a collection reference object, or a query
276
+ # to be run.
277
+ #
278
+ # @param [AggregateQuery] aggregate_query
279
+ # An AggregateQuery object
280
+ #
281
+ # @yield [documents] The block for accessing the aggregate query snapshot.
282
+ # @yieldparam [AggregateQuerySnapshot] aggregate_snapshot An aggregate query snapshot.
283
+ #
284
+ # @example
285
+ # require "google/cloud/firestore"
286
+ #
287
+ # firestore = Google::Cloud::Firestore.new
288
+ #
289
+ # firestore.transaction do |tx|
290
+ # tx.get_aggregate aq do |aggregate_snapshot|
291
+ # puts aggregate_snapshot.get('count')
292
+ # end
293
+ # end
294
+ #
295
+ def get_aggregate aggregate_query
296
+ ensure_not_closed!
297
+ ensure_service!
298
+
299
+ return enum_for :get_aggregate, aggregate_query unless block_given?
300
+
301
+ results = service.run_aggregate_query aggregate_query.parent_path,
302
+ aggregate_query.structured_aggregation_query,
303
+ transaction: transaction_or_create
304
+ results.each do |result|
305
+ extract_transaction_from_result! result
306
+ next if result.result.nil?
307
+ yield AggregateQuerySnapshot.from_run_aggregate_query_response result
308
+ end
309
+ end
310
+
272
311
  # @!endgroup
273
312
 
274
313
  # @!group Modifications
@@ -16,7 +16,7 @@
16
16
  module Google
17
17
  module Cloud
18
18
  module Firestore
19
- VERSION = "2.7.1".freeze
19
+ VERSION = "2.8.0".freeze
20
20
  end
21
21
  end
22
22
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: google-cloud-firestore
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.7.1
4
+ version: 2.8.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Google Inc
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2022-07-15 00:00:00.000000000 Z
11
+ date: 2023-01-06 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: google-cloud-core
@@ -225,6 +225,8 @@ files:
225
225
  - TROUBLESHOOTING.md
226
226
  - lib/google-cloud-firestore.rb
227
227
  - lib/google/cloud/firestore.rb
228
+ - lib/google/cloud/firestore/aggregate_query.rb
229
+ - lib/google/cloud/firestore/aggregate_query_snapshot.rb
228
230
  - lib/google/cloud/firestore/batch.rb
229
231
  - lib/google/cloud/firestore/client.rb
230
232
  - lib/google/cloud/firestore/collection_group.rb