refactored post search

This commit is contained in:
albert
2012-01-27 13:05:41 -05:00
parent 8b241138cd
commit 75d977ae80
6 changed files with 29 additions and 20 deletions

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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}")

View File

@@ -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

View File

@@ -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"))