]> source.dussan.org Git - redmine.git/commitdiff
Fixed date filters accuracy with SQLite (#2221).
authorJean-Philippe Lang <jp_lang@yahoo.fr>
Sun, 23 Nov 2008 16:40:35 +0000 (16:40 +0000)
committerJean-Philippe Lang <jp_lang@yahoo.fr>
Sun, 23 Nov 2008 16:40:35 +0000 (16:40 +0000)
git-svn-id: svn+ssh://rubyforge.org/var/svn/redmine/trunk@2054 e93f8b46-1217-0410-a6f0-8f06a7374b81

app/models/query.rb
test/fixtures/issues.yml
test/unit/query_test.rb

index ac8777721b912c855b6485b8b25c9a537435c961..5ad0dd80407f216407a6783de9927f03c09d701c 100644 (file)
@@ -329,19 +329,19 @@ class Query < ActiveRecord::Base
       when "c"
         sql = sql + "#{IssueStatus.table_name}.is_closed=#{connection.quoted_true}" if field == "status_id"
       when ">t-"
-        sql = sql + "#{db_table}.#{db_field} BETWEEN '%s' AND '%s'" % [connection.quoted_date((Date.today - v.first.to_i).to_time), connection.quoted_date((Date.today + 1).to_time)]
+        sql = sql + date_range_clause(db_table, db_field, - v.first.to_i, 0)
       when "<t-"
-        sql = sql + "#{db_table}.#{db_field} <= '%s'" % connection.quoted_date((Date.today - v.first.to_i).to_time)
+        sql = sql + date_range_clause(db_table, db_field, nil, - v.first.to_i)
       when "t-"
-        sql = sql + "#{db_table}.#{db_field} BETWEEN '%s' AND '%s'" % [connection.quoted_date((Date.today - v.first.to_i).to_time), connection.quoted_date((Date.today - v.first.to_i + 1).to_time)]
+        sql = sql + date_range_clause(db_table, db_field, - v.first.to_i, - v.first.to_i)
       when ">t+"
-        sql = sql + "#{db_table}.#{db_field} >= '%s'" % connection.quoted_date((Date.today + v.first.to_i).to_time)
+        sql = sql + date_range_clause(db_table, db_field, v.first.to_i, nil)
       when "<t+"
-        sql = sql + "#{db_table}.#{db_field} BETWEEN '%s' AND '%s'" % [connection.quoted_date(Date.today.to_time), connection.quoted_date((Date.today + v.first.to_i + 1).to_time)]
+        sql = sql + date_range_clause(db_table, db_field, 0, v.first.to_i)
       when "t+"
-        sql = sql + "#{db_table}.#{db_field} BETWEEN '%s' AND '%s'" % [connection.quoted_date((Date.today + v.first.to_i).to_time), connection.quoted_date((Date.today + v.first.to_i + 1).to_time)]
+        sql = sql + date_range_clause(db_table, db_field, v.first.to_i, v.first.to_i)
       when "t"
-        sql = sql + "#{db_table}.#{db_field} BETWEEN '%s' AND '%s'" % [connection.quoted_date(Date.today.to_time), connection.quoted_date((Date.today+1).to_time)]
+        sql = sql + date_range_clause(db_table, db_field, 0, 0)
       when "w"
         from = l(:general_first_day_of_week) == '7' ?
           # week starts on sunday
@@ -382,4 +382,16 @@ class Query < ActiveRecord::Base
       @available_filters["cf_#{field.id}"] = options.merge({ :name => field.name })
     end
   end
+  
+  # Returns a SQL clause for a date or datetime field.
+  def date_range_clause(table, field, from, to)
+    s = []
+    if from
+      s << ("#{table}.#{field} > '%s'" % [connection.quoted_date((Date.yesterday + from).to_time.end_of_day)])
+    end
+    if to
+      s << ("#{table}.#{field} <= '%s'" % [connection.quoted_date((Date.today + to).to_time.end_of_day)])
+    end
+    s.join(' AND ')
+  end
 end
index 9d3287c6ffa7eb9540b4e231b3a3a601e016cde8..4e1416378cb85a447a43995a8e445d91d11149c0 100644 (file)
@@ -91,4 +91,21 @@ issues_006:
   status_id: 1\r
   start_date: <%= Date.today.to_s(:db) %>\r
   due_date: <%= 1.days.from_now.to_date.to_s(:db) %>\r
+issues_007: \r
+  created_on: <%= 10.days.ago.to_date.to_s(:db) %>\r
+  project_id: 1\r
+  updated_on: <%= 10.days.ago.to_date.to_s(:db) %>\r
+  priority_id: 3\r
+  subject: Issue due today\r
+  id: 7\r
+  fixed_version_id: \r
+  category_id: \r
+  description: This is an issue that is due today\r
+  tracker_id: 1\r
+  assigned_to_id: \r
+  author_id: 2\r
+  status_id: 1\r
+  start_date: <%= 10.days.ago.to_s(:db) %>\r
+  due_date: <%= Date.today.to_s(:db) %>\r
+  lock_version: 0\r
   
\ No newline at end of file
index c243dfbad3e5768250bc403490d6453fb6dae702..ac3e3cadc8e8f0577c1d1a628cff7bf6c21d10f3 100644 (file)
@@ -18,7 +18,7 @@
 require File.dirname(__FILE__) + '/../test_helper'
 
 class QueryTest < Test::Unit::TestCase
-  fixtures :projects, :users, :members, :roles, :trackers, :issue_statuses, :issue_categories, :enumerations, :issues, :custom_fields, :custom_values, :queries
+  fixtures :projects, :enabled_modules, :users, :members, :roles, :trackers, :issue_statuses, :issue_categories, :enumerations, :issues, :custom_fields, :custom_values, :versions, :queries
 
   def test_custom_fields_for_all_projects_should_be_available_in_global_queries
     query = Query.new(:project => nil, :name => '_')
@@ -75,37 +75,76 @@ class QueryTest < Test::Unit::TestCase
   end
 
   def test_operator_in_more_than
+    Issue.find(7).update_attribute(:due_date, (Date.today + 15))
     query = Query.new(:project => Project.find(1), :name => '_')
     query.add_filter('due_date', '>t+', ['15'])
-    assert query.statement.include?("#{Issue.table_name}.due_date >=")
-    find_issues_with_query(query)
+    issues = find_issues_with_query(query)
+    assert !issues.empty?
+    issues.each {|issue| assert(issue.due_date >= (Date.today + 15))}
   end
 
   def test_operator_in_less_than
     query = Query.new(:project => Project.find(1), :name => '_')
     query.add_filter('due_date', '<t+', ['15'])
-    assert query.statement.include?("#{Issue.table_name}.due_date BETWEEN")
-    find_issues_with_query(query)
+    issues = find_issues_with_query(query)
+    assert !issues.empty?
+    issues.each {|issue| assert(issue.due_date >= Date.today && issue.due_date <= (Date.today + 15))}
+  end
+  
+  def test_operator_less_than_ago
+    Issue.find(7).update_attribute(:due_date, (Date.today - 3))
+    query = Query.new(:project => Project.find(1), :name => '_')
+    query.add_filter('due_date', '>t-', ['3'])
+    issues = find_issues_with_query(query)
+    assert !issues.empty?
+    issues.each {|issue| assert(issue.due_date >= (Date.today - 3) && issue.due_date <= Date.today)}
+  end
+  
+  def test_operator_more_than_ago
+    Issue.find(7).update_attribute(:due_date, (Date.today - 10))
+    query = Query.new(:project => Project.find(1), :name => '_')
+    query.add_filter('due_date', '<t-', ['10'])
+    assert query.statement.include?("#{Issue.table_name}.due_date <=")
+    issues = find_issues_with_query(query)
+    assert !issues.empty?
+    issues.each {|issue| assert(issue.due_date <= (Date.today - 10))}
+  end
+
+  def test_operator_in
+    Issue.find(7).update_attribute(:due_date, (Date.today + 2))
+    query = Query.new(:project => Project.find(1), :name => '_')
+    query.add_filter('due_date', 't+', ['2'])
+    issues = find_issues_with_query(query)
+    assert !issues.empty?
+    issues.each {|issue| assert_equal((Date.today + 2), issue.due_date)}
+  end
+
+  def test_operator_ago
+    Issue.find(7).update_attribute(:due_date, (Date.today - 3))
+    query = Query.new(:project => Project.find(1), :name => '_')
+    query.add_filter('due_date', 't-', ['3'])
+    issues = find_issues_with_query(query)
+    assert !issues.empty?
+    issues.each {|issue| assert_equal((Date.today - 3), issue.due_date)}
   end
 
   def test_operator_today
     query = Query.new(:project => Project.find(1), :name => '_')
     query.add_filter('due_date', 't', [''])
-    assert query.statement.include?("#{Issue.table_name}.due_date BETWEEN")
-    find_issues_with_query(query)
+    issues = find_issues_with_query(query)
+    assert !issues.empty?
+    issues.each {|issue| assert_equal Date.today, issue.due_date}
   end
 
   def test_operator_this_week_on_date
     query = Query.new(:project => Project.find(1), :name => '_')
     query.add_filter('due_date', 'w', [''])
-    assert query.statement.include?("#{Issue.table_name}.due_date BETWEEN")
     find_issues_with_query(query)
   end
 
   def test_operator_this_week_on_datetime
     query = Query.new(:project => Project.find(1), :name => '_')
     query.add_filter('created_on', 'w', [''])
-    assert query.statement.include?("#{Issue.table_name}.created_on BETWEEN")
     find_issues_with_query(query)
   end