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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 95f6475b2b10bb6d51c5b4ad3feb7ebe08404663230abcae5278e81babe5e189
4
- data.tar.gz: 90bfdddfeda70290d119eaad3bb4cdd35afc593e04a1d7d7a0c71736567b6710
3
+ metadata.gz: a00752d7d95c527463926fbb1e14ab869308906d7b40dead1cb538f8e8c590c9
4
+ data.tar.gz: 6530bcf049d2fa65ff5e69830e2ed678aae9c25689ff526839b13d549734a399
5
5
  SHA512:
6
- metadata.gz: 5406cb277bf3591e979e14adb5aef5f92370483cd8dce83fb1cd78c333f0c57ebd9a9de3a586272c649738ee44fe5a32a2d7f08b3ab54b545c914366033e1bb9
7
- data.tar.gz: 20950b080d702d04bde47999be305945643acdf50d078f9d0fe05a50108656ad648f453f652d248e4e0980b9df980f9e84cb0ae8b84b5b366597bffb4616f05b
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(search, 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
- args << arg
34
- end
35
- filters.map do |filter|
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(search)
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
- phrases_to_exclude = search.scan(/-"([^"]*)"/) # e.g. -"Phrase to exclude"
61
- phrases_or = search.scan(/\+"([^"]*)"/) # e.g. +"Phrase for OR"
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!('-"' + "#{phrase.first}" + '"', '')}
69
+ phrases_to_exclude.each { |phrase| search.gsub!('-"' + phrase.first.to_s + '"', '') }
66
70
  end
67
71
 
68
- # remove 'or' phrases from search if any
69
- if phrases_or.any?
70
- phrases_or.each {|phrase| search.gsub!('+"' + "#{phrase.first}" + '"', '')}
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
- sanitized_excluded_terms += phrases_to_exclude.flatten.map{|phrase| '%' + phrase.downcase.strip + '%'}
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 ') + '))', and_args + excluded_args]
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 ') + '))', or_args + excluded_args]
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
- 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
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)
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module RadCoreRails
4
- VERSION = '0.7.5'
4
+ VERSION = '0.8.0'
5
5
  end
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.7.5
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-01-27 00:00:00.000000000 Z
11
+ date: 2021-02-02 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activesupport