Class: Gcloud::Datastore::Dataset::QueryResults

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

Overview

QueryResults is a special case Array with additional values. A QueryResults object is returned from Dataset#run and contains the Entities from the query as well as the query’s cursor and more_results value.

Please be cautious when treating the QueryResults as an Array. Many common Array methods will return a new Array instance.

Examples:

require "gcloud"

gcloud = Gcloud.new
datastore = gcloud.datastore

query = datastore.query("Task")
tasks = datastore.run query

tasks.size #=> 3
tasks.cursor #=> Gcloud::Datastore::Cursor(c3VwZXJhd2Vzb21lIQ)

Caution, many Array methods will return a new Array instance:

require "gcloud"

gcloud = Gcloud.new
datastore = gcloud.datastore

query = datastore.query("Task")
tasks = datastore.run query

tasks.size #=> 3
tasks.end_cursor #=> Gcloud::Datastore::Cursor(c3VwZXJhd2Vzb21lIQ)
descriptions = tasks.map { |task| task["description"] }
descriptions.size #=> 3
descriptions.cursor #=> NoMethodError

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(arr = []) ⇒ QueryResults



114
115
116
# File 'lib/gcloud/datastore/dataset/query_results.rb', line 114

def initialize arr = []
  super arr
end

Instance Attribute Details

#cursorsObject



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

def cursors
  @cursors
end

#end_cursorGcloud::Datastore::Cursor Also known as: cursor

The end_cursor of the QueryResults.



62
63
64
# File 'lib/gcloud/datastore/dataset/query_results.rb', line 62

def end_cursor
  @end_cursor
end

#more_resultsObject

The state of the query after the current batch.

Expected values are:

  • ‘:NOT_FINISHED`

  • ‘:MORE_RESULTS_AFTER_LIMIT`

  • ‘:MORE_RESULTS_AFTER_CURSOR`

  • ‘:NO_MORE_RESULTS`



74
75
76
# File 'lib/gcloud/datastore/dataset/query_results.rb', line 74

def more_results
  @more_results
end

#namespaceObject



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

def namespace
  @namespace
end

#queryObject



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

def query
  @query
end

#serviceObject



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

def service
  @service
end

Class Method Details

.from_grpc(query_res, service, namespace, query) ⇒ Object

Google::Dataset::V1beta3::RunQueryResponse object.



358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
# File 'lib/gcloud/datastore/dataset/query_results.rb', line 358

def self.from_grpc query_res, service, namespace, query
  r, c = Array(query_res.batch.entity_results).map do |result|
    [Entity.from_grpc(result.entity), Cursor.from_grpc(result.cursor)]
  end.transpose
  r ||= []
  c ||= []
  new(r).tap do |qr|
    qr.cursors = c
    qr.end_cursor = Cursor.from_grpc query_res.batch.end_cursor
    qr.more_results = query_res.batch.more_results
    qr.service = service
    qr.namespace = namespace
    qr.query = query_res.query || query
  end
end

Instance Method Details

#all(request_limit: nil) {|result| ... } ⇒ Enumerator

Retrieves all query results by repeatedly loading #next until #next? returns ‘false`. Calls the given block once for each query result, which is passed as the parameter.

An Enumerator is returned if no block is given.

This method may make several API calls until all query results are retrieved. Be sure to use as narrow a search criteria as possible. Please use with caution.

Examples:

Iterating each query result by passing a block:

require "gcloud"

gcloud = Gcloud.new
datastore = gcloud.datastore
query = datastore.query "Task"
tasks = datastore.run query
tasks.all do |task|
  puts "Task #{task.key.id} (#cursor)"
end

Using the enumerator by not passing a block:

require "gcloud"

gcloud = Gcloud.new
datastore = gcloud.datastore
query = datastore.query "Task"
tasks = datastore.run query
tasks.all.map(&:key).each do |key|
  puts "Key #{key.id}"
end

Limit the number of API calls made:

require "gcloud"

gcloud = Gcloud.new
datastore = gcloud.datastore
query = datastore.query "Task"
tasks = datastore.run query
tasks.all(request_limit: 10) do |task|
  puts "Task #{task.key.id} (#cursor)"
end

Yields:

  • (result)

    The block for accessing each query result.

Yield Parameters:

  • result (Entity)

    The query result object.



269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
# File 'lib/gcloud/datastore/dataset/query_results.rb', line 269

def all request_limit: nil
  request_limit = request_limit.to_i if request_limit
  unless block_given?
    return enum_for(:all, request_limit: request_limit)
  end
  results = self
  loop do
    results.each { |r| yield r }
    if request_limit
      request_limit -= 1
      break if request_limit < 0
    end
    break unless results.next?
    results = results.next
  end
end

#all_with_cursor(request_limit: nil) {|result, cursor| ... } ⇒ Enumerator

Retrieves all query results and cursors by repeatedly loading #next until #next? returns ‘false`. Calls the given block once for each result and cursor combination, which are passed as parameters.

An Enumerator is returned if no block is given.

This method may make several API calls until all query results are retrieved. Be sure to use as narrow a search criteria as possible. Please use with caution.

Examples:

Iterating all results and cursors by passing a block:

require "gcloud"

gcloud = Gcloud.new
datastore = gcloud.datastore
query = datastore.query "Task"
tasks = datastore.run query
tasks.all_with_cursor do |task, cursor|
  puts "Task #{task.key.id} (#cursor)"
end

Using the enumerator by not passing a block:

require "gcloud"

gcloud = Gcloud.new
datastore = gcloud.datastore
query = datastore.query "Task"
tasks = datastore.run query
tasks.all_with_cursor.count #=> number of result/cursor pairs

Limit the number of API calls made:

require "gcloud"

gcloud = Gcloud.new
datastore = gcloud.datastore
query = datastore.query "Task"
tasks = datastore.run query
tasks.all_with_cursor(request_limit: 10) do |task, cursor|
  puts "Task #{task.key.id} (#cursor)"
end

Yields:

  • (result, cursor)

    The block for accessing each query result and cursor.

Yield Parameters:

  • result (Entity)

    The query result object.

  • cursor (Cursor)

    The cursor object.



337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
# File 'lib/gcloud/datastore/dataset/query_results.rb', line 337

def all_with_cursor request_limit: nil
  request_limit = request_limit.to_i if request_limit
  unless block_given?
    return enum_for(:all_with_cursor, request_limit: request_limit)
  end
  results = self

  loop do
    results.zip(results.cursors).each { |r, c| yield r, c }
    if request_limit
      request_limit -= 1
      break if request_limit < 0
    end
    break unless results.next?
    results = results.next
  end
end

#cursor_for(result) ⇒ Cursor

Retrieve the Cursor for the provided result.

Examples:

require "gcloud"

gcloud = Gcloud.new
datastore = gcloud.datastore
query = datastore.query "Task"
tasks = datastore.run query

first_task = tasks.first
first_cursor = tasks.cursor_for first_task


183
184
185
186
187
# File 'lib/gcloud/datastore/dataset/query_results.rb', line 183

def cursor_for result
  cursor_index = index result
  return nil if cursor_index.nil?
  cursors[cursor_index]
end

#each_with_cursor {|result, cursor| ... } ⇒ Enumerator

Calls the given block once for each result and cursor combination, which are passed as parameters.

An Enumerator is returned if no block is given.

Examples:

require "gcloud"

gcloud = Gcloud.new
datastore = gcloud.datastore
query = datastore.query "Task"
tasks = datastore.run query
tasks.each_with_cursor do |task, cursor|
  puts "Task #{task.key.id} (#cursor)"
end

Yields:

  • (result, cursor)

    The block for accessing each query result and cursor.

Yield Parameters:

  • result (Entity)

    The query result object.

  • cursor (Cursor)

    The cursor object.



213
214
215
216
# File 'lib/gcloud/datastore/dataset/query_results.rb', line 213

def each_with_cursor
  return enum_for(:each_with_cursor) unless block_given?
  zip(cursors).each { |r, c| yield [r, c] }
end

#more_after_cursor?Boolean

Convenience method for determining if the ‘more_results` value is `:MORE_RESULTS_AFTER_CURSOR`



101
102
103
# File 'lib/gcloud/datastore/dataset/query_results.rb', line 101

def more_after_cursor?
  more_results == :MORE_RESULTS_AFTER_CURSOR
end

#more_after_limit?Boolean

Convenience method for determining if the ‘more_results` value is `:MORE_RESULTS_AFTER_LIMIT`



94
95
96
# File 'lib/gcloud/datastore/dataset/query_results.rb', line 94

def more_after_limit?
  more_results == :MORE_RESULTS_AFTER_LIMIT
end

#nextQueryResults

Retrieve the next page of results.

Examples:

require "gcloud"

gcloud = Gcloud.new
datastore = gcloud.datastore
query = datastore.query "Task"
tasks = datastore.run query

if tasks.next?
  next_tasks = tasks.next
end


156
157
158
159
160
161
162
163
# File 'lib/gcloud/datastore/dataset/query_results.rb', line 156

def next
  return nil unless next?
  return nil if end_cursor.nil?
  ensure_service!
  query.start_cursor = cursor.to_grpc # should always be a Cursor...
  query_res = service.run_query query, namespace
  self.class.from_grpc query_res, service, namespace, query
end

#next?Boolean

Whether there are more results available.

Examples:

require "gcloud"

gcloud = Gcloud.new
datastore = gcloud.datastore
query = datastore.query "Task"
tasks = datastore.run query

if tasks.next?
  next_tasks = tasks.next
end


135
136
137
# File 'lib/gcloud/datastore/dataset/query_results.rb', line 135

def next?
  not_finished?
end

#no_more?Boolean

Convenience method for determining if the ‘more_results` value is `:NO_MORE_RESULTS`



108
109
110
# File 'lib/gcloud/datastore/dataset/query_results.rb', line 108

def no_more?
  more_results == :NO_MORE_RESULTS
end

#not_finished?Boolean

Convenience method for determining if the ‘more_results` value is `:NOT_FINISHED`



87
88
89
# File 'lib/gcloud/datastore/dataset/query_results.rb', line 87

def not_finished?
  more_results == :NOT_FINISHED
end