2024-02-25 12:15:55 -05:00
|
|
|
# frozen_string_literal: true
|
|
|
|
|
2020-10-17 12:01:47 -04:00
|
|
|
class PostQueryBuilder
|
2022-03-05 09:36:48 -05:00
|
|
|
attr_accessor :query_string
|
2020-10-17 12:01:47 -04:00
|
|
|
|
2022-03-05 09:36:48 -05:00
|
|
|
def initialize(query_string)
|
2020-10-17 12:01:47 -04:00
|
|
|
@query_string = query_string
|
|
|
|
end
|
|
|
|
|
|
|
|
def add_tag_string_search_relation(tags, relation)
|
2023-09-03 09:23:27 -04:00
|
|
|
if tags[:must].any?
|
|
|
|
relation = relation.where("string_to_array(posts.tag_string, ' ') @> ARRAY[?]", tags[:must])
|
2020-10-17 12:01:47 -04:00
|
|
|
end
|
2023-09-03 09:23:27 -04:00
|
|
|
if tags[:must_not].any?
|
|
|
|
relation = relation.where("NOT(string_to_array(posts.tag_string, ' ') && ARRAY[?])", tags[:must_not])
|
2020-10-17 12:01:47 -04:00
|
|
|
end
|
2023-09-03 09:23:27 -04:00
|
|
|
if tags[:should].any?
|
|
|
|
relation = relation.where("string_to_array(posts.tag_string, ' ') && ARRAY[?]", tags[:should])
|
2020-10-17 12:01:47 -04:00
|
|
|
end
|
|
|
|
|
|
|
|
relation
|
|
|
|
end
|
|
|
|
|
2023-08-20 08:29:20 -04:00
|
|
|
def add_array_range_relation(relation, values, field)
|
|
|
|
values&.each do |value|
|
|
|
|
relation = relation.add_range_relation(value, field)
|
|
|
|
end
|
|
|
|
relation
|
|
|
|
end
|
|
|
|
|
2023-09-05 10:03:13 -04:00
|
|
|
def search
|
2023-08-24 07:16:44 -04:00
|
|
|
q = TagQuery.new(query_string)
|
2022-03-05 09:36:48 -05:00
|
|
|
relation = Post.all
|
2020-10-17 12:01:47 -04:00
|
|
|
|
2024-03-03 14:04:02 -05:00
|
|
|
relation = add_array_range_relation(relation, q[:post_id], "posts.id")
|
2023-08-20 08:29:20 -04:00
|
|
|
relation = add_array_range_relation(relation, q[:mpixels], "posts.image_width * posts.image_height / 1000000.0")
|
|
|
|
relation = add_array_range_relation(relation, q[:ratio], "ROUND(1.0 * posts.image_width / GREATEST(1, posts.image_height), 2)")
|
|
|
|
relation = add_array_range_relation(relation, q[:width], "posts.image_width")
|
|
|
|
relation = add_array_range_relation(relation, q[:height], "posts.image_height")
|
|
|
|
relation = add_array_range_relation(relation, q[:score], "posts.score")
|
|
|
|
relation = add_array_range_relation(relation, q[:fav_count], "posts.fav_count")
|
|
|
|
relation = add_array_range_relation(relation, q[:filesize], "posts.file_size")
|
|
|
|
relation = add_array_range_relation(relation, q[:change_seq], "posts.change_seq")
|
|
|
|
relation = add_array_range_relation(relation, q[:date], "posts.created_at")
|
|
|
|
relation = add_array_range_relation(relation, q[:age], "posts.created_at")
|
2023-08-18 13:08:52 -04:00
|
|
|
TagCategory::CATEGORIES.each do |category|
|
2023-12-03 09:36:37 -05:00
|
|
|
relation = add_array_range_relation(relation, q[:"#{category}_tag_count"], "posts.tag_count_#{category}")
|
2020-10-17 12:01:47 -04:00
|
|
|
end
|
2023-08-20 08:29:20 -04:00
|
|
|
relation = add_array_range_relation(relation, q[:post_tag_count], "posts.tag_count")
|
2020-10-17 12:01:47 -04:00
|
|
|
|
2023-08-24 07:16:44 -04:00
|
|
|
TagQuery::COUNT_METATAGS.each do |column|
|
2023-08-20 08:29:20 -04:00
|
|
|
relation = add_array_range_relation(relation, q[column.to_sym], "posts.#{column}")
|
2020-10-17 12:01:47 -04:00
|
|
|
end
|
|
|
|
|
|
|
|
if q[:md5]
|
|
|
|
relation = relation.where("posts.md5": q[:md5])
|
|
|
|
end
|
|
|
|
|
|
|
|
if q[:status] == "pending"
|
|
|
|
relation = relation.where("posts.is_pending = TRUE")
|
|
|
|
elsif q[:status] == "flagged"
|
|
|
|
relation = relation.where("posts.is_flagged = TRUE")
|
|
|
|
elsif q[:status] == "modqueue"
|
|
|
|
relation = relation.where("posts.is_pending = TRUE OR posts.is_flagged = TRUE")
|
|
|
|
elsif q[:status] == "deleted"
|
|
|
|
relation = relation.where("posts.is_deleted = TRUE")
|
|
|
|
elsif q[:status] == "active"
|
|
|
|
relation = relation.where("posts.is_pending = FALSE AND posts.is_deleted = FALSE AND posts.is_flagged = FALSE")
|
|
|
|
elsif q[:status] == "all" || q[:status] == "any"
|
|
|
|
# do nothing
|
2023-09-03 10:43:10 -04:00
|
|
|
elsif q[:status_must_not] == "pending"
|
2020-10-17 12:01:47 -04:00
|
|
|
relation = relation.where("posts.is_pending = FALSE")
|
2023-09-03 10:43:10 -04:00
|
|
|
elsif q[:status_must_not] == "flagged"
|
2020-10-17 12:01:47 -04:00
|
|
|
relation = relation.where("posts.is_flagged = FALSE")
|
2023-09-03 10:43:10 -04:00
|
|
|
elsif q[:status_must_not] == "modqueue"
|
2020-10-17 12:01:47 -04:00
|
|
|
relation = relation.where("posts.is_pending = FALSE AND posts.is_flagged = FALSE")
|
2023-09-03 10:43:10 -04:00
|
|
|
elsif q[:status_must_not] == "deleted"
|
2020-10-17 12:01:47 -04:00
|
|
|
relation = relation.where("posts.is_deleted = FALSE")
|
2023-09-03 10:43:10 -04:00
|
|
|
elsif q[:status_must_not] == "active"
|
2020-10-17 12:01:47 -04:00
|
|
|
relation = relation.where("posts.is_pending = TRUE OR posts.is_deleted = TRUE OR posts.is_flagged = TRUE")
|
|
|
|
end
|
|
|
|
|
2023-08-19 16:43:12 -04:00
|
|
|
q[:filetype]&.each do |filetype|
|
|
|
|
relation = relation.where("posts.file_ext": filetype)
|
2020-10-17 12:01:47 -04:00
|
|
|
end
|
|
|
|
|
2023-09-03 10:43:10 -04:00
|
|
|
q[:filetype_must_not]&.each do |filetype|
|
2023-08-19 16:43:12 -04:00
|
|
|
relation = relation.where.not("posts.file_ext": filetype)
|
2020-10-17 12:01:47 -04:00
|
|
|
end
|
|
|
|
|
|
|
|
if q[:pool] == "none"
|
|
|
|
relation = relation.where("posts.pool_string = ''")
|
|
|
|
elsif q[:pool] == "any"
|
|
|
|
relation = relation.where("posts.pool_string != ''")
|
|
|
|
end
|
|
|
|
|
2023-08-19 16:43:12 -04:00
|
|
|
q[:uploader_ids]&.each do |uploader_id|
|
|
|
|
relation = relation.where("posts.uploader_id": uploader_id)
|
2020-10-17 12:01:47 -04:00
|
|
|
end
|
|
|
|
|
2023-09-03 10:43:10 -04:00
|
|
|
q[:uploader_ids_must_not]&.each do |uploader_id|
|
2023-08-19 16:43:12 -04:00
|
|
|
relation = relation.where.not("posts.uploader_id": uploader_id)
|
2020-10-17 12:01:47 -04:00
|
|
|
end
|
|
|
|
|
2023-08-19 09:34:02 -04:00
|
|
|
if q[:approver] == "any"
|
|
|
|
relation = relation.where("posts.approver_id is not null")
|
|
|
|
elsif q[:approver] == "none"
|
|
|
|
relation = relation.where("posts.approver_id is null")
|
2020-10-17 12:01:47 -04:00
|
|
|
end
|
|
|
|
|
2023-08-19 16:43:12 -04:00
|
|
|
q[:approver_ids]&.each do |approver_id|
|
|
|
|
relation = relation.where("posts.approver_id": approver_id)
|
|
|
|
end
|
|
|
|
|
2023-09-03 10:43:10 -04:00
|
|
|
q[:approver_ids_must_not]&.each do |approver_id|
|
2023-08-19 16:43:12 -04:00
|
|
|
relation = relation.where.not("posts.approver_id": approver_id)
|
2023-08-19 09:34:02 -04:00
|
|
|
end
|
|
|
|
|
|
|
|
if q[:commenter] == "any"
|
|
|
|
relation = relation.where("posts.last_commented_at is not null")
|
|
|
|
elsif q[:commenter] == "none"
|
|
|
|
relation = relation.where("posts.last_commented_at is null")
|
|
|
|
end
|
|
|
|
|
|
|
|
if q[:noter] == "any"
|
|
|
|
relation = relation.where("posts.last_noted_at is not null")
|
|
|
|
elsif q[:noter] == "none"
|
|
|
|
relation = relation.where("posts.last_noted_at is null")
|
2020-10-17 12:01:47 -04:00
|
|
|
end
|
|
|
|
|
|
|
|
if q[:parent] == "none"
|
|
|
|
relation = relation.where("posts.parent_id IS NULL")
|
|
|
|
elsif q[:parent] == "any"
|
|
|
|
relation = relation.where("posts.parent_id IS NOT NULL")
|
|
|
|
end
|
|
|
|
|
2023-08-19 16:43:12 -04:00
|
|
|
q[:parent_ids]&.each do |parent_id|
|
|
|
|
relation = relation.where("posts.parent_id = ?", parent_id)
|
2023-08-19 09:34:02 -04:00
|
|
|
end
|
|
|
|
|
2023-09-03 10:43:10 -04:00
|
|
|
q[:parent_ids_must_not]&.each do |parent_id|
|
2023-08-19 16:43:12 -04:00
|
|
|
relation = relation.where.not("posts.parent_id = ?", parent_id)
|
2020-10-17 12:01:47 -04:00
|
|
|
end
|
|
|
|
|
|
|
|
if q[:child] == "none"
|
|
|
|
relation = relation.where("posts.has_children = FALSE")
|
|
|
|
elsif q[:child] == "any"
|
|
|
|
relation = relation.where("posts.has_children = TRUE")
|
|
|
|
end
|
|
|
|
|
2023-08-19 16:43:12 -04:00
|
|
|
q[:rating]&.each do |rating|
|
|
|
|
relation = relation.where("posts.rating = ?", rating)
|
2023-08-19 12:52:29 -04:00
|
|
|
end
|
|
|
|
|
2023-09-03 10:43:10 -04:00
|
|
|
q[:rating_must_not]&.each do |rating|
|
2023-08-19 16:43:12 -04:00
|
|
|
relation = relation.where("posts.rating = ?", rating)
|
2020-10-17 12:01:47 -04:00
|
|
|
end
|
|
|
|
|
2023-08-19 09:59:38 -04:00
|
|
|
add_tag_string_search_relation(q[:tags], relation)
|
2020-10-17 12:01:47 -04:00
|
|
|
end
|
|
|
|
end
|