lib/ddr/index/query_builder.rb in ddr-models-3.0.0.beta.3 vs lib/ddr/index/query_builder.rb in ddr-models-3.0.0.beta.4
- old
+ new
@@ -1,74 +1,194 @@
module Ddr::Index
+ #
+ # QueryBuilder - Provides a DSL for building a Query.
+ #
+ # Note: Where a method receives a [field] parameter, the parameter value is
+ # coerced to a Field instance. See FieldAttribute#coerce for details.
+ #
+ # *** DSL METHODS ***
+ #
+ # absent [field]
+ # Adds a filter selecting documents where the field is not present (no values).
+ #
+ # asc [field], ...
+ # Adds ascending orderings by the fields specified.
+ #
+ # See also: desc, order_by
+ #
+ # before [field], [date_time]
+ # Adds a filter selecting documents where the field has a date/time before
+ # (earlier than) the value.
+ #
+ # before_days [field], [int]
+ # Adds a filter selecting documents where the field has a date/time the
+ # specified number of days before today (now) or earlier.
+ #
+ # desc [field], ...
+ # Adds descending orderings by the fields specified.
+ #
+ # See also: asc, order_by
+ #
+ # id [doc_id]
+ # For selecting a single document by ID.
+ #
+ # filter [filter1], ...
+ # Adds filters to the query.
+ #
+ # Aliased as: filters
+ #
+ # filters [filter], ...
+ # Alias for: filter
+ #
+ # field [field1], ...
+ # Adds fields to result documents.
+ # Note that all fields are returned when none is specified.
+ #
+ # Aliased as: fields
+ #
+ # fields [field], ...
+ # Alias for: field
+ #
+ # limit [int]
+ # Limits the number of documents returned by the query.
+ #
+ # Aliased as: rows
+ #
+ # model [model_name], ...
+ # Adds a filter selecting document where ActiveFedora model equals value
+ # or one of the values.
+ #
+ # negative [field], [value]
+ # Adds a filter selecting document where field does not have the value.
+ #
+ # order_by [{field => order, ...}], ...
+ # Adds ordering(s) to the query.
+ #
+ # Aliased as: sort
+ #
+ # present [field]
+ # Adds a filter selecting document where the field has any value.
+ #
+ # q [query_clause]
+ # Sets a query clause for the `q` parameter.
+ #
+ # raw [clause1], ...
+ # Adds a filter of "raw" query clauses (i.e., pre-constructed).
+ #
+ # rows [int]
+ # Alias for: limit
+ #
+ # sort [{field => order, ...}]
+ # Alias for: order_by
+ #
+ # term [{field => value, ...}]
+ # Adds a filter of "term" query clauses for the fields and values.
+ #
+ # where [{field => value, ...}]
+ # Adds a filter of "standard" query clauses.
+ # Values will be escaped when the filter is serialized.
+ # If a hash value is an array, that query clause will select documents
+ # where the field matches any array entry.
+ #
class QueryBuilder
+ # Builds a Query object
+ # @yield [builder] a new QueryBuilder instance.
+ # @return [Query]
def self.build
+ Deprecation.warn(self,
+ "`Ddr::Index::QueryBuilder.build` is deprecated and will be removed in ddr-models 3.0." \
+ " Use `Ddr::Index::QueryBuilder.new` instead.")
builder = new
yield builder
builder.query
end
- def initialize
- @q = nil
- @fields = [ ]
- @filters = [ ]
- @sort = [ ]
- @rows = nil
- end
+ attr_reader :query
- def query
- Query.new.tap do |qry|
- instance_variables.each do |var|
- qry.instance_variable_set(var, instance_variable_get(var))
- end
+ def initialize(query = nil, &block)
+ @query = query || Query.new
+ if block_given?
+ instance_eval &block
end
end
+ # @param pid [String]
+ # @return [QueryBuilder]
def id(pid)
q QueryClause.id(pid)
limit 1
end
- def filter(*fltrs)
- @filters.push *fltrs
+ # @param filters [Array<Filter>]
+ # @return [QueryBuilder]
+ def filter(*filters)
+ query.filters += filters
self
end
+ alias_method :filters, :filter
- def fields(*flds)
- @fields.push *flds
+ # @param fields [Array<Field>]
+ # @return [QueryBuilder] self
+ def field(*fields)
+ query.fields += fields.flatten.map { |f| FieldAttribute.coerce(f) }
self
end
+ alias_method :fields, :field
+ # @param num [Integer]
+ # @return [QueryBuilder] self
def limit(num)
- @rows = num
+ query.rows = num.to_i
self
end
+ alias_method :rows, :limit
- def order_by(field, order)
- @sort << [field, order].join(" ")
+ # @param orderings [Hash<Field, String>]
+ # @return [QueryBuilder] self
+ def order_by(*orderings)
+ unless orderings.first.is_a? Hash
+ Deprecation.warn(QueryBuilder, "`order_by` will require a hash of orderings in ddr-models 3.0.")
+ field, order = orderings
+ return order_by(field => order)
+ end
+ query.sort += orderings.first.map { |field, order| SortOrder.new(field: field, order: order) }
self
end
+ alias_method :sort, :order_by
- def asc(field)
- order_by field, "asc"
+ # @param fields [Array<Field, Symbol, String>]
+ # @return [QueryBuilder] self
+ def asc(*fields)
+ query.sort += fields.map { |field| SortOrder.asc(field) }
+ self
end
-
- def desc(field)
- order_by field, "desc"
+ # @param fields [Array<Field, Symbol, String>]
+ # @return [QueryBuilder] self
+ def desc(*fields)
+ query.sort += fields.map { |field| SortOrder.desc(field) }
+ self
end
- def q(q)
- @q = q
+ # @param query_clause [QueryClause, String]
+ # @return [QueryBuilder] self
+ def q(query_clause)
+ query.q = query_clause
self
end
- protected
+ private
+ def respond_to_missing?(name, include_all)
+ Filter::ClassMethods.public_instance_methods.include?(name)
+ end
+
def method_missing(name, *args, &block)
- if Filter.respond_to? name
- return filter Filter.send(name, *args, &block)
+ if respond_to?(name)
+ filter Filter.send(name, *args)
+ else
+ super
end
- super
end
end
end