mirror of
https://github.com/middleman/middleman.git
synced 2022-11-09 12:20:27 -05:00
remove queryable api
This commit is contained in:
parent
ffe9226aac
commit
1e43784cc2
5 changed files with 1 additions and 328 deletions
|
@ -1,6 +1,7 @@
|
||||||
master
|
master
|
||||||
===
|
===
|
||||||
|
|
||||||
|
* Removed Queryable Sitemap API
|
||||||
* Removed `css_compressor` setting, use `activate :minify_css, :compressor =>` instead.
|
* Removed `css_compressor` setting, use `activate :minify_css, :compressor =>` instead.
|
||||||
* Removed `js_compressor` setting, use `activate :minify_javascript, :compressor =>` instead.
|
* Removed `js_compressor` setting, use `activate :minify_javascript, :compressor =>` instead.
|
||||||
* Removed ability to server folders of content statically (non-Middleman projects).
|
* Removed ability to server folders of content statically (non-Middleman projects).
|
||||||
|
|
|
@ -1,35 +0,0 @@
|
||||||
Feature: Queryable Selector
|
|
||||||
Scenario: Basic Selector Tests
|
|
||||||
Then should initialize with an attribute and an operator
|
|
||||||
Then should raise an exception if the operator is not supported
|
|
||||||
Scenario: Using offset and limit
|
|
||||||
Given the Server is running at "queryable-app"
|
|
||||||
Then should limit the documents to the number specified
|
|
||||||
Then should offset the documents by the number specified
|
|
||||||
Then should support offset and limit at the same time
|
|
||||||
Then should not freak out about an offset higher than the document count
|
|
||||||
Scenario: Using where queries with an equal operator
|
|
||||||
Given the Server is running at "queryable-app"
|
|
||||||
Then should return the right documents
|
|
||||||
Then should be chainable
|
|
||||||
Then should not be confused by attributes not present in all documents
|
|
||||||
Scenario: Using where queries with a complex operator
|
|
||||||
Given the Server is running at "queryable-app"
|
|
||||||
Then with a gt operator should return the right documents
|
|
||||||
Then with a gte operator should return the right documents
|
|
||||||
Then with an in operator should return the right documents
|
|
||||||
Then with an lt operator should return the right documents
|
|
||||||
Then with an lte operator should return the right documents
|
|
||||||
Then with an include operator include should return the right documents
|
|
||||||
Then with mixed operators should return the right documents
|
|
||||||
Then using multiple constrains in one where should return the right documents
|
|
||||||
Scenario: Sorting documents
|
|
||||||
Given the Server is running at "queryable-app"
|
|
||||||
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
|
|
||||||
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
|
|
|
@ -1,135 +0,0 @@
|
||||||
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
|
|
||||||
'equal'.should == selector.operator
|
|
||||||
end
|
|
||||||
|
|
||||||
Then /^should raise an exception if the operator is not supported$/ do
|
|
||||||
expect {
|
|
||||||
selector = ::Middleman::Sitemap::Queryable::Selector.new :attribute => :author, :operator => 'zomg'
|
|
||||||
}.to raise_error(::Middleman::Sitemap::Queryable::OperatorNotSupportedError)
|
|
||||||
end
|
|
||||||
|
|
||||||
Then /^should limit the documents to the number specified$/ do
|
|
||||||
@server_inst.sitemap.order_by(:id).limit(2).all.map { |r| r.raw_data[:id] }.sort.should == [1,2].sort
|
|
||||||
end
|
|
||||||
|
|
||||||
Then /^should offset the documents by the number specified$/ do
|
|
||||||
@server_inst.sitemap.order_by(:id).offset(2).all.map { |r| r.raw_data[:id] }.sort.should == [3,4,5].sort
|
|
||||||
end
|
|
||||||
|
|
||||||
Then /^should support offset and limit at the same time$/ do
|
|
||||||
@server_inst.sitemap.order_by(:id).offset(1).limit(2).all.map { |r| r.raw_data[:id] }.sort.should == [2,3].sort
|
|
||||||
end
|
|
||||||
|
|
||||||
Then /^should not freak out about an offset higher than the document count$/ do
|
|
||||||
@server_inst.sitemap.order_by(:id).offset(5).all.should == []
|
|
||||||
end
|
|
||||||
|
|
||||||
Then /^should return the right documents$/ do
|
|
||||||
documents = @server_inst.sitemap.resources.select { |r| !r.raw_data.empty? }
|
|
||||||
document_1 = documents[0]
|
|
||||||
document_2 = documents[1]
|
|
||||||
|
|
||||||
found_document = @server_inst.sitemap.where(:title => document_1.raw_data[:title]).first
|
|
||||||
document_1.should == found_document
|
|
||||||
|
|
||||||
found_document = @server_inst.sitemap.where(:title => document_2.raw_data[:title]).first
|
|
||||||
document_2.should == found_document
|
|
||||||
end
|
|
||||||
|
|
||||||
Then /^should be chainable$/ do
|
|
||||||
documents = @server_inst.sitemap.resources.select { |r| !r.raw_data.empty? }
|
|
||||||
document_1 = documents[0]
|
|
||||||
|
|
||||||
document_proxy = @server_inst.sitemap.where(:title => document_1.raw_data[:title])
|
|
||||||
document_proxy.where(:id => document_1.raw_data[:id])
|
|
||||||
document_1.should == document_proxy.first
|
|
||||||
end
|
|
||||||
|
|
||||||
Then /^should not be confused by attributes not present in all documents$/ do
|
|
||||||
result = @server_inst.sitemap.where(:seldom_attribute => 'is seldom').all
|
|
||||||
result.map { |r| r.raw_data[:id] }.should == [4]
|
|
||||||
end
|
|
||||||
|
|
||||||
Then /^with a gt operator should return the right documents$/ do
|
|
||||||
selector = ::Middleman::Sitemap::Queryable::Selector.new :attribute => :id, :operator => 'gt'
|
|
||||||
found_documents = @server_inst.sitemap.where(selector => 2).all
|
|
||||||
found_documents.map { |r| r.raw_data[:id] }.sort.should == [5,3,4].sort
|
|
||||||
end
|
|
||||||
|
|
||||||
Then /^with a gte operator should return the right documents$/ do
|
|
||||||
selector = ::Middleman::Sitemap::Queryable::Selector.new :attribute => :id, :operator => 'gte'
|
|
||||||
found_documents = @server_inst.sitemap.where(selector => 2).all
|
|
||||||
found_documents.map { |r| r.raw_data[:id] }.sort.should == [2,5,3,4].sort
|
|
||||||
end
|
|
||||||
|
|
||||||
Then /^with an in operator should return the right documents$/ do
|
|
||||||
selector = ::Middleman::Sitemap::Queryable::Selector.new :attribute => :id, :operator => 'in'
|
|
||||||
found_documents = @server_inst.sitemap.where(selector => [2,3]).all
|
|
||||||
found_documents.map { |r| r.raw_data[:id] }.sort.should == [2,3].sort
|
|
||||||
end
|
|
||||||
|
|
||||||
Then /^with an lt operator should return the right documents$/ do
|
|
||||||
selector = ::Middleman::Sitemap::Queryable::Selector.new :attribute => :id, :operator => 'lt'
|
|
||||||
found_documents = @server_inst.sitemap.where(selector => 2).all
|
|
||||||
found_documents.map { |r| r.raw_data[:id] }.should == [1]
|
|
||||||
end
|
|
||||||
|
|
||||||
Then /^with an lte operator should return the right documents$/ do
|
|
||||||
selector = ::Middleman::Sitemap::Queryable::Selector.new :attribute => :id, :operator => 'lte'
|
|
||||||
found_documents = @server_inst.sitemap.where(selector => 2).all
|
|
||||||
found_documents.map { |r| r.raw_data[:id] }.sort.should == [1,2].sort
|
|
||||||
end
|
|
||||||
|
|
||||||
Then /^with an include operator include should return the right documents$/ do
|
|
||||||
selector = ::Middleman::Sitemap::Queryable::Selector.new :attribute => :tags, :operator => 'include'
|
|
||||||
found_documents = @server_inst.sitemap.where(selector => 'ruby').all
|
|
||||||
found_documents.map { |r| r.raw_data[:id] }.sort.should == [1,2].sort
|
|
||||||
end
|
|
||||||
|
|
||||||
Then /^with mixed operators should return the right documents$/ do
|
|
||||||
in_selector = ::Middleman::Sitemap::Queryable::Selector.new :attribute => :id, :operator => 'in'
|
|
||||||
gt_selector = ::Middleman::Sitemap::Queryable::Selector.new :attribute => :id, :operator => 'gt'
|
|
||||||
documents_proxy = @server_inst.sitemap.where(in_selector => [2,3])
|
|
||||||
found_documents = documents_proxy.where(gt_selector => 2).all
|
|
||||||
found_documents.map { |r| r.raw_data[:id] }.should == [3]
|
|
||||||
end
|
|
||||||
|
|
||||||
Then /^using multiple constrains in one where should return the right documents$/ do
|
|
||||||
selector = ::Middleman::Sitemap::Queryable::Selector.new :attribute => :id, :operator => 'lte'
|
|
||||||
found_documents = @server_inst.sitemap.where(selector => 2, :status => :published).all
|
|
||||||
found_documents.map { |r| r.raw_data[:id] }.sort.should == [1,2].sort
|
|
||||||
end
|
|
||||||
|
|
||||||
Then /^should support ordering by attribute ascending$/ do
|
|
||||||
found_documents = @server_inst.sitemap.order_by(:title => :asc).all
|
|
||||||
found_documents.map { |r| r.raw_data[:id] }.should == [2,3,1,5,4]
|
|
||||||
end
|
|
||||||
|
|
||||||
Then /^should support ordering by attribute descending$/ do
|
|
||||||
found_documents = @server_inst.sitemap.order_by(:title => :desc).all
|
|
||||||
found_documents.map { |r| r.raw_data[:id] }.should == [4,5,1,3,2]
|
|
||||||
end
|
|
||||||
|
|
||||||
Then /^should order by attribute ascending by default$/ do
|
|
||||||
found_documents = @server_inst.sitemap.order_by(:title).all
|
|
||||||
found_documents.map { |r| r.raw_data[:id] }.should == [2,3,1,5,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
|
|
|
@ -1,155 +0,0 @@
|
||||||
require 'active_support/core_ext/object/inclusion'
|
|
||||||
|
|
||||||
module Middleman
|
|
||||||
module Sitemap
|
|
||||||
|
|
||||||
# Code adapted from https://github.com/ralph/document_mapper/
|
|
||||||
module Queryable
|
|
||||||
OPERATOR_MAPPING = {
|
|
||||||
'equal' => :==,
|
|
||||||
'gt' => :>,
|
|
||||||
'gte' => :>=,
|
|
||||||
'in' => :in?,
|
|
||||||
'include' => :include?,
|
|
||||||
'lt' => :<,
|
|
||||||
'lte' => :<=
|
|
||||||
}
|
|
||||||
|
|
||||||
VALID_OPERATORS = OPERATOR_MAPPING.keys
|
|
||||||
|
|
||||||
FileNotFoundError = Class.new StandardError
|
|
||||||
OperatorNotSupportedError = Class.new StandardError
|
|
||||||
|
|
||||||
module API
|
|
||||||
def select(options = {})
|
|
||||||
documents = resources.select { |r| !r.raw_data.empty? }
|
|
||||||
options[:where].each do |selector, selector_value|
|
|
||||||
documents = documents.select do |document|
|
|
||||||
next unless document.raw_data.has_key? selector.attribute
|
|
||||||
document_value = document.raw_data[selector.attribute]
|
|
||||||
operator = OPERATOR_MAPPING[selector.operator]
|
|
||||||
document_value.send operator, selector_value
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
if options[:order_by].present?
|
|
||||||
order_attribute = options[:order_by].keys.first
|
|
||||||
asc_or_desc = options[:order_by].values.first
|
|
||||||
documents = documents.select do |document|
|
|
||||||
document.raw_data.include? order_attribute
|
|
||||||
end
|
|
||||||
documents = documents.sort_by do |document|
|
|
||||||
document.raw_data[order_attribute]
|
|
||||||
end
|
|
||||||
documents.reverse! if asc_or_desc == :desc
|
|
||||||
end
|
|
||||||
|
|
||||||
documents
|
|
||||||
end
|
|
||||||
|
|
||||||
def where(hash)
|
|
||||||
Query.new(self).where(hash)
|
|
||||||
end
|
|
||||||
|
|
||||||
def order_by(field)
|
|
||||||
Query.new(self).order_by(field)
|
|
||||||
end
|
|
||||||
|
|
||||||
def offset(number)
|
|
||||||
Query.new(self).offset(number)
|
|
||||||
end
|
|
||||||
|
|
||||||
def limit(number)
|
|
||||||
Query.new(self).limit(number)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
class Query
|
|
||||||
def initialize(model, opts={})
|
|
||||||
@model = model
|
|
||||||
@where = opts[:where] || {}
|
|
||||||
@order_by = opts[:order_by]
|
|
||||||
@offset = opts[:offset]
|
|
||||||
@limit = opts[:limit]
|
|
||||||
end
|
|
||||||
|
|
||||||
def where(constraints_hash)
|
|
||||||
selector_hash = constraints_hash.reject { |key, value| !key.is_a? Selector }
|
|
||||||
symbol_hash = constraints_hash.reject { |key, value| key.is_a? Selector }
|
|
||||||
symbol_hash.each do |attribute, value|
|
|
||||||
selector = Selector.new(:attribute => attribute, :operator => 'equal')
|
|
||||||
selector_hash.update({ selector => value })
|
|
||||||
end
|
|
||||||
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)
|
|
||||||
Query.new @model, opts(:order_by => field.is_a?(Symbol) ? {field => :asc} : field)
|
|
||||||
end
|
|
||||||
|
|
||||||
def offset(number)
|
|
||||||
Query.new @model, opts(:offset => number)
|
|
||||||
end
|
|
||||||
|
|
||||||
def limit(number)
|
|
||||||
Query.new @model, opts(:limit => number)
|
|
||||||
end
|
|
||||||
|
|
||||||
def first
|
|
||||||
self.all.first
|
|
||||||
end
|
|
||||||
|
|
||||||
def last
|
|
||||||
self.all.last
|
|
||||||
end
|
|
||||||
|
|
||||||
def all
|
|
||||||
result = @model.select(:where => @where, :order_by => @order_by)
|
|
||||||
if @offset.present?
|
|
||||||
result = result.last([result.size - @offset, 0].max)
|
|
||||||
end
|
|
||||||
if @limit.present?
|
|
||||||
result = result.first(@limit)
|
|
||||||
end
|
|
||||||
result
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
class Selector
|
|
||||||
attr_reader :attribute, :operator
|
|
||||||
|
|
||||||
def initialize(opts = {})
|
|
||||||
unless VALID_OPERATORS.include? opts[:operator]
|
|
||||||
raise OperatorNotSupportedError
|
|
||||||
end
|
|
||||||
@attribute, @operator = opts[:attribute], opts[:operator]
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
# Add operators to symbol objects
|
|
||||||
class Symbol
|
|
||||||
Middleman::Sitemap::Queryable::VALID_OPERATORS.each do |operator|
|
|
||||||
class_eval <<-OPERATORS
|
|
||||||
def #{operator}
|
|
||||||
Middleman::Sitemap::Queryable::Selector.new(:attribute => self, :operator => '#{operator}')
|
|
||||||
end
|
|
||||||
OPERATORS
|
|
||||||
end
|
|
||||||
|
|
||||||
unless method_defined?(:"<=>")
|
|
||||||
def <=>(other)
|
|
||||||
self.to_s <=> other.to_s
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
|
@ -1,7 +1,6 @@
|
||||||
# Used for merging results of metadata callbacks
|
# Used for merging results of metadata callbacks
|
||||||
require 'active_support/core_ext/hash/deep_merge'
|
require 'active_support/core_ext/hash/deep_merge'
|
||||||
require 'monitor'
|
require 'monitor'
|
||||||
require 'middleman-core/sitemap/queryable'
|
|
||||||
|
|
||||||
# Extensions
|
# Extensions
|
||||||
require 'middleman-core/sitemap/extensions/on_disk'
|
require 'middleman-core/sitemap/extensions/on_disk'
|
||||||
|
@ -26,8 +25,6 @@ module Middleman
|
||||||
# @return [Middleman::Application]
|
# @return [Middleman::Application]
|
||||||
attr_accessor :app
|
attr_accessor :app
|
||||||
|
|
||||||
include ::Middleman::Sitemap::Queryable::API
|
|
||||||
|
|
||||||
# Initialize with parent app
|
# Initialize with parent app
|
||||||
# @param [Middleman::Application] app
|
# @param [Middleman::Application] app
|
||||||
def initialize(app)
|
def initialize(app)
|
||||||
|
|
Loading…
Reference in a new issue