1
0
mirror of https://github.com/meineerde/redmine.git synced 2026-03-29 20:21:11 +00:00

Fixed filtering on date custom field with SQLServer.

git-svn-id: http://svn.redmine.org/redmine/trunk@13993 e93f8b46-1217-0410-a6f0-8f06a7374b81
This commit is contained in:
Jean-Philippe Lang 2015-02-08 16:23:16 +00:00
parent c3b91d6f04
commit db9bf8cd73

View File

@ -648,7 +648,7 @@ class Query < ActiveRecord::Base
if value.any? if value.any?
case type_for(field) case type_for(field)
when :date, :date_past when :date, :date_past
sql = date_clause(db_table, db_field, parse_date(value.first), parse_date(value.first)) sql = date_clause(db_table, db_field, parse_date(value.first), parse_date(value.first), is_custom_filter)
when :integer when :integer
if is_custom_filter 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})" 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})"
@ -683,7 +683,7 @@ class Query < ActiveRecord::Base
sql << " AND #{db_table}.#{db_field} <> ''" if is_custom_filter sql << " AND #{db_table}.#{db_field} <> ''" if is_custom_filter
when ">=" when ">="
if [:date, :date_past].include?(type_for(field)) if [:date, :date_past].include?(type_for(field))
sql = date_clause(db_table, db_field, parse_date(value.first), nil) sql = date_clause(db_table, db_field, parse_date(value.first), nil, is_custom_filter)
else else
if is_custom_filter 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})" 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})"
@ -693,7 +693,7 @@ class Query < ActiveRecord::Base
end end
when "<=" when "<="
if [:date, :date_past].include?(type_for(field)) if [:date, :date_past].include?(type_for(field))
sql = date_clause(db_table, db_field, nil, parse_date(value.first)) sql = date_clause(db_table, db_field, nil, parse_date(value.first), is_custom_filter)
else else
if is_custom_filter 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})" 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})"
@ -703,7 +703,7 @@ class Query < ActiveRecord::Base
end end
when "><" when "><"
if [:date, :date_past].include?(type_for(field)) if [:date, :date_past].include?(type_for(field))
sql = date_clause(db_table, db_field, parse_date(value[0]), parse_date(value[1])) sql = date_clause(db_table, db_field, parse_date(value[0]), parse_date(value[1]), is_custom_filter)
else else
if is_custom_filter 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})" 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})"
@ -717,64 +717,64 @@ class Query < ActiveRecord::Base
sql = "#{queried_table_name}.status_id IN (SELECT id FROM #{IssueStatus.table_name} WHERE is_closed=#{self.class.connection.quoted_true})" if field == "status_id" sql = "#{queried_table_name}.status_id IN (SELECT id FROM #{IssueStatus.table_name} WHERE is_closed=#{self.class.connection.quoted_true})" if field == "status_id"
when "><t-" when "><t-"
# between today - n days and today # between today - n days and today
sql = relative_date_clause(db_table, db_field, - value.first.to_i, 0) sql = relative_date_clause(db_table, db_field, - value.first.to_i, 0, is_custom_filter)
when ">t-" when ">t-"
# >= today - n days # >= today - n days
sql = relative_date_clause(db_table, db_field, - value.first.to_i, nil) sql = relative_date_clause(db_table, db_field, - value.first.to_i, nil, is_custom_filter)
when "<t-" when "<t-"
# <= today - n days # <= today - n days
sql = relative_date_clause(db_table, db_field, nil, - value.first.to_i) sql = relative_date_clause(db_table, db_field, nil, - value.first.to_i, is_custom_filter)
when "t-" when "t-"
# = n days in past # = n days in past
sql = relative_date_clause(db_table, db_field, - value.first.to_i, - value.first.to_i) sql = relative_date_clause(db_table, db_field, - value.first.to_i, - value.first.to_i, is_custom_filter)
when "><t+" when "><t+"
# between today and today + n days # between today and today + n days
sql = relative_date_clause(db_table, db_field, 0, value.first.to_i) sql = relative_date_clause(db_table, db_field, 0, value.first.to_i, is_custom_filter)
when ">t+" when ">t+"
# >= today + n days # >= today + n days
sql = relative_date_clause(db_table, db_field, value.first.to_i, nil) sql = relative_date_clause(db_table, db_field, value.first.to_i, nil, is_custom_filter)
when "<t+" when "<t+"
# <= today + n days # <= today + n days
sql = relative_date_clause(db_table, db_field, nil, value.first.to_i) sql = relative_date_clause(db_table, db_field, nil, value.first.to_i, is_custom_filter)
when "t+" when "t+"
# = today + n days # = today + n days
sql = relative_date_clause(db_table, db_field, value.first.to_i, value.first.to_i) sql = relative_date_clause(db_table, db_field, value.first.to_i, value.first.to_i, is_custom_filter)
when "t" when "t"
# = today # = today
sql = relative_date_clause(db_table, db_field, 0, 0) sql = relative_date_clause(db_table, db_field, 0, 0, is_custom_filter)
when "ld" when "ld"
# = yesterday # = yesterday
sql = relative_date_clause(db_table, db_field, -1, -1) sql = relative_date_clause(db_table, db_field, -1, -1, is_custom_filter)
when "w" when "w"
# = this week # = this week
first_day_of_week = l(:general_first_day_of_week).to_i first_day_of_week = l(:general_first_day_of_week).to_i
day_of_week = Date.today.cwday day_of_week = Date.today.cwday
days_ago = (day_of_week >= first_day_of_week ? day_of_week - first_day_of_week : day_of_week + 7 - first_day_of_week) days_ago = (day_of_week >= first_day_of_week ? day_of_week - first_day_of_week : day_of_week + 7 - first_day_of_week)
sql = relative_date_clause(db_table, db_field, - days_ago, - days_ago + 6) sql = relative_date_clause(db_table, db_field, - days_ago, - days_ago + 6, is_custom_filter)
when "lw" when "lw"
# = last week # = last week
first_day_of_week = l(:general_first_day_of_week).to_i first_day_of_week = l(:general_first_day_of_week).to_i
day_of_week = Date.today.cwday day_of_week = Date.today.cwday
days_ago = (day_of_week >= first_day_of_week ? day_of_week - first_day_of_week : day_of_week + 7 - first_day_of_week) days_ago = (day_of_week >= first_day_of_week ? day_of_week - first_day_of_week : day_of_week + 7 - first_day_of_week)
sql = relative_date_clause(db_table, db_field, - days_ago - 7, - days_ago - 1) sql = relative_date_clause(db_table, db_field, - days_ago - 7, - days_ago - 1, is_custom_filter)
when "l2w" when "l2w"
# = last 2 weeks # = last 2 weeks
first_day_of_week = l(:general_first_day_of_week).to_i first_day_of_week = l(:general_first_day_of_week).to_i
day_of_week = Date.today.cwday day_of_week = Date.today.cwday
days_ago = (day_of_week >= first_day_of_week ? day_of_week - first_day_of_week : day_of_week + 7 - first_day_of_week) days_ago = (day_of_week >= first_day_of_week ? day_of_week - first_day_of_week : day_of_week + 7 - first_day_of_week)
sql = relative_date_clause(db_table, db_field, - days_ago - 14, - days_ago - 1) sql = relative_date_clause(db_table, db_field, - days_ago - 14, - days_ago - 1, is_custom_filter)
when "m" when "m"
# = this month # = this month
date = Date.today date = Date.today
sql = date_clause(db_table, db_field, date.beginning_of_month, date.end_of_month) sql = date_clause(db_table, db_field, date.beginning_of_month, date.end_of_month, is_custom_filter)
when "lm" when "lm"
# = last month # = last month
date = Date.today.prev_month date = Date.today.prev_month
sql = date_clause(db_table, db_field, date.beginning_of_month, date.end_of_month) sql = date_clause(db_table, db_field, date.beginning_of_month, date.end_of_month, is_custom_filter)
when "y" when "y"
# = this year # = this year
date = Date.today date = Date.today
sql = date_clause(db_table, db_field, date.beginning_of_year, date.end_of_year) sql = date_clause(db_table, db_field, date.beginning_of_year, date.end_of_year, is_custom_filter)
when "~" when "~"
sql = "LOWER(#{db_table}.#{db_field}) LIKE '%#{self.class.connection.quote_string(value.first.to_s.downcase)}%'" sql = "LOWER(#{db_table}.#{db_field}) LIKE '%#{self.class.connection.quote_string(value.first.to_s.downcase)}%'"
when "!~" when "!~"
@ -829,8 +829,18 @@ class Query < ActiveRecord::Base
end end
end end
def quoted_time(time, is_custom_filter)
if is_custom_filter
# Custom field values are stored as strings in the DB
# using this format that does not depend on DB date representation
time.strftime("%Y-%m-%d %H:%M:%S")
else
self.class.connection.quoted_date(time)
end
end
# Returns a SQL clause for a date or datetime field. # Returns a SQL clause for a date or datetime field.
def date_clause(table, field, from, to) def date_clause(table, field, from, to, is_custom_filter)
s = [] s = []
if from if from
if from.is_a?(Date) if from.is_a?(Date)
@ -841,7 +851,7 @@ class Query < ActiveRecord::Base
if self.class.default_timezone == :utc if self.class.default_timezone == :utc
from = from.utc from = from.utc
end end
s << ("#{table}.#{field} > '%s'" % [self.class.connection.quoted_date(from)]) s << ("#{table}.#{field} > '%s'" % [quoted_time(from, is_custom_filter)])
end end
if to if to
if to.is_a?(Date) if to.is_a?(Date)
@ -850,14 +860,14 @@ class Query < ActiveRecord::Base
if self.class.default_timezone == :utc if self.class.default_timezone == :utc
to = to.utc to = to.utc
end end
s << ("#{table}.#{field} <= '%s'" % [self.class.connection.quoted_date(to)]) s << ("#{table}.#{field} <= '%s'" % [quoted_time(to, is_custom_filter)])
end end
s.join(' AND ') s.join(' AND ')
end end
# Returns a SQL clause for a date or datetime field using relative dates. # Returns a SQL clause for a date or datetime field using relative dates.
def relative_date_clause(table, field, days_from, days_to) def relative_date_clause(table, field, days_from, days_to, is_custom_filter)
date_clause(table, field, (days_from ? Date.today + days_from : nil), (days_to ? Date.today + days_to : nil)) date_clause(table, field, (days_from ? Date.today + days_from : nil), (days_to ? Date.today + days_to : nil), is_custom_filter)
end end
# Returns a Date or Time from the given filter value # Returns a Date or Time from the given filter value