google-cloud-spanner 0.21.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (68) hide show
  1. checksums.yaml +7 -0
  2. data/lib/google-cloud-spanner.rb +106 -0
  3. data/lib/google/cloud/spanner.rb +382 -0
  4. data/lib/google/cloud/spanner/admin/database/v1.rb +17 -0
  5. data/lib/google/cloud/spanner/admin/database/v1/database_admin_client.rb +703 -0
  6. data/lib/google/cloud/spanner/admin/database/v1/database_admin_client_config.json +73 -0
  7. data/lib/google/cloud/spanner/admin/database/v1/doc/google/iam/v1/policy.rb +139 -0
  8. data/lib/google/cloud/spanner/admin/database/v1/doc/google/protobuf/any.rb +114 -0
  9. data/lib/google/cloud/spanner/admin/database/v1/doc/google/rpc/status.rb +83 -0
  10. data/lib/google/cloud/spanner/admin/database/v1/doc/google/spanner/admin/database/v1/spanner_database_admin.rb +188 -0
  11. data/lib/google/cloud/spanner/admin/instance/v1.rb +17 -0
  12. data/lib/google/cloud/spanner/admin/instance/v1/doc/google/iam/v1/policy.rb +139 -0
  13. data/lib/google/cloud/spanner/admin/instance/v1/doc/google/protobuf/any.rb +114 -0
  14. data/lib/google/cloud/spanner/admin/instance/v1/doc/google/protobuf/field_mask.rb +223 -0
  15. data/lib/google/cloud/spanner/admin/instance/v1/doc/google/rpc/status.rb +83 -0
  16. data/lib/google/cloud/spanner/admin/instance/v1/doc/google/spanner/admin/instance/v1/spanner_instance_admin.rb +268 -0
  17. data/lib/google/cloud/spanner/admin/instance/v1/instance_admin_client.rb +868 -0
  18. data/lib/google/cloud/spanner/admin/instance/v1/instance_admin_client_config.json +78 -0
  19. data/lib/google/cloud/spanner/client.rb +1034 -0
  20. data/lib/google/cloud/spanner/commit.rb +351 -0
  21. data/lib/google/cloud/spanner/convert.rb +311 -0
  22. data/lib/google/cloud/spanner/credentials.rb +32 -0
  23. data/lib/google/cloud/spanner/data.rb +199 -0
  24. data/lib/google/cloud/spanner/database.rb +377 -0
  25. data/lib/google/cloud/spanner/database/job.rb +179 -0
  26. data/lib/google/cloud/spanner/database/list.rb +171 -0
  27. data/lib/google/cloud/spanner/errors.rb +73 -0
  28. data/lib/google/cloud/spanner/fields.rb +252 -0
  29. data/lib/google/cloud/spanner/instance.rb +472 -0
  30. data/lib/google/cloud/spanner/instance/config.rb +99 -0
  31. data/lib/google/cloud/spanner/instance/config/list.rb +171 -0
  32. data/lib/google/cloud/spanner/instance/job.rb +197 -0
  33. data/lib/google/cloud/spanner/instance/list.rb +167 -0
  34. data/lib/google/cloud/spanner/policy.rb +201 -0
  35. data/lib/google/cloud/spanner/pool.rb +279 -0
  36. data/lib/google/cloud/spanner/project.rb +480 -0
  37. data/lib/google/cloud/spanner/range.rb +99 -0
  38. data/lib/google/cloud/spanner/results.rb +280 -0
  39. data/lib/google/cloud/spanner/service.rb +458 -0
  40. data/lib/google/cloud/spanner/session.rb +565 -0
  41. data/lib/google/cloud/spanner/snapshot.rb +260 -0
  42. data/lib/google/cloud/spanner/transaction.rb +533 -0
  43. data/lib/google/cloud/spanner/v1.rb +17 -0
  44. data/lib/google/cloud/spanner/v1/doc/google/protobuf/duration.rb +77 -0
  45. data/lib/google/cloud/spanner/v1/doc/google/protobuf/struct.rb +73 -0
  46. data/lib/google/cloud/spanner/v1/doc/google/protobuf/timestamp.rb +81 -0
  47. data/lib/google/cloud/spanner/v1/doc/google/spanner/v1/keys.rb +148 -0
  48. data/lib/google/cloud/spanner/v1/doc/google/spanner/v1/mutation.rb +80 -0
  49. data/lib/google/cloud/spanner/v1/doc/google/spanner/v1/query_plan.rb +120 -0
  50. data/lib/google/cloud/spanner/v1/doc/google/spanner/v1/result_set.rb +175 -0
  51. data/lib/google/cloud/spanner/v1/doc/google/spanner/v1/spanner.rb +206 -0
  52. data/lib/google/cloud/spanner/v1/doc/google/spanner/v1/transaction.rb +351 -0
  53. data/lib/google/cloud/spanner/v1/spanner_client.rb +850 -0
  54. data/lib/google/cloud/spanner/v1/spanner_client_config.json +78 -0
  55. data/lib/google/cloud/spanner/version.rb +22 -0
  56. data/lib/google/spanner/admin/database/v1/spanner_database_admin_pb.rb +85 -0
  57. data/lib/google/spanner/admin/database/v1/spanner_database_admin_services_pb.rb +95 -0
  58. data/lib/google/spanner/admin/instance/v1/spanner_instance_admin_pb.rb +106 -0
  59. data/lib/google/spanner/admin/instance/v1/spanner_instance_admin_services_pb.rb +180 -0
  60. data/lib/google/spanner/v1/keys_pb.rb +33 -0
  61. data/lib/google/spanner/v1/mutation_pb.rb +38 -0
  62. data/lib/google/spanner/v1/query_plan_pb.rb +47 -0
  63. data/lib/google/spanner/v1/result_set_pb.rb +43 -0
  64. data/lib/google/spanner/v1/spanner_pb.rb +90 -0
  65. data/lib/google/spanner/v1/spanner_services_pb.rb +131 -0
  66. data/lib/google/spanner/v1/transaction_pb.rb +51 -0
  67. data/lib/google/spanner/v1/type_pb.rb +43 -0
  68. metadata +309 -0
@@ -0,0 +1,565 @@
1
+ # Copyright 2016 Google Inc. All rights reserved.
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
+ # http://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
+
16
+ require "google/cloud/spanner/data"
17
+ require "google/cloud/spanner/results"
18
+ require "google/cloud/spanner/commit"
19
+
20
+ module Google
21
+ module Cloud
22
+ module Spanner
23
+ ##
24
+ # @private
25
+ #
26
+ # # Session
27
+ #
28
+ # A session can be used to perform transactions that read and/or modify
29
+ # data in a Cloud Spanner database. Sessions are meant to be reused for
30
+ # many consecutive transactions.
31
+ #
32
+ # Sessions can only execute one transaction at a time. To execute multiple
33
+ # concurrent read-write/write-only transactions, create multiple sessions.
34
+ # Note that standalone reads and queries use a transaction internally, and
35
+ # count toward the one transaction limit.
36
+ #
37
+ # Cloud Spanner limits the number of sessions that can exist at any given
38
+ # time; thus, it is a good idea to delete idle and/or unneeded sessions.
39
+ # Aside from explicit deletes, Cloud Spanner can delete sessions for which
40
+ # no operations are sent for more than an hour.
41
+ #
42
+ class Session
43
+ ##
44
+ # @private The Google::Spanner::V1::Session object
45
+ attr_accessor :grpc
46
+
47
+ ##
48
+ # @private The gRPC Service object.
49
+ attr_accessor :service
50
+
51
+ # @private Creates a new Session instance.
52
+ def initialize grpc, service
53
+ @grpc = grpc
54
+ @service = service
55
+ end
56
+
57
+ # The unique identifier for the project.
58
+ # @return [String]
59
+ def project_id
60
+ V1::SpannerClient.match_project_from_session_name @grpc.name
61
+ end
62
+
63
+ # The unique identifier for the instance.
64
+ # @return [String]
65
+ def instance_id
66
+ V1::SpannerClient.match_instance_from_session_name @grpc.name
67
+ end
68
+
69
+ # The unique identifier for the database.
70
+ # @return [String]
71
+ def database_id
72
+ V1::SpannerClient.match_database_from_session_name @grpc.name
73
+ end
74
+
75
+ # The unique identifier for the session.
76
+ # @return [String]
77
+ def session_id
78
+ V1::SpannerClient.match_session_from_session_name @grpc.name
79
+ end
80
+
81
+ # rubocop:disable LineLength
82
+
83
+ ##
84
+ # The full path for the session resource. Values are of the form
85
+ # `projects/<project_id>/instances/<instance_id>/databases/<database_id>/sessions/<session_id>`.
86
+ # @return [String]
87
+ def path
88
+ @grpc.name
89
+ end
90
+
91
+ # rubocop:enable LineLength
92
+
93
+ ##
94
+ # Executes a SQL query.
95
+ #
96
+ # Arguments can be passed using `params`, Ruby types are mapped to
97
+ # Spanner types as follows:
98
+ #
99
+ # | Spanner | Ruby | Notes |
100
+ # |-------------|----------------|---|
101
+ # | `BOOL` | `true`/`false` | |
102
+ # | `INT64` | `Integer` | |
103
+ # | `FLOAT64` | `Float` | |
104
+ # | `STRING` | `String` | |
105
+ # | `DATE` | `Date` | |
106
+ # | `TIMESTAMP` | `Time`, `DateTime` | |
107
+ # | `BYTES` | `File`, `IO`, `StringIO`, or similar | |
108
+ # | `ARRAY` | `Array` | Nested arrays are not supported. |
109
+ #
110
+ # See [Data
111
+ # types](https://cloud.google.com/spanner/docs/data-definition-language#data_types).
112
+ #
113
+ # @param [String] sql The SQL query string. See [Query
114
+ # syntax](https://cloud.google.com/spanner/docs/query-syntax).
115
+ #
116
+ # The SQL query string can contain parameter placeholders. A parameter
117
+ # placeholder consists of "@" followed by the parameter name.
118
+ # Parameter names consist of any combination of letters, numbers, and
119
+ # underscores.
120
+ # @param [Hash] params SQL parameters for the query string. The
121
+ # parameter placeholders, minus the "@", are the the hash keys, and
122
+ # the literal values are the hash values. If the query string contains
123
+ # something like "WHERE id > @msg_id", then the params must contain
124
+ # something like `:msg_id => 1`.
125
+ # @param [Hash] types Types of the SQL parameters in `params`. It is not
126
+ # always possible for Cloud Spanner to infer the right SQL type from a
127
+ # value in `params`. In these cases, the `types` hash can be used to
128
+ # specify the exact SQL type for some or all of the SQL query
129
+ # parameters.
130
+ #
131
+ # The keys of the hash should be query string parameter placeholders,
132
+ # minus the "@". The values of the hash should be Cloud Spanner type
133
+ # codes from the following list:
134
+ #
135
+ # * `:BOOL`
136
+ # * `:BYTES`
137
+ # * `:DATE`
138
+ # * `:FLOAT64`
139
+ # * `:INT64`
140
+ # * `:STRING`
141
+ # * `:TIMESTAMP`
142
+ #
143
+ # Arrays are specified by providing the type code in an array. For
144
+ # example, an array of integers are specified as `[:INT64]`.
145
+ #
146
+ # Structs are not yet supported in query parameters.
147
+ #
148
+ # Types are optional.
149
+ # @param [Google::Spanner::V1::TransactionSelector] transaction The
150
+ # transaction selector value to send. Only used for single-use
151
+ # transactions.
152
+ #
153
+ # @return [Google::Cloud::Spanner::Results] The results of the query
154
+ # execution.
155
+ #
156
+ # @example
157
+ # require "google/cloud/spanner"
158
+ #
159
+ # spanner = Google::Cloud::Spanner.new
160
+ #
161
+ # db = spanner.client "my-instance", "my-database"
162
+ #
163
+ # results = db.execute "SELECT * FROM users"
164
+ #
165
+ # results.rows.each do |row|
166
+ # puts "User #{row[:id]} is #{row[:name]}"
167
+ # end
168
+ #
169
+ # @example Query using query parameters:
170
+ # require "google/cloud/spanner"
171
+ #
172
+ # spanner = Google::Cloud::Spanner.new
173
+ #
174
+ # db = spanner.client "my-instance", "my-database"
175
+ #
176
+ # results = db.execute "SELECT * FROM users WHERE active = @active",
177
+ # params: { active: true }
178
+ #
179
+ # results.rows.each do |row|
180
+ # puts "User #{row[:id]} is #{row[:name]}"
181
+ # end
182
+ #
183
+ def execute sql, params: nil, types: nil, transaction: nil
184
+ ensure_service!
185
+ results = Results.execute service, path, sql,
186
+ params: params, types: types,
187
+ transaction: transaction
188
+ @last_updated_at = Time.now
189
+ results
190
+ end
191
+ alias_method :query, :execute
192
+
193
+ ##
194
+ # Read rows from a database table, as a simple alternative to
195
+ # {#execute}.
196
+ #
197
+ # @param [String] table The name of the table in the database to be
198
+ # read.
199
+ # @param [Array<String, Symbol>] columns The columns of table to be
200
+ # returned for each row matching this request.
201
+ # @param [Object, Array<Object>] keys A single, or list of keys or key
202
+ # ranges to match returned data to. Values should have exactly as many
203
+ # elements as there are columns in the primary key.
204
+ # @param [String] index The name of an index to use instead of the
205
+ # table's primary key when interpreting `id` and sorting result rows.
206
+ # Optional.
207
+ # @param [Integer] limit If greater than zero, no more than this number
208
+ # of rows will be returned. The default is no limit.
209
+ # @param [Google::Spanner::V1::TransactionSelector] transaction The
210
+ # transaction selector value to send. Only used for single-use
211
+ # transactions.
212
+ #
213
+ # @return [Google::Cloud::Spanner::Results] The results of the read
214
+ # operation.
215
+ #
216
+ # @example
217
+ # require "google/cloud/spanner"
218
+ #
219
+ # spanner = Google::Cloud::Spanner.new
220
+ #
221
+ # db = spanner.client "my-instance", "my-database"
222
+ #
223
+ # results = db.read "users", [:id, :name]
224
+ #
225
+ # results.rows.each do |row|
226
+ # puts "User #{row[:id]} is #{row[:name]}"
227
+ # end
228
+ #
229
+ def read table, columns, keys: nil, index: nil, limit: nil,
230
+ transaction: nil
231
+ ensure_service!
232
+ results = Results.read service, path, table, columns,
233
+ keys: keys, index: index, limit: limit,
234
+ transaction: transaction
235
+ @last_updated_at = Time.now
236
+ results
237
+ end
238
+
239
+ ##
240
+ # Creates changes to be applied to rows in the database.
241
+ #
242
+ # @param [String] transaction_id The identifier of previously-started
243
+ # transaction to be used instead of starting a new transaction.
244
+ # Optional.
245
+ # @yield [commit] The block for mutating the data.
246
+ # @yieldparam [Google::Cloud::Spanner::Commit] commit The Commit object.
247
+ #
248
+ # @return [Time] The timestamp at which the operation committed.
249
+ #
250
+ # @example
251
+ # require "google/cloud/spanner"
252
+ #
253
+ # spanner = Google::Cloud::Spanner.new
254
+ #
255
+ # db = spanner.client "my-instance", "my-database"
256
+ #
257
+ # db.commit do |c|
258
+ # c.update "users", [{ id: 1, name: "Charlie", active: false }]
259
+ # c.insert "users", [{ id: 2, name: "Harvey", active: true }]
260
+ # end
261
+ #
262
+ def commit transaction_id: nil
263
+ ensure_service!
264
+ commit = Commit.new
265
+ yield commit
266
+ commit_resp = service.commit path, commit.mutations,
267
+ transaction_id: transaction_id
268
+ @last_updated_at = Time.now
269
+ Convert.timestamp_to_time commit_resp.commit_timestamp
270
+ end
271
+
272
+ ##
273
+ # Inserts or updates rows in a table. If any of the rows already exist,
274
+ # then its column values are overwritten with the ones provided. Any
275
+ # column values not explicitly written are preserved.
276
+ #
277
+ # @param [String] table The name of the table in the database to be
278
+ # modified.
279
+ # @param [Array<Hash>] rows One or more hash objects with the hash keys
280
+ # matching the table's columns, and the hash values matching the
281
+ # table's values.
282
+ #
283
+ # Ruby types are mapped to Spanner types as follows:
284
+ #
285
+ # | Spanner | Ruby | Notes |
286
+ # |-------------|----------------|---|
287
+ # | `BOOL` | `true`/`false` | |
288
+ # | `INT64` | `Integer` | |
289
+ # | `FLOAT64` | `Float` | |
290
+ # | `STRING` | `String` | |
291
+ # | `DATE` | `Date` | |
292
+ # | `TIMESTAMP` | `Time`, `DateTime` | |
293
+ # | `BYTES` | `File`, `IO`, `StringIO`, or similar | |
294
+ # | `ARRAY` | `Array` | Nested arrays are not supported. |
295
+ #
296
+ # See [Data
297
+ # types](https://cloud.google.com/spanner/docs/data-definition-language#data_types).
298
+ #
299
+ # @return [Time] The timestamp at which the operation committed.
300
+ #
301
+ # @example
302
+ # require "google/cloud/spanner"
303
+ #
304
+ # spanner = Google::Cloud::Spanner.new
305
+ #
306
+ # db = spanner.client "my-instance", "my-database"
307
+ #
308
+ # db.upsert "users", [{ id: 1, name: "Charlie", active: false },
309
+ # { id: 2, name: "Harvey", active: true }]
310
+ #
311
+ def upsert table, *rows, transaction_id: nil
312
+ commit transaction_id: transaction_id do |c|
313
+ c.upsert table, rows
314
+ end
315
+ end
316
+ alias_method :save, :upsert
317
+
318
+ ##
319
+ # Inserts new rows in a table. If any of the rows already exist, the
320
+ # write or request fails with error `ALREADY_EXISTS`.
321
+ #
322
+ # @param [String] table The name of the table in the database to be
323
+ # modified.
324
+ # @param [Array<Hash>] rows One or more hash objects with the hash keys
325
+ # matching the table's columns, and the hash values matching the
326
+ # table's values.
327
+ #
328
+ # Ruby types are mapped to Spanner types as follows:
329
+ #
330
+ # | Spanner | Ruby | Notes |
331
+ # |-------------|----------------|---|
332
+ # | `BOOL` | `true`/`false` | |
333
+ # | `INT64` | `Integer` | |
334
+ # | `FLOAT64` | `Float` | |
335
+ # | `STRING` | `String` | |
336
+ # | `DATE` | `Date` | |
337
+ # | `TIMESTAMP` | `Time`, `DateTime` | |
338
+ # | `BYTES` | `File`, `IO`, `StringIO`, or similar | |
339
+ # | `ARRAY` | `Array` | Nested arrays are not supported. |
340
+ #
341
+ # See [Data
342
+ # types](https://cloud.google.com/spanner/docs/data-definition-language#data_types).
343
+ #
344
+ # @return [Time] The timestamp at which the operation committed.
345
+ #
346
+ # @example
347
+ # require "google/cloud/spanner"
348
+ #
349
+ # spanner = Google::Cloud::Spanner.new
350
+ #
351
+ # db = spanner.client "my-instance", "my-database"
352
+ #
353
+ # db.insert "users", [{ id: 1, name: "Charlie", active: false },
354
+ # { id: 2, name: "Harvey", active: true }]
355
+ #
356
+ def insert table, *rows, transaction_id: nil
357
+ commit transaction_id: transaction_id do |c|
358
+ c.insert table, rows
359
+ end
360
+ end
361
+
362
+ ##
363
+ # Updates existing rows in a table. If any of the rows does not already
364
+ # exist, the request fails with error `NOT_FOUND`.
365
+ #
366
+ # @param [String] table The name of the table in the database to be
367
+ # modified.
368
+ # @param [Array<Hash>] rows One or more hash objects with the hash keys
369
+ # matching the table's columns, and the hash values matching the
370
+ # table's values.
371
+ #
372
+ # Ruby types are mapped to Spanner types as follows:
373
+ #
374
+ # | Spanner | Ruby | Notes |
375
+ # |-------------|----------------|---|
376
+ # | `BOOL` | `true`/`false` | |
377
+ # | `INT64` | `Integer` | |
378
+ # | `FLOAT64` | `Float` | |
379
+ # | `STRING` | `String` | |
380
+ # | `DATE` | `Date` | |
381
+ # | `TIMESTAMP` | `Time`, `DateTime` | |
382
+ # | `BYTES` | `File`, `IO`, `StringIO`, or similar | |
383
+ # | `ARRAY` | `Array` | Nested arrays are not supported. |
384
+ #
385
+ # See [Data
386
+ # types](https://cloud.google.com/spanner/docs/data-definition-language#data_types).
387
+ #
388
+ # @return [Time] The timestamp at which the operation committed.
389
+ #
390
+ # @example
391
+ # require "google/cloud/spanner"
392
+ #
393
+ # spanner = Google::Cloud::Spanner.new
394
+ #
395
+ # db = spanner.client "my-instance", "my-database"
396
+ #
397
+ # db.update "users", [{ id: 1, name: "Charlie", active: false },
398
+ # { id: 2, name: "Harvey", active: true }]
399
+ #
400
+ def update table, *rows, transaction_id: nil
401
+ commit transaction_id: transaction_id do |c|
402
+ c.update table, rows
403
+ end
404
+ end
405
+
406
+ ##
407
+ # Inserts or replaces rows in a table. If any of the rows already exist,
408
+ # it is deleted, and the column values provided are inserted instead.
409
+ # Unlike #upsert, this means any values not explicitly written become
410
+ # `NULL`.
411
+ #
412
+ # @param [String] table The name of the table in the database to be
413
+ # modified.
414
+ # @param [Array<Hash>] rows One or more hash objects with the hash keys
415
+ # matching the table's columns, and the hash values matching the
416
+ # table's values.
417
+ #
418
+ # Ruby types are mapped to Spanner types as follows:
419
+ #
420
+ # | Spanner | Ruby | Notes |
421
+ # |-------------|----------------|---|
422
+ # | `BOOL` | `true`/`false` | |
423
+ # | `INT64` | `Integer` | |
424
+ # | `FLOAT64` | `Float` | |
425
+ # | `STRING` | `String` | |
426
+ # | `DATE` | `Date` | |
427
+ # | `TIMESTAMP` | `Time`, `DateTime` | |
428
+ # | `BYTES` | `File`, `IO`, `StringIO`, or similar | |
429
+ # | `ARRAY` | `Array` | Nested arrays are not supported. |
430
+ #
431
+ # See [Data
432
+ # types](https://cloud.google.com/spanner/docs/data-definition-language#data_types).
433
+ #
434
+ # @return [Time] The timestamp at which the operation committed.
435
+ #
436
+ # @example
437
+ # require "google/cloud/spanner"
438
+ #
439
+ # spanner = Google::Cloud::Spanner.new
440
+ #
441
+ # db = spanner.client "my-instance", "my-database"
442
+ #
443
+ # db.replace "users", [{ id: 1, name: "Charlie", active: false },
444
+ # { id: 2, name: "Harvey", active: true }]
445
+ #
446
+ def replace table, *rows, transaction_id: nil
447
+ commit transaction_id: transaction_id do |c|
448
+ c.replace table, rows
449
+ end
450
+ end
451
+
452
+ ##
453
+ # Deletes rows from a table. Succeeds whether or not the specified rows
454
+ # were present.
455
+ #
456
+ # @param [String] table The name of the table in the database to be
457
+ # modified.
458
+ # @param [Object, Array<Object>] keys A single, or list of keys or key
459
+ # ranges to match returned data to. Values should have exactly as many
460
+ # elements as there are columns in the primary key.
461
+ #
462
+ # @return [Time] The timestamp at which the operation committed.
463
+ #
464
+ # @example
465
+ # require "google/cloud/spanner"
466
+ #
467
+ # spanner = Google::Cloud::Spanner.new
468
+ #
469
+ # db = spanner.client "my-instance", "my-database"
470
+ #
471
+ # db.delete "users", [1, 2, 3]
472
+ #
473
+ def delete table, keys = [], transaction_id: nil
474
+ commit transaction_id: transaction_id do |c|
475
+ c.delete table, keys
476
+ end
477
+ end
478
+
479
+ ##
480
+ # Rolls back the transaction, releasing any locks it holds.
481
+ def rollback transaction_id
482
+ service.rollback path, transaction_id
483
+ @last_updated_at = Time.now
484
+ true
485
+ end
486
+
487
+ ##
488
+ # @private
489
+ # Creates a new transaction object every time.
490
+ def create_transaction
491
+ tx_grpc = service.begin_transaction path
492
+ Transaction.from_grpc(tx_grpc, self)
493
+ end
494
+
495
+ ##
496
+ # Reloads the session resource. Useful for determining if the session is
497
+ # still valid on the Spanner API.
498
+ def reload!
499
+ ensure_service!
500
+ @grpc = service.get_session path
501
+ @last_updated_at = Time.now
502
+ return self
503
+ rescue Google::Cloud::NotFoundError
504
+ @grpc = service.create_session \
505
+ Admin::Database::V1::DatabaseAdminClient.database_path(
506
+ project_id, instance_id, database_id)
507
+ @last_updated_at = Time.now
508
+ return self
509
+ end
510
+
511
+ ##
512
+ # @private
513
+ # Keeps the session alive by executing `"SELECT 1"`.
514
+ def keepalive!
515
+ ensure_service!
516
+ execute "SELECT 1"
517
+ return true
518
+ rescue Google::Cloud::NotFoundError
519
+ @grpc = service.create_session \
520
+ Admin::Database::V1::DatabaseAdminClient.database_path(
521
+ project_id, instance_id, database_id)
522
+ return false
523
+ end
524
+
525
+ ##
526
+ # Permanently deletes the session.
527
+ def release!
528
+ ensure_service!
529
+ service.delete_session path
530
+ end
531
+
532
+ ##
533
+ # @private
534
+ # Determines if the session has been idle longer than the given
535
+ # duration.
536
+ def idle_since? duration
537
+ return true if @last_updated_at.nil?
538
+ Time.now > @last_updated_at + duration
539
+ end
540
+
541
+ ##
542
+ # @private Creates a new Session instance from a
543
+ # Google::Spanner::V1::Session.
544
+ def self.from_grpc grpc, service
545
+ new grpc, service
546
+ end
547
+
548
+ ##
549
+ # @private
550
+ def session
551
+ self
552
+ end
553
+
554
+ protected
555
+
556
+ ##
557
+ # @private Raise an error unless an active connection to the service is
558
+ # available.
559
+ def ensure_service!
560
+ fail "Must have active connection to service" unless service
561
+ end
562
+ end
563
+ end
564
+ end
565
+ end