Class: Gcloud::Datastore::Dataset

Inherits:
Object
  • Object
show all
Defined in:
lib/gcloud/datastore/dataset.rb,
lib/gcloud/datastore/dataset/query_results.rb,
lib/gcloud/datastore/dataset/lookup_results.rb

Overview

# Dataset

Dataset is the data saved in a project’s Datastore. Dataset is analogous to a database in relational database world.

Gcloud::Datastore::Dataset is the main object for interacting with Google Datastore. Entity objects are created, read, updated, and deleted by Gcloud::Datastore::Dataset.

See Gcloud#datastore

Examples:

require "gcloud"

gcloud = Gcloud.new
dataset = gcloud.datastore

query = dataset.query("Task").
  where("completed", "=", true)

tasks = dataset.run query

Direct Known Subclasses

Transaction

Defined Under Namespace

Classes: LookupResults, QueryResults

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(project, credentials) ⇒ Dataset



59
60
61
62
63
# File 'lib/gcloud/datastore/dataset.rb', line 59

def initialize project, credentials
  project = project.to_s # Always cast to a string
  fail ArgumentError, "project is missing" if project.empty?
  @connection = Connection.new project, credentials
end

Instance Attribute Details

#connectionObject



53
54
55
# File 'lib/gcloud/datastore/dataset.rb', line 53

def connection
  @connection
end

Class Method Details

.default_projectObject



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

def self.default_project
  ENV["DATASTORE_DATASET"] ||
    ENV["DATASTORE_PROJECT"] ||
    ENV["GCLOUD_PROJECT"] ||
    ENV["GOOGLE_CLOUD_PROJECT"] ||
    Gcloud::GCE.project_id
end

Instance Method Details

#allocate_ids(incomplete_key, count = 1) ⇒ Array<Gcloud::Datastore::Key>

Generate IDs for a Key before creating an entity.

Examples:

empty_key = dataset.key "Task"
task_keys = dataset.allocate_ids empty_key, 5

Parameters:

  • incomplete_key (Key)

    A Key without ‘id` or `name` set.

  • count (String) (defaults to: 1)

    The number of new key IDs to create.

Returns:



103
104
105
106
107
108
109
110
111
112
113
# File 'lib/gcloud/datastore/dataset.rb', line 103

def allocate_ids incomplete_key, count = 1
  if incomplete_key.complete?
    fail Gcloud::Datastore::Error, "An incomplete key must be provided."
  end

  incomplete_keys = count.times.map { incomplete_key.to_proto }
  response = connection.allocate_ids(*incomplete_keys)
  Array(response.key).map do |key|
    Key.from_proto key
  end
end

#commit {|commit| ... } ⇒ Array<Gcloud::Datastore::Entity>

Make multiple changes in a single commit.

Examples:

dataset.commit do |c|
  c.save task1, task2
  c.delete entity1, entity2
end

Yields:

  • (commit)

    a block for making changes

Yield Parameters:

  • commit (Commit)

    The object that changes are made on

Returns:



162
163
164
165
166
167
168
169
170
171
172
173
# File 'lib/gcloud/datastore/dataset.rb', line 162

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

#delete(*entities_or_keys) ⇒ Boolean

Remove entities from the Datastore.

Examples:

gcloud = Gcloud.new
dataset = gcloud.datastore
dataset.delete entity1, entity2

Parameters:

  • entities_or_keys (Entity, Key)

    One or more Entity or Key objects to remove.

Returns:

  • (Boolean)

    Returns ‘true` if successful



142
143
144
145
# File 'lib/gcloud/datastore/dataset.rb', line 142

def delete *entities_or_keys
  commit { |c| c.delete(*entities_or_keys) }
  true
end

#entity(key_or_kind = nil, id_or_name = nil) {|entity| ... } ⇒ Gcloud::Datastore::Entity

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

end

Examples:

entity = dataset.entity

The previous example is equivalent to:

entity = Gcloud::Datastore::Entity.new

The key can also be passed in as an object:

key = dataset.key "User", "[email protected]"
entity = dataset.entity key

Or the key values can be passed in as parameters:

entity = dataset.entity "User", "[email protected]"

The previous example is equivalent to:

key = Gcloud::Datastore::Key.new "User", "[email protected]"
entity = Gcloud::Datastore::Entity.new
entity.key = key

The newly created entity can also be configured using a block:

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

The previous example is equivalent to:

key = Gcloud::Datastore::Key.new "User", "[email protected]"
entity = Gcloud::Datastore::Entity.new
entity.key = key
entity["name"] = "Heidi Henderson"

Parameters:

  • key_or_kind (Key, String, nil) (defaults to: nil)

    A Key object or ‘kind` string value. This is optional.

  • id_or_name (Integer, String, nil) (defaults to: nil)

    The Key’s ‘id` or `name` value if a `kind` was provided in the first parameter.

Yields:

  • (entity)

    a block yielding a new entity

Yield Parameters:

  • entity (Entity)

    the newly created entity object

Returns:



429
430
431
432
433
434
435
436
437
438
439
440
441
442
# File 'lib/gcloud/datastore/dataset.rb', line 429

def entity key_or_kind = nil, id_or_name = nil
  entity = Entity.new

  # Set the key
  key = key_or_kind
  unless key.is_a? Gcloud::Datastore::Key
    key = Key.new key_or_kind, id_or_name
  end
  entity.key = key

  yield entity if block_given?

  entity
end

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

Retrieve an entity by providing key information.

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.

  • id_or_name (Integer, String, nil) (defaults to: nil)

    The Key’s ‘id` or `name` value if a `kind` was provided in the first parameter.

  • consistency (Symbol) (defaults to: nil)

    The non-transactional read consistency to use. Cannot be set to ‘:strong` for global queries. Accepted values are `:eventual` and `:strong`.

    The default consistency depends on the type of lookup used. See [Eventual Consistency in Google Cloud Datastore](cloud.google.com/datastore/docs/articles/balancing-strong-and-eventual-consistency-with-google-cloud-datastore/#h.tf76fya5nqk8) for more information.

Returns:



199
200
201
202
203
204
205
# File 'lib/gcloud/datastore/dataset.rb', line 199

def find key_or_kind, id_or_name = nil, consistency: 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, consistency: consistency).first
end

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

Retrieve the entities for the provided keys.

Examples:

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

Parameters:

Returns:



230
231
232
233
234
235
236
237
238
# File 'lib/gcloud/datastore/dataset.rb', line 230

def find_all *keys, consistency: nil
  check_consistency! consistency
  response = connection.lookup(*keys.map(&:to_proto),
                               consistency: consistency)
  entities = to_gcloud_entities response.found
  deferred = to_gcloud_keys response.deferred
  missing  = to_gcloud_entities response.missing
  LookupResults.new entities, deferred, missing
end

#key(kind = nil, id_or_name = nil) ⇒ Gcloud::Datastore::Key

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

Examples:

key = dataset.key "User", "[email protected]"

The previous example is equivalent to:

key = Gcloud::Datastore::Key.new "User", "[email protected]"

Parameters:

  • kind (String) (defaults to: nil)

    The kind of the Key. This is optional.

  • id_or_name (Integer, String) (defaults to: nil)

    The id or name of the Key. This is optional.

Returns:



383
384
385
# File 'lib/gcloud/datastore/dataset.rb', line 383

def key kind = nil, id_or_name = nil
  Key.new kind, id_or_name
end

#projectObject

The Datastore project connected to.

Examples:

require "gcloud"

gcloud = Gcloud.new "my-todo-project",
                    "/path/to/keyfile.json"

dataset = gcloud.datastore
dataset.project #=> "my-todo-project"


77
78
79
# File 'lib/gcloud/datastore/dataset.rb', line 77

def project
  connection.dataset_id
end

#query(*kinds) ⇒ Gcloud::Datastore::Query

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

Examples:

query = dataset.query("Task").
  where("completed", "=", true)
tasks = dataset.run query

The previous example is equivalent to:

query = Gcloud::Datastore::Query.new.
  kind("Task").
  where("completed", "=", true)
tasks = dataset.run query

Parameters:

  • kinds (String)

    The kind of entities to query. This is optional.

Returns:



361
362
363
364
365
# File 'lib/gcloud/datastore/dataset.rb', line 361

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

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

Retrieve entities specified by a Query.

Examples:

query = dataset.query("Task").
  where("completed", "=", true)
tasks = dataset.run query

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

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

Parameters:

Returns:



267
268
269
270
271
272
273
274
275
276
# File 'lib/gcloud/datastore/dataset.rb', line 267

def run query, namespace: nil, consistency: nil
  partition = optional_partition_id namespace
  check_consistency! consistency
  response = connection.run_query query.to_proto, partition,
                                  consistency: consistency
  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) ⇒ Array<Gcloud::Datastore::Entity>

Persist one or more entities to the Datastore.

Examples:

dataset.save task1, task2

Parameters:

  • entities (Entity)

    One or more entity objects to be saved.

Returns:



125
126
127
# File 'lib/gcloud/datastore/dataset.rb', line 125

def save *entities
  commit { |c| c.save(*entities) }
end

#transaction {|tx| ... } ⇒ Object

Creates a Datastore Transaction.

Examples:

Runs the given block in a database transaction:

require "gcloud"

gcloud = Gcloud.new
dataset = gcloud.datastore

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

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

If no block is given, a Transaction object is returned:

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

Yields:

  • (tx)

    a block yielding a new transaction

Yield Parameters:



323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
# File 'lib/gcloud/datastore/dataset.rb', line 323

def transaction
  tx = Transaction.new connection
  return tx unless block_given?

  begin
    yield tx
    tx.commit
  rescue => e
    begin
      tx.rollback
    rescue => re
      msg = "Transaction failed to commit and rollback."
      raise TransactionError.new(msg, commit_error: e, rollback_error: re)
    end
    raise TransactionError.new("Transaction failed to commit.",
                               commit_error: e)
  end
end