search_lingo 1.0.2 → 1.0.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +5 -5
- data/.travis.yml +2 -2
- data/README.md +4 -5
- data/examples/complex.rb +15 -33
- data/examples/sequel_example.rb +15 -3
- data/lib/search_lingo/abstract_search.rb +25 -17
- data/lib/search_lingo/parsers/date_parser.rb +55 -17
- data/lib/search_lingo/parsers/mdy.rb +6 -5
- data/lib/search_lingo/parsers.rb +0 -5
- data/lib/search_lingo/version.rb +1 -1
- data/search_lingo.gemspec +1 -1
- metadata +7 -11
- data/lib/search_lingo/parsers/date_range_parser.rb +0 -15
- data/lib/search_lingo/parsers/gte_date_parser.rb +0 -13
- data/lib/search_lingo/parsers/lte_date_parser.rb +0 -13
- data/lib/search_lingo/parsers/open_date_range_parser.rb +0 -46
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
|
-
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: 473413fa017d4fe273ea20952b89c778fd07d98735efaeef1c28954bc70c96ea
|
4
|
+
data.tar.gz: 11df6b8d3f02b8147afc5a7248a548861b038c8e7e9dffd854dca506e185fa7e
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: a6783a0cb4a8d8db96ddaf4a9cff6704484a6421f93351de009202a7f680c46a50d44c62672e7201a7cdaeb3999ac9df7646b1905471cfef43ef2c9c2e6ef87d
|
7
|
+
data.tar.gz: bed0ac621a52ffc67fc50ee32f5dd560f58a3f11444741bc3bae63a9be8f1d0e7e59e0656b5d1cab07cc2a05c1c200889d408c1c7142ceab31416a156edc9d38
|
data/.travis.yml
CHANGED
data/README.md
CHANGED
@@ -276,11 +276,10 @@ Additionally, there are parsers for handling closed date ranges (e.g.,
|
|
276
276
|
`12/31/15`). Look at the files in `lib/search_lingo/parsers` for more details.
|
277
277
|
|
278
278
|
The date parser are specifically designed to work with US-formatted dates. Time
|
279
|
-
permitting, I will work on making them more flexible.
|
280
|
-
|
281
|
-
|
282
|
-
|
283
|
-
route, a Sequel-specific implementation should also be provided.)
|
279
|
+
permitting, I will work on making them more flexible.
|
280
|
+
|
281
|
+
As implemented they generate queries using AREL. In the future, we should try
|
282
|
+
generalizing this behavior to also support Sequel for generating queries.
|
284
283
|
|
285
284
|
## Development
|
286
285
|
|
data/examples/complex.rb
CHANGED
@@ -21,36 +21,18 @@ module Parsers # :nodoc:
|
|
21
21
|
end
|
22
22
|
|
23
23
|
class JobSearch < SearchLingo::AbstractSearch # :nodoc:
|
24
|
+
parser SearchLingo::Parsers::DateParser.new Job.arel_table[:date]
|
24
25
|
parser Parsers::IdParser.new Job.table_name
|
25
26
|
|
26
|
-
parser SearchLingo::Parsers::DateParser.new Job.table_name,
|
27
|
-
:date
|
28
|
-
parser SearchLingo::Parsers::DateRangeParser.new Job.table_name,
|
29
|
-
:date
|
30
|
-
parser SearchLingo::Parsers::OpenDateRangeParser.new Job.table_name,
|
31
|
-
:date, connection: Job.connection
|
32
|
-
|
33
27
|
def default_parse(token)
|
34
|
-
[:where,
|
28
|
+
[:where, Job.arel_table[:name].lower.like("%#{token}%")]
|
35
29
|
end
|
36
30
|
end
|
37
31
|
|
38
32
|
class ReceiptSearch < SearchLingo::AbstractSearch # :nodoc:
|
39
|
-
parser Parsers::
|
40
|
-
|
41
|
-
|
42
|
-
:check_date
|
43
|
-
parser SearchLingo::Parsers::DateRangeParser.new Receipt.table_name,
|
44
|
-
:check_date
|
45
|
-
parser SearchLingo::Parsers::OpenDateRangeParser.new Receipt.table_name,
|
46
|
-
:check_date, connection: Receipt.connection
|
47
|
-
|
48
|
-
parser SearchLingo::Parsers::DateParser.new Receipt.table_name,
|
49
|
-
:post_date, 'posted'
|
50
|
-
parser SearchLingo::Parsers::DateRangeParser.new Receipt.table_name,
|
51
|
-
:post_date, 'posted'
|
52
|
-
parser SearchLingo::Parsers::OpenDateRangeParser.new Receipt.table_name,
|
53
|
-
:post_date, 'posted', connection: Receipt.connection
|
33
|
+
parser SearchLingo::Parsers::DateParser.new Receipt.arel_table[:check_date]
|
34
|
+
parser SearchLingo::Parsers::DateParser.new Receipt.arel_table[:post_date],
|
35
|
+
modifier: 'posted'
|
54
36
|
|
55
37
|
parser do |token|
|
56
38
|
token.match /\Aamount: (\d+(?:\.\d+)?)\z/ do |m|
|
@@ -59,19 +41,19 @@ class ReceiptSearch < SearchLingo::AbstractSearch # :nodoc:
|
|
59
41
|
end
|
60
42
|
|
61
43
|
def default_parse(token)
|
62
|
-
[:where,
|
44
|
+
[:where, Receipt.arel_table[:check_no].like(token)]
|
63
45
|
end
|
64
46
|
end
|
65
47
|
|
66
48
|
search = JobSearch.new('6/4/15-6/5/15 id: 42 "foo bar"')
|
67
|
-
search.results
|
68
|
-
|
69
|
-
|
70
|
-
|
49
|
+
search.results
|
50
|
+
# => Job.where(Job.arel_table[:date].in(Date.new(2015,6,4)..Date.new(2015,6,5)))
|
51
|
+
# .where('jobs' => { id: '42' })
|
52
|
+
# .where(Job.arel_table[:name].lower.like('%foo bar%'))
|
71
53
|
|
72
54
|
search = ReceiptSearch.new('-6/4/15 posted: 6/5/15- amount: 1000 123')
|
73
|
-
search.results
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
55
|
+
search.results
|
56
|
+
# => Receipt.where(Receipt.arel_table[:check_date].lteq(Date.new(2015,6,4)))
|
57
|
+
# .where(Receipt.arel_table[:post_date].gteq(Date.new(2015,6,5)))
|
58
|
+
# .where(receipts: { amount: '1000' })
|
59
|
+
# .where(Receipt.arel_table[:check_no].matches('123'))
|
data/examples/sequel_example.rb
CHANGED
@@ -31,7 +31,7 @@ end
|
|
31
31
|
class CategoryParser # :nodoc:
|
32
32
|
def call(token)
|
33
33
|
if token.modifier == 'cat'
|
34
|
-
[:where, {
|
34
|
+
[:where, { Sequel.qualify('category', 'name') => token.term }]
|
35
35
|
end
|
36
36
|
end
|
37
37
|
end
|
@@ -39,12 +39,20 @@ end
|
|
39
39
|
class TaskSearch < SearchLingo::AbstractSearch # :nodoc:
|
40
40
|
parser CategoryParser.new
|
41
41
|
|
42
|
+
# Match categories with priority less than or greater than a given value.
|
43
|
+
#
|
44
|
+
# <2 => Categories with priority < 2
|
45
|
+
# >5 => Categories with priority > 5
|
42
46
|
parser do |token|
|
43
47
|
token.match /\A([<>])([[:digit:]]+)\z/ do |m|
|
44
|
-
[:where,
|
48
|
+
[:where, Sequel.expr { priority.send m[1], m[2] }]
|
45
49
|
end
|
46
50
|
end
|
47
51
|
|
52
|
+
# Match tasks with a given due_date.
|
53
|
+
#
|
54
|
+
# 7/4/1776 => Tasks with due_date == Date.new(1776, 7, 4)
|
55
|
+
# 7/4/17 => Tasks with due_date == Date.new(2017, 7, 4)
|
48
56
|
parser do |token|
|
49
57
|
token.match %r{\A(?<m>\d{1,2})/(?<d>\d{1,2})/(?<y>\d{2}\d{2}?)\z} do |m|
|
50
58
|
begin
|
@@ -54,8 +62,12 @@ class TaskSearch < SearchLingo::AbstractSearch # :nodoc:
|
|
54
62
|
end
|
55
63
|
end
|
56
64
|
|
65
|
+
# Match tasks with names that contain a given term.
|
66
|
+
#
|
67
|
+
# pay bills => Match tasks with names like "pay bills", "pay bills by today"
|
68
|
+
# brush teeth => Match tasks with names like "brush teeth", "brush teeth and floss"
|
57
69
|
def default_parse(token)
|
58
|
-
[:where, 'tasks.name LIKE ?', "%#{token.term}%"]
|
70
|
+
[:where, Sequel.lit('tasks.name LIKE ?', "%#{token.term}%")]
|
59
71
|
end
|
60
72
|
|
61
73
|
def scope
|
@@ -23,34 +23,30 @@ module SearchLingo
|
|
23
23
|
##
|
24
24
|
# Adds a new parser to the list of parsers used by this class.
|
25
25
|
#
|
26
|
-
# The parser
|
27
|
-
# +#call
|
28
|
-
#
|
29
|
-
#
|
30
|
-
#
|
26
|
+
# The parser may be given as an anonymous block or as any argument which
|
27
|
+
# responds to +#call+. The parser will be send +#call+ with a single
|
28
|
+
# argument which will be a token from the query string.
|
29
|
+
#
|
30
|
+
# If both a callable object and a block are given, or if neither a callable
|
31
|
+
# object nor a block are given, an +ArgumentError+ will be raised.
|
31
32
|
#
|
32
33
|
# class MyParser
|
33
|
-
# def call
|
34
|
+
# def call(token)
|
34
35
|
# # return something
|
35
36
|
# end
|
36
37
|
# end
|
37
38
|
#
|
38
39
|
# class MySearch < SearchLingo::AbstractSearch
|
39
40
|
# parser MyParser.new
|
40
|
-
# parser do
|
41
|
+
# parser do |token|
|
41
42
|
# # return something
|
42
43
|
# end
|
43
44
|
# end
|
44
|
-
def self.parser(
|
45
|
-
unless
|
46
|
-
raise ArgumentError, 'parse must be called with callable
|
47
|
-
end
|
48
|
-
if callable && block_given?
|
49
|
-
# TODO: should this raise an error instead?
|
50
|
-
warn "WARNING: parse called with callable and block (#{caller.first}"
|
45
|
+
def self.parser(parser = nil, &block)
|
46
|
+
unless block_given? ^ parser.respond_to?(:call)
|
47
|
+
raise ArgumentError, 'parse must be called with callable OR block'
|
51
48
|
end
|
52
|
-
|
53
|
-
parsers << (callable || block)
|
49
|
+
parsers << (parser || block)
|
54
50
|
end
|
55
51
|
|
56
52
|
##
|
@@ -62,7 +58,13 @@ module SearchLingo
|
|
62
58
|
##
|
63
59
|
# Returns the results of executing the search.
|
64
60
|
def results
|
65
|
-
@results ||=
|
61
|
+
@results ||= load_results
|
62
|
+
end
|
63
|
+
|
64
|
+
##
|
65
|
+
# Constructs and performs the query.
|
66
|
+
def load_results
|
67
|
+
conditions.inject(scope) do |query, condition|
|
66
68
|
query.public_send(*condition)
|
67
69
|
end
|
68
70
|
end
|
@@ -85,11 +87,16 @@ module SearchLingo
|
|
85
87
|
def conditions
|
86
88
|
tokenizer.inject([]) do |conditions, token|
|
87
89
|
conditions << catch(:match) do
|
90
|
+
# 1. Try each parser with the token until :match is thrown.
|
88
91
|
parse token
|
92
|
+
|
93
|
+
# 2. If :match not thrown and token is compound, simplify and try again.
|
89
94
|
if token.compound?
|
90
95
|
token = tokenizer.simplify
|
91
96
|
parse token
|
92
97
|
end
|
98
|
+
|
99
|
+
# 3. If :match still not thrown, fallback on default parser.
|
93
100
|
default_parse token
|
94
101
|
end
|
95
102
|
end
|
@@ -113,6 +120,7 @@ module SearchLingo
|
|
113
120
|
result = parser.call token
|
114
121
|
throw :match, result if result
|
115
122
|
end
|
123
|
+
nil
|
116
124
|
end
|
117
125
|
|
118
126
|
##
|
@@ -5,33 +5,71 @@ module SearchLingo
|
|
5
5
|
class DateParser
|
6
6
|
include MDY
|
7
7
|
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
8
|
+
##
|
9
|
+
# Instantiates a new DateParser object.
|
10
|
+
#
|
11
|
+
# The required argument +column+ should be an Arel attribute.
|
12
|
+
#
|
13
|
+
# If present, the optional argument +modifier+ will be used as the
|
14
|
+
# operator which precedes the date term.
|
15
|
+
#
|
16
|
+
# DateParser.new Booking.arel_table[:date]
|
17
|
+
# DateParser.new Contract.arel_table[:date], modifier: 'contract'
|
18
|
+
def initialize(column, modifier: nil)
|
19
|
+
@column = column
|
20
|
+
@prefix = %r{#{modifier}:[[:space:]]*} if modifier
|
14
21
|
end
|
15
22
|
|
16
|
-
attr_reader :
|
23
|
+
attr_reader :column, :prefix
|
17
24
|
|
18
|
-
|
19
|
-
#
|
20
|
-
#
|
21
|
-
#
|
25
|
+
##
|
26
|
+
# Attempts to parse the token as a date, closed date range, or open date
|
27
|
+
# range.
|
28
|
+
#
|
29
|
+
# Examples of single dates are 7/14, 7/14/17, and 7/14/2017.
|
30
|
+
# Examples of closed date ranges are 1/1-6/30 and 7/1/16-6/30/18.
|
31
|
+
# Examples of open date ranges are -6/30 and 7/1/17-.
|
22
32
|
def call(token)
|
33
|
+
parse_single_date(token) ||
|
34
|
+
parse_date_range(token) ||
|
35
|
+
parse_lte_date(token) ||
|
36
|
+
parse_gte_date(token)
|
37
|
+
end
|
38
|
+
|
39
|
+
def inspect # :nodoc:
|
40
|
+
'#<%s:0x%x @prefix=%s @column=%s>' %
|
41
|
+
[self.class, object_id << 1, prefix.inspect, column.inspect]
|
42
|
+
end
|
43
|
+
|
44
|
+
private
|
45
|
+
|
46
|
+
def parse_single_date(token)
|
23
47
|
token.match /\A#{prefix}(?<date>#{US_DATE})\z/ do |m|
|
24
|
-
date = parse
|
25
|
-
[:where,
|
48
|
+
date = parse(m[:date]) or return nil
|
49
|
+
[:where, column.eq(date)]
|
26
50
|
end
|
27
51
|
end
|
28
52
|
|
29
|
-
def
|
53
|
+
def parse_date_range(token)
|
54
|
+
token.match /\A#{prefix}(?<min>#{US_DATE})-(?<max>#{US_DATE})\z/ do |m|
|
55
|
+
min = parse(m[:min]) or return nil
|
56
|
+
max = parse(m[:max], relative_to: min.next_year) or return nil
|
57
|
+
[:where, column.in(min..max)]
|
58
|
+
end
|
30
59
|
end
|
31
60
|
|
32
|
-
def
|
33
|
-
|
34
|
-
|
61
|
+
def parse_lte_date(token)
|
62
|
+
token.match /\A#{prefix}-(?<date>#{US_DATE})\z/ do |m|
|
63
|
+
date = parse(m[:date]) or return nil
|
64
|
+
[:where, column.lteq(date)]
|
65
|
+
end
|
66
|
+
end
|
67
|
+
|
68
|
+
def parse_gte_date(token)
|
69
|
+
token.match /\A#{prefix}(?<date>#{US_DATE})-\z/ do |m|
|
70
|
+
date = parse(m[:date]) or return nil
|
71
|
+
[:where, column.gteq(date)]
|
72
|
+
end
|
35
73
|
end
|
36
74
|
end
|
37
75
|
end
|
@@ -13,8 +13,8 @@ module SearchLingo
|
|
13
13
|
# Returns a +Date+ object for the date represented by +term+. Returns
|
14
14
|
# +nil+ if +term+ can not be parsed.
|
15
15
|
#
|
16
|
-
# If the year has two digits, it will be expanded into a
|
17
|
-
# +Date.parse+.
|
16
|
+
# If the year has two digits, it will be implicitly expanded into a
|
17
|
+
# four-digit year by +Date.parse+. Otherwise it will be used as is.
|
18
18
|
#
|
19
19
|
# If the year is omitted, it will be inferred using +relative_to+ as a
|
20
20
|
# reference date. In this scenario, the resulting date will always be
|
@@ -26,12 +26,13 @@ module SearchLingo
|
|
26
26
|
term.match /\A#{US_DATE}\z/ do |m|
|
27
27
|
return Date.parse "#{m[:y]}/#{m[:m]}/#{m[:d]}" if m[:y]
|
28
28
|
|
29
|
+
ref = relative_to
|
29
30
|
day = Integer(m[:d])
|
30
31
|
month = Integer(m[:m])
|
31
|
-
year = if month <
|
32
|
-
|
32
|
+
year = if month < ref.month || month == ref.month && day <= ref.day
|
33
|
+
ref.year
|
33
34
|
else
|
34
|
-
|
35
|
+
ref.year - 1
|
35
36
|
end
|
36
37
|
|
37
38
|
Date.new year, month, day
|
data/lib/search_lingo/parsers.rb
CHANGED
data/lib/search_lingo/version.rb
CHANGED
data/search_lingo.gemspec
CHANGED
@@ -27,6 +27,6 @@ Gem::Specification.new do |spec|
|
|
27
27
|
spec.add_development_dependency "rake", "~> 10.0"
|
28
28
|
spec.add_development_dependency 'minitest'
|
29
29
|
spec.add_development_dependency 'pry'
|
30
|
-
spec.add_development_dependency 'sequel'
|
30
|
+
spec.add_development_dependency 'sequel', '~> 4.48'
|
31
31
|
spec.add_development_dependency 'sqlite3'
|
32
32
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: search_lingo
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.0.
|
4
|
+
version: 1.0.3
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- John Parker
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2018-10-02 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
@@ -70,16 +70,16 @@ dependencies:
|
|
70
70
|
name: sequel
|
71
71
|
requirement: !ruby/object:Gem::Requirement
|
72
72
|
requirements:
|
73
|
-
- - "
|
73
|
+
- - "~>"
|
74
74
|
- !ruby/object:Gem::Version
|
75
|
-
version: '
|
75
|
+
version: '4.48'
|
76
76
|
type: :development
|
77
77
|
prerelease: false
|
78
78
|
version_requirements: !ruby/object:Gem::Requirement
|
79
79
|
requirements:
|
80
|
-
- - "
|
80
|
+
- - "~>"
|
81
81
|
- !ruby/object:Gem::Version
|
82
|
-
version: '
|
82
|
+
version: '4.48'
|
83
83
|
- !ruby/object:Gem::Dependency
|
84
84
|
name: sqlite3
|
85
85
|
requirement: !ruby/object:Gem::Requirement
|
@@ -117,11 +117,7 @@ files:
|
|
117
117
|
- lib/search_lingo/constants.rb
|
118
118
|
- lib/search_lingo/parsers.rb
|
119
119
|
- lib/search_lingo/parsers/date_parser.rb
|
120
|
-
- lib/search_lingo/parsers/date_range_parser.rb
|
121
|
-
- lib/search_lingo/parsers/gte_date_parser.rb
|
122
|
-
- lib/search_lingo/parsers/lte_date_parser.rb
|
123
120
|
- lib/search_lingo/parsers/mdy.rb
|
124
|
-
- lib/search_lingo/parsers/open_date_range_parser.rb
|
125
121
|
- lib/search_lingo/token.rb
|
126
122
|
- lib/search_lingo/tokenizer.rb
|
127
123
|
- lib/search_lingo/version.rb
|
@@ -150,7 +146,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
150
146
|
version: '0'
|
151
147
|
requirements: []
|
152
148
|
rubyforge_project:
|
153
|
-
rubygems_version: 2.
|
149
|
+
rubygems_version: 2.7.7
|
154
150
|
signing_key:
|
155
151
|
specification_version: 4
|
156
152
|
summary: Framework for building simple query languages
|
@@ -1,15 +0,0 @@
|
|
1
|
-
require 'search_lingo/parsers/date_parser'
|
2
|
-
|
3
|
-
module SearchLingo
|
4
|
-
module Parsers # :nodoc:
|
5
|
-
class DateRangeParser < DateParser
|
6
|
-
def call(token)
|
7
|
-
token.match /\A#{prefix}(?<min>#{US_DATE})-(?<max>#{US_DATE})\z/ do |m|
|
8
|
-
min = parse m[:min]
|
9
|
-
max = parse m[:max], relative_to: min.next_year if min
|
10
|
-
[:where, { table => { column => min..max } }] if min && max
|
11
|
-
end
|
12
|
-
end
|
13
|
-
end
|
14
|
-
end
|
15
|
-
end
|
@@ -1,13 +0,0 @@
|
|
1
|
-
require 'search_lingo/parsers/open_date_range_parser'
|
2
|
-
|
3
|
-
module SearchLingo
|
4
|
-
module Parsers # :nodoc:
|
5
|
-
class GTEDateParser < OpenDateRangeParser # :nodoc:
|
6
|
-
def initialize(*)
|
7
|
-
warn "DEPRECATION WARNING: use SearchLingo::Parsers::OpenDateRangeParser " \
|
8
|
-
"instead of #{self.class} (from #{caller.first})"
|
9
|
-
super
|
10
|
-
end
|
11
|
-
end
|
12
|
-
end
|
13
|
-
end
|
@@ -1,13 +0,0 @@
|
|
1
|
-
require 'search_lingo/parsers/open_date_range_parser'
|
2
|
-
|
3
|
-
module SearchLingo
|
4
|
-
module Parsers # :nodoc:
|
5
|
-
class LTEDateParser < OpenDateRangeParser # :nodoc:
|
6
|
-
def initialize(*)
|
7
|
-
warn "DEPRECATION WARNING: use SearchLingo::Parsers::OpenDateRangeParser " \
|
8
|
-
"instead of #{self.class} (from #{caller.first})"
|
9
|
-
super
|
10
|
-
end
|
11
|
-
end
|
12
|
-
end
|
13
|
-
end
|
@@ -1,46 +0,0 @@
|
|
1
|
-
require 'search_lingo/parsers/date_parser'
|
2
|
-
require 'forwardable'
|
3
|
-
|
4
|
-
module SearchLingo
|
5
|
-
module Parsers # :nodoc:
|
6
|
-
class OpenDateRangeParser < DateParser
|
7
|
-
extend Forwardable
|
8
|
-
|
9
|
-
def call(token)
|
10
|
-
parse_lte(token) || parse_gte(token)
|
11
|
-
end
|
12
|
-
|
13
|
-
def post_initialize(connection:, **)
|
14
|
-
@connection = connection
|
15
|
-
end
|
16
|
-
|
17
|
-
def_delegators :@connection, :quote_column_name, :quote_table_name
|
18
|
-
|
19
|
-
private
|
20
|
-
|
21
|
-
def parse_lte(token) # :nodoc:
|
22
|
-
token.match /\A#{prefix}-(?<date>#{US_DATE})\z/ do |m|
|
23
|
-
if date = parse(m[:date])
|
24
|
-
[
|
25
|
-
:where,
|
26
|
-
"#{quote_table_name table}.#{quote_column_name column} <= ?",
|
27
|
-
date
|
28
|
-
]
|
29
|
-
end
|
30
|
-
end
|
31
|
-
end
|
32
|
-
|
33
|
-
def parse_gte(token) # :nodoc:
|
34
|
-
token.match /\A#{prefix}(?<date>#{US_DATE})-\z/ do |m|
|
35
|
-
if date = parse(m[:date])
|
36
|
-
[
|
37
|
-
:where,
|
38
|
-
"#{quote_table_name table}.#{quote_column_name column} >= ?",
|
39
|
-
date
|
40
|
-
]
|
41
|
-
end
|
42
|
-
end
|
43
|
-
end
|
44
|
-
end
|
45
|
-
end
|
46
|
-
end
|