Class: Google::Cloud::Spanner::Session

Inherits:
Object
  • Object
show all
Defined in:
lib/google/cloud/spanner/session.rb

Overview

# Session

A session can be used to perform transactions that read and/or modify data in a Cloud Spanner database. Sessions are meant to be reused for many consecutive transactions.

Sessions can only execute one transaction at a time. To execute multiple concurrent read-write/write-only transactions, create multiple sessions. Note that standalone reads and queries use a transaction internally, and count toward the one transaction limit.

Cloud Spanner limits the number of sessions that can exist at any given time; thus, it is a good idea to delete idle and/or unneeded sessions. Aside from explicit deletes, Cloud Spanner can delete sessions for which no operations are sent for more than an hour.

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(grpc, service) ⇒ Session



52
53
54
55
# File 'lib/google/cloud/spanner/session.rb', line 52

def initialize grpc, service
  @grpc = grpc
  @service = service
end

Instance Attribute Details

#grpcObject



45
46
47
# File 'lib/google/cloud/spanner/session.rb', line 45

def grpc
  @grpc
end

#serviceObject



49
50
51
# File 'lib/google/cloud/spanner/session.rb', line 49

def service
  @service
end

Class Method Details

.from_grpc(grpc, service) ⇒ Object

Google::Spanner::V1::Session.



544
545
546
# File 'lib/google/cloud/spanner/session.rb', line 544

def self.from_grpc grpc, service
  new grpc, service
end

Instance Method Details

#commit(transaction_id: nil) {|commit| ... } ⇒ Time

Creates changes to be applied to rows in the database.

Examples:

require "google/cloud/spanner"

spanner = Google::Cloud::Spanner.new

db = spanner.client "my-instance", "my-database"

db.commit do |c|
  c.update "users", [{ id: 1, name: "Charlie", active: false }]
  c.insert "users", [{ id: 2, name: "Harvey",  active: true }]
end

Yields:

  • (commit)

    The block for mutating the data.

Yield Parameters:



262
263
264
265
266
267
268
269
270
# File 'lib/google/cloud/spanner/session.rb', line 262

def commit transaction_id: nil
  ensure_service!
  commit = Commit.new
  yield commit
  commit_resp = service.commit path, commit.mutations,
                               transaction_id: transaction_id
  @last_updated_at = Time.now
  Convert.timestamp_to_time commit_resp.commit_timestamp
end

#create_transactionObject

Creates a new transaction object every time.



490
491
492
493
# File 'lib/google/cloud/spanner/session.rb', line 490

def create_transaction
  tx_grpc = service.begin_transaction path
  Transaction.from_grpc(tx_grpc, self)
end

#database_idString

The unique identifier for the database.



71
72
73
# File 'lib/google/cloud/spanner/session.rb', line 71

def database_id
  @grpc.name.split("/")[5]
end

#delete(table, keys = [], transaction_id: nil) ⇒ Time

Deletes rows from a table. Succeeds whether or not the specified rows were present.

Examples:

require "google/cloud/spanner"

spanner = Google::Cloud::Spanner.new

db = spanner.client "my-instance", "my-database"

db.delete "users", [1, 2, 3]


473
474
475
476
477
# File 'lib/google/cloud/spanner/session.rb', line 473

def delete table, keys = [], transaction_id: nil
  commit transaction_id: transaction_id do |c|
    c.delete table, keys
  end
end

#execute(sql, params: nil, types: nil, transaction: nil) ⇒ Google::Cloud::Spanner::Results Also known as: query

Executes a SQL query.

Arguments can be passed using params, Ruby types are mapped to Spanner types as follows:

| Spanner | Ruby | Notes | |————-|—————-|—| | BOOL | true/false | | | INT64 | Integer | | | FLOAT64 | Float | | | STRING | String | | | DATE | Date | | | TIMESTAMP | Time, DateTime | | | BYTES | File, IO, StringIO, or similar | | | ARRAY | Array | Nested arrays are not supported. |

See [Data types](cloud.google.com/spanner/docs/data-definition-language#data_types).

Examples:

require "google/cloud/spanner"

spanner = Google::Cloud::Spanner.new

db = spanner.client "my-instance", "my-database"

results = db.execute "SELECT * FROM users"

results.rows.each do |row|
  puts "User #{row[:id]} is #{row[:name]}"
end

Query using query parameters:

require "google/cloud/spanner"

spanner = Google::Cloud::Spanner.new

db = spanner.client "my-instance", "my-database"

results = db.execute "SELECT * FROM users WHERE active = @active",
                     params: { active: true }

results.rows.each do |row|
  puts "User #{row[:id]} is #{row[:name]}"
end


183
184
185
186
187
188
189
190
# File 'lib/google/cloud/spanner/session.rb', line 183

def execute sql, params: nil, types: nil, transaction: nil
  ensure_service!
  results = Results.execute service, path, sql,
                            params: params, types: types,
                            transaction: transaction
  @last_updated_at = Time.now
  results
end

#idle_since?(duration) ⇒ Boolean

Determines if the session has been idle longer than the given duration.



536
537
538
539
# File 'lib/google/cloud/spanner/session.rb', line 536

def idle_since? duration
  return true if @last_updated_at.nil?
  Time.now > @last_updated_at + duration
end

#insert(table, *rows, transaction_id: nil) ⇒ Time

Inserts new rows in a table. If any of the rows already exist, the write or request fails with error ALREADY_EXISTS.

Examples:

require "google/cloud/spanner"

spanner = Google::Cloud::Spanner.new

db = spanner.client "my-instance", "my-database"

db.insert "users", [{ id: 1, name: "Charlie", active: false },
                    { id: 2, name: "Harvey",  active: true }]


356
357
358
359
360
# File 'lib/google/cloud/spanner/session.rb', line 356

def insert table, *rows, transaction_id: nil
  commit transaction_id: transaction_id do |c|
    c.insert table, rows
  end
end

#instance_idString

The unique identifier for the instance.



65
66
67
# File 'lib/google/cloud/spanner/session.rb', line 65

def instance_id
  @grpc.name.split("/")[3]
end

#keepalive!Object

Keeps the session alive by executing ‘“SELECT 1”`.



514
515
516
517
518
519
520
521
522
523
# File 'lib/google/cloud/spanner/session.rb', line 514

def keepalive!
  ensure_service!
  execute "SELECT 1"
  return true
rescue Google::Cloud::NotFoundError
  @grpc = service.create_session \
    Admin::Database::V1::DatabaseAdminClient.database_path(
      project_id, instance_id, database_id)
  return false
end

#pathString

The full path for the session resource. Values are of the form ‘projects/<project_id>/instances/<instance_id>/databases/<database_id>/sessions/<session_id>`.



87
88
89
# File 'lib/google/cloud/spanner/session.rb', line 87

def path
  @grpc.name
end

#project_idString

The unique identifier for the project.



59
60
61
# File 'lib/google/cloud/spanner/session.rb', line 59

def project_id
  @grpc.name.split("/")[1]
end

#read(table, columns, keys: nil, index: nil, limit: nil, transaction: nil) ⇒ Google::Cloud::Spanner::Results

Read rows from a database table, as a simple alternative to #execute.

Examples:

require "google/cloud/spanner"

spanner = Google::Cloud::Spanner.new

db = spanner.client "my-instance", "my-database"

results = db.read "users", [:id, :name]

results.rows.each do |row|
  puts "User #{row[:id]} is #{row[:name]}"
end


229
230
231
232
233
234
235
236
237
# File 'lib/google/cloud/spanner/session.rb', line 229

def read table, columns, keys: nil, index: nil, limit: nil,
         transaction: nil
  ensure_service!
  results = Results.read service, path, table, columns,
                         keys: keys, index: index, limit: limit,
                         transaction: transaction
  @last_updated_at = Time.now
  results
end

#release!Object

Permanently deletes the session.



527
528
529
530
# File 'lib/google/cloud/spanner/session.rb', line 527

def release!
  ensure_service!
  service.delete_session path
end

#reload!Object

Reloads the session resource. Useful for determining if the session is still valid on the Spanner API.



498
499
500
501
502
503
504
505
506
507
508
509
# File 'lib/google/cloud/spanner/session.rb', line 498

def reload!
  ensure_service!
  @grpc = service.get_session path
  @last_updated_at = Time.now
  return self
rescue Google::Cloud::NotFoundError
  @grpc = service.create_session \
    Admin::Database::V1::DatabaseAdminClient.database_path(
      project_id, instance_id, database_id)
  @last_updated_at = Time.now
  return self
end

#replace(table, *rows, transaction_id: nil) ⇒ Time

Inserts or replaces rows in a table. If any of the rows already exist, it is deleted, and the column values provided are inserted instead. Unlike #upsert, this means any values not explicitly written become NULL.

Examples:

require "google/cloud/spanner"

spanner = Google::Cloud::Spanner.new

db = spanner.client "my-instance", "my-database"

db.replace "users", [{ id: 1, name: "Charlie", active: false },
                     { id: 2, name: "Harvey",  active: true }]


446
447
448
449
450
# File 'lib/google/cloud/spanner/session.rb', line 446

def replace table, *rows, transaction_id: nil
  commit transaction_id: transaction_id do |c|
    c.replace table, rows
  end
end

#rollback(transaction_id) ⇒ Object

Rolls back the transaction, releasing any locks it holds.



481
482
483
484
485
# File 'lib/google/cloud/spanner/session.rb', line 481

def rollback transaction_id
  service.rollback path, transaction_id
  @last_updated_at = Time.now
  true
end

#sessionObject



550
551
552
# File 'lib/google/cloud/spanner/session.rb', line 550

def session
  self
end

#session_idString

The unique identifier for the session.



77
78
79
# File 'lib/google/cloud/spanner/session.rb', line 77

def session_id
  @grpc.name.split("/")[7]
end

#update(table, *rows, transaction_id: nil) ⇒ Time

Updates existing rows in a table. If any of the rows does not already exist, the request fails with error NOT_FOUND.

Examples:

require "google/cloud/spanner"

spanner = Google::Cloud::Spanner.new

db = spanner.client "my-instance", "my-database"

db.update "users", [{ id: 1, name: "Charlie", active: false },
                    { id: 2, name: "Harvey",  active: true }]


400
401
402
403
404
# File 'lib/google/cloud/spanner/session.rb', line 400

def update table, *rows, transaction_id: nil
  commit transaction_id: transaction_id do |c|
    c.update table, rows
  end
end

#upsert(table, *rows, transaction_id: nil) ⇒ Time Also known as: save

Inserts or updates rows in a table. If any of the rows already exist, then its column values are overwritten with the ones provided. Any column values not explicitly written are preserved.

Examples:

require "google/cloud/spanner"

spanner = Google::Cloud::Spanner.new

db = spanner.client "my-instance", "my-database"

db.upsert "users", [{ id: 1, name: "Charlie", active: false },
                    { id: 2, name: "Harvey",  active: true }]


311
312
313
314
315
# File 'lib/google/cloud/spanner/session.rb', line 311

def upsert table, *rows, transaction_id: nil
  commit transaction_id: transaction_id do |c|
    c.upsert table, rows
  end
end