class Google::Cloud::Spanner::Database

# Database

Represents a Cloud Spanner database. To use Cloud Spanner's read and write operations, you must first create a database. A database belongs to a {Instance} and contains tables and indexes. You may create multiple databases in an {Instance}.

See {Google::Cloud::Spanner::Instance#databases}, {Google::Cloud::Spanner::Instance#database}, and {Google::Cloud::Spanner::Instance#create_database}.

To read and/or modify data in a Cloud Spanner database, use an instance of {Google::Cloud::Spanner::Client}. See {Google::Cloud::Spanner::Project#client}.

@example

require "google/cloud"

spanner = Google::Cloud::Spanner.new
instance = spanner.instance "my-instance"

job = instance.create_database "my-new-database"

job.done? #=> false
job.reload! # API call
job.done? #=> true

if job.error?
  status = job.error
else
  database = job.database
end

Constants

DATBASE_OPERATION_METADAT_FILTER_TEMPLATE

@private

Attributes

service[RW]

@private The gRPC Service object.

Public Class Methods

from_grpc(grpc, service) click to toggle source

@private Creates a new Database instance from a `Google::Cloud::Spanner::Admin::Database::V1::Database`.

# File lib/google/cloud/spanner/database.rb, line 723
def self.from_grpc grpc, service
  new grpc, service
end
new(grpc, service) click to toggle source

@private Creates a new Database instance.

# File lib/google/cloud/spanner/database.rb, line 65
def initialize grpc, service
  @grpc = grpc
  @service = service
end

Public Instance Methods

backups(page_size: nil) click to toggle source

Retrieves backups belonging to the database.

@param [Integer] page_size Optional. Number of backups to be returned

in the response. If 0 or less, defaults to the server's maximum
allowed page size.

@return [Array<Google::Cloud::Spanner::Backup>] Enumerable list of

backups. (See {Google::Cloud::Spanner::Backup::List})

@example

require "google/cloud/spanner"

spanner = Google::Cloud::Spanner.new
database = spanner.database "my-instance", "my-database"

database.backups.all.each do |backup|
  puts backup.backup_id
end

@example List backups by page size

require "google/cloud/spanner"

spanner = Google::Cloud::Spanner.new
database = spanner.database "my-instance", "my-database"

database.backups(page_size: 5).all.each do |backup|
  puts backup.backup_id
end
# File lib/google/cloud/spanner/database.rb, line 572
def backups page_size: nil
  ensure_service!
  grpc = service.list_backups \
    instance_id,
    filter: "database:#{database_id}",
    page_size: page_size
  Backup::List.from_grpc grpc, service
end
create_backup(backup_id, expire_time, version_time: nil, encryption_config: nil) click to toggle source

Creates a database backup.

@param [String] backup_id The unique identifier for the backup.

Values are of the form `[a-z][a-z0-9_\-]*[a-z0-9]` and must be
between 2 and 60 characters in length. Required.

@param [Time] expire_time The expiration time of the backup, with

microseconds granularity that must be at least 6 hours and at most
366 days from the time the request is received. Required.
Once the `expire_time` has passed, Cloud Spanner will delete the
backup and free the resources used by the backup. Required.

@param [Time] version_time Specifies the time to have an externally

consistent copy of the database. If no version time is specified,
it will be automatically set to the backup create time. The version
time can be as far in the past as specified by the database earliest
version time. Optional.

@param [Hash] encryption_config An encryption configuration describing

the encryption type and key resources in Cloud KMS. Optional. The
following settings can be provided:

* `:kms_key_name` (String) The name of KMS key to use which should
  be the full path, e.g., `projects/<project>/locations/<location>\
  /keyRings/<key_ring>/cryptoKeys/<kms_key_name>`
  This field should be set only when encryption type
  `:CUSTOMER_MANAGED_ENCRYPTION`.
* `:encryption_type` (Symbol) The encryption type of the backup.
  Valid values are:
    1. `:USE_DATABASE_ENCRYPTION` - Use the same encryption configuration as
      the database.
    2. `:GOOGLE_DEFAULT_ENCRYPTION` - Google default encryption.
    3. `:CUSTOMER_MANAGED_ENCRYPTION` - Use customer managed encryption.
      If specified, `:kms_key_name` must contain a valid Cloud KMS key.

@raise [ArgumentError] if `:CUSTOMER_MANAGED_ENCRYPTION` specified without

customer managed kms key.

@return [Google::Cloud::Spanner::Backup::Job] The job representing

the long-running, asynchronous processing of a backup create
operation.

@example Create backup with expiration time

require "google/cloud/spanner"

spanner = Google::Cloud::Spanner.new
database = spanner.database "my-instance", "my-database"

backup_id = "my-backup"
expire_time = Time.now + (24 * 60 * 60) # 1 day from now
version_time = Time.now - (24 * 60 * 60) # 1 day ago (optional)

job = database.create_backup backup_id, expire_time, version_time: version_time

job.done? #=> false
job.reload! # API call
job.done? #=> true

if job.error?
  status = job.error
else
  backup = job.backup
end

@example Create backup with encryption config

require "google/cloud/spanner"

spanner = Google::Cloud::Spanner.new
database = spanner.database "my-instance", "my-database"

kms_key_name = "projects/<project>/locations/<location>/keyRings/<key_ring>/cryptoKeys/<kms_key_name>"
encryption_config = {
  kms_key_name: kms_key_name,
  encryption_type: :CUSTOMER_MANAGED_ENCRYPTION
}
job = database.create_backup "my-backup",
                             Time.now + 36000,
                             encryption_config: encryption_config

job.done? #=> false
job.reload! # API call
job.done? #=> true

if job.error?
  status = job.error
else
  backup = job.backup
end
# File lib/google/cloud/spanner/database.rb, line 523
def create_backup backup_id, expire_time,
                  version_time: nil, encryption_config: nil
  ensure_service!

  if encryption_config&.include?(:kms_key_name) &&
     encryption_config[:encryption_type] != :CUSTOMER_MANAGED_ENCRYPTION
    raise Google::Cloud::InvalidArgumentError,
          "kms_key_name only used with CUSTOMER_MANAGED_ENCRYPTION"
  end

  grpc = service.create_backup \
    instance_id,
    database_id,
    backup_id,
    expire_time,
    version_time,
    encryption_config: encryption_config
  Backup::Job.from_grpc grpc, service
end
create_time() click to toggle source

Time at which the database creation started. @return [Time]

# File lib/google/cloud/spanner/database.rb, line 119
def create_time
  Convert.timestamp_to_time @grpc.create_time
end
creating?() click to toggle source

The database is still being created. Operations on the database may raise with `FAILED_PRECONDITION` in this state. @return [Boolean]

# File lib/google/cloud/spanner/database.rb, line 152
def creating?
  state == :CREATING
end
database_id() click to toggle source

The unique identifier for the database. @return [String]

# File lib/google/cloud/spanner/database.rb, line 84
def database_id
  @grpc.name.split("/")[5]
end
database_operations(filter: nil, page_size: nil) click to toggle source

Retrieves the list of database operations for the given database.

@param filter [String]

A filter expression that filters what operations are returned in the
response.

The response returns a list of
`Google::Longrunning::Operation` long-running operations whose names
are prefixed by a database name within the specified instance.
The long-running operation
`Google::Longrunning::Operation#metadata` metadata field type
`metadata.type_url` describes the type of the metadata.

The filter expression must specify the field name,
a comparison operator, and the value that you want to use for
filtering. The value must be a string, a number, or a boolean.
The comparison operator must be
<, >, <=, >=, !=, =, or :. Colon ':' represents a HAS operator
which is roughly synonymous with equality. Filter rules are case
insensitive.

The long-running operation fields eligible for filtering are:
  * `name` --> The name of the long-running operation
  * `done` --> False if the operation is in progress, else true.
  * `metadata.type_url` (using filter string `metadata.@type`) and
    fields in `metadata.value` (using filter string
    `metadata.<field_name>`, where <field_name> is a field in
    metadata.value) are eligible for filtering.
  * `error` --> Error associated with the long-running operation.
  * `response.type_url` (using filter string `response.@type`) and
    fields in `response.value` (using filter string
    `response.<field_name>`, where <field_name> is a field in
    response.value)are eligible for filtering.

  To filter on multiple expressions, provide each separate
  expression within parentheses. By default, each expression
  is an AND expression. However, you can include AND, OR, and NOT
  expressions explicitly.

Some examples of using filters are:

  * `done:true` --> The operation is complete.
  * `(metadata.@type:type.googleapis.com/google.spanner.admin.\
    database.v1.RestoreDatabaseMetadata)
    AND (metadata.source_type:BACKUP)
    AND (metadata.backup_info.backup:backup_howl)
    AND (metadata.name:restored_howl)
    AND (metadata.progress.start_time < \"2018-03-28T14:50:00Z\")
    AND (error:*)`
    --> Return RestoreDatabase operations from backups whose name
    contains "backup_howl", where the created database name
    contains the string "restored_howl", the start_time of the
    restore operation is before 2018-03-28T14:50:00Z,
    and the operation returned an error.

@param page_size [Integer]

The maximum number of resources contained in the underlying API
response. If page streaming is performed per-resource, this
parameter does not affect the return value. If page streaming is
performed per-page, this determines the maximum number of
resources in a page.

@return [Array<Google::Cloud::Spanner::Database::Job>] List

representing the long-running, asynchronous processing
of a database operations.
(See {Google::Cloud::Spanner::Database::Job::List})

@example

require "google/cloud/spanner"

spanner = Google::Cloud::Spanner.new

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

jobs = database.database_operations
jobs.each do |job|
  if job.error?
    p job.error
  else
    p job.database.database_id
  end
end

@example Retrieve all

require "google/cloud/spanner"

spanner = Google::Cloud::Spanner.new

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

jobs = database.database_operations
jobs.all do |job|
  if job.error?
    p job.error
  else
    puts job.database.database_id
  end
end

@example List by page size

require "google/cloud/spanner"

spanner = Google::Cloud::Spanner.new

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

jobs = database.database_operations page_size: 10
jobs.each do |job|
  if job.error?
    p job.error
  else
    puts job.database.database_id
  end
end

@example Filter and list

require "google/cloud/spanner"

spanner = Google::Cloud::Spanner.new

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

jobs = database.database_operations filter: "done:true"
jobs.each do |job|
  if job.error?
    p job.error
  else
    puts job.database.database_id
  end
end
# File lib/google/cloud/spanner/database.rb, line 417
def database_operations filter: nil, page_size: nil
  database_filter = format(
    DATBASE_OPERATION_METADAT_FILTER_TEMPLATE,
    database_id: database_id
  )

  if filter
    database_filter = format(
      "(%<filter>s) AND (%<database_filter>s)",
      filter: filter, database_filter: database_filter
    )
  end

  grpc = service.list_database_operations instance_id,
                                          filter: database_filter,
                                          page_size: page_size
  Database::Job::List.from_grpc grpc, service
end
ddl(force: nil) click to toggle source

Retrieve the Data Definition Language (DDL) statements that define database structures. DDL statements are used to create, update, and delete tables and indexes.

@see cloud.google.com/spanner/docs/data-definition-language

Data Definition Language

@param [Boolean] force Force the latest DDL statements to be retrieved

from the Spanner service when `true`. Otherwise the DDL statements
will be memoized to reduce the number of API calls made to the
Spanner service. The default is `false`.

@return [Array<String>] The DDL statements.

@example statements are memoized to reduce the number of API calls:

require "google/cloud/spanner"

spanner = Google::Cloud::Spanner.new
database = spanner.database "my-instance", "my-database"

statements = database.ddl # API call
statements_2 = database.ddl # No API call

@example Use `force` to retrieve the statements from the service:

require "google/cloud/spanner"

spanner = Google::Cloud::Spanner.new
database = spanner.database "my-instance", "my-database"

statements = database.ddl force: true # API call
statements_2 = database.ddl force: true # API call
# File lib/google/cloud/spanner/database.rb, line 203
def ddl force: nil
  return @ddl if @ddl && !force
  ensure_service!
  ddl_grpc = service.get_database_ddl instance_id, database_id
  @ddl = ddl_grpc.statements
end
drop() click to toggle source

Drops (deletes) the Cloud Spanner database.

@return [Boolean] Returns `true` if the database was deleted.

@example

require "google/cloud/spanner"

spanner = Google::Cloud::Spanner.new
database = spanner.database "my-instance", "my-database"

database.drop
# File lib/google/cloud/spanner/database.rb, line 270
def drop
  ensure_service!
  service.drop_database instance_id, database_id
  true
end
earliest_version_time() click to toggle source

The earliest available version time for a database. @return [Time]

# File lib/google/cloud/spanner/database.rb, line 96
def earliest_version_time
  Convert.timestamp_to_time @grpc.earliest_version_time
end
encryption_config() click to toggle source

An encryption configuration describing the encryption type and key resources in Cloud KMS.

@return [Google::Cloud::Spanner::Admin::Database::V1::EncryptionConfig, nil]

# File lib/google/cloud/spanner/database.rb, line 127
def encryption_config
  @grpc.encryption_config
end
encryption_info() click to toggle source

Encryption information for the database.

For databases that are using customer managed encryption, this field contains the encryption information for the database, such as encryption state and the Cloud KMS key versions that are in use.

For databases that are using Google default or other types of encryption, this field is empty.

This field is propagated lazily from the backend. There might be a delay from when a key version is being used and when it appears in this field.

@return [Array<Google::Cloud::Spanner::Admin::Database::V1::EncryptionInfo>]

# File lib/google/cloud/spanner/database.rb, line 144
def encryption_info
  @grpc.encryption_info.to_a
end
instance_id() click to toggle source

The unique identifier for the instance. @return [String]

# File lib/google/cloud/spanner/database.rb, line 78
def instance_id
  @grpc.name.split("/")[3]
end
path() click to toggle source

The full path for the database resource. Values are of the form `projects/<project_id>/instances/<instance_id>/databases/<database_id>`. @return [String]

# File lib/google/cloud/spanner/database.rb, line 104
def path
  @grpc.name
end
policy() { |policy| ... } click to toggle source

Gets the [Cloud IAM](cloud.google.com/iam/) access control policy for this database.

@see cloud.google.com/spanner/reference/rpc/google.iam.v1#google.iam.v1.Policy

google.iam.v1.IAMPolicy

@yield [policy] A block for updating the policy. The latest policy

will be read from the Spanner service and passed to the block. After
the block completes, the modified policy will be written to the
service.

@yieldparam [Policy] policy the current Cloud IAM Policy for this

database

@return [Policy] The current Cloud IAM Policy for this database.

@example

require "google/cloud/spanner"

spanner = Google::Cloud::Spanner.new
database = spanner.database "my-instance", "my-database"

policy = database.policy

@example Update the policy by passing a block:

require "google/cloud/spanner"

spanner = Google::Cloud::Spanner.new
database = spanner.database "my-instance", "my-database"

database.policy do |p|
  p.add "roles/owner", "user:owner@example.com"
end # 2 API calls
# File lib/google/cloud/spanner/database.rb, line 623
def policy
  ensure_service!
  grpc = service.get_database_policy instance_id, database_id
  policy = Policy.from_grpc grpc
  return policy unless block_given?
  yield policy
  update_policy policy
end
policy=(new_policy)
Alias for: update_policy
project_id() click to toggle source

The unique identifier for the project. @return [String]

# File lib/google/cloud/spanner/database.rb, line 72
def project_id
  @grpc.name.split("/")[1]
end
ready?() click to toggle source

The database is fully created and ready for use. @return [Boolean]

# File lib/google/cloud/spanner/database.rb, line 159
def ready?
  state == :READY
end
ready_optimizing?() click to toggle source

The database is fully created from backup and optimizing. @return [Boolean]

# File lib/google/cloud/spanner/database.rb, line 166
def ready_optimizing?
  state == :READY_OPTIMIZING
end
restore_info() click to toggle source

Information about the source used to restore the database.

@return [Google::Cloud::Spanner::Database::RestoreInfo, nil]

# File lib/google/cloud/spanner/database.rb, line 584
def restore_info
  return nil unless @grpc.restore_info
  RestoreInfo.from_grpc @grpc.restore_info
end
state() click to toggle source

The current database state. Possible values are `:CREATING` and `:READY`. @return [Symbol]

# File lib/google/cloud/spanner/database.rb, line 112
def state
  @grpc.state
end
test_permissions(*permissions) click to toggle source

Tests the specified permissions against the [Cloud IAM](cloud.google.com/iam/) access control policy.

@see cloud.google.com/iam/docs/managing-policies Managing

Policies

@param [String, Array<String>] permissions The set of permissions to

 check access for. Permissions with wildcards (such as `*` or
 `storage.*`) are not allowed.

 The permissions that can be checked on a database are:

* spanner.databases.beginPartitionedDmlTransaction
* spanner.databases.create
* spanner.databases.createBackup
* spanner.databases.list
* spanner.databases.update
* spanner.databases.updateDdl
* spanner.databases.get
* spanner.databases.getDdl
* spanner.databases.getIamPolicy
* spanner.databases.setIamPolicy
* spanner.databases.beginReadOnlyTransaction
* spanner.databases.beginOrRollbackReadWriteTransaction
* spanner.databases.read
* spanner.databases.select
* spanner.databases.write
* spanner.databases.drop

@return [Array<Strings>] The permissions that have access.

@example

require "google/cloud/spanner"

spanner = Google::Cloud::Spanner.new
database = spanner.database "my-instance", "my-database"
perms = database.test_permissions "spanner.databases.get",
                                  "spanner.databases.update"
perms.include? "spanner.databases.get" #=> true
perms.include? "spanner.databases.update" #=> false
# File lib/google/cloud/spanner/database.rb, line 711
def test_permissions *permissions
  permissions = Array(permissions).flatten
  permissions = Array(permissions).flatten
  ensure_service!
  grpc = service.test_database_permissions \
    instance_id, database_id, permissions
  grpc.permissions
end
update(statements: [], operation_id: nil) click to toggle source

Updates the database schema by adding Data Definition Language (DDL) statements to create, update, and delete tables and indexes.

@see cloud.google.com/spanner/docs/data-definition-language

Data Definition Language

@param [Array<String>] statements The DDL statements to be applied to

the database.

@param [String, nil] operation_id The operation ID used to perform the

update. When `nil`, the update request is assigned an
automatically-generated operation ID. Specifying an explicit value
simplifies determining whether the statements were executed in the
event that the update is replayed, or the return value is otherwise
lost. This value should be unique within the database, and must be a
valid identifier: `[a-z][a-z0-9_]*`. Will raise
{Google::Cloud::AlreadyExistsError} if the named operation already
exists. Optional.

@return [Database::Job] The job representing the long-running,

asynchronous processing of a database schema update operation.

@example

require "google/cloud/spanner"

spanner = Google::Cloud::Spanner.new
database = spanner.database "my-instance", "my-database"

add_users_table_sql = %q(
  CREATE TABLE users (
    id INT64 NOT NULL,
    username STRING(25) NOT NULL,
    name STRING(45) NOT NULL,
    email STRING(128),
  ) PRIMARY KEY(id)
)

database.update statements: [add_users_table_sql]
# File lib/google/cloud/spanner/database.rb, line 249
def update statements: [], operation_id: nil
  ensure_service!
  grpc = service.update_database_ddl instance_id, database_id,
                                     statements: statements,
                                     operation_id: operation_id
  Database::Job.from_grpc grpc, service
end
update_policy(new_policy) click to toggle source

Updates the [Cloud IAM](cloud.google.com/iam/) access control policy for this database. The policy should be read from {#policy}. See {Google::Cloud::Spanner::Policy} for an explanation of the policy `etag` property and how to modify policies.

You can also update the policy by passing a block to {#policy}, which will call this method internally after the block completes.

@see cloud.google.com/spanner/reference/rpc/google.iam.v1#google.iam.v1.Policy

google.iam.v1.IAMPolicy

@param [Policy] new_policy a new or modified Cloud IAM Policy for this

database

@return [Policy] The policy returned by the API update operation.

@example

require "google/cloud/spanner"

spanner = Google::Cloud::Spanner.new
database = spanner.database "my-instance", "my-database"

policy = database.policy # API call

policy.add "roles/owner", "user:owner@example.com"

database.update_policy policy # API call
# File lib/google/cloud/spanner/database.rb, line 661
def update_policy new_policy
  ensure_service!
  grpc = service.set_database_policy \
    instance_id, database_id, new_policy.to_grpc
  Policy.from_grpc grpc
end
Also aliased as: policy=
version_retention_period() click to toggle source

The version retention period for a database. @return [String]

# File lib/google/cloud/spanner/database.rb, line 90
def version_retention_period
  @grpc.version_retention_period
end

Protected Instance Methods

ensure_service!() click to toggle source

@private Raise an error unless an active connection to the service is available.

# File lib/google/cloud/spanner/database.rb, line 732
def ensure_service!
  raise "Must have active connection to service" unless service
end
session_path(instance_id, database_id, session_id) click to toggle source
# File lib/google/cloud/spanner/database.rb, line 736
def session_path instance_id, database_id, session_id
  V1::SpannerClient.session_path(
    project_id, instance_id, database_id, session_id
  )
end