generic_search 1.3.2

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 ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: c7ea1f7c8f6d0091ee267fecfc54a5bbf4aaea91
4
+ data.tar.gz: 3594824bb78a70db17620bfffbd0347fd7c9173e
5
+ SHA512:
6
+ metadata.gz: 00762261f46fd12bb1fe00aaaa9c21247c8846c9948e8b2e773a8b3928df63b1be0e7b9b55a0d6250630d0f05da9d90bd46b0bfee54440825984f4d44a9a1d59
7
+ data.tar.gz: f8bc639f68cedc7aac59fde4d5da387ddc62cf5c611fc22a7446511673c20b41e87644057efdacd6b3c1c07f2253ee90837a6f84baa4c78abb707a2811bab117
@@ -0,0 +1,297 @@
1
+ module GenericSearch
2
+
3
+ #def self.custom_config
4
+ # {
5
+ # :transitions => {
6
+ # :script_status => {
7
+ # :field => :script_status_id,
8
+ # :lambda => lambda do |operator, value|
9
+ # Status.where("name #{operator} ?", value).collect(&:id)
10
+ # end
11
+ # }
12
+ # }
13
+ # }
14
+ #end
15
+
16
+ module BuildMethods
17
+
18
+ def build_where(query)
19
+
20
+ if query.blank?
21
+ return
22
+ end
23
+
24
+ query_table_list = []
25
+
26
+ query.each_line('),') do |segment|
27
+ segment.gsub!(/,$/, "")
28
+ query_table_list << segment
29
+ end
30
+
31
+ query_per_table = Array.new
32
+
33
+ @joins = []
34
+
35
+ query_table_list.each do |query_item|
36
+
37
+ table, search_params = query_item.to_s.split('(', 2)
38
+ table.strip!
39
+
40
+ column_names = []
41
+
42
+ if table.strip != @base_table
43
+ relation_name = @base_class._table_relation[table.strip]
44
+ @joins << relation_name if relation_name
45
+ end
46
+
47
+ search_params ||= ''
48
+ search_params.gsub!(/\)$/, "")
49
+
50
+ single_param_array = search_params.strip.split(/\s*,\s*/)
51
+ single_param_array_length = single_param_array.length
52
+
53
+ column_values = []
54
+ current_value = single_param_array[0]
55
+ i=0
56
+
57
+ until i >= single_param_array_length
58
+
59
+ next_value = single_param_array[i + 1]
60
+
61
+ if next_value.nil? or next_value.match(/([<>=!~]|between)/)
62
+ column_values << current_value
63
+ current_value = next_value
64
+ else
65
+ current_value << (',' + next_value)
66
+ end
67
+
68
+ i = i + 1
69
+ end
70
+
71
+ column_values.each do |search_param|
72
+ search_param.gsub!(/,$/, "")
73
+
74
+ if search_param.match(/(\w+)\s+between\s+(\*?.*)and(\*?.*)/i)
75
+ key, from, to = $1.strip, $2.strip, $3.strip
76
+
77
+ single_search_param = if from.match(/^\d+$/) and to.match(/^\d+$/)
78
+ "\"#{table}\".\"#{key}\" between #{from} and #{to}"
79
+ else
80
+ "\"#{table}\".\"#{key}\" between '#{from.to_time.to_s(:db)}' and '#{to.to_time.to_s(:db)}'"
81
+ end
82
+
83
+ else
84
+ search_param.match(/(\w+)(\s*[<>=!~]*\s*)(\*?.*)/)
85
+ key, operator, value = $1.strip, $2.strip, $3.strip
86
+
87
+ if operator == '='
88
+ if value.include? '*'
89
+ value.gsub!('*', '%')
90
+ value = "#{value}"
91
+ operator = 'ILIKE'
92
+ #elsif value.include? '/'
93
+ # value = "(#{value})"
94
+ # operator = 'in'
95
+ #elsif value.include? '|'
96
+ # value = "(#{value})"
97
+ # operator = 'in'
98
+ #else
99
+ # value = "'#{value}'"
100
+ end
101
+
102
+ else
103
+ value = "#{value}"
104
+ end
105
+
106
+ config = GenericSearch.config[table.intern]
107
+ config = (config and config[:for_where])
108
+ key_intern = key.intern
109
+
110
+ #TODO: Test Requires
111
+ single_search_param = if config and config.has_key?(key_intern)
112
+ config = config[key_intern]
113
+ value = config[:lambda].call(operator, value)
114
+ #subQuery = value.is_a?(Array) ? "in (#{value.blank? ? 'NULL' : value.join(',')})" : "= '#{value}'"
115
+ subQuery = if value.is_a?(Array)
116
+ if value.blank?
117
+ "in (NULL)"
118
+ else
119
+ "in (#{value.join(',')})"
120
+ end
121
+ else
122
+ "= '#{value}'"
123
+ end
124
+ "\"#{table}\".\"#{config[:field]}\" #{subQuery}"
125
+ elsif operator == '=' and value.include?(',') or value.include?('|')
126
+
127
+ value = value.gsub(/\s*,\s*/, ' AND ').gsub(/\s*\|\s*/, ' OR ').split(/(AND|OR)/)
128
+ .collect do |val|
129
+ val.match(/(AND|OR)/) ? val : "\"#{table}\".\"#{key}\" #{operator} '#{val.strip}'"
130
+ end.join(' ')
131
+
132
+ "(#{value})"
133
+
134
+ else
135
+ "\"#{table}\".\"#{key}\" #{operator} '#{value}'"
136
+ end
137
+
138
+ column_names << key
139
+ end
140
+
141
+ query_per_table << single_search_param
142
+ end
143
+
144
+ self.validate_columns(table, column_names, :query)
145
+ end
146
+
147
+ self.where = query_per_table.join(' AND ')
148
+ end
149
+
150
+ def build_results(results)
151
+ table_selected_fields = {}
152
+
153
+ selects = if results.blank?
154
+ [self.base_class.table_name]
155
+ else
156
+ selects = results.scan(/\w+\(.*?\)/)
157
+ results_clone = results.clone
158
+
159
+ selects.each do |select|
160
+ results_clone.gsub!(select, '')
161
+ end
162
+
163
+ selects += results_clone.split(/,/).delete_if(&:blank?)
164
+ selects
165
+ end
166
+
167
+ selects.each do |select|
168
+ match, table, select_fields = *select.match(/(\w+)\(*([\s\w,]*)\)*/)
169
+ table_selected_fields[table] = select_fields.blank? ? nil : select_fields.strip.split(/\s*,\s*/)
170
+ end
171
+
172
+ table_selected_fields.each do |table_name, column_names|
173
+ validate_columns(table_name, column_names, :results)
174
+ end
175
+
176
+ #TODO: self.select = table_selected_fields.clone
177
+ self.select = table_selected_fields
178
+ end
179
+
180
+ def build_group(group)
181
+
182
+ if group.blank?
183
+ return
184
+ end
185
+
186
+ group_entities = group.scan(/\w+\(.*?\)/)
187
+
188
+ @joins ||= []
189
+ group_table_fields_map = {}
190
+ @group = []
191
+ @group_object_access = []
192
+
193
+ group_entities.each do |group_entity|
194
+ match, table, select_fields = *group_entity.match(/(\w+)\(*([\s\w,]*)\)*/)
195
+ table.strip!
196
+ fields = select_fields.split(/\s*,\s*/)
197
+ group_table_fields_map[table] = fields
198
+
199
+ #@joins << @base_class._table_relation[table.strip] if table != @base_class.table_name
200
+
201
+ table.strip!
202
+ if table != @base_table
203
+ relation_name = (@base_class._table_relation[table] || (@base_class._relation_table[table.intern] ? table.intern : nil))
204
+ table_name = @base_class._table_relation[table] ? table : @base_class._relation_table[table.intern]
205
+ @joins << relation_name if relation_name
206
+ else
207
+ table_name = table
208
+ end
209
+
210
+ fields.each do |field|
211
+ @group << "#{table_name}.#{field}"
212
+ #@group_object_access << (@base_table == table ? field : "#{@base_class._table_relation[table]}.#{field}")
213
+ @group_object_access << (@base_table == table_name ? field : "#{relation_name}.#{field}")
214
+ end
215
+ end
216
+
217
+ group_table_fields_map.each do |table, column_names|
218
+ validate_columns(table, column_names, :group)
219
+ end
220
+
221
+
222
+ end
223
+
224
+ def build_sort_order(sort_order)
225
+ self.sort_order = if sort_order.nil?
226
+ "\"#{self.base_table}\".\"id\" ASC"
227
+ elsif sort_order.strip == "\"\"" || sort_order.strip == "\'\'" || sort_order.strip == ''
228
+ nil
229
+ else
230
+ sort_order.strip
231
+ end
232
+ end
233
+
234
+ def build_limit(limit)
235
+ #TODO: Test required for group.blank?
236
+ if self.options[:no_results] or !self.group.blank?
237
+ self.limit = nil
238
+ else
239
+ self.limit = limit.blank? ? GenericSearch::DEFAULT_LIMIT : limit
240
+ end
241
+
242
+ end
243
+
244
+ def build_start(start)
245
+ #TODO: Test required for group.blank?
246
+ self.start = if self.options[:no_results] or !self.group.blank?
247
+ nil
248
+ else
249
+ start.blank? ? 0 : start
250
+ end
251
+ end
252
+
253
+ # options = no_results, no_limit_count
254
+ def build_options(options)
255
+
256
+ self.options = {}
257
+
258
+ return if options.blank?
259
+
260
+ if options.include? 'no_results'
261
+ self.options[:no_results] = true
262
+ end
263
+
264
+ if options.include? 'no_limit_count'
265
+ self.options[:no_limit_count] = true
266
+ end
267
+
268
+ if options.include? 'distinct'
269
+ self.options[:distinct] = true
270
+ end
271
+
272
+ end
273
+
274
+ def build_response
275
+
276
+ self.response = {
277
+ :success => self.status == :ok ? true : false,
278
+ :code => self.status == :ok ? 200 : 400,
279
+ :status => self.status,
280
+ :message => self.messages,
281
+ :client_IP => nil,
282
+ :controller => nil,
283
+
284
+ :server => Socket.gethostname,
285
+ :where_clause => self.where,
286
+ :no_limit_result_count => self.no_limit_count,
287
+ :limit_result_count => self.limit_result_count,
288
+ :timestamp => Time.now,
289
+ :groups => self.grouped_results
290
+ #"groups" => params.has_key?(:no_results) ? [] : @grouped_results
291
+ }
292
+
293
+ end
294
+
295
+ end
296
+
297
+ end
@@ -0,0 +1,4 @@
1
+ module GenericSearch
2
+ #DEFAULT_LIMIT = 1000
3
+ DEFAULT_LIMIT = nil
4
+ end
@@ -0,0 +1,5 @@
1
+ module GenericSearch
2
+ class UnknownInputType < Exception
3
+
4
+ end
5
+ end
@@ -0,0 +1,8 @@
1
+ module GenericSearch
2
+ module Messages
3
+ DoubleCloseParan = 'malformed url - double close paren'
4
+ IncorrectUseOfParan = 'malformed url - incorrect use of parentheses'
5
+ DoubleOpenParan = 'malformed url - double open paren'
6
+ DoubleComma = "malformed url - double comma"
7
+ end
8
+ end
@@ -0,0 +1,62 @@
1
+ class ActiveRecord::Base
2
+
3
+ def _generic_search(args)
4
+ if args.is_a? HashWithIndifferentAccess or args.is_a? Hash
5
+ generic_search = GenericSearch::Klass.new(args, self.class)
6
+ generic_search.search
7
+ elsif args.is_a? GenericSearch
8
+
9
+ else
10
+ raise UnknownInputType
11
+ end
12
+
13
+ end
14
+
15
+ def self.generic_search config
16
+ GenericSearch.update_config(self.table_name, config[:custom_attributes])
17
+ end
18
+
19
+ def self._table_relation
20
+ #@@table_relation ||= begin
21
+ # puts "processing..."
22
+ self.reflect_on_all_associations.inject({}) do |hash, assoc_reflection|
23
+ hash[assoc_reflection.table_name] ||= assoc_reflection.name
24
+ hash
25
+ end
26
+ #end
27
+ end
28
+
29
+ def self._relation_table
30
+ #@@relation_table ||= begin
31
+ #puts "processing..."
32
+ self.reflect_on_all_associations.inject({}) do |hash, assoc_reflection|
33
+ hash[assoc_reflection.name] ||= assoc_reflection.table_name
34
+ hash
35
+ end
36
+ #end
37
+ end
38
+
39
+ end
40
+
41
+ #class ApplicationController
42
+ #
43
+ # def _generic_search
44
+ # base_class = self.class.to_s.gsub('Controller', '').singularize.constantize
45
+ # generic_search = GenericSearch::Klass.new(params, base_class)
46
+ # generic_search.search
47
+ # response = generic_search.response
48
+ #
49
+ # response[:client_IP] = self.request.headers["X-Cluster-Client-Ip"]
50
+ # response[:controller] = controller_name.classify.to_s
51
+ #
52
+ # render :json => generic_search.response
53
+ # end
54
+ #
55
+ # # Restrictions to the controller
56
+ # # generic_search_config(false) # to disable the generic search in a controller
57
+ # # generic_search_config(:model_class => Script) # to disable the generic search in a controller
58
+ # def self.generic_search_config(restrictions)
59
+ # # Restriction logic for controller
60
+ # end
61
+ #
62
+ #end
@@ -0,0 +1,181 @@
1
+ module GenericSearch
2
+
3
+ module Validation
4
+
5
+ def validate
6
+
7
+ end
8
+
9
+ def validate_syntax
10
+
11
+ [params[:query], params[:results], params[:group]].each do |query_string|
12
+
13
+ next if query_string.blank?
14
+
15
+ #if query_string.include?(',,')
16
+ if query_string.match(/\s*\,\s*\,\s*/)
17
+ @status = :bad_request
18
+ #@message = "malformed url - double comma"
19
+ @message = GenericSearch::Messages::DoubleComma
20
+ self.errors.add(:base, @message)
21
+ #return false
22
+ end
23
+
24
+ #if query_string.include?('((')
25
+ if query_string.match(/\s*\(\s*\(\s*/)
26
+ @status = :bad_request
27
+ @message = GenericSearch::Messages::DoubleOpenParan
28
+ self.errors.add(:base, @message)
29
+ #return false
30
+ end
31
+
32
+ # To check ))
33
+ if query_string.match(/\s*\)\s*\)\s*/)
34
+ @status = :bad_request
35
+ @message = GenericSearch::Messages::DoubleCloseParan
36
+ self.errors.add(:base, @message)
37
+ end
38
+
39
+ if query_string.count("()") % 2 == 1
40
+ @status = :bad_request
41
+ @message = GenericSearch::Messages::IncorrectUseOfParan
42
+ self.errors.add(:base, @message)
43
+ end
44
+ end
45
+
46
+ #if type.eql?("where_clause")
47
+ # puts "verifying specific legal query_strings for where_clause"
48
+ # if !query_string.include?('(')
49
+ # @status = :bad_request
50
+ # @message = "malformed url - no query arguments"
51
+ # return false
52
+ # end
53
+ #end
54
+
55
+ #return true
56
+ end
57
+
58
+ #def validate_table_columns
59
+ #
60
+ # #self.validate_query
61
+ #
62
+ #end
63
+
64
+ def validate_columns(table_name, column_names, clause)
65
+
66
+ connection = ActiveRecord::Base.connection
67
+ config = GenericSearch.config[table_name.intern]
68
+ config_for_where = (config and config[:for_where]) || {}
69
+ config_for_select = (config and config[:for_select]) || {}
70
+
71
+ if !connection.table_exists?(table_name) and !self.base_class.reflections.has_key?(table_name)
72
+ self.errors.add(:base, "'#{table_name}' table is invalid (in '#{clause}')")
73
+ return
74
+ end
75
+
76
+ if !connection.table_exists?(table_name)
77
+ if !self.base_class.reflections.has_key?(table_name)
78
+ self.errors.add(:base, "'#{table_name}' table is invalid (in '#{clause}')")
79
+ return
80
+ else
81
+ table_name = self.base_class._relation_table[table_name.intern]
82
+ end
83
+ end
84
+
85
+ return if column_names.blank?
86
+
87
+ unknown_columns = []
88
+
89
+ column_names.each do |column_name|
90
+ next if config_for_select and config_for_select.has_key?(column_name.intern)
91
+ next if config_for_where and config_for_where.has_key?(column_name.intern)
92
+
93
+ if !connection.column_exists?(table_name, column_name) and !config_for_select.has_key?(column_name.intern) and !config_for_where.has_key?(column_name.intern)
94
+ unknown_columns << column_name
95
+ end
96
+ end
97
+
98
+ if !unknown_columns.blank?
99
+ self.errors.add(:base, "'#{unknown_columns.join(', ')}' column#{unknown_columns.size > 1 ? 's' : ''} not found in '#{table_name}' table (in '#{clause}')")
100
+ end
101
+
102
+ end
103
+
104
+ def valid_syntax?(query_string)
105
+
106
+ end
107
+
108
+ def validate_query
109
+
110
+ end
111
+
112
+ def validate_results
113
+
114
+ end
115
+
116
+ def validate_group
117
+
118
+ end
119
+
120
+ def validate_sort_order
121
+
122
+ end
123
+
124
+ def validate_limit
125
+
126
+ end
127
+
128
+ #def validate_columns(table_name, column_names, clause)
129
+ #
130
+ # connection = ActiveRecord::Base.connection
131
+ #
132
+ # if !connection.table_exists?(table_name) and !self.base_class.reflections.has_key?(table_name.intern)
133
+ # @_uri_errors << "'#{table_name}' is invalid in '#{clause}'"
134
+ # return
135
+ # end
136
+ #
137
+ # if !connection.table_exists?(table_name)
138
+ # if !self.base_class.reflections.has_key?(table_name.intern)
139
+ # @_uri_errors << "'#{table_name}' is invalid in '#{clause}'"
140
+ # return
141
+ # else
142
+ # table_name = self.base_class._relation_table[table_name.intern]
143
+ # end
144
+ # end
145
+ #
146
+ # return if column_names.blank?
147
+ #
148
+ # unknown_columns = []
149
+ #
150
+ # config = GenericSearchMethods.config[table_name.intern]
151
+ # column_names.each do |column_name|
152
+ #
153
+ # next if config and config.has_key?(column_name.intern)
154
+ #
155
+ # if !connection.column_exists?(table_name, column_name)
156
+ # unknown_columns << column_name
157
+ # end
158
+ # end
159
+ #
160
+ # if !unknown_columns.blank?
161
+ # @_uri_errors << "'#{unknown_columns.join(', ')}' column#{unknown_columns.size > 1 ? 's' : ''} not found in '#{table_name}' table in '#{clause}'"
162
+ # end
163
+ #
164
+ #end
165
+
166
+ def validate_table_columns(table, columns)
167
+ #connection = ActiveRecord::Base.connection
168
+
169
+ #if connection.table_exists? table
170
+ #
171
+ #end
172
+
173
+ end
174
+
175
+ def validate_uri_syntax
176
+
177
+ end
178
+
179
+ end
180
+
181
+ end
@@ -0,0 +1,3 @@
1
+ module GenericSearch
2
+ VERSION = "1.3.2"
3
+ end
@@ -0,0 +1,201 @@
1
+ require 'active_record'
2
+ require 'generic_search/validation'
3
+ require 'generic_search/build_methods'
4
+ require 'generic_search/config'
5
+ require 'generic_search/exception'
6
+ require 'generic_search/rails_overrides'
7
+ require 'generic_search/validation'
8
+ require 'generic_search/messages'
9
+
10
+ module GenericSearch
11
+
12
+ @@generic_search = {
13
+ :config => {}
14
+ }
15
+
16
+ def self.update_config(class_name, config)
17
+ @@generic_search[:config][class_name.intern] = config
18
+ end
19
+
20
+ def self.config
21
+ @@generic_search[:config]
22
+ end
23
+
24
+ class Klass
25
+ include ActiveModel::Validations
26
+ include GenericSearch::Validation
27
+ include GenericSearch::BuildMethods
28
+
29
+ # Clause attributes
30
+ attr_accessor :where, :includes, :joins, :select, :group, :limit, :start, :sort_order, :options
31
+
32
+ # Utility attributes
33
+ attr_accessor :base_class, :base_table, :grouped_results, :params
34
+
35
+ # Output attributes
36
+ attr_accessor :status, :messages, :response, :results, :no_limit_count, :limit_result_count
37
+
38
+ validate :validate_syntax
39
+
40
+ # ===== To configure generic search in model =====
41
+ #generic_search_config {
42
+ # table_alias: {
43
+ # transitions: transition
44
+ # }
45
+ #}
46
+ # ===== To configure generic search in model =====
47
+
48
+
49
+ # ==== Hash Inputs: ===
50
+ #{
51
+ # :query => "responsibles(username=ksmanoj)",
52
+ # :results => "scripts(id, name), responsibles",
53
+ # :limit => 5,
54
+ # :options => "no_results"
55
+ #}
56
+ def initialize(params, base_class)
57
+
58
+ self.base_class = base_class.is_a?(String) ? base_class.constantize : base_class
59
+ self.base_table = self.base_class.table_name
60
+
61
+ unless params.is_a?(Hash) or params.is_a?(HashWithIndifferentAccess)
62
+ raise GenericSearch::UnknownInputType
63
+ end
64
+
65
+ self.params = params
66
+
67
+ self.validate_syntax
68
+
69
+ return unless self.errors.blank?
70
+
71
+ self.build_where(params[:query])
72
+ self.build_results(params[:results])
73
+ self.build_group(params[:group])
74
+ self.build_options(params[:options])
75
+ self.build_limit(params[:limit])
76
+ self.build_start(params[:start])
77
+ self.build_sort_order(params[:sort_order])
78
+
79
+ end
80
+
81
+ def search
82
+
83
+ unless self.errors.blank?
84
+ self.status = :bad_request
85
+ self.messages = self.errors.full_messages
86
+ self.build_response
87
+ return self.response
88
+ end
89
+
90
+ table_relation_map = self.base_class._table_relation
91
+ relation_table_map = self.base_class._relation_table
92
+
93
+ includes = Hash.new
94
+ json_includes = Hash.new
95
+
96
+ self.select.each do |table, value|
97
+ table = table.strip
98
+ relationship_name = table_relation_map[table]
99
+ relationship_name = table.intern if !relationship_name or relation_table_map[table.intern]
100
+ includes[relationship_name] = {} if table != self.base_table
101
+ json_includes[relationship_name] = {:only => self.select[table]} if table != self.base_table
102
+ end
103
+
104
+ # TODO: Solve n+1 issue for custom columns
105
+ #config = GenericSearch.config[self.base_table.intern][:for_select]
106
+ #selected_fields = table_selected_fields[self.base_table]
107
+ #
108
+ #config.each do |custom_column, attrs|
109
+ # if attrs[:include] and selected_fields.include?(custom_column.to_s)
110
+ # selected_fields << attrs[:include]
111
+ # end
112
+ #end
113
+ #
114
+
115
+ self.results = self.base_class.where(self.where).joins(self.joins).includes(self.includes).order(self.sort_order)
116
+
117
+ #result_list = @model_class.joins(@joins).includes(includes).where(@where_clause).distinct
118
+
119
+ # TODO: Test required
120
+ if self.options[:distinct]
121
+ self.results = self.results.uniq
122
+ end
123
+
124
+ # ========== Limiting & Grouping =========
125
+ # TODO: If there is a limit then only following count query has to be executed otherwise use .length
126
+ if self.options[:no_limit_count]
127
+ # Note: If no limit or start, then .length will fire the query, from that length is calculated.
128
+ # Additional count query is not required
129
+ self.no_limit_count = (self.limit || self.start) ? self.results.count : self.results.length
130
+ #self.no_limit_count = self.results.count
131
+ end
132
+
133
+ # TODO: Test required
134
+ unless self.options[:no_results]
135
+ self.results = self.results.limit(self.limit).offset(self.start)
136
+ end
137
+
138
+ # TODO: Test required
139
+ if self.group
140
+ group_result_counts = self.results.group(self.group).count
141
+ end
142
+
143
+ # ============== Group result processing
144
+ # TODO: Test required
145
+ if group_result_counts
146
+ # Hack to dynamically group the array of objects
147
+ eval_str = @group_object_access.collect { |i| "result.#{i}.to_s" }.join(' + ')
148
+ grouped_result = self.results.group_by { |result| eval eval_str }
149
+
150
+ group_hsh = group_result_counts.collect do |values, group_result_count|
151
+
152
+ values = values.is_a?(Array) ? values.collect(&:to_s) : [values.to_s]
153
+ result_key = values.join('')
154
+
155
+ results = if self.options[:no_results]
156
+ []
157
+ else
158
+ #grouped_result[result_key].as_json(:include => json_includes, :only => @table_selected_fields[self.base_table])
159
+ grouped_result[result_key].as_json(:include => json_includes, :only => self.select[self.base_table], :methods => self.select[self.base_table])
160
+ end
161
+
162
+ {
163
+ :group_by_field => self.group.join(', '),
164
+ :group_by_value => values.join(','),
165
+ :num_results => group_result_count,
166
+ #:results => grouped_result[result_key]
167
+ :results => results
168
+ }
169
+ end
170
+ else
171
+
172
+ results = if self.options[:no_results]
173
+ []
174
+ else
175
+
176
+ #self.results.as_json(:include => json_includes, :only => @table_selected_fields[self.base_table])
177
+ #self.results.as_json(:include => json_includes, :only => self.select[self.base_table], :methods => [:address_ids])
178
+ self.results.as_json(:include => json_includes, :only => self.select[self.base_table], :methods => self.select[self.base_table])
179
+ end
180
+
181
+ group_hsh = [{:num_results => self.results.length, :results => results}]
182
+
183
+ end
184
+
185
+ self.grouped_results = group_hsh
186
+
187
+ limit_result_count = 0
188
+
189
+ self.grouped_results.each do |grouped_result|
190
+ #limit_result_count += grouped_result["results"].count
191
+ limit_result_count += grouped_result[:num_results]
192
+ end
193
+
194
+ self.limit_result_count = limit_result_count
195
+ self.status = :ok
196
+ self.build_response
197
+ end
198
+
199
+ end
200
+
201
+ end
metadata ADDED
@@ -0,0 +1,124 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: generic_search
3
+ version: !ruby/object:Gem::Version
4
+ version: 1.3.2
5
+ platform: ruby
6
+ authors:
7
+ - Justin Hayes
8
+ - Manoj
9
+ autorequire:
10
+ bindir: exe
11
+ cert_chain: []
12
+ date: 2018-02-12 00:00:00.000000000 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: bundler
16
+ requirement: !ruby/object:Gem::Requirement
17
+ requirements:
18
+ - - ">="
19
+ - !ruby/object:Gem::Version
20
+ version: '0'
21
+ type: :development
22
+ prerelease: false
23
+ version_requirements: !ruby/object:Gem::Requirement
24
+ requirements:
25
+ - - ">="
26
+ - !ruby/object:Gem::Version
27
+ version: '0'
28
+ - !ruby/object:Gem::Dependency
29
+ name: rake
30
+ requirement: !ruby/object:Gem::Requirement
31
+ requirements:
32
+ - - ">="
33
+ - !ruby/object:Gem::Version
34
+ version: '0'
35
+ type: :development
36
+ prerelease: false
37
+ version_requirements: !ruby/object:Gem::Requirement
38
+ requirements:
39
+ - - ">="
40
+ - !ruby/object:Gem::Version
41
+ version: '0'
42
+ - !ruby/object:Gem::Dependency
43
+ name: rspec
44
+ requirement: !ruby/object:Gem::Requirement
45
+ requirements:
46
+ - - ">="
47
+ - !ruby/object:Gem::Version
48
+ version: '0'
49
+ type: :development
50
+ prerelease: false
51
+ version_requirements: !ruby/object:Gem::Requirement
52
+ requirements:
53
+ - - ">="
54
+ - !ruby/object:Gem::Version
55
+ version: '0'
56
+ - !ruby/object:Gem::Dependency
57
+ name: pry
58
+ requirement: !ruby/object:Gem::Requirement
59
+ requirements:
60
+ - - ">="
61
+ - !ruby/object:Gem::Version
62
+ version: '0'
63
+ type: :development
64
+ prerelease: false
65
+ version_requirements: !ruby/object:Gem::Requirement
66
+ requirements:
67
+ - - ">="
68
+ - !ruby/object:Gem::Version
69
+ version: '0'
70
+ - !ruby/object:Gem::Dependency
71
+ name: activerecord
72
+ requirement: !ruby/object:Gem::Requirement
73
+ requirements:
74
+ - - ">="
75
+ - !ruby/object:Gem::Version
76
+ version: '0'
77
+ type: :runtime
78
+ prerelease: false
79
+ version_requirements: !ruby/object:Gem::Requirement
80
+ requirements:
81
+ - - ">="
82
+ - !ruby/object:Gem::Version
83
+ version: '0'
84
+ description: Search any data from database without writing any code.
85
+ email:
86
+ - jhayes@juniper.net
87
+ - ksmanoj@juniper.net
88
+ executables: []
89
+ extensions: []
90
+ extra_rdoc_files: []
91
+ files:
92
+ - lib/generic_search.rb
93
+ - lib/generic_search/build_methods.rb
94
+ - lib/generic_search/config.rb
95
+ - lib/generic_search/exception.rb
96
+ - lib/generic_search/messages.rb
97
+ - lib/generic_search/rails_overrides.rb
98
+ - lib/generic_search/validation.rb
99
+ - lib/generic_search/version.rb
100
+ homepage: https://rubygems.org/bethink/generic_search
101
+ licenses:
102
+ - MIT
103
+ metadata: {}
104
+ post_install_message:
105
+ rdoc_options: []
106
+ require_paths:
107
+ - lib
108
+ required_ruby_version: !ruby/object:Gem::Requirement
109
+ requirements:
110
+ - - ">="
111
+ - !ruby/object:Gem::Version
112
+ version: '0'
113
+ required_rubygems_version: !ruby/object:Gem::Requirement
114
+ requirements:
115
+ - - ">="
116
+ - !ruby/object:Gem::Version
117
+ version: '0'
118
+ requirements: []
119
+ rubyforge_project:
120
+ rubygems_version: 2.4.5.1
121
+ signing_key:
122
+ specification_version: 4
123
+ summary: Search any data from database without writing any code.
124
+ test_files: []