123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235 |
- class SqlHelper
- def self.quote_string(value)
- ActiveRecord::Base.connection.quote_string(value)
- end
- def self.quote_like(...)
- ApplicationModel.sanitize_sql_like(...)
- end
- def initialize(object:, table_name: nil)
- @object = object
- @table_name = table_name
- end
- def db_column(column)
- "#{ActiveRecord::Base.connection.quote_table_name(@table_name || @object.table_name)}.#{ActiveRecord::Base.connection.quote_column_name(column)}"
- end
- def json_column?(attribute)
- @object.column_for_attribute(attribute).type == :jsonb
- end
- def json_db_column_with_key(attribute, key)
- "#{db_column(attribute)}->>#{ActiveRecord::Base.connection.quote(key)}"
- end
- def get_param_key(key, params)
- sort_by = []
- if params[key].present? && params[key].is_a?(String)
- params[key] = params[key].split(%r{\s*,\s*})
- elsif params[key].blank?
- params[key] = []
- end
- sort_by
- end
- def get_sort_by(params, default = nil)
- sort_by = get_param_key(:sort_by, params)
-
- params[:sort_by].each do |value|
-
- raise "Found invalid column '#{value}' for sorting." if @object.columns_hash[value].blank?
- sort_by.push(value)
- end
- if sort_by.blank? && default.present?
- if default.is_a?(Array)
- sort_by = default
- else
- sort_by.push(default)
- end
- end
- sort_by
- end
- def get_order_by(params, default = nil)
- order_by = get_param_key(:order_by, params)
-
- params[:order_by].each do |value|
- raise "Found invalid order by value #{value}. Please use 'asc' or 'desc'." if !value.match?(%r{\A(asc|desc)\z}i)
- order_by.push(value.downcase)
- end
- if order_by.blank? && default.present?
- if default.is_a?(Array)
- order_by = default
- else
- order_by.push(default)
- end
- end
- order_by
- end
- def set_sql_order_default(sql, default)
- if sql.blank? && default.present?
- sql.push(db_column(default))
- end
- sql
- end
- def get_order_select(sort_by, order_by, default = nil)
- sql = []
- sort_by.each_with_index do |value, index|
- next if value.blank?
- next if order_by[index].blank?
- sql.push(db_column(value))
- end
- sql = set_sql_order_default(sql, default)
- sql.join(', ')
- end
- def get_order(sort_by, order_by, default = nil)
- sql = []
- sort_by.each_with_index do |value, index|
- next if value.blank?
- next if order_by[index].blank?
- sql.push("#{db_column(value)} #{order_by[index]}")
- end
- sql = set_sql_order_default(sql, default)
- sql.join(', ')
- end
- def containable?(attribute)
- ObjectManager::Attribute.for_object(@object).exists?(name: attribute, data_type: %w[multiselect multi_tree_select])
- end
- def array_contains_all(attribute, value, negated: false)
- value = [''] if value.blank?
- value = Array(value)
- result = if Rails.application.config.db_column_array
- "(#{db_column(attribute)} @> ARRAY[#{value.map { |v| "'#{self.class.quote_string(v)}'" }.join(',')}]::varchar[])"
- else
- "JSON_CONTAINS(#{db_column(attribute)}, '#{self.class.quote_string(value.to_json)}', '$')"
- end
- negated ? "NOT(#{result})" : "(#{result})"
- end
- def array_contains_one(attribute, value, negated: false)
- value = [''] if value.blank?
- value = Array(value)
- result = if Rails.application.config.db_column_array
- "(#{db_column(attribute)} && ARRAY[#{value.map { |v| "'#{self.class.quote_string(v)}'" }.join(',')}]::varchar[])"
- else
- value.map { |v| "JSON_CONTAINS(#{db_column(attribute)}, '#{self.class.quote_string(v.to_json)}', '$')" }.join(' OR ')
- end
- negated ? "NOT(#{result})" : "(#{result})"
- end
- def regex_match(attribute, negated: false)
- operator = if mysql?
- negated ? 'NOT REGEXP' : 'REGEXP'
- else
- negated ? '!~*' : '~*'
- end
- "#{attribute} #{operator} (?)"
- end
- private
- def mysql?
- ActiveRecord::Base.connection_db_config.configuration_hash[:adapter] == 'mysql2'
- end
- end
|