Merge pull request #1060 from mootpointer/queryable_mutation_fix

Update queryable interface so that it doesn't mutate
This commit is contained in:
Thomas Reynolds 2013-10-29 09:22:01 -07:00
commit 2097055502
3 changed files with 36 additions and 13 deletions

View file

@ -28,4 +28,8 @@ Feature: Queryable Selector
Then should support ordering by attribute ascending
Then should support ordering by attribute descending
Then should order by attribute ascending by default
Then should exclude documents that do not own the attribute
Then should exclude documents that do not own the attribute
Scenario: Passing queries around
Given a simple 'where' query
When I chain a where clause onto that query
Then the original query should remain unchanged

View file

@ -1,3 +1,15 @@
Given /^a simple 'where' query$/ do
@query = Middleman::Sitemap::Queryable::Query.new({}).where(:foo => 'bar')
end
When /^I chain a where clause onto that query$/ do
@new_query = @query.where(:baz => 'foo')
end
Then /^the original query should remain unchanged$/ do
@query.opts({}).should_not eql @new_query.opts({})
end
Then /^should initialize with an attribute and an operator$/ do
selector = ::Middleman::Sitemap::Queryable::Selector.new :attribute => :author, :operator => 'equal'
:author.should == selector.attribute
@ -120,4 +132,4 @@ end
Then /^should exclude documents that do not own the attribute$/ do
found_documents = @server_inst.sitemap.order_by(:status).all
found_documents.map { |r| r.raw_data[:id] }.to_set.should == [1,2].to_set
end
end

View file

@ -65,9 +65,12 @@ module Middleman
end
class Query
def initialize(model)
def initialize(model, opts={})
@model = model
@where = {}
@where = opts[:where] || {}
@order_by = opts[:order_by]
@offset = opts[:offset]
@limit = opts[:limit]
end
def where(constraints_hash)
@ -77,23 +80,27 @@ module Middleman
selector = Selector.new(:attribute => attribute, :operator => 'equal')
selector_hash.update({ selector => value })
end
@where.merge! selector_hash
self
Query.new @model, opts(:where => @where.merge(selector_hash))
end
def opts new_opts
{ :where => {}.merge(@where),
:order_by => @order_by,
:offset => @offset,
:limit => @limit
}.merge(new_opts)
end
def order_by(field)
@order_by = field.is_a?(Symbol) ? {field => :asc} : field
self
Query.new @model, opts(:order_by => field.is_a?(Symbol) ? {field => :asc} : field)
end
def offset(number)
@offset = number
self
Query.new @model, opts(:offset => number)
end
def limit(number)
@limit = number
self
Query.new @model, opts(:limit => number)
end
def first
@ -145,4 +152,4 @@ class Symbol
self.to_s <=> other.to_s
end
end
end
end