spanner/spanner_samples.rb (1,699 lines of code) (raw):

# Copyright 2017 Google, Inc # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. def create_instance project_id:, instance_id:, instance_config_id: "regional-us-central1" # [START spanner_create_instance] # project_id = "Your Google Cloud project ID" # instance_id = "Your Spanner instance ID" # instance_config_id = "Your Spanner InstanceConfig ID" require "google/cloud/spanner" require "google/cloud/spanner/admin/instance" instance_admin_client = Google::Cloud::Spanner::Admin::Instance.instance_admin project_path = instance_admin_client.project_path project: project_id instance_path = instance_admin_client.instance_path project: project_id, instance: instance_id instance_config_path = instance_admin_client.instance_config_path project: project_id, instance_config: instance_config_id job = instance_admin_client.create_instance parent: project_path, instance_id: instance_id, instance: { name: instance_path, config: instance_config_path, display_name: instance_id, node_count: 2, labels: { cloud_spanner_samples: "true" } } puts "Waiting for create instance operation to complete" job.wait_until_done! if job.error? puts job.error else puts "Created instance #{instance_id}" end # [END spanner_create_instance] end def create_instance_with_processing_units project_id:, instance_id: # [START spanner_create_instance_with_processing_units] # project_id = "Your Google Cloud project ID" # instance_id = "Your Spanner instance ID" require "google/cloud/spanner" require "google/cloud/spanner/admin/instance" instance_admin_client = Google::Cloud::Spanner::Admin::Instance.instance_admin project_path = instance_admin_client.project_path project: project_id instance_path = instance_admin_client.instance_path project: project_id, instance: instance_id instance_config_path = instance_admin_client.instance_config_path project: project_id, instance_config: "regional-us-central1" job = instance_admin_client.create_instance parent: project_path, instance_id: instance_id, instance: { name: instance_path, config: instance_config_path, display_name: instance_id, processing_units: 500, labels: { cloud_spanner_samples: "true" } } puts "Waiting for creating instance operation to complete" job.wait_until_done! if job.error? puts job.error else puts "Created instance #{instance_id}" end instance = instance_admin_client.get_instance name: instance_path puts "Instance #{instance_id} has #{instance.processing_units} processing units." # [END spanner_create_instance_with_processing_units] end def create_database project_id:, instance_id:, database_id: # [START spanner_create_database] # project_id = "Your Google Cloud project ID" # instance_id = "Your Spanner instance ID" # database_id = "Your Spanner database ID" require "google/cloud/spanner" require "google/cloud/spanner/admin/database" database_admin_client = Google::Cloud::Spanner::Admin::Database.database_admin instance_path = database_admin_client.instance_path project: project_id, instance: instance_id job = database_admin_client.create_database parent: instance_path, create_statement: "CREATE DATABASE `#{database_id}`", extra_statements: [ "CREATE TABLE Singers ( SingerId INT64 NOT NULL, FirstName STRING(1024), LastName STRING(1024), SingerInfo BYTES(MAX) ) PRIMARY KEY (SingerId)", "CREATE TABLE Albums ( SingerId INT64 NOT NULL, AlbumId INT64 NOT NULL, AlbumTitle STRING(MAX) ) PRIMARY KEY (SingerId, AlbumId), INTERLEAVE IN PARENT Singers ON DELETE CASCADE" ] puts "Waiting for create database operation to complete" job.wait_until_done! puts "Created database #{database_id} on instance #{instance_id}" # [END spanner_create_database] end def create_database_with_version_retention_period project_id:, instance_id:, database_id: # [START spanner_create_database_with_version_retention_period] # project_id = "Your Google Cloud project ID" # instance_id = "Your Spanner instance ID" # database_id = "Your Spanner database ID" require "google/cloud/spanner" require "google/cloud/spanner/admin/database" database_admin_client = Google::Cloud::Spanner::Admin::Database.database_admin instance_path = database_admin_client.instance_path project: project_id, instance: instance_id version_retention_period = "7d" db_path = database_admin_client.database_path project: project_id, instance: instance_id, database: database_id job = database_admin_client.create_database parent: instance_path, create_statement: "CREATE DATABASE `#{database_id}`", extra_statements: [ "CREATE TABLE Singers ( SingerId INT64 NOT NULL, FirstName STRING(1024), LastName STRING(1024), SingerInfo BYTES(MAX) ) PRIMARY KEY (SingerId)", "CREATE TABLE Albums ( SingerId INT64 NOT NULL, AlbumId INT64 NOT NULL, AlbumTitle STRING(MAX) ) PRIMARY KEY (SingerId, AlbumId), INTERLEAVE IN PARENT Singers ON DELETE CASCADE", "ALTER DATABASE `#{database_id}` SET OPTIONS ( version_retention_period = '#{version_retention_period}' )" ] puts "Waiting for create database operation to complete" job.wait_until_done! database = database_admin_client.get_database name: db_path puts "Created database #{database_id} on instance #{instance_id}" puts "\tVersion retention period: #{database.version_retention_period}" puts "\tEarliest version time: #{database.earliest_version_time}" # [END spanner_create_database_with_version_retention_period] end def create_database_with_encryption_key project_id:, instance_id:, database_id:, kms_key_name: # [START spanner_create_database_with_encryption_key] # project_id = "Your Google Cloud project ID" # instance_id = "Your Spanner instance ID" # database_id = "Your Spanner database ID" # kms_key_name = "Database eencryption KMS key" require "google/cloud/spanner" require "google/cloud/spanner/admin/database" database_admin_client = Google::Cloud::Spanner::Admin::Database.database_admin instance_path = database_admin_client.instance_path project: project_id, instance: instance_id db_path = database_admin_client.database_path project: project_id, instance: instance_id, database: database_id job = database_admin_client.create_database parent: instance_path, create_statement: "CREATE DATABASE `#{database_id}`", extra_statements: [ "CREATE TABLE Singers ( SingerId INT64 NOT NULL, FirstName STRING(1024), LastName STRING(1024), SingerInfo BYTES(MAX) ) PRIMARY KEY (SingerId)", "CREATE TABLE Albums ( SingerId INT64 NOT NULL, AlbumId INT64 NOT NULL, AlbumTitle STRING(MAX) ) PRIMARY KEY (SingerId, AlbumId), INTERLEAVE IN PARENT Singers ON DELETE CASCADE" ], encryption_config: { kms_key_name: kms_key_name } puts "Waiting for create database operation to complete" job.wait_until_done! database = database_admin_client.get_database name: db_path puts "Database #{database_id} created with encryption key #{database.encryption_config.kms_key_name}" # [END spanner_create_database_with_encryption_key] end def create_database_with_multiple_kms_keys( project_id:, instance_id:, database_id:, kms_key_names: ) # [START spanner_create_database_with_MR_CMEK] # project_id = "Your Google Cloud project ID" # instance_id = "Your Spanner instance ID" # database_id = "Your Spanner database ID" # kms_key_names = ["key1", "key2", "key3"] require "google/cloud/spanner" require "google/cloud/spanner/admin/database" database_admin_client = Google::Cloud::Spanner::Admin::Database.database_admin instance_path = database_admin_client.instance_path( project: project_id, instance: instance_id ) encryption_config = { kms_key_names: kms_key_names } db_path = database_admin_client.database_path( project: project_id, instance: instance_id, database: database_id ) job = database_admin_client.create_database( parent: instance_path, create_statement: "CREATE DATABASE `#{database_id}`", extra_statements: [ <<~STATEMENT, CREATE TABLE Singers ( SingerId INT64 NOT NULL, FirstName STRING(1024), LastName STRING(1024), SingerInfo BYTES(MAX) ) PRIMARY KEY (SingerId) STATEMENT <<~STATEMENT CREATE TABLE Albums ( SingerId INT64 NOT NULL, AlbumId INT64 NOT NULL, AlbumTitle STRING(MAX) ) PRIMARY KEY (SingerId, AlbumId), INTERLEAVE IN PARENT Singers ON DELETE CASCADE STATEMENT ], encryption_config: encryption_config ) puts "Waiting for create database operation to complete" job.wait_until_done! database = database_admin_client.get_database name: db_path puts "Database #{database_id} created with encryption key " \ "#{database.encryption_config.kms_key_names}" # [END spanner_create_database_with_MR_CMEK] end def create_dml_database project_id:, instance_id:, database_id: require "google/cloud/spanner" require "google/cloud/spanner/admin/database" database_admin_client = Google::Cloud::Spanner::Admin::Database.database_admin instance_path = database_admin_client.instance_path project: project_id, instance: instance_id job = database_admin_client.create_database parent: instance_path, create_statement: "CREATE DATABASE `#{database_id}`", extra_statements: [ "CREATE TABLE Singers ( SingerId INT64 NOT NULL, FirstName STRING(1024), LastName STRING(1024), SingerInfo BYTES(MAX), FullName STRING(2048) AS (ARRAY_TO_STRING([FirstName, LastName], \" \")) STORED ) PRIMARY KEY (SingerId)", "CREATE TABLE Albums ( SingerId INT64 NOT NULL, AlbumId INT64 NOT NULL, AlbumTitle STRING(MAX), MarketingBudget INT64 ) PRIMARY KEY (SingerId, AlbumId), INTERLEAVE IN PARENT Singers ON DELETE CASCADE" ] puts "Waiting for create database operation to complete" job.wait_until_done! puts "Created database #{database_id} on instance #{instance_id}" end def create_table_with_timestamp_column project_id:, instance_id:, database_id: # [START spanner_create_table_with_timestamp_column] # project_id = "Your Google Cloud project ID" # instance_id = "Your Spanner instance ID" # database_id = "Your Spanner database ID" require "google/cloud/spanner" require "google/cloud/spanner/admin/database" database_admin_client = Google::Cloud::Spanner::Admin::Database.database_admin db_path = database_admin_client.database_path project: project_id, instance: instance_id, database: database_id job = database_admin_client.update_database_ddl database: db_path, statements: [ "CREATE TABLE Performances ( SingerId INT64 NOT NULL, VenueId INT64 NOT NULL, EventDate Date, Revenue INT64, LastUpdateTime TIMESTAMP NOT NULL OPTIONS (allow_commit_timestamp=true) ) PRIMARY KEY (SingerId, VenueId, EventDate), INTERLEAVE IN PARENT Singers ON DELETE CASCADE" ] puts "Waiting for update database operation to complete" job.wait_until_done! puts "Created table Performances in #{database_id}" # [END spanner_create_table_with_timestamp_column] end def insert_data project_id:, instance_id:, database_id: # [START spanner_insert_data] # project_id = "Your Google Cloud project ID" # instance_id = "Your Spanner instance ID" # database_id = "Your Spanner database ID" require "google/cloud/spanner" spanner = Google::Cloud::Spanner.new project: project_id client = spanner.client instance_id, database_id client.commit do |c| c.insert "Singers", [ { SingerId: 1, FirstName: "Marc", LastName: "Richards" }, { SingerId: 2, FirstName: "Catalina", LastName: "Smith" }, { SingerId: 3, FirstName: "Alice", LastName: "Trentor" }, { SingerId: 4, FirstName: "Lea", LastName: "Martin" }, { SingerId: 5, FirstName: "David", LastName: "Lomond" } ] c.insert "Albums", [ { SingerId: 1, AlbumId: 1, AlbumTitle: "Total Junk" }, { SingerId: 1, AlbumId: 2, AlbumTitle: "Go, Go, Go" }, { SingerId: 2, AlbumId: 1, AlbumTitle: "Green" }, { SingerId: 2, AlbumId: 2, AlbumTitle: "Forever Hold Your Peace" }, { SingerId: 2, AlbumId: 3, AlbumTitle: "Terrified" } ] end puts "Inserted data" # [END spanner_insert_data] end def insert_dml_data project_id:, instance_id:, database_id: require "google/cloud/spanner" spanner = Google::Cloud::Spanner.new project: project_id client = spanner.client instance_id, database_id client.commit do |c| c.insert "Singers", [ { SingerId: 1, FirstName: "Marc", LastName: "Richards" }, { SingerId: 2, FirstName: "Catalina", LastName: "Smith" }, { SingerId: 3, FirstName: "Alice", LastName: "Trentor" }, { SingerId: 4, FirstName: "Lea", LastName: "Martin" }, { SingerId: 5, FirstName: "David", LastName: "Lomond" } ] c.insert "Albums", [ { SingerId: 1, AlbumId: 1, AlbumTitle: "Total Junk", MarketingBudget: 20_000 }, { SingerId: 1, AlbumId: 2, AlbumTitle: "Go, Go, Go", MarketingBudget: 20_000 }, { SingerId: 2, AlbumId: 1, AlbumTitle: "Green", MarketingBudget: 20_000 }, { SingerId: 2, AlbumId: 2, AlbumTitle: "Forever Hold Your Peace", MarketingBudget: 20_000 }, { SingerId: 2, AlbumId: 3, AlbumTitle: "Terrified", MarketingBudget: 20_000 } ] end puts "Inserted data" end def insert_data_with_timestamp_column project_id:, instance_id:, database_id: # [START spanner_insert_data_with_timestamp_column] # project_id = "Your Google Cloud project ID" # instance_id = "Your Spanner instance ID" # database_id = "Your Spanner database ID" require "google/cloud/spanner" spanner = Google::Cloud::Spanner.new project: project_id client = spanner.client instance_id, database_id # Get commit_timestamp commit_timestamp = client.commit_timestamp client.commit do |c| c.insert "Performances", [ { SingerId: 1, VenueId: 4, EventDate: "2017-10-05", Revenue: 11_000, LastUpdateTime: commit_timestamp }, { SingerId: 1, VenueId: 19, EventDate: "2017-11-02", Revenue: 15_000, LastUpdateTime: commit_timestamp }, { SingerId: 2, VenueId: 42, EventDate: "2017-12-23", Revenue: 7000, LastUpdateTime: commit_timestamp } ] end puts "Inserted data" # [END spanner_insert_data_with_timestamp_column] end def query_data project_id:, instance_id:, database_id: # [START spanner_query_data] # project_id = "Your Google Cloud project ID" # instance_id = "Your Spanner instance ID" # database_id = "Your Spanner database ID" require "google/cloud/spanner" spanner = Google::Cloud::Spanner.new project: project_id client = spanner.client instance_id, database_id client.execute("SELECT SingerId, AlbumId, AlbumTitle FROM Albums").rows.each do |row| puts "#{row[:SingerId]} #{row[:AlbumId]} #{row[:AlbumTitle]}" end # [END spanner_query_data] end def query_data_with_timestamp_column project_id:, instance_id:, database_id: # [START spanner_query_data_with_timestamp_column] # project_id = "Your Google Cloud project ID" # instance_id = "Your Spanner instance ID" # database_id = "Your Spanner database ID" require "google/cloud/spanner" spanner = Google::Cloud::Spanner.new project: project_id client = spanner.client instance_id, database_id client.execute("SELECT SingerId, AlbumId, MarketingBudget, LastUpdateTime FROM Albums ORDER BY LastUpdateTime DESC").rows.each do |row| puts "#{row[:SingerId]} #{row[:AlbumId]} #{row[:MarketingBudget]} #{row[:LastUpdateTime]}" end # [END spanner_query_data_with_timestamp_column] end def read_data project_id:, instance_id:, database_id: # [START spanner_read_data] # project_id = "Your Google Cloud project ID" # instance_id = "Your Spanner instance ID" # database_id = "Your Spanner database ID" require "google/cloud/spanner" spanner = Google::Cloud::Spanner.new project: project_id client = spanner.client instance_id, database_id client.read("Albums", [:SingerId, :AlbumId, :AlbumTitle]).rows.each do |row| puts "#{row[:SingerId]} #{row[:AlbumId]} #{row[:AlbumTitle]}" end # [END spanner_read_data] end def delete_data project_id:, instance_id:, database_id: # [START spanner_delete_data] # project_id = "Your Google Cloud project ID" # instance_id = "Your Spanner instance ID" # database_id = "Your Spanner database ID" require "google/cloud/spanner" spanner = Google::Cloud::Spanner.new project: project_id client = spanner.client instance_id, database_id # Delete individual rows client.delete "Albums", [[2, 1], [2, 3]] # Delete a range of rows where the column key is >=3 and <5 key_range = client.range 3, 5, exclude_end: true client.delete "Singers", key_range # Delete remaining Singers rows, which will also delete the remaining # Albums rows because Albums was defined with ON DELETE CASCADE client.delete "Singers" # [END spanner_delete_data] end def read_stale_data project_id:, instance_id:, database_id: # [START spanner_read_stale_data] # project_id = "Your Google Cloud project ID" # instance_id = "Your Spanner instance ID" # database_id = "Your Spanner database ID" require "google/cloud/spanner" spanner = Google::Cloud::Spanner.new project: project_id client = spanner.client instance_id, database_id # Perform a read with a data staleness of 15 seconds client.snapshot staleness: 15 do |snapshot| snapshot.read("Albums", [:SingerId, :AlbumId, :AlbumTitle]).rows.each do |row| puts "#{row[:SingerId]} #{row[:AlbumId]} #{row[:AlbumTitle]}" end end # [END spanner_read_stale_data] end def create_index project_id:, instance_id:, database_id: # [START spanner_create_index] # project_id = "Your Google Cloud project ID" # instance_id = "Your Spanner instance ID" # database_id = "Your Spanner database ID" require "google/cloud/spanner" require "google/cloud/spanner/admin/database" database_admin_client = Google::Cloud::Spanner::Admin::Database.database_admin db_path = database_admin_client.database_path project: project_id, instance: instance_id, database: database_id job = database_admin_client.update_database_ddl database: db_path, statements: [ "CREATE INDEX AlbumsByAlbumTitle ON Albums(AlbumTitle)" ] puts "Waiting for database update to complete" job.wait_until_done! puts "Added the AlbumsByAlbumTitle index" # [END spanner_create_index] end def create_storing_index project_id:, instance_id:, database_id: # [START spanner_create_storing_index] # project_id = "Your Google Cloud project ID" # instance_id = "Your Spanner instance ID" # database_id = "Your Spanner database ID" require "google/cloud/spanner" require "google/cloud/spanner/admin/database" database_admin_client = Google::Cloud::Spanner::Admin::Database.database_admin db_path = database_admin_client.database_path project: project_id, instance: instance_id, database: database_id job = database_admin_client.update_database_ddl database: db_path, statements: [ "CREATE INDEX AlbumsByAlbumTitle2 ON Albums(AlbumTitle) STORING (MarketingBudget)" ] puts "Waiting for database update to complete" job.wait_until_done! puts "Added the AlbumsByAlbumTitle2 storing index" # [END spanner_create_storing_index] end def add_column project_id:, instance_id:, database_id: # [START spanner_add_column] # project_id = "Your Google Cloud project ID" # instance_id = "Your Spanner instance ID" # database_id = "Your Spanner database ID" require "google/cloud/spanner" require "google/cloud/spanner/admin/database" database_admin_client = Google::Cloud::Spanner::Admin::Database.database_admin db_path = database_admin_client.database_path project: project_id, instance: instance_id, database: database_id job = database_admin_client.update_database_ddl database: db_path, statements: [ "ALTER TABLE Albums ADD COLUMN MarketingBudget INT64" ] puts "Waiting for database update to complete" job.wait_until_done! puts "Added the MarketingBudget column" # [END spanner_add_column] end def add_timestamp_column project_id:, instance_id:, database_id: # [START spanner_add_timestamp_column] # project_id = "Your Google Cloud project ID" # instance_id = "Your Spanner instance ID" # database_id = "Your Spanner database ID" require "google/cloud/spanner" require "google/cloud/spanner/admin/database" database_admin_client = Google::Cloud::Spanner::Admin::Database.database_admin db_path = database_admin_client.database_path project: project_id, instance: instance_id, database: database_id job = database_admin_client.update_database_ddl database: db_path, statements: [ "ALTER TABLE Albums ADD COLUMN LastUpdateTime TIMESTAMP OPTIONS (allow_commit_timestamp=true)" ] puts "Waiting for database update to complete" job.wait_until_done! puts "Added the LastUpdateTime as a commit timestamp column in Albums table" # [END spanner_add_timestamp_column] end def add_numeric_column project_id:, instance_id:, database_id: # [START spanner_add_numeric_column] # project_id = "Your Google Cloud project ID" # instance_id = "Your Spanner instance ID" # database_id = "Your Spanner database ID" require "google/cloud/spanner" require "google/cloud/spanner/admin/database" database_admin_client = Google::Cloud::Spanner::Admin::Database.database_admin db_path = database_admin_client.database_path project: project_id, instance: instance_id, database: database_id job = database_admin_client.update_database_ddl database: db_path, statements: [ "ALTER TABLE Venues ADD COLUMN Revenue NUMERIC" ] puts "Waiting for database update to complete" job.wait_until_done! puts "Added the Revenue as a numeric column in Venues table" # [END spanner_add_numeric_column] end def write_struct_data project_id:, instance_id:, database_id: # [START spanner_write_data_for_struct_queries] # project_id = "Your Google Cloud project ID" # instance_id = "Your Spanner instance ID" # database_id = "Your Spanner database ID" require "google/cloud/spanner" spanner = Google::Cloud::Spanner.new project: project_id client = spanner.client instance_id, database_id client.commit do |c| c.insert "Singers", [ { SingerId: 6, FirstName: "Elena", LastName: "Campbell" }, { SingerId: 7, FirstName: "Gabriel", LastName: "Wright" }, { SingerId: 8, FirstName: "Benjamin", LastName: "Martinez" }, { SingerId: 9, FirstName: "Hannah", LastName: "Harris" } ] end puts "Inserted Data for Struct queries" # [END spanner_write_data_for_struct_queries] end def query_with_struct project_id:, instance_id:, database_id: # [START spanner_create_struct_with_data] name_struct = { FirstName: "Elena", LastName: "Campbell" } # [END spanner_create_struct_with_data] # [START spanner_query_data_with_struct] # project_id = "Your Google Cloud project ID" # instance_id = "Your Spanner instance ID" # database_id = "Your Spanner database ID" require "google/cloud/spanner" spanner = Google::Cloud::Spanner.new project: project_id client = spanner.client instance_id, database_id client.execute( "SELECT SingerId FROM Singers WHERE " + "(FirstName, LastName) = @name", params: { name: name_struct } ).rows.each do |row| puts row[:SingerId] end # [END spanner_query_data_with_struct] end def query_with_array_of_struct project_id:, instance_id:, database_id: # project_id = "Your Google Cloud project ID" # instance_id = "Your Spanner instance ID" # database_id = "Your Spanner database ID" require "google/cloud/spanner" spanner = Google::Cloud::Spanner.new project: project_id client = spanner.client instance_id, database_id # [START spanner_create_user_defined_struct] name_type = client.fields FirstName: :STRING, LastName: :STRING # [END spanner_create_user_defined_struct] # [START spanner_create_array_of_struct_with_data] band_members = [name_type.struct(["Elena", "Campbell"]), name_type.struct(["Gabriel", "Wright"]), name_type.struct(["Benjamin", "Martinez"])] # [END spanner_create_array_of_struct_with_data] # [START spanner_query_data_with_array_of_struct] client.execute( "SELECT SingerId FROM Singers WHERE " + "STRUCT<FirstName STRING, LastName STRING>(FirstName, LastName) IN UNNEST(@names)", params: { names: band_members } ).rows.each do |row| puts row[:SingerId] end # [END spanner_query_data_with_array_of_struct] end def query_struct_field project_id:, instance_id:, database_id: # [START spanner_field_access_on_struct_parameters] # project_id = "Your Google Cloud project ID" # instance_id = "Your Spanner instance ID" # database_id = "Your Spanner database ID" require "google/cloud/spanner" spanner = Google::Cloud::Spanner.new project: project_id client = spanner.client instance_id, database_id name_struct = { FirstName: "Elena", LastName: "Campbell" } client.execute( "SELECT SingerId FROM Singers WHERE FirstName = @name.FirstName", params: { name: name_struct } ).rows.each do |row| puts row[:SingerId] end # [END spanner_field_access_on_struct_parameters] end def query_nested_struct_field project_id:, instance_id:, database_id: # [START spanner_field_access_on_nested_struct_parameters] # project_id = "Your Google Cloud project ID" # instance_id = "Your Spanner instance ID" # database_id = "Your Spanner database ID" require "google/cloud/spanner" spanner = Google::Cloud::Spanner.new project: project_id client = spanner.client instance_id, database_id name_type = client.fields FirstName: :STRING, LastName: :STRING song_info_struct = { SongName: "Imagination", ArtistNames: [name_type.struct(["Elena", "Campbell"]), name_type.struct(["Hannah", "Harris"])] } client.execute( "SELECT SingerId, @song_info.SongName " \ "FROM Singers WHERE STRUCT<FirstName STRING, LastName STRING>(FirstName, LastName) " \ "IN UNNEST(@song_info.ArtistNames)", params: { song_info: song_info_struct } ).rows.each do |row| puts (row[:SingerId]), (row[:SongName]) end # [END spanner_field_access_on_nested_struct_parameters] end def update_data project_id:, instance_id:, database_id: # [START spanner_update_data] # project_id = "Your Google Cloud project ID" # instance_id = "Your Spanner instance ID" # database_id = "Your Spanner database ID" require "google/cloud/spanner" spanner = Google::Cloud::Spanner.new project: project_id client = spanner.client instance_id, database_id client.commit do |c| c.update "Albums", [ { SingerId: 1, AlbumId: 1, MarketingBudget: 100_000 }, { SingerId: 2, AlbumId: 2, MarketingBudget: 500_000 } ] end puts "Updated data" # [END spanner_update_data] end def update_data_with_timestamp_column project_id:, instance_id:, database_id: # [START spanner_update_data_with_timestamp_column] # project_id = "Your Google Cloud project ID" # instance_id = "Your Spanner instance ID" # database_id = "Your Spanner database ID" require "google/cloud/spanner" spanner = Google::Cloud::Spanner.new project: project_id client = spanner.client instance_id, database_id commit_timestamp = client.commit_timestamp client.commit do |c| c.update "Albums", [ { SingerId: 1, AlbumId: 1, MarketingBudget: 100_000, LastUpdateTime: commit_timestamp }, { SingerId: 2, AlbumId: 2, MarketingBudget: 750_000, LastUpdateTime: commit_timestamp } ] end puts "Updated data" # [END spanner_update_data_with_timestamp_column] end def update_data_with_numeric_column project_id:, instance_id:, database_id: # [START spanner_update_data_with_numeric_column] # project_id = "Your Google Cloud project ID" # instance_id = "Your Spanner instance ID" # database_id = "Your Spanner database ID" require "google/cloud/spanner" spanner = Google::Cloud::Spanner.new project: project_id client = spanner.client instance_id, database_id client.commit do |c| c.update "Venues", [ { VenueId: 4, Revenue: "35000" }, { VenueId: 19, Revenue: "104500" }, { VenueId: 42, Revenue: "99999999999999999999999999999.99" } ] end puts "Updated data" # [END spanner_update_data_with_numeric_column] end def query_data_with_new_column project_id:, instance_id:, database_id: # [START spanner_query_data_with_new_column] # project_id = "Your Google Cloud project ID" # instance_id = "Your Spanner instance ID" # database_id = "Your Spanner database ID" require "google/cloud/spanner" spanner = Google::Cloud::Spanner.new project: project_id client = spanner.client instance_id, database_id client.execute("SELECT SingerId, AlbumId, MarketingBudget FROM Albums").rows.each do |row| puts "#{row[:SingerId]} #{row[:AlbumId]} #{row[:MarketingBudget]}" end # [END spanner_query_data_with_new_column] end def read_write_transaction project_id:, instance_id:, database_id: # [START spanner_read_write_transaction] # project_id = "Your Google Cloud project ID" # instance_id = "Your Spanner instance ID" # database_id = "Your Spanner database ID" require "google/cloud/spanner" spanner = Google::Cloud::Spanner.new project: project_id client = spanner.client instance_id, database_id transfer_amount = 200_000 client.transaction do |transaction| first_album = transaction.read("Albums", [:MarketingBudget], keys: [[1, 1]]).rows.first second_album = transaction.read("Albums", [:MarketingBudget], keys: [[2, 2]]).rows.first raise "The second album does not have enough funds to transfer" if second_album[:MarketingBudget] < transfer_amount new_first_album_budget = first_album[:MarketingBudget] + transfer_amount new_second_album_budget = second_album[:MarketingBudget] - transfer_amount transaction.update "Albums", [ { SingerId: 1, AlbumId: 1, MarketingBudget: new_first_album_budget }, { SingerId: 2, AlbumId: 2, MarketingBudget: new_second_album_budget } ] end puts "Transaction complete" # [END spanner_read_write_transaction] end def query_data_with_index project_id:, instance_id:, database_id:, start_title: "Ardvark", end_title: "Goo" # [START spanner_query_data_with_index] # project_id = "Your Google Cloud project ID" # instance_id = "Your Spanner instance ID" # database_id = "Your Spanner database ID" # start_title = "An album title to start with such as 'Ardvark'" # end_title = "An album title to end with such as 'Goo'" require "google/cloud/spanner" spanner = Google::Cloud::Spanner.new project: project_id client = spanner.client instance_id, database_id sql_query = "SELECT AlbumId, AlbumTitle, MarketingBudget FROM Albums@{FORCE_INDEX=AlbumsByAlbumTitle} WHERE AlbumTitle >= @start_title AND AlbumTitle < @end_title" params = { start_title: start_title, end_title: end_title } param_types = { start_title: :STRING, end_title: :STRING } client.execute(sql_query, params: params, types: param_types).rows.each do |row| puts "#{row[:AlbumId]} #{row[:AlbumTitle]} #{row[:MarketingBudget]}" end # [END spanner_query_data_with_index] end def read_data_with_index project_id:, instance_id:, database_id: # [START spanner_read_data_with_index] # project_id = "Your Google Cloud project ID" # instance_id = "Your Spanner instance ID" # database_id = "Your Spanner database ID" require "google/cloud/spanner" spanner = Google::Cloud::Spanner.new project: project_id client = spanner.client instance_id, database_id result = client.read "Albums", [:AlbumId, :AlbumTitle], index: "AlbumsByAlbumTitle" result.rows.each do |row| puts "#{row[:AlbumId]} #{row[:AlbumTitle]}" end # [END spanner_read_data_with_index] end def read_data_with_storing_index project_id:, instance_id:, database_id: # [START spanner_read_data_with_storing_index] # project_id = "Your Google Cloud project ID" # instance_id = "Your Spanner instance ID" # database_id = "Your Spanner database ID" require "google/cloud/spanner" spanner = Google::Cloud::Spanner.new project: project_id client = spanner.client instance_id, database_id result = client.read "Albums", [:AlbumId, :AlbumTitle, :MarketingBudget], index: "AlbumsByAlbumTitle2" result.rows.each do |row| puts "#{row[:AlbumId]} #{row[:AlbumTitle]} #{row[:MarketingBudget]}" end # [END spanner_read_data_with_storing_index] end def read_only_transaction project_id:, instance_id:, database_id: # [START spanner_read_only_transaction] # project_id = "Your Google Cloud project ID" # instance_id = "Your Spanner instance ID" # database_id = "Your Spanner database ID" require "google/cloud/spanner" spanner = Google::Cloud::Spanner.new project: project_id client = spanner.client instance_id, database_id client.snapshot do |snapshot| snapshot.execute("SELECT SingerId, AlbumId, AlbumTitle FROM Albums").rows.each do |row| puts "#{row[:AlbumId]} #{row[:AlbumTitle]} #{row[:SingerId]}" end # Even if changes occur in-between the reads, the transaction ensures that # both return the same data. snapshot.read("Albums", [:AlbumId, :AlbumTitle, :SingerId]).rows.each do |row| puts "#{row[:AlbumId]} #{row[:AlbumTitle]} #{row[:SingerId]}" end end # [END spanner_read_only_transaction] end def spanner_batch_client project_id:, instance_id:, database_id: # [START spanner_batch_client] # project_id = "Your Google Cloud project ID" # instance_id = "Your Spanner instance ID" # database_id = "Your Spanner database ID" require "google/cloud/spanner" # Prepare a thread pool with number of processors processor_count = Concurrent.processor_count thread_pool = Concurrent::FixedThreadPool.new processor_count # Prepare AtomicFixnum to count total records using multiple threads total_records = Concurrent::AtomicFixnum.new # Create a new Spanner batch client spanner = Google::Cloud::Spanner.new project: project_id batch_client = spanner.batch_client instance_id, database_id # Get a strong timestamp bound batch_snapshot batch_snapshot = batch_client.batch_snapshot strong: true # Get partitions for specified query # data_boost_enabled option is an optional parameter which can be used for partition read # and query to execute the request via spanner independent compute resources. partitions = batch_snapshot.partition_query "SELECT SingerId, FirstName, LastName FROM Singers", data_boost_enabled: true total_partitions = partitions.size # Enqueue a new thread pool job partitions.each_with_index do |partition, _partition_index| thread_pool.post do # Increment total_records per new row batch_snapshot.execute_partition(partition).rows.each do |_row| total_records.increment end end end # Wait for queued jobs to complete thread_pool.shutdown thread_pool.wait_for_termination # Close the client connection and release resources. batch_snapshot.close # Collect statistics for batch query average_records_per_partition = 0.0 if total_partitions != 0 average_records_per_partition = total_records.value / total_partitions.to_f end puts "Total Partitions: #{total_partitions}" puts "Total Records: #{total_records.value}" puts "Average records per Partition: #{average_records_per_partition}" # [END spanner_batch_client] end def insert_using_dml project_id:, instance_id:, database_id: # [START spanner_dml_standard_insert] # project_id = "Your Google Cloud project ID" # instance_id = "Your Spanner instance ID" # database_id = "Your Spanner database ID" require "google/cloud/spanner" spanner = Google::Cloud::Spanner.new project: project_id client = spanner.client instance_id, database_id row_count = 0 client.transaction do |transaction| row_count = transaction.execute_update( "INSERT INTO Singers (SingerId, FirstName, LastName) VALUES (10, 'Virginia', 'Watson')" ) end puts "#{row_count} record inserted." # [END spanner_dml_standard_insert] end def update_using_dml project_id:, instance_id:, database_id: # [START spanner_dml_standard_update] # project_id = "Your Google Cloud project ID" # instance_id = "Your Spanner instance ID" # database_id = "Your Spanner database ID" require "google/cloud/spanner" spanner = Google::Cloud::Spanner.new project: project_id client = spanner.client instance_id, database_id row_count = 0 client.transaction do |transaction| row_count = transaction.execute_update( "UPDATE Albums SET MarketingBudget = MarketingBudget * 2 WHERE SingerId = 1 and AlbumId = 1" ) end puts "#{row_count} record updated." # [END spanner_dml_standard_update] end def delete_using_dml project_id:, instance_id:, database_id: # [START spanner_dml_standard_delete] # project_id = "Your Google Cloud project ID" # instance_id = "Your Spanner instance ID" # database_id = "Your Spanner database ID" require "google/cloud/spanner" spanner = Google::Cloud::Spanner.new project: project_id client = spanner.client instance_id, database_id row_count = 0 client.transaction do |transaction| row_count = transaction.execute_update( "DELETE FROM Singers WHERE FirstName = 'Alice'" ) end puts "#{row_count} record deleted." # [END spanner_dml_standard_delete] end def update_using_dml_with_timestamp project_id:, instance_id:, database_id: # [START spanner_dml_standard_update_with_timestamp] # project_id = "Your Google Cloud project ID" # instance_id = "Your Spanner instance ID" # database_id = "Your Spanner database ID" require "google/cloud/spanner" spanner = Google::Cloud::Spanner.new project: project_id client = spanner.client instance_id, database_id row_count = 0 client.transaction do |transaction| row_count = transaction.execute_update( "UPDATE Albums SET LastUpdateTime = PENDING_COMMIT_TIMESTAMP() WHERE SingerId = 1" ) end puts "#{row_count} records updated." # [END spanner_dml_standard_update_with_timestamp] end def write_and_read_using_dml project_id:, instance_id:, database_id: # [START spanner_dml_write_then_read] # project_id = "Your Google Cloud project ID" # instance_id = "Your Spanner instance ID" # database_id = "Your Spanner database ID" require "google/cloud/spanner" spanner = Google::Cloud::Spanner.new project: project_id client = spanner.client instance_id, database_id row_count = 0 client.transaction do |transaction| row_count = transaction.execute_update( "INSERT INTO Singers (SingerId, FirstName, LastName) VALUES (11, 'Timothy', 'Campbell')" ) puts "#{row_count} record updated." transaction.execute("SELECT FirstName, LastName FROM Singers WHERE SingerId = 11").rows.each do |row| puts "#{row[:FirstName]} #{row[:LastName]}" end end # [END spanner_dml_write_then_read] end def update_using_dml_with_struct project_id:, instance_id:, database_id: # [START spanner_dml_structs] # project_id = "Your Google Cloud project ID" # instance_id = "Your Spanner instance ID" # database_id = "Your Spanner database ID" require "google/cloud/spanner" spanner = Google::Cloud::Spanner.new project: project_id client = spanner.client instance_id, database_id row_count = 0 name_struct = { FirstName: "Timothy", LastName: "Campbell" } client.transaction do |transaction| row_count = transaction.execute_update( "UPDATE Singers SET LastName = 'Grant' WHERE STRUCT<FirstName STRING, LastName STRING>(FirstName, LastName) = @name", params: { name: name_struct } ) end puts "#{row_count} record updated." # [END spanner_dml_structs] end def write_using_dml project_id:, instance_id:, database_id: # [START spanner_dml_getting_started_insert] # project_id = "Your Google Cloud project ID" # instance_id = "Your Spanner instance ID" # database_id = "Your Spanner database ID" require "google/cloud/spanner" spanner = Google::Cloud::Spanner.new project: project_id client = spanner.client instance_id, database_id row_count = 0 client.transaction do |transaction| row_count = transaction.execute_update( "INSERT INTO Singers (SingerId, FirstName, LastName) VALUES (12, 'Melissa', 'Garcia'), (13, 'Russell', 'Morales'), (14, 'Jacqueline', 'Long'), (15, 'Dylan', 'Shaw'), (16, 'Billie', 'Eillish'), (17, 'Judy', 'Garland'), (18, 'Taylor', 'Swift'), (19, 'Miley', 'Cyrus'), (20, 'Michael', 'Jackson'), (21, 'Ariana', 'Grande'), (22, 'Elvis', 'Presley'), (23, 'Kanye', 'West'), (24, 'Lady', 'Gaga'), (25, 'Nick', 'Jonas')" ) end puts "#{row_count} records inserted." # [END spanner_dml_getting_started_insert] end def query_with_parameter project_id:, instance_id:, database_id: # [START spanner_query_with_parameter] # project_id = "Your Google Cloud project ID" # instance_id = "Your Spanner instance ID" # database_id = "Your Spanner database ID" require "google/cloud/spanner" spanner = Google::Cloud::Spanner.new project: project_id client = spanner.client instance_id, database_id sql_query = "SELECT SingerId, FirstName, LastName FROM Singers WHERE LastName = @lastName" params = { lastName: "Garcia" } param_types = { lastName: :STRING } client.execute(sql_query, params: params, types: param_types).rows.each do |row| puts "#{row[:SingerId]} #{row[:FirstName]} #{row[:LastName]}" end # [END spanner_query_with_parameter] end def query_with_numeric_parameter project_id:, instance_id:, database_id: # [START spanner_query_with_numeric_parameter] # project_id = "Your Google Cloud project ID" # instance_id = "Your Spanner instance ID" # database_id = "Your Spanner database ID" require "google/cloud/spanner" require "bigdecimal" spanner = Google::Cloud::Spanner.new project: project_id client = spanner.client instance_id, database_id sql_query = "SELECT VenueId, Revenue FROM Venues WHERE Revenue < @revenue" params = { revenue: BigDecimal("100000") } param_types = { revenue: :NUMERIC } client.execute(sql_query, params: params, types: param_types).rows.each do |row| puts "#{row[:VenueId]} #{row[:Revenue]}" end # [END spanner_query_with_numeric_parameter] end def write_with_transaction_using_dml project_id:, instance_id:, database_id: # [START spanner_dml_getting_started_update] # project_id = "Your Google Cloud project ID" # instance_id = "Your Spanner instance ID" # database_id = "Your Spanner database ID" require "google/cloud/spanner" spanner = Google::Cloud::Spanner.new project: project_id client = spanner.client instance_id, database_id transfer_amount = 200_000 client.transaction do |transaction| first_album = transaction.execute( "SELECT MarketingBudget from Albums WHERE SingerId = 1 and AlbumId = 1" ).rows.first second_album = transaction.execute( "SELECT MarketingBudget from Albums WHERE SingerId = 2 and AlbumId = 2" ).rows.first raise "The second album does not have enough funds to transfer" if second_album[:MarketingBudget] < transfer_amount new_first_album_budget = first_album[:MarketingBudget] + transfer_amount new_second_album_budget = second_album[:MarketingBudget] - transfer_amount transaction.execute_update( "UPDATE Albums SET MarketingBudget = @albumBudget WHERE SingerId = 1 and AlbumId = 1", params: { albumBudget: new_first_album_budget } ) transaction.execute_update( "UPDATE Albums SET MarketingBudget = @albumBudget WHERE SingerId = 2 and AlbumId = 2", params: { albumBudget: new_second_album_budget } ) end puts "Transaction complete" # [END spanner_dml_getting_started_update] end def update_using_partitioned_dml project_id:, instance_id:, database_id: # [START spanner_dml_partitioned_update] # project_id = "Your Google Cloud project ID" # instance_id = "Your Spanner instance ID" # database_id = "Your Spanner database ID" require "google/cloud/spanner" spanner = Google::Cloud::Spanner.new project: project_id client = spanner.client instance_id, database_id row_count = client.execute_partition_update( "UPDATE Albums SET MarketingBudget = 100000 WHERE SingerId > 1" ) puts "#{row_count} records updated." # [END spanner_dml_partitioned_update] end def delete_using_partitioned_dml project_id:, instance_id:, database_id: # [START spanner_dml_partitioned_delete] # project_id = "Your Google Cloud project ID" # instance_id = "Your Spanner instance ID" # database_id = "Your Spanner database ID" require "google/cloud/spanner" spanner = Google::Cloud::Spanner.new project: project_id client = spanner.client instance_id, database_id row_count = client.execute_partition_update( "DELETE FROM Singers WHERE SingerId > 10" ) puts "#{row_count} records deleted." # [END spanner_dml_partitioned_delete] end def update_using_batch_dml project_id:, instance_id:, database_id: # [START spanner_dml_batch_update] # project_id = "Your Google Cloud project ID" # instance_id = "Your Spanner instance ID" # database_id = "Your Spanner database ID" require "google/cloud/spanner" spanner = Google::Cloud::Spanner.new project: project_id client = spanner.client instance_id, database_id row_counts = nil client.transaction do |transaction| row_counts = transaction.batch_update do |b| b.batch_update( "INSERT INTO Albums " \ "(SingerId, AlbumId, AlbumTitle, MarketingBudget) " \ "VALUES (1, 3, 'Test Album Title', 10000)" ) b.batch_update( "UPDATE Albums " \ "SET MarketingBudget = MarketingBudget * 2 " \ "WHERE SingerId = 1 and AlbumId = 3" ) end end statement_count = row_counts.count puts "Executed #{statement_count} SQL statements using Batch DML." # [END spanner_dml_batch_update] end def create_table_with_datatypes project_id:, instance_id:, database_id: # [START spanner_create_table_with_datatypes] # project_id = "Your Google Cloud project ID" # instance_id = "Your Spanner instance ID" # database_id = "Your Spanner database ID" require "google/cloud/spanner" spanner = Google::Cloud::Spanner.new project: project_id client = spanner.database instance_id, database_id job = client.update statements: [ "CREATE TABLE Venues ( VenueId INT64 NOT NULL, VenueName STRING(100), VenueInfo BYTES(MAX), Capacity INT64, AvailableDates ARRAY<DATE>, LastContactDate DATE, OutdoorVenue BOOL, PopularityScore FLOAT64, LastUpdateTime TIMESTAMP NOT NULL OPTIONS (allow_commit_timestamp=true) ) PRIMARY KEY (VenueId)" ] puts "Waiting for update database operation to complete" job.wait_until_done! puts "Created table Venues in #{database_id}" # [END spanner_create_table_with_datatypes] end def write_datatypes_data project_id:, instance_id:, database_id: # [START spanner_insert_datatypes_data] # project_id = "Your Google Cloud project ID" # instance_id = "Your Spanner instance ID" # database_id = "Your Spanner database ID" require "google/cloud/spanner" spanner = Google::Cloud::Spanner.new project: project_id client = spanner.client instance_id, database_id # Get commit_timestamp commit_timestamp = client.commit_timestamp client.commit do |c| c.insert "Venues", [ { VenueId: 4, VenueName: "Venue 4", VenueInfo: StringIO.new("Hello World 1"), Capacity: 1_800, AvailableDates: ["2020-12-01", "2020-12-02", "2020-12-03"], LastContactDate: "2018-09-02", OutdoorVenue: false, PopularityScore: 0.85543, LastUpdateTime: commit_timestamp }, { VenueId: 19, VenueName: "Venue 19", VenueInfo: StringIO.new("Hello World 2"), Capacity: 6_300, AvailableDates: ["2020-11-01", "2020-11-05", "2020-11-15"], LastContactDate: "2019-01-15", OutdoorVenue: true, PopularityScore: 0.98716, LastUpdateTime: commit_timestamp }, { VenueId: 42, VenueName: "Venue 42", VenueInfo: StringIO.new("Hello World 3"), Capacity: 3_000, AvailableDates: ["2020-10-01", "2020-10-07"], LastContactDate: "2018-10-01", OutdoorVenue: false, PopularityScore: 0.72598, LastUpdateTime: commit_timestamp } ] end puts "Inserted data" # [END spanner_insert_datatypes_data] end def query_with_array project_id:, instance_id:, database_id: # [START spanner_query_with_array_parameter] # project_id = "Your Google Cloud project ID" # instance_id = "Your Spanner instance ID" # database_id = "Your Spanner database ID" require "google/cloud/spanner" spanner = Google::Cloud::Spanner.new project: project_id client = spanner.client instance_id, database_id sql_query = "SELECT VenueId, VenueName, AvailableDate FROM Venues v, UNNEST(v.AvailableDates) as AvailableDate WHERE AvailableDate in UNNEST(@available_dates)" params = { available_dates: ["2020-10-01", "2020-11-01"] } param_types = { available_dates: [:DATE] } client.execute(sql_query, params: params, types: param_types).rows.each do |row| puts "#{row[:VenueId]} #{row[:VenueName]} #{row[:AvailableDate]}" end # [END spanner_query_with_array_parameter] end def query_with_bool project_id:, instance_id:, database_id: # [START spanner_query_with_bool_parameter] # project_id = "Your Google Cloud project ID" # instance_id = "Your Spanner instance ID" # database_id = "Your Spanner database ID" require "google/cloud/spanner" spanner = Google::Cloud::Spanner.new project: project_id client = spanner.client instance_id, database_id sql_query = "SELECT VenueId, VenueName, OutdoorVenue FROM Venues WHERE OutdoorVenue = @outdoor_venue" params = { outdoor_venue: true } param_types = { outdoor_venue: :BOOL } client.execute(sql_query, params: params, types: param_types).rows.each do |row| puts "#{row[:VenueId]} #{row[:VenueName]} #{row[:OutdoorVenue]}" end # [END spanner_query_with_bool_parameter] end def query_with_bytes project_id:, instance_id:, database_id: # [START spanner_query_with_bytes_parameter] # project_id = "Your Google Cloud project ID" # instance_id = "Your Spanner instance ID" # database_id = "Your Spanner database ID" require "google/cloud/spanner" spanner = Google::Cloud::Spanner.new project: project_id client = spanner.client instance_id, database_id example_bytes = StringIO.new "Hello World 1" sql_query = "SELECT VenueId, VenueName FROM Venues WHERE VenueInfo = @venue_info" params = { venue_info: example_bytes } param_types = { venue_info: :BYTES } client.execute(sql_query, params: params, types: param_types).rows.each do |row| puts "#{row[:VenueId]} #{row[:VenueName]}" end # [END spanner_query_with_bytes_parameter] end def query_with_date project_id:, instance_id:, database_id: # [START spanner_query_with_date_parameter] # project_id = "Your Google Cloud project ID" # instance_id = "Your Spanner instance ID" # database_id = "Your Spanner database ID" require "google/cloud/spanner" spanner = Google::Cloud::Spanner.new project: project_id client = spanner.client instance_id, database_id sql_query = "SELECT VenueId, VenueName, LastContactDate FROM Venues WHERE LastContactDate < @last_contact_date" params = { last_contact_date: "2019-01-01" } param_types = { last_contact_date: :DATE } client.execute(sql_query, params: params, types: param_types).rows.each do |row| puts "#{row[:VenueId]} #{row[:VenueName]} #{row[:LastContactDate]}" end # [END spanner_query_with_date_parameter] end def query_with_float project_id:, instance_id:, database_id: # [START spanner_query_with_float_parameter] # project_id = "Your Google Cloud project ID" # instance_id = "Your Spanner instance ID" # database_id = "Your Spanner database ID" require "google/cloud/spanner" spanner = Google::Cloud::Spanner.new project: project_id client = spanner.client instance_id, database_id sql_query = "SELECT VenueId, VenueName, PopularityScore FROM Venues WHERE PopularityScore > @popularity_score" params = { popularity_score: 0.8 } param_types = { popularity_score: :FLOAT64 } client.execute(sql_query, params: params, types: param_types).rows.each do |row| puts "#{row[:VenueId]} #{row[:VenueName]} #{row[:PopularityScore]}" end # [END spanner_query_with_float_parameter] end def query_with_int project_id:, instance_id:, database_id: # [START spanner_query_with_int_parameter] # project_id = "Your Google Cloud project ID" # instance_id = "Your Spanner instance ID" # database_id = "Your Spanner database ID" require "google/cloud/spanner" spanner = Google::Cloud::Spanner.new project: project_id client = spanner.client instance_id, database_id sql_query = "SELECT VenueId, VenueName, Capacity FROM Venues WHERE Capacity >= @capacity" params = { capacity: 3_000 } param_types = { capacity: :INT64 } client.execute(sql_query, params: params, types: param_types).rows.each do |row| puts "#{row[:VenueId]} #{row[:VenueName]} #{row[:Capacity]}" end # [END spanner_query_with_int_parameter] end def query_with_string project_id:, instance_id:, database_id: # [START spanner_query_with_string_parameter] # project_id = "Your Google Cloud project ID" # instance_id = "Your Spanner instance ID" # database_id = "Your Spanner database ID" require "google/cloud/spanner" spanner = Google::Cloud::Spanner.new project: project_id client = spanner.client instance_id, database_id sql_query = "SELECT VenueId, VenueName FROM Venues WHERE VenueName = @venue_name" params = { venue_name: "Venue 42" } param_types = { venue_name: :STRING } client.execute(sql_query, params: params, types: param_types).rows.each do |row| puts "#{row[:VenueId]} #{row[:VenueName]}" end # [END spanner_query_with_string_parameter] end def query_with_timestamp project_id:, instance_id:, database_id: # [START spanner_query_with_timestamp_parameter] # project_id = "Your Google Cloud project ID" # instance_id = "Your Spanner instance ID" # database_id = "Your Spanner database ID" require "google/cloud/spanner" spanner = Google::Cloud::Spanner.new project: project_id client = spanner.client instance_id, database_id example_timestamp = DateTime.now sql_query = "SELECT VenueId, VenueName, LastUpdateTime FROM Venues WHERE LastUpdateTime < @last_update_time" params = { last_update_time: example_timestamp } param_types = { last_update_time: :TIMESTAMP } client.execute(sql_query, params: params, types: param_types).rows.each do |row| puts "#{row[:VenueId]} #{row[:VenueName]} #{row[:LastUpdateTime]}" end # [END spanner_query_with_timestamp_parameter] end def query_with_query_options project_id:, instance_id:, database_id: # [START spanner_query_with_query_options] # project_id = "Your Google Cloud project ID" # instance_id = "Your Spanner instance ID" # database_id = "Your Spanner database ID" require "google/cloud/spanner" spanner = Google::Cloud::Spanner.new project: project_id client = spanner.client instance_id, database_id sql_query = "SELECT VenueId, VenueName, LastUpdateTime FROM Venues" query_options = { optimizer_version: "1", # The list of available statistics packagebs can be # found by querying the "INFORMATION_SCHEMA.SPANNER_STATISTICS" # table. optimizer_statistics_package: "latest" } client.execute(sql_query, query_options: query_options).rows.each do |row| puts "#{row[:VenueId]} #{row[:VenueName]} #{row[:LastUpdateTime]}" end # [END spanner_query_with_query_options] end def create_client_with_query_options project_id:, instance_id:, database_id: # [START spanner_create_client_with_query_options] # project_id = "Your Google Cloud project ID" # instance_id = "Your Spanner instance ID" # database_id = "Your Spanner database ID" require "google/cloud/spanner" query_options = { optimizer_version: "1", # The list of available statistics packages can be # found by querying the "INFORMATION_SCHEMA.SPANNER_STATISTICS" # table. optimizer_statistics_package: "latest" } spanner = Google::Cloud::Spanner.new project: project_id client = spanner.client instance_id, database_id, query_options: query_options sql_query = "SELECT VenueId, VenueName, LastUpdateTime FROM Venues" client.execute(sql_query).rows.each do |row| puts "#{row[:VenueId]} #{row[:VenueName]} #{row[:LastUpdateTime]}" end # [END spanner_create_client_with_query_options] end def write_read_bool_array project_id:, instance_id:, database_id: # [START spanner_write_read_bool_array] # project_id = "Your Google Cloud project ID" # instance_id = "Your Spanner instance ID" # database_id = "Your Spanner database ID" require "google/cloud/spanner" require "google/cloud/spanner/admin/database" require "securerandom" database_admin_client = Google::Cloud::Spanner::Admin::Database.database_admin db_path = database_admin_client.database_path project: project_id, instance: instance_id, database: database_id job = database_admin_client.update_database_ddl database: db_path, statements: [ "CREATE TABLE Boxes ( BoxId STRING(36) NOT NULL, Heights ARRAY<INT64>, Weights ARRAY<FLOAT64>, ErrorChecks ARRAY<BOOL> ) PRIMARY KEY (BoxId)" ] job.wait_until_done! spanner = Google::Cloud::Spanner.new project: project_id client = spanner.client instance_id, database_id box_id = SecureRandom.uuid client.insert "Boxes", [{ BoxId: box_id, ErrorChecks: [true, false, true] }] results = client.read "Boxes", [:BoxId, :ErrorChecks], keys: box_id results.rows.each do |row| puts row["ErrorChecks"] end # [END spanner_write_read_bool_array] end def write_read_empty_int64_array project_id:, instance_id:, database_id: # [START spanner_write_read_empty_int64_array] # project_id = "Your Google Cloud project ID" # instance_id = "Your Spanner instance ID" # database_id = "Your Spanner database ID" require "google/cloud/spanner" require "google/cloud/spanner/admin/database" require "securerandom" database_admin_client = Google::Cloud::Spanner::Admin::Database.database_admin db_path = database_admin_client.database_path project: project_id, instance: instance_id, database: database_id job = database_admin_client.update_database_ddl database: db_path, statements: [ "CREATE TABLE Boxes ( BoxId STRING(36) NOT NULL, Heights ARRAY<INT64>, Weights ARRAY<FLOAT64>, ErrorChecks ARRAY<BOOL> ) PRIMARY KEY (BoxId)" ] job.wait_until_done! spanner = Google::Cloud::Spanner.new project: project_id client = spanner.client instance_id, database_id box_id = SecureRandom.uuid client.insert "Boxes", [{ BoxId: box_id, Heights: [] }] results = client.read "Boxes", [:BoxId, :Heights], keys: box_id results.rows.each do |row| puts row["Heights"].empty? end # [END spanner_write_read_empty_int64_array] end def write_read_null_int64_array project_id:, instance_id:, database_id: # [START spanner_write_read_null_int64_array] # project_id = "Your Google Cloud project ID" # instance_id = "Your Spanner instance ID" # database_id = "Your Spanner database ID" require "google/cloud/spanner" require "google/cloud/spanner/admin/database" require "securerandom" database_admin_client = Google::Cloud::Spanner::Admin::Database.database_admin db_path = database_admin_client.database_path project: project_id, instance: instance_id, database: database_id job = database_admin_client.update_database_ddl database: db_path, statements: [ "CREATE TABLE Boxes ( BoxId STRING(36) NOT NULL, Heights ARRAY<INT64>, Weights ARRAY<FLOAT64>, ErrorChecks ARRAY<BOOL> ) PRIMARY KEY (BoxId)" ] job.wait_until_done! spanner = Google::Cloud::Spanner.new project: project_id client = spanner.client instance_id, database_id box_id = SecureRandom.uuid client.insert "Boxes", [{ BoxId: box_id, Heights: [nil, nil, nil] }] results = client.read "Boxes", [:BoxId, :Heights], keys: box_id results.rows.each do |row| row["Heights"].each { |height| puts height.nil? } end # [END spanner_write_read_null_int64_array] end def write_read_int64_array project_id:, instance_id:, database_id: # [START spanner_write_read_int64_array] # project_id = "Your Google Cloud project ID" # instance_id = "Your Spanner instance ID" # database_id = "Your Spanner database ID" require "google/cloud/spanner" require "google/cloud/spanner/admin/database" require "securerandom" database_admin_client = Google::Cloud::Spanner::Admin::Database.database_admin db_path = database_admin_client.database_path project: project_id, instance: instance_id, database: database_id job = database_admin_client.update_database_ddl database: db_path, statements: [ "CREATE TABLE Boxes ( BoxId STRING(36) NOT NULL, Heights ARRAY<INT64>, Weights ARRAY<FLOAT64>, ErrorChecks ARRAY<BOOL> ) PRIMARY KEY (BoxId)" ] job.wait_until_done! spanner = Google::Cloud::Spanner.new project: project_id client = spanner.client instance_id, database_id box_id = SecureRandom.uuid client.insert "Boxes", [{ BoxId: box_id, Heights: [10, 11, 12] }] results = client.read "Boxes", [:BoxId, :Heights], keys: box_id results.rows.each do |row| puts row["Heights"] end # [END spanner_write_read_int64_array] end def write_read_empty_float64_array project_id:, instance_id:, database_id: # [START spanner_write_read_empty_float64_array] # project_id = "Your Google Cloud project ID" # instance_id = "Your Spanner instance ID" # database_id = "Your Spanner database ID" require "google/cloud/spanner" require "google/cloud/spanner/admin/database" require "securerandom" database_admin_client = Google::Cloud::Spanner::Admin::Database.database_admin db_path = database_admin_client.database_path project: project_id, instance: instance_id, database: database_id job = database_admin_client.update_database_ddl database: db_path, statements: [ "CREATE TABLE Boxes ( BoxId STRING(36) NOT NULL, Heights ARRAY<INT64>, Weights ARRAY<FLOAT64>, ErrorChecks ARRAY<BOOL> ) PRIMARY KEY (BoxId)" ] job.wait_until_done! spanner = Google::Cloud::Spanner.new project: project_id client = spanner.client instance_id, database_id box_id = SecureRandom.uuid client.insert "Boxes", [{ BoxId: box_id, Weights: [] }] results = client.read "Boxes", [:BoxId, :Weights], keys: box_id results.rows.each do |row| puts row["Weights"].empty? end # [END spanner_write_read_empty_float64_array] end def write_read_null_float64_array project_id:, instance_id:, database_id: # [START spanner_write_read_null_float64_array] # project_id = "Your Google Cloud project ID" # instance_id = "Your Spanner instance ID" # database_id = "Your Spanner database ID" require "google/cloud/spanner" require "google/cloud/spanner/admin/database" require "securerandom" database_admin_client = Google::Cloud::Spanner::Admin::Database.database_admin db_path = database_admin_client.database_path project: project_id, instance: instance_id, database: database_id job = database_admin_client.update_database_ddl database: db_path, statements: [ "CREATE TABLE Boxes ( BoxId STRING(36) NOT NULL, Heights ARRAY<INT64>, Weights ARRAY<FLOAT64>, ErrorChecks ARRAY<BOOL> ) PRIMARY KEY (BoxId)" ] job.wait_until_done! spanner = Google::Cloud::Spanner.new project: project_id client = spanner.client instance_id, database_id box_id = SecureRandom.uuid client.insert "Boxes", [{ BoxId: box_id, Weights: [nil, nil, nil] }] results = client.read "Boxes", [:BoxId, :Weights], keys: box_id results.rows.each do |row| row["Weights"].each { |weight| puts weight.nil? } end # [END spanner_write_read_null_float64_array] end def write_read_float64_array project_id:, instance_id:, database_id: # [START spanner_write_read_float64_array] # project_id = "Your Google Cloud project ID" # instance_id = "Your Spanner instance ID" # database_id = "Your Spanner database ID" require "google/cloud/spanner" require "google/cloud/spanner/admin/database" require "securerandom" database_admin_client = Google::Cloud::Spanner::Admin::Database.database_admin db_path = database_admin_client.database_path project: project_id, instance: instance_id, database: database_id job = database_admin_client.update_database_ddl database: db_path, statements: [ "CREATE TABLE Boxes ( BoxId STRING(36) NOT NULL, Heights ARRAY<INT64>, Weights ARRAY<FLOAT64>, ErrorChecks ARRAY<BOOL> ) PRIMARY KEY (BoxId)" ] job.wait_until_done! spanner = Google::Cloud::Spanner.new project: project_id client = spanner.client instance_id, database_id box_id = SecureRandom.uuid client.insert "Boxes", [{ BoxId: box_id, Weights: [10.001, 11.1212, 104.4123101] }] results = client.read "Boxes", [:BoxId, :Weights], keys: box_id results.rows.each do |row| puts row["Weights"] end # [END spanner_write_read_float64_array] end def create_backup project_id:, instance_id:, database_id:, backup_id:, version_time: # [START spanner_create_backup] # project_id = "Your Google Cloud project ID" # instance_id = "Your Spanner instance ID" # database_id = "Your Spanner database ID" # backup_id = "Your Spanner backup ID" # version_time = Time.now - 60 * 60 * 24 # 1 day ago require "google/cloud/spanner" require "google/cloud/spanner/admin/database" database_admin_client = Google::Cloud::Spanner::Admin::Database.database_admin instance_path = database_admin_client.instance_path project: project_id, instance: instance_id db_path = database_admin_client.database_path project: project_id, instance: instance_id, database: database_id backup_path = database_admin_client.backup_path project: project_id, instance: instance_id, backup: backup_id expire_time = Time.now + (14 * 24 * 3600) # 14 days from now job = database_admin_client.create_backup parent: instance_path, backup_id: backup_id, backup: { database: db_path, expire_time: expire_time, version_time: version_time } puts "Backup operation in progress" job.wait_until_done! backup = database_admin_client.get_backup name: backup_path puts "Backup #{backup_id} of size #{backup.size_bytes} bytes was created at #{backup.create_time} for version of database at #{backup.version_time}" # [END spanner_create_backup] end def create_backup_with_encryption_key project_id:, instance_id:, database_id:, backup_id:, kms_key_name: # [START spanner_create_backup_with_encryption_key] # project_id = "Your Google Cloud project ID" # instance_id = "Your Spanner instance ID" # database_id = "Your Spanner database ID" # backup_id = "Your Spanner backup ID" # kms_key_name = "Your backup encryption database KMS key" require "google/cloud/spanner" require "google/cloud/spanner/admin/database" database_admin_client = Google::Cloud::Spanner::Admin::Database.database_admin instance_path = database_admin_client.instance_path project: project_id, instance: instance_id db_path = database_admin_client.database_path project: project_id, instance: instance_id, database: database_id backup_path = database_admin_client.backup_path project: project_id, instance: instance_id, backup: backup_id expire_time = Time.now + (14 * 24 * 3600) # 14 days from now encryption_config = { encryption_type: :CUSTOMER_MANAGED_ENCRYPTION, kms_key_name: kms_key_name } job = database_admin_client.create_backup parent: instance_path, backup_id: backup_id, backup: { database: db_path, expire_time: expire_time }, encryption_config: encryption_config puts "Backup operation in progress" job.wait_until_done! backup = database_admin_client.get_backup name: backup_path puts "Backup #{backup_id} of size #{backup.size_bytes} bytes was created at #{backup.create_time} using encryption key #{kms_key_name}" # [END spanner_create_backup_with_encryption_key] end def create_backup_with_multiple_kms_keys( project_id:, instance_id:, database_id:, backup_id:, kms_key_names: ) # [START spanner_create_backup_with_MR_CMEK] # project_id = "Your Google Cloud project ID" # instance_id = "Your Spanner instance ID" # database_id = "Your Spanner database ID" # backup_id = "Your Spanner backup ID" # kms_key_names = ["key1", "key2", "key3"] require "google/cloud/spanner" require "google/cloud/spanner/admin/database" database_admin_client = Google::Cloud::Spanner::Admin::Database.database_admin instance_path = database_admin_client.instance_path( project: project_id, instance: instance_id ) db_path = database_admin_client.database_path project: project_id, instance: instance_id, database: database_id backup_path = database_admin_client.backup_path project: project_id, instance: instance_id, backup: backup_id expire_time = Time.now + (14 * 24 * 3600) # 14 days from now encryption_config = { encryption_type: :CUSTOMER_MANAGED_ENCRYPTION, kms_key_names: kms_key_names } job = database_admin_client.create_backup parent: instance_path, backup_id: backup_id, backup: { database: db_path, expire_time: expire_time }, encryption_config: encryption_config puts "Backup operation in progress" job.wait_until_done! backup = database_admin_client.get_backup name: backup_path puts "Backup #{backup_id} of size #{backup.size_bytes} bytes was created " \ "at #{backup.create_time} using encryption key #{kms_key_names}" # [END spanner_create_backup_with_MR_CMEK] end def restore_backup project_id:, instance_id:, database_id:, backup_id: # [START spanner_restore_backup] # project_id = "Your Google Cloud project ID" # instance_id = "Your Spanner instance ID" # database_id = "Your Spanner database ID of where to restore" # backup_id = "Your Spanner backup ID" require "google/cloud/spanner" require "google/cloud/spanner/admin/database" database_admin_client = Google::Cloud::Spanner::Admin::Database.database_admin instance_path = database_admin_client.instance_path project: project_id, instance: instance_id db_path = database_admin_client.database_path project: project_id, instance: instance_id, database: database_id backup_path = database_admin_client.backup_path project: project_id, instance: instance_id, backup: backup_id job = database_admin_client.restore_database parent: instance_path, database_id: database_id, backup: backup_path puts "Waiting for restore backup operation to complete" job.wait_until_done! database = database_admin_client.get_database name: db_path restore_info = database.restore_info puts "Database #{restore_info.backup_info.source_database} was restored to #{database_id} from backup #{restore_info.backup_info.backup} with version time #{restore_info.backup_info.version_time}" # [END spanner_restore_backup] end def restore_database_with_encryption_key project_id:, instance_id:, database_id:, backup_id:, kms_key_name: # [START spanner_restore_backup_with_encryption_key] # project_id = "Your Google Cloud project ID" # instance_id = "Your Spanner instance ID" # database_id = "Your Spanner database ID of where to restore" # backup_id = "Your Spanner backup ID" # kms_key_name = "Your backup encryption database KMS key" require "google/cloud/spanner" require "google/cloud/spanner/admin/database" database_admin_client = Google::Cloud::Spanner::Admin::Database.database_admin instance_path = database_admin_client.instance_path project: project_id, instance: instance_id db_path = database_admin_client.database_path project: project_id, instance: instance_id, database: database_id backup_path = database_admin_client.backup_path project: project_id, instance: instance_id, backup: backup_id encryption_config = { encryption_type: :CUSTOMER_MANAGED_ENCRYPTION, kms_key_name: kms_key_name } job = database_admin_client.restore_database parent: instance_path, database_id: database_id, backup: backup_path, encryption_config: encryption_config puts "Waiting for restore backup operation to complete" job.wait_until_done! database = database_admin_client.get_database name: db_path restore_info = database.restore_info puts "Database #{restore_info.backup_info.source_database} was restored to #{database_id} from backup #{restore_info.backup_info.backup} using encryption key #{database.encryption_config.kms_key_name}" # [END spanner_restore_backup_with_encryption_key] end def restore_database_with_multiple_kms_keys( project_id:, instance_id:, database_id:, backup_id:, kms_key_names: ) # [START spanner_restore_backup_with_MR_CMEK] # project_id = "Your Google Cloud project ID" # instance_id = "Your Spanner instance ID" # database_id = "Your Spanner database ID of where to restore" # backup_id = "Your Spanner backup ID" # kms_key_names = ["key1", "key2", "key3"] require "google/cloud/spanner" require "google/cloud/spanner/admin/database" database_admin_client = Google::Cloud::Spanner::Admin::Database.database_admin instance_path = database_admin_client.instance_path( project: project_id, instance: instance_id ) db_path = database_admin_client.database_path project: project_id, instance: instance_id, database: database_id backup_path = database_admin_client.backup_path project: project_id, instance: instance_id, backup: backup_id encryption_config = { encryption_type: :CUSTOMER_MANAGED_ENCRYPTION, kms_key_names: kms_key_names } job = database_admin_client.restore_database( parent: instance_path, database_id: database_id, backup: backup_path, encryption_config: encryption_config ) puts "Waiting for restore backup operation to complete" job.wait_until_done! database = database_admin_client.get_database name: db_path restore_info = database.restore_info puts "Database #{restore_info.backup_info.source_database} was restored " \ "to #{database_id} from backup #{restore_info.backup_info.backup} " \ "using encryption key #{database.encryption_config.kms_key_names}" # [END spanner_restore_backup_with_MR_CMEK] end def create_backup_cancel project_id:, instance_id:, database_id:, backup_id: # [START spanner_cancel_backup_create] # project_id = "Your Google Cloud project ID" # instance_id = "Your Spanner instance ID" # database_id = "Your Spanner database ID" # backup_id = "Your Spanner backup ID" require "google/cloud/spanner" require "google/cloud/spanner/admin/database" database_admin_client = Google::Cloud::Spanner::Admin::Database.database_admin instance_path = database_admin_client.instance_path project: project_id, instance: instance_id db_path = database_admin_client.database_path project: project_id, instance: instance_id, database: database_id backup_path = database_admin_client.backup_path project: project_id, instance: instance_id, backup: backup_id expire_time = Time.now + (14 * 24 * 3600) # 14 days from now job = database_admin_client.create_backup parent: instance_path, backup_id: backup_id, backup: { database: db_path, expire_time: expire_time } puts "Backup operation in progress" job.cancel job.wait_until_done! begin backup = database_admin_client.get_backup name: backup_path database_admin_client.delete_backup name: backup_path if backup rescue StandardError nil # no cleanup needed when a backup is not created end puts "#{backup_id} creation job cancelled" # [END spanner_cancel_backup_create] end def list_backup_operations project_id:, instance_id:, database_id: # [START spanner_list_backup_operations] # project_id = "Your Google Cloud project ID" # instance_id = "Your Spanner instance ID" # database_id = "Your Spanner database ID" require "google/cloud/spanner" require "google/cloud/spanner/admin/database" database_admin_client = Google::Cloud::Spanner::Admin::Database.database_admin instance_path = database_admin_client.instance_path project: project_id, instance: instance_id jobs = database_admin_client.list_backup_operations parent: instance_path, filter: "metadata.@type:type.googleapis.com/google.spanner.admin.database.v1.CreateBackupMetadata" jobs.each do |job| if job.error? puts job.error else puts "Backup #{job.results.name} on database #{database_id} is #{job.metadata.progress.progress_percent}% complete" end end # [END spanner_list_backup_operations] end def list_copy_backup_operations project_id:, instance_id:, backup_id: # [START spanner_list_copy_backup_operations] # project_id = "Your Google Cloud project ID" # instance_id = "Your Spanner instance ID" # backup_id = "You Spanner backup ID" require "google/cloud/spanner" require "google/cloud/spanner/admin/database" database_admin_client = Google::Cloud::Spanner::Admin::Database.database_admin instance_path = database_admin_client.instance_path project: project_id, instance: instance_id filter = "(metadata.@type:type.googleapis.com/google.spanner.admin.database.v1.CopyBackupMetadata) AND (metadata.source_backup:#{backup_id})" jobs = database_admin_client.list_backup_operations parent: instance_path, filter: filter jobs.each do |job| if job.error? puts job.error else puts "Backup #{job.results.name} on source backup #{backup_id} is #{job.metadata.progress.progress_percent}% complete" end end # [END spanner_list_copy_backup_operations] end def list_database_operations project_id:, instance_id: # [START spanner_list_database_operations] # project_id = "Your Google Cloud project ID" # instance_id = "Your Spanner instance ID" require "google/cloud/spanner" require "google/cloud/spanner/admin/database" database_admin_client = Google::Cloud::Spanner::Admin::Database.database_admin instance_path = database_admin_client.instance_path project: project_id, instance: instance_id jobs = database_admin_client.list_database_operations parent: instance_path, filter: "metadata.@type:type.googleapis.com/google.spanner.admin.database.v1.OptimizeRestoredDatabaseMetadata" jobs.each do |job| if job.error? puts job.error elsif job.results progress_percent = job.metadata.progress.progress_percent puts "Database #{job.results.name} restored from backup is #{progress_percent}% optimized" end end puts "List database operations with optimized database filter found #{jobs.count} jobs." # [END spanner_list_database_operations] end def list_backups project_id:, instance_id:, backup_id:, database_id: # [START spanner_list_backups] # project_id = "Your Google Cloud project ID" # instance_id = "Your Spanner instance ID" # backup_id = "Your Spanner database backup ID" # database_id = "Your Spanner databaseID" require "google/cloud/spanner" require "google/cloud/spanner/admin/database" database_admin_client = Google::Cloud::Spanner::Admin::Database.database_admin instance_path = database_admin_client.instance_path project: project_id, instance: instance_id puts "All backups" database_admin_client.list_backups(parent: instance_path).each do |backup| puts backup.name end puts "All backups with backup name containing \"#{backup_id}\":" database_admin_client.list_backups(parent: instance_path, filter: "name:#{backup_id}").each do |backup| puts backup.name end puts "All backups for databases with a name containing \"#{database_id}\":" database_admin_client.list_backups(parent: instance_path, filter: "database:#{database_id}").each do |backup| puts backup.name end puts "All backups that expire before a timestamp:" expire_time = Time.now + (30 * 24 * 3600) # 30 days from now database_admin_client.list_backups(parent: instance_path, filter: "expire_time < \"#{expire_time.iso8601}\"").each do |backup| puts backup.name end puts "All backups with a size greater than 500 bytes:" database_admin_client.list_backups(parent: instance_path, filter: "size_bytes >= 500").each do |backup| puts backup.name end puts "All backups that were created after a timestamp that are also ready:" create_time = Time.now - (24 * 3600) # From 1 day ago database_admin_client.list_backups(parent: instance_path, filter: "create_time >= \"#{create_time.iso8601}\" AND state:READY").each do |backup| puts backup.name end puts "All backups with pagination:" list = database_admin_client.list_backups parent: instance_path, page_size: 5 list.each do |backup| puts backup.name end # [END spanner_list_backups] end def delete_backup project_id:, instance_id:, backup_id: # [START spanner_delete_backup] # project_id = "Your Google Cloud project ID" # instance_id = "Your Spanner instance ID" # backup_id = "Your Spanner backup ID" require "google/cloud/spanner" require "google/cloud/spanner/admin/database" database_admin_client = Google::Cloud::Spanner::Admin::Database.database_admin instance_path = database_admin_client.instance_path project: project_id, instance: instance_id backup_path = database_admin_client.backup_path project: project_id, instance: instance_id, backup: backup_id database_admin_client.delete_backup name: backup_path puts "Backup #{backup_id} deleted" # [END spanner_delete_backup] end def update_backup project_id:, instance_id:, backup_id: # [START spanner_update_backup] # project_id = "Your Google Cloud project ID" # instance_id = "Your Spanner instance ID" # backup_id = "Your Spanner backup ID" require "google/cloud/spanner" require "google/cloud/spanner/admin/database" database_admin_client = Google::Cloud::Spanner::Admin::Database.database_admin instance_path = database_admin_client.instance_path project: project_id, instance: instance_id backup_path = database_admin_client.backup_path project: project_id, instance: instance_id, backup: backup_id backup = database_admin_client.get_backup name: backup_path backup.expire_time = Time.now + (60 * 24 * 3600) # Extending the expiry time by 60 days from now. database_admin_client.update_backup backup: backup, update_mask: { paths: ["expire_time"] } puts "Expiration time updated: #{backup.expire_time}" # [END spanner_update_backup] end def copy_backup project_id:, instance_id:, backup_id:, source_backup_id: # [START spanner_copy_backup] # project_id = "Your Google Cloud project ID" # instance_id = "The ID of the destination instance that will contain the backup copy" # backup_id = "The ID of the backup copy" # source_backup = "The source backup to be copied" require "google/cloud/spanner" require "google/cloud/spanner/admin/database" database_admin_client = Google::Cloud::Spanner::Admin::Database.database_admin instance_path = database_admin_client.instance_path project: project_id, instance: instance_id backup_path = database_admin_client.backup_path project: project_id, instance: instance_id, backup: backup_id source_backup = database_admin_client.backup_path project: project_id, instance: instance_id, backup: source_backup_id expire_time = Time.now + (14 * 24 * 3600) # 14 days from now job = database_admin_client.copy_backup parent: instance_path, backup_id: backup_id, source_backup: source_backup, expire_time: expire_time puts "Copy backup operation in progress" job.wait_until_done! backup = database_admin_client.get_backup name: backup_path puts "Backup #{backup_id} of size #{backup.size_bytes} bytes was copied at #{backup.create_time} from #{source_backup} for version #{backup.version_time}" # [END spanner_copy_backup] end def copy_backup_with_multiple_kms_keys(project_id:, instance_id:, backup_id:, source_backup_id:, kms_key_names:) # [START spanner_copy_backup_with_MR_CMEK] # project_id = "Your Google Cloud project ID" # instance_id = "The ID of the destination instance that will contain the backup copy" # backup_id = "The ID of the backup copy" # source_backup = "The source backup to be copied" # kms_key_names = ["key1", "key2", "key3"] require "google/cloud/spanner" require "google/cloud/spanner/admin/database" database_admin_client = Google::Cloud::Spanner::Admin::Database.database_admin instance_path = database_admin_client.instance_path( project: project_id, instance: instance_id ) backup_path = database_admin_client.backup_path project: project_id, instance: instance_id, backup: backup_id source_backup = database_admin_client.backup_path project: project_id, instance: instance_id, backup: source_backup_id expire_time = Time.now + (14 * 24 * 3600) # 14 days from now encryption_config = { encryption_type: :CUSTOMER_MANAGED_ENCRYPTION, kms_key_names: kms_key_names } job = database_admin_client.copy_backup parent: instance_path, backup_id: backup_id, source_backup: source_backup, expire_time: expire_time, encryption_config: encryption_config puts "Copy backup operation in progress" job.wait_until_done! backup = database_admin_client.get_backup name: backup_path puts "Backup #{backup_id} of size #{backup.size_bytes} bytes was copied at " \ "#{backup.create_time} from #{source_backup} for version " \ "#{backup.version_time} using encryption keys #{kms_key_names}" # [END spanner_copy_backup_with_MR_CMEK] end def set_custom_timeout_and_retry project_id:, instance_id:, database_id: # [START spanner_set_custom_timeout_and_retry] # project_id = "Your Google Cloud project ID" # instance_id = "Your Spanner instance ID" # database_id = "Your Spanner database ID" require "google/cloud/spanner" spanner = Google::Cloud::Spanner.new project: project_id client = spanner.client instance_id, database_id row_count = 0 timeout = 60.0 retry_policy = { initial_delay: 0.5, max_delay: 16.0, multiplier: 1.5, retry_codes: ["UNAVAILABLE"] } call_options = { timeout: timeout, retry_policy: retry_policy } client.transaction do |transaction| row_count = transaction.execute_update( "INSERT INTO Singers (SingerId, FirstName, LastName) VALUES (10, 'Virginia', 'Watson')", call_options: call_options ) end puts "#{row_count} record inserted." # [END spanner_set_custom_timeout_and_retry] end def commit_stats project_id:, instance_id:, database_id: # [START spanner_get_commit_stats] # project_id = "Your Google Cloud project ID" # instance_id = "Your Spanner instance ID" # database_id = "Your Spanner database ID" require "google/cloud/spanner" spanner = Google::Cloud::Spanner.new project: project_id client = spanner.client instance_id, database_id records = [ { SingerId: 1, AlbumId: 1, MarketingBudget: 200_000 }, { SingerId: 2, AlbumId: 2, MarketingBudget: 400_000 } ] commit_options = { return_commit_stats: true } resp = client.upsert "Albums", records, commit_options: commit_options puts "Updated data with #{resp.stats.mutation_count} mutations." # [END spanner_get_commit_stats] end def usage puts <<~USAGE Usage: bundle exec ruby spanner_samples.rb [command] [arguments] Commands: create_instance <instance_id> Create Instance create_database <instance_id> <database_id> Create Database create_database_with_encryption_key <instance_id> <database_id> Create Database with encryption create_database_with_multiple_kms_keys <instance_id> <database_id> Create Database with multiple KMS keys create_table_with_timestamp_column <instance_id> <database_id> Create table Performances with commit timestamp column insert_data <instance_id> <database_id> Insert Data insert_data_with_timestamp_column <instance_id> <database_id> Inserts data into Performances table containing the commit timestamp column query_data <instance_id> <database_id> Query Data read_data <instance_id> <database_id> Read Data delete_data <instance_id> <database_id> Delete Data read_stale_data <instance_id> <database_id> Read Stale Data create_index <instance_id> <database_id> Create Index create_storing_index <instance_id> <database_id> Create Storing Index add_column <instance_id> <database_id> Add Column add_timestamp_column <instance_id> <database_id> Alters existing Albums table, adding a commit timestamp column add_numeric_column <instance_id> <database_id> Alters existing Venues table, adding a numeric column update_data <instance_id> <database_id> Update Data update_data_with_timestamp_column <instance_id> <database_id> Updates two records in the altered table where the commit timestamp column was added update_data_with_numeric_column <instance_id> <database_id> Updates three records in the altered table where the numeric column was added query_data_with_new_column <instance_id> <database_id> Query Data with New Column query_data_with_timestamp_column <instance_id> <database_id> Queries data from altered table where the commit timestamp column was added write_struct_data <instance_id> <database_id> Inserts sample data that can be used for STRUCT queries query_with_struct <instance_id> <database_id> Queries data using a STRUCT paramater query_with_array_of_struct <instance_id> <database_id> Queries data using an array of STRUCT values as parameter query_struct_field <instance_id> <database_id> Queries data by accessing field from a STRUCT parameter query_nested_struct_field <instance_id> <database_id> Queries data by accessing field from nested STRUCT parameters query_data_with_index <instance_id> <database_id> <start_title> <end_title> Query Data with Index read_write_transaction <instance_id> <database_id> Read-Write Transaction read_data_with_index <instance_id> <database_id> Read Data with Index read_data_with_storing_index <instance_id> <database_id> Read Data with Storing Index read_only_transaction <instance_id> <database_id> Read-Only Transaction spanner_batch_client <instance_id> <database_id> Use Spanner batch query with a thread pool insert_using_dml <instance_id> <database_id> Insert Data using a DML statement. update_using_dml <instance_id> <database_id> Update Data using a DML statement. delete_using_dml <instance_id> <database_id> Delete Data using a DML statement. update_using_dml_with_timestamp <instance_id> <database_id> Update the timestamp value of specifc records using a DML statement. write_and_read_using_dml <instance_id> <database_id> Insert data using a DML statement and then read the inserted data. update_using_dml_with_struct <instance_id> <database_id> Update data using a DML statement combined with a Spanner struct. write_using_dml <instance_id> <database_id> Insert multiple records using a DML statement. query_with_parameter <instance_id> <database_id> Query record inserted using DML with a query parameter. query_with_numeric_parameter <instance_id> <database_id> Query record inserted using DML with a numeric query parameter. write_with_transaction_using_dml <instance_id> <database_id> Update data using a DML statement within a read-write transaction. update_using_partitioned_dml <instance_id> <database_id> Update multiple records using a partitioned DML statement. delete_using_partitioned_dml <instance_id> <database_id> Delete multiple records using a partitioned DML statement. update_using_batch_dml <instance_id> <database_id> Updates sample data in the database using Batch DML. create_table_with_datatypes <instance_id> <database_id> Create table Venues with supported datatype columns. write_datatypes_data <instance_id> <database_id> Inserts sample data that can be used for datatype queries. query_with_array <instance_id> <database_id> Queries data using an ARRAY parameter. query_with_bool <instance_id> <database_id> Queries data using a BOOL parameter. query_with_bytes <instance_id> <database_id> Queries data using a BYTES parameter. query_with_date <instance_id> <database_id> Queries data using a DATE parameter. query_with_float <instance_id> <database_id> Queries data using a FLOAT64 parameter. query_with_int <instance_id> <database_id> Queries data using a INT64 parameter. query_with_string <instance_id> <database_id> Queries data using a STRING parameter. query_with_timestamp <instance_id> <database_id> Queries data using a TIMESTAMP parameter. query_with_query_options <instance_id> <database_id> Queries data with query options. create_client_with_query_options <instance_id> <database_id> Create a client with query options. write_read_bool_array <instance_id> <database_id> Writes and read BOOL array. write_read_empty_int64_array <instance_id> <database_id> Writes empty INT64 array and read. write_read_null_int64_array <instance_id> <database_id> Writes nil to INT64 array and read. write_read_int64_array <instance_id> <database_id> Writes INT64 array and read. write_read_empty_float64_array <instance_id> <database_id> Writes empty FLOAT64 array and read. write_read_null_float64_array <instance_id> <database_id> Writes nil to FLOAT64 array and read. write_read_float64_array <instance_id> <database_id> Writes FLOAT64 array and read. create_backup <instance_id> <database_id> <backup_id> <version_time> Create a backup. create_backup_with_encryption_key <instance_id> <database_id> <backup_id> <kms_key_name> Create a backup using encryption key. create_backup_with_multiple_kms_keys <instance_id> <database_id> <backup_id> "<kms_key_name>,<kms_key_name>" Create a backup using multiple KMS keys. restore_backup <instance_id> <database_id> <backup_id> Restore a database. restore_database_with_encryption_key <instance_id> <database_id> <backup_id> <kms_key_name> Restore a database using encryption key. restore_database_with_multiple_kms_keys <instance_id> <database_id> <backup_id> "<kms_key_name>,<kms_key_name>" Restore a database using multiple KMS keys create_backup_cancel <instance_id> <database_id> <backup_id> Cancel a backup. list_backup_operations <instance_id> List backup operations. list_database_operations <instance_id> List database operations. list_backups <instance_id> <backup_id> <database_id> List and filter backups. delete_backup <instance_id> <backup_id> Delete a backup. update_backup <instance_id> <backup_id> Update the backup. copy_backup <instance_id> <backup_id> <source_backup> Copies a backup copy_backup_with_multiple_kms_keys <instance_id> <backup_id> <source_backup> "<kms_key_name>,<kms_key_name>" Copies a backup with multiple KMS keys set_custom_timeout_and_retry <instance_id> <database_id> Set custom timeout and retry settings. commit_stats <instance_id> <database_id> Get commit stats. Environment variables: GOOGLE_CLOUD_PROJECT must be set to your Google Cloud project ID USAGE end def run_sample arguments command = arguments.shift instance_id = arguments.shift database_id = arguments.shift project_id = ENV["GOOGLE_CLOUD_PROJECT"] commands = [ "create_instance", "create_instance_with_processing_units", "create_database", "create_table_with_timestamp_column", "create_database_with_version_retention_period", "insert_data", "insert_data_with_timestamp_column", "query_data", "query_data_with_timestamp_column", "read_data", "delete_data", "read_stale_data", "create_index", "create_storing_index", "add_column", "add_timestamp_column", "add_numeric_column", "update_data", "query_data_with_new_column", "update_data_with_timestamp_column", "read_write_transaction", "query_data_with_index", "read_data_with_index", "read_data_with_storing_index", "read_only_transaction", "spanner_batch_client", "write_struct_data", "query_with_struct", "query_with_array_of_struct", "query_struct_field", "query_nested_struct_field", "insert_using_dml", "update_using_dml", "delete_using_dml", "update_using_dml_with_timestamp", "write_and_read_using_dml", "update_using_dml_with_struct", "write_using_dml", "query_with_parameter", "write_with_transaction_using_dml", "update_using_partitioned_dml", "delete_using_partitioned_dml", "update_using_batch_dml", "create_table_with_datatypes", "write_datatypes_data", "query_with_array", "query_with_bool", "query_with_bytes", "query_with_date", "query_with_float", "query_with_int", "query_with_string", "query_with_timestamp", "query_with_query_options", "create_client_with_query_options", "write_read_bool_array", "write_read_empty_int64_array", "write_read_null_int64_array", "write_read_int64_array", "write_read_empty_float64_array", "write_read_null_float64_array", "write_read_float64_array", "create_backup", "restore_backup", "create_backup_cancel", "list_backup_operations", "list_database_operations", "list_backups", "delete_backup", "update_backup_expiration_time", "copy_backup", "set_custom_timeout_and_retry", "query_with_numeric_parameter", "update_data_with_numeric_column", "commit_stats", "create_database_with_encryption_key", "create_backup_with_encryption_key", "restore_database_with_encryption_key", "update_backup" ] if command.eql?("query_data_with_index") && instance_id && database_id && arguments.size >= 2 query_data_with_index project_id: project_id, instance_id: instance_id, database_id: database_id, start_title: arguments.shift, end_title: arguments.shift elsif commands.include?(command) && instance_id && database_id send command, project_id: project_id, instance_id: instance_id, database_id: database_id else usage end end if $PROGRAM_NAME == __FILE__ run_sample ARGV end