Project

General

Profile

Feature #31879 » 31879_add_filter_operators.patch

Yuichi HARADA, 2019-09-19 04:03

View differences:

app/models/query.rb
287 287
    "!p"  => :label_no_issues_in_project,
288 288
    "*o"  => :label_any_open_issues,
289 289
    "!o"  => :label_no_open_issues,
290
    "^="  => :label_starts_with,
291
    "$="  => :label_ends_with,
290 292
  }
291 293

  
292 294
  class_attribute :operators_by_filter_type
......
297 299
    :list_subprojects => [ "*", "!*", "=", "!" ],
298 300
    :date => [ "=", ">=", "<=", "><", "<t+", ">t+", "><t+", "t+", "nd", "t", "ld", "nw", "w", "lw", "l2w", "nm", "m", "lm", "y", ">t-", "<t-", "><t-", "t-", "!*", "*" ],
299 301
    :date_past => [ "=", ">=", "<=", "><", ">t-", "<t-", "><t-", "t-", "t", "ld", "w", "lw", "l2w", "m", "lm", "y", "!*", "*" ],
300
    :string => [ "~", "=", "!~", "!", "!*", "*" ],
301
    :text => [  "~", "!~", "!*", "*" ],
302
    :string => [ "~", "=", "!~", "!", "^=", "$=", "!*", "*" ],
303
    :text => [  "~", "!~", "^=", "$=", "!*", "*" ],
302 304
    :integer => [ "=", ">=", "<=", "><", "!*", "*" ],
303 305
    :float => [ "=", ">=", "<=", "><", "!*", "*" ],
304 306
    :relation => ["=", "=p", "=!p", "!p", "*o", "!o", "!*", "*"],
......
1260 1262
    when "~"
1261 1263
      sql = sql_contains("#{db_table}.#{db_field}", value.first)
1262 1264
    when "!~"
1263
      sql = sql_contains("#{db_table}.#{db_field}", value.first, false)
1265
      sql = sql_contains("#{db_table}.#{db_field}", value.first, :match => false)
1266
    when "^="
1267
      sql = sql_contains("#{db_table}.#{db_field}", value.first, :starts_with => true)
1268
    when "$="
1269
      sql = sql_contains("#{db_table}.#{db_field}", value.first, :ends_with => true)
1264 1270
    else
1265 1271
      raise "Unknown query operator #{operator}"
1266 1272
    end
......
1269 1275
  end
1270 1276

  
1271 1277
  # Returns a SQL LIKE statement with wildcards
1272
  def sql_contains(db_field, value, match=true)
1278
  def sql_contains(db_field, value, options={})
1279
    options = {} unless options.is_a?(Hash)
1280
    options.symbolize_keys!
1281
    prefix = suffix = nil
1282
    prefix = '%' if options[:ends_with]
1283
    suffix = '%' if options[:starts_with]
1284
    prefix = suffix = '%' if prefix.nil? && suffix.nil?
1273 1285
    queried_class.send :sanitize_sql_for_conditions,
1274
      [Redmine::Database.like(db_field, '?', :match => match), "%#{value}%"]
1286
      [Redmine::Database.like(db_field, '?', :match => options[:match]), "#{prefix}#{value}#{suffix}"]
1275 1287
  end
1276 1288

  
1277 1289
  # Adds a filter for the given custom field
config/locales/en.yml
771 771
  label_ago: days ago
772 772
  label_contains: contains
773 773
  label_not_contains: doesn't contain
774
  label_starts_with: starts with
775
  label_ends_with: ends with
774 776
  label_any_issues_in_project: any issues in project
775 777
  label_any_issues_not_in_project: any issues not in project
776 778
  label_no_issues_in_project: no issues in project
test/unit/query_test.rb
1353 1353
    assert_nil issues.detect {|issue| issue.attachments.any? {|attachment| attachment.filename.include?('error281')}}
1354 1354
  end
1355 1355

  
1356
  def test_filter_on_subject_when_starts_with
1357
    query = IssueQuery.new(:name => '_')
1358
    query.filters = {'subject' => {:operator => '^=', :values => ['issue']}}
1359
    issues = find_issues_with_query(query)
1360
    assert_equal [4, 6, 7, 10], issues.collect(&:id).sort
1361
  end
1362

  
1363
  def test_filter_on_subject_when_ends_with
1364
    query = IssueQuery.new(:name => '_')
1365
    query.filters = {'subject' => {:operator => '$=', :values => ['issue']}}
1366
    issues = find_issues_with_query(query)
1367
    assert_equal [5, 8, 9], issues.collect(&:id).sort
1368
  end
1369

  
1356 1370
  def test_statement_should_be_nil_with_no_filters
1357 1371
    q = IssueQuery.new(:name => '_')
1358 1372
    q.filters = {}
(1-1/3)