Module: Hatio::SearchHelper
- Defined in:
- lib/hatio-core/action_controller/search_helper.rb
Instance Method Summary collapse
-
#build_conditions_by_filters(table_name, filter_str, columns) ⇒ Object
filter로 search condition 정보 생성.
-
#build_conditions_by_search_params(table_name, search_params, columns) ⇒ Object
search params로 search condition 정보 생성.
-
#build_orders_by_sort_params(orders) ⇒ Object
넘어온 sort 정보로 부터 sort정보를 추출 - “[”property“:”name“,”direction“:”DESC“]”.
-
#build_orders_by_sorters(sorter_str) ⇒ Object
넘어온 sort parameter 정보로 부터 sort정보를 추출.
-
#convert_like_type_condition_value(operator, value) ⇒ Object
like 타입 검색 조건이면 like 검색을 위해서 검색 조건 값을 like문에 맞게 변환한다.
-
#convert_reference_filter(column_name, filter_value, operator) ⇒ Object
resource.name-eq 형식으로 넘어온 파라미터는 Resource.find_by_name(파라미터 값)으로 검색하여 id를 찾아 값을 대치하고 파라미터 명도 resource_id-eq로 대치 TODO operator가 like 였을 경우 join query가 되어야 하고 파라미터 값은 join table의 검색 조건으로 변경되어야 한다.
-
#convert_value_by_col_type(filter_value, column) ⇒ Object
필드 타입 정보를 바탕으로 검색 조건 값을 sql에 맞게 변환한다.
-
#find_association_list(resource, columns, options = {}) ⇒ Object
resource의 entity_columns 정보 중 select 필드를 바탕으로 관계 정보를 추출한다.
-
#find_pagination_info ⇒ Object
params로 부터 pagination을 위한 정보를 추출한다.
-
#find_select_columns(columns) ⇒ Object
select fields를 찾는다.
-
#get_condition_str(table_name, column_name, operator) ⇒ Object
검색 조건 타입에 따라 sql where 문을 작성한다.
-
#include_entity_column?(columns, filter_name) ⇒ Boolean
filter name이 entity column내에 속해 있는지 확인한다.
-
#like_type_operator?(operator) ⇒ Boolean
검색 조건 중에 like 타입의 조건인지를 판단한다.
-
#none_value_operator?(operator) ⇒ Boolean
검색 조건 중에 검색 조건 값이 필요 없는 검색 조건인지 판단한다.
-
#search_filter(resource, options = {}) ⇒ Object
검색 조건, 소트 조건, Pagination 조건을 분석하여 검색을 구현.
-
#validate_filter_info(columns, filter_name, filter_value) ⇒ Object
filter 정보를 validation한다.
Instance Method Details
#build_conditions_by_filters(table_name, filter_str, columns) ⇒ Object
filter로 search condition 정보 생성
181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 |
# File 'lib/hatio-core/action_controller/search_helper.rb', line 181 def build_conditions_by_filters(table_name, filter_str, columns) # filter_str을 파싱하여 filter 오브젝트로 변환 filters, where_sql_arr, conditions = JSON.parse(filter_str), ["#{table_name}.id is not null"], [] filters.each do |filter| # filter의 name, value으로 validation check filter_name, filter_value, operator = validate_filter_info(columns, filter['property'], filter['value']) # valid 하지 않으면 처리하지 않는다. next unless filter_name # 검색조건 필드명이 entity_column에 등록되어 있는 경우에는 entity_column에서 필드 타입을 찾아 알맞은 타입으로 조건 값을 변경 entity_column = columns.find { |c| c.name == filter_name } if columns filter_value = convert_value_by_col_type(filter_value, entity_column) if entity_column # like 타입이라면 검색 조건이라면 like문에 맞게 값에 조건문을 수정한다. (like, not like) where_sql_arr << get_condition_str(table_name, filter_name, operator) # like 타입이라면 검색 조건이라면 like문에 맞게 값에 %를 붙인다. ('%찾을 문자열%', '%찾을 문자열', '찾을 문자열%') filter_value = convert_like_type_condition_value(operator, filter_value) #debug_print("Filter : #{filter_name}, Value : #{filter_value}, Operator : #{operator}") # 하나의 필드에 대한 조건 값을 conditions 배열에 추가한다. conditions.push(filter_value) unless none_value_operator?(operator) end # 최종적으로 만들어진 sql where문을 conditions 배열 맨 앞쪽에 추가한다. conditions.insert(0, where_sql_arr.join(" and ")) end |
#build_conditions_by_search_params(table_name, search_params, columns) ⇒ Object
search params로 search condition 정보 생성
207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 |
# File 'lib/hatio-core/action_controller/search_helper.rb', line 207 def build_conditions_by_search_params(table_name, search_params, columns) where_sql_arr, conditions = ["#{table_name}.id is not null"], [] # 넘어온 검색 조건 값을 - 로 구분하여 앞 부분은 검색 조건 필드명으로, 뒷 부분은 검색을 위한 operator로 사용햔다. search_params.each do |param_name, param_value| # filter의 name, value으로 validation check filter_name, filter_value, operator = validate_filter_info(columns, param_name, param_value) # valid 하지 않으면 처리하지 않는다. next unless filter_name # 검색조건 필드명이 entity_column에 등록되어 있는 경우에는 entity_column에서 필드 타입을 찾아 알맞은 타입으로 조건 값을 변경 entity_column = columns.find { |c| c.name == filter_name } if columns filter_value = convert_value_by_col_type(filter_value, entity_column) if entity_column # like 타입이라면 검색 조건이라면 like문에 맞게 값에 조건문을 수정한다. (like, not like) where_sql_arr << get_condition_str(table_name, filter_name, operator) # like 타입이라면 검색 조건이라면 like문에 맞게 값에 %를 붙인다. ('%찾을 문자열%', '%찾을 문자열', '찾을 문자열%') filter_value = convert_like_type_condition_value(operator, filter_value) #debug_print("Filter : #{filter_name}, Value : #{filter_value}, Operator : #{operator}") # 하나의 필드에 대한 조건 값을 conditions 배열에 추가한다. conditions.push(filter_value) unless none_value_operator?(operator) end conditions.insert(0, where_sql_arr.join(" and ")) end |
#build_orders_by_sort_params(orders) ⇒ Object
넘어온 sort 정보로 부터 sort정보를 추출 - “[”property“:”name“,”direction“:”DESC“]”
283 284 285 |
# File 'lib/hatio-core/action_controller/search_helper.rb', line 283 def build_orders_by_sort_params(orders) return (orders && !orders.empty?) ? orders.collect { |name, direction| "#{name} #{direction}"}.join(",") : "" end |
#build_orders_by_sorters(sorter_str) ⇒ Object
넘어온 sort parameter 정보로 부터 sort정보를 추출
290 291 292 293 294 295 296 297 |
# File 'lib/hatio-core/action_controller/search_helper.rb', line 290 def build_orders_by_sorters(sorter_str) order_result = "" if(sorter_str && !sorter_str.blank?) sorters = JSON.parse(sorter_str) order_result = sorters.collect { |sorter| "#{sorter['property']} #{sorter['direction']}" }.join(",") end return order_result end |
#convert_like_type_condition_value(operator, value) ⇒ Object
like 타입 검색 조건이면 like 검색을 위해서 검색 조건 값을 like문에 맞게 변환한다.
81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 |
# File 'lib/hatio-core/action_controller/search_helper.rb', line 81 def convert_like_type_condition_value(operator, value) return value unless like_type_operator?(operator) value = value.strip case operator when 'like' # like return "%#{value}%" when 'contains' # equals to like return "%#{value}%" when 'nlike' # not like return "%#{value}%" when 'sw' # starts with return "#{value}%" when 'dnsw' # does not start with return "#{value}%" when 'ew' # ends with return "%#{value}" when 'dnew' # does not end with return "%#{value}" when 'in' val_arr = value.split(",") return val_arr; when 'notin' val_arr = value.split(",") return val_arr; end end |
#convert_reference_filter(column_name, filter_value, operator) ⇒ Object
resource.name-eq 형식으로 넘어온 파라미터는 Resource.find_by_name(파라미터 값)으로 검색하여 id를 찾아 값을 대치하고 파라미터 명도 resource_id-eq로 대치TODO operator가 like 였을 경우 join query가 되어야 하고 파라미터 값은 join table의 검색 조건으로 변경되어야 한다.
263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 |
# File 'lib/hatio-core/action_controller/search_helper.rb', line 263 def convert_reference_filter(column_name, filter_value, operator) column_name_arr = column_name.split('.') return column_name, filter_value, operator if(column_name_arr.size <= 1 || filter_value.blank?) # 새로운 컬럼명 : {entityname}_id new_column_name = "#{column_name_arr[0]}_id" if(column_name_arr[1] == 'id') return new_column_name, filter_value, operator else resource = column_name_arr[0].camelcase.constantize conds = { column_name_arr[1].to_sym => filter_value } #conds[:domain_id] = @domain.id if(@domain.respond_to?(resource.name.pluralize.to_sym)) instance = resource.where(conds).first return new_column_name, (instance ? instance.id : ''), operator end end |
#convert_value_by_col_type(filter_value, column) ⇒ Object
필드 타입 정보를 바탕으로 검색 조건 값을 sql에 맞게 변환한다.
66 67 68 69 70 71 72 73 74 75 76 |
# File 'lib/hatio-core/action_controller/search_helper.rb', line 66 def convert_value_by_col_type(filter_value, column) if(column.col_type == 'time' || column.col_type == 'datetime' || column.col_type == 'timestamp') return (filter_value.size <= 10) ? parse_date(filter_value) : parse_time_to_db(filter_value) elsif(column.col_type == 'date') return parse_date(filter_value) elsif(column.col_type == 'boolean') return (filter_value.to_s =~ /^(t|true|on|y|yes)$/i) == 0 ? true : false else return filter_value end end |
#find_association_list(resource, columns, options = {}) ⇒ Object
resource의 entity_columns 정보 중 select 필드를 바탕으로 관계 정보를 추출한다.
312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 |
# File 'lib/hatio-core/action_controller/search_helper.rb', line 312 def find_association_list(resource, columns, = {}) ref_columns = columns.select { |c| c.name != "domain_id" && c.ref_type == "Entity" && c.ref_name } return ref_columns.collect do |column| association_symbol = column.name.sub(/_id$/, '').to_sym association = resource.reflect_on_association association_symbol if association association_symbol unless association.[:polymorphic] == true else association = resource.reflect_on_all_associations.detect { |a| a.[:foreign_key] == column.name.to_sym } if association association.name.to_sym else association = resource.reflect_on_all_associations.detect { |a| a.[:class_name] == column.ref_name } association.name.to_sym if association end end end.compact end |
#find_pagination_info ⇒ Object
params로 부터 pagination을 위한 정보를 추출한다.
302 303 304 305 306 307 |
# File 'lib/hatio-core/action_controller/search_helper.rb', line 302 def find_pagination_info page = (params[:page] || 1).to_i limit = (params[:limit] || GlobalConfig.default_page_size).to_i offset = (page - 1) * limit return page, limit, offset end |
#find_select_columns(columns) ⇒ Object
select fields를 찾는다. select 파라미터가 넘어오면 해당 필드만, 그렇지 않으면 모든 필드가 select 대상이다.
56 57 58 59 60 61 |
# File 'lib/hatio-core/action_controller/search_helper.rb', line 56 def find_select_columns(columns) select_columns = (!params[:_s] || params[:_s].blank?) ? [] : params[:_s] return select_columns.empty? ? columns : columns.select{ |c| select_columns.include?(c.name) || select_columns.include?(c.name.sub(/_id$/, '')) } end |
#get_condition_str(table_name, column_name, operator) ⇒ Object
검색 조건 타입에 따라 sql where 문을 작성한다.
126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 |
# File 'lib/hatio-core/action_controller/search_helper.rb', line 126 def get_condition_str(table_name, column_name, operator) case operator when 'eq' # equal return " #{table_name}.#{column_name} = ?" when 'noteq' # not equal return " #{table_name}.#{column_name} != ?" when 'in' # in return " #{table_name}.#{column_name} in (?)" when 'notin' # not in return " #{table_name}.#{column_name} not in (?)" when 'like', 'contains', 'sw', 'ew' # like return " lower(#{table_name}.#{column_name}) like lower(?)" when 'nlike', 'dnsw', 'dnew' # not like return " lower(#{table_name}.#{column_name}) not like lower(?)" when 'gt' # greater than return " #{table_name}.#{column_name} > ?" when 'gte' # greater than equal return " #{table_name}.#{column_name} >= ?" when 'lt' # less than return " #{table_name}.#{column_name} < ?" when 'lte' # less than equal return " #{table_name}.#{column_name} <= ?" when 'dt_eq' # date equal return " #{GlobalConfig.to_date_db_func}(#{table_name}.#{column_name}) = ?" when 'dt_noteq' # date not equal return " #{GlobalConfig.to_date_db_func}(#{table_name}.#{column_name}) != ?" when 'dt_gt' # date greater than return " #{GlobalConfig.to_date_db_func}(#{table_name}.#{column_name}) > ?" when 'dt_gte' # date greater than equal return " #{GlobalConfig.to_date_db_func}(#{table_name}.#{column_name}) >= ?" when 'dt_lt' # date less than return " #{GlobalConfig.to_date_db_func}(#{table_name}.#{column_name}) < ?" when 'dt_lte' # date less than equal return " #{GlobalConfig.to_date_db_func}(#{table_name}.#{column_name}) <= ?" when 'is_null' # is null return " #{table_name}.#{column_name} is null" when 'is_not_null' # is not null return " #{table_name}.#{column_name} is not null" when 'is_true' # is true return " #{table_name}.#{column_name} = true" when 'is_false' # is false return " #{table_name}.#{column_name} = false" when 'is_present' # not null or not empty string return " (#{table_name}.#{column_name} is not null and #{table_name}.#{column_name} != '')" when 'is_blank' # null or empty string return " (#{table_name}.#{column_name} is null or #{table_name}.#{column_name} = '')" end return ""; end |
#include_entity_column?(columns, filter_name) ⇒ Boolean
filter name이 entity column내에 속해 있는지 확인한다.
254 255 256 257 |
# File 'lib/hatio-core/action_controller/search_helper.rb', line 254 def include_entity_column?(columns, filter_name) fc = columns.find { |column| column.name == filter_name } return !fc.nil? end |
#like_type_operator?(operator) ⇒ Boolean
검색 조건 중에 like 타입의 조건인지를 판단한다.
119 120 121 |
# File 'lib/hatio-core/action_controller/search_helper.rb', line 119 def like_type_operator?(operator) ['like', 'contains', 'nlike', 'sw', 'dnsw', 'ew', 'dnew', 'in', 'notin'].include?(operator) end |
#none_value_operator?(operator) ⇒ Boolean
검색 조건 중에 검색 조건 값이 필요 없는 검색 조건인지 판단한다.
112 113 114 |
# File 'lib/hatio-core/action_controller/search_helper.rb', line 112 def none_value_operator?(operator) ['is_null', 'is_not_null', 'is_true', 'is_false', 'is_present', 'is_blank'].include?(operator) end |
#search_filter(resource, options = {}) ⇒ Object
검색 조건, 소트 조건, Pagination 조건을 분석하여 검색을 구현
7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 |
# File 'lib/hatio-core/action_controller/search_helper.rb', line 7 def search_filter resource, = {} # pagination 정보는 넘어온 page, limit 정보를 이용 page, limit, offset = find_pagination_info search_param_type, search_params = nil, nil # search parameter는 filter or _q 파라미터를 이용 if(!params[:_q].blank?) search_param_type, search_params = 1, params[:_q] elsif(!params[:filter].blank?) search_param_type, search_params = 2, params[:filter] else search_param_type, search_params = 1, params end # sort parameter는 sort or _o 파라미터를 이용 sort_type, sort_params, order_result = nil, nil, "" if(!params[:_o].blank?) sort_type, sort_params = 1, params[:_o] elsif(!params[:sort].blank?) sort_type, sort_params = 2, params[:sort] end # table name을 찾고 where 조건의 컬럼명 앞에 table_name.을 붙인다. Join 쿼리를 사용 할 경우 애매한 열 정의를 없애기 위함 table_name = .key?(:table_name) ? [:table_name] : resource.table_name entity = Entity.find_by_name(resource.to_s) if(entity) columns = entity.columns_for_search # select fields는 select parameter가 있으면 select parameter를, 없으면 select * list_columns = find_select_columns(columns) if(search_param_type == 1) conditions = build_conditions_by_search_params(table_name, search_params, columns) elsif(search_param_type == 2) conditions = build_conditions_by_filters(table_name, search_params, columns) end # select parameter로 association이 있는 부분을 찾아서 ... include_arr = find_association_list(resource, list_columns, ) order_result = (sort_type == 1) ? build_orders_by_sort_params(sort_params) : build_orders_by_sorters(sort_params) if(sort_type) return conditions, include_arr, order_result, limit, offset else debug_print "Not found Entity of resource [#{resource.to_s}]" return "", [], "", limit, offset end end |
#validate_filter_info(columns, filter_name, filter_value) ⇒ Object
filter 정보를 validation한다.
232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 |
# File 'lib/hatio-core/action_controller/search_helper.rb', line 232 def validate_filter_info(columns, filter_name, filter_value) # filter_name이 domain_id라면 스킵 return false if(filter_name.start_with?('domain_id')) gubunIndex = filter_name.rindex('-') filter_name_length = filter_name.length # - 로 구분된 문자열이 없다면 조건 검색을 위한 용도가 아니라고 판단 return false unless gubunIndex # operator는 무조건 두 글자 이상이어야 한다. return false unless (filter_name_length - gubunIndex > 1) # 넘어온 검색 조건 값을 - 로 구분하여 앞 부분은 검색 조건 필드명으로, 뒷 부분은 검색을 위한 operator로 사용햔다. column_name, operator = filter_name[0 .. (gubunIndex - 1)], filter_name[(gubunIndex + 1) .. (filter_name_length - 1)] # resource.name-eq 형식으로 넘어온 경우는 Resource.find_by_name으로 검색하고 파라미터 명은 resource_id-eq형식으로 변환한다. column_name, filter_value, operator = convert_reference_filter(column_name, filter_value, operator) # 값이 비어 있고 조건 값이 필요없는 경우 ('is_null', 'is_not_null', 'is_true', 'is_false', 'is_present', 'is_blank')가 아니면 스킵 return false if (filter_value.blank? && !none_value_operator?(operator)) return false unless (include_entity_column?(columns, column_name)) return column_name, filter_value, operator end |