Class: Google::Cloud::Datastore::ReadOnlyTransaction

Inherits:
Object
  • Object
show all
Defined in:
lib/google/cloud/datastore/read_only_transaction.rb

Overview

ReadOnlyTransaction

Represents a read-only Datastore transaction that only allows reads.

A read-only transaction cannot modify entities; in return they do not contend with other read-write or read-only transactions. Using a read-only transaction for transactions that only read data will potentially improve throughput.

See Dataset#transaction

Examples:

require "google/cloud/datastore"

datastore = Google::Cloud::Datastore.new

task_list_key = datastore.key "TaskList", "default"
query = datastore.query("Task").
  ancestor(task_list_key)

tasks = nil

datastore.read_only_transaction do |tx|
  task_list = tx.find task_list_key
  if task_list
    tasks = tx.run query
  end
end

See Also:

Instance Attribute Summary collapse

Instance Method Summary collapse

Instance Attribute Details

#idObject (readonly)

Returns the value of attribute id.



56
57
58
# File 'lib/google/cloud/datastore/read_only_transaction.rb', line 56

def id
  @id
end

#read_timeObject (readonly)

Reads entities at the given time. This may not be older than 60 seconds.



65
66
67
# File 'lib/google/cloud/datastore/read_only_transaction.rb', line 65

def read_time
  @read_time
end

Instance Method Details

#commitObject

Commits the transaction.

Examples:

require "google/cloud/datastore"

datastore = Google::Cloud::Datastore.new

task_list_key = datastore.key "TaskList", "default"

tx = datastore.transaction
task_list = tx.find task_list_key
if task_list
  query = tx.query("Task").
    ancestor(task_list_key)
  tasks = tx.run query
end
tx.commit


231
232
233
234
235
236
237
238
239
240
# File 'lib/google/cloud/datastore/read_only_transaction.rb', line 231

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

  ensure_service!

  service.commit [], transaction: @id
  true
end

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

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

Examples:

require "google/cloud/datastore"

datastore = Google::Cloud::Datastore.new

task_list_key = datastore.key "TaskList", "default"

datastore.read_only_transaction do |tx|
  task_list = tx.find task_list_key
end

Parameters:

  • key_or_kind (Key, String)

    A Key object or kind string value.

Returns:



100
101
102
103
104
105
106
# File 'lib/google/cloud/datastore/read_only_transaction.rb', line 100

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

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

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

Examples:

require "google/cloud/datastore"

datastore = Google::Cloud::Datastore.new

task_key1 = datastore.key "Task", 123456
task_key2 = datastore.key "Task", 987654

datastore.read_only_transaction do |tx|
  tasks = tx.find_all task_key1, task_key2
end

Parameters:

  • keys (Key)

    One or more Key objects to find records for.

Returns:



129
130
131
132
133
134
# File 'lib/google/cloud/datastore/read_only_transaction.rb', line 129

def find_all *keys
  ensure_service!
  lookup_res = service.lookup(*Array(keys).flatten.map(&:to_grpc),
                              transaction: @id)
  Dataset::LookupResults.from_grpc lookup_res, service, nil, @id
end

#gql(query, bindings = {}) ⇒ Google::Cloud::Datastore::GqlQuery

Create a new GqlQuery instance. This is a convenience method to make the creation of GqlQuery objects easier.

Examples:

require "google/cloud/datastore"

datastore = Google::Cloud::Datastore.new

datastore.read_only_transaction do |tx|
  gql_query = tx.gql "SELECT * FROM Task WHERE done = @done",
                     done: false
  tasks = tx.run gql_query
end

The previous example is equivalent to:

require "google/cloud/datastore"

datastore = Google::Cloud::Datastore.new

datastore.read_only_transaction do |tx|
  gql_query = Google::Cloud::Datastore::GqlQuery.new
  gql_query.query_string = "SELECT * FROM Task WHERE done = @done"
  gql_query.named_bindings = {done: false}
  tasks = tx.run gql_query
end

Parameters:

  • query (String)

    The GQL query string.

  • bindings (Hash) (defaults to: {})

    Named bindings for the GQL query string, each key must match regex [A-Za-z_$][A-Za-z_$0-9]*, must not match regex __.*__, and must not be "". The value must be an Object that can be stored as an Entity property value, or a Cursor.

Returns:



338
339
340
341
342
343
# File 'lib/google/cloud/datastore/read_only_transaction.rb', line 338

def gql query, bindings = {}
  gql = GqlQuery.new
  gql.query_string = query
  gql.named_bindings = bindings unless bindings.empty?
  gql
end

#key(*path, project: nil, namespace: nil) ⇒ Google::Cloud::Datastore::Key

Create a new Key instance. This is a convenience method to make the creation of Key objects easier.

Examples:

require "google/cloud/datastore"

datastore = Google::Cloud::Datastore.new

datastore.read_only_transaction do |tx|
  task_key = tx.key "Task", "sampleTask"
end

The previous example is equivalent to:

require "google/cloud/datastore"

datastore = Google::Cloud::Datastore.new

datastore.read_only_transaction do |tx|
  task_key = Google::Cloud::Datastore::Key.new "Task", "sampleTask"
end

Create a key with a parent:

require "google/cloud/datastore"

datastore = Google::Cloud::Datastore.new

datastore.read_only_transaction do |tx|
  key = tx.key [["TaskList", "default"], ["Task", "sampleTask"]]
  results = tx.find_all key
end

Create a key with multi-level ancestry:

require "google/cloud/datastore"

datastore = Google::Cloud::Datastore.new

datastore.read_only_transaction do |tx|
  key = tx.key([
    ["User", "alice"],
    ["TaskList", "default"],
    ["Task", "sampleTask"]
  ])
  results = tx.find_all key
end

Create a key with a project and namespace:

require "google/cloud/datastore"

datastore = Google::Cloud::Datastore.new

datastore.read_only_transaction do |tx|
  key = tx.key ["TaskList", "default"], ["Task", "sampleTask"],
               project: "my-todo-project",
               namespace: "example-ns"
  results = tx.find_all key
end

Parameters:

  • path (Array<Array(String,(String|Integer|nil))>)

    An optional list of pairs for the key's path. Each pair may include the key's kind (String) and an id (Integer) or name (String). This is optional.

  • project (String) (defaults to: nil)

    The project of the Key. This is optional.

  • namespace (String) (defaults to: nil)

    namespace kind of the Key. This is optional.

Returns:



412
413
414
415
416
417
418
419
420
421
422
# File 'lib/google/cloud/datastore/read_only_transaction.rb', line 412

def key *path, project: nil, namespace: nil
  path = path.flatten.each_slice(2).to_a # group in pairs
  kind, id_or_name = path.pop
  Key.new(kind, id_or_name).tap do |k|
    k.project = project
    k.namespace = namespace
    unless path.empty?
      k.parent = key path, project: project, namespace: namespace
    end
  end
end

#query(*kinds) ⇒ Google::Cloud::Datastore::Query

Create a new Query instance. This is a convenience method to make the creation of Query objects easier.

Examples:

require "google/cloud/datastore"

datastore = Google::Cloud::Datastore.new

datastore.read_only_transaction do |tx|
  query = tx.query("Task").
    where("done", "=", false)
  tasks = tx.run query
end

Parameters:

  • kinds (String)

    The kind of entities to query. This is optional.

Returns:



297
298
299
300
301
# File 'lib/google/cloud/datastore/read_only_transaction.rb', line 297

def query *kinds
  query = Query.new
  query.kind(*kinds) unless kinds.empty?
  query
end

#reset!Object

Reset the transaction. #start must be called afterwards.



274
275
276
# File 'lib/google/cloud/datastore/read_only_transaction.rb', line 274

def reset!
  @id = nil
end

#rollbackObject

Rolls back the transaction.

Examples:

require "google/cloud/datastore"

datastore = Google::Cloud::Datastore.new

task_list_key = datastore.key "TaskList", "default"

tx = datastore.transaction
task_list = tx.find task_list_key
if task_list
  query = tx.query("Task").
    ancestor(task_list_key)
  tasks = tx.run query
end
tx.rollback


261
262
263
264
265
266
267
268
269
# File 'lib/google/cloud/datastore/read_only_transaction.rb', line 261

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

  ensure_service!
  service.rollback @id
  true
end

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

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

Examples:

require "google/cloud/datastore"

datastore = Google::Cloud::Datastore.new

datastore.read_only_transaction do |tx|
  query = tx.query("Task").
    where("done", "=", false)
  tasks = tx.run query
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:



157
158
159
160
161
162
163
164
165
166
# File 'lib/google/cloud/datastore/read_only_transaction.rb', line 157

def run query, namespace: nil
  ensure_service!
  unless query.is_a?(Query) || query.is_a?(GqlQuery)
    raise ArgumentError, "Cannot run a #{query.class} object."
  end
  query_res = service.run_query query.to_grpc, namespace,
                                transaction: @id
  Dataset::QueryResults.from_grpc query_res, service, namespace,
                                  query.to_grpc.dup
end

#run_aggregation(aggregate_query, namespace: nil) ⇒ Google::Cloud::Datastore::Dataset::AggregateQueryResults

Retrieve aggregate query results specified by an AggregateQuery. The query is run within the transaction.

Examples:

require "google/cloud/datastore"

datastore = Google::Cloud::Datastore.new

datastore.read_only_transaction do |tx|
  query = tx.query("Task")
            .where("done", "=", false)
  aggregate_query = query.aggregate_query
                         .add_count
  res = tx.run_aggregation aggregate_query
end

Parameters:

  • query (AggregateQuery, GqlQuery)

    The Query object with the search criteria.

  • namespace (String) (defaults to: nil)

    The namespace the query is to run within.

Returns:



191
192
193
194
195
196
197
198
# File 'lib/google/cloud/datastore/read_only_transaction.rb', line 191

def run_aggregation aggregate_query, namespace: nil
  ensure_service!
  unless aggregate_query.is_a?(AggregateQuery) || aggregate_query.is_a?(GqlQuery)
    raise ArgumentError, "Cannot run a #{aggregate_query.class} object."
  end
  aggregate_query_results = service.run_aggregation_query aggregate_query.to_grpc, namespace, transaction: @id
  Dataset::AggregateQueryResults.from_grpc aggregate_query_results
end

#startObject Also known as: begin_transaction

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

Raises:



204
205
206
207
208
209
# File 'lib/google/cloud/datastore/read_only_transaction.rb', line 204

def start
  raise TransactionError, "Transaction already opened." unless @id.nil?
  ensure_service!
  tx_res = service.begin_transaction read_only: true, read_time: @read_time
  @id = tx_res.transaction
end