rad_core_rails 0.7.5 → 0.8.0
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 +4 -4
- data/lib/rad_core_rails/query_generator.rb +114 -44
- data/lib/rad_core_rails/version.rb +1 -1
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: a00752d7d95c527463926fbb1e14ab869308906d7b40dead1cb538f8e8c590c9
|
4
|
+
data.tar.gz: 6530bcf049d2fa65ff5e69830e2ed678aae9c25689ff526839b13d549734a399
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 72c7c3a5700725dfadf879f3f02f0ff9273e2a7fab1fdd1d35a3aec3f28571ac66ddcd94b49a06c523a795b588f5134db2419669b60fdb22e4ae1b0a89d4f9b8
|
7
|
+
data.tar.gz: 6fbd8139f169048dd2512c69477d8dc0f89cb2ac844e6d46221ce8d55c3491c53901125803c152cdf8d4af43742bcc0f765149fd6c10ef8b90c3f6269d943caa
|
@@ -24,15 +24,16 @@ module RadCoreRails
|
|
24
24
|
@filter_manifest || {}.with_indifferent_access
|
25
25
|
end
|
26
26
|
|
27
|
-
def create_filters(
|
27
|
+
def create_filters(filters)
|
28
28
|
query = []
|
29
29
|
args = []
|
30
|
-
clause, arguments = generate_search_clause(search)
|
31
|
-
query << clause
|
32
|
-
arguments.each do |arg|
|
33
|
-
|
34
|
-
end
|
35
|
-
filters.map do |
|
30
|
+
# clause, arguments = generate_search_clause(search)
|
31
|
+
# query << clause
|
32
|
+
# arguments.each do |arg|
|
33
|
+
# args << arg
|
34
|
+
# end
|
35
|
+
filters.map do |raw_filter|
|
36
|
+
filter = raw_filter.with_indifferent_access
|
36
37
|
begin
|
37
38
|
clause, arguments = filter_manifest[filter[:key]].call(filter)
|
38
39
|
query << clause
|
@@ -46,7 +47,8 @@ module RadCoreRails
|
|
46
47
|
[query.reject(&:blank?).join(' AND '), args]
|
47
48
|
end
|
48
49
|
|
49
|
-
def generate_search_clause(
|
50
|
+
def generate_search_clause(filter)
|
51
|
+
search = filter[:values][0]
|
50
52
|
search_clause = ['', []]
|
51
53
|
|
52
54
|
if search.present? && searchable_columns.is_a?(Array)
|
@@ -57,23 +59,28 @@ module RadCoreRails
|
|
57
59
|
or_args = [] # SQL from sanitized_or_terms
|
58
60
|
or_clause = [] # table columns SQL for all the OR terms
|
59
61
|
|
60
|
-
|
61
|
-
|
62
|
+
phrases_or = search.scan(/\+"([^"]*)"/) # e.g. +"Phrase for OR"
|
63
|
+
# remove 'or' phrases from search if any
|
64
|
+
phrases_or.each { |phrase| search.gsub!('+"' + phrase.first.to_s + '"', '') } if phrases_or.any?
|
62
65
|
|
66
|
+
phrases_to_exclude = search.scan(/-"([^"]*)"/) # e.g. -"Phrase to exclude"
|
63
67
|
# remove excluded phrases from search if any
|
64
68
|
if phrases_to_exclude.any?
|
65
|
-
phrases_to_exclude.each {|phrase| search.gsub!('-"' +
|
69
|
+
phrases_to_exclude.each { |phrase| search.gsub!('-"' + phrase.first.to_s + '"', '') }
|
66
70
|
end
|
67
71
|
|
68
|
-
|
69
|
-
if
|
70
|
-
|
71
|
-
end
|
72
|
+
phrases_and = search.scan(/"([^"]*)"/) # e.g. "Phrase for AND"
|
73
|
+
# remove 'and' phrases from search if any
|
74
|
+
phrases_and.each { |phrase| search.gsub!('"' + phrase.first.to_s + '"', '') } if phrases_and.any?
|
72
75
|
|
73
76
|
# extract 'and' terms, remove casing, and add ILIKE '%' comparisons
|
74
77
|
sanitized_and_terms = search.split(' ')
|
75
78
|
.reject { |term| term.include?('+') || term.include?('-') }
|
76
79
|
.map { |term| '%' + term.downcase.strip + '%' }
|
80
|
+
# add 'and' phrase terms, remove casing, and add ILIKE '%' comparisons
|
81
|
+
if phrases_and.any?
|
82
|
+
sanitized_and_terms += phrases_and.flatten.map { |phrase| '%' + phrase.downcase.strip + '%' }
|
83
|
+
end
|
77
84
|
|
78
85
|
# extract 'or' terms, remove casing, and add ILIKE '%' comparisons
|
79
86
|
sanitized_or_terms = search.split(' ')
|
@@ -81,9 +88,7 @@ module RadCoreRails
|
|
81
88
|
.map { |term| '%' + term[1, term.length].downcase.strip + '%' }
|
82
89
|
|
83
90
|
# add 'or' phrase terms, remove casing, and add ILIKE '%' comparisons
|
84
|
-
if phrases_or.any?
|
85
|
-
sanitized_or_terms += phrases_or.flatten.map{|phrase| '%' + phrase.downcase.strip + '%'}
|
86
|
-
end
|
91
|
+
sanitized_or_terms += phrases_or.flatten.map { |phrase| '%' + phrase.downcase.strip + '%' } if phrases_or.any?
|
87
92
|
|
88
93
|
# extract excluded terms, remove casing, and add NOT ILIKE '%' comparisons
|
89
94
|
sanitized_excluded_terms = search.split(' ')
|
@@ -92,7 +97,8 @@ module RadCoreRails
|
|
92
97
|
|
93
98
|
# add excluded phrase terms, remove casing, and add NOT ILIKE '%' comparisons
|
94
99
|
if phrases_to_exclude.any?
|
95
|
-
|
100
|
+
sanitized_excluded_terms += phrases_to_exclude.flatten
|
101
|
+
.map { |phrase| '%' + phrase.downcase.strip + '%' }
|
96
102
|
end
|
97
103
|
|
98
104
|
# loop through sanitized_and_terms to find all possible columns.
|
@@ -100,7 +106,7 @@ module RadCoreRails
|
|
100
106
|
columns = []
|
101
107
|
# all possible columns where this should be searched
|
102
108
|
searchable_columns.each do |col|
|
103
|
-
columns.push("(LOWER(#{col}) ILIKE ?)")
|
109
|
+
columns.push("(COALESCE(LOWER(#{col}), '') ILIKE ?)")
|
104
110
|
and_args.push sanitized_term
|
105
111
|
end
|
106
112
|
and_clause.push '(' + columns.join(' OR ') + ')'
|
@@ -110,7 +116,7 @@ module RadCoreRails
|
|
110
116
|
columns = []
|
111
117
|
# all possible columns where this should be searched
|
112
118
|
searchable_columns.each do |col|
|
113
|
-
columns.push("(LOWER(#{col}) NOT ILIKE ?)")
|
119
|
+
columns.push("(COALESCE(LOWER(#{col}), '') NOT ILIKE ?)")
|
114
120
|
excluded_args.push sanitized_term
|
115
121
|
end
|
116
122
|
excluded_clause.push '(' + columns.join(' AND ') + ')'
|
@@ -120,34 +126,28 @@ module RadCoreRails
|
|
120
126
|
columns = []
|
121
127
|
# all possible columns where this should be searched
|
122
128
|
searchable_columns.each do |col|
|
123
|
-
columns.push("(LOWER(#{col}) ILIKE ?)")
|
129
|
+
columns.push("(COALESCE(LOWER(#{col}), '') ILIKE ?)")
|
124
130
|
or_args.push sanitized_term
|
125
131
|
end
|
126
132
|
or_clause.push '(' + columns.join(' OR ') + ')'
|
127
133
|
end
|
128
134
|
|
129
|
-
if or_clause.empty? && and_clause.empty? && excluded_clause.empty?
|
130
|
-
return ['', []]
|
131
|
-
end
|
135
|
+
return ['', []] if or_clause.empty? && and_clause.empty? && excluded_clause.empty?
|
132
136
|
|
133
|
-
if or_clause.empty? && excluded_clause.empty?
|
134
|
-
return ['(' + and_clause.join(' AND ') + ')', and_args]
|
135
|
-
end
|
137
|
+
return ['(' + and_clause.join(' AND ') + ')', and_args] if or_clause.empty? && excluded_clause.empty?
|
136
138
|
|
137
|
-
if and_clause.empty? && excluded_clause.empty?
|
138
|
-
return ['(' + or_clause.join(' OR ') + ')', or_args]
|
139
|
-
end
|
139
|
+
return ['(' + or_clause.join(' OR ') + ')', or_args] if and_clause.empty? && excluded_clause.empty?
|
140
140
|
|
141
|
-
if or_clause.empty? && and_clause.empty?
|
142
|
-
return ['(' + excluded_clause.join(' AND ') + ')', excluded_args]
|
143
|
-
end
|
141
|
+
return ['(' + excluded_clause.join(' AND ') + ')', excluded_args] if or_clause.empty? && and_clause.empty?
|
144
142
|
|
145
143
|
if or_clause.empty?
|
146
|
-
return ['((' + and_clause.join(' AND ') + ') AND (' + excluded_clause.join(' AND ') + '))',
|
144
|
+
return ['((' + and_clause.join(' AND ') + ') AND (' + excluded_clause.join(' AND ') + '))',
|
145
|
+
and_args + excluded_args]
|
147
146
|
end
|
148
147
|
|
149
148
|
if and_clause.empty?
|
150
|
-
return ['((' + or_clause.join(' OR ') + ') AND (' + excluded_clause.join(' AND ') + '))',
|
149
|
+
return ['((' + or_clause.join(' OR ') + ') AND (' + excluded_clause.join(' AND ') + '))',
|
150
|
+
or_args + excluded_args]
|
151
151
|
end
|
152
152
|
|
153
153
|
if excluded_clause.empty?
|
@@ -155,14 +155,14 @@ module RadCoreRails
|
|
155
155
|
end
|
156
156
|
|
157
157
|
search_clause = [
|
158
|
-
|
159
|
-
|
160
|
-
|
161
|
-
|
162
|
-
|
163
|
-
|
164
|
-
|
165
|
-
|
158
|
+
'((' +
|
159
|
+
and_clause.join(' AND ') +
|
160
|
+
') AND (' +
|
161
|
+
or_clause.join(' OR ') +
|
162
|
+
') AND (' +
|
163
|
+
excluded_clause.join(' AND ') +
|
164
|
+
'))',
|
165
|
+
and_args + or_args + excluded_args
|
166
166
|
]
|
167
167
|
end
|
168
168
|
|
@@ -191,6 +191,76 @@ module RadCoreRails
|
|
191
191
|
[str, args]
|
192
192
|
end
|
193
193
|
|
194
|
+
def sanitize_vector_string(search)
|
195
|
+
phrases_or = search.scan(/\+"([^"]*)"/) # e.g. +"Phrase for OR"
|
196
|
+
# remove 'or' phrases from search if any
|
197
|
+
phrases_or.each { |phrase| search.gsub!('+"' + phrase.first.to_s + '"', '') } if phrases_or.any?
|
198
|
+
|
199
|
+
phrases_to_exclude = search.scan(/-"([^"]*)"/) # e.g. -"Phrase to exclude"
|
200
|
+
# remove excluded phrases from search if any
|
201
|
+
phrases_to_exclude.each { |phrase| search.gsub!('-"' + phrase.first.to_s + '"', '') } if phrases_to_exclude.any?
|
202
|
+
|
203
|
+
phrases_and = search.scan(/"([^"]*)"/) # e.g. "Phrase for AND"
|
204
|
+
# remove 'and' phrases from search if any
|
205
|
+
phrases_and.each { |phrase| search.gsub!('"' + phrase.first.to_s + '"', '') } if phrases_and.any?
|
206
|
+
|
207
|
+
sanitized_and_terms = search.split(' ')
|
208
|
+
.reject { |term| term.include?('+') || term.include?('-') }
|
209
|
+
.map { |term| term.downcase.strip.gsub('*', ':*') }
|
210
|
+
.reject { |t| t.blank? }
|
211
|
+
|
212
|
+
sanitized_or_terms = search.split(' ')
|
213
|
+
.select { |term| term.include?('+') }
|
214
|
+
.map { |term| term[1, term.length].downcase.strip.gsub('*', ':*') }
|
215
|
+
.reject { |t| t.blank? }
|
216
|
+
|
217
|
+
sanitized_excluded_terms = search.split(' ')
|
218
|
+
.select { |term| term.include?('-') }
|
219
|
+
.map { |term| term[1, term.length].downcase.strip.gsub('*', ':*') }
|
220
|
+
.reject { |t| t.blank? }
|
221
|
+
|
222
|
+
and_clause = sanitized_and_terms.join(' & ')
|
223
|
+
|
224
|
+
or_clause = sanitized_or_terms.join(' | ')
|
225
|
+
|
226
|
+
excluded_clause = sanitized_excluded_terms.map { |t| "!#{t}" }.join(' & ')
|
227
|
+
|
228
|
+
# puts '------'
|
229
|
+
# puts '------'
|
230
|
+
# puts '------'
|
231
|
+
# puts and_clause.inspect
|
232
|
+
# puts or_clause.inspect
|
233
|
+
# puts excluded_clause.inspect
|
234
|
+
# puts '------'
|
235
|
+
# puts '------'
|
236
|
+
|
237
|
+
if and_clause.present? && or_clause.empty? && excluded_clause.empty?
|
238
|
+
and_clause
|
239
|
+
elsif and_clause.empty? && or_clause.present? && excluded_clause.empty?
|
240
|
+
or_clause
|
241
|
+
elsif and_clause.empty? && or_clause.empty? && excluded_clause.present?
|
242
|
+
excluded_clause
|
243
|
+
elsif and_clause.present? && or_clause.present? && excluded_clause.empty?
|
244
|
+
"(#{and_clause}) & (#{or_clause})"
|
245
|
+
elsif and_clause.present? && or_clause.empty? && excluded_clause.present?
|
246
|
+
"(#{and_clause}) & (#{excluded_clause})"
|
247
|
+
elsif and_clause.empty? && or_clause.present? && excluded_clause.present?
|
248
|
+
"(#{or_clause}) & (#{excluded_clause})"
|
249
|
+
elsif and_clause.present? && or_clause.present? && excluded_clause.present?
|
250
|
+
"(#{and_clause}) & (#{or_clause}) & (#{excluded_clause})"
|
251
|
+
else
|
252
|
+
raise StandardError, 'Combination not available.'
|
253
|
+
end
|
254
|
+
end
|
255
|
+
|
256
|
+
def generate_vector_clause(column_name, filter)
|
257
|
+
return ['', []] if filter[:values][0].blank?
|
258
|
+
vector_string = sanitize_vector_string(filter[:values][0])
|
259
|
+
|
260
|
+
query = "(#{column_name} @@ to_tsquery('english', ?))"
|
261
|
+
[query, [vector_string]]
|
262
|
+
end
|
263
|
+
|
194
264
|
def generate_zip_codes_clause(column_name, filter)
|
195
265
|
str = "(#{column_name} = ANY(#{zip_code_class.distance_query}))"
|
196
266
|
args = zip_code_class.distance_args(filter)
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: rad_core_rails
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.8.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Oleksandr Poltavets, James Marrs
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2021-
|
11
|
+
date: 2021-02-02 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: activesupport
|