command_search 0.11.1 → 0.11.2
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/lib/command_search.rb +9 -0
- data/lib/command_search/backends/mysql.rb +106 -0
- data/lib/command_search/backends/postgres.rb +1 -1
- metadata +3 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: c9a7f59d4e3aefbd46963b94d52d18d49d63263ab51ceb31a207ee17ca23bf1b
|
4
|
+
data.tar.gz: 43fe311f65ec44dd89dcb997f0b61daa1347466f63fae1721c0168eb62bfa377
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: f9751ac591a874cf99009d28fc691b6543b5fc038dbbb6d7a7b063cf47f134da0e8ee500300877565e5c2b4164f82a446d983c9a6730c2eab35a86a6ae6a92ed
|
7
|
+
data.tar.gz: 47173f4d0904edcb9ddcbd1f2a24e00f9cd70d528c9234cd1840c861cb4cb7e85681bc6b3362fb73fefff095d16cb6aa277f83027185bc5068ed43c3b5b9b757
|
data/lib/command_search.rb
CHANGED
@@ -8,6 +8,7 @@ load(__dir__ + '/command_search/backends/memory.rb')
|
|
8
8
|
load(__dir__ + '/command_search/backends/mongoer.rb')
|
9
9
|
load(__dir__ + '/command_search/backends/postgres.rb')
|
10
10
|
load(__dir__ + '/command_search/backends/sqlite.rb')
|
11
|
+
load(__dir__ + '/command_search/backends/mysql.rb')
|
11
12
|
|
12
13
|
class Boolean; end
|
13
14
|
|
@@ -29,6 +30,10 @@ module CommandSearch
|
|
29
30
|
Normalizer.normalize!(ast, fields, false)
|
30
31
|
return Sqlite.build_query(ast)
|
31
32
|
end
|
33
|
+
if type == :mysql
|
34
|
+
Normalizer.normalize!(ast, fields, false)
|
35
|
+
return Mysql.build_query(ast)
|
36
|
+
end
|
32
37
|
Normalizer.normalize!(ast, fields)
|
33
38
|
return Mongoer.build_query(ast) if type == :mongo
|
34
39
|
ast
|
@@ -47,6 +52,10 @@ module CommandSearch
|
|
47
52
|
ast = CommandSearch.build(:sqlite, query, options)
|
48
53
|
return source.where(ast)
|
49
54
|
end
|
55
|
+
if source.respond_to?(:mysql2_connection)
|
56
|
+
ast = CommandSearch.build(:mysql, query, options)
|
57
|
+
return source.where(ast)
|
58
|
+
end
|
50
59
|
ast = CommandSearch.build(:other, query, options)
|
51
60
|
source.select { |x| CommandSearch::Memory.check(x, ast) }
|
52
61
|
end
|
@@ -0,0 +1,106 @@
|
|
1
|
+
module CommandSearch
|
2
|
+
module Mysql
|
3
|
+
module_function
|
4
|
+
|
5
|
+
def quote_string(str)
|
6
|
+
# activerecord/lib/active_record/connection_adapters/abstract/quoting.rb:62
|
7
|
+
str.gsub('\\', '\&\&').gsub("'", "''")
|
8
|
+
end
|
9
|
+
|
10
|
+
def build_quoted_regex(str)
|
11
|
+
str = Regexp.escape(str)
|
12
|
+
str = quote_string(str)
|
13
|
+
if str[/(^\W)|(\W$)/]
|
14
|
+
head_border = '(^|[^:+[[:alnum:]]])'
|
15
|
+
tail_border = '($|[^:+[[:alnum:]]])'
|
16
|
+
return head_border + str + tail_border
|
17
|
+
end
|
18
|
+
'\\\\b' + str + '\\\\b'
|
19
|
+
end
|
20
|
+
|
21
|
+
def command_search(node)
|
22
|
+
field_node = node[:value].first
|
23
|
+
field = field_node[:value]
|
24
|
+
search_node = node[:value].last
|
25
|
+
val = search_node[:value]
|
26
|
+
type = search_node[:type]
|
27
|
+
return '0 = 1' if field == '__CommandSearch_dummy_key__'
|
28
|
+
if type == Boolean || type == :existence
|
29
|
+
if val
|
30
|
+
return "(NOT ((#{field} IS NULL) OR (#{field} LIKE '0')))"
|
31
|
+
end
|
32
|
+
return "((#{field} IS NULL) OR (#{field} LIKE '0'))"
|
33
|
+
end
|
34
|
+
if type == Time
|
35
|
+
return '0 = 1' unless val
|
36
|
+
return "
|
37
|
+
(
|
38
|
+
(#{field} > '#{val[0] - 1}') AND
|
39
|
+
(#{field} <= '#{val[1] - 1}') AND
|
40
|
+
(#{field} IS NOT NULL)
|
41
|
+
)
|
42
|
+
"
|
43
|
+
end
|
44
|
+
if type == :quote
|
45
|
+
op = 'RLIKE BINARY'
|
46
|
+
val = "'#{build_quoted_regex(val)}'"
|
47
|
+
elsif type == :str
|
48
|
+
op = 'LIKE'
|
49
|
+
val = quote_string(val)
|
50
|
+
val.gsub!('%', '\%')
|
51
|
+
val.gsub!('_', '\_')
|
52
|
+
val = "'%#{val}%'"
|
53
|
+
elsif type == :number
|
54
|
+
op = '='
|
55
|
+
end
|
56
|
+
"((#{field} #{op} #{val}) AND (#{field} IS NOT NULL))"
|
57
|
+
end
|
58
|
+
|
59
|
+
def compare_search(node)
|
60
|
+
field_node = node[:value].first
|
61
|
+
field = field_node[:value]
|
62
|
+
search_node = node[:value].last
|
63
|
+
val = search_node[:value]
|
64
|
+
type = search_node[:type]
|
65
|
+
op = node[:nest_op]
|
66
|
+
if node[:compare_across_fields]
|
67
|
+
"
|
68
|
+
(
|
69
|
+
(#{field} #{op} #{val}) AND
|
70
|
+
(#{field} IS NOT NULL) AND
|
71
|
+
(#{val} IS NOT NULL)
|
72
|
+
)
|
73
|
+
"
|
74
|
+
elsif type == Time && val
|
75
|
+
"(#{field} #{op} '#{val}') AND (#{field} IS NOT NULL)"
|
76
|
+
elsif val.is_a?(Numeric) || val == val.to_i.to_s || val == val.to_f.to_s
|
77
|
+
"(#{field} #{op} #{val}) AND (#{field} IS NOT NULL)"
|
78
|
+
else
|
79
|
+
'0 = 1'
|
80
|
+
end
|
81
|
+
end
|
82
|
+
|
83
|
+
def build_query(ast)
|
84
|
+
out = []
|
85
|
+
ast = [ast] unless ast.is_a?(Array)
|
86
|
+
ast.each do |node|
|
87
|
+
type = node[:type]
|
88
|
+
if type == :colon
|
89
|
+
out.push(command_search(node))
|
90
|
+
elsif type == :compare
|
91
|
+
out.push(compare_search(node))
|
92
|
+
elsif type == :and
|
93
|
+
out.push(build_query(node[:value]))
|
94
|
+
elsif type == :or
|
95
|
+
clauses = node[:value].map { |x| build_query(x) }
|
96
|
+
clause = clauses.join(' OR ')
|
97
|
+
out.push("(#{clause})")
|
98
|
+
elsif type == :not
|
99
|
+
clause = build_query(node[:value])
|
100
|
+
out.push("NOT (#{clause})")
|
101
|
+
end
|
102
|
+
end
|
103
|
+
out.join(' AND ')
|
104
|
+
end
|
105
|
+
end
|
106
|
+
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: command_search
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.11.
|
4
|
+
version: 0.11.2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- zumbalogy
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2019-12-
|
11
|
+
date: 2019-12-19 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: chronic
|
@@ -34,6 +34,7 @@ files:
|
|
34
34
|
- lib/command_search/aliaser.rb
|
35
35
|
- lib/command_search/backends/memory.rb
|
36
36
|
- lib/command_search/backends/mongoer.rb
|
37
|
+
- lib/command_search/backends/mysql.rb
|
37
38
|
- lib/command_search/backends/postgres.rb
|
38
39
|
- lib/command_search/backends/sqlite.rb
|
39
40
|
- lib/command_search/lexer.rb
|