Sha256: c0245dd9a752145bc90dc369461f5ea550a07f1ceeb8cf1c6f9a634b641c55ab

Contents?: true

Size: 1.94 KB

Versions: 2

Compression:

Stored size: 1.94 KB

Contents

# frozen-string-literal: true

require 'sequel'
require 'sqlite3'

# DB = Sequel.sqlite
#
# DB.create_table :categories do
#   primary_key :id
#   String :name, null: false, unique: true
# end
#
# DB.create_table :tasks do
#   foreign_key :category_id, :categories
#   String :name, null: false, unique: true
#   Integer :priority, null: false
#   Date :due_date, null: false
# end

class CategoryParser # :nodoc:
  def call(token, chain)
    return nil unless token.modifier == 'cat'

    # This is not an ideal example. Sequel will join the categories table for
    # each token that matches. I'm ignoring the problem since this is only an
    # example.
    category_name = Sequel.qualify :categories, :name
    chain.join(:categories, id: :category_id).where category_name => token.term
  end
end

class TaskSearch < SearchLingo::AbstractSearch # :nodoc:
  parser CategoryParser.new

  # Match tasks with matching priority
  #
  # prio<2 => Tasks with priority less than 2
  # prio>2 => Tasks with priority greater than 2
  # prio=2 => Tasks with priority equal to 5
  parser do |token, chain|
    token.match(/\A prio ([<=>]) (\d+) \z/x) do |m|
      case m[1]
      when '<'
        chain.where { priority <  m[2] }
      when '>'
        chain.where { priority >  m[2] }
      else
        chain.where { priority =~ m[2] }
      end
    end
  end

  # Match tasks with a given due_date.
  #
  # 7/4/1776 => Tasks with due_date == Date.new(1776, 7, 4)
  # 7/4/17   => Tasks with due_date == Date.new(2017, 7, 4)
  parser do |token, chain|
    token.match %r{\A(?<m>\d{1,2})/(?<d>\d{1,2})/(?<y>\d{2}\d{2}?)\z} do |m|
      begin
        date = Date.parse "#{m[:y]}/#{m[:m]}/#{m[:d]}"
        chain.where due_date: date
      rescue ArgumentError
        # Fail if Date.parse raises an ArgumentError
        nil
      end
    end
  end

  # Match tasks with names containing the given string.
  def default_parse(token, chain)
    chain.where { name.like "%#{token.term}%" }
  end
end

Version data entries

2 entries across 2 versions & 1 rubygems

Version Path
search_lingo-2.0.0 examples/sequel_example.rb
search_lingo-2.0.0.pre3 examples/sequel_example.rb