##// END OF EJS Templates
Fixed: warning: class variable access from toplevel on Ruby 2.0 (#14511)....
Fixed: warning: class variable access from toplevel on Ruby 2.0 (#14511). git-svn-id: svn+ssh://rubyforge.org/var/svn/redmine/trunk@12052 e93f8b46-1217-0410-a6f0-8f06a7374b81

File last commit:

r11790:010bfc56e15f
r11822:9a0db9cb888c
Show More
query.rb
866 lines | 28.6 KiB | text/x-ruby | RubyLexer
Jean-Philippe Lang
Adds support for free ticket filtering and custom queries on Calendar....
r1796 # Redmine - project management software
Jean-Philippe Lang
Copyright for 2013 (#12788)....
r10939 # Copyright (C) 2006-2013 Jean-Philippe Lang
Jean-Philippe Lang
"queries" branch merged...
r92 #
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
# as published by the Free Software Foundation; either version 2
# of the License, or (at your option) any later version.
Toshi MARUYAMA
remove trailing white-spaces from query model source....
r5702 #
Jean-Philippe Lang
"queries" branch merged...
r92 # This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
Toshi MARUYAMA
remove trailing white-spaces from query model source....
r5702 #
Jean-Philippe Lang
"queries" branch merged...
r92 # You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
Toshi MARUYAMA
remove trailing white-spaces from query model source....
r5702 class QueryColumn
Jean-Philippe Lang
Reverts r3072 (#4302: error raised when sorting on an association not included as column)....
r2983 attr_accessor :name, :sortable, :groupable, :default_order
Jean-Philippe Lang
Merged Rails 2.2 branch. Redmine now requires Rails 2.2.2....
r2430 include Redmine::I18n
Toshi MARUYAMA
remove trailing white-spaces from query model source....
r5702
Jean-Philippe Lang
Added the ability to customize columns of a saved query....
r771 def initialize(name, options={})
self.name = name
self.sortable = options[:sortable]
Jean-Philippe Lang
Ticket grouping (#2679)....
r2604 self.groupable = options[:groupable] || false
Jean-Philippe Lang
Allow issue grouping by custom field (#2679)....
r2957 if groupable == true
self.groupable = name.to_s
end
Jean-Philippe Lang
More appropriate default sort order on sortable columns....
r1107 self.default_order = options[:default_order]
Jean-Philippe Lang
Adds an option for displaying the issue description on the issue list (#3447)....
r10721 @inline = options.key?(:inline) ? options[:inline] : true
Jean-Philippe Lang
Refactor: makes issue id a regular QueryColumn....
r11217 @caption_key = options[:caption] || "field_#{name}".to_sym
@frozen = options[:frozen]
Jean-Philippe Lang
Added the ability to customize columns of a saved query....
r771 end
Toshi MARUYAMA
remove trailing white-spaces from query model source....
r5702
Jean-Philippe Lang
Custom fields can now be displayed as columns on the issue list....
r876 def caption
Jean-Philippe Lang
Refactor: makes issue id a regular QueryColumn....
r11217 @caption_key.is_a?(Symbol) ? l(@caption_key) : @caption_key
Jean-Philippe Lang
Custom fields can now be displayed as columns on the issue list....
r876 end
Toshi MARUYAMA
remove trailing white-spaces from query model source....
r5702
Jean-Philippe Lang
Ability to save "sort order" in custom queries (#2899)....
r2504 # Returns true if the column is sortable, otherwise false
def sortable?
Jean-Philippe Lang
Sort the issue list by author/assignee according to user display format (#9669)....
r7818 !@sortable.nil?
end
Toshi MARUYAMA
remove trailing white-spaces from app/models/query.rb...
r10262
Jean-Philippe Lang
Sort the issue list by author/assignee according to user display format (#9669)....
r7818 def sortable
@sortable.is_a?(Proc) ? @sortable.call : @sortable
Jean-Philippe Lang
Ability to save "sort order" in custom queries (#2899)....
r2504 end
Toshi MARUYAMA
remove trailing white-spaces from query model source....
r5702
Jean-Philippe Lang
Adds an option for displaying the issue description on the issue list (#3447)....
r10721 def inline?
@inline
end
Jean-Philippe Lang
Refactor: makes issue id a regular QueryColumn....
r11217 def frozen?
@frozen
end
Jean-Philippe Lang
Moves issue specific code to IssueQuery....
r10738 def value(object)
object.send name
Jean-Philippe Lang
Fixed: "None" category issue count is empty while grouping by category (#4308)....
r2998 end
Toshi MARUYAMA
remove trailing white-spaces from query model source....
r5702
Jean-Philippe Lang
Wrap text custom fields in the issue list (#8064)....
r5212 def css_classes
name
end
Jean-Philippe Lang
Custom fields can now be displayed as columns on the issue list....
r876 end
class QueryCustomFieldColumn < QueryColumn
def initialize(custom_field)
self.name = "cf_#{custom_field.id}".to_sym
Jean-Philippe Lang
Ability to sort the issue list by text, list, date and boolean custom fields (#1139)....
r2255 self.sortable = custom_field.order_statement || false
Jean-Philippe Lang
Adds CustomField#group_statement....
r9888 self.groupable = custom_field.group_statement || false
Jean-Philippe Lang
Adds an option for displaying the issue description on the issue list (#3447)....
r10721 @inline = true
Jean-Philippe Lang
Custom fields can now be displayed as columns on the issue list....
r876 @cf = custom_field
end
Toshi MARUYAMA
remove trailing white-spaces from query model source....
r5702
Jean-Philippe Lang
Custom fields can now be displayed as columns on the issue list....
r876 def caption
@cf.name
end
Toshi MARUYAMA
remove trailing white-spaces from query model source....
r5702
Jean-Philippe Lang
Custom fields can now be displayed as columns on the issue list....
r876 def custom_field
@cf
end
Toshi MARUYAMA
remove trailing white-spaces from query model source....
r5702
Jean-Philippe Lang
Moves issue specific code to IssueQuery....
r10738 def value(object)
Jean-Philippe Lang
Role-based issue custom field visibility (#5037)....
r11782 if custom_field.visible_by?(object.project, User.current)
cv = object.custom_values.select {|v| v.custom_field_id == @cf.id}.collect {|v| @cf.cast_value(v.value)}
cv.size > 1 ? cv.sort {|a,b| a.to_s <=> b.to_s} : cv.first
else
nil
end
Jean-Philippe Lang
Fixed: "None" category issue count is empty while grouping by category (#4308)....
r2998 end
Toshi MARUYAMA
remove trailing white-spaces from query model source....
r5702
Jean-Philippe Lang
Wrap text custom fields in the issue list (#8064)....
r5212 def css_classes
@css_classes ||= "#{name} #{@cf.field_format}"
end
Jean-Philippe Lang
Added the ability to customize columns of a saved query....
r771 end
Jean-Philippe Lang
Makes issue custom fields available as timelog columns (#1766)....
r10944 class QueryAssociationCustomFieldColumn < QueryCustomFieldColumn
def initialize(association, custom_field)
super(custom_field)
self.name = "#{association}.cf_#{custom_field.id}".to_sym
# TODO: support sorting/grouping by association custom field
self.sortable = false
self.groupable = false
@association = association
end
def value(object)
if assoc = object.send(@association)
super(assoc)
end
end
def css_classes
@css_classes ||= "#{@association}_cf_#{@cf.id} #{@cf.field_format}"
end
end
Jean-Philippe Lang
"queries" branch merged...
r92 class Query < ActiveRecord::Base
Jean-Philippe Lang
Rescue invalid query statement error with an error message....
r2990 class StatementInvalid < ::ActiveRecord::StatementInvalid
end
Toshi MARUYAMA
remove trailing white-spaces from query model source....
r5702
Jean-Philippe Lang
Role based custom queries (#1019)....
r11764 VISIBILITY_PRIVATE = 0
VISIBILITY_ROLES = 1
VISIBILITY_PUBLIC = 2
Jean-Philippe Lang
"queries" branch merged...
r92 belongs_to :project
belongs_to :user
Jean-Philippe Lang
Role based custom queries (#1019)....
r11764 has_and_belongs_to_many :roles, :join_table => "#{table_name_prefix}queries_roles#{table_name_suffix}", :foreign_key => "query_id"
Jean-Philippe Lang
"queries" branch merged...
r92 serialize :filters
Jean-Philippe Lang
Added the ability to customize columns of a saved query....
r771 serialize :column_names
Jean-Philippe Lang
Ability to save "sort order" in custom queries (#2899)....
r2504 serialize :sort_criteria, Array
Jean-Philippe Lang
Ability to save Gantt query filters (#7836)....
r11790 serialize :options, Hash
Toshi MARUYAMA
remove trailing white-spaces from query model source....
r5702
Jean-Philippe Lang
Fix query management broken by r1027....
r1018 attr_protected :project_id, :user_id
Toshi MARUYAMA
remove trailing white-spaces from query model source....
r5702
Jean-Philippe Lang
Removed useless option....
r8858 validates_presence_of :name
Jean-Philippe Lang
Added several validates_length_of...
r590 validates_length_of :name, :maximum => 255
Jean-Philippe Lang
Role based custom queries (#1019)....
r11764 validates :visibility, :inclusion => { :in => [VISIBILITY_PUBLIC, VISIBILITY_ROLES, VISIBILITY_PRIVATE] }
Toshi MARUYAMA
Rails3: replace deprecated 'validate' method at Query model...
r7305 validate :validate_query_filters
Jean-Philippe Lang
Role based custom queries (#1019)....
r11764 validate do |query|
errors.add(:base, l(:label_role_plural) + ' ' + l('activerecord.errors.messages.blank')) if query.visibility == VISIBILITY_ROLES && roles.blank?
end
after_save do |query|
if query.visibility_changed? && query.visibility != VISIBILITY_ROLES
query.roles.clear
end
end
Toshi MARUYAMA
remove trailing white-spaces from query model source....
r5702
Jean-Philippe Lang
Use inheritable class attributes in Query model....
r10736 class_attribute :operators
self.operators = {
"=" => :label_equals,
"!" => :label_not_equals,
"o" => :label_open_issues,
"c" => :label_closed_issues,
"!*" => :label_none,
"*" => :label_any,
">=" => :label_greater_or_equal,
"<=" => :label_less_or_equal,
"><" => :label_between,
"<t+" => :label_in_less_than,
">t+" => :label_in_more_than,
"><t+"=> :label_in_the_next_days,
"t+" => :label_in,
"t" => :label_today,
Jean-Philippe Lang
Adds TimeEntryQuery for listing time entries....
r10740 "ld" => :label_yesterday,
Jean-Philippe Lang
Use inheritable class attributes in Query model....
r10736 "w" => :label_this_week,
Jean-Philippe Lang
Adds TimeEntryQuery for listing time entries....
r10740 "lw" => :label_last_week,
Jean-Philippe Lang
Fixed syntax for ruby1.8....
r10742 "l2w" => [:label_last_n_weeks, {:count => 2}],
Jean-Philippe Lang
Adds TimeEntryQuery for listing time entries....
r10740 "m" => :label_this_month,
"lm" => :label_last_month,
"y" => :label_this_year,
Jean-Philippe Lang
Use inheritable class attributes in Query model....
r10736 ">t-" => :label_less_than_ago,
"<t-" => :label_more_than_ago,
"><t-"=> :label_in_the_past_days,
"t-" => :label_ago,
"~" => :label_contains,
"!~" => :label_not_contains,
"=p" => :label_any_issues_in_project,
"=!p" => :label_any_issues_not_in_project,
"!p" => :label_no_issues_in_project
}
class_attribute :operators_by_filter_type
self.operators_by_filter_type = {
:list => [ "=", "!" ],
:list_status => [ "o", "=", "!", "c", "*" ],
:list_optional => [ "=", "!", "!*", "*" ],
:list_subprojects => [ "*", "!*", "=" ],
Jean-Philippe Lang
Adds TimeEntryQuery for listing time entries....
r10740 :date => [ "=", ">=", "<=", "><", "<t+", ">t+", "><t+", "t+", "t", "ld", "w", "lw", "l2w", "m", "lm", "y", ">t-", "<t-", "><t-", "t-", "!*", "*" ],
:date_past => [ "=", ">=", "<=", "><", ">t-", "<t-", "><t-", "t-", "t", "ld", "w", "lw", "l2w", "m", "lm", "y", "!*", "*" ],
Jean-Philippe Lang
Use inheritable class attributes in Query model....
r10736 :string => [ "=", "~", "!", "!~", "!*", "*" ],
:text => [ "~", "!~", "!*", "*" ],
:integer => [ "=", ">=", "<=", "><", "!*", "*" ],
:float => [ "=", ">=", "<=", "><", "!*", "*" ],
:relation => ["=", "=p", "=!p", "!p", "!*", "*"]
}
class_attribute :available_columns
Jean-Philippe Lang
Adds STI to Query model. Issue queries are now IssueQuery instances....
r10737 self.available_columns = []
Toshi MARUYAMA
remove trailing white-spaces from app/models/query.rb....
r6345
Jean-Philippe Lang
Moves issue specific code to IssueQuery....
r10738 class_attribute :queried_class
def queried_table_name
@queried_table_name ||= self.class.queried_class.table_name
end
Jean-Philippe Lang
Makes models #initialize accept additional arguments....
r8167 def initialize(attributes=nil, *args)
Jean-Philippe Lang
"queries" branch merged...
r92 super attributes
Jean-Philippe Lang
Queries can be marked as 'For all projects'. Such queries will be available on all projects and on the global issue list (#897, closes #671)....
r1296 @is_for_all = project.nil?
end
Toshi MARUYAMA
remove trailing white-spaces from query model source....
r5702
Jean-Philippe Lang
Moved build_query_from_params helper to Query#build_from_params....
r10739 # Builds the query from the given params
def build_from_params(params)
if params[:fields] || params[:f]
self.filters = {}
add_filters(params[:fields] || params[:f], params[:operators] || params[:op], params[:values] || params[:v])
else
available_filters.keys.each do |field|
add_short_filter(field, params[field]) if params[field]
end
end
self.group_by = params[:group_by] || (params[:query] && params[:query][:group_by])
self.column_names = params[:c] || (params[:query] && params[:query][:column_names])
self
end
Jean-Philippe Lang
Adds TimeEntryQuery for listing time entries....
r10740 # Builds a new query from the given params and attributes
def self.build_from_params(params, attributes={})
new(attributes).build_from_params(params)
end
Toshi MARUYAMA
Rails3: replace deprecated 'validate' method at Query model...
r7305 def validate_query_filters
Jean-Philippe Lang
"queries" branch merged...
r92 filters.each_key do |field|
Jean-Philippe Lang
Fixes "=" filter on float values....
r6136 if values_for(field)
case type_for(field)
Toshi MARUYAMA
remove trailing white-spaces from app/models/query.rb....
r6345 when :integer
Jean-Philippe Lang
Fixed: Can't filter for negative numeric custom field (#11307)....
r9725 add_filter_error(field, :invalid) if values_for(field).detect {|v| v.present? && !v.match(/^[+-]?\d+$/) }
Toshi MARUYAMA
remove trailing white-spaces from app/models/query.rb....
r6345 when :float
Jean-Philippe Lang
Fixed: Can't filter for negative numeric custom field (#11307)....
r9725 add_filter_error(field, :invalid) if values_for(field).detect {|v| v.present? && !v.match(/^[+-]?\d+(\.\d*)?$/) }
Jean-Philippe Lang
Validate date filters values....
r6144 when :date, :date_past
case operator_for(field)
when "=", ">=", "<=", "><"
Jean-Philippe Lang
Do not add errors on attributes on fake attributes....
r8268 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?) }
Jean-Philippe Lang
Changes how relative date filters work and adds specific filters for filtering dates in past/next n days (#11426)....
r10546 when ">t-", "<t-", "t-", ">t+", "<t+", "t+", "><t+", "><t-"
Jean-Philippe Lang
Do not add errors on attributes on fake attributes....
r8268 add_filter_error(field, :invalid) if values_for(field).detect {|v| v.present? && !v.match(/^\d+$/) }
Jean-Philippe Lang
Validate date filters values....
r6144 end
Jean-Philippe Lang
Fixes "=" filter on float values....
r6136 end
Jean-Philippe Lang
Keep invalid values and add validation error message....
r6109 end
Toshi MARUYAMA
remove trailing white-spaces from app/models/query.rb....
r6345
Jean-Philippe Lang
Do not add errors on attributes on fake attributes....
r8268 add_filter_error(field, :blank) unless
Jean-Philippe Lang
"queries" branch merged...
r92 # filter requires one or more values
Toshi MARUYAMA
remove trailing white-spaces from query model source....
r5702 (values_for(field) and !values_for(field).first.blank?) or
Jean-Philippe Lang
"queries" branch merged...
r92 # filter doesn't require any value
Jean-Philippe Lang
Adds TimeEntryQuery for listing time entries....
r10740 ["o", "c", "!*", "*", "t", "ld", "w", "lw", "l2w", "m", "lm", "y"].include? operator_for(field)
Jean-Philippe Lang
"queries" branch merged...
r92 end if filters
end
Toshi MARUYAMA
remove trailing white-spaces from app/models/query.rb....
r6345
Jean-Philippe Lang
Do not add errors on attributes on fake attributes....
r8268 def add_filter_error(field, message)
m = label_for(field) + " " + l(message, :scope => 'activerecord.errors.messages')
errors.add(:base, m)
end
Jean-Philippe Lang
Added per user custom queries....
r563 def editable_by?(user)
return false unless user
Jean-Philippe Lang
Queries can be marked as 'For all projects'. Such queries will be available on all projects and on the global issue list (#897, closes #671)....
r1296 # Admin can edit them all and regular users can edit their private queries
Jean-Philippe Lang
Role based custom queries (#1019)....
r11764 return true if user.admin? || (is_private? && self.user_id == user.id)
Jean-Philippe Lang
Queries can be marked as 'For all projects'. Such queries will be available on all projects and on the global issue list (#897, closes #671)....
r1296 # Members can not edit public queries that are for all project (only admin is allowed to)
Jean-Philippe Lang
Role based custom queries (#1019)....
r11764 is_public? && !@is_for_all && user.allowed_to?(:manage_public_queries, project)
Jean-Philippe Lang
Added per user custom queries....
r563 end
Toshi MARUYAMA
remove trailing white-spaces from query model source....
r5702
Jean-Philippe Lang
Ability to disable standard fields on a per tracker basis (#1091)....
r9729 def trackers
Jean-Philippe Lang
Replaces find(:all) calls....
r10690 @trackers ||= project.nil? ? Tracker.sorted.all : project.rolled_up_trackers
Jean-Philippe Lang
Ability to disable standard fields on a per tracker basis (#1091)....
r9729 end
Jean-Philippe Lang
Build issue filters using javascript....
r9979 # Returns a hash of localized labels for all filter operators
def self.operators_labels
Jean-Philippe Lang
Adds TimeEntryQuery for listing time entries....
r10740 operators.inject({}) {|h, operator| h[operator.first] = l(*operator.last); h}
Jean-Philippe Lang
Build issue filters using javascript....
r9979 end
Toshi MARUYAMA
replace tab to space at app/models/query.rb...
r10261 # Returns a representation of the available filters for JSON serialization
Jean-Philippe Lang
Build issue filters using javascript....
r9979 def available_filters_as_json
json = {}
available_filters.each do |field, options|
json[field] = options.slice(:type, :name, :values).stringify_keys
end
json
end
Jean-Philippe Lang
Makes related issues available for display and filtering on the issue list (#3239, #3265)....
r10303 def all_projects
@all_projects ||= Project.visible.all
end
def all_projects_values
return @all_projects_values if @all_projects_values
values = []
Project.project_tree(all_projects) do |p, level|
prefix = (level > 0 ? ('--' * level + ' ') : '')
values << ["#{prefix}#{p.name}", p.id.to_s]
end
@all_projects_values = values
end
Jean-Philippe Lang
Refactor: use an ordered hash to store available filters and remove :order option (#13154)....
r11142 # Adds available filters
def initialize_available_filters
# implemented by sub-classes
end
protected :initialize_available_filters
# Adds an available filter
def add_available_filter(field, options)
@available_filters ||= ActiveSupport::OrderedHash.new
@available_filters[field] = options
@available_filters
end
# Removes an available filter
def delete_available_filter(field)
if @available_filters
@available_filters.delete(field)
end
end
# Return a hash of available filters
def available_filters
unless @available_filters
initialize_available_filters
@available_filters.each do |field, options|
options[:name] ||= l(options[:label] || "field_#{field}".gsub(/_id$/, ''))
end
end
@available_filters
end
Jean-Philippe Lang
Adds TimeEntryQuery for listing time entries....
r10740 def add_filter(field, operator, values=nil)
Jean-Philippe Lang
"queries" branch merged...
r92 # values must be an array
Jean-Philippe Lang
Adds date based filters (#4729) and date range filter (#6954)....
r6106 return unless values.nil? || values.is_a?(Array)
Jean-Philippe Lang
"queries" branch merged...
r92 # check if field is defined as an available filter
if available_filters.has_key? field
filter_options = available_filters[field]
Jean-Philippe Lang
Keep invalid values and add validation error message....
r6109 filters[field] = {:operator => operator, :values => (values || [''])}
Jean-Philippe Lang
"queries" branch merged...
r92 end
end
Toshi MARUYAMA
remove trailing white-spaces from query model source....
r5702
Jean-Philippe Lang
"queries" branch merged...
r92 def add_short_filter(field, expression)
Etienne Massip
Fixed shot filter expression parsing depending upon field operators (#8371)....
r7504 return unless expression && available_filters.has_key?(field)
field_type = available_filters[field][:type]
Jean-Philippe Lang
Use inheritable class attributes in Query model....
r10736 operators_by_filter_type[field_type].sort.reverse.detect do |operator|
Etienne Massip
Fixed shot filter expression parsing depending upon field operators (#8371)....
r7504 next unless expression =~ /^#{Regexp.escape(operator)}(.*)$/
Jean-Philippe Lang
Test failure with JRuby 1.7.2 (#12228)....
r11050 values = $1
add_filter field, operator, values.present? ? values.split('|') : ['']
Etienne Massip
Fixed shot filter expression parsing depending upon field operators (#8371)....
r7504 end || add_filter(field, '=', expression.split('|'))
Jean-Philippe Lang
"queries" branch merged...
r92 end
Eric Davis
Refactor: Move method to Query model...
r3570
# Add multiple filters using +add_filter+
def add_filters(fields, operators, values)
Jean-Philippe Lang
Adds date based filters (#4729) and date range filter (#6954)....
r6106 if fields.is_a?(Array) && operators.is_a?(Hash) && (values.nil? || values.is_a?(Hash))
Jean-Philippe Lang
Fixed: unchecking status filter on the issue list has no effect (#6844)....
r4273 fields.each do |field|
Jean-Philippe Lang
Adds date based filters (#4729) and date range filter (#6954)....
r6106 add_filter(field, operators[field], values && values[field])
Jean-Philippe Lang
Fixed: unchecking status filter on the issue list has no effect (#6844)....
r4273 end
Eric Davis
Refactor: Move method to Query model...
r3570 end
end
Toshi MARUYAMA
remove trailing white-spaces from query model source....
r5702
Jean-Philippe Lang
"queries" branch merged...
r92 def has_filter?(field)
filters and filters[field]
end
Toshi MARUYAMA
remove trailing white-spaces from app/models/query.rb....
r6345
Jean-Philippe Lang
Adds date based filters (#4729) and date range filter (#6954)....
r6106 def type_for(field)
available_filters[field][:type] if available_filters.has_key?(field)
end
Toshi MARUYAMA
remove trailing white-spaces from query model source....
r5702
Jean-Philippe Lang
"queries" branch merged...
r92 def operator_for(field)
has_filter?(field) ? filters[field][:operator] : nil
end
Toshi MARUYAMA
remove trailing white-spaces from query model source....
r5702
Jean-Philippe Lang
"queries" branch merged...
r92 def values_for(field)
has_filter?(field) ? filters[field][:values] : nil
end
Toshi MARUYAMA
remove trailing white-spaces from app/models/query.rb....
r6345
Jean-Philippe Lang
Adds "between" operator for numeric filters (#6180)....
r6097 def value_for(field, index=0)
(values_for(field) || [])[index]
end
Toshi MARUYAMA
remove trailing white-spaces from query model source....
r5702
Jean-Philippe Lang
Custom fields for issues can now be used as filters on issue list....
r444 def label_for(field)
Jean-Philippe Lang
Prevents NoMethodError on @available_filters.has_key? in query.rb (#1178)....
r1440 label = available_filters[field][:name] if available_filters.has_key?(field)
Jean-Philippe Lang
Do not add errors on attributes on fake attributes....
r8268 label ||= l("field_#{field.to_s.gsub(/_id$/, '')}", :default => field)
Jean-Philippe Lang
Custom fields for issues can now be used as filters on issue list....
r444 end
Jean-Philippe Lang
Added the ability to customize columns of a saved query....
r771
Eric Davis
Adding missing setter for Query#available_columns...
r3571 def self.add_available_column(column)
self.available_columns << (column) if column.is_a?(QueryColumn)
end
Toshi MARUYAMA
remove trailing white-spaces from query model source....
r5702
Jean-Philippe Lang
Ticket grouping (#2679)....
r2604 # Returns an array of columns that can be used to group the results
def groupable_columns
available_columns.select {|c| c.groupable}
end
Eric Davis
Refactor: Extract Query#sortable_columns from the controller....
r3490
# Returns a Hash of columns and the key for sorting
def sortable_columns
Jean-Philippe Lang
Moves issue specific code to IssueQuery....
r10738 available_columns.inject({}) {|h, column|
h[column.name.to_s] = column.sortable
h
}
Eric Davis
Refactor: Extract Query#sortable_columns from the controller....
r3490 end
Toshi MARUYAMA
remove trailing white-spaces from query model source....
r5702
Jean-Philippe Lang
Added the ability to customize columns of a saved query....
r771 def columns
Etienne Massip
Allow project column to be removed from the global issue list columns (#8411)....
r7418 # preserve the column_names order
Jean-Philippe Lang
Refactor: makes issue id a regular QueryColumn....
r11217 cols = (has_default_columns? ? default_columns_names : column_names).collect do |name|
Etienne Massip
Allow project column to be removed from the global issue list columns (#8411)....
r7418 available_columns.find { |col| col.name == name }
end.compact
Jean-Philippe Lang
Refactor: makes issue id a regular QueryColumn....
r11217 available_columns.select(&:frozen?) | cols
Etienne Massip
Allow project column to be removed from the global issue list columns (#8411)....
r7418 end
Jean-Philippe Lang
Adds an option for displaying the issue description on the issue list (#3447)....
r10721 def inline_columns
columns.select(&:inline?)
end
def block_columns
columns.reject(&:inline?)
end
def available_inline_columns
available_columns.select(&:inline?)
end
def available_block_columns
available_columns.reject(&:inline?)
end
Etienne Massip
Allow project column to be removed from the global issue list columns (#8411)....
r7418 def default_columns_names
Jean-Philippe Lang
Moves issue specific code to IssueQuery....
r10738 []
Jean-Philippe Lang
Added the ability to customize columns of a saved query....
r771 end
Toshi MARUYAMA
remove trailing white-spaces from query model source....
r5702
Jean-Philippe Lang
Added the ability to customize columns of a saved query....
r771 def column_names=(names)
Jean-Philippe Lang
Adds dynamic columns selection on the issue list (#4272)....
r2991 if names
names = names.select {|n| n.is_a?(Symbol) || !n.blank? }
names = names.collect {|n| n.is_a?(Symbol) ? n : n.to_sym }
# Set column_names to nil if default columns
Etienne Massip
Allow project column to be removed from the global issue list columns (#8411)....
r7418 if names == default_columns_names
Jean-Philippe Lang
Adds dynamic columns selection on the issue list (#4272)....
r2991 names = nil
end
end
Jean-Philippe Lang
Added the ability to customize columns of a saved query....
r771 write_attribute(:column_names, names)
end
Toshi MARUYAMA
remove trailing white-spaces from query model source....
r5702
Jean-Philippe Lang
Added the ability to customize columns of a saved query....
r771 def has_column?(column)
Jean-Philippe Lang
Makes spent time column available on the issue list (#971)....
r7953 column_names && column_names.include?(column.is_a?(QueryColumn) ? column.name : column)
Jean-Philippe Lang
Added the ability to customize columns of a saved query....
r771 end
Toshi MARUYAMA
remove trailing white-spaces from query model source....
r5702
Jean-Philippe Lang
Added a checkbox on custom query form to explicitly say if the query uses default columns or not....
r772 def has_default_columns?
column_names.nil? || column_names.empty?
end
Toshi MARUYAMA
remove trailing white-spaces from query model source....
r5702
Jean-Philippe Lang
Ability to save "sort order" in custom queries (#2899)....
r2504 def sort_criteria=(arg)
c = []
if arg.is_a?(Hash)
arg = arg.keys.sort.collect {|k| arg[k]}
end
Jean-Philippe Lang
Ability to sort issues by grouped column (#3511)....
r10543 c = arg.select {|k,o| !k.to_s.blank?}.slice(0,3).collect {|k,o| [k.to_s, (o == 'desc' || o == false) ? 'desc' : 'asc']}
Jean-Philippe Lang
Ability to save "sort order" in custom queries (#2899)....
r2504 write_attribute(:sort_criteria, c)
end
Toshi MARUYAMA
remove trailing white-spaces from query model source....
r5702
Jean-Philippe Lang
Ability to save "sort order" in custom queries (#2899)....
r2504 def sort_criteria
read_attribute(:sort_criteria) || []
end
Toshi MARUYAMA
remove trailing white-spaces from query model source....
r5702
Jean-Philippe Lang
Ability to save "sort order" in custom queries (#2899)....
r2504 def sort_criteria_key(arg)
sort_criteria && sort_criteria[arg] && sort_criteria[arg].first
end
Toshi MARUYAMA
remove trailing white-spaces from query model source....
r5702
Jean-Philippe Lang
Ability to save "sort order" in custom queries (#2899)....
r2504 def sort_criteria_order(arg)
sort_criteria && sort_criteria[arg] && sort_criteria[arg].last
end
Toshi MARUYAMA
remove trailing white-spaces from query model source....
r5702
Jean-Philippe Lang
Ability to sort issues by grouped column (#3511)....
r10543 def sort_criteria_order_for(key)
sort_criteria.detect {|k, order| key.to_s == k}.try(:last)
end
Jean-Philippe Lang
Ticket grouping (#2679)....
r2604 # Returns the SQL sort order that should be prepended for grouping
def group_by_sort_order
if grouped? && (column = group_by_column)
Jean-Philippe Lang
Ability to sort issues by grouped column (#3511)....
r10543 order = sort_criteria_order_for(column.name) || column.default_order
Jean-Philippe Lang
Ticket grouping (#2679)....
r2604 column.sortable.is_a?(Array) ?
Jean-Philippe Lang
Ability to sort issues by grouped column (#3511)....
r10543 column.sortable.collect {|s| "#{s} #{order}"}.join(',') :
"#{column.sortable} #{order}"
Jean-Philippe Lang
Ticket grouping (#2679)....
r2604 end
end
Toshi MARUYAMA
remove trailing white-spaces from query model source....
r5702
Jean-Philippe Lang
Ticket grouping (#2679)....
r2604 # Returns true if the query is a grouped query
def grouped?
Jean-Philippe Lang
Fixed: 500 error on issue query grouped by a custom field that was deleted (#7144)....
r4439 !group_by_column.nil?
Jean-Philippe Lang
Ticket grouping (#2679)....
r2604 end
Toshi MARUYAMA
remove trailing white-spaces from query model source....
r5702
Jean-Philippe Lang
Ticket grouping (#2679)....
r2604 def group_by_column
Jean-Philippe Lang
Fixed: 500 error on issue query grouped by a custom field that was deleted (#7144)....
r4439 groupable_columns.detect {|c| c.groupable && c.name.to_s == group_by}
Jean-Philippe Lang
Ticket grouping (#2679)....
r2604 end
Toshi MARUYAMA
remove trailing white-spaces from query model source....
r5702
Jean-Philippe Lang
Allow issue grouping by custom field (#2679)....
r2957 def group_by_statement
Jean-Philippe Lang
Fixed: 500 error on issue query grouped by a custom field that was deleted (#7144)....
r4439 group_by_column.try(:groupable)
Jean-Philippe Lang
Allow issue grouping by custom field (#2679)....
r2957 end
Toshi MARUYAMA
remove trailing white-spaces from query model source....
r5702
Jean-Philippe Lang
Adds support for free ticket filtering and custom queries on Calendar....
r1796 def project_statement
Jean-Philippe Lang
Fixed: private subprojects are listed on the issues view (#1217)....
r1417 project_clauses = []
Jean-Philippe Lang
Do not use instance variable....
r7777 if project && !project.descendants.active.empty?
Jean-Philippe Lang
Include subprojects on the issue list, calendar and gantt by default....
r1164 ids = [project.id]
Jean-Philippe Lang
Adds an application setting to choose whether or not subprojects issues should be displayed by default on the issue list, calendar and gantt (r1178). Default is true....
r1184 if has_filter?("subproject_id")
case operator_for("subproject_id")
when '='
# include the selected subprojects
ids += values_for("subproject_id").each(&:to_i)
when '!*'
# main project only
else
# all subprojects
Jean-Philippe Lang
Merged nested projects branch. Removes limit on subproject nesting (#594)....
r2302 ids += project.descendants.collect(&:id)
Jean-Philippe Lang
Adds an application setting to choose whether or not subprojects issues should be displayed by default on the issue list, calendar and gantt (r1178). Default is true....
r1184 end
elsif Setting.display_subprojects_issues?
Jean-Philippe Lang
Merged nested projects branch. Removes limit on subproject nesting (#594)....
r2302 ids += project.descendants.collect(&:id)
Jean-Philippe Lang
added back "subproject" filter on issue list...
r347 end
Jean-Philippe Lang
Adds support for free ticket filtering and custom queries on Calendar....
r1796 project_clauses << "#{Project.table_name}.id IN (%s)" % ids.join(',')
Jean-Philippe Lang
Added a cross-project issue list. It displays the issues of all the projects visible by the user....
r673 elsif project
Jean-Philippe Lang
Adds support for free ticket filtering and custom queries on Calendar....
r1796 project_clauses << "#{Project.table_name}.id = %d" % project.id
Jean-Philippe Lang
added back "subproject" filter on issue list...
r347 end
Jean-Philippe Lang
Extract visibility condition from project statement and use visible scopes instead....
r5322 project_clauses.any? ? project_clauses.join(' AND ') : nil
Jean-Philippe Lang
Adds support for free ticket filtering and custom queries on Calendar....
r1796 end
def statement
Jean-Philippe Lang
Fixed: queries with multiple custom fields return no result....
r662 # filters clauses
filters_clauses = []
Jean-Philippe Lang
"queries" branch merged...
r92 filters.each_key do |field|
Jean-Philippe Lang
added back "subproject" filter on issue list...
r347 next if field == "subproject_id"
Jean-Philippe Lang
"me" value is now available in queries for "assigned to" and "author" filters....
r517 v = values_for(field).clone
Jean-Philippe Lang
Custom fields for issues can now be used as filters on issue list....
r444 next unless v and !v.empty?
Jean-Philippe Lang
Adds ability to filter watched issues (#846)....
r2395 operator = operator_for(field)
Toshi MARUYAMA
remove trailing white-spaces from query model source....
r5702
Jean-Philippe Lang
Adds ability to filter watched issues (#846)....
r2395 # "me" value subsitution
Jean-Philippe Lang
Adds filters for regular/custom fields to the time entries list/report (#10191)....
r10743 if %w(assigned_to_id author_id user_id watcher_id).include?(field)
Jean-Philippe Lang
Include issues asigned to user's groups when using "assigned to me" filter (#2964)....
r6212 if v.delete("me")
if User.current.logged?
v.push(User.current.id.to_s)
v += User.current.group_ids.map(&:to_s) if field == 'assigned_to_id'
else
v.push("0")
end
end
Jean-Philippe Lang
Adds ability to filter watched issues (#846)....
r2395 end
Toshi MARUYAMA
remove trailing white-spaces from query model source....
r5702
Jean-Philippe Lang
Adds "my projects" filter on the cross-project issue list....
r8517 if field == 'project_id'
if v.delete('mine')
v += User.current.memberships.map(&:project_id).map(&:to_s)
end
end
Jean-Philippe Lang
Ability to filter issues using project, author, assignee and target version custom fields (#8161)....
r9981 if field =~ /cf_(\d+)$/
Jean-Philippe Lang
Custom fields for issues can now be used as filters on issue list....
r444 # custom field
Jean-Philippe Lang
Refactor: extract specific filter statements to methods....
r6181 filters_clauses << sql_for_custom_field(field, operator, v, $1)
elsif respond_to?("sql_for_#{field}_field")
# specific statement
filters_clauses << send("sql_for_#{field}_field", field, operator, v)
Jean-Philippe Lang
Custom fields for issues can now be used as filters on issue list....
r444 else
# regular field
Jean-Philippe Lang
Moves issue specific code to IssueQuery....
r10738 filters_clauses << '(' + sql_for_field(field, operator, v, queried_table_name, field) + ')'
Jean-Philippe Lang
Custom fields for issues can now be used as filters on issue list....
r444 end
Jean-Philippe Lang
"queries" branch merged...
r92 end if filters and valid?
Toshi MARUYAMA
remove trailing white-spaces from query model source....
r5702
Jean-Philippe Lang
Role-based issue custom field visibility (#5037)....
r11782 if (c = group_by_column) && c.is_a?(QueryCustomFieldColumn)
# Excludes results for which the grouped custom field is not visible
filters_clauses << c.custom_field.visibility_by_project_condition
end
Jean-Philippe Lang
Extract visibility condition from project statement and use visible scopes instead....
r5322 filters_clauses << project_statement
filters_clauses.reject!(&:blank?)
Toshi MARUYAMA
remove trailing white-spaces from query model source....
r5702
Jean-Philippe Lang
Extract visibility condition from project statement and use visible scopes instead....
r5322 filters_clauses.any? ? filters_clauses.join(' AND ') : nil
Jean-Philippe Lang
"queries" branch merged...
r92 end
Toshi MARUYAMA
remove trailing white-spaces from query model source....
r5702
Jean-Philippe Lang
Refactor: extract specific filter statements to methods....
r6181 private
Toshi MARUYAMA
remove trailing white-spaces from app/models/query.rb....
r6345
Jean-Philippe Lang
Refactor: extract specific filter statements to methods....
r6181 def sql_for_custom_field(field, operator, value, custom_field_id)
db_table = CustomValue.table_name
db_field = 'value'
Jean-Philippe Lang
Adds "me" to user custom fields filters (#9923)....
r8518 filter = @available_filters[field]
Jean-Philippe Lang
Ability to filter issues using project, author, assignee and target version custom fields (#8161)....
r9981 return nil unless filter
if filter[:format] == 'user'
Jean-Philippe Lang
Adds "me" to user custom fields filters (#9923)....
r8518 if value.delete('me')
value.push User.current.id.to_s
end
end
Jean-Philippe Lang
Adds support for multiselect custom fields (#1189)....
r8601 not_in = nil
if operator == '!'
# Makes ! operator work for custom fields with multiple values
operator = '='
not_in = 'NOT'
end
Jean-Philippe Lang
Ability to filter issues using project, author, assignee and target version custom fields (#8161)....
r9981 customized_key = "id"
Jean-Philippe Lang
Moves issue specific code to IssueQuery....
r10738 customized_class = queried_class
Jean-Philippe Lang
Ability to filter issues using project, author, assignee and target version custom fields (#8161)....
r9981 if field =~ /^(.+)\.cf_/
assoc = $1
customized_key = "#{assoc}_id"
Jean-Philippe Lang
Moves issue specific code to IssueQuery....
r10738 customized_class = queried_class.reflect_on_association(assoc.to_sym).klass.base_class rescue nil
raise "Unknown #{queried_class.name} association #{assoc}" unless customized_class
Jean-Philippe Lang
Ability to filter issues using project, author, assignee and target version custom fields (#8161)....
r9981 end
Jean-Philippe Lang
Fixed that filtering may return unwanted blank values (#14051)....
r11620 where = sql_for_field(field, operator, value, db_table, db_field, true)
if operator =~ /[<>]/
where = "(#{where}) AND #{db_table}.#{db_field} <> ''"
end
Jean-Philippe Lang
Role-based issue custom field visibility (#5037)....
r11782 "#{queried_table_name}.#{customized_key} #{not_in} IN (" +
"SELECT #{customized_class.table_name}.id FROM #{customized_class.table_name}" +
" LEFT OUTER JOIN #{db_table} ON #{db_table}.customized_type='#{customized_class}' AND #{db_table}.customized_id=#{customized_class.table_name}.id AND #{db_table}.custom_field_id=#{custom_field_id}" +
" WHERE (#{where}) AND (#{filter[:field].visibility_by_project_condition}))"
Jean-Philippe Lang
Refactor: extract specific filter statements to methods....
r6181 end
Toshi MARUYAMA
remove trailing white-spaces from app/models/query.rb....
r6345
Jean-Philippe Lang
Adds ability to filter watched issues (#846)....
r2395 # Helper method to generate the WHERE sql for a +field+, +operator+ and a +value+
def sql_for_field(field, operator, value, db_table, db_field, is_custom_filter=false)
Eric Davis
Refactor: Extracted new method Query#sql_for_field from Query#statement in...
r2088 sql = ''
Jean-Philippe Lang
Adds ability to filter watched issues (#846)....
r2395 case operator
Eric Davis
Refactor: Extracted new method Query#sql_for_field from Query#statement in...
r2088 when "="
Jean-Philippe Lang
Fixes "=" filter on float values....
r6136 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))
when :integer
Jean-Philippe Lang
Fixed: error when filtering by numeric custom field with postgresql (#9719)....
r7978 if is_custom_filter
Jean-Philippe Lang
Make sure we don't cast an empty string to numeric (#12713)....
r10873 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})"
Jean-Philippe Lang
Fixed: error when filtering by numeric custom field with postgresql (#9719)....
r7978 else
sql = "#{db_table}.#{db_field} = #{value.first.to_i}"
end
Jean-Philippe Lang
Fixes "=" filter on float values....
r6136 when :float
Jean-Philippe Lang
Fixed: error when filtering by numeric custom field with postgresql (#9719)....
r7978 if is_custom_filter
Jean-Philippe Lang
Make sure we don't cast an empty string to numeric (#12713)....
r10873 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.first.to_f - 1e-5} AND #{value.first.to_f + 1e-5})"
Jean-Philippe Lang
Fixed: error when filtering by numeric custom field with postgresql (#9719)....
r7978 else
sql = "#{db_table}.#{db_field} BETWEEN #{value.first.to_f - 1e-5} AND #{value.first.to_f + 1e-5}"
end
Jean-Philippe Lang
Adds date based filters (#4729) and date range filter (#6954)....
r6106 else
Jean-Philippe Lang
Fixes "=" filter on float values....
r6136 sql = "#{db_table}.#{db_field} IN (" + value.collect{|val| "'#{connection.quote_string(val)}'"}.join(",") + ")"
Jean-Philippe Lang
Adds date based filters (#4729) and date range filter (#6954)....
r6106 end
Jean-Philippe Lang
Fixes "=" filter on float values....
r6136 else
# IN an empty set
sql = "1=0"
Jean-Philippe Lang
Fixed: SQL error when filtering issues with an empty group or role (#7656)....
r4768 end
Eric Davis
Refactor: Extracted new method Query#sql_for_field from Query#statement in...
r2088 when "!"
Jean-Philippe Lang
Fixed: SQL error when filtering issues with an empty group or role (#7656)....
r4768 if value.any?
sql = "(#{db_table}.#{db_field} IS NULL OR #{db_table}.#{db_field} NOT IN (" + value.collect{|val| "'#{connection.quote_string(val)}'"}.join(",") + "))"
else
# NOT IN an empty set
sql = "1=1"
end
Eric Davis
Refactor: Extracted new method Query#sql_for_field from Query#statement in...
r2088 when "!*"
sql = "#{db_table}.#{db_field} IS NULL"
sql << " OR #{db_table}.#{db_field} = ''" if is_custom_filter
when "*"
sql = "#{db_table}.#{db_field} IS NOT NULL"
sql << " AND #{db_table}.#{db_field} <> ''" if is_custom_filter
when ">="
Jean-Philippe Lang
Adds date based filters (#4729) and date range filter (#6954)....
r6106 if [:date, :date_past].include?(type_for(field))
sql = date_clause(db_table, db_field, (Date.parse(value.first) rescue nil), nil)
Jean-Philippe Lang
Fixes "less than", "greater than" filters on custom fields with postgres (#6180)....
r6096 else
Jean-Philippe Lang
Adds date based filters (#4729) and date range filter (#6954)....
r6106 if is_custom_filter
Jean-Philippe Lang
Make sure we don't cast an empty string to numeric (#12713)....
r10873 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})"
Jean-Philippe Lang
Adds date based filters (#4729) and date range filter (#6954)....
r6106 else
Jean-Philippe Lang
Fixes filters on float values....
r6107 sql = "#{db_table}.#{db_field} >= #{value.first.to_f}"
Jean-Philippe Lang
Adds date based filters (#4729) and date range filter (#6954)....
r6106 end
Jean-Philippe Lang
Fixes "less than", "greater than" filters on custom fields with postgres (#6180)....
r6096 end
Eric Davis
Refactor: Extracted new method Query#sql_for_field from Query#statement in...
r2088 when "<="
Jean-Philippe Lang
Adds date based filters (#4729) and date range filter (#6954)....
r6106 if [:date, :date_past].include?(type_for(field))
sql = date_clause(db_table, db_field, nil, (Date.parse(value.first) rescue nil))
Jean-Philippe Lang
Fixes "less than", "greater than" filters on custom fields with postgres (#6180)....
r6096 else
Jean-Philippe Lang
Adds date based filters (#4729) and date range filter (#6954)....
r6106 if is_custom_filter
Jean-Philippe Lang
Make sure we don't cast an empty string to numeric (#12713)....
r10873 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})"
Jean-Philippe Lang
Adds date based filters (#4729) and date range filter (#6954)....
r6106 else
Jean-Philippe Lang
Fixes filters on float values....
r6107 sql = "#{db_table}.#{db_field} <= #{value.first.to_f}"
Jean-Philippe Lang
Adds date based filters (#4729) and date range filter (#6954)....
r6106 end
Jean-Philippe Lang
Fixes "less than", "greater than" filters on custom fields with postgres (#6180)....
r6096 end
Jean-Philippe Lang
Adds "between" operator for numeric filters (#6180)....
r6097 when "><"
Jean-Philippe Lang
Adds date based filters (#4729) and date range filter (#6954)....
r6106 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))
Jean-Philippe Lang
Adds "between" operator for numeric filters (#6180)....
r6097 else
Jean-Philippe Lang
Adds date based filters (#4729) and date range filter (#6954)....
r6106 if is_custom_filter
Jean-Philippe Lang
Make sure we don't cast an empty string to numeric (#12713)....
r10873 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})"
Jean-Philippe Lang
Adds date based filters (#4729) and date range filter (#6954)....
r6106 else
Jean-Philippe Lang
Fixes filters on float values....
r6107 sql = "#{db_table}.#{db_field} BETWEEN #{value[0].to_f} AND #{value[1].to_f}"
Jean-Philippe Lang
Adds date based filters (#4729) and date range filter (#6954)....
r6106 end
Jean-Philippe Lang
Adds "between" operator for numeric filters (#6180)....
r6097 end
Eric Davis
Refactor: Extracted new method Query#sql_for_field from Query#statement in...
r2088 when "o"
Jean-Philippe Lang
Moves issue specific code to IssueQuery....
r10738 sql = "#{queried_table_name}.status_id IN (SELECT id FROM #{IssueStatus.table_name} WHERE is_closed=#{connection.quoted_false})" if field == "status_id"
Eric Davis
Refactor: Extracted new method Query#sql_for_field from Query#statement in...
r2088 when "c"
Jean-Philippe Lang
Moves issue specific code to IssueQuery....
r10738 sql = "#{queried_table_name}.status_id IN (SELECT id FROM #{IssueStatus.table_name} WHERE is_closed=#{connection.quoted_true})" if field == "status_id"
Jean-Philippe Lang
Changes how relative date filters work and adds specific filters for filtering dates in past/next n days (#11426)....
r10546 when "><t-"
# between today - n days and today
Jean-Philippe Lang
Adds date based filters (#4729) and date range filter (#6954)....
r6106 sql = relative_date_clause(db_table, db_field, - value.first.to_i, 0)
Jean-Philippe Lang
Changes how relative date filters work and adds specific filters for filtering dates in past/next n days (#11426)....
r10546 when ">t-"
# >= today - n days
sql = relative_date_clause(db_table, db_field, - value.first.to_i, nil)
Eric Davis
Refactor: Extracted new method Query#sql_for_field from Query#statement in...
r2088 when "<t-"
Jean-Philippe Lang
Changes how relative date filters work and adds specific filters for filtering dates in past/next n days (#11426)....
r10546 # <= today - n days
Jean-Philippe Lang
Adds date based filters (#4729) and date range filter (#6954)....
r6106 sql = relative_date_clause(db_table, db_field, nil, - value.first.to_i)
Eric Davis
Refactor: Extracted new method Query#sql_for_field from Query#statement in...
r2088 when "t-"
Jean-Philippe Lang
Changes how relative date filters work and adds specific filters for filtering dates in past/next n days (#11426)....
r10546 # = n days in past
Jean-Philippe Lang
Adds date based filters (#4729) and date range filter (#6954)....
r6106 sql = relative_date_clause(db_table, db_field, - value.first.to_i, - value.first.to_i)
Jean-Philippe Lang
Changes how relative date filters work and adds specific filters for filtering dates in past/next n days (#11426)....
r10546 when "><t+"
# between today and today + n days
sql = relative_date_clause(db_table, db_field, 0, value.first.to_i)
Eric Davis
Refactor: Extracted new method Query#sql_for_field from Query#statement in...
r2088 when ">t+"
Jean-Philippe Lang
Changes how relative date filters work and adds specific filters for filtering dates in past/next n days (#11426)....
r10546 # >= today + n days
Jean-Philippe Lang
Adds date based filters (#4729) and date range filter (#6954)....
r6106 sql = relative_date_clause(db_table, db_field, value.first.to_i, nil)
Eric Davis
Refactor: Extracted new method Query#sql_for_field from Query#statement in...
r2088 when "<t+"
Jean-Philippe Lang
Changes how relative date filters work and adds specific filters for filtering dates in past/next n days (#11426)....
r10546 # <= today + n days
sql = relative_date_clause(db_table, db_field, nil, value.first.to_i)
Eric Davis
Refactor: Extracted new method Query#sql_for_field from Query#statement in...
r2088 when "t+"
Jean-Philippe Lang
Changes how relative date filters work and adds specific filters for filtering dates in past/next n days (#11426)....
r10546 # = today + n days
Jean-Philippe Lang
Adds date based filters (#4729) and date range filter (#6954)....
r6106 sql = relative_date_clause(db_table, db_field, value.first.to_i, value.first.to_i)
Eric Davis
Refactor: Extracted new method Query#sql_for_field from Query#statement in...
r2088 when "t"
Jean-Philippe Lang
Changes how relative date filters work and adds specific filters for filtering dates in past/next n days (#11426)....
r10546 # = today
Jean-Philippe Lang
Adds date based filters (#4729) and date range filter (#6954)....
r6106 sql = relative_date_clause(db_table, db_field, 0, 0)
Jean-Philippe Lang
Adds TimeEntryQuery for listing time entries....
r10740 when "ld"
# = yesterday
sql = relative_date_clause(db_table, db_field, -1, -1)
Eric Davis
Refactor: Extracted new method Query#sql_for_field from Query#statement in...
r2088 when "w"
Jean-Philippe Lang
Changes how relative date filters work and adds specific filters for filtering dates in past/next n days (#11426)....
r10546 # = this week
Jean-Philippe Lang
Makes 'This week' filter work with any starting day of week (#7097)....
r5476 first_day_of_week = l(:general_first_day_of_week).to_i
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)
Jean-Philippe Lang
Adds date based filters (#4729) and date range filter (#6954)....
r6106 sql = relative_date_clause(db_table, db_field, - days_ago, - days_ago + 6)
Jean-Philippe Lang
Adds TimeEntryQuery for listing time entries....
r10740 when "lw"
# = last week
first_day_of_week = l(:general_first_day_of_week).to_i
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)
sql = relative_date_clause(db_table, db_field, - days_ago - 7, - days_ago - 1)
when "l2w"
# = last 2 weeks
first_day_of_week = l(:general_first_day_of_week).to_i
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)
sql = relative_date_clause(db_table, db_field, - days_ago - 14, - days_ago - 1)
when "m"
# = this month
date = Date.today
sql = date_clause(db_table, db_field, date.beginning_of_month, date.end_of_month)
when "lm"
# = last month
date = Date.today.prev_month
sql = date_clause(db_table, db_field, date.beginning_of_month, date.end_of_month)
when "y"
# = this year
date = Date.today
sql = date_clause(db_table, db_field, date.beginning_of_year, date.end_of_year)
Eric Davis
Refactor: Extracted new method Query#sql_for_field from Query#statement in...
r2088 when "~"
Jean-Philippe Lang
Fixed: case sensitivity in issue subject filtering (#3536)....
r2696 sql = "LOWER(#{db_table}.#{db_field}) LIKE '%#{connection.quote_string(value.first.to_s.downcase)}%'"
Eric Davis
Refactor: Extracted new method Query#sql_for_field from Query#statement in...
r2088 when "!~"
Jean-Philippe Lang
Fixed: case sensitivity in issue subject filtering (#3536)....
r2696 sql = "LOWER(#{db_table}.#{db_field}) NOT LIKE '%#{connection.quote_string(value.first.to_s.downcase)}%'"
Jean-Philippe Lang
Adds "between" operator for numeric filters (#6180)....
r6097 else
raise "Unknown query operator #{operator}"
Eric Davis
Refactor: Extracted new method Query#sql_for_field from Query#statement in...
r2088 end
Toshi MARUYAMA
remove trailing white-spaces from query model source....
r5702
Eric Davis
Bit more refactoring on Query#sql_for_field to remove multiple returns...
r2089 return sql
Eric Davis
Refactor: Extracted new method Query#sql_for_field from Query#statement in...
r2088 end
Toshi MARUYAMA
remove trailing white-spaces from query model source....
r5702
Jean-Philippe Lang
Query#add_custom_fields_filters now takes a custom fields scope....
r11687 # 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"]
Jean-Philippe Lang
Ability to filter issues using project, author, assignee and target version custom fields (#8161)....
r9981 end
Jean-Philippe Lang
Query#add_custom_fields_filters now takes a custom fields scope....
r11687 options = { :type => :list_optional, :values => values }
else
options = { :type => :string }
end
filter_id = "cf_#{field.id}"
filter_name = field.name
if assoc.present?
filter_id = "#{assoc}.#{filter_id}"
filter_name = l("label_attribute_of_#{assoc}", :name => filter_name)
Jean-Philippe Lang
Ability to filter issues using project, author, assignee and target version custom fields (#8161)....
r9981 end
Jean-Philippe Lang
Query#add_custom_fields_filters now takes a custom fields scope....
r11687 add_available_filter filter_id, options.merge({
:name => filter_name,
:format => field.field_format,
:field => field
})
Jean-Philippe Lang
Ability to filter issues using project, author, assignee and target version custom fields (#8161)....
r9981 end
Jean-Philippe Lang
Query#add_custom_fields_filters now takes a custom fields scope....
r11687 # Adds filters for the given custom fields scope
def add_custom_fields_filters(scope, assoc=nil)
Jean-Philippe Lang
Role-based issue custom field visibility (#5037)....
r11782 scope.visible.where(:is_filter => true).sorted.each do |field|
Jean-Philippe Lang
Query#add_custom_fields_filters now takes a custom fields scope....
r11687 add_custom_field_filter(field, assoc)
end
end
# Adds filters for the given associations custom fields
Jean-Philippe Lang
Ability to filter issues using project, author, assignee and target version custom fields (#8161)....
r9981 def add_associations_custom_fields_filters(*associations)
Jean-Philippe Lang
Role-based issue custom field visibility (#5037)....
r11782 fields_by_class = CustomField.visible.where(:is_filter => true).group_by(&:class)
Jean-Philippe Lang
Ability to filter issues using project, author, assignee and target version custom fields (#8161)....
r9981 associations.each do |assoc|
Jean-Philippe Lang
Moves issue specific code to IssueQuery....
r10738 association_klass = queried_class.reflect_on_association(assoc).klass
Jean-Philippe Lang
Ability to filter issues using project, author, assignee and target version custom fields (#8161)....
r9981 fields_by_class.each do |field_class, fields|
if field_class.customized_class <= association_klass
Jean-Philippe Lang
Query#add_custom_fields_filters now takes a custom fields scope....
r11687 fields.sort.each do |field|
add_custom_field_filter(field, assoc)
end
Jean-Philippe Lang
Ability to filter issues using project, author, assignee and target version custom fields (#8161)....
r9981 end
end
Jean-Philippe Lang
Add filters on cross-project issue list for custom fields marked as 'For all projects'....
r1562 end
end
Toshi MARUYAMA
remove trailing white-spaces from app/models/query.rb....
r6345
Jean-Philippe Lang
Fixed date filters accuracy with SQLite (#2221)....
r2052 # Returns a SQL clause for a date or datetime field.
Jean-Philippe Lang
Adds date based filters (#4729) and date range filter (#6954)....
r6106 def date_clause(table, field, from, to)
Jean-Philippe Lang
Fixed date filters accuracy with SQLite (#2221)....
r2052 s = []
if from
Toshi MARUYAMA
Rails3: model: query: parse dates using UTC (ruby 1.9 inside) (#4796)...
r7471 from_yesterday = from - 1
Jean-Philippe Lang
Fixed time zone issues introduced by r9719 (#10996)....
r9543 from_yesterday_time = Time.local(from_yesterday.year, from_yesterday.month, from_yesterday.day)
if self.class.default_timezone == :utc
from_yesterday_time = from_yesterday_time.utc
end
s << ("#{table}.#{field} > '%s'" % [connection.quoted_date(from_yesterday_time.end_of_day)])
Jean-Philippe Lang
Fixed date filters accuracy with SQLite (#2221)....
r2052 end
if to
Jean-Philippe Lang
Fixed time zone issues introduced by r9719 (#10996)....
r9543 to_time = Time.local(to.year, to.month, to.day)
if self.class.default_timezone == :utc
to_time = to_time.utc
end
s << ("#{table}.#{field} <= '%s'" % [connection.quoted_date(to_time.end_of_day)])
Jean-Philippe Lang
Fixed date filters accuracy with SQLite (#2221)....
r2052 end
s.join(' AND ')
end
Toshi MARUYAMA
remove trailing white-spaces from app/models/query.rb....
r6345
Jean-Philippe Lang
Adds date based filters (#4729) and date range filter (#6954)....
r6106 # Returns a SQL clause for a date or datetime field using relative dates.
def relative_date_clause(table, field, days_from, days_to)
date_clause(table, field, (days_from ? Date.today + days_from : nil), (days_to ? Date.today + days_to : nil))
end
Jean-Philippe Lang
Ability to group and sort the issue list by user/version custom field (#9419)....
r9890
# Additional joins required for the given sort options
def joins_for_order_statement(order_options)
joins = []
if order_options
if order_options.include?('authors')
Jean-Philippe Lang
Moves issue specific code to IssueQuery....
r10738 joins << "LEFT OUTER JOIN #{User.table_name} authors ON authors.id = #{queried_table_name}.author_id"
Jean-Philippe Lang
Ability to group and sort the issue list by user/version custom field (#9419)....
r9890 end
order_options.scan(/cf_\d+/).uniq.each do |name|
column = available_columns.detect {|c| c.name.to_s == name}
Jean-Philippe Lang
In case the column is not found....
r9891 join = column && column.custom_field.join_for_order_statement
Jean-Philippe Lang
Ability to group and sort the issue list by user/version custom field (#9419)....
r9890 if join
joins << join
end
end
end
joins.any? ? joins.join(' ') : nil
end
Jean-Philippe Lang
"queries" branch merged...
r92 end