google-cloud-spanner 2.27.0 → 2.28.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: 2950745d1ef3cf6be982e2bc64a29ce467e8a15710293265181d41dd138a80ad
4
- data.tar.gz: 6e96c531e76300e6d77d5d261ec0d09da96157f82aa3f4c32c502b52ce6b6f74
3
+ metadata.gz: 850ac8a54d873ff6d92cc7d7b835abd1d0fd980d22529296b036b67d5c4ecbfe
4
+ data.tar.gz: 585441baf49b27942fddc9876044221965fe9edd475bdf8f6c53f463a3a75cf0
5
5
  SHA512:
6
- metadata.gz: 55291fac48fb628c64d4df17266cf1a07babbd918b8411e7116e8ba23b0430c20dbf0f210098f27052bbcd9d97c9e3ed0ec2937a4c342cb5994946df2dcf2ac6
7
- data.tar.gz: b2e91d7c79a316a69b3657eace1232936a13013236117170b974a9487e0d9fdd5c9de34bba851ffbe310a26c6864954fd94de68df91fdb1a9d64bd06773d5aff
6
+ metadata.gz: dca36d5f2479c792b0c7e10051cf52915314c76de12581d09ff8284ae8e591430d2d67f779c71b2956580e4f970054ddcac3d3f8429ed8ced759b8cd0be0339a
7
+ data.tar.gz: 887212c39b640de69edf12df3bca506494a7bb65c6f0b102eb80cefb3c41e8c3511b027f18334669ab58a9d1ba7114ab1d5bdc83d4982c39521ff4d542b94344
data/CHANGELOG.md CHANGED
@@ -1,5 +1,19 @@
1
1
  # Release History
2
2
 
3
+ ### 2.28.0 (2025-10-22)
4
+
5
+ #### Features
6
+
7
+ * Add support for order_by and lock_hint options ([#182](https://github.com/googleapis/ruby-spanner/issues/182))
8
+
9
+ #### Bug Fixes
10
+
11
+ * use create Transaction when retrying when enumerating rows in `Spanner::Results` ([#191](https://github.com/googleapis/ruby-spanner/issues/191))
12
+ * run explicit BeginTransaction in Client#transaction for mutation-only payloads ([#191](https://github.com/googleapis/ruby-spanner/issues/191))
13
+ * Transaction#initialize is no longer incorrectly marked as public in documentation ([#191](https://github.com/googleapis/ruby-spanner/issues/191))
14
+ * several field accessors in Partition are no longer incorrectly marked as public in documentation ([#191](https://github.com/googleapis/ruby-spanner/issues/191))
15
+ * session keepalive uses Process.clock_gettime instead of Time.now ([#185](https://github.com/googleapis/ruby-spanner/pull/185))
16
+
3
17
  ### 2.27.0 (2025-05-28)
4
18
 
5
19
  #### Features
@@ -33,8 +33,9 @@ module Google
33
33
  # {Google::Cloud::Spanner::Admin::Database.database_admin}.list_backup_operations instead.
34
34
  #
35
35
  class List < DelegateClass(::Array)
36
+ # The `Spanner::Service` reference.
36
37
  # @private
37
- # The gRPC Service object.
38
+ # @return [::Google::Cloud::Spanner::Service]
38
39
  attr_accessor :service
39
40
 
40
41
  # @private
@@ -148,13 +149,14 @@ module Google
148
149
  end
149
150
  end
150
151
 
151
- ##
152
- # @private
153
- #
154
- # New Backup::Job::List from a
152
+ # Creates a new `Spanner::Backup::Job::List` of `Gapic::Operation` operations from a
155
153
  # `Gapic::PagedEnumerable<Google::Longrunning::Operation>`
156
154
  # object. Operation object is a backup operation.
157
- #
155
+ # @param grpc [::Gapic::PagedEnumerable<::Google::Longrunning::Operation>]
156
+ # Wrapped `Gapic::PagedEnumberable` reference.
157
+ # @param service [::Google::Cloud::Spanner::Service] A `Spanner::Service` reference.
158
+ # @private
159
+ # @return [::Google::Cloud::Spanner::Backup::Job::List]
158
160
  def self.from_grpc grpc, service
159
161
  operations_client =
160
162
  service.databases.instance_variable_get "@operations_client"
@@ -58,12 +58,14 @@ module Google
58
58
  # end
59
59
  #
60
60
  class Job
61
- ##
62
- # @private The `Gapic::Operation` gRPC object.
61
+ # The wrapped `Gapic::Operation` object.
62
+ # @private
63
+ # @return [::Gapic::Operation]
63
64
  attr_accessor :grpc
64
65
 
65
- ##
66
- # @private The gRPC Service object.
66
+ # The `Spanner::Service` reference.
67
+ # @private
68
+ # @return [::Google::Cloud::Spanner::Service]
67
69
  attr_accessor :service
68
70
 
69
71
  ##
@@ -265,8 +267,11 @@ module Google
265
267
  Convert.timestamp_to_time @grpc.metadata.cancel_time
266
268
  end
267
269
 
268
- ##
269
- # @private New Backup::Job from a `Gapic::Operation` object.
270
+ # Create a new Backup::Job from a `Gapic::Operation` object.
271
+ # @param grpc [::Gapic::Operation`] The wrapped `Gapic::Operation` object.
272
+ # @param service [::Google::Cloud::Spanner::Service] A `Spanner::Service` reference.
273
+ # @private
274
+ # @return [::Google::Cloud::Spanner::Backup::Job]
270
275
  def self.from_grpc grpc, service
271
276
  new.tap do |job|
272
277
  job.instance_variable_set :@grpc, grpc
@@ -63,8 +63,18 @@ module Google
63
63
  # new_partition
64
64
  #
65
65
  class BatchClient
66
- ##
67
- # @private Creates a new Spanner BatchClient instance.
66
+ # Creates a new Spanner BatchClient instance.
67
+ # @param project [::Google::Cloud::Spanner::Project] A `Spanner::Project` ref.
68
+ # @param instance_id [::String] Instance id, e.g. `"my-instance"`.
69
+ # @param database_id [::String] Database id, e.g. `"my-database"`.
70
+ # @param session_labels [::Hash, nil] Optional. The labels to be applied to all sessions
71
+ # created by the client. Example: `"team" => "billing-service"`.
72
+ # @param query_options [::Hash, nil] Optional. A hash of values to specify the custom
73
+ # query options for executing SQL query. Example parameter `:optimizer_version`.
74
+ # @param directed_read_options [::Hash, nil] Optional. Client options used to set
75
+ # the `directed_read_options` for all ReadRequests and ExecuteSqlRequests.
76
+ # Converts to `V1::DirectedReadOptions`. Example option: `:exclude_replicas`.
77
+ # @private
68
78
  def initialize project, instance_id, database_id, session_labels: nil,
69
79
  query_options: nil, directed_read_options: nil
70
80
  @project = project
@@ -404,15 +414,18 @@ module Google
404
414
 
405
415
  protected
406
416
 
407
- ##
408
- # @private Raise an error unless an active connection to the service is
417
+ # Raise an error unless an active connection to the service is
409
418
  # available.
419
+ # @private
420
+ # @raise [StandardError]
421
+ # @return [nil]
410
422
  def ensure_service!
411
423
  raise "Must have active connection to service" unless @project.service
412
424
  end
413
425
 
414
- ##
415
426
  # New session for each use.
427
+ # @private
428
+ # @return [::Google::Cloud::Spanner::Session]
416
429
  def session
417
430
  ensure_service!
418
431
  grpc = @project.service.create_session \
@@ -51,12 +51,26 @@ module Google
51
51
  # end
52
52
  #
53
53
  class Client
54
- ##
54
+ # A semi-arbitrary constant for thread-wide global parameter name
55
55
  # @private
56
56
  IS_TRANSACTION_RUNNING_KEY = "ruby_spanner_is_transaction_running".freeze
57
57
 
58
- ##
59
- # @private Creates a new Spanner Client instance.
58
+ # Creates a new Spanner Client instance.
59
+ # @param project [::Google::Cloud::Spanner::Project] A `Spanner::Project` ref.
60
+ # @param instance_id [::String] Instance id, e.g. `"my-instance"`.
61
+ # @param database_id [::String] Database id, e.g. `"my-database"`.
62
+ # @param session_labels [::Hash, nil] Optional. The labels to be applied to all sessions
63
+ # created by the client. Example: `"team" => "billing-service"`.
64
+ # @param pool_opts [::Hash] Optional. `Spanner::Pool` creation options.
65
+ # Example parameter: `:keepalive`.
66
+ # @param query_options [::Hash, nil] Optional. A hash of values to specify the custom
67
+ # query options for executing SQL query. Example parameter `:optimizer_version`.
68
+ # @param database_role [::String, nil] Optional. The Spanner session creator role.
69
+ # Example: `analyst`
70
+ # @param directed_read_options [::Hash, nil] Optional. Client options used to set
71
+ # the `directed_read_options` for all ReadRequests and ExecuteSqlRequests.
72
+ # Converts to `V1::DirectedReadOptions`. Example option: `:exclude_replicas`.
73
+ # @private
60
74
  def initialize project, instance_id, database_id, session_labels: nil,
61
75
  pool_opts: {}, query_options: nil, database_role: nil,
62
76
  directed_read_options: nil
@@ -89,7 +103,7 @@ module Google
89
103
  end
90
104
 
91
105
  # The Spanner project connected to.
92
- # @return [Project]
106
+ # @return [::Google::Cloud::Spanner::Project]
93
107
  def project
94
108
  @project
95
109
  end
@@ -878,6 +892,14 @@ module Google
878
892
  # and all replicas are exhausted without finding a healthy replica,
879
893
  # Spanner will wait for a replica in the list to become available,
880
894
  # requests may fail due to DEADLINE_EXCEEDED errors.
895
+ # @param [::Google::Cloud::Spanner::V1::ReadRequest::OrderBy] order_by An option to control the order in which
896
+ # rows are returned from a read.
897
+ # To see the available options refer to
898
+ # [Google::Cloud::Spanner::V1::ReadRequest::OrderBy](https://cloud.google.com/ruby/docs/reference/google-cloud-spanner-v1/latest/Google-Cloud-Spanner-V1-ReadRequest-OrderBy)
899
+ # @param [::Google::Cloud::Spanner::V1::ReadRequest::LockHint] lock_hint A lock hint mechanism for reads done
900
+ # within a transaction.
901
+ # To see the available options refer to
902
+ # [Google::Cloud::Spanner::V1::ReadRequest::LockHint](https://cloud.google.com/ruby/docs/reference/google-cloud-spanner-v1/latest/Google-Cloud-Spanner-V1-ReadRequest-LockHint)
881
903
  #
882
904
  # @return [Google::Cloud::Spanner::Results] The results of the read.
883
905
  #
@@ -962,7 +984,7 @@ module Google
962
984
  #
963
985
  def read table, columns, keys: nil, index: nil, limit: nil,
964
986
  single_use: nil, request_options: nil, call_options: nil,
965
- directed_read_options: nil
987
+ directed_read_options: nil, order_by: nil, lock_hint: nil
966
988
  validate_single_use_args! single_use
967
989
  ensure_service!
968
990
 
@@ -981,7 +1003,9 @@ module Google
981
1003
  request_options: request_options,
982
1004
  call_options: call_options,
983
1005
  directed_read_options: directed_read_options || @directed_read_options,
984
- route_to_leader: route_to_leader
1006
+ route_to_leader: route_to_leader,
1007
+ order_by: order_by,
1008
+ lock_hint: lock_hint
985
1009
  end
986
1010
  results
987
1011
  end
@@ -2102,15 +2126,28 @@ module Google
2102
2126
  begin
2103
2127
  Thread.current[IS_TRANSACTION_RUNNING_KEY] = true
2104
2128
  yield tx
2105
- transaction_id = nil
2106
- transaction_id = tx.transaction_id if tx.existing_transaction?
2107
- commit_resp = @project.service.commit \
2108
- tx.session.path, tx.mutations,
2129
+
2130
+ unless tx.existing_transaction?
2131
+ # This can happen if the yielded `tx` object was only used to add mutations.
2132
+ # Then it never called any RPCs and didn't create a server-side Transaction object.
2133
+ # In which case we should make an explicit BeginTransaction call here.
2134
+ tx.safe_begin_transaction!(
2135
+ exclude_from_change_streams: exclude_txn_from_change_streams,
2136
+ request_options: request_options,
2137
+ call_options: call_options
2138
+ )
2139
+ end
2140
+
2141
+ transaction_id = tx.transaction_id
2142
+ commit_resp = @project.service.commit(
2143
+ tx.session.path,
2144
+ tx.mutations,
2109
2145
  transaction_id: transaction_id,
2110
2146
  exclude_txn_from_change_streams: exclude_txn_from_change_streams,
2111
2147
  commit_options: commit_options,
2112
2148
  request_options: request_options,
2113
2149
  call_options: call_options
2150
+ )
2114
2151
  resp = CommitResponse.from_grpc commit_resp
2115
2152
  commit_options ? resp : resp.timestamp
2116
2153
  rescue GRPC::Aborted,
@@ -2409,17 +2446,21 @@ module Google
2409
2446
  @pool.reset
2410
2447
  end
2411
2448
 
2412
- ##
2449
+ # Creates a new Session objece.
2450
+ # @param multiplexed [::Boolean] Optional. Default to `false`.
2451
+ # If `true`, specifies a multiplexed session.
2413
2452
  # @private
2414
- # Creates a new session object every time.
2415
- def create_new_session
2453
+ # @return [::Google::Cloud::Spanner::Session]
2454
+ def create_new_session multiplexed: false
2416
2455
  ensure_service!
2417
2456
  grpc = @project.service.create_session \
2418
2457
  Admin::Database::V1::DatabaseAdmin::Paths.database_path(
2419
2458
  project: project_id, instance: instance_id, database: database_id
2420
2459
  ),
2421
2460
  labels: @session_labels,
2422
- database_role: @database_role
2461
+ database_role: @database_role,
2462
+ multiplexed: multiplexed
2463
+
2423
2464
  Session.from_grpc grpc, @project.service, query_options: @query_options
2424
2465
  end
2425
2466
 
@@ -74,11 +74,16 @@ module Google
74
74
  # end
75
75
  #
76
76
  class Instance
77
- ##
78
- # @private The gRPC Service object.
77
+ # The `Spanner::Service` reference.
78
+ # @private
79
+ # @return [::Google::Cloud::Spanner::Service]
79
80
  attr_accessor :service
80
81
 
81
- # @private Creates a new Instance instance.
82
+ # Creates a new `Spanner::Instance` instance.
83
+ # @param grpc [::Google::Cloud::Spanner::Admin::Instance::V1::Instance]
84
+ # The protobuf `V1::Instance` underlying object.
85
+ # @param service [::Google::Cloud::Spanner::Service] A `Spanner::Service` reference.
86
+ # @private
82
87
  def initialize grpc, service
83
88
  @grpc = grpc
84
89
  @service = service
@@ -957,9 +962,13 @@ module Google
957
962
  grpc.permissions
958
963
  end
959
964
 
960
- ##
961
- # @private Creates a new Instance instance from a
965
+ # Creates a new Instance instance from a
962
966
  # `Google::Cloud::Spanner::Admin::Instance::V1::Instance`.
967
+ # @param grpc [::Google::Cloud::Spanner::Admin::Instance::V1::Instance]
968
+ # The protobuf `V1::Instance` underlying object.
969
+ # @param service [::Google::Cloud::Spanner::Service] A `Spanner::Service` reference.
970
+ # @private
971
+ # @return [::Google::Cloud::Spanner::Instance]
963
972
  def self.from_grpc grpc, service
964
973
  new grpc, service
965
974
  end
@@ -75,7 +75,7 @@ module Google
75
75
  (?:T(?!$)
76
76
  (?:(?<hours>-?\d+)H)?
77
77
  (?:(?<minutes>-?\d+)M)?
78
- (?:(?<seconds>-?(?!S)\d*(?:[\.,]\d{1,9})?)S)?)?
78
+ (?:(?<seconds>-?(?!S)\d*(?:[.,]\d{1,9})?)S)?)?
79
79
  $
80
80
  /x
81
81
  interval_months = 0
@@ -44,8 +44,14 @@ module Google
44
44
  # results = batch_snapshot.execute_partition partition
45
45
  #
46
46
  class Partition
47
- # @ private
47
+ # A `V1::ExecuteSqlRequest` that is related to this partition.
48
+ # @private
49
+ # @return [::Google::Cloud::Spanner::V1::ExecuteSqlRequest]
48
50
  attr_reader :execute
51
+
52
+ # A `V1::ReadRequest` that is related to this partition.
53
+ # @private
54
+ # @return [::Google::Cloud::Spanner::V1::ReadRequest]
49
55
  attr_reader :read
50
56
 
51
57
  ##
@@ -36,6 +36,16 @@ module Google
36
36
  # and `Session` objects as values.
37
37
  attr_accessor :sessions_in_use
38
38
 
39
+ # Creates a new Session pool that manages non-multiplexed sessions.
40
+ # @param client [::Google::Cloud::Spanner::Client] A `Spanner::Client` reference
41
+ # @param min [::Integer] Min number of sessions to keep
42
+ # @param max [::Integer] Max number of sessions to keep
43
+ # @param keepalive [::Numeric] How long after their last usage the sessions can be reclaimed
44
+ # @param fail [::Boolean] If `true` the pool will raise `SessionLimitError` if number of new sessions
45
+ # needed is more that can be created due to the `max` parameter. If `false` it will wait instead.
46
+ # @param threads [::Integer, nil] Number of threads in the thread pool that is used for keepalive and
47
+ # release session actions. If `nil` the Pool will choose a reasonable default.
48
+ # @private
39
49
  def initialize client, min: 10, max: 100, keepalive: 1800,
40
50
  fail: true, threads: nil
41
51
  @client = client
@@ -52,6 +62,11 @@ module Google
52
62
  init
53
63
  end
54
64
 
65
+ # Provides a session for running an operation
66
+ # @yield session Session a client can use to run an operation
67
+ # @yieldparam [::Google::Cloud::Spanner::Session] `Spanner::Session` to run an operation
68
+ # @private
69
+ # @return [nil]
55
70
  def with_session
56
71
  session = checkout_session
57
72
  begin
@@ -66,12 +66,22 @@ module Google
66
66
  # end
67
67
  #
68
68
  class Project
69
- ##
70
- # @private The Service object.
71
- attr_accessor :service, :query_options
69
+ # The `Spanner::Service` reference.
70
+ # @private
71
+ # @return [::Google::Cloud::Spanner::Service]
72
+ attr_accessor :service
72
73
 
73
- ##
74
- # @private Creates a new Spanner Project instance.
74
+ # A hash of values to specify the custom query options for executing SQL query.
75
+ # Example option: `:optimizer_version`.
76
+ # @private
77
+ # @return [::Hash, nil]
78
+ attr_accessor :query_options
79
+
80
+ # Creates a new Spanner Project instance.
81
+ # @param service [::Google::Cloud::Spanner::Service] The `Spanner::Service` ref.
82
+ # @param query_options [::Hash, nil] Optional. A hash of values to specify the custom
83
+ # query options for executing SQL query. Example option: `:optimizer_version`.
84
+ # @private
75
85
  def initialize service, query_options: nil
76
86
  @service = service
77
87
  @query_options = query_options
@@ -80,6 +90,8 @@ module Google
80
90
  ##
81
91
  # The identifier for the Cloud Spanner project.
82
92
  #
93
+ # @return [::String]
94
+ #
83
95
  # @example
84
96
  # require "google/cloud"
85
97
  #
@@ -40,19 +40,44 @@ module Google
40
40
  # puts "Column #{name} is type #{type}"
41
41
  # end
42
42
  #
43
+ # results.rows.each do |row|
44
+ # puts "User #{row[:id]} is #{row[:name]}"
45
+ # end
46
+ #
43
47
  class Results
44
- ##
45
- # @private Object of type
46
- # Google::Cloud::Spanner::V1::ResultSetMetadata
48
+ # The `V1::ResultSetMetadata` protobuf object from the first
49
+ # PartialResultSet.
50
+ # @private
51
+ # @return [::Google::Cloud::Spanner::V1::ResultSetMetadata]
47
52
  attr_reader :metadata
48
53
 
54
+ # Creates a new Results instance.
55
+ # @param service [::Google::Cloud::Spanner::Service] The `Spanner::Service` reference.
56
+ # @param partial_result_sets [::Enumerable<::Google::Cloud::Spanner::V1::PartialResultSet>]
57
+ # Raw enumerable from grpc `StreamingRead` call.
58
+ # @param session_name [::String] Required.
59
+ # The session in which the transaction to be committed is running.
60
+ # Values are of the form:
61
+ # `projects/<project_id>/instances/<instance_id>/databases/<database_id>/sessions/<session_id>`.
62
+ # @param metadata [::Google::Cloud::Spanner::V1::ResultSetMetadata] ParialResultSet metadata object
63
+ # @param stats [::Google::Cloud::Spanner::V1::ResultSetStats] Query plan and execution statistics
64
+ # for the statement that produced this streaming result set.
65
+ # @private
66
+ def initialize service, partial_result_sets, session_name, metadata, stats
67
+ @service = service
68
+ @partial_result_sets = partial_result_sets
69
+ @session_name = session_name
70
+ @metadata = metadata
71
+ @stats = stats
72
+ end
73
+
49
74
  ##
50
75
  # The read timestamp chosen for single-use snapshots (read-only
51
76
  # transactions).
52
77
  # @return [Time] The chosen timestamp.
53
78
  def timestamp
54
- return nil if @metadata.nil? || @metadata.transaction.nil?
55
- Convert.timestamp_to_time @metadata.transaction.read_timestamp
79
+ return nil if transaction.nil?
80
+ Convert.timestamp_to_time transaction.read_timestamp
56
81
  end
57
82
 
58
83
  ##
@@ -78,9 +103,9 @@ module Google
78
103
  @fields ||= Fields.from_grpc @metadata.row_type.fields
79
104
  end
80
105
 
81
- ##
106
+ # Returns a transaction from the first ResultSet's metadata if available
82
107
  # @private
83
- # Returns a transaction if available
108
+ # @return [::Google::Cloud::Spanner::V1::Transaction, nil]
84
109
  def transaction
85
110
  @metadata&.transaction
86
111
  end
@@ -128,16 +153,18 @@ module Google
128
153
  loop do
129
154
  begin
130
155
  if should_resume_request
131
- @enum = resume_request(resume_token)
156
+ @partial_result_sets = resume_request(resume_token)
132
157
  buffered_responses = []
133
158
  should_resume_request = false
134
159
  elsif should_retry_request
135
- @enum = retry_request()
160
+ @partial_result_sets = retry_request()
136
161
  buffered_responses = []
137
162
  should_retry_request = false
138
163
  end
139
164
 
140
- grpc = @enum.next
165
+ # @type [::Google::Cloud::Spanner::V1::PartialResultsSet]
166
+ grpc = @partial_result_sets.next
167
+
141
168
  # metadata should be set before the first iteration...
142
169
  @metadata ||= grpc.metadata
143
170
  @stats ||= grpc.stats
@@ -243,13 +270,13 @@ module Google
243
270
  def resume_request resume_token
244
271
  if @execute_query_options
245
272
  @service.execute_streaming_sql(
246
- @session_path,
273
+ @session_name,
247
274
  @sql,
248
275
  **@execute_query_options.merge(resume_token: resume_token)
249
276
  )
250
277
  else
251
278
  @service.streaming_read_table(
252
- @session_path,
279
+ @session_name,
253
280
  @table,
254
281
  @columns,
255
282
  **@read_options.merge(resume_token: resume_token)
@@ -262,9 +289,9 @@ module Google
262
289
  # Retries a request, by re-executing it from scratch.
263
290
  def retry_request
264
291
  if @execute_query_options
265
- @service.execute_streaming_sql @session_path, @sql, **@execute_query_options
292
+ @service.execute_streaming_sql @session_name, @sql, **@execute_query_options
266
293
  else
267
- @service.streaming_read_table @session_path, @table, @columns, **@read_options
294
+ @service.streaming_read_table @session_name, @table, @columns, **@read_options
268
295
  end
269
296
  end
270
297
 
@@ -295,35 +322,80 @@ module Google
295
322
  @stats.row_count == :row_count_exact
296
323
  end
297
324
 
325
+ # Creates a `Spanner::Results` for a given `PartialResultSet` grpc stream.
326
+ # @param partial_result_sets [::Enumerable<::Google::Cloud::Spanner::V1::PartialResultSet>]
327
+ # Raw enumerable from underlying grpc call.
328
+ # @param service [::Google::Cloud::Spanner::Service] The `Spanner::Service` reference.
329
+ # @param session_name [::String] Required.
330
+ # The session in which the transaction to be committed is running.
331
+ # Values are of the form:
332
+ # `projects/<project_id>/instances/<instance_id>/databases/<database_id>/sessions/<session_id>`.
298
333
  # @private
299
- def self.from_enum enum, service
300
- grpc = enum.peek
301
- new.tap do |results|
302
- results.instance_variable_set :@metadata, grpc.metadata
303
- results.instance_variable_set :@stats, grpc.stats
304
- results.instance_variable_set :@enum, enum
305
- results.instance_variable_set :@service, service
306
- end
334
+ # @return [::Google::Cloud::Spanner::Results]
335
+ def self.from_partial_result_sets partial_result_sets, service, session_name
336
+ # @type [::Google::Cloud::Spanner::V1::PartialResultSet]
337
+ partial_result_set = partial_result_sets.peek
338
+ metadata = partial_result_set.metadata
339
+ stats = partial_result_set.stats
340
+ new service, partial_result_sets, session_name, metadata, stats
307
341
  rescue GRPC::BadStatus => e
308
342
  raise Google::Cloud::Error.from_error(e)
309
343
  end
310
344
 
345
+ # Creates a `Spanner::Results` wrapper from ExecuteStreamingSql call results and params.
346
+ # @param response [::Enumerable<::Google::Cloud::Spanner::V1::PartialResultSet>]
347
+ # Raw enumerable from grpc `ExecuteStreamingSql` call.
348
+ # @param service [::Google::Cloud::Spanner::Service] The `Spanner::Service` reference.
349
+ # @param session_name [::String] Required.
350
+ # The session in which the transaction to be committed is running.
351
+ # Values are of the form:
352
+ # `projects/<project_id>/instances/<instance_id>/databases/<database_id>/sessions/<session_id>`.
353
+ # @param sql [::String] The SQL query string that was executed.
354
+ # @param execute_query_options [::Hash] Full request options
355
+ # that were sent to the `service.execute_streaming_sql`. This hash joins params needed to
356
+ # construct `::Gapic::CallOptions`, e.g. `call_options` and header-related `route_to_leader`
357
+ # with params specific to `execute_streaming_sql`, such as `seqno`.
311
358
  # @private
312
- def self.from_execute_query_response response, service, session_path, sql, execute_query_options
313
- from_enum(response, service).tap do |results|
314
- results.instance_variable_set :@session_path, session_path
359
+ # @return [::Google::Cloud::Spanner::Results]
360
+ def self.from_execute_query_response response, service, session_name, sql, execute_query_options
361
+ from_partial_result_sets(response, service, session_name).tap do |results|
362
+ execute_query_options_copy = execute_query_options.dup
363
+ unless results.metadata.transaction.nil?
364
+ execute_query_options_copy[:transaction] = V1::TransactionSelector.new id: results.metadata.transaction.id
365
+ end
366
+
315
367
  results.instance_variable_set :@sql, sql
316
- results.instance_variable_set :@execute_query_options, execute_query_options
368
+ results.instance_variable_set :@execute_query_options, execute_query_options_copy
317
369
  end
318
370
  end
319
371
 
372
+ # Creates a `Spanner::Results` wrapper from StreamingRead call results and params.
373
+ # @param response [::Enumerable<::Google::Cloud::Spanner::V1::PartialResultSet>]
374
+ # Raw enumerable from grpc `StreamingRead` call.
375
+ # @param service [::Google::Cloud::Spanner::Service] The `Spanner::Service` reference.
376
+ # @param session_name [::String] Required.
377
+ # The session in which the transaction to be committed is running.
378
+ # Values are of the form:
379
+ # `projects/<project_id>/instances/<instance_id>/databases/<database_id>/sessions/<session_id>`.
380
+ # @param table [::String] The name of the table in the database that was read by `StreamingRead` request.
381
+ # @param columns [::Array<String, Symbol>] The columns of table that were returned
382
+ # by the `StreamingRead` request.
383
+ # @param read_options [::Hash] Full request options
384
+ # that were sent to the `service.streaming_read_table`. This hash joins params needed to
385
+ # construct `::Gapic::CallOptions`, e.g. `call_options` and header-related `route_to_leader`
386
+ # with params specific to `streaming_read_table`, such as `keys`.
320
387
  # @private
321
- def self.from_read_response response, service, session_path, table, columns, read_options
322
- from_enum(response, service).tap do |results|
323
- results.instance_variable_set :@session_path, session_path
388
+ # @return [::Google::Cloud::Spanner::Results]
389
+ def self.from_read_response response, service, session_name, table, columns, read_options
390
+ from_partial_result_sets(response, service, session_name).tap do |results|
391
+ read_options_copy = read_options.dup
392
+ unless results.metadata.transaction.nil?
393
+ read_options_copy[:transaction] = V1::TransactionSelector.new id: results.metadata.transaction.id
394
+ end
395
+
324
396
  results.instance_variable_set :@table, table
325
397
  results.instance_variable_set :@columns, columns
326
- results.instance_variable_set :@read_options, read_options
398
+ results.instance_variable_set :@read_options, read_options_copy
327
399
  end
328
400
  end
329
401
 
@@ -43,8 +43,18 @@ module Google
43
43
  RST_STREAM_INTERNAL_ERROR = "Received RST_STREAM".freeze
44
44
  EOS_INTERNAL_ERROR = "Received unexpected EOS on DATA frame from server".freeze
45
45
 
46
- ##
47
- # Creates a new Service instance.
46
+ # Creates a new `Spanner::Service` instance.
47
+ # @param project [::String] The project id to use
48
+ # @param credentials [::Symbol, ::Google::Auth::Credentials] Credentials
49
+ # @param quota_project [::String, nil] Optional. The quota project id to use
50
+ # @param host [::String, nil] Optional. The endpoint override.
51
+ # @param timeout [::Numeric, nil] Optional. Timeout for Gapic client.
52
+ # @param lib_name [::String, nil] Optional. Library name for headers.
53
+ # @param lib_version [::String, nil] Optional. Library version for headers.
54
+ # @param enable_leader_aware_routing [::Boolean, nil] Optional. Whether Leader
55
+ # Aware Routing should be enabled.
56
+ # @param universe_domain [::String, nil] Optional. The domain of the universe to connect to.
57
+ # @private
48
58
  def initialize project, credentials, quota_project: nil,
49
59
  host: nil, timeout: nil, lib_name: nil, lib_version: nil,
50
60
  enable_leader_aware_routing: nil, universe_domain: nil
@@ -82,6 +92,8 @@ module Google
82
92
  GRPC::Core::CallCredentials.new credentials.client.updater_proc
83
93
  end
84
94
 
95
+ # `V1::Spanner::Client` or a mock.
96
+ # @return [::Google::Cloud::Spanner::V1::Spanner::Client]
85
97
  def service
86
98
  return mocked_service if mocked_service
87
99
  @service ||=
@@ -145,6 +157,11 @@ module Google
145
157
  paged_enum.response
146
158
  end
147
159
 
160
+ # Gets information about a particular instance
161
+ # @param name [::String] The name of the Spanner instance, e.g. 'myinstance'
162
+ # or path to the Spanner instance, e.g. `projects/myproject/instances/myinstance`.
163
+ # @private
164
+ # @return [::Google::Cloud::Spanner::Admin::Instance::V1::Instance]
148
165
  def get_instance name, call_options: nil
149
166
  opts = default_options call_options: call_options
150
167
  request = { name: instance_path(name) }
@@ -329,13 +346,41 @@ module Google
329
346
  service.get_session({ name: session_name }, opts)
330
347
  end
331
348
 
349
+ # Creates a new Spanner session.
350
+ # This creates a `V1::Session` protobuf object not wrapped in `Spanner::Session`.
351
+ #
352
+ # @param database_name [::String] The full name of the database.
353
+ # @param labels [::Hash, nil] Optional. The labels to be applied to all sessions
354
+ # created by the client. Example: `"team" => "billing-service"`.
355
+ # @param call_options [::Hash, nil] Optional. A hash of values to specify the custom
356
+ # call options. Example option `:timeout`.
357
+ # @param database_role [::String, nil] Optional. The Spanner session creator role.
358
+ # Example: `analyst`.
359
+ # @param multiplexed [::Boolean] Optional. Default to `false`.
360
+ # If `true`, specifies a multiplexed session.
361
+ # @return [::Google::Cloud::Spanner::V1::Session]
362
+ # @private
332
363
  def create_session database_name, labels: nil,
333
- call_options: nil, database_role: nil
364
+ call_options: nil, database_role: nil,
365
+ multiplexed: false
334
366
  route_to_leader = LARHeaders.create_session
335
- opts = default_options session_name: database_name,
336
- call_options: call_options,
337
- route_to_leader: route_to_leader
338
- session = V1::Session.new labels: labels, creator_role: database_role if labels || database_role
367
+ opts = default_options(
368
+ session_name: database_name,
369
+ call_options: call_options,
370
+ route_to_leader: route_to_leader
371
+ )
372
+
373
+ # check if we need a session object in request or server defaults would work.
374
+ params_diff_from_default = !(labels.nil? && database_role.nil? && !multiplexed)
375
+
376
+ if params_diff_from_default
377
+ session = V1::Session.new(
378
+ labels: labels,
379
+ creator_role: database_role,
380
+ multiplexed: multiplexed
381
+ )
382
+ end
383
+
339
384
  service.create_session(
340
385
  { database: database_name, session: session }, opts
341
386
  )
@@ -414,7 +459,7 @@ module Google
414
459
  resume_token: nil, partition_token: nil,
415
460
  request_options: nil, call_options: nil,
416
461
  data_boost_enabled: nil, directed_read_options: nil,
417
- route_to_leader: nil
462
+ route_to_leader: nil, order_by: nil, lock_hint: nil
418
463
  opts = default_options session_name: session_name,
419
464
  call_options: call_options,
420
465
  route_to_leader: route_to_leader
@@ -422,7 +467,8 @@ module Google
422
467
  session: session_name, table: table_name, columns: columns,
423
468
  key_set: keys, transaction: transaction, index: index,
424
469
  limit: limit, resume_token: resume_token,
425
- partition_token: partition_token, request_options: request_options
470
+ partition_token: partition_token, request_options: request_options,
471
+ order_by: order_by, lock_hint: lock_hint
426
472
  }
427
473
  request[:data_boost_enabled] = data_boost_enabled unless data_boost_enabled.nil?
428
474
  request[:directed_read_options] = directed_read_options unless directed_read_options.nil?
@@ -463,6 +509,29 @@ module Google
463
509
  service.partition_query request, opts
464
510
  end
465
511
 
512
+ # Commits a transaction. Can be a predefined (`transaction_id`) transaction
513
+ # or a single-use created for this request. The request includes the mutations to be
514
+ # applied to rows in the database.
515
+ #
516
+ # @param session_name [::String]
517
+ # Required. The session in which the transaction to be committed is running.
518
+ # @param mutations [::Array<::Google::Cloud::Spanner::V1::Mutation>] Optional.
519
+ # The mutations to be executed when this transaction commits. All
520
+ # mutations are applied atomically, in the order they appear in
521
+ # this list. Defaults to an empty array.
522
+ # @param transaction_id [::String, nil] Optional.
523
+ # Commit a previously-started transaction. If nil, a new single-use transation will be used.
524
+ # @param exclude_txn_from_change_streams [::Boolean] Optional. Defaults to `false`.
525
+ # When `exclude_txn_from_change_streams` is set to `true`, it prevents read
526
+ # or write transactions from being tracked in change streams.
527
+ # @param commit_options [::Hash, nil] Optional. A hash of commit options.
528
+ # Example option: `:return_commit_stats`.
529
+ # @param request_options [::Hash, nil] Optional. Common request options.
530
+ # Example option: `:priority`.
531
+ # @param call_options [::Hash, nil] Optional. A hash of values to specify the custom
532
+ # call options. Example option `:timeout`.
533
+ # @private
534
+ # @return [::Google::Cloud::Spanner::V1::CommitResponse]
466
535
  def commit session_name, mutations = [],
467
536
  transaction_id: nil, exclude_txn_from_change_streams: false,
468
537
  commit_options: nil, request_options: nil, call_options: nil
@@ -484,10 +553,16 @@ module Google
484
553
  }
485
554
 
486
555
  request = add_commit_options request, commit_options
487
-
556
+ # request is a hash equivalent of `::Google::Cloud::Spanner::V1::CommitRequest`
488
557
  service.commit request, opts
489
558
  end
490
559
 
560
+ # Merges commit options hash to a hash representing a `V1::CommitRequest`.
561
+ # @param request [::Hash] A `::Google::Cloud::Spanner::V1::CommitRequest` in a hash form.
562
+ # @param commit_options [::Hash, nil] Optional. A hash of commit options.
563
+ # Example option: `:return_commit_stats`.
564
+ # @return [::Hash] An enriched `::Google::Cloud::Spanner::V1::CommitRequest` in a hash form.
565
+ # @private
491
566
  def add_commit_options request, commit_options
492
567
  if commit_options
493
568
  if commit_options.key? :return_commit_stats
@@ -512,6 +587,38 @@ module Google
512
587
  service.rollback request, opts
513
588
  end
514
589
 
590
+ # Explicitly begins a new transaction, making a `BeginTransaction` rpc call,
591
+ # and creating and returning a `V1::Transaction` object.
592
+ #
593
+ # Explicit transaction creation can often be skipped:
594
+ # {::Google::Cloud::Spanner::V1::Spanner::Client#read Read},
595
+ # {::Google::Cloud::Spanner::V1::Spanner::Client#execute_sql ExecuteSql} and
596
+ # {::Google::Cloud::Spanner::V1::Spanner::Client#execute_batch_dml ExecuteBatchDml}
597
+ # can begin a new transaction as part of the request (so-called inline-begin).
598
+ # The inline-begin functionality is used in methods on `Spanner::Transaction` class,
599
+ # e.g. `Spanner::Transaction#read`, accessible to the end-users via the `Spanner::Client#transaction` method.
600
+ #
601
+ # All the above methods, and {::Google::Cloud::Spanner::V1::Spanner::Client#commit Commit}
602
+ # can utilize single-use transactions that do not require an explicit BeginTransaction call.
603
+ # Single-use transactions are used by the methods on `Spanner::Client` class,
604
+ # e.g. `Spanner::Client#read`, with the exception of `Spanner::Client#transaction`.
605
+ #
606
+ # @param session_name [::String]
607
+ # Required. The session in which the transaction is to be created.
608
+ # Values are of the form:
609
+ # `projects/<project_id>/instances/<instance_id>/databases/<database_id>/sessions/<session_id>`.
610
+ # @param exclude_txn_from_change_streams [::Boolean] Optional. Defaults to `false`.
611
+ # When `exclude_txn_from_change_streams` is set to `true`, it prevents read
612
+ # or write transactions from being tracked in change streams.
613
+ # @param request_options [::Hash, nil] Optional. Common request options.
614
+ # Example option: `:priority`.
615
+ # @param call_options [::Hash, nil] Optional. A hash of values to specify the custom
616
+ # call options. Example option `:timeout`.
617
+ # @param route_to_leader [::String, nil] Optional. The value to be sent
618
+ # as `x-goog-spanner-route-to-leader` header for leader aware routing.
619
+ # Expected values: `"true"` or `"false"`.
620
+ # @private
621
+ # @return [::Google::Cloud::Spanner::V1::Transaction]
515
622
  def begin_transaction session_name,
516
623
  exclude_txn_from_change_streams: false,
517
624
  request_options: nil,
@@ -647,6 +754,25 @@ module Google
647
754
  databases.list_database_operations request, opts
648
755
  end
649
756
 
757
+ # Lists the backup `::Google::Longrunning::Operation` long-running operations in
758
+ # the given instance. A backup operation has a name of the form
759
+ # projects/<project>/instances/<instance>/backups/<backup>/operations/<operation>.
760
+ # @param instance_id [::String] The name of the Spanner instance, e.g. 'myinstance'
761
+ # or path to the Spanner instance, e.g. `projects/myproject/instances/myinstance`.
762
+ # @param filter [::String, nil] Optional.
763
+ # An expression that filters the list of returned backup operations.
764
+ # Example filter: `done:true`.
765
+ # @param page_size [::Integer, nil] Optional.
766
+ # Number of operations to be returned in the response. If 0 or
767
+ # less, defaults to the server's maximum allowed page size.
768
+ # @param page_token [::String, nil] Optional.
769
+ # If set, `page_token` should contain a value received as a `next_page_token`
770
+ # from a previous `ListBackupOperationsResponse` to the same `parent`
771
+ # and with the same `filter`.
772
+ # @param call_options [::Hash, nil] Optional. A hash of values to specify the custom
773
+ # call options. Example option `:timeout`.
774
+ # @private
775
+ # @return [::Gapic::PagedEnumerable<::Gapic::Operation>]
650
776
  def list_backup_operations instance_id,
651
777
  filter: nil, page_size: nil,
652
778
  page_token: nil,
@@ -736,6 +862,12 @@ module Google
736
862
  project: project
737
863
  end
738
864
 
865
+ # Converts an instance name to instance path.
866
+ # If an instance path is given, returns it unchanged
867
+ # @param name [::String] name of the Spanner instance, e.g. 'myinstance'
868
+ # or path to the Spanner instance, e.g. `projects/myproject/instances/myinstance`.
869
+ # @private
870
+ # @return [::String]
739
871
  def instance_path name
740
872
  return name if name.to_s.include? "/"
741
873
 
@@ -43,19 +43,28 @@ module Google
43
43
  # no operations are sent for more than an hour.
44
44
  #
45
45
  class Session
46
- ##
47
- # @private The `Google::Cloud::Spanner::V1::Session` object
46
+ # The wrapped `V1::Session` protobuf session object.
47
+ # @return [::Google::Cloud::Spanner::V1::Session]
48
+ # @private
48
49
  attr_accessor :grpc
49
50
 
50
- ##
51
- # @private The gRPC Service object.
51
+ # The `Spanner::Service` object.
52
+ # @private
53
+ # @return [::Google::Cloud::Spanner::Service]
52
54
  attr_accessor :service
53
55
 
54
- ##
55
- # @private The hash of query options.
56
+ # A hash of values to specify the custom query options for executing SQL query.
57
+ # Example option: `:optimizer_version`.
58
+ # @private
59
+ # @return [::Hash, nil]
56
60
  attr_accessor :query_options
57
61
 
58
- # @private Creates a new Session instance.
62
+ # Creates a new Session instance.
63
+ # @param grpc [::Google::Cloud::Spanner::V1::Session] Underlying `V1::Session` object.
64
+ # @param service [::Google::Cloud::Spanner::Service] A `Spanner::Service` object.
65
+ # @param query_options [::Hash, nil] Optional. A hash of values to specify the custom
66
+ # query options for executing SQL query. Example option: `:optimizer_version`.
67
+ # @private
59
68
  def initialize grpc, service, query_options: nil
60
69
  @grpc = grpc
61
70
  @service = service
@@ -63,33 +72,38 @@ module Google
63
72
  end
64
73
 
65
74
  # The unique identifier for the project.
66
- # @return [String]
75
+ # @private
76
+ # @return [::String]
67
77
  def project_id
68
78
  @grpc.name.split("/")[1]
69
79
  end
70
80
 
71
81
  # The unique identifier for the instance.
72
- # @return [String]
82
+ # @private
83
+ # @return [::String]
73
84
  def instance_id
74
85
  @grpc.name.split("/")[3]
75
86
  end
76
87
 
77
88
  # The unique identifier for the database.
78
- # @return [String]
89
+ # @private
90
+ # @return [::String]
79
91
  def database_id
80
92
  @grpc.name.split("/")[5]
81
93
  end
82
94
 
83
95
  # The unique identifier for the session.
84
- # @return [String]
96
+ # @private
97
+ # @return [::String]
85
98
  def session_id
86
99
  @grpc.name.split("/")[7]
87
100
  end
88
101
 
89
- ##
90
- # The full path for the session resource. Values are of the form
102
+ # Full session name.
103
+ # Values are of the form:
91
104
  # `projects/<project_id>/instances/<instance_id>/databases/<database_id>/sessions/<session_id>`.
92
- # @return [String]
105
+ # @private
106
+ # @return [::String]
93
107
  def path
94
108
  @grpc.name
95
109
  end
@@ -360,7 +374,7 @@ module Google
360
374
  response = service.execute_streaming_sql path, sql, **execute_query_options
361
375
 
362
376
  results = Results.from_execute_query_response response, service, path, sql, execute_query_options
363
- @last_updated_at = Time.now
377
+ @last_updated_at = Process.clock_gettime Process::CLOCK_MONOTONIC
364
378
  results
365
379
  end
366
380
 
@@ -430,7 +444,7 @@ module Google
430
444
  batch.statements, seqno,
431
445
  request_options: request_options,
432
446
  call_options: call_options
433
- @last_updated_at = Time.now
447
+ @last_updated_at = Process.clock_gettime Process::CLOCK_MONOTONIC
434
448
  results
435
449
  end
436
450
 
@@ -483,6 +497,14 @@ module Google
483
497
  # * `:multiplier` (`Numeric`) - The incremental backoff multiplier.
484
498
  # * `:retry_codes` (`Array<String>`) - The error codes that should
485
499
  # trigger a retry.
500
+ # @param [::Google::Cloud::Spanner::V1::ReadRequest::OrderBy] order_by An option to control the order in which
501
+ # rows are returned from a read.
502
+ # To see the available options refer to
503
+ # ['Google::Cloud::Spanner::V1::ReadRequest::OrderBy'](https://cloud.google.com/ruby/docs/reference/google-cloud-spanner-v1/latest/Google-Cloud-Spanner-V1-ReadRequest-OrderBy)
504
+ # @param [::Google::Cloud::Spanner::V1::ReadRequest::LockHint] lock_hint A lock hint mechanism for reads done
505
+ # within a transaction.
506
+ # To see the available options refer to
507
+ # ['Google::Cloud::Spanner::V1::ReadRequest::LockHint'](https://cloud.google.com/ruby/docs/reference/google-cloud-spanner-v1/latest/Google-Cloud-Spanner-V1-ReadRequest-LockHint)
486
508
  #
487
509
  # @return [Google::Cloud::Spanner::Results] The results of the read
488
510
  # operation.
@@ -503,7 +525,7 @@ module Google
503
525
  def read table, columns, keys: nil, index: nil, limit: nil,
504
526
  transaction: nil, partition_token: nil, request_options: nil,
505
527
  call_options: nil, data_boost_enabled: nil, directed_read_options: nil,
506
- route_to_leader: nil
528
+ route_to_leader: nil, order_by: nil, lock_hint: nil
507
529
  ensure_service!
508
530
 
509
531
  read_options = {
@@ -512,7 +534,9 @@ module Google
512
534
  partition_token: partition_token,
513
535
  request_options: request_options,
514
536
  call_options: call_options,
515
- route_to_leader: route_to_leader
537
+ route_to_leader: route_to_leader,
538
+ order_by: order_by,
539
+ lock_hint: lock_hint
516
540
  }
517
541
  read_options[:data_boost_enabled] = data_boost_enabled unless data_boost_enabled.nil?
518
542
  read_options[:directed_read_options] = directed_read_options unless directed_read_options.nil?
@@ -522,7 +546,7 @@ module Google
522
546
 
523
547
  results = Results.from_read_response response, service, path, table, columns, read_options
524
548
 
525
- @last_updated_at = Time.now
549
+ @last_updated_at = Process.clock_gettime Process::CLOCK_MONOTONIC
526
550
 
527
551
  results
528
552
  end
@@ -538,7 +562,7 @@ module Google
538
562
  max_partitions: max_partitions,
539
563
  call_options: call_options
540
564
 
541
- @last_updated_at = Time.now
565
+ @last_updated_at = Process.clock_gettime Process::CLOCK_MONOTONIC
542
566
 
543
567
  results
544
568
  end
@@ -555,7 +579,7 @@ module Google
555
579
  max_partitions: max_partitions,
556
580
  call_options: call_options
557
581
 
558
- @last_updated_at = Time.now
582
+ @last_updated_at = Process.clock_gettime Process::CLOCK_MONOTONIC
559
583
 
560
584
  results
561
585
  end
@@ -657,7 +681,7 @@ module Google
657
681
  commit_options: commit_options,
658
682
  request_options: request_options,
659
683
  call_options: call_options
660
- @last_updated_at = Time.now
684
+ @last_updated_at = Process.clock_gettime Process::CLOCK_MONOTONIC
661
685
  resp = CommitResponse.from_grpc commit_resp
662
686
  commit_options ? resp : resp.timestamp
663
687
  end
@@ -755,7 +779,7 @@ module Google
755
779
  request_options: request_options,
756
780
  call_options: call_options
757
781
  results = BatchWriteResults.new response
758
- @last_updated_at = Time.now
782
+ @last_updated_at = Process.clock_gettime Process::CLOCK_MONOTONIC
759
783
  results
760
784
  end
761
785
 
@@ -1341,7 +1365,7 @@ module Google
1341
1365
  # Rolls back the transaction, releasing any locks it holds.
1342
1366
  def rollback transaction_id
1343
1367
  service.rollback path, transaction_id
1344
- @last_updated_at = Time.now
1368
+ @last_updated_at = Process.clock_gettime Process::CLOCK_MONOTONIC
1345
1369
  true
1346
1370
  end
1347
1371
 
@@ -1370,7 +1394,7 @@ module Google
1370
1394
  def reload!
1371
1395
  ensure_service!
1372
1396
  @grpc = service.get_session path
1373
- @last_updated_at = Time.now
1397
+ @last_updated_at = Process.clock_gettime Process::CLOCK_MONOTONIC
1374
1398
  self
1375
1399
  rescue Google::Cloud::NotFoundError
1376
1400
  labels = @grpc.labels.to_h unless @grpc.labels.to_h.empty?
@@ -1379,7 +1403,7 @@ module Google
1379
1403
  project: project_id, instance: instance_id, database: database_id
1380
1404
  ),
1381
1405
  labels: labels
1382
- @last_updated_at = Time.now
1406
+ @last_updated_at = Process.clock_gettime Process::CLOCK_MONOTONIC
1383
1407
  self
1384
1408
  end
1385
1409
 
@@ -1408,18 +1432,23 @@ module Google
1408
1432
  service.delete_session path
1409
1433
  end
1410
1434
 
1411
- ##
1412
- # @private
1413
1435
  # Determines if the session has been idle longer than the given
1414
1436
  # duration.
1415
- def idle_since? duration
1437
+ # @param duration_sec [::Numeric] interval in seconds
1438
+ # @private
1439
+ # @return [::Boolean]
1440
+ def idle_since? duration_sec
1416
1441
  return true if @last_updated_at.nil?
1417
- Time.now > @last_updated_at + duration
1442
+ Process.clock_gettime(Process::CLOCK_MONOTONIC) > @last_updated_at + duration_sec
1418
1443
  end
1419
1444
 
1420
- ##
1421
- # @private Creates a new Session instance from a
1422
- # `Google::Cloud::Spanner::V1::Session`.
1445
+ # Creates a new Session instance from a `V1::Session`.
1446
+ # @param grpc [::Google::Cloud::Spanner::V1::Session] Underlying `V1::Session` object.
1447
+ # @param service [::Google::Cloud::Spanner::Service] A `Spanner::Service` ref.
1448
+ # @param query_options [::Hash, nil] Optional. A hash of values to specify the custom
1449
+ # query options for executing SQL query. Example option: `:optimizer_version`.
1450
+ # @private
1451
+ # @return [::Google::Cloud::Spanner::Session]
1423
1452
  def self.from_grpc grpc, service, query_options: nil
1424
1453
  new grpc, service, query_options: query_options
1425
1454
  end
@@ -1439,6 +1468,11 @@ module Google
1439
1468
  raise "Must have active connection to service" unless service
1440
1469
  end
1441
1470
 
1471
+ # Merge two hashes
1472
+ # @param hash [::Hash, nil]
1473
+ # @param hash_to_merge [::Hash, nil]
1474
+ # @private
1475
+ # @return [::Hash, nil]
1442
1476
  def merge_if_present hash, hash_to_merge
1443
1477
  if hash.nil?
1444
1478
  hash_to_merge
@@ -76,19 +76,40 @@ module Google
76
76
  # end
77
77
  #
78
78
  class Transaction
79
- # @private The `Google::Cloud::Spanner::V1::Transaction` object.
79
+ # The underlying `V1::Transaction` protobuf object.
80
+ # @private
81
+ # @return [::Google::Cloud::Spanner::V1::Transaction]
80
82
  attr_reader :grpc
81
83
 
82
- # @private The Session object.
84
+ # The `Spanner::Session` session for this transaction.
85
+ # @private
86
+ # @return [::Google::Cloud::Spanner::Session]
83
87
  attr_accessor :session
84
88
 
85
- # @private Transaction tag for statistics collection.
89
+ # Transaction tag for statistics collection.
90
+ # Example: `"update_user_profile"`.
91
+ # @private
92
+ # @return [::String, nil]
86
93
  attr_accessor :transaction_tag
87
94
 
88
- # @private Whether to exclude from change streams.
95
+ # Whether to exclude this transaction from change streams.
96
+ # @private
97
+ # @return [::Boolean]
89
98
  attr_accessor :exclude_txn_from_change_streams
90
99
 
91
- def initialize
100
+ # Creates a new `Spanner::Transaction` instance from a `V1::Transaction` object.
101
+ # @param grpc [::Google::Cloud::Spanner::V1::Transaction] Underlying `V1::Transaction` object.
102
+ # @param session [::Google::Cloud::Spanner::Session] The session this transaction is running in.
103
+ # @param exclude_txn_from_change_streams [::Boolean]
104
+ # When `exclude_txn_from_change_streams` is set to `true`, it prevents read
105
+ # or write transactions from being tracked in change streams.
106
+ # @private
107
+ # @return [::Google::Cloud::Spanner::Transaction]
108
+ def initialize grpc, session, exclude_txn_from_change_streams
109
+ @grpc = grpc
110
+ @session = session
111
+ @exclude_txn_from_change_streams = exclude_txn_from_change_streams
112
+
92
113
  @commit = Commit.new
93
114
  @seqno = 0
94
115
  @exclude_txn_from_change_streams = false
@@ -116,7 +137,7 @@ module Google
116
137
  # @return [String] The transaction id.
117
138
  def transaction_id
118
139
  return @grpc.id if existing_transaction?
119
- safe_begin_transaction
140
+ safe_begin_transaction!
120
141
  @grpc.id
121
142
  end
122
143
 
@@ -1153,15 +1174,16 @@ module Google
1153
1174
  @commit.mutations
1154
1175
  end
1155
1176
 
1156
- ##
1157
- # @private Creates a new Transaction instance from a
1158
- # `Google::Cloud::Spanner::V1::Transaction`.
1177
+ # Creates a new `Spanner::Transaction` instance from a `V1::Transaction` object.
1178
+ # @param grpc [::Google::Cloud::Spanner::V1::Transaction] Underlying `V1::Transaction` object.
1179
+ # @param session [::Google::Cloud::Spanner::Session] The session this transaction is running in.
1180
+ # @param exclude_txn_from_change_streams [::Boolean] Optional. Defaults to `false`.
1181
+ # When `exclude_txn_from_change_streams` is set to `true`, it prevents read
1182
+ # or write transactions from being tracked in change streams.
1183
+ # @private
1184
+ # @return [::Google::Cloud::Spanner::Transaction]
1159
1185
  def self.from_grpc grpc, session, exclude_txn_from_change_streams: false
1160
- new.tap do |s|
1161
- s.instance_variable_set :@grpc, grpc
1162
- s.instance_variable_set :@session, session
1163
- s.exclude_txn_from_change_streams = exclude_txn_from_change_streams
1164
- end
1186
+ new grpc, session, exclude_txn_from_change_streams
1165
1187
  end
1166
1188
 
1167
1189
  ##
@@ -1176,6 +1198,33 @@ module Google
1176
1198
  @grpc.nil?
1177
1199
  end
1178
1200
 
1201
+ # Begins a new transaction in a thread-safe manner if one does not already exist.
1202
+ #
1203
+ # @param exclude_from_change_streams [::Boolean] Optional. Defaults to `false`.
1204
+ # When `exclude_from_change_streams` is set to `true`, it prevents read
1205
+ # or write transactions from being tracked in change streams.
1206
+ # @param request_options [::Hash, nil] Optional. Common request options.
1207
+ # Example option: `:priority`.
1208
+ # @param call_options [::Hash, nil] Optional. A hash of values to specify the custom
1209
+ # call options. Example option `:timeout`.
1210
+ # @private
1211
+ # @return [::Google::Cloud::Spanner::V1::Transaction, nil] The new transaction
1212
+ # object, or `nil` if a transaction already exists.
1213
+ def safe_begin_transaction! exclude_from_change_streams: false, request_options: nil, call_options: nil
1214
+ @mutex.synchronize do
1215
+ return if existing_transaction?
1216
+ ensure_session!
1217
+ route_to_leader = LARHeaders.begin_transaction true
1218
+ @grpc = service.begin_transaction(
1219
+ session.path,
1220
+ exclude_txn_from_change_streams: exclude_from_change_streams,
1221
+ request_options: request_options,
1222
+ call_options: call_options,
1223
+ route_to_leader: route_to_leader
1224
+ )
1225
+ end
1226
+ end
1227
+
1179
1228
  protected
1180
1229
 
1181
1230
  ##
@@ -1203,24 +1252,18 @@ module Google
1203
1252
  end
1204
1253
  end
1205
1254
 
1206
- ##
1207
- # Create a new transaction in a thread-safe manner.
1208
- def safe_begin_transaction
1209
- @mutex.synchronize do
1210
- return if existing_transaction?
1211
- ensure_session!
1212
- route_to_leader = LARHeaders.begin_transaction true
1213
- @grpc = service.begin_transaction session.path, route_to_leader: route_to_leader
1214
- end
1215
- end
1216
-
1217
- ##
1218
- # @private The TransactionSelector to be used for queries. This method must
1219
- # be called from within a synchronized block, since the value returned
1220
- # depends on the state of @grpc field.
1255
+ # The TransactionSelector to be used for queries. This method must
1256
+ # be called from within a synchronized block, since the value returned
1257
+ # depends on the state of @grpc field.
1221
1258
  #
1222
- # This method is expected to be called from within `safe_execute()` method's block,
1223
- # since it provides synchronization and gurantees thread safety.
1259
+ # This method is expected to be called from within `safe_execute()` method's block,
1260
+ # since it provides synchronization and gurantees thread safety.
1261
+ #
1262
+ # @param exclude_txn_from_change_streams [::Boolean] Optional. Defaults to `false`.
1263
+ # When `exclude_txn_from_change_streams` is set to `true`, it prevents read
1264
+ # or write transactions from being tracked in change streams.
1265
+ # @private
1266
+ # @return [::Google::Cloud::Spanner::V1::TransactionSelector]
1224
1267
  def tx_selector exclude_txn_from_change_streams: false
1225
1268
  return V1::TransactionSelector.new id: transaction_id if existing_transaction?
1226
1269
  V1::TransactionSelector.new(
@@ -1261,6 +1304,9 @@ module Google
1261
1304
  raise "Must have active connection to service" unless session
1262
1305
  end
1263
1306
 
1307
+ # The `Spanner::Service` object used by this transaction.
1308
+ # @private
1309
+ # @return [::Google::Cloud::Spanner::Service]
1264
1310
  def service
1265
1311
  session.service
1266
1312
  end
@@ -16,7 +16,7 @@
16
16
  module Google
17
17
  module Cloud
18
18
  module Spanner
19
- VERSION = "2.27.0".freeze
19
+ VERSION = "2.28.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-spanner
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.27.0
4
+ version: 2.28.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Mike Moore