diff --git a/app/logical/post_query_builder.rb b/app/logical/post_query_builder.rb index 0cdce1d41..48a03ed7a 100644 --- a/app/logical/post_query_builder.rb +++ b/app/logical/post_query_builder.rb @@ -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 diff --git a/app/models/post.rb b/app/models/post.rb index d67ad95db..f41e64c4b 100644 --- a/app/models/post.rb +++ b/app/models/post.rb @@ -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 diff --git a/app/models/tag.rb b/app/models/tag.rb index e8023da2b..5dcf586f1 100644 --- a/app/models/tag.rb +++ b/app/models/tag.rb @@ -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 diff --git a/app/models/tag_alias.rb b/app/models/tag_alias.rb index 8ecedeff2..f329afe77 100644 --- a/app/models/tag_alias.rb +++ b/app/models/tag_alias.rb @@ -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}") diff --git a/test/unit/post_test.rb b/test/unit/post_test.rb index a997e0258..8654feb08 100644 --- a/test/unit/post_test.rb +++ b/test/unit/post_test.rb @@ -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 diff --git a/test/unit/tag_alias_test.rb b/test/unit/tag_alias_test.rb index 8e12b48f9..d25410480 100644 --- a/test/unit/tag_alias_test.rb +++ b/test/unit/tag_alias_test.rb @@ -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"))