google-cloud-datastore 2.3.1 → 2.4.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: c300ee184929b5e46058e32af1e18a2e0e786e3eb17b32d24a265713e442b75d
4
- data.tar.gz: 06752add810608b745cc157a60fcfc23aa77ab54a7395f54e8f8b2d3867fc882
3
+ metadata.gz: c5cb153ea77e6581236392f42ec5755cde46733fc2331d6c6b7f204e171c4006
4
+ data.tar.gz: 57e1bde4b98c1f21b7d65d56255d66b79ab19c7d0a62d03d67fdbc90027fe1ca
5
5
  SHA512:
6
- metadata.gz: aa87df55a375dba1110cd28463a59f0c81e81cfa4aa513edeb380302f63e6e4610a1e5064a47af57753aa4e31c21c092276cbbf92325a6a55b9e3cffb7cbbf35
7
- data.tar.gz: f39b9d73f4c149cf633b376d10aa811b7f3e8a607e294753e0b796319312082771a112d049c90d548fd80c8024b7b4b18fa11940a88fe07a62ee8e16b7b61d3f
6
+ metadata.gz: 950fa042833ec644777f8b2e89ed0078f4c4629f4f32d6833b6de20d7f4f09a4563c96fbb9515a0eb6e3d76ace6d610e63178033a6d6318a0b2b897b91ccfb4e
7
+ data.tar.gz: 4c6757326810a722fc9c2543bcbb0135b15ad698cd5b9b5bfdfe33ae4f84bf8e9df437d8838784f0a71c3debf7c51d8a6be70ed671efc9382cefddd10ec2c672
data/CHANGELOG.md CHANGED
@@ -1,5 +1,11 @@
1
1
  # Release History
2
2
 
3
+ ### 2.4.0 (2023-02-02)
4
+
5
+ #### Features
6
+
7
+ * Support query count for Datastore ([#20039](https://github.com/googleapis/google-cloud-ruby/issues/20039))
8
+
3
9
  ### 2.3.1 (2022-12-14)
4
10
 
5
11
  #### Bug Fixes
@@ -0,0 +1,139 @@
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
+ require "google/cloud/datastore/v1"
17
+
18
+ module Google
19
+ module Cloud
20
+ module Datastore
21
+ ##
22
+ # # AggregateQuery
23
+ #
24
+ # An aggregate query can be used to fetch aggregate values (ex: count) for a query
25
+ #
26
+ # @example
27
+ # require "google/cloud/datastore"
28
+ #
29
+ # datastore = Google::Cloud::Datastore.new
30
+ #
31
+ # query = Google::Cloud::Datastore::Query.new
32
+ # query.kind("Task")
33
+ # .where("done", "=", false)
34
+ #
35
+ # Create an aggregate query
36
+ # aggregate_query = query.aggregate_query
37
+ # .add_count
38
+ #
39
+ # aggregate_query_results = dataset.run_aggregation aggregate_query
40
+ # puts aggregate_query_results.get
41
+ #
42
+ # @example Alias an aggregate query
43
+ # require "google/cloud/datastore"
44
+ #
45
+ # datastore = Google::Cloud::Datastore.new
46
+ #
47
+ # query = Google::Cloud::Datastore::Query.new
48
+ # query.kind("Task")
49
+ # .where("done", "=", false)
50
+ #
51
+ # Create an aggregate query
52
+ # aggregate_query = query.aggregate_query
53
+ # .add_count aggregate_alias: 'total'
54
+ #
55
+ # aggregate_query_results = dataset.run_aggregation aggregate_query
56
+ # puts aggregate_query_results.get('total')
57
+ #
58
+ class AggregateQuery
59
+ ##
60
+ # @private The Google::Cloud::Datastore::V1::Query object.
61
+ attr_reader :query
62
+
63
+ ##
64
+ # @private Array of Google::Cloud::Datastore::V1::AggregationQuery::Aggregation objects
65
+ attr_reader :aggregates
66
+
67
+ ##
68
+ # @private Creates a new AggregateQuery
69
+ def initialize query
70
+ @query = query
71
+ @aggregates = []
72
+ end
73
+
74
+ ##
75
+ # Adds a count aggregate.
76
+ #
77
+ # @param aggregate_alias [String] Alias to refer to the aggregate. Optional
78
+ #
79
+ # @return [AggregateQuery] The modified aggregate query object with the added count aggregate.
80
+ #
81
+ # @example
82
+ # require "google/cloud/datastore"
83
+ #
84
+ # datastore = Google::Cloud::Datastore.new
85
+ #
86
+ # query = Google::Cloud::Datastore::Query.new
87
+ # query.kind("Task")
88
+ # .where("done", "=", false)
89
+ #
90
+ # Create an aggregate query
91
+ # aggregate_query = query.aggregate_query
92
+ # .add_count
93
+ #
94
+ # aggregate_query_results = dataset.run_aggregation aggregate_query
95
+ # puts aggregate_query_results.get
96
+ #
97
+ # @example Alias an aggregate query
98
+ # require "google/cloud/datastore"
99
+ #
100
+ # datastore = Google::Cloud::Datastore.new
101
+ #
102
+ # query = Google::Cloud::Datastore::Query.new
103
+ # query.kind("Task")
104
+ # .where("done", "=", false)
105
+ #
106
+ # Create an aggregate query
107
+ # aggregate_query = query.aggregate_query
108
+ # .add_count aggregate_alias: 'total'
109
+ #
110
+ # aggregate_query_results = dataset.run_aggregation aggregate_query
111
+ # puts aggregate_query_results.get('total')
112
+ #
113
+ def add_count aggregate_alias: nil
114
+ aggregate_alias ||= ALIASES[:count]
115
+ aggregates << Google::Cloud::Datastore::V1::AggregationQuery::Aggregation.new(
116
+ count: Google::Cloud::Datastore::V1::AggregationQuery::Aggregation::Count.new,
117
+ alias: aggregate_alias
118
+ )
119
+
120
+ self
121
+ end
122
+
123
+ # @private
124
+ def to_grpc
125
+ Google::Cloud::Datastore::V1::AggregationQuery.new(
126
+ nested_query: query,
127
+ aggregations: aggregates
128
+ )
129
+ end
130
+
131
+ ##
132
+ # @private
133
+ ALIASES = {
134
+ count: "count"
135
+ }.freeze
136
+ end
137
+ end
138
+ end
139
+ end
@@ -0,0 +1,115 @@
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
+ module Google
16
+ module Cloud
17
+ module Datastore
18
+ class Dataset
19
+ ##
20
+ # # AggregateQueryResults
21
+ #
22
+ # An AggregateQueryResult object is a representation for
23
+ # a result of an AggregateQuery or a GqlQuery.
24
+ #
25
+ # @example
26
+ # require "google/cloud/datastore"
27
+ #
28
+ # datastore = Google::Cloud::Datastore.new
29
+ #
30
+ # query = Google::Cloud::Datastore::Query.new
31
+ # query.kind("Task")
32
+ # .where("done", "=", false)
33
+ #
34
+ # Create an aggregate query
35
+ # aggregate_query = query.aggregate_query
36
+ # .add_count
37
+ #
38
+ # aggregate_query_results = dataset.run_aggregation aggregate_query
39
+ # puts aggregate_query_results.get
40
+ #
41
+ class AggregateQueryResults
42
+ ##
43
+ # Read timestamp the query was done on the database at.
44
+ #
45
+ # @return Google::Protobuf::Timestamp
46
+ attr_reader :read_time
47
+
48
+ ##
49
+ # Retrieves the aggregate data.
50
+ #
51
+ # @param aggregate_alias [String] The alias used to access
52
+ # the aggregate value. For an AggregateQuery with a
53
+ # single aggregate field, this parameter can be omitted.
54
+ #
55
+ # @return [Integer] The aggregate value.
56
+ #
57
+ # @example
58
+ # require "google/cloud/datastore"
59
+ #
60
+ # datastore = Google::Cloud::Datastore.new
61
+ #
62
+ # query = Google::Cloud::Datastore::Query.new
63
+ # query.kind("Task")
64
+ # .where("done", "=", false)
65
+ #
66
+ # Create an aggregate query
67
+ # aggregate_query = query.aggregate_query
68
+ # .add_count
69
+ #
70
+ # aggregate_query_results = dataset.run_aggregation aggregate_query
71
+ # puts aggregate_query_results.get
72
+ #
73
+ # @example Alias an aggregate query
74
+ # require "google/cloud/datastore"
75
+ #
76
+ # datastore = Google::Cloud::Datastore.new
77
+ #
78
+ # query = Google::Cloud::Datastore::Query.new
79
+ # query.kind("Task")
80
+ # .where("done", "=", false)
81
+ #
82
+ # Create an aggregate query
83
+ # aggregate_query = query.aggregate_query
84
+ # .add_count aggregate_alias: 'total'
85
+ #
86
+ # aggregate_query_results = dataset.run_aggregation aggregate_query
87
+ # puts aggregate_query_results.get('total')
88
+ def get aggregate_alias = nil
89
+ if @aggregate_fields.count > 1 && aggregate_alias.nil?
90
+ raise ArgumentError, "Required param aggregate_alias for AggregateQuery with multiple aggregate fields"
91
+ end
92
+ aggregate_alias ||= @aggregate_fields.keys.first
93
+ @aggregate_fields[aggregate_alias]
94
+ end
95
+
96
+ ##
97
+ # @private New AggregateQueryResults from a
98
+ # Google::Cloud::Datastore::V1::RunAggregationQueryResponse object.
99
+ def self.from_grpc aggregate_query_response
100
+ aggregate_fields = aggregate_query_response
101
+ .batch
102
+ .aggregation_results[0]
103
+ .aggregate_properties
104
+ .to_h
105
+ .transform_values { |v| v[:integer_value] }
106
+ new.tap do |s|
107
+ s.instance_variable_set :@aggregate_fields, aggregate_fields
108
+ s.instance_variable_set :@read_time, aggregate_query_response.batch.read_time
109
+ end
110
+ end
111
+ end
112
+ end
113
+ end
114
+ end
115
+ end
@@ -24,6 +24,7 @@ require "google/cloud/datastore/gql_query"
24
24
  require "google/cloud/datastore/cursor"
25
25
  require "google/cloud/datastore/dataset/lookup_results"
26
26
  require "google/cloud/datastore/dataset/query_results"
27
+ require "google/cloud/datastore/dataset/aggregate_query_results"
27
28
  require "google/cloud/datastore/transaction"
28
29
  require "google/cloud/datastore/read_only_transaction"
29
30
 
@@ -453,6 +454,88 @@ module Google
453
454
  end
454
455
  alias run_query run
455
456
 
457
+ ##
458
+ # Retrieve aggregate results specified by an AggregateQuery.
459
+ #
460
+ # @param [AggregateQuery, GqlQuery] query The object with the aggregate criteria.
461
+ # @param [String] namespace The namespace the query is to run within.
462
+ # @param [Symbol] consistency The non-transactional read consistency to
463
+ # use. Cannot be set to `:strong` for global queries. Accepted values
464
+ # are `:eventual` and `:strong`.
465
+ #
466
+ # The default consistency depends on the type of query used. See
467
+ # [Eventual Consistency in Google Cloud
468
+ # Datastore](https://cloud.google.com/datastore/docs/articles/balancing-strong-and-eventual-consistency-with-google-cloud-datastore/#h.tf76fya5nqk8)
469
+ # for more information.
470
+ #
471
+ # @return [Google::Cloud::Datastore::Dataset::AggregateQueryResults]
472
+ #
473
+ # @example
474
+ # require "google/cloud/datastore"
475
+ #
476
+ # datastore = Google::Cloud::Datastore.new
477
+ #
478
+ # query = datastore.query("Task")
479
+ # .where("done", "=", false)
480
+ #
481
+ # aggregate_query = query.aggregate_query
482
+ #
483
+ # res = datastore.run_aggregation aggregate_query
484
+ #
485
+ # @example Run an aggregate ancestor query with eventual consistency:
486
+ # require "google/cloud/datastore"
487
+ #
488
+ # datastore = Google::Cloud::Datastore.new
489
+ #
490
+ # task_list_key = datastore.key "TaskList", "default"
491
+ # query = datastore.query.kind("Task")
492
+ # .ancestor(task_list_key)
493
+ #
494
+ # aggregate_query = query.aggregate_query
495
+ #
496
+ # res = datastore.run_aggregation aggregate_query, consistency: :eventual
497
+ #
498
+ # @example Run the aggregate query within a namespace with the `namespace` option:
499
+ # require "google/cloud/datastore"
500
+ #
501
+ # datastore = Google::Cloud::Datastore.new
502
+ #
503
+ # query = datastore.query("Task")
504
+ # .where("done", "=", false)
505
+ #
506
+ # aggregate_query = query.aggregate_query
507
+ #
508
+ # res = datastore.run_aggregation aggregate_query, namespace: "example-ns"
509
+ #
510
+ # @example Run the aggregate query with a GQL string.
511
+ # require "google/cloud/datastore"
512
+ #
513
+ # datastore = Google::Cloud::Datastore.new
514
+ #
515
+ # gql_query = datastore.gql "SELECT COUNT(*) FROM Task WHERE done = @done",
516
+ # done: false
517
+ # res = datastore.run_aggregation gql_query
518
+ #
519
+ # @example Run the aggregate GQL query within a namespace with `namespace` option:
520
+ # require "google/cloud/datastore"
521
+ #
522
+ # datastore = Google::Cloud::Datastore.new
523
+ #
524
+ # gql_query = datastore.gql "SELECT COUNT(*) FROM Task WHERE done = @done",
525
+ # done: false
526
+ # res = datastore.run_aggregation gql_query, namespace: "example-ns"
527
+ #
528
+ def run_aggregation aggregate_query, namespace: nil, consistency: nil
529
+ ensure_service!
530
+ unless aggregate_query.is_a?(AggregateQuery) || aggregate_query.is_a?(GqlQuery)
531
+ raise ArgumentError, "Cannot run a #{aggregate_query.class} object."
532
+ end
533
+ check_consistency! consistency
534
+ aggregate_query_res = service.run_aggregation_query aggregate_query.to_grpc, namespace,
535
+ consistency: consistency
536
+ AggregateQueryResults.from_grpc aggregate_query_res
537
+ end
538
+
456
539
  ##
457
540
  # Creates a Datastore Transaction.
458
541
  #
@@ -15,6 +15,7 @@
15
15
 
16
16
  require "google/cloud/datastore/entity"
17
17
  require "google/cloud/datastore/key"
18
+ require "google/cloud/datastore/aggregate_query"
18
19
 
19
20
  module Google
20
21
  module Cloud
@@ -425,6 +426,27 @@ module Google
425
426
  end
426
427
  alias distinct_on group_by
427
428
 
429
+ ##
430
+ # Creates an AggregateQuery object for the query.
431
+ #
432
+ # @return [AggregateQuery] New empty aggregate query.
433
+ #
434
+ # @example
435
+ # require "google/cloud/datastore"
436
+ #
437
+ # datastore = Google::Cloud::Datastore.new
438
+ #
439
+ # query = Google::Cloud::Datastore::Query.new
440
+ # query.kind("Task")
441
+ # .where("done", "=", false)
442
+ #
443
+ # Create an aggregate query
444
+ # aggregate_query = query.aggregate_query
445
+ #
446
+ def aggregate_query
447
+ AggregateQuery.new @grpc
448
+ end
449
+
428
450
  # @private
429
451
  def to_grpc
430
452
  @grpc
@@ -157,6 +157,37 @@ module Google
157
157
  end
158
158
  alias run_query run
159
159
 
160
+ ##
161
+ # Retrieve aggregate query results specified by an AggregateQuery. The query is run within the
162
+ # transaction.
163
+ #
164
+ # @param [AggregateQuery, GqlQuery] query The Query object with the search criteria.
165
+ # @param [String] namespace The namespace the query is to run within.
166
+ #
167
+ # @return [Google::Cloud::Datastore::Dataset::AggregateQueryResults]
168
+ #
169
+ # @example
170
+ # require "google/cloud/datastore"
171
+ #
172
+ # datastore = Google::Cloud::Datastore.new
173
+ #
174
+ # datastore.read_only_transaction do |tx|
175
+ # query = tx.query("Task")
176
+ # .where("done", "=", false)
177
+ # aggregate_query = query.aggregate_query
178
+ # .add_count
179
+ # res = tx.run_aggregation aggregate_query
180
+ # end
181
+ #
182
+ def run_aggregation aggregate_query, namespace: nil
183
+ ensure_service!
184
+ unless aggregate_query.is_a?(AggregateQuery) || aggregate_query.is_a?(GqlQuery)
185
+ raise ArgumentError, "Cannot run a #{aggregate_query.class} object."
186
+ end
187
+ aggregate_query_results = service.run_aggregation_query aggregate_query.to_grpc, namespace, transaction: @id
188
+ Dataset::AggregateQueryResults.from_grpc aggregate_query_results
189
+ end
190
+
160
191
  ##
161
192
  # Begins a transaction.
162
193
  # This method is run when a new ReadOnlyTransaction is created.
@@ -88,6 +88,27 @@ module Google
88
88
  gql_query: gql_query
89
89
  end
90
90
 
91
+ ## Query for aggregates
92
+ def run_aggregation_query query, namespace = nil, consistency: nil, transaction: nil
93
+ gql_query = nil
94
+ if query.is_a? Google::Cloud::Datastore::V1::GqlQuery
95
+ gql_query = query
96
+ query = nil
97
+ end
98
+ read_options = generate_read_options consistency, transaction
99
+ if namespace
100
+ partition_id = Google::Cloud::Datastore::V1::PartitionId.new(
101
+ namespace_id: namespace
102
+ )
103
+ end
104
+
105
+ service.run_aggregation_query project_id: project,
106
+ partition_id: partition_id,
107
+ read_options: read_options,
108
+ aggregation_query: query,
109
+ gql_query: gql_query
110
+ end
111
+
91
112
  ##
92
113
  # Begin a new transaction.
93
114
  def begin_transaction read_only: nil, previous_transaction: nil
@@ -16,7 +16,7 @@
16
16
  module Google
17
17
  module Cloud
18
18
  module Datastore
19
- VERSION = "2.3.1".freeze
19
+ VERSION = "2.4.0".freeze
20
20
  end
21
21
  end
22
22
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: google-cloud-datastore
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.3.1
4
+ version: 2.4.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Mike Moore
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2022-12-14 00:00:00.000000000 Z
12
+ date: 2023-02-03 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: google-cloud-core
@@ -199,11 +199,13 @@ files:
199
199
  - TROUBLESHOOTING.md
200
200
  - lib/google-cloud-datastore.rb
201
201
  - lib/google/cloud/datastore.rb
202
+ - lib/google/cloud/datastore/aggregate_query.rb
202
203
  - lib/google/cloud/datastore/commit.rb
203
204
  - lib/google/cloud/datastore/convert.rb
204
205
  - lib/google/cloud/datastore/credentials.rb
205
206
  - lib/google/cloud/datastore/cursor.rb
206
207
  - lib/google/cloud/datastore/dataset.rb
208
+ - lib/google/cloud/datastore/dataset/aggregate_query_results.rb
207
209
  - lib/google/cloud/datastore/dataset/lookup_results.rb
208
210
  - lib/google/cloud/datastore/dataset/query_results.rb
209
211
  - lib/google/cloud/datastore/entity.rb
@@ -235,7 +237,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
235
237
  - !ruby/object:Gem::Version
236
238
  version: '0'
237
239
  requirements: []
238
- rubygems_version: 3.3.14
240
+ rubygems_version: 3.4.2
239
241
  signing_key:
240
242
  specification_version: 4
241
243
  summary: API Client library for Google Cloud Datastore