1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495 |
- require 'sequel'
-
- require_relative './models/post'
- require_relative './models/thread'
-
- RESULTS_PER_PAGE = 50
-
- def search(params)
- query = params[:q].strip
- offset = (params[:page] - 1) * RESULTS_PER_PAGE
- username = params[:username].strip
- from_date = params[:from_date].strip
- to_date = params[:to_date].strip
- sort = params[:sort].strip
- exact_match = params[:exact_match].strip == "yes"
-
- errors = Array.new
-
- if from_date.empty?
- from_date = nil
- else
- if from_date.match(/\d{4}-\d{2}-\d{2}/)
- from_date = Date.parse(params[:from_date]) rescue errors << 'Invalid From Date'
- else
- errors << 'From Date must be in the format YYYY-MM-DD'
- end
- end
-
- if to_date.empty?
- to_date = nil
- else
- if to_date.match(/\d{4}-\d{2}-\d{2}/)
- to_date = Date.parse(params[:to_date]).next rescue errors << 'Invalid To Date'
- else
- errors << 'To Date must be in the format YYYY-MM-DD'
- end
- end
-
- if errors.empty? && !to_date.nil? && !from_date.nil? && to_date < from_date
- errors << 'To Date must be after From Date'
- end
-
- return {results: Array.new, errors: errors} unless errors.empty?
-
- results = case params[:type]
- when 'threads'
- search_threads(query, username, from_date, to_date, sort, offset, exact_match)
- when 'posts'
- search_posts(query, username, from_date, to_date, offset, exact_match)
- else
- Array.new
- end
-
- {results: results, errors: errors}
- end
-
- def search_threads(q, username, from_date, to_date, sort, offset, exact_match)
- sort = Sequel.desc(sort == 'post' ? :last_post_created_at : :created_at)
- query = VLV::Thread
- .select(Sequel.lit('threads.*'))
- .where(Sequel.lit("(LOWER(threads.creator) = LOWER(?) OR ? = '')", username, username))
- .where(Sequel.lit("created_at >= ? OR ? IS NULL", from_date, from_date))
- .where(Sequel.lit("created_at >= ? OR ? IS NULL", to_date, to_date))
- .order(sort)
- .limit(RESULTS_PER_PAGE)
- .offset(Sequel.lit('?', offset))
-
- if exact_match
- query.where(Sequel.ilike(:title, "%#{q}%"))
- else
- query.full_text_search(:title, Sequel.lit("websearch_to_tsquery(?)", q), tsquery: true, language: 'english')
- end
- end
-
- def search_posts(q, username, from_date, to_date, offset, exact_match)
- query = VLV::Post
- .select(Sequel.lit('posts.*, threads.title as thread_title, threads.remote_id as remote_thread_id'))
- .join(Sequel.lit('threads on posts.thread_id = threads.id'))
- .where(Sequel.lit("(LOWER(posts.creator) = LOWER(?) OR (? = ''))", username, username))
- .where(Sequel.lit("posts.created_at >= ? OR ? IS NULL", from_date, from_date))
- .where(Sequel.lit("posts.created_at >= ? OR ? IS NULL", to_date, to_date))
- .limit(RESULTS_PER_PAGE)
- .offset(Sequel.lit('?', offset))
- .order(Sequel.desc(Sequel.lit('posts.created_at')))
-
- if exact_match
- query.where(Sequel.ilike(:body, "%#{q}%"))
- else
- query.full_text_search(:tsv, Sequel.lit("websearch_to_tsquery(?)", q), {
- tsquery: true,
- tsvector: true,
- language: 'english'
- })
- end
- end
|