google-cloud-datastore 2.5.0 → 2.6.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 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