Class: AppEngine::Datastore::Query

Inherits:
Object
  • Object
show all
Includes:
Constants
Defined in:
lib/appengine-apis/datastore.rb

Overview

Query encapsulates a request for zero or more Entity objects out of the datastore. It supports querying on zero or more properties, querying by ancestor, and sorting.

Entity objects which match the query can be retrieved in a single list, or with an unbounded iterator.

A Query does not cache results. Each use of the Query results in a new trip to the Datastore.

Defined Under Namespace

Modules: Constants

Constant Summary collapse

JQuery =
JavaDatastore::Query
FetchOptions =
JavaDatastore::FetchOptions

Constants included from Constants

Constants::ASCENDING, Constants::DESCENDING, Constants::EQUAL, Constants::GREATER_THAN, Constants::GREATER_THAN_OR_EQUAL, Constants::LESS_THAN, Constants::LESS_THAN_OR_EQUAL, Constants::OP_MAP

Instance Method Summary collapse

Constructor Details

#initialize(*args) ⇒ Query

call-seq:

Query.new(kind)
Query.new(ancestor)
Query.new(kind, ancestor)

Creates a new Query with the specified kind and/or ancestor.

Args:

  • kind: String. Only return entities with this kind.

  • ancestor: Key. Only return entities with the given ancestor.



320
321
322
# File 'lib/appengine-apis/datastore.rb', line 320

def initialize(*args)
  @query = JQuery.new(*args)
end

Instance Method Details

#ancestorObject



329
330
331
# File 'lib/appengine-apis/datastore.rb', line 329

def ancestor
  @query.ancestor
end

#ancestor=(key) ⇒ Object

Sets an ancestor for this query.

This restricts the query to only return result entities that are descended from a given entity. In other words, all of the results will have the ancestor as their parent, or parent’s parent, or etc.

If nil is specified, unsets any previously-set ancestor.

Throws ArgumentError if the ancestor key is incomplete, or if you try to unset an ancestor and have not set a kind.



345
346
347
348
349
350
# File 'lib/appengine-apis/datastore.rb', line 345

def ancestor=(key)
  Datastore.convert_exceptions do
    @query.set_ancestor(key)
  end
  clear_cache
end

#convert_options(options) ⇒ Object

Converts an options hash into FetchOptions.

Supported options:

:limit

Maximum number of results the query will return

:offset

Number of result to skip before returning any results. Results that are skipped due to offset do not count against limit.

:chunk

Determines the internal chunking strategy of the iterator returned by #iterator. This affects only the performance of the query, not the actual results returned.

:transaction

Transaction in which the query should run. Only supported for ancestor queries. Uses the current transaction if not specified.



508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
# File 'lib/appengine-apis/datastore.rb', line 508

def convert_options(options)
  transaction = :current
  return [transaction, options] if options.java_kind_of? FetchOptions
  if options.include? :transaction
    transaction = options.delete(:transaction)
  end
  limit = options.delete(:limit)
  offset = options.delete(:offset)
  chunk_size = options.delete(:chunk) || FetchOptions::DEFAULT_CHUNK_SIZE
  unless options.empty?
    raise ArgumentError, "Unsupported options #{options.inspect}"
  end
  options = FetchOptions::Builder.with_chunk_size(chunk_size)
  options.offset(offset) if offset
  options.limit(limit) if limit
  [transaction, options]
end

#count(transaction = :current) ⇒ Object

Returns the number of entities that currently match this query.



424
425
426
# File 'lib/appengine-apis/datastore.rb', line 424

def count(transaction=:current)
  pquery(transaction).count_entities
end

#each(options = {}, &proc) ⇒ Object

Streams the matching entities from the datastore and yields each matching entity.

See #convert_options for supported options



446
447
448
449
450
451
# File 'lib/appengine-apis/datastore.rb', line 446

def each(options={}, &proc)  # :yields: entity
  transaction, options = convert_options(options)
  Datastore.convert_exceptions do
    pquery(transaction).as_iterator(options).each(&proc)
  end
end

#entity(transaction = :current) ⇒ Object

Retrieves the one and only result for the Query.

Throws TooManyResults if more than one result is returned from the Query.

Returns the single, matching result, or nil if no entities match



435
436
437
438
439
# File 'lib/appengine-apis/datastore.rb', line 435

def entity(transaction=:current)
  Datastore.convert_exceptions do
    pquery(transaction).as_single_entity
  end
end

#fetch(options = {}) ⇒ Object

Fetch all matching entities. For large result sets you should prefer #each or #iterator, which stream the results from the datastore.



468
469
470
471
472
473
# File 'lib/appengine-apis/datastore.rb', line 468

def fetch(options={})
  transaction, options = convert_options(options)
  Datastore.convert_exceptions do
    pquery(transaction).as_list(options)
  end      
end

#filter(name, operator, value) ⇒ Object

Add a filter on the specified property.

Note that entities with multi-value properties identified by name will match this filter if the multi-value property has at least one value that matches the condition expressed by operator and value. For more information on multi-value property filtering please see the datastore documentation



381
382
383
384
385
386
387
388
# File 'lib/appengine-apis/datastore.rb', line 381

def filter(name, operator, value)
  name = name.to_s if name.kind_of? Symbol
  operator = operator.to_s if operator.kind_of? Symbol
  operator = OP_MAP[operator]
  value = Datastore.ruby_to_java(value)
  @query.add_filter(name, operator, value)
  clear_cache
end

#filter_predicatesObject

Returns an unmodifiable list of the current filter predicates.



414
415
416
# File 'lib/appengine-apis/datastore.rb', line 414

def filter_predicates
  @query.getFilterPredicates
end

#inspectObject



526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
# File 'lib/appengine-apis/datastore.rb', line 526

def inspect
  output = "<Query("
  query = java_query
  output << query.kind if query.kind
  output << ", " if query.ancestor && query.kind
  output << query.ancestor.inspect if query.ancestor
  output << ")"
  query.filter_predicates.each do |pred|
    output << " (#{pred.property_name.inspect} #{pred.operator.name} #{pred.value.inspect})"
  end
  query.sort_predicates.each do |pred|
    output << " (ORDER BY #{pred.property_name.inspect} #{pred.direction.name})"
  end
  output
end

#iterator(options = {}) ⇒ Object

Returns an Enumerable over the matching entities.

See #convert_options for supported options



457
458
459
460
461
462
# File 'lib/appengine-apis/datastore.rb', line 457

def iterator(options={})
  transaction, options = convert_options(options)
  Datastore.convert_exceptions do
    pquery(transaction).as_iterator(options)
  end
end

#java_queryObject

Returns a Java.ComGoogleAppengineApiDatastore.Query for this query.



487
488
489
# File 'lib/appengine-apis/datastore.rb', line 487

def java_query
  @query
end

#kindObject



324
325
326
# File 'lib/appengine-apis/datastore.rb', line 324

def kind
  @query.kind
end

#pquery(transaction = :current) ⇒ Object

Returns a Java.ComGoogleAppengineApiDatastore.PreparedQuery for this query.



478
479
480
481
482
483
484
# File 'lib/appengine-apis/datastore.rb', line 478

def pquery(transaction=:current)
  @pquery ||= if transaction != :current
    Datastore.service.prepare(transaction, @query)
  else
    Datastore.service.prepare(@query)
  end
end

#set_ancestor(key) ⇒ Object

call-seq:

query.set_ancestor(key) -> query

Sets an ancestor for this query.

This restricts the query to only return result entities that are descended from a given entity. In other words, all of the results will have the ancestor as their parent, or parent’s parent, or etc.

If nil is specified, unsets any previously-set ancestor.

Throws ArgumentError if the ancestor key is incomplete, or if you try to unset an ancestor and have not set a kind.



367
368
369
370
# File 'lib/appengine-apis/datastore.rb', line 367

def set_ancestor(key)
  self.ancestor = key
  self
end

#sort(name, direction = ASCENDING) ⇒ Object

Specify how the query results should be sorted.

The first call to #sort will register the property that will serve as the primary sort key. A second call to #sort will set a secondary sort key, etc.

This method will sort in ascending order by defaul. To control the order of the sort, pass ASCENDING or DESCENDING as the direction.

Note that entities with multi-value properties identified by name will be sorted by the smallest value in the list. For more information on sorting properties with multiple values please see the datastore documentation.

Returns self (for chaining)



407
408
409
410
411
# File 'lib/appengine-apis/datastore.rb', line 407

def sort(name, direction=ASCENDING)
  name = name.to_s if name.kind_of? Symbol
  @query.add_sort(name, direction)
  clear_cache
end

#sort_predicatesObject

Returns an unmodifiable list of the current sort predicates.



419
420
421
# File 'lib/appengine-apis/datastore.rb', line 419

def sort_predicates
  @query.getSortPredicates
end