google-cloud-datastore 2.5.0 → 2.6.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: ded45a15f44ec5a2e095ef0369db26c2a4a65e59c2af1e08bb8f6028736062ea
4
- data.tar.gz: 8d7321547294a1c1ab492df132e19300a0466f252e74f9c7122fb7941bbaeac7
3
+ metadata.gz: 1471082bad6f76859fd0172a40bac47c81c31d3bc7f42e0f5135547f280307a6
4
+ data.tar.gz: a182edc1deadbfe697c45fad2bcde90379c58d07985833fd3f4bca64584bfaf2
5
5
  SHA512:
6
- metadata.gz: 8a4039bbc1c34698507c3b7a1e2c22b011f4df3ea66a57927c7dd147c4468d97c85f15b49efa6c06dcb124815ad5fc4098eeaa8e6f54d23570489e6da0d8dbf3
7
- data.tar.gz: af0981ba4ea2bd054ba35ddd372399addbbb5e0d0c8e4032f518b48ab03065771af8a6185dea29483a9948ae42147011c0f6a100c747dd08100736780a5cb286
6
+ metadata.gz: 41ae448187ef6bbd842bcafcb2c6cbd107b81e4dfb55b72bbfb62857af387a82b4361cc3b86cdf00ab2657a5b98bcf6f51c1caf2090b2c922f8f3db03016e19a
7
+ data.tar.gz: 25725fc96567a06df8c6b75c4b29f9ff8077e77b59a7bb1c31d0c384a9a0d880d9e0d807653f75986c56d428dbcf7aaf09fa4074f7335eef76dcc520e21c9304
data/CHANGELOG.md CHANGED
@@ -1,5 +1,11 @@
1
1
  # Release History
2
2
 
3
+ ### 2.6.0 (2023-02-13)
4
+
5
+ #### Features
6
+
7
+ * Added support for snapshot read ([#19422](https://github.com/googleapis/google-cloud-ruby/issues/19422))
8
+
3
9
  ### 2.5.0 (2023-02-09)
4
10
 
5
11
  #### 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
@@ -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
- def initialize service
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
@@ -16,7 +16,7 @@
16
16
  module Google
17
17
  module Cloud
18
18
  module Datastore
19
- VERSION = "2.5.0".freeze
19
+ VERSION = "2.6.0".freeze
20
20
  end
21
21
  end
22
22
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: google-cloud-datastore
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.5.0
4
+ version: 2.6.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-02-09 00:00:00.000000000 Z
12
+ date: 2023-02-13 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: google-cloud-core