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::IN, Constants::LESS_THAN, Constants::LESS_THAN_OR_EQUAL, Constants::NOT_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.



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

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

Instance Method Details

#ancestorObject



337
338
339
# File 'lib/appengine-apis/datastore.rb', line 337

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.



353
354
355
356
357
358
# File 'lib/appengine-apis/datastore.rb', line 353

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.



516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
# File 'lib/appengine-apis/datastore.rb', line 516

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.



432
433
434
# File 'lib/appengine-apis/datastore.rb', line 432

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



454
455
456
457
458
459
# File 'lib/appengine-apis/datastore.rb', line 454

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



443
444
445
446
447
# File 'lib/appengine-apis/datastore.rb', line 443

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.



476
477
478
479
480
481
# File 'lib/appengine-apis/datastore.rb', line 476

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



389
390
391
392
393
394
395
396
# File 'lib/appengine-apis/datastore.rb', line 389

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.



422
423
424
# File 'lib/appengine-apis/datastore.rb', line 422

def filter_predicates
  @query.getFilterPredicates
end

#inspectObject



534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
# File 'lib/appengine-apis/datastore.rb', line 534

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



465
466
467
468
469
470
# File 'lib/appengine-apis/datastore.rb', line 465

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.



495
496
497
# File 'lib/appengine-apis/datastore.rb', line 495

def java_query
  @query
end

#kindObject



332
333
334
# File 'lib/appengine-apis/datastore.rb', line 332

def kind
  @query.kind
end

#pquery(transaction = :current) ⇒ Object

Returns a Java.ComGoogleAppengineApiDatastore.PreparedQuery for this query.



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

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.



375
376
377
378
# File 'lib/appengine-apis/datastore.rb', line 375

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)



415
416
417
418
419
# File 'lib/appengine-apis/datastore.rb', line 415

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.



427
428
429
# File 'lib/appengine-apis/datastore.rb', line 427

def sort_predicates
  @query.getSortPredicates
end