Class: Gcloud::Datastore::Transaction

Inherits:
Dataset
  • Object
show all
Defined in:
lib/gcloud/datastore/transaction.rb

Overview

# Transaction

Special Connection instance for running transactions.

See Dataset#transaction

Instance Attribute Summary collapse

Attributes inherited from Dataset

#connection

Instance Method Summary collapse

Methods inherited from Dataset

#allocate_ids, default_project, #entity, #key, #project, #query, #transaction

Constructor Details

#initialize(connection) ⇒ Transaction

Takes a Connection instead of project and Credentials.



30
31
32
33
34
# File 'lib/gcloud/datastore/transaction.rb', line 30

def initialize connection
  @connection = connection
  reset!
  start
end

Instance Attribute Details

#idObject (readonly)

Returns the value of attribute id.



25
26
27
# File 'lib/gcloud/datastore/transaction.rb', line 25

def id
  @id
end

Instance Method Details

#commit {|commit| ... } ⇒ Object

Commits a transaction.

Examples:

require "gcloud"

gcloud = Gcloud.new
dataset = gcloud.datastore

user = dataset.entity "User", "heidi" do |u|
  u["name"] = "Heidi Henderson"
  u["email"] = "[email protected]"
end

tx = dataset.transaction
begin
  if tx.find(user.key).nil?
    tx.save user
  end
  tx.commit
rescue
  tx.rollback
end

Commit can be passed a block, same as Dataset#commit:

require "gcloud"

gcloud = Gcloud.new
dataset = gcloud.datastore

tx = dataset.transaction
begin
  tx.commit do |c|
    c.save task1, task2
    c.delete entity1, entity2
  end
rescue
  tx.rollback
end

Yields:

  • (commit)

    an optional block for making changes

Yield Parameters:

  • commit (Commit)

    The object that changes are made on



205
206
207
208
209
210
211
212
213
214
215
216
217
# File 'lib/gcloud/datastore/transaction.rb', line 205

def commit
  if @id.nil?
    fail TransactionError, "Cannot commit when not in a transaction."
  end

  yield @commit if block_given?
  response = connection.commit @commit.mutation, @id
  auto_id_assign_ids @commit.auto_id_entities,
                     response.mutation_result.insert_auto_id_key
  # Make sure all entity keys are frozen so all show as persisted
  @commit.entities.each { |e| e.key.freeze unless e.persisted? }
  true
end

#delete(*entities_or_keys) ⇒ Object

Remove entities in a transaction.

Examples:

dataset.transaction do |tx|
  if tx.find(user.key).nil?
    tx.delete task1, task2
  end
end


62
63
64
65
66
# File 'lib/gcloud/datastore/transaction.rb', line 62

def delete *entities_or_keys
  @commit.delete(*entities_or_keys)
  # Do not delete yet
  true
end

#find(key_or_kind, id_or_name = nil) ⇒ Gcloud::Datastore::Entity? Also known as: get

Retrieve an entity by providing key information. The lookup is run within the transaction.

Examples:

Finding an entity with a key:

key = dataset.key "Task", 123456
task = dataset.find key

Finding an entity with a ‘kind` and `id`/`name`:

task = dataset.find "Task", 123456

Parameters:

  • key_or_kind (Key, String)

    A Key object or ‘kind` string value.

Returns:



83
84
85
86
87
88
89
# File 'lib/gcloud/datastore/transaction.rb', line 83

def find key_or_kind, id_or_name = nil
  key = key_or_kind
  unless key.is_a? Gcloud::Datastore::Key
    key = Key.new key_or_kind, id_or_name
  end
  find_all(key).first
end

#find_all(*keys) ⇒ Gcloud::Datastore::Dataset::LookupResults Also known as: lookup

Retrieve the entities for the provided keys. The lookup is run within the transaction.

Examples:

gcloud = Gcloud.new
dataset = gcloud.datastore
key1 = dataset.key "Task", 123456
key2 = dataset.key "Task", 987654
tasks = dataset.find_all key1, key2

Parameters:

  • keys (Key)

    One or more Key objects to find records for.

Returns:



107
108
109
110
111
112
113
114
# File 'lib/gcloud/datastore/transaction.rb', line 107

def find_all *keys
  response = connection.lookup(*keys.map(&:to_proto),
                               transaction: @id)
  entities = to_gcloud_entities response.found
  deferred = to_gcloud_keys response.deferred
  missing  = to_gcloud_entities response.missing
  LookupResults.new entities, deferred, missing
end

#reset!Object

Reset the transaction. #start must be called afterwards.



254
255
256
257
# File 'lib/gcloud/datastore/transaction.rb', line 254

def reset!
  @id = nil
  @commit = Commit.new
end

#rollbackObject

Rolls a transaction back.

Examples:

require "gcloud"

gcloud = Gcloud.new
dataset = gcloud.datastore

user = dataset.entity "User", "heidi" do |u|
  u["name"] = "Heidi Henderson"
  u["email"] = "[email protected]"
end

tx = dataset.transaction
begin
  if tx.find(user.key).nil?
    tx.save user
  end
  tx.commit
rescue
  tx.rollback
end


242
243
244
245
246
247
248
249
# File 'lib/gcloud/datastore/transaction.rb', line 242

def rollback
  if @id.nil?
    fail TransactionError, "Cannot rollback when not in a transaction."
  end

  connection.rollback @id
  true
end

#run(query, namespace: nil) ⇒ Gcloud::Datastore::Dataset::QueryResults Also known as: run_query

Retrieve entities specified by a Query. The query is run within the transaction.

Examples:

query = dataset.query("Task").
  where("completed", "=", true)
dataset.transaction do |tx|
  tasks = tx.run query
end

Run the query within a namespace with the ‘namespace` option:

query = Gcloud::Datastore::Query.new.kind("Task").
  where("completed", "=", true)
dataset.transaction do |tx|
  tasks = tx.run query, namespace: "ns~todo-project"
end

Parameters:

  • query (Query)

    The Query object with the search criteria.

  • namespace (String) (defaults to: nil)

    The namespace the query is to run within.

Returns:



140
141
142
143
144
145
146
147
148
# File 'lib/gcloud/datastore/transaction.rb', line 140

def run query, namespace: nil
  partition = optional_partition_id namespace
  response = connection.run_query query.to_proto, partition,
                                  transaction: @id
  entities = to_gcloud_entities response.batch.entity_result
  cursor = Proto.encode_cursor response.batch.end_cursor
  more_results = Proto.to_more_results_string response.batch.more_results
  QueryResults.new entities, cursor, more_results
end

#save(*entities) ⇒ Object

Persist entities in a transaction.

Examples:

dataset.transaction do |tx|
  if tx.find(user.key).nil?
    tx.save task1, task2
  end
end


46
47
48
49
50
# File 'lib/gcloud/datastore/transaction.rb', line 46

def save *entities
  @commit.save(*entities)
  # Do not save or assign auto_ids yet
  entities
end

#startObject Also known as: begin_transaction

Begins a transaction. This method is run when a new Transaction is created.



154
155
156
157
158
159
# File 'lib/gcloud/datastore/transaction.rb', line 154

def start
  fail TransactionError, "Transaction already opened." unless @id.nil?

  response = connection.begin_transaction
  @id = response.transaction
end