google-cloud-firestore 2.13.1 → 2.14.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 30cb17b1e946e584cbe565b74143e0051f93bc4666f11a183a0f3f0a541b8a9d
4
- data.tar.gz: 18b71ed2191e4f15e6bc667f8e6825e1c33d66dc3f98a7753536cd87a6dff177
3
+ metadata.gz: 9ff9b426ba1d870f0620a434f5e826f81cd878b09fa9aad5838d97245974b23c
4
+ data.tar.gz: 9f798211b2b5252f9992f1bf1f8c413cfd99154ee656c1b9d8e72ec6945fbc64
5
5
  SHA512:
6
- metadata.gz: 539e3c8a868b4ece85550090a53829d615ba519bf4e0eaaea4e7ac5601977be51c5978fc8eb5ac12d2ea4e3e8c4b803c0a6a406111c381d45983516accafb3c0
7
- data.tar.gz: a95df5fec2c114cbdde41bd78b6835664865d09a900b445f2b4deb595a4ba6cd761f777c9ce08746604b7289727d9f36b218033e3bde6261365f6835d4ab3df8
6
+ metadata.gz: 587f4928f11528d167b2f6649a1be0b43b29c109192c200c8825315e506671321345a4bd0880652be59d44ab3349dce5ea30dd84921a10d973539e9c67dfd691
7
+ data.tar.gz: 8df7d3795cc14f938b883877ee78940e2a0935b5494f799216676814533b2b77d35c66806a1677ada54a7430ed3868ce8be9b423a75dab7d60ea9b5444430040
data/CHANGELOG.md CHANGED
@@ -1,5 +1,11 @@
1
1
  # Release History
2
2
 
3
+ ### 2.14.0 (2024-01-31)
4
+
5
+ #### Features
6
+
7
+ * Support sum & avg aggregate functions ([#23446](https://github.com/googleapis/google-cloud-ruby/issues/23446))
8
+
3
9
  ### 2.13.1 (2023-06-16)
4
10
 
5
11
  #### Documentation
@@ -67,26 +67,39 @@ module Google
67
67
  attr_reader :parent_path
68
68
 
69
69
  ##
70
- # @private The Google::Cloud::Firestore::V1::StructuredQuery object.
70
+ # @private The Google::Cloud::Firestore::Query object.
71
71
  attr_reader :query
72
72
 
73
73
  ##
74
- # @private Array of Google::Cloud::Firestore::V1::StructuredAggregationQuery::Aggregation objects
75
- attr_reader :aggregates
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
76
86
 
77
87
  ##
78
88
  # @private Creates a new AggregateQuery
79
- def initialize query, parent_path, client, aggregates: []
89
+ def initialize query, parent_path, client
80
90
  @query = query
81
91
  @parent_path = parent_path
82
- @aggregates = aggregates
83
92
  @client = client
93
+ @grpc = Google::Cloud::Firestore::V1::StructuredAggregationQuery.new(
94
+ structured_query: @query.query,
95
+ aggregations: []
96
+ )
84
97
  end
85
98
 
86
99
  ##
87
100
  # Adds a count aggregate.
88
101
  #
89
- # @param [aggregate_alias] Alias to refer to the aggregate. Optional
102
+ # @param aggregate_alias [String] Alias to refer to the aggregate. Optional
90
103
  #
91
104
  # @return [AggregateQuery] A new aggregate query with the added count aggregate.
92
105
  #
@@ -106,13 +119,102 @@ module Google
106
119
  # end
107
120
  #
108
121
  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,
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
+ ),
113
163
  alias: aggregate_alias
114
164
  )
115
- AggregateQuery.start query, new_aggregates, parent_path, client
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).concat([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
116
218
  end
117
219
 
118
220
  ##
@@ -143,7 +245,7 @@ module Google
143
245
 
144
246
  return enum_for :get unless block_given?
145
247
 
146
- responses = service.run_aggregate_query @parent_path, structured_aggregation_query
248
+ responses = service.run_aggregate_query @parent_path, @grpc
147
249
  responses.each do |response|
148
250
  next if response.result.nil?
149
251
  yield AggregateQuerySnapshot.from_run_aggregate_query_response response
@@ -151,32 +253,13 @@ module Google
151
253
  end
152
254
 
153
255
  ##
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
256
+ # @private
257
+ def to_grpc
258
+ @grpc
166
259
  end
167
260
 
168
261
  protected
169
262
 
170
- ##
171
- # @private
172
- StructuredAggregationQuery = Google::Cloud::Firestore::V1::StructuredAggregationQuery
173
-
174
- ##
175
- # @private
176
- ALIASES = {
177
- count: "count"
178
- }.freeze
179
-
180
263
  ##
181
264
  # @private Raise an error unless a database is available.
182
265
  def ensure_client!
@@ -53,6 +53,19 @@ module Google
53
53
  # puts aggregate_snapshot.get('total')
54
54
  # end
55
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
+
56
69
  ##
57
70
  # Retrieves the aggregate data.
58
71
  #
@@ -60,7 +73,9 @@ module Google
60
73
  # the aggregate value. For an AggregateQuery with a
61
74
  # single aggregate field, this parameter can be omitted.
62
75
  #
63
- # @return [Integer] The aggregate value.
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.
64
79
  #
65
80
  # @example
66
81
  # require "google/cloud/firestore"
@@ -104,11 +119,21 @@ module Google
104
119
  # @private New AggregateQuerySnapshot from a
105
120
  # Google::Cloud::Firestore::V1::RunAggregationQueryResponse object.
106
121
  def self.from_run_aggregate_query_response response
122
+ # rubocop:disable Style/MapToHash
107
123
  aggregate_fields = response
108
124
  .result
109
125
  .aggregate_fields
110
- .to_h # convert from protobuf to ruby map
111
- .transform_values { |v| v[:integer_value] }
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
112
137
 
113
138
  new.tap do |s|
114
139
  s.instance_variable_set :@aggregate_fields, aggregate_fields
@@ -1018,7 +1018,7 @@ module Google
1018
1018
  # aggregate_query = query.aggregate_query
1019
1019
  #
1020
1020
  def aggregate_query
1021
- AggregateQuery.new query, parent_path, client
1021
+ AggregateQuery.new self, parent_path, client
1022
1022
  end
1023
1023
 
1024
1024
  ##
@@ -305,7 +305,7 @@ module Google
305
305
  return enum_for :get_aggregate, aggregate_query unless block_given?
306
306
 
307
307
  results = service.run_aggregate_query aggregate_query.parent_path,
308
- aggregate_query.structured_aggregation_query,
308
+ aggregate_query.to_grpc,
309
309
  transaction: transaction_or_create
310
310
  results.each do |result|
311
311
  extract_transaction_from_result! result
@@ -16,7 +16,7 @@
16
16
  module Google
17
17
  module Cloud
18
18
  module Firestore
19
- VERSION = "2.13.1".freeze
19
+ VERSION = "2.14.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.13.1
4
+ version: 2.14.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: 2023-06-16 00:00:00.000000000 Z
11
+ date: 2024-01-31 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: google-cloud-core
@@ -283,7 +283,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
283
283
  - !ruby/object:Gem::Version
284
284
  version: '0'
285
285
  requirements: []
286
- rubygems_version: 3.4.2
286
+ rubygems_version: 3.5.3
287
287
  signing_key:
288
288
  specification_version: 4
289
289
  summary: API Client library for Google Cloud Firestore API