Mercurial > hg > soundsoftware-site
diff app/models/query.rb @ 1517:dffacf8a6908 redmine-2.5
Update to Redmine SVN revision 13367 on 2.5-stable branch
author | Chris Cannam |
---|---|
date | Tue, 09 Sep 2014 09:29:00 +0100 |
parents | e248c7af89ec |
children |
line wrap: on
line diff
--- a/app/models/query.rb Tue Sep 09 09:28:31 2014 +0100 +++ b/app/models/query.rb Tue Sep 09 09:29:00 2014 +0100 @@ -242,7 +242,9 @@ when :date, :date_past case operator_for(field) when "=", ">=", "<=", "><" - add_filter_error(field, :invalid) if values_for(field).detect {|v| v.present? && (!v.match(/^\d{4}-\d{2}-\d{2}$/) || (Date.parse(v) rescue nil).nil?) } + add_filter_error(field, :invalid) if values_for(field).detect {|v| + v.present? && (!v.match(/\A\d{4}-\d{2}-\d{2}(T\d{2}((:)?\d{2}){0,2}(Z|\d{2}:?\d{2})?)?\z/) || parse_date(v).nil?) + } when ">t-", "<t-", "t-", ">t+", "<t+", "t+", "><t+", "><t-" add_filter_error(field, :invalid) if values_for(field).detect {|v| v.present? && !v.match(/^\d+$/) } end @@ -587,7 +589,7 @@ db_field = 'value' filter = @available_filters[field] return nil unless filter - if filter[:format] == 'user' + if filter[:field].format.target_class && filter[:field].format.target_class <= User if value.delete('me') value.push User.current.id.to_s end @@ -624,7 +626,7 @@ if value.any? case type_for(field) when :date, :date_past - sql = date_clause(db_table, db_field, (Date.parse(value.first) rescue nil), (Date.parse(value.first) rescue nil)) + sql = date_clause(db_table, db_field, parse_date(value.first), parse_date(value.first)) when :integer if is_custom_filter sql = "(#{db_table}.#{db_field} <> '' AND CAST(CASE #{db_table}.#{db_field} WHEN '' THEN '0' ELSE #{db_table}.#{db_field} END AS decimal(30,3)) = #{value.first.to_i})" @@ -659,7 +661,7 @@ sql << " AND #{db_table}.#{db_field} <> ''" if is_custom_filter when ">=" if [:date, :date_past].include?(type_for(field)) - sql = date_clause(db_table, db_field, (Date.parse(value.first) rescue nil), nil) + sql = date_clause(db_table, db_field, parse_date(value.first), nil) else if is_custom_filter sql = "(#{db_table}.#{db_field} <> '' AND CAST(CASE #{db_table}.#{db_field} WHEN '' THEN '0' ELSE #{db_table}.#{db_field} END AS decimal(30,3)) >= #{value.first.to_f})" @@ -669,7 +671,7 @@ end when "<=" if [:date, :date_past].include?(type_for(field)) - sql = date_clause(db_table, db_field, nil, (Date.parse(value.first) rescue nil)) + sql = date_clause(db_table, db_field, nil, parse_date(value.first)) else if is_custom_filter sql = "(#{db_table}.#{db_field} <> '' AND CAST(CASE #{db_table}.#{db_field} WHEN '' THEN '0' ELSE #{db_table}.#{db_field} END AS decimal(30,3)) <= #{value.first.to_f})" @@ -679,7 +681,7 @@ end when "><" if [:date, :date_past].include?(type_for(field)) - sql = date_clause(db_table, db_field, (Date.parse(value[0]) rescue nil), (Date.parse(value[1]) rescue nil)) + sql = date_clause(db_table, db_field, parse_date(value[0]), parse_date(value[1])) else if is_custom_filter sql = "(#{db_table}.#{db_field} <> '' AND CAST(CASE #{db_table}.#{db_field} WHEN '' THEN '0' ELSE #{db_table}.#{db_field} END AS decimal(30,3)) BETWEEN #{value[0].to_f} AND #{value[1].to_f})" @@ -764,29 +766,13 @@ # Adds a filter for the given custom field def add_custom_field_filter(field, assoc=nil) - case field.field_format - when "text" - options = { :type => :text } - when "list" - options = { :type => :list_optional, :values => field.possible_values } - when "date" - options = { :type => :date } - when "bool" - options = { :type => :list, :values => [[l(:general_text_yes), "1"], [l(:general_text_no), "0"]] } - when "int" - options = { :type => :integer } - when "float" - options = { :type => :float } - when "user", "version" - return unless project - values = field.possible_values_options(project) - if User.current.logged? && field.field_format == 'user' - values.unshift ["<< #{l(:label_me)} >>", "me"] + options = field.format.query_filter_options(field, self) + if field.format.target_class && field.format.target_class <= User + if options[:values].is_a?(Array) && User.current.logged? + options[:values].unshift ["<< #{l(:label_me)} >>", "me"] end - options = { :type => :list_optional, :values => values } - else - options = { :type => :string } end + filter_id = "cf_#{field.id}" filter_name = field.name if assoc.present? @@ -795,7 +781,6 @@ end add_available_filter filter_id, options.merge({ :name => filter_name, - :format => field.field_format, :field => field }) end @@ -826,19 +811,24 @@ def date_clause(table, field, from, to) s = [] if from - from_yesterday = from - 1 - from_yesterday_time = Time.local(from_yesterday.year, from_yesterday.month, from_yesterday.day) + if from.is_a?(Date) + from = Time.local(from.year, from.month, from.day).yesterday.end_of_day + else + from = from - 1 # second + end if self.class.default_timezone == :utc - from_yesterday_time = from_yesterday_time.utc + from = from.utc end - s << ("#{table}.#{field} > '%s'" % [connection.quoted_date(from_yesterday_time.end_of_day)]) + s << ("#{table}.#{field} > '%s'" % [connection.quoted_date(from)]) end if to - to_time = Time.local(to.year, to.month, to.day) + if to.is_a?(Date) + to = Time.local(to.year, to.month, to.day).end_of_day + end if self.class.default_timezone == :utc - to_time = to_time.utc + to = to.utc end - s << ("#{table}.#{field} <= '%s'" % [connection.quoted_date(to_time.end_of_day)]) + s << ("#{table}.#{field} <= '%s'" % [connection.quoted_date(to)]) end s.join(' AND ') end @@ -848,6 +838,15 @@ date_clause(table, field, (days_from ? Date.today + days_from : nil), (days_to ? Date.today + days_to : nil)) end + # Returns a Date or Time from the given filter value + def parse_date(arg) + if arg.to_s =~ /\A\d{4}-\d{2}-\d{2}T/ + Time.parse(arg) rescue nil + else + Date.parse(arg) rescue nil + end + end + # Additional joins required for the given sort options def joins_for_order_statement(order_options) joins = []