google-cloud-datastore 2.3.1 → 2.5.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 +4 -4
- data/CHANGELOG.md +12 -0
- data/lib/google/cloud/datastore/aggregate_query.rb +139 -0
- data/lib/google/cloud/datastore/dataset/aggregate_query_results.rb +115 -0
- data/lib/google/cloud/datastore/dataset.rb +103 -0
- data/lib/google/cloud/datastore/key.rb +24 -2
- data/lib/google/cloud/datastore/query.rb +22 -0
- data/lib/google/cloud/datastore/read_only_transaction.rb +31 -0
- data/lib/google/cloud/datastore/service.rb +33 -8
- data/lib/google/cloud/datastore/version.rb +1 -1
- data/lib/google/cloud/datastore.rb +18 -6
- data/lib/google-cloud-datastore.rb +8 -6
- metadata +5 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: ded45a15f44ec5a2e095ef0369db26c2a4a65e59c2af1e08bb8f6028736062ea
|
4
|
+
data.tar.gz: 8d7321547294a1c1ab492df132e19300a0466f252e74f9c7122fb7941bbaeac7
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 8a4039bbc1c34698507c3b7a1e2c22b011f4df3ea66a57927c7dd147c4468d97c85f15b49efa6c06dcb124815ad5fc4098eeaa8e6f54d23570489e6da0d8dbf3
|
7
|
+
data.tar.gz: af0981ba4ea2bd054ba35ddd372399addbbb5e0d0c8e4032f518b48ab03065771af8a6185dea29483a9948ae42147011c0f6a100c747dd08100736780a5cb286
|
data/CHANGELOG.md
CHANGED
@@ -1,5 +1,17 @@
|
|
1
1
|
# Release History
|
2
2
|
|
3
|
+
### 2.5.0 (2023-02-09)
|
4
|
+
|
5
|
+
#### Features
|
6
|
+
|
7
|
+
* Added support for multiple database ([#20038](https://github.com/googleapis/google-cloud-ruby/issues/20038))
|
8
|
+
|
9
|
+
### 2.4.0 (2023-02-02)
|
10
|
+
|
11
|
+
#### Features
|
12
|
+
|
13
|
+
* Support query count for Datastore ([#20039](https://github.com/googleapis/google-cloud-ruby/issues/20039))
|
14
|
+
|
3
15
|
### 2.3.1 (2022-12-14)
|
4
16
|
|
5
17
|
#### 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
|
|
@@ -83,6 +84,26 @@ module Google
|
|
83
84
|
end
|
84
85
|
alias project project_id
|
85
86
|
|
87
|
+
##
|
88
|
+
# The Datastore database connected to.
|
89
|
+
#
|
90
|
+
# @return [String] ID of the database
|
91
|
+
#
|
92
|
+
# @example
|
93
|
+
# require "google/cloud/datastore"
|
94
|
+
#
|
95
|
+
# datastore = Google::Cloud::Datastore.new(
|
96
|
+
# project_id: "my-todo-project",
|
97
|
+
# credentials: "/path/to/keyfile.json",
|
98
|
+
# database_id: "my-database"
|
99
|
+
# )
|
100
|
+
#
|
101
|
+
# datastore.database_id #=> "my-database"
|
102
|
+
#
|
103
|
+
def database_id
|
104
|
+
service.database
|
105
|
+
end
|
106
|
+
|
86
107
|
##
|
87
108
|
# Generate IDs for a Key before creating an entity.
|
88
109
|
#
|
@@ -453,6 +474,88 @@ module Google
|
|
453
474
|
end
|
454
475
|
alias run_query run
|
455
476
|
|
477
|
+
##
|
478
|
+
# Retrieve aggregate results specified by an AggregateQuery.
|
479
|
+
#
|
480
|
+
# @param [AggregateQuery, GqlQuery] query The object with the aggregate criteria.
|
481
|
+
# @param [String] namespace The namespace the query is to run within.
|
482
|
+
# @param [Symbol] consistency The non-transactional read consistency to
|
483
|
+
# use. Cannot be set to `:strong` for global queries. Accepted values
|
484
|
+
# are `:eventual` and `:strong`.
|
485
|
+
#
|
486
|
+
# The default consistency depends on the type of query used. See
|
487
|
+
# [Eventual Consistency in Google Cloud
|
488
|
+
# Datastore](https://cloud.google.com/datastore/docs/articles/balancing-strong-and-eventual-consistency-with-google-cloud-datastore/#h.tf76fya5nqk8)
|
489
|
+
# for more information.
|
490
|
+
#
|
491
|
+
# @return [Google::Cloud::Datastore::Dataset::AggregateQueryResults]
|
492
|
+
#
|
493
|
+
# @example
|
494
|
+
# require "google/cloud/datastore"
|
495
|
+
#
|
496
|
+
# datastore = Google::Cloud::Datastore.new
|
497
|
+
#
|
498
|
+
# query = datastore.query("Task")
|
499
|
+
# .where("done", "=", false)
|
500
|
+
#
|
501
|
+
# aggregate_query = query.aggregate_query
|
502
|
+
#
|
503
|
+
# res = datastore.run_aggregation aggregate_query
|
504
|
+
#
|
505
|
+
# @example Run an aggregate ancestor query with eventual consistency:
|
506
|
+
# require "google/cloud/datastore"
|
507
|
+
#
|
508
|
+
# datastore = Google::Cloud::Datastore.new
|
509
|
+
#
|
510
|
+
# task_list_key = datastore.key "TaskList", "default"
|
511
|
+
# query = datastore.query.kind("Task")
|
512
|
+
# .ancestor(task_list_key)
|
513
|
+
#
|
514
|
+
# aggregate_query = query.aggregate_query
|
515
|
+
#
|
516
|
+
# res = datastore.run_aggregation aggregate_query, consistency: :eventual
|
517
|
+
#
|
518
|
+
# @example Run the aggregate query within a namespace with the `namespace` option:
|
519
|
+
# require "google/cloud/datastore"
|
520
|
+
#
|
521
|
+
# datastore = Google::Cloud::Datastore.new
|
522
|
+
#
|
523
|
+
# query = datastore.query("Task")
|
524
|
+
# .where("done", "=", false)
|
525
|
+
#
|
526
|
+
# aggregate_query = query.aggregate_query
|
527
|
+
#
|
528
|
+
# res = datastore.run_aggregation aggregate_query, namespace: "example-ns"
|
529
|
+
#
|
530
|
+
# @example Run the aggregate query with a GQL string.
|
531
|
+
# require "google/cloud/datastore"
|
532
|
+
#
|
533
|
+
# datastore = Google::Cloud::Datastore.new
|
534
|
+
#
|
535
|
+
# gql_query = datastore.gql "SELECT COUNT(*) FROM Task WHERE done = @done",
|
536
|
+
# done: false
|
537
|
+
# res = datastore.run_aggregation gql_query
|
538
|
+
#
|
539
|
+
# @example Run the aggregate GQL query within a namespace with `namespace` option:
|
540
|
+
# require "google/cloud/datastore"
|
541
|
+
#
|
542
|
+
# datastore = Google::Cloud::Datastore.new
|
543
|
+
#
|
544
|
+
# gql_query = datastore.gql "SELECT COUNT(*) FROM Task WHERE done = @done",
|
545
|
+
# done: false
|
546
|
+
# res = datastore.run_aggregation gql_query, namespace: "example-ns"
|
547
|
+
#
|
548
|
+
def run_aggregation aggregate_query, namespace: nil, consistency: nil
|
549
|
+
ensure_service!
|
550
|
+
unless aggregate_query.is_a?(AggregateQuery) || aggregate_query.is_a?(GqlQuery)
|
551
|
+
raise ArgumentError, "Cannot run a #{aggregate_query.class} object."
|
552
|
+
end
|
553
|
+
check_consistency! consistency
|
554
|
+
aggregate_query_res = service.run_aggregation_query aggregate_query.to_grpc, namespace,
|
555
|
+
consistency: consistency
|
556
|
+
AggregateQueryResults.from_grpc aggregate_query_res
|
557
|
+
end
|
558
|
+
|
456
559
|
##
|
457
560
|
# Creates a Datastore Transaction.
|
458
561
|
#
|
@@ -69,6 +69,27 @@ module Google
|
|
69
69
|
alias dataset_id project
|
70
70
|
alias dataset_id= project=
|
71
71
|
|
72
|
+
##
|
73
|
+
# The database of the Key.
|
74
|
+
#
|
75
|
+
# @return [String]
|
76
|
+
#
|
77
|
+
# @example
|
78
|
+
# require "google/cloud/datastore"
|
79
|
+
#
|
80
|
+
# datastore = Google::Cloud::Datastore.new(
|
81
|
+
# project: "my-todo-project",
|
82
|
+
# database: "my-todo-database",
|
83
|
+
# keyfile: "/path/to/keyfile.json"
|
84
|
+
# )
|
85
|
+
#
|
86
|
+
# task = datastore.find "Task", "sampleTask"
|
87
|
+
# task.key.database #=> "my-todo-database"
|
88
|
+
#
|
89
|
+
attr_accessor :database
|
90
|
+
alias database_id database
|
91
|
+
alias database_id= database=
|
92
|
+
|
72
93
|
##
|
73
94
|
# The namespace of the Key.
|
74
95
|
#
|
@@ -281,9 +302,9 @@ module Google
|
|
281
302
|
Google::Cloud::Datastore::V1::Key::PathElement.new path_args
|
282
303
|
end
|
283
304
|
grpc = Google::Cloud::Datastore::V1::Key.new path: grpc_path
|
284
|
-
if project || namespace
|
305
|
+
if project || database || namespace
|
285
306
|
grpc.partition_id = Google::Cloud::Datastore::V1::PartitionId.new(
|
286
|
-
project_id: project.to_s, namespace_id: namespace.to_s
|
307
|
+
project_id: project.to_s, database_id: database.to_s, namespace_id: namespace.to_s
|
287
308
|
)
|
288
309
|
end
|
289
310
|
grpc
|
@@ -304,6 +325,7 @@ module Google
|
|
304
325
|
end
|
305
326
|
if key_grpc.partition_id
|
306
327
|
key.project = key_grpc.partition_id.project_id
|
328
|
+
key.database = key_grpc.partition_id.database_id
|
307
329
|
key.namespace = key_grpc.partition_id.namespace_id
|
308
330
|
end
|
309
331
|
key.parent = Key.from_grpc key_grpc if key_grpc.path.count.positive?
|
@@ -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.
|
@@ -29,14 +29,16 @@ module Google
|
|
29
29
|
attr_accessor :credentials
|
30
30
|
attr_accessor :host
|
31
31
|
attr_accessor :timeout
|
32
|
+
attr_accessor :database
|
32
33
|
|
33
34
|
##
|
34
35
|
# Creates a new Service instance.
|
35
|
-
def initialize project, credentials, host: nil, timeout: nil
|
36
|
+
def initialize project, credentials, database, host: nil, timeout: nil
|
36
37
|
@project = project
|
37
38
|
@credentials = credentials
|
38
39
|
@host = host
|
39
40
|
@timeout = timeout
|
41
|
+
@database = database
|
40
42
|
end
|
41
43
|
|
42
44
|
def service
|
@@ -47,7 +49,7 @@ module Google
|
|
47
49
|
config.endpoint = host if host
|
48
50
|
config.lib_name = "gccl"
|
49
51
|
config.lib_version = Google::Cloud::Datastore::VERSION
|
50
|
-
config.metadata = { "google-cloud-resource-prefix": "projects/#{@project}" }
|
52
|
+
config.metadata = { "google-cloud-resource-prefix": "projects/#{@project}/databases/#{database}" }
|
51
53
|
end
|
52
54
|
end
|
53
55
|
attr_accessor :mocked_service
|
@@ -56,7 +58,7 @@ module Google
|
|
56
58
|
# Allocate IDs for incomplete keys.
|
57
59
|
# (This is useful for referencing an entity before it is inserted.)
|
58
60
|
def allocate_ids *incomplete_keys
|
59
|
-
service.allocate_ids project_id: project, keys: incomplete_keys
|
61
|
+
service.allocate_ids project_id: project, database_id: database, keys: incomplete_keys
|
60
62
|
end
|
61
63
|
|
62
64
|
##
|
@@ -64,7 +66,7 @@ module Google
|
|
64
66
|
def lookup *keys, consistency: nil, transaction: nil
|
65
67
|
read_options = generate_read_options consistency, transaction
|
66
68
|
|
67
|
-
service.lookup project_id: project, keys: keys, read_options: read_options
|
69
|
+
service.lookup project_id: project, database_id: database, keys: keys, read_options: read_options
|
68
70
|
end
|
69
71
|
|
70
72
|
# Query for entities.
|
@@ -82,12 +84,34 @@ module Google
|
|
82
84
|
end
|
83
85
|
|
84
86
|
service.run_query project_id: project,
|
87
|
+
database_id: database,
|
85
88
|
partition_id: partition_id,
|
86
89
|
read_options: read_options,
|
87
90
|
query: query,
|
88
91
|
gql_query: gql_query
|
89
92
|
end
|
90
93
|
|
94
|
+
## Query for aggregates
|
95
|
+
def run_aggregation_query query, namespace = nil, consistency: nil, transaction: nil
|
96
|
+
gql_query = nil
|
97
|
+
if query.is_a? Google::Cloud::Datastore::V1::GqlQuery
|
98
|
+
gql_query = query
|
99
|
+
query = nil
|
100
|
+
end
|
101
|
+
read_options = generate_read_options consistency, transaction
|
102
|
+
if namespace
|
103
|
+
partition_id = Google::Cloud::Datastore::V1::PartitionId.new(
|
104
|
+
namespace_id: namespace
|
105
|
+
)
|
106
|
+
end
|
107
|
+
|
108
|
+
service.run_aggregation_query project_id: project,
|
109
|
+
partition_id: partition_id,
|
110
|
+
read_options: read_options,
|
111
|
+
aggregation_query: query,
|
112
|
+
gql_query: gql_query
|
113
|
+
end
|
114
|
+
|
91
115
|
##
|
92
116
|
# Begin a new transaction.
|
93
117
|
def begin_transaction read_only: nil, previous_transaction: nil
|
@@ -104,7 +128,7 @@ module Google
|
|
104
128
|
)
|
105
129
|
transaction_options.read_write = rw
|
106
130
|
end
|
107
|
-
service.begin_transaction project_id: project, transaction_options: transaction_options
|
131
|
+
service.begin_transaction project_id: project, database_id: database, transaction_options: transaction_options
|
108
132
|
end
|
109
133
|
|
110
134
|
##
|
@@ -112,17 +136,18 @@ module Google
|
|
112
136
|
# some entities.
|
113
137
|
def commit mutations, transaction: nil
|
114
138
|
mode = transaction.nil? ? :NON_TRANSACTIONAL : :TRANSACTIONAL
|
115
|
-
service.commit project_id: project,
|
139
|
+
service.commit project_id: project, database_id: database, mode: mode,
|
140
|
+
mutations: mutations, transaction: transaction
|
116
141
|
end
|
117
142
|
|
118
143
|
##
|
119
144
|
# Roll back a transaction.
|
120
145
|
def rollback transaction
|
121
|
-
service.rollback project_id: project, transaction: transaction
|
146
|
+
service.rollback project_id: project, database_id: database, transaction: transaction
|
122
147
|
end
|
123
148
|
|
124
149
|
def inspect
|
125
|
-
"#{self.class}(#{@project})"
|
150
|
+
"#{self.class}(#{@project})(#{database})"
|
126
151
|
end
|
127
152
|
|
128
153
|
protected
|
@@ -74,6 +74,8 @@ module Google
|
|
74
74
|
# If the param is nil, uses the default endpoint.
|
75
75
|
# @param [String] emulator_host Datastore emulator host. Optional.
|
76
76
|
# If the param is nil, uses the value of the `emulator_host` config.
|
77
|
+
# @param [String] database_id Identifier for a Datastore database in the project. If not
|
78
|
+
# present, the default database of the project will be used.
|
77
79
|
# @param [String] project Alias for the `project_id` argument. Deprecated.
|
78
80
|
# @param [String] keyfile Alias for the `credentials` argument.
|
79
81
|
# Deprecated.
|
@@ -103,13 +105,15 @@ module Google
|
|
103
105
|
timeout: nil,
|
104
106
|
endpoint: nil,
|
105
107
|
emulator_host: nil,
|
108
|
+
database_id: nil,
|
106
109
|
project: nil,
|
107
110
|
keyfile: nil
|
108
|
-
project_id
|
109
|
-
scope
|
110
|
-
timeout
|
111
|
-
endpoint
|
111
|
+
project_id = get_project_id project_id, project
|
112
|
+
scope ||= configure.scope
|
113
|
+
timeout ||= configure.timeout
|
114
|
+
endpoint ||= configure.endpoint
|
112
115
|
emulator_host ||= configure.emulator_host
|
116
|
+
database_id ||= configure.database_id
|
113
117
|
|
114
118
|
if emulator_host
|
115
119
|
project_id = project_id.to_s # Always cast to a string
|
@@ -117,7 +121,7 @@ module Google
|
|
117
121
|
|
118
122
|
return Datastore::Dataset.new(
|
119
123
|
Datastore::Service.new(
|
120
|
-
project_id, :this_channel_is_insecure,
|
124
|
+
project_id, :this_channel_is_insecure, database_id,
|
121
125
|
host: emulator_host, timeout: timeout
|
122
126
|
)
|
123
127
|
)
|
@@ -136,7 +140,7 @@ module Google
|
|
136
140
|
|
137
141
|
Datastore::Dataset.new(
|
138
142
|
Datastore::Service.new(
|
139
|
-
project_id, credentials,
|
143
|
+
project_id, credentials, database_id,
|
140
144
|
host: endpoint, timeout: timeout
|
141
145
|
)
|
142
146
|
)
|
@@ -175,6 +179,14 @@ module Google
|
|
175
179
|
Google::Cloud.configure.datastore
|
176
180
|
end
|
177
181
|
|
182
|
+
##
|
183
|
+
# @private Default project.
|
184
|
+
def self.get_project_id project_id, project
|
185
|
+
project_id || project || Google::Cloud.configure.datastore.project_id ||
|
186
|
+
Google::Cloud.configure.project_id ||
|
187
|
+
Google::Cloud.env.project_id
|
188
|
+
end
|
189
|
+
|
178
190
|
##
|
179
191
|
# @private Default project.
|
180
192
|
def self.default_project_id
|
@@ -67,9 +67,10 @@ module Google
|
|
67
67
|
# platform_scope = "https://www.googleapis.com/auth/cloud-platform"
|
68
68
|
# datastore = gcloud.datastore scope: platform_scope
|
69
69
|
#
|
70
|
-
def datastore scope: nil, timeout: nil
|
70
|
+
def datastore scope: nil, timeout: nil, database_id: nil
|
71
71
|
Google::Cloud.datastore @project, @keyfile,
|
72
|
-
scope: scope, timeout: (timeout || @timeout)
|
72
|
+
scope: scope, timeout: (timeout || @timeout),
|
73
|
+
database_id: database_id
|
73
74
|
end
|
74
75
|
|
75
76
|
##
|
@@ -112,11 +113,12 @@ module Google
|
|
112
113
|
# datastore.save task
|
113
114
|
#
|
114
115
|
def self.datastore project_id = nil, credentials = nil, scope: nil,
|
115
|
-
timeout: nil
|
116
|
+
timeout: nil, database_id: nil
|
116
117
|
require "google/cloud/datastore"
|
117
118
|
Google::Cloud::Datastore.new project_id: project_id,
|
118
119
|
credentials: credentials,
|
119
|
-
scope: scope, timeout: timeout
|
120
|
+
scope: scope, timeout: timeout,
|
121
|
+
database_id: database_id
|
120
122
|
end
|
121
123
|
end
|
122
124
|
end
|
@@ -136,8 +138,7 @@ Google::Cloud.configure.add_config! :datastore do |config|
|
|
136
138
|
ENV["DATASTORE_EMULATOR_HOST"]
|
137
139
|
end
|
138
140
|
default_scopes = [
|
139
|
-
"https://www.googleapis.com/auth/cloud-platform",
|
140
|
-
"https://www.googleapis.com/auth/datastore"
|
141
|
+
"https://www.googleapis.com/auth/cloud-platform", "https://www.googleapis.com/auth/datastore"
|
141
142
|
]
|
142
143
|
|
143
144
|
config.add_field! :project_id, default_project, match: String, allow_nil: true
|
@@ -149,4 +150,5 @@ Google::Cloud.configure.add_config! :datastore do |config|
|
|
149
150
|
config.add_field! :timeout, nil, match: Integer
|
150
151
|
config.add_field! :emulator_host, default_emulator, match: String, allow_nil: true
|
151
152
|
config.add_field! :endpoint, "datastore.googleapis.com", match: String
|
153
|
+
config.add_field! :database_id, "", match: String
|
152
154
|
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.
|
4
|
+
version: 2.5.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:
|
12
|
+
date: 2023-02-09 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.
|
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
|