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

Returns a new instance of 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

Parameters:

  • transaction_id (String) (defaults to: nil)

    The identifier of previously-started transaction to be used instead of starting a new transaction. Optional.

Yields:

  • (commit)

    The block for mutating the data.

Yield Parameters:

Returns:

  • (Time)

    The timestamp at which the operation committed.



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.

Returns:

  • (String)


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

def database_id
  V1::SpannerClient.match_database_from_session_name @grpc.name
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]

Parameters:

  • table (String)

    The name of the table in the database to be modified.

  • keys (Object, Array<Object>) (defaults to: [])

    A single, or list of keys or key ranges to match returned data to. Values should have exactly as many elements as there are columns in the primary key.

Returns:

  • (Time)

    The timestamp at which the operation committed.



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

Parameters:

  • sql (String)

    The SQL query string. See [Query syntax](cloud.google.com/spanner/docs/query-syntax).

    The SQL query string can contain parameter placeholders. A parameter placeholder consists of “@” followed by the parameter name. Parameter names consist of any combination of letters, numbers, and underscores.

  • params (Hash) (defaults to: nil)

    SQL parameters for the query string. The parameter placeholders, minus the “@”, are the the hash keys, and the literal values are the hash values. If the query string contains something like “WHERE id > @msg_id”, then the params must contain something like ‘:msg_id => 1`.

  • types (Hash) (defaults to: nil)

    Types of the SQL parameters in ‘params`. It is not always possible for Cloud Spanner to infer the right SQL type from a value in `params`. In these cases, the `types` hash can be used to specify the exact SQL type for some or all of the SQL query parameters.

    The keys of the hash should be query string parameter placeholders, minus the “@”. The values of the hash should be Cloud Spanner type codes from the following list:

    • ‘:BOOL`

    • ‘:BYTES`

    • ‘:DATE`

    • ‘:FLOAT64`

    • ‘:INT64`

    • ‘:STRING`

    • ‘:TIMESTAMP`

    Arrays are specified by providing the type code in an array. For example, an array of integers are specified as ‘[:INT64]`.

    Structs are not yet supported in query parameters.

    Types are optional.

  • transaction (Google::Spanner::V1::TransactionSelector) (defaults to: nil)

    The transaction selector value to send. Only used for single-use transactions.

Returns:



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.

Returns:

  • (Boolean)


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 }]

Parameters:

  • table (String)

    The name of the table in the database to be modified.

  • rows (Array<Hash>)

    One or more hash objects with the hash keys matching the table’s columns, and the hash values matching the table’s values.

    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).

Returns:

  • (Time)

    The timestamp at which the operation committed.



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.

Returns:

  • (String)


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

def instance_id
  V1::SpannerClient.match_instance_from_session_name @grpc.name
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>`.

Returns:

  • (String)


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.

Returns:

  • (String)


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

def project_id
  V1::SpannerClient.match_project_from_session_name @grpc.name
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

Parameters:

  • table (String)

    The name of the table in the database to be read.

  • columns (Array<String, Symbol>)

    The columns of table to be returned for each row matching this request.

  • keys (Object, Array<Object>) (defaults to: nil)

    A single, or list of keys or key ranges to match returned data to. Values should have exactly as many elements as there are columns in the primary key.

  • index (String) (defaults to: nil)

    The name of an index to use instead of the table’s primary key when interpreting ‘id` and sorting result rows. Optional.

  • limit (Integer) (defaults to: nil)

    If greater than zero, no more than this number of rows will be returned. The default is no limit.

  • transaction (Google::Spanner::V1::TransactionSelector) (defaults to: nil)

    The transaction selector value to send. Only used for single-use transactions.

Returns:



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 }]

Parameters:

  • table (String)

    The name of the table in the database to be modified.

  • rows (Array<Hash>)

    One or more hash objects with the hash keys matching the table’s columns, and the hash values matching the table’s values.

    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).

Returns:

  • (Time)

    The timestamp at which the operation committed.



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.

Returns:

  • (String)


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

def session_id
  V1::SpannerClient.match_session_from_session_name @grpc.name
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 }]

Parameters:

  • table (String)

    The name of the table in the database to be modified.

  • rows (Array<Hash>)

    One or more hash objects with the hash keys matching the table’s columns, and the hash values matching the table’s values.

    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).

Returns:

  • (Time)

    The timestamp at which the operation committed.



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 }]

Parameters:

  • table (String)

    The name of the table in the database to be modified.

  • rows (Array<Hash>)

    One or more hash objects with the hash keys matching the table’s columns, and the hash values matching the table’s values.

    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).

Returns:

  • (Time)

    The timestamp at which the operation committed.



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