google-cloud-spanner 2.29.0 → 2.31.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.
@@ -44,8 +44,8 @@ module Google
44
44
  #
45
45
  class Session
46
46
  # The wrapped `V1::Session` protobuf session object.
47
- # @return [::Google::Cloud::Spanner::V1::Session]
48
47
  # @private
48
+ # @return [::Google::Cloud::Spanner::V1::Session]
49
49
  attr_accessor :grpc
50
50
 
51
51
  # The `Spanner::Service` object.
@@ -59,7 +59,7 @@ module Google
59
59
  # @return [::Hash, nil]
60
60
  attr_accessor :query_options
61
61
 
62
- # Creates a new Session instance.
62
+ # Creates a new `Spanner::Session` instance.
63
63
  # @param grpc [::Google::Cloud::Spanner::V1::Session] Underlying `V1::Session` object.
64
64
  # @param service [::Google::Cloud::Spanner::Service] A `Spanner::Service` object.
65
65
  # @param query_options [::Hash, nil] Optional. A hash of values to specify the custom
@@ -69,6 +69,7 @@ module Google
69
69
  @grpc = grpc
70
70
  @service = service
71
71
  @query_options = query_options
72
+ @created_time = Process.clock_gettime Process::CLOCK_MONOTONIC
72
73
  end
73
74
 
74
75
  # The unique identifier for the project.
@@ -216,6 +217,9 @@ module Google
216
217
  # * `:retry_codes` (`Array<String>`) - The error codes that should
217
218
  # trigger a retry.
218
219
  #
220
+ # @param precommit_token_notify [::Proc, nil] Optional.
221
+ # The notification function for the precommit token.
222
+ #
219
223
  # @return [Google::Cloud::Spanner::Results] The results of the query
220
224
  # execution.
221
225
  #
@@ -357,7 +361,8 @@ module Google
357
361
  def execute_query sql, params: nil, types: nil, transaction: nil,
358
362
  partition_token: nil, seqno: nil, query_options: nil,
359
363
  request_options: nil, call_options: nil, data_boost_enabled: nil,
360
- directed_read_options: nil, route_to_leader: nil
364
+ directed_read_options: nil, route_to_leader: nil,
365
+ precommit_token_notify: nil
361
366
  ensure_service!
362
367
  query_options = merge_if_present query_options, @query_options
363
368
 
@@ -373,7 +378,8 @@ module Google
373
378
 
374
379
  response = service.execute_streaming_sql path, sql, **execute_query_options
375
380
 
376
- results = Results.from_execute_query_response response, service, path, sql, execute_query_options
381
+ results = Results.from_execute_query_response response, service, path, sql, execute_query_options,
382
+ precommit_token_notify: precommit_token_notify
377
383
  @last_updated_at = Process.clock_gettime Process::CLOCK_MONOTONIC
378
384
  results
379
385
  end
@@ -428,8 +434,8 @@ module Google
428
434
  # number of rows that were modified for each successful statement
429
435
  # before the error.
430
436
  #
431
- # @return [Array<Integer>] A list with the exact number of rows that
432
- # were modified for each DML statement.
437
+ # @return [::Google::Cloud::Spanner::V1::ExecuteBatchDmlResponse]
438
+ # An unwrapped result of the service call -- a `V1::ExecuteBatchDmlResponse` object.
433
439
  #
434
440
  def batch_update transaction, seqno, request_options: nil,
435
441
  call_options: nil
@@ -506,6 +512,9 @@ module Google
506
512
  # To see the available options refer to
507
513
  # ['Google::Cloud::Spanner::V1::ReadRequest::LockHint'](https://cloud.google.com/ruby/docs/reference/google-cloud-spanner-v1/latest/Google-Cloud-Spanner-V1-ReadRequest-LockHint)
508
514
  #
515
+ # @param precommit_token_notify [::Proc, nil] Optional.
516
+ # The notification function for the precommit token.
517
+ #
509
518
  # @return [Google::Cloud::Spanner::Results] The results of the read
510
519
  # operation.
511
520
  #
@@ -525,7 +534,7 @@ module Google
525
534
  def read table, columns, keys: nil, index: nil, limit: nil,
526
535
  transaction: nil, partition_token: nil, request_options: nil,
527
536
  call_options: nil, data_boost_enabled: nil, directed_read_options: nil,
528
- route_to_leader: nil, order_by: nil, lock_hint: nil
537
+ route_to_leader: nil, order_by: nil, lock_hint: nil, precommit_token_notify: nil
529
538
  ensure_service!
530
539
 
531
540
  read_options = {
@@ -544,7 +553,8 @@ module Google
544
553
  response = service.streaming_read_table \
545
554
  path, table, columns, **read_options
546
555
 
547
- results = Results.from_read_response response, service, path, table, columns, read_options
556
+ results = Results.from_read_response response, service, path, table, columns, read_options,
557
+ precommit_token_notify: precommit_token_notify
548
558
 
549
559
  @last_updated_at = Process.clock_gettime Process::CLOCK_MONOTONIC
550
560
 
@@ -593,6 +603,8 @@ module Google
593
603
  # @param [Boolean] exclude_txn_from_change_streams If set to true,
594
604
  # mutations will not be recorded in change streams with DDL option
595
605
  # `allow_txn_exclusion=true`. Used if starting a new transaction.
606
+ # @param [Google::Cloud::Spanner::V1::TransactionOptions::IsolationLevel] isolation_level Optional. The
607
+ # isolation level for the transaction.
596
608
  # @param [Hash] commit_options A hash of commit options.
597
609
  # e.g., return_commit_stats. Commit options are optional.
598
610
  # The following options can be provided:
@@ -671,16 +683,30 @@ module Google
671
683
  # puts commit_resp.stats.mutation_count
672
684
  #
673
685
  def commit transaction_id: nil, exclude_txn_from_change_streams: false,
674
- commit_options: nil, request_options: nil, call_options: nil
686
+ isolation_level: nil, commit_options: nil, request_options: nil,
687
+ call_options: nil
675
688
  ensure_service!
676
689
  commit = Commit.new
677
690
  yield commit
678
- commit_resp = service.commit path, commit.mutations,
679
- transaction_id: transaction_id,
680
- exclude_txn_from_change_streams: exclude_txn_from_change_streams,
681
- commit_options: commit_options,
682
- request_options: request_options,
683
- call_options: call_options
691
+
692
+ should_retry = true
693
+ # @type [Google::Cloud::Spanner::V1::MultiplexedSessionPrecommitToken]
694
+ precommit_token = nil
695
+ while should_retry
696
+ commit_resp = service.commit(path,
697
+ commit.mutations,
698
+ transaction_id: transaction_id,
699
+ exclude_txn_from_change_streams: exclude_txn_from_change_streams,
700
+ isolation_level: isolation_level,
701
+ commit_options: commit_options,
702
+ request_options: request_options,
703
+ call_options: call_options,
704
+ precommit_token: precommit_token)
705
+
706
+ precommit_token = commit_resp.precommit_token
707
+ should_retry = !precommit_token.nil?
708
+ end
709
+
684
710
  @last_updated_at = Process.clock_gettime Process::CLOCK_MONOTONIC
685
711
  resp = CommitResponse.from_grpc commit_resp
686
712
  commit_options ? resp : resp.timestamp
@@ -818,6 +844,8 @@ module Google
818
844
  # @param [Boolean] exclude_txn_from_change_streams If set to true,
819
845
  # mutations will not be recorded in change streams with DDL option
820
846
  # `allow_txn_exclusion=true`. Used if starting a new transaction.
847
+ # @param [Google::Cloud::Spanner::V1::TransactionOptions::IsolationLevel] isolation_level Optional. The
848
+ # isolation level for the transaction.
821
849
  # @param [Hash] commit_options A hash of commit options.
822
850
  # e.g., return_commit_stats. Commit options are optional.
823
851
  # The following options can be provided:
@@ -890,10 +918,12 @@ module Google
890
918
  #
891
919
  def upsert table, *rows,
892
920
  transaction_id: nil, exclude_txn_from_change_streams: false,
893
- commit_options: nil, request_options: nil, call_options: nil
921
+ isolation_level: nil, commit_options: nil, request_options: nil,
922
+ call_options: nil
894
923
  opts = {
895
924
  transaction_id: transaction_id,
896
925
  exclude_txn_from_change_streams: exclude_txn_from_change_streams,
926
+ isolation_level: isolation_level,
897
927
  commit_options: commit_options,
898
928
  request_options: request_options,
899
929
  call_options: call_options
@@ -938,6 +968,8 @@ module Google
938
968
  # @param [Boolean] exclude_txn_from_change_streams If set to true,
939
969
  # mutations will not be recorded in change streams with DDL option
940
970
  # `allow_txn_exclusion=true`. Used if starting a new transaction.
971
+ # @param [Google::Cloud::Spanner::V1::TransactionOptions::IsolationLevel] isolation_level Optional. The
972
+ # isolation level for the transaction.
941
973
  # @param [Hash] commit_options A hash of commit options.
942
974
  # e.g., return_commit_stats. Commit options are optional.
943
975
  # The following options can be provided:
@@ -1010,10 +1042,12 @@ module Google
1010
1042
  #
1011
1043
  def insert table, *rows,
1012
1044
  transaction_id: nil, exclude_txn_from_change_streams: false,
1013
- commit_options: nil, request_options: nil, call_options: nil
1045
+ isolation_level: nil, commit_options: nil, request_options: nil,
1046
+ call_options: nil
1014
1047
  opts = {
1015
1048
  transaction_id: transaction_id,
1016
1049
  exclude_txn_from_change_streams: exclude_txn_from_change_streams,
1050
+ isolation_level: isolation_level,
1017
1051
  commit_options: commit_options,
1018
1052
  request_options: request_options,
1019
1053
  call_options: call_options
@@ -1057,6 +1091,8 @@ module Google
1057
1091
  # @param [Boolean] exclude_txn_from_change_streams If set to true,
1058
1092
  # mutations will not be recorded in change streams with DDL option
1059
1093
  # `allow_txn_exclusion=true`. Used if starting a new transaction.
1094
+ # @param [Google::Cloud::Spanner::V1::TransactionOptions::IsolationLevel] isolation_level Optional. The
1095
+ # isolation level for the transaction.
1060
1096
  # @param [Hash] commit_options A hash of commit options.
1061
1097
  # e.g., return_commit_stats. Commit options are optional.
1062
1098
  # The following options can be provided:
@@ -1129,10 +1165,12 @@ module Google
1129
1165
  #
1130
1166
  def update table, *rows,
1131
1167
  transaction_id: nil, exclude_txn_from_change_streams: false,
1132
- commit_options: nil, request_options: nil, call_options: nil
1168
+ isolation_level: nil, commit_options: nil, request_options: nil,
1169
+ call_options: nil
1133
1170
  opts = {
1134
1171
  transaction_id: transaction_id,
1135
1172
  exclude_txn_from_change_streams: exclude_txn_from_change_streams,
1173
+ isolation_level: isolation_level,
1136
1174
  commit_options: commit_options,
1137
1175
  request_options: request_options,
1138
1176
  call_options: call_options
@@ -1178,6 +1216,8 @@ module Google
1178
1216
  # @param [Boolean] exclude_txn_from_change_streams If set to true,
1179
1217
  # mutations will not be recorded in change streams with DDL option
1180
1218
  # `allow_txn_exclusion=true`. Used if starting a new transaction.
1219
+ # @param [Google::Cloud::Spanner::V1::TransactionOptions::IsolationLevel] isolation_level Optional. The
1220
+ # isolation level for the transaction.
1181
1221
  # @param [Hash] commit_options A hash of commit options.
1182
1222
  # e.g., return_commit_stats. Commit options are optional.
1183
1223
  # The following options can be provided:
@@ -1251,10 +1291,11 @@ module Google
1251
1291
  #
1252
1292
  def replace table, *rows,
1253
1293
  transaction_id: nil, exclude_txn_from_change_streams: false,
1254
- commit_options: nil, request_options: nil, call_options: nil
1294
+ isolation_level: nil, commit_options: nil, request_options: nil, call_options: nil
1255
1295
  opts = {
1256
1296
  transaction_id: transaction_id,
1257
1297
  exclude_txn_from_change_streams: exclude_txn_from_change_streams,
1298
+ isolation_level: isolation_level,
1258
1299
  commit_options: commit_options,
1259
1300
  request_options: request_options,
1260
1301
  call_options: call_options
@@ -1279,6 +1320,8 @@ module Google
1279
1320
  # @param [Boolean] exclude_txn_from_change_streams If set to true,
1280
1321
  # mutations will not be recorded in change streams with DDL option
1281
1322
  # `allow_txn_exclusion=true`. Used if starting a new transaction.
1323
+ # @param [Google::Cloud::Spanner::V1::TransactionOptions::IsolationLevel] isolation_level Optional. The
1324
+ # isolation level for the transaction.
1282
1325
  # @param [Hash] commit_options A hash of commit options.
1283
1326
  # e.g., return_commit_stats. Commit options are optional.
1284
1327
  # The following options can be provided:
@@ -1348,10 +1391,12 @@ module Google
1348
1391
  #
1349
1392
  def delete table, keys = [],
1350
1393
  transaction_id: nil, exclude_txn_from_change_streams: false,
1351
- commit_options: nil, request_options: nil, call_options: nil
1394
+ isolation_level: nil, commit_options: nil, request_options: nil,
1395
+ call_options: nil
1352
1396
  opts = {
1353
1397
  transaction_id: transaction_id,
1354
1398
  exclude_txn_from_change_streams: exclude_txn_from_change_streams,
1399
+ isolation_level: isolation_level,
1355
1400
  commit_options: commit_options,
1356
1401
  request_options: request_options,
1357
1402
  call_options: call_options
@@ -1369,9 +1414,15 @@ module Google
1369
1414
  true
1370
1415
  end
1371
1416
 
1372
- ##
1417
+ # Explicitly begins a new transaction and creates a server-side transaction object.
1418
+ # Unlike {#create_empty_transaction}, this method makes an immediate
1419
+ # `BeginTransaction` RPC call.
1420
+ #
1421
+ # @param exclude_txn_from_change_streams [::Boolean] Optional. Defaults to `false`.
1422
+ # When `exclude_txn_from_change_streams` is set to `true`, it prevents read
1423
+ # or write transactions from being tracked in change streams.
1373
1424
  # @private
1374
- # Creates a new transaction object every time.
1425
+ # @return [::Google::Cloud::Spanner::Transaction]
1375
1426
  def create_transaction exclude_txn_from_change_streams: false
1376
1427
  route_to_leader = LARHeaders.begin_transaction true
1377
1428
  tx_grpc = service.begin_transaction path,
@@ -1380,37 +1431,34 @@ module Google
1380
1431
  Transaction.from_grpc tx_grpc, self, exclude_txn_from_change_streams: exclude_txn_from_change_streams
1381
1432
  end
1382
1433
 
1383
- ##
1434
+ # Creates a new empty transaction wrapper without a server-side object.
1435
+ # This is used for inline-begin transactions and does not make an RPC call.
1436
+ # See {#create_transaction} for the RPC-based method.
1437
+ #
1438
+ # @param exclude_txn_from_change_streams [::Boolean] Optional. Defaults to `false`.
1439
+ # When `exclude_txn_from_change_streams` is set to `true`, it prevents read
1440
+ # or write transactions from being tracked in change streams.
1441
+ # @param previous_transaction_id [::String, nil] Optional.
1442
+ # An id of the previous transaction, if this new transaction wrapper is being created
1443
+ # as a part of a retry. Previous transaction id should be added to TransactionOptions
1444
+ # of a new ReadWrite transaction when retry is attempted.
1384
1445
  # @private
1385
- # Creates a new transaction object without the grpc object
1386
- # within it. Use it for inline-begin of a transaction.
1387
- def create_empty_transaction exclude_txn_from_change_streams: false
1388
- Transaction.from_grpc nil, self, exclude_txn_from_change_streams: exclude_txn_from_change_streams
1389
- end
1390
-
1391
- ##
1392
- # Reloads the session resource. Useful for determining if the session is
1393
- # still valid on the Spanner API.
1394
- def reload!
1395
- ensure_service!
1396
- @grpc = service.get_session path
1397
- @last_updated_at = Process.clock_gettime Process::CLOCK_MONOTONIC
1398
- self
1399
- rescue Google::Cloud::NotFoundError
1400
- labels = @grpc.labels.to_h unless @grpc.labels.to_h.empty?
1401
- @grpc = service.create_session \
1402
- V1::Spanner::Paths.database_path(
1403
- project: project_id, instance: instance_id, database: database_id
1404
- ),
1405
- labels: labels
1406
- @last_updated_at = Process.clock_gettime Process::CLOCK_MONOTONIC
1407
- self
1446
+ # @return [::Google::Cloud::Spanner::Transaction] The new *empty-wrapper* transaction object.
1447
+ def create_empty_transaction exclude_txn_from_change_streams: false, previous_transaction_id: nil
1448
+ Transaction.from_grpc nil, self, exclude_txn_from_change_streams: exclude_txn_from_change_streams,
1449
+ previous_transaction_id: previous_transaction_id
1408
1450
  end
1409
1451
 
1410
- ##
1452
+ # If the session is non-multiplexed, keeps the session alive by executing `"SELECT 1"`.
1453
+ # This method will re-create the session if necessary.
1454
+ # For multiplexed session the keepalive is not required and this method immediately returns `true`.
1411
1455
  # @private
1412
- # Keeps the session alive by executing `"SELECT 1"`.
1456
+ # @return [::Boolean]
1457
+ # `true` if the session is multiplexed or if the keepalive was successful for non-multiplexed session,
1458
+ # `false` if the non-multiplexed session was not found and the had to be recreated.
1413
1459
  def keepalive!
1460
+ return true if multiplexed?
1461
+
1414
1462
  ensure_service!
1415
1463
  route_to_leader = LARHeaders.execute_query false
1416
1464
  execute_query "SELECT 1", route_to_leader: route_to_leader
@@ -1425,15 +1473,19 @@ module Google
1425
1473
  false
1426
1474
  end
1427
1475
 
1428
- ##
1429
- # Permanently deletes the session.
1476
+ # Permanently deletes the session unless this session is multiplexed.
1477
+ # Multiplexed sessions can not be deleted, and this method immediately returns.
1478
+ # @private
1479
+ # @return [void]
1430
1480
  def release!
1481
+ return if multiplexed?
1431
1482
  ensure_service!
1432
1483
  service.delete_session path
1433
1484
  end
1434
1485
 
1435
1486
  # Determines if the session has been idle longer than the given
1436
- # duration.
1487
+ # duration in seconds.
1488
+ #
1437
1489
  # @param duration_sec [::Numeric] interval in seconds
1438
1490
  # @private
1439
1491
  # @return [::Boolean]
@@ -1442,7 +1494,17 @@ module Google
1442
1494
  Process.clock_gettime(Process::CLOCK_MONOTONIC) > @last_updated_at + duration_sec
1443
1495
  end
1444
1496
 
1445
- # Creates a new Session instance from a `V1::Session`.
1497
+ # Determines if the session did exist for at least the given
1498
+ # duration in seconds.
1499
+ #
1500
+ # @param duration_sec [::Numeric] interval in seconds
1501
+ # @private
1502
+ # @return [::Boolean]
1503
+ def existed_since? duration_sec
1504
+ Process.clock_gettime(Process::CLOCK_MONOTONIC) > @created_time + duration_sec
1505
+ end
1506
+
1507
+ # Creates a new `Spanner::Session` instance from a `V1::Session` object.
1446
1508
  # @param grpc [::Google::Cloud::Spanner::V1::Session] Underlying `V1::Session` object.
1447
1509
  # @param service [::Google::Cloud::Spanner::Service] A `Spanner::Service` ref.
1448
1510
  # @param query_options [::Hash, nil] Optional. A hash of values to specify the custom
@@ -1461,6 +1523,13 @@ module Google
1461
1523
 
1462
1524
  protected
1463
1525
 
1526
+ # Whether this session is multiplexed.
1527
+ # @private
1528
+ # @return [::Boolean]
1529
+ def multiplexed?
1530
+ @grpc.multiplexed
1531
+ end
1532
+
1464
1533
  ##
1465
1534
  # @private Raise an error unless an active connection to the service is
1466
1535
  # available.
@@ -0,0 +1,125 @@
1
+ # Copyright 2025 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 "concurrent"
16
+ require "google/cloud/spanner/session"
17
+ require "google/cloud/spanner/session_creation_options"
18
+
19
+ module Google
20
+ module Cloud
21
+ module Spanner
22
+ # Cache for the multiplex `{Google::Cloud::Spanner::Session}` instance.
23
+ # @private
24
+ class SessionCache
25
+ # Time in seconds before this SessionCache will refresh the session.
26
+ # Counted from the session creation time (not from last usage).
27
+ # This is specific to multiplex sessions.
28
+ # The backend can keep sessions alive for quite a bit longer (28 days) but
29
+ # we perform refresh after 7 days.
30
+ # @private
31
+ SESSION_REFRESH_SEC = 7 * 24 * 3600
32
+
33
+ # Create a single-session "cache" for multiplex sessions.
34
+ # @param service [::Google::Cloud::Spanner::Service] A `Spanner::Service` reference.
35
+ # @param session_creation_options [::Google::Cloud::Spanner::SessionCreationOptions] Required.
36
+ # @private
37
+ def initialize service, session_creation_options
38
+ @service = service
39
+ @session_creation_options = session_creation_options
40
+ @mutex = Mutex.new
41
+ @session = nil
42
+ end
43
+
44
+ # Yields the current session to run an operation (or a series of operations) on.
45
+ # @yield session A session to run requests on
46
+ # @yieldparam session [::Google::Cloud::Spanner::Session]
47
+ # @private
48
+ # @yieldreturn [::Object] The result of the operation that ran on a session.
49
+ # @return [::Object] The value returned by the yielded block.
50
+ def with_session
51
+ ensure_session!
52
+ yield @session
53
+ end
54
+
55
+ # Re-initializes the session in the session cache.
56
+ # @private
57
+ # @return [::Boolean]
58
+ def reset!
59
+ @mutex.synchronize do
60
+ @session = create_new_session
61
+ end
62
+
63
+ true
64
+ end
65
+
66
+ # Closes the pool. This is a NOP for Multiplex Session Cache since
67
+ # multiplex sessions don't require cleanup.
68
+ # @private
69
+ # @return [::Boolean]
70
+ def close
71
+ true
72
+ end
73
+
74
+ # Returns the current session. For use in the `{Spanner::BatchClient}`
75
+ # where usage pattern is incompatible with `with_session`.
76
+ # For other uses please use `with_session` instead.
77
+ # @private
78
+ # @return [::Google::Cloud::Spanner::Session]
79
+ def session
80
+ ensure_session!
81
+ @session
82
+ end
83
+
84
+ private
85
+
86
+ # Ensures that a single session exists and is current.
87
+ # @private
88
+ # @return [nil]
89
+ def ensure_session!
90
+ return unless @session.nil? || @session.existed_since?(SESSION_REFRESH_SEC)
91
+
92
+ @mutex.synchronize do
93
+ return unless @session.nil? || @session.existed_since?(SESSION_REFRESH_SEC)
94
+ @session = create_new_session
95
+ end
96
+
97
+ nil
98
+ end
99
+
100
+ # Creates a new multiplexed `Spanner::Session`.
101
+ # @private
102
+ # @return [::Google::Cloud::Spanner::Session]
103
+ def create_new_session
104
+ ensure_service!
105
+ grpc = @service.create_session(
106
+ @session_creation_options.database_path,
107
+ labels: @session_creation_options.session_labels,
108
+ database_role: @session_creation_options.session_creator_role,
109
+ multiplexed: true
110
+ )
111
+
112
+ Session.from_grpc grpc, @service, query_options: @session_creation_options.query_options
113
+ end
114
+
115
+ # Raise an error unless an active connection to the service is available.
116
+ # @private
117
+ # @raise [::StandardError]
118
+ # @return [void]
119
+ def ensure_service!
120
+ raise "Must have active connection to service" unless @service
121
+ end
122
+ end
123
+ end
124
+ end
125
+ end
@@ -0,0 +1,70 @@
1
+ # Copyright 2025 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
+ module Google
16
+ module Cloud
17
+ module Spanner
18
+ # Options for creating new sessions that clients use
19
+ # to parametrize Pool and SessionCache.
20
+ # Example: session labels.
21
+ # @private
22
+ class SessionCreationOptions
23
+ # The full path to the Spanner database. Values are of the form:
24
+ # `projects/<project_id>/instances/<instance_id>/databases/<database_id>.
25
+ # @private
26
+ # @return [::String]
27
+ attr_reader :database_path
28
+
29
+ # The labels to be applied to all sessions created by the client.
30
+ # Optional. Example: `"team" => "billing-service"`.
31
+ # @private
32
+ # @return [::Hash, nil]
33
+ attr_reader :session_labels
34
+
35
+ # The Spanner session creator role.
36
+ # Optional. Example: `analyst`.
37
+ # @return [::String, nil]
38
+ attr_reader :session_creator_role
39
+
40
+ # A hash of values to specify the custom query options for executing SQL query.
41
+ # Optional. Example option: `:optimizer_version`.
42
+ # @private
43
+ # @return [::Hash, nil]
44
+ attr_reader :query_options
45
+
46
+ # Creates a new SessionCreationOptions object.
47
+ # @param database_path [::String]
48
+ # The full path to the Spanner database. Values are of the form:
49
+ # `projects/<project_id>/instances/<instance_id>/databases/<database_id>.
50
+ # @param session_labels [::Hash, nil] Optional. The labels to be applied to all sessions
51
+ # created by the client. Example: `"team" => "billing-service"`.
52
+ # @param session_creator_role [::String, nil] Optional. The Spanner session creator role.
53
+ # Example: `analyst`.
54
+ # @param query_options [::Hash, nil] Optional. A hash of values to specify the custom
55
+ # query options for executing SQL query. Example option: `:optimizer_version`.
56
+ # @private
57
+ def initialize database_path:, session_labels: nil, session_creator_role: nil, query_options: nil
58
+ if database_path.nil? || database_path.empty?
59
+ raise ArgumentError, "database_path is required for session creation options"
60
+ end
61
+
62
+ @database_path = database_path
63
+ @session_labels = session_labels
64
+ @session_creator_role = session_creator_role
65
+ @query_options = query_options
66
+ end
67
+ end
68
+ end
69
+ end
70
+ end
@@ -41,9 +41,26 @@ module Google
41
41
  # end
42
42
  #
43
43
  class Snapshot
44
- # @private The Session object.
44
+ # A `V1::Session` reference.
45
+ # @private
46
+ # @return [::Google::Cloud::Spanner::V1::Session]
45
47
  attr_accessor :session
46
48
 
49
+ # Creates a new `Spanner::Snapshot` instance.
50
+ # @param grpc [::Google::Cloud::Spanner::V1::Transaction]
51
+ # Underlying `V1::Transaction` object.
52
+ # @param session [::Google::Cloud::Spanner::Session] A `Spanner::Session` reference.
53
+ # @param directed_read_options [::Hash, nil] Optional. Client options used to set
54
+ # the `directed_read_options` for all ReadRequests and ExecuteSqlRequests.
55
+ # Converts to `V1::DirectedReadOptions`. Example option: `:exclude_replicas`.
56
+ # @private
57
+ # @return [::Google::Cloud::Spanner::Snapshot]
58
+ def initialize grpc, session, directed_read_options: nil
59
+ @grpc = grpc
60
+ @session = session
61
+ @directed_read_options = directed_read_options
62
+ end
63
+
47
64
  ##
48
65
  # Identifier of the transaction results were run in.
49
66
  # @return [String] The transaction id.
@@ -536,15 +553,18 @@ module Google
536
553
  exclude_end: exclude_end
537
554
  end
538
555
 
539
- ##
540
- # @private Creates a new Snapshot instance from a
556
+ # Creates a new `Spanner::Snapshot` instance from a
541
557
  # `Google::Cloud::Spanner::V1::Transaction`.
542
- def self.from_grpc grpc, session, directed_read_options
543
- new.tap do |s|
544
- s.instance_variable_set :@grpc, grpc
545
- s.instance_variable_set :@session, session
546
- s.instance_variable_set :@directed_read_options, directed_read_options
547
- end
558
+ # @param grpc [::Google::Cloud::Spanner::V1::Transaction]
559
+ # Underlying `V1::Transaction` object.
560
+ # @param session [::Google::Cloud::Spanner::Session] A `Spanner::Session` reference.
561
+ # @param directed_read_options [::Hash, nil] Optional. Client options used to set
562
+ # the `directed_read_options` for all ReadRequests and ExecuteSqlRequests.
563
+ # Converts to `V1::DirectedReadOptions`. Example option: `:exclude_replicas`.
564
+ # @private
565
+ # @return [::Google::Cloud::Spanner::Snapshot]
566
+ def self.from_grpc grpc, session, directed_read_options: nil
567
+ new grpc, session, directed_read_options: directed_read_options
548
568
  end
549
569
 
550
570
  protected