require 'sequel' 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 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' sort = case params[:sort] when 'thread' 'created_at DESC' when 'post' 'last_post_created_at DESC' else 'created_at DESC' end search_threads(query, username, from_date, to_date, sort, offset) when 'posts' search_posts(query, username, from_date, to_date, offset) else Array.new end {results: results, errors: errors} end def search_threads(query, username, from_date, to_date, sort, offset) DB[<<-SQL, query, username, username, from_date, from_date, to_date, to_date, offset] SELECT threads.*, count(*) OVER() AS full_count FROM threads WHERE to_tsvector(title) @@ plainto_tsquery(?) AND (LOWER(threads.creator) = LOWER(?) OR ? = '') AND (created_at >= ? OR ? IS NULL) AND (created_at <= ? OR ? IS NULL) ORDER BY #{sort} LIMIT #{RESULTS_PER_PAGE} OFFSET ?; SQL end def search_posts(query, username, from_date, to_date, offset) DB[<<-SQL, query, username, username, from_date, from_date, to_date, to_date, offset] SELECT posts.*, threads.title as thread_title, threads.remote_id as remote_thread_id, count(*) OVER() AS full_count FROM posts INNER JOIN threads on posts.thread_id = threads.id WHERE tsv @@ plainto_tsquery(?) AND ((LOWER(posts.creator) = LOWER(?)) OR (? = '')) AND (posts.created_at >= ? OR ? IS NULL) AND (posts.created_at <= ? OR ? IS NULL) ORDER BY posts.created_at DESC LIMIT #{RESULTS_PER_PAGE} OFFSET ?; SQL end