google-cloud-datastore 2.5.0 → 2.7.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
|