refactored post search
This commit is contained in:
@@ -1,8 +1,8 @@
|
||||
class PostQueryBuilder
|
||||
attr_accessor :q, :has_constraints
|
||||
attr_accessor :query_string, :has_constraints
|
||||
|
||||
def initialize(q)
|
||||
@q = q
|
||||
def initialize(query_string)
|
||||
@query_string = query_string
|
||||
@has_constraint = false
|
||||
end
|
||||
|
||||
@@ -54,20 +54,20 @@ class PostQueryBuilder
|
||||
tag_query_sql = []
|
||||
|
||||
if tags[:include].any?
|
||||
raise SearchError.new("You cannot search for more than #{Danbooru.config.tag_query_limit} tags at a time") if tags[:include].size > Danbooru.config.tag_query_limit
|
||||
raise ::Post::SearchError.new("You cannot search for more than #{Danbooru.config.tag_query_limit} tags at a time") if tags[:include].size > Danbooru.config.tag_query_limit
|
||||
tag_query_sql << "(" + escape_string_for_tsquery(tags[:include]).join(" | ") + ")"
|
||||
has_constraints!
|
||||
end
|
||||
|
||||
if tags[:related].any?
|
||||
raise SearchError.new("You cannot search for more than #{Danbooru.config.tag_query_limit} tags at a time") if tags[:related].size > Danbooru.config.tag_query_limit
|
||||
raise ::Post::SearchError.new("You cannot search for more than #{Danbooru.config.tag_query_limit} tags at a time") if tags[:related].size > Danbooru.config.tag_query_limit
|
||||
tag_query_sql << "(" + escape_string_for_tsquery(tags[:related]).join(" & ") + ")"
|
||||
has_constraints!
|
||||
end
|
||||
|
||||
if tags[:exclude].any?
|
||||
raise SearchError.new("You cannot search for more than #{Danbooru.config.tag_query_limit} tags at a time") if tags[:exclude].size > Danbooru.config.tag_query_limit
|
||||
raise SearchError.new("You cannot search for only excluded tags") unless has_constraints?
|
||||
raise ::Post::SearchError.new("You cannot search for more than #{Danbooru.config.tag_query_limit} tags at a time") if tags[:exclude].size > Danbooru.config.tag_query_limit
|
||||
raise ::Post::SearchError.new("You cannot search for only excluded tags") unless has_constraints?
|
||||
|
||||
tag_query_sql << "!(" + escape_string_for_tsquery(tags[:exclude]).join(" | ") + ")"
|
||||
end
|
||||
@@ -101,8 +101,8 @@ class PostQueryBuilder
|
||||
end
|
||||
|
||||
def build
|
||||
unless q.is_a?(Hash)
|
||||
q = Tag.parse_query(q)
|
||||
unless query_string.is_a?(Hash)
|
||||
q = Tag.parse_query(query_string)
|
||||
end
|
||||
|
||||
relation = Post.scoped
|
||||
|
||||
@@ -43,7 +43,7 @@ class Post < ActiveRecord::Base
|
||||
scope :for_user, lambda {|user_id| where(["uploader_id = ?", user_id])}
|
||||
scope :available_for_moderation, lambda {|hidden| hidden.present? ? where(["id IN (SELECT pd.post_id FROM post_disapprovals pd WHERE pd.user_id = ?)", CurrentUser.id]) : where(["id NOT IN (SELECT pd.post_id FROM post_disapprovals pd WHERE pd.user_id = ?)", CurrentUser.id])}
|
||||
scope :hidden_from_moderation, lambda {where(["id IN (SELECT pd.post_id FROM post_disapprovals pd WHERE pd.user_id = ?)", CurrentUser.id])}
|
||||
scope :tag_match, lambda {|query| Post.tag_match_helper(query)}
|
||||
scope :tag_match, lambda {|query| PostQueryBuilder.new(query).build}
|
||||
scope :positive, where("score > 1")
|
||||
scope :negative, where("score < -1")
|
||||
search_methods :tag_match
|
||||
@@ -568,13 +568,6 @@ class Post < ActiveRecord::Base
|
||||
end
|
||||
end
|
||||
|
||||
module SearchMethods
|
||||
def tag_match_helper(q)
|
||||
builder = PostQueryBuilder.new(q)
|
||||
builder.build
|
||||
end
|
||||
end
|
||||
|
||||
module UploaderMethods
|
||||
def initialize_uploader
|
||||
if uploader_id.blank?
|
||||
@@ -904,7 +897,6 @@ class Post < ActiveRecord::Base
|
||||
include FavoriteMethods
|
||||
include UploaderMethods
|
||||
include PoolMethods
|
||||
extend SearchMethods
|
||||
include VoteMethods
|
||||
extend CountMethods
|
||||
include CacheMethods
|
||||
|
||||
@@ -211,7 +211,7 @@ class Tag < ActiveRecord::Base
|
||||
:include => [],
|
||||
:exclude => []
|
||||
}
|
||||
|
||||
|
||||
scan_query(query).each do |token|
|
||||
if token =~ /\A(-uploader|uploader|-approver|approver|-pool|pool|-fav|fav|sub|md5|-rating|rating|width|height|mpixels|score|filesize|source|id|date|order|status|tagcount|gentags|arttags|chartags|copytags|parent):(.+)\Z/
|
||||
case $1
|
||||
@@ -308,7 +308,7 @@ class Tag < ActiveRecord::Base
|
||||
parse_tag(token, q[:tags])
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
normalize_tags_in_query(q)
|
||||
|
||||
return q
|
||||
|
||||
@@ -26,6 +26,7 @@ class TagAlias < ActiveRecord::Base
|
||||
def process!
|
||||
update_column(:status, "processing")
|
||||
update_posts
|
||||
clear_all_cache
|
||||
update_column(:status, "active")
|
||||
rescue Exception => e
|
||||
update_column(:status, "error: #{e}")
|
||||
|
||||
@@ -830,6 +830,20 @@ class PostTest < ActiveSupport::TestCase
|
||||
relation = Post.tag_match("order:landscape")
|
||||
assert_equal(post3.id, relation.first.id)
|
||||
end
|
||||
|
||||
should "fail for exclusive tag searches with no other tag" do
|
||||
post1 = Factory.create(:post, :rating => "s", :tag_string => "aaa")
|
||||
assert_raise(::Post::SearchError) do
|
||||
relation = Post.tag_match("-aaa")
|
||||
end
|
||||
end
|
||||
|
||||
should "succeed for exclusive tag searches combined with a metatag" do
|
||||
post1 = Factory.create(:post, :rating => "s", :tag_string => "aaa")
|
||||
assert_nothing_raised do
|
||||
relation = Post.tag_match("-aaa id:>0")
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
context "Voting:" do
|
||||
|
||||
@@ -31,6 +31,8 @@ class TagAliasTest < ActiveSupport::TestCase
|
||||
tag1 = Factory.create(:tag, :name => "aaa")
|
||||
tag2 = Factory.create(:tag, :name => "bbb")
|
||||
ta = FactoryGirl.create(:tag_alias, :antecedent_name => "aaa", :consequent_name => "bbb")
|
||||
assert_nil(MEMCACHE.get("ta:aaa"))
|
||||
ta.update_cache
|
||||
assert_equal("bbb", MEMCACHE.get("ta:aaa"))
|
||||
ta.destroy
|
||||
assert_nil(MEMCACHE.get("ta:aaa"))
|
||||
|
||||
Reference in New Issue
Block a user