google-cloud-firestore 2.13.1 → 2.14.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: 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