google-cloud-datastore 2.5.0 → 2.7.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/dataset/lookup_results.rb +14 -3
- data/lib/google/cloud/datastore/dataset/query_results.rb +23 -3
- data/lib/google/cloud/datastore/dataset.rb +55 -12
- data/lib/google/cloud/datastore/filter.rb +222 -0
- data/lib/google/cloud/datastore/query.rb +57 -11
- data/lib/google/cloud/datastore/read_only_transaction.rb +11 -3
- data/lib/google/cloud/datastore/service.rb +28 -10
- data/lib/google/cloud/datastore/version.rb +1 -1
- metadata +3 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: b372b670c25604994c20b79779906b9a7c00b21bdf3ada9a23eb2cbb5968d053
|
4
|
+
data.tar.gz: 2cb8cac3d2de7b1b631d1c9ee7332b7391a73a720968bf09dc0608430de2a472
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: dba07c333a2230e08f4c315dce2b8e28c748a082561c0692d9e419ba47565496b4b47463912e6cebea34ca3c33732df257ec6b4bcd9419b664cc16a4338b9b76
|
7
|
+
data.tar.gz: e817d031036cefd768ccf202a291435c6a710f69292ea61f2349bd5456732b3e0253ce94c75006abbcbc231c6c6e664bd4340dd2836f20978542dc2bb30b3b45
|
data/CHANGELOG.md
CHANGED
@@ -1,5 +1,17 @@
|
|
1
1
|
# Release History
|
2
2
|
|
3
|
+
### 2.7.0 (2023-04-12)
|
4
|
+
|
5
|
+
#### Features
|
6
|
+
|
7
|
+
* Support OR filter ([#21002](https://github.com/googleapis/google-cloud-ruby/issues/21002))
|
8
|
+
|
9
|
+
### 2.6.0 (2023-02-13)
|
10
|
+
|
11
|
+
#### Features
|
12
|
+
|
13
|
+
* Added support for snapshot read ([#19422](https://github.com/googleapis/google-cloud-ruby/issues/19422))
|
14
|
+
|
3
15
|
### 2.5.0 (2023-02-09)
|
4
16
|
|
5
17
|
#### Features
|
@@ -53,6 +53,15 @@ module Google
|
|
53
53
|
# descriptions.missing #=> raise NoMethodError
|
54
54
|
#
|
55
55
|
class LookupResults < DelegateClass(::Array)
|
56
|
+
##
|
57
|
+
# The time at which these entities were read or found missing.
|
58
|
+
attr_reader :response_read_time
|
59
|
+
|
60
|
+
##
|
61
|
+
# Time at which the entities are being read. This would not be
|
62
|
+
# older than 270 seconds.
|
63
|
+
attr_reader :read_time
|
64
|
+
|
56
65
|
##
|
57
66
|
# Keys that were not looked up due to resource constraints.
|
58
67
|
attr_accessor :deferred
|
@@ -110,9 +119,9 @@ module Google
|
|
110
119
|
ensure_service!
|
111
120
|
lookup_res = @service.lookup(
|
112
121
|
*Array(@deferred).flatten.map(&:to_grpc),
|
113
|
-
consistency: @consistency, transaction: @transaction
|
122
|
+
consistency: @consistency, transaction: @transaction, read_time: @read_time
|
114
123
|
)
|
115
|
-
self.class.from_grpc lookup_res, @service, @consistency
|
124
|
+
self.class.from_grpc lookup_res, @service, @consistency, nil, @read_time
|
116
125
|
end
|
117
126
|
|
118
127
|
##
|
@@ -187,7 +196,7 @@ module Google
|
|
187
196
|
##
|
188
197
|
# @private New Dataset::LookupResults from a
|
189
198
|
# Google::Dataset::V1::LookupResponse object.
|
190
|
-
def self.from_grpc lookup_res, service, consistency = nil, transaction = nil
|
199
|
+
def self.from_grpc lookup_res, service, consistency = nil, transaction = nil, read_time = nil
|
191
200
|
entities = to_gcloud_entities lookup_res.found
|
192
201
|
deferred = to_gcloud_keys lookup_res.deferred
|
193
202
|
missing = to_gcloud_entities lookup_res.missing
|
@@ -195,6 +204,8 @@ module Google
|
|
195
204
|
lr.instance_variable_set :@service, service
|
196
205
|
lr.instance_variable_set :@consistency, consistency
|
197
206
|
lr.instance_variable_set :@transaction, transaction
|
207
|
+
lr.instance_variable_set :@read_time, read_time
|
208
|
+
lr.instance_variable_set :@response_read_time, lookup_res.read_time
|
198
209
|
lr.instance_variable_set :@deferred, deferred
|
199
210
|
lr.instance_variable_set :@missing, missing
|
200
211
|
end
|
@@ -72,6 +72,24 @@ module Google
|
|
72
72
|
# * `:NO_MORE_RESULTS`
|
73
73
|
attr_reader :more_results
|
74
74
|
|
75
|
+
##
|
76
|
+
# Read timestamp this batch was returned from.
|
77
|
+
# This applies to the range of results from the query's `start_cursor` (or
|
78
|
+
# the beginning of the query if no cursor was given) to this batch's
|
79
|
+
# `end_cursor` (not the query's `end_cursor`).
|
80
|
+
#
|
81
|
+
# In a single transaction, subsequent query result batches for the same query
|
82
|
+
# can have a greater timestamp. Each batch's read timestamp
|
83
|
+
# is valid for all preceding batches.
|
84
|
+
# This value will not be set for eventually consistent queries in Cloud
|
85
|
+
# Datastore.
|
86
|
+
attr_reader :batch_read_time
|
87
|
+
|
88
|
+
##
|
89
|
+
# Time at which the entities are being read. This would not be
|
90
|
+
# older than 270 seconds.
|
91
|
+
attr_reader :read_time
|
92
|
+
|
75
93
|
##
|
76
94
|
# @private
|
77
95
|
attr_accessor :service, :namespace, :cursors, :query
|
@@ -162,8 +180,8 @@ module Google
|
|
162
180
|
# Reduce the limit by the number of entities returned in the current batch
|
163
181
|
query.limit.value -= count
|
164
182
|
end
|
165
|
-
query_res = service.run_query query, namespace
|
166
|
-
self.class.from_grpc query_res, service, namespace, query
|
183
|
+
query_res = service.run_query query, namespace, read_time: read_time
|
184
|
+
self.class.from_grpc query_res, service, namespace, query, read_time
|
167
185
|
end
|
168
186
|
|
169
187
|
##
|
@@ -360,7 +378,7 @@ module Google
|
|
360
378
|
##
|
361
379
|
# @private New Dataset::QueryResults from a
|
362
380
|
# Google::Dataset::V1::RunQueryResponse object.
|
363
|
-
def self.from_grpc query_res, service, namespace, query
|
381
|
+
def self.from_grpc query_res, service, namespace, query, read_time = nil
|
364
382
|
r, c = Array(query_res.batch.entity_results).map do |result|
|
365
383
|
[Entity.from_grpc(result.entity), Cursor.from_grpc(result.cursor)]
|
366
384
|
end.transpose
|
@@ -373,6 +391,8 @@ module Google
|
|
373
391
|
qr.service = service
|
374
392
|
qr.namespace = namespace
|
375
393
|
qr.query = query_res.query || query
|
394
|
+
qr.instance_variable_set :@read_time, read_time
|
395
|
+
qr.instance_variable_set :@batch_read_time, query_res.batch.read_time
|
376
396
|
end
|
377
397
|
end
|
378
398
|
|
@@ -337,6 +337,8 @@ module Google
|
|
337
337
|
# [Eventual Consistency in Google Cloud
|
338
338
|
# Datastore](https://cloud.google.com/datastore/docs/articles/balancing-strong-and-eventual-consistency-with-google-cloud-datastore/#h.tf76fya5nqk8)
|
339
339
|
# for more information.
|
340
|
+
# @param [Time] read_time Reads entities as they were at the given time.
|
341
|
+
# This may not be older than 270 seconds. Optional
|
340
342
|
#
|
341
343
|
# @return [Google::Cloud::Datastore::Entity, nil]
|
342
344
|
#
|
@@ -355,12 +357,12 @@ module Google
|
|
355
357
|
#
|
356
358
|
# task = datastore.find "Task", "sampleTask"
|
357
359
|
#
|
358
|
-
def find key_or_kind, id_or_name = nil, consistency: nil
|
360
|
+
def find key_or_kind, id_or_name = nil, consistency: nil, read_time: nil
|
359
361
|
key = key_or_kind
|
360
362
|
unless key.is_a? Google::Cloud::Datastore::Key
|
361
363
|
key = Key.new key_or_kind, id_or_name
|
362
364
|
end
|
363
|
-
find_all(key, consistency: consistency).first
|
365
|
+
find_all(key, consistency: consistency, read_time: read_time).first
|
364
366
|
end
|
365
367
|
alias get find
|
366
368
|
|
@@ -377,6 +379,8 @@ module Google
|
|
377
379
|
# [Eventual Consistency in Google Cloud
|
378
380
|
# Datastore](https://cloud.google.com/datastore/docs/articles/balancing-strong-and-eventual-consistency-with-google-cloud-datastore/#h.tf76fya5nqk8)
|
379
381
|
# for more information.
|
382
|
+
# @param [Time] read_time Reads entities as they were at the given time.
|
383
|
+
# This may not be older than 270 seconds. Optional
|
380
384
|
#
|
381
385
|
# @return [Google::Cloud::Datastore::Dataset::LookupResults]
|
382
386
|
#
|
@@ -389,12 +393,12 @@ module Google
|
|
389
393
|
# task_key2 = datastore.key "Task", "sampleTask2"
|
390
394
|
# tasks = datastore.find_all task_key1, task_key2
|
391
395
|
#
|
392
|
-
def find_all *keys, consistency: nil
|
396
|
+
def find_all *keys, consistency: nil, read_time: nil
|
393
397
|
ensure_service!
|
394
398
|
check_consistency! consistency
|
395
399
|
lookup_res = service.lookup(*Array(keys).flatten.map(&:to_grpc),
|
396
|
-
consistency: consistency)
|
397
|
-
LookupResults.from_grpc lookup_res, service, consistency
|
400
|
+
consistency: consistency, read_time: read_time)
|
401
|
+
LookupResults.from_grpc lookup_res, service, consistency, nil, read_time
|
398
402
|
end
|
399
403
|
alias lookup find_all
|
400
404
|
|
@@ -411,6 +415,8 @@ module Google
|
|
411
415
|
# [Eventual Consistency in Google Cloud
|
412
416
|
# Datastore](https://cloud.google.com/datastore/docs/articles/balancing-strong-and-eventual-consistency-with-google-cloud-datastore/#h.tf76fya5nqk8)
|
413
417
|
# for more information.
|
418
|
+
# @param [Time] read_time Reads entities as they were at the given time.
|
419
|
+
# This may not be older than 270 seconds. Optional
|
414
420
|
#
|
415
421
|
# @return [Google::Cloud::Datastore::Dataset::QueryResults]
|
416
422
|
#
|
@@ -461,16 +467,16 @@ module Google
|
|
461
467
|
# done: false
|
462
468
|
# tasks = datastore.run gql_query, namespace: "example-ns"
|
463
469
|
#
|
464
|
-
def run query, namespace: nil, consistency: nil
|
470
|
+
def run query, namespace: nil, consistency: nil, read_time: nil
|
465
471
|
ensure_service!
|
466
472
|
unless query.is_a?(Query) || query.is_a?(GqlQuery)
|
467
473
|
raise ArgumentError, "Cannot run a #{query.class} object."
|
468
474
|
end
|
469
475
|
check_consistency! consistency
|
470
476
|
query_res = service.run_query query.to_grpc, namespace,
|
471
|
-
consistency: consistency
|
477
|
+
consistency: consistency, read_time: read_time
|
472
478
|
QueryResults.from_grpc query_res, service, namespace,
|
473
|
-
query.to_grpc.dup
|
479
|
+
query.to_grpc.dup, read_time
|
474
480
|
end
|
475
481
|
alias run_query run
|
476
482
|
|
@@ -482,6 +488,8 @@ module Google
|
|
482
488
|
# @param [Symbol] consistency The non-transactional read consistency to
|
483
489
|
# use. Cannot be set to `:strong` for global queries. Accepted values
|
484
490
|
# are `:eventual` and `:strong`.
|
491
|
+
# @param [Time] read_time Reads entities as they were at the given time.
|
492
|
+
# This may not be older than 270 seconds. Optional
|
485
493
|
#
|
486
494
|
# The default consistency depends on the type of query used. See
|
487
495
|
# [Eventual Consistency in Google Cloud
|
@@ -545,14 +553,14 @@ module Google
|
|
545
553
|
# done: false
|
546
554
|
# res = datastore.run_aggregation gql_query, namespace: "example-ns"
|
547
555
|
#
|
548
|
-
def run_aggregation aggregate_query, namespace: nil, consistency: nil
|
556
|
+
def run_aggregation aggregate_query, namespace: nil, consistency: nil, read_time: nil
|
549
557
|
ensure_service!
|
550
558
|
unless aggregate_query.is_a?(AggregateQuery) || aggregate_query.is_a?(GqlQuery)
|
551
559
|
raise ArgumentError, "Cannot run a #{aggregate_query.class} object."
|
552
560
|
end
|
553
561
|
check_consistency! consistency
|
554
562
|
aggregate_query_res = service.run_aggregation_query aggregate_query.to_grpc, namespace,
|
555
|
-
consistency: consistency
|
563
|
+
consistency: consistency, read_time: read_time
|
556
564
|
AggregateQueryResults.from_grpc aggregate_query_res
|
557
565
|
end
|
558
566
|
|
@@ -677,6 +685,9 @@ module Google
|
|
677
685
|
# @see https://cloud.google.com/datastore/docs/concepts/transactions
|
678
686
|
# Transactions
|
679
687
|
#
|
688
|
+
# @param [Time] read_time Reads entities at the given time.
|
689
|
+
# This may not be older than 60 seconds. Optional
|
690
|
+
#
|
680
691
|
# @yield [tx] a block yielding a new transaction
|
681
692
|
# @yieldparam [ReadOnlyTransaction] tx the transaction object
|
682
693
|
#
|
@@ -698,8 +709,8 @@ module Google
|
|
698
709
|
# end
|
699
710
|
# end
|
700
711
|
#
|
701
|
-
def read_only_transaction
|
702
|
-
tx = ReadOnlyTransaction.new service
|
712
|
+
def read_only_transaction read_time: nil
|
713
|
+
tx = ReadOnlyTransaction.new service, read_time: read_time
|
703
714
|
return tx unless block_given?
|
704
715
|
|
705
716
|
begin
|
@@ -970,6 +981,38 @@ module Google
|
|
970
981
|
entity
|
971
982
|
end
|
972
983
|
|
984
|
+
##
|
985
|
+
# Create a new Filter instance. This is a convenience method to make the
|
986
|
+
# creation of Filter objects easier.
|
987
|
+
#
|
988
|
+
# @param name [String] The property to filter by.
|
989
|
+
# @param operator [String] The operator to filter by. Defaults to nil.
|
990
|
+
# @param value The value to compare the property to. Defaults to nil.
|
991
|
+
# Possible values are:
|
992
|
+
# - Integer
|
993
|
+
# - Float/BigDecimal
|
994
|
+
# - String
|
995
|
+
# - Boolean
|
996
|
+
# - Array
|
997
|
+
# - Date/Time
|
998
|
+
# - StringIO
|
999
|
+
# - Google::Cloud::Datastore::Key
|
1000
|
+
# - Google::Cloud::Datastore::Entity
|
1001
|
+
# - nil
|
1002
|
+
#
|
1003
|
+
# @return [Google::Cloud::Datastore::Filter]
|
1004
|
+
#
|
1005
|
+
# @example
|
1006
|
+
# require "google/cloud/datastore"
|
1007
|
+
#
|
1008
|
+
# datastore = Google::Cloud::Datastore.new
|
1009
|
+
#
|
1010
|
+
# filter = datastore.filter("done", "=", false)
|
1011
|
+
#
|
1012
|
+
def filter name, operator, value
|
1013
|
+
Filter.new name, operator, value
|
1014
|
+
end
|
1015
|
+
|
973
1016
|
protected
|
974
1017
|
|
975
1018
|
##
|
@@ -0,0 +1,222 @@
|
|
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
|
+
require "google/cloud/datastore/v1"
|
16
|
+
|
17
|
+
module Google
|
18
|
+
module Cloud
|
19
|
+
module Datastore
|
20
|
+
##
|
21
|
+
# Filter
|
22
|
+
#
|
23
|
+
# Represents the filter criteria for a datastore query.
|
24
|
+
#
|
25
|
+
# @example Run a query with a simple property filter.
|
26
|
+
# require "google/cloud/datastore"
|
27
|
+
#
|
28
|
+
# datastore = Google::Cloud::Datastore.new
|
29
|
+
#
|
30
|
+
# filter = Google::Cloud::Datastore::Filter.new("done", "=", "false")
|
31
|
+
#
|
32
|
+
# query = Google::Cloud::Datastore::Query.new
|
33
|
+
# query.kind("Task")
|
34
|
+
# .where(filter)
|
35
|
+
#
|
36
|
+
# tasks = datastore.run query
|
37
|
+
#
|
38
|
+
# @example Construct a composite filter with a logical OR.
|
39
|
+
# require "google/cloud/datastore"
|
40
|
+
#
|
41
|
+
# datastore = Google::Cloud::Datastore.new
|
42
|
+
#
|
43
|
+
# filter = Google::Cloud::Datastore::Filter.new("done", "=", "false")
|
44
|
+
# .or("priority", ">=", "4")
|
45
|
+
#
|
46
|
+
# query = Google::Cloud::Datastore::Query.new
|
47
|
+
# query.kind("Task")
|
48
|
+
# .where(filter)
|
49
|
+
#
|
50
|
+
# tasks = datastore.run query
|
51
|
+
#
|
52
|
+
# @example Construct a composite filter by combining multiple filters.
|
53
|
+
# require "google/cloud/datastore"
|
54
|
+
#
|
55
|
+
# datastore = Google::Cloud::Datastore.new
|
56
|
+
#
|
57
|
+
# filter_1 = Google::Cloud::Datastore::Filter.new("done", "=", "false")
|
58
|
+
# filter_2 = Google::Cloud::Datastore::Filter.new("priority", ">=", "4")
|
59
|
+
# filter = filter_1.or(filter_2)
|
60
|
+
#
|
61
|
+
# query = Google::Cloud::Datastore::Query.new
|
62
|
+
# query.kind("Task")
|
63
|
+
# .where(filter)
|
64
|
+
#
|
65
|
+
# tasks = datastore.run query
|
66
|
+
#
|
67
|
+
class Filter
|
68
|
+
##
|
69
|
+
# @private Object of type
|
70
|
+
# Google::Cloud::Datastore::V1::Filter
|
71
|
+
attr_accessor :grpc
|
72
|
+
|
73
|
+
##
|
74
|
+
# Creates a new Filter.
|
75
|
+
#
|
76
|
+
# @example
|
77
|
+
# require "google/cloud/datastore"
|
78
|
+
#
|
79
|
+
# filter = Google::Cloud::Datastore::Filter.new("done", "=", "false")
|
80
|
+
#
|
81
|
+
def initialize name, operator, value
|
82
|
+
@grpc = create_property_filter name, operator, value
|
83
|
+
end
|
84
|
+
|
85
|
+
##
|
86
|
+
# Joins two filters with an AND operator.
|
87
|
+
#
|
88
|
+
# @overload and(name, operator, value)
|
89
|
+
# Joins the filter with a property filter
|
90
|
+
# @param name [String]
|
91
|
+
# @param operator [String]
|
92
|
+
# @param value
|
93
|
+
#
|
94
|
+
# @overload and(filter)
|
95
|
+
# Joins the filter with a Filter object
|
96
|
+
# @param filter [Filter]
|
97
|
+
#
|
98
|
+
# @example Join the filter with a property filter
|
99
|
+
# require "google/cloud/datastore"
|
100
|
+
#
|
101
|
+
# datastore = Google::Cloud::Datastore.new
|
102
|
+
#
|
103
|
+
# filter = Google::Cloud::Filter.new("done", "=", false)
|
104
|
+
# .and("priority", ">=", 4)
|
105
|
+
#
|
106
|
+
# @example Join the filter with a filter object
|
107
|
+
# require "google/cloud/datastore"
|
108
|
+
#
|
109
|
+
# datastore = Google::Cloud::Datastore.new
|
110
|
+
#
|
111
|
+
# filter_1 = Google::Cloud::Filter.new("done", "=", false)
|
112
|
+
# filter_2 = Google::Cloud::Filter.new("priority", ">=", 4)
|
113
|
+
#
|
114
|
+
# filter = filter_1.and(filter_2)
|
115
|
+
#
|
116
|
+
def and name_or_filter, operator = nil, value = nil
|
117
|
+
combine_filters composite_filter_and, name_or_filter, operator, value
|
118
|
+
end
|
119
|
+
|
120
|
+
##
|
121
|
+
# Joins two filters with an OR operator.
|
122
|
+
#
|
123
|
+
# @overload or(name, operator, value)
|
124
|
+
# Joins the filter with a property filter
|
125
|
+
# @param name [String] The property to filter by.
|
126
|
+
# @param operator [String] The operator to filter by. Defaults to nil.
|
127
|
+
# @param value [Object] The value to compare the property to. Defaults to nil.
|
128
|
+
# Possible values are:
|
129
|
+
# - Integer
|
130
|
+
# - Float/BigDecimal
|
131
|
+
# - String
|
132
|
+
# - Boolean
|
133
|
+
# - Array
|
134
|
+
# - Date/Time
|
135
|
+
# - StringIO
|
136
|
+
# - Google::Cloud::Datastore::Key
|
137
|
+
# - Google::Cloud::Datastore::Entity
|
138
|
+
# - nil
|
139
|
+
#
|
140
|
+
# @overload or(filter)
|
141
|
+
# Joins the filter with a Filter object
|
142
|
+
# @param flter [Filter]
|
143
|
+
#
|
144
|
+
# @example Join the filter with a property filter
|
145
|
+
# require "google/cloud/datastore"
|
146
|
+
#
|
147
|
+
# datastore = Google::Cloud::Datastore.new
|
148
|
+
#
|
149
|
+
# filter = Google::Cloud::Filter.new("done", "=", false)
|
150
|
+
# .or("priority", ">=", 4)
|
151
|
+
#
|
152
|
+
# @example Join the filter with a filter object
|
153
|
+
# require "google/cloud/datastore"
|
154
|
+
#
|
155
|
+
# datastore = Google::Cloud::Datastore.new
|
156
|
+
#
|
157
|
+
# filter_1 = Google::Cloud::Filter.new("done", "=", false)
|
158
|
+
# filter_2 = Google::Cloud::Filter.new("priority", ">=", 4)
|
159
|
+
#
|
160
|
+
# filter = filter_1.or(filter_2)
|
161
|
+
#
|
162
|
+
def or name_or_filter, operator = nil, value = nil
|
163
|
+
combine_filters composite_filter_or, name_or_filter, operator, value
|
164
|
+
end
|
165
|
+
|
166
|
+
# @private
|
167
|
+
def to_grpc
|
168
|
+
@grpc
|
169
|
+
end
|
170
|
+
|
171
|
+
protected
|
172
|
+
|
173
|
+
##
|
174
|
+
# @private
|
175
|
+
#
|
176
|
+
# Combines self.grpc and (name_or_filter, operator, value)
|
177
|
+
# into the new_filter object with the specified AND/OR operator
|
178
|
+
def combine_filters new_filter, name_or_filter, operator, value
|
179
|
+
new_filter.composite_filter.filters << to_grpc
|
180
|
+
new_filter.composite_filter.filters << if name_or_filter.is_a? Google::Cloud::Datastore::Filter
|
181
|
+
name_or_filter.to_grpc
|
182
|
+
else
|
183
|
+
create_property_filter name_or_filter, operator, value
|
184
|
+
end
|
185
|
+
dup.tap do |f|
|
186
|
+
f.grpc = new_filter
|
187
|
+
end
|
188
|
+
end
|
189
|
+
|
190
|
+
##
|
191
|
+
# @private
|
192
|
+
def composite_filter_and
|
193
|
+
Google::Cloud::Datastore::V1::Filter.new(
|
194
|
+
composite_filter: Google::Cloud::Datastore::V1::CompositeFilter.new(op: :AND)
|
195
|
+
)
|
196
|
+
end
|
197
|
+
|
198
|
+
##
|
199
|
+
# @private
|
200
|
+
def composite_filter_or
|
201
|
+
Google::Cloud::Datastore::V1::Filter.new(
|
202
|
+
composite_filter: Google::Cloud::Datastore::V1::CompositeFilter.new(op: :OR)
|
203
|
+
)
|
204
|
+
end
|
205
|
+
|
206
|
+
##
|
207
|
+
# @private
|
208
|
+
def create_property_filter name, operator, value
|
209
|
+
Google::Cloud::Datastore::V1::Filter.new(
|
210
|
+
property_filter: Google::Cloud::Datastore::V1::PropertyFilter.new(
|
211
|
+
property: Google::Cloud::Datastore::V1::PropertyReference.new(
|
212
|
+
name: name
|
213
|
+
),
|
214
|
+
op: Convert.to_prop_filter_op(operator),
|
215
|
+
value: Convert.to_value(value)
|
216
|
+
)
|
217
|
+
)
|
218
|
+
end
|
219
|
+
end
|
220
|
+
end
|
221
|
+
end
|
222
|
+
end
|
@@ -16,6 +16,7 @@
|
|
16
16
|
require "google/cloud/datastore/entity"
|
17
17
|
require "google/cloud/datastore/key"
|
18
18
|
require "google/cloud/datastore/aggregate_query"
|
19
|
+
require "google/cloud/datastore/filter"
|
19
20
|
|
20
21
|
module Google
|
21
22
|
module Cloud
|
@@ -96,6 +97,27 @@ module Google
|
|
96
97
|
##
|
97
98
|
# Add a property filter to the query.
|
98
99
|
#
|
100
|
+
# @overload and(name, operator, value)
|
101
|
+
# Joins the filter with a property filter
|
102
|
+
# @param name [String] The property to filter by.
|
103
|
+
# @param operator [String] The operator to filter by. Defaults to nil.
|
104
|
+
# @param value [Object] The value to compare the property to. Defaults to nil.
|
105
|
+
# Possible values are:
|
106
|
+
# - Integer
|
107
|
+
# - Float/BigDecimal
|
108
|
+
# - String
|
109
|
+
# - Boolean
|
110
|
+
# - Array
|
111
|
+
# - Date/Time
|
112
|
+
# - StringIO
|
113
|
+
# - Google::Cloud::Datastore::Key
|
114
|
+
# - Google::Cloud::Datastore::Entity
|
115
|
+
# - nil
|
116
|
+
#
|
117
|
+
# @overload and(filter)
|
118
|
+
# Joins the filter with a Filter object
|
119
|
+
# @param filter [Filter]
|
120
|
+
#
|
99
121
|
# @example
|
100
122
|
# require "google/cloud/datastore"
|
101
123
|
#
|
@@ -119,6 +141,34 @@ module Google
|
|
119
141
|
#
|
120
142
|
# tasks = datastore.run query
|
121
143
|
#
|
144
|
+
# @example Add a composite "AND" filter:
|
145
|
+
# require "google/cloud/datastore"
|
146
|
+
#
|
147
|
+
# datastore = Google::Cloud::Datastore.new
|
148
|
+
#
|
149
|
+
# filter = Google::Cloud::Filter.new("done", "=", false)
|
150
|
+
# .and("priority", ">=", 4)
|
151
|
+
#
|
152
|
+
# query = Google::Cloud::Datastore::Query.new
|
153
|
+
# query.kind("Task")
|
154
|
+
# .where(filter)
|
155
|
+
#
|
156
|
+
# tasks = datastore.run query
|
157
|
+
#
|
158
|
+
# @example Add a composite "OR" filter:
|
159
|
+
# require "google/cloud/datastore"
|
160
|
+
#
|
161
|
+
# datastore = Google::Cloud::Datastore.new
|
162
|
+
#
|
163
|
+
# filter = Google::Cloud::Filter.new("done", "=", false)
|
164
|
+
# .or("priority", ">=", 4)
|
165
|
+
#
|
166
|
+
# query = Google::Cloud::Datastore::Query.new
|
167
|
+
# query.kind("Task")
|
168
|
+
# .where(filter)
|
169
|
+
#
|
170
|
+
# tasks = datastore.run query
|
171
|
+
#
|
122
172
|
# @example Add an inequality filter on a **single** property only:
|
123
173
|
# require "google/cloud/datastore"
|
124
174
|
#
|
@@ -177,22 +227,18 @@ module Google
|
|
177
227
|
#
|
178
228
|
# tasks = datastore.run query
|
179
229
|
#
|
180
|
-
def where
|
230
|
+
def where name_or_filter, operator = nil, value = nil
|
181
231
|
@grpc.filter ||= Google::Cloud::Datastore::V1::Filter.new(
|
182
232
|
composite_filter: Google::Cloud::Datastore::V1::CompositeFilter.new(
|
183
233
|
op: :AND
|
184
234
|
)
|
185
235
|
)
|
186
|
-
|
187
|
-
|
188
|
-
|
189
|
-
|
190
|
-
|
191
|
-
|
192
|
-
op: Convert.to_prop_filter_op(operator),
|
193
|
-
value: Convert.to_value(value)
|
194
|
-
)
|
195
|
-
)
|
236
|
+
if name_or_filter.is_a? Google::Cloud::Datastore::Filter
|
237
|
+
@grpc.filter.composite_filter.filters << name_or_filter.to_grpc
|
238
|
+
else
|
239
|
+
@grpc.filter.composite_filter.filters << \
|
240
|
+
Google::Cloud::Datastore::Filter.new(name_or_filter, operator, value).to_grpc
|
241
|
+
end
|
196
242
|
|
197
243
|
self
|
198
244
|
end
|
@@ -59,13 +59,22 @@ module Google
|
|
59
59
|
# @private The Service object.
|
60
60
|
attr_accessor :service
|
61
61
|
|
62
|
+
##
|
63
|
+
# Reads entities at the given time.
|
64
|
+
# This may not be older than 60 seconds.
|
65
|
+
attr_reader :read_time
|
66
|
+
|
62
67
|
##
|
63
68
|
# @private Creates a new ReadOnlyTransaction instance.
|
64
69
|
# Takes a Service instead of project and Credentials.
|
65
70
|
#
|
66
|
-
|
71
|
+
# @param [Time] read_time Reads documents as they were at the given time.
|
72
|
+
# This may not be older than 270 seconds. Optional
|
73
|
+
#
|
74
|
+
def initialize service, read_time: nil
|
67
75
|
@service = service
|
68
76
|
reset!
|
77
|
+
@read_time = read_time
|
69
78
|
start
|
70
79
|
end
|
71
80
|
|
@@ -194,9 +203,8 @@ module Google
|
|
194
203
|
#
|
195
204
|
def start
|
196
205
|
raise TransactionError, "Transaction already opened." unless @id.nil?
|
197
|
-
|
198
206
|
ensure_service!
|
199
|
-
tx_res = service.begin_transaction read_only: true
|
207
|
+
tx_res = service.begin_transaction read_only: true, read_time: @read_time
|
200
208
|
@id = tx_res.transaction
|
201
209
|
end
|
202
210
|
alias begin_transaction start
|
@@ -52,6 +52,7 @@ module Google
|
|
52
52
|
config.metadata = { "google-cloud-resource-prefix": "projects/#{@project}/databases/#{database}" }
|
53
53
|
end
|
54
54
|
end
|
55
|
+
|
55
56
|
attr_accessor :mocked_service
|
56
57
|
|
57
58
|
##
|
@@ -63,20 +64,19 @@ module Google
|
|
63
64
|
|
64
65
|
##
|
65
66
|
# Look up entities by keys.
|
66
|
-
def lookup *keys, consistency: nil, transaction: nil
|
67
|
-
read_options = generate_read_options consistency, transaction
|
68
|
-
|
67
|
+
def lookup *keys, consistency: nil, transaction: nil, read_time: nil
|
68
|
+
read_options = generate_read_options consistency, transaction, read_time
|
69
69
|
service.lookup project_id: project, database_id: database, keys: keys, read_options: read_options
|
70
70
|
end
|
71
71
|
|
72
72
|
# Query for entities.
|
73
|
-
def run_query query, namespace = nil, consistency: nil, transaction: nil
|
73
|
+
def run_query query, namespace = nil, consistency: nil, transaction: nil, read_time: nil
|
74
74
|
gql_query = nil
|
75
75
|
if query.is_a? Google::Cloud::Datastore::V1::GqlQuery
|
76
76
|
gql_query = query
|
77
77
|
query = nil
|
78
78
|
end
|
79
|
-
read_options = generate_read_options consistency, transaction
|
79
|
+
read_options = generate_read_options consistency, transaction, read_time
|
80
80
|
if namespace
|
81
81
|
partition_id = Google::Cloud::Datastore::V1::PartitionId.new(
|
82
82
|
namespace_id: namespace
|
@@ -92,13 +92,13 @@ module Google
|
|
92
92
|
end
|
93
93
|
|
94
94
|
## Query for aggregates
|
95
|
-
def run_aggregation_query query, namespace = nil, consistency: nil, transaction: nil
|
95
|
+
def run_aggregation_query query, namespace = nil, consistency: nil, transaction: nil, read_time: nil
|
96
96
|
gql_query = nil
|
97
97
|
if query.is_a? Google::Cloud::Datastore::V1::GqlQuery
|
98
98
|
gql_query = query
|
99
99
|
query = nil
|
100
100
|
end
|
101
|
-
read_options = generate_read_options consistency, transaction
|
101
|
+
read_options = generate_read_options consistency, transaction, read_time
|
102
102
|
if namespace
|
103
103
|
partition_id = Google::Cloud::Datastore::V1::PartitionId.new(
|
104
104
|
namespace_id: namespace
|
@@ -114,11 +114,13 @@ module Google
|
|
114
114
|
|
115
115
|
##
|
116
116
|
# Begin a new transaction.
|
117
|
-
def begin_transaction read_only: nil, previous_transaction: nil
|
117
|
+
def begin_transaction read_only: nil, previous_transaction: nil, read_time: nil
|
118
118
|
if read_only
|
119
119
|
transaction_options = Google::Cloud::Datastore::V1::TransactionOptions.new
|
120
120
|
transaction_options.read_only = \
|
121
|
-
Google::Cloud::Datastore::V1::TransactionOptions::ReadOnly.new
|
121
|
+
Google::Cloud::Datastore::V1::TransactionOptions::ReadOnly.new \
|
122
|
+
read_time: read_time_to_timestamp(read_time)
|
123
|
+
|
122
124
|
end
|
123
125
|
if previous_transaction
|
124
126
|
transaction_options ||= \
|
@@ -152,7 +154,7 @@ module Google
|
|
152
154
|
|
153
155
|
protected
|
154
156
|
|
155
|
-
def generate_read_options consistency, transaction
|
157
|
+
def generate_read_options consistency, transaction, read_time
|
156
158
|
if consistency == :eventual
|
157
159
|
return Google::Cloud::Datastore::V1::ReadOptions.new(
|
158
160
|
read_consistency: :EVENTUAL
|
@@ -165,9 +167,25 @@ module Google
|
|
165
167
|
return Google::Cloud::Datastore::V1::ReadOptions.new(
|
166
168
|
transaction: transaction
|
167
169
|
)
|
170
|
+
elsif read_time
|
171
|
+
return Google::Cloud::Datastore::V1::ReadOptions.new(
|
172
|
+
read_time: read_time_to_timestamp(read_time)
|
173
|
+
)
|
168
174
|
end
|
169
175
|
nil
|
170
176
|
end
|
177
|
+
|
178
|
+
def read_time_to_timestamp time
|
179
|
+
return nil if time.nil?
|
180
|
+
|
181
|
+
# Force the object to be a Time object.
|
182
|
+
time = time.to_time.utc
|
183
|
+
|
184
|
+
Google::Protobuf::Timestamp.new(
|
185
|
+
seconds: time.to_i,
|
186
|
+
nanos: time.usec * 1000
|
187
|
+
)
|
188
|
+
end
|
171
189
|
end
|
172
190
|
end
|
173
191
|
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.7.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: 2023-
|
12
|
+
date: 2023-04-12 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: google-cloud-core
|
@@ -210,6 +210,7 @@ files:
|
|
210
210
|
- lib/google/cloud/datastore/dataset/query_results.rb
|
211
211
|
- lib/google/cloud/datastore/entity.rb
|
212
212
|
- lib/google/cloud/datastore/errors.rb
|
213
|
+
- lib/google/cloud/datastore/filter.rb
|
213
214
|
- lib/google/cloud/datastore/gql_query.rb
|
214
215
|
- lib/google/cloud/datastore/key.rb
|
215
216
|
- lib/google/cloud/datastore/properties.rb
|