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 ascending
Then should support ordering by attribute descending Then should support ordering by attribute descending
Then should order by attribute ascending by default 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 Then /^should initialize with an attribute and an operator$/ do
selector = ::Middleman::Sitemap::Queryable::Selector.new :attribute => :author, :operator => 'equal' selector = ::Middleman::Sitemap::Queryable::Selector.new :attribute => :author, :operator => 'equal'
:author.should == selector.attribute :author.should == selector.attribute
@ -120,4 +132,4 @@ end
Then /^should exclude documents that do not own the attribute$/ do Then /^should exclude documents that do not own the attribute$/ do
found_documents = @server_inst.sitemap.order_by(:status).all found_documents = @server_inst.sitemap.order_by(:status).all
found_documents.map { |r| r.raw_data[:id] }.to_set.should == [1,2].to_set 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 end
class Query class Query
def initialize(model) def initialize(model, opts={})
@model = model @model = model
@where = {} @where = opts[:where] || {}
@order_by = opts[:order_by]
@offset = opts[:offset]
@limit = opts[:limit]
end end
def where(constraints_hash) def where(constraints_hash)
@ -77,23 +80,27 @@ module Middleman
selector = Selector.new(:attribute => attribute, :operator => 'equal') selector = Selector.new(:attribute => attribute, :operator => 'equal')
selector_hash.update({ selector => value }) selector_hash.update({ selector => value })
end end
@where.merge! selector_hash Query.new @model, opts(:where => @where.merge(selector_hash))
self end
def opts new_opts
{ :where => {}.merge(@where),
:order_by => @order_by,
:offset => @offset,
:limit => @limit
}.merge(new_opts)
end end
def order_by(field) def order_by(field)
@order_by = field.is_a?(Symbol) ? {field => :asc} : field Query.new @model, opts(:order_by => field.is_a?(Symbol) ? {field => :asc} : field)
self
end end
def offset(number) def offset(number)
@offset = number Query.new @model, opts(:offset => number)
self
end end
def limit(number) def limit(number)
@limit = number Query.new @model, opts(:limit => number)
self
end end
def first def first
@ -145,4 +152,4 @@ class Symbol
self.to_s <=> other.to_s self.to_s <=> other.to_s
end end
end end
end end