# Returns false, if the custom field can not be used for sorting.
def order_statement
case field_format
- when 'string', 'list', 'date', 'bool'
+ when 'string', 'text', 'list', 'date', 'bool'
# COALESCE is here to make sure that blank and NULL values are sorted equally
"COALESCE((SELECT cv_sort.value FROM #{CustomValue.table_name} cv_sort" +
" WHERE cv_sort.customized_type='#{self.class.customized_class.name}'" +
" AND cv_sort.customized_id=#{self.class.customized_class.table_name}.id" +
" AND cv_sort.custom_field_id=#{id} LIMIT 1), '')"
+ when 'int', 'float'
+ # Make the database cast values into numeric
+ # Postgresql will raise an error if a value can not be casted!
+ # CustomValue validations should ensure that it doesn't occur
+ "(SELECT CAST(cv_sort.value AS decimal(60,3)) FROM #{CustomValue.table_name} cv_sort" +
+ " WHERE cv_sort.customized_type='#{self.class.customized_class.name}'" +
+ " AND cv_sort.customized_id=#{self.class.customized_class.table_name}.id" +
+ " AND cv_sort.custom_field_id=#{id} AND cv_sort.value <> '' AND cv_sort.value IS NOT NULL LIMIT 1)"
else
nil
end
is_required: false\r
field_format: float\r
default_value: ""\r
+custom_fields_006: \r
+ name: Float field\r
+ min_length: 0\r
+ regexp: ""\r
+ is_for_all: true\r
+ type: IssueCustomField\r
+ max_length: 0\r
+ possible_values: ""\r
+ id: 6\r
+ is_required: false\r
+ field_format: float\r
+ default_value: ""\r
\ No newline at end of file
custom_fields_trackers_003: \r
custom_field_id: 2\r
tracker_id: 3\r
+custom_fields_trackers_004: \r
+ custom_field_id: 6\r
+ tracker_id: 1\r
+custom_fields_trackers_005: \r
+ custom_field_id: 6\r
+ tracker_id: 2\r
+custom_fields_trackers_006: \r
+ custom_field_id: 6\r
+ tracker_id: 3\r
customized_type: Issue\r
custom_field_id: 2\r
customized_id: 3\r
- id: 9\r
+ id: 6\r
value: "125"\r
custom_values_007: \r
customized_type: Project\r
custom_field_id: 3\r
customized_id: 1\r
- id: 10\r
+ id: 7\r
value: Stable\r
custom_values_001: \r
customized_type: User\r
custom_field_id: 4\r
customized_id: 3\r
- id: 2\r
+ id: 1\r
value: ""\r
custom_values_002: \r
customized_type: User\r
custom_field_id: 4\r
customized_id: 4\r
- id: 3\r
+ id: 2\r
value: 01 23 45 67 89\r
custom_values_003: \r
customized_type: User\r
custom_field_id: 4\r
customized_id: 2\r
- id: 4\r
+ id: 3\r
value: ""\r
custom_values_004: \r
customized_type: Issue\r
custom_field_id: 2\r
customized_id: 1\r
- id: 7\r
+ id: 4\r
value: "125"\r
custom_values_005: \r
customized_type: Issue\r
custom_field_id: 2\r
customized_id: 2\r
- id: 8\r
+ id: 5\r
value: ""\r
custom_values_008: \r
customized_type: Issue\r
custom_field_id: 1\r
customized_id: 3\r
- id: 11\r
+ id: 8\r
value: "MySQL"\r
custom_values_009: \r
customized_type: Issue\r
custom_field_id: 2\r
customized_id: 3\r
- id: 12\r
+ id: 9\r
value: "this is a stringforcustomfield search"\r
+custom_values_010: \r
+ customized_type: Issue\r
+ custom_field_id: 6\r
+ customized_id: 1\r
+ id: 10\r
+ value: "2.1"\r
+custom_values_011: \r
+ customized_type: Issue\r
+ custom_field_id: 6\r
+ customized_id: 2\r
+ id: 11\r
+ value: "2.05"\r
+custom_values_012: \r
+ customized_type: Issue\r
+ custom_field_id: 6\r
+ customized_id: 3\r
+ id: 12\r
+ value: "11.65"\r
+custom_values_013: \r
+ customized_type: Issue\r
+ custom_field_id: 6\r
+ customized_id: 7\r
+ id: 13\r
+ value: ""\r
+custom_values_014: \r
+ customized_type: Issue\r
+ custom_field_id: 6\r
+ customized_id: 5\r
+ id: 14\r
+ value: "-7.6"\r
\ No newline at end of file
:conditions => q.statement,
:order => "#{c.sortable} ASC"
values = issues.collect {|i| i.custom_value_for(c.custom_field).to_s}
+ assert !values.empty?
assert_equal values.sort, values
end
:conditions => q.statement,
:order => "#{c.sortable} DESC"
values = issues.collect {|i| i.custom_value_for(c.custom_field).to_s}
+ assert !values.empty?
assert_equal values.sort.reverse, values
end
+ def test_sort_by_float_custom_field_asc
+ q = Query.new
+ c = q.available_columns.find {|col| col.is_a?(QueryCustomFieldColumn) && col.custom_field.field_format == 'float' }
+ assert c
+ assert c.sortable
+ issues = Issue.find :all,
+ :include => [ :assigned_to, :status, :tracker, :project, :priority ],
+ :conditions => q.statement,
+ :order => "#{c.sortable} ASC"
+ values = issues.collect {|i| begin; Kernel.Float(i.custom_value_for(c.custom_field).to_s); rescue; nil; end}.compact
+ assert !values.empty?
+ assert_equal values.sort, values
+ end
+
def test_label_for
q = Query.new
assert_equal 'assigned_to', q.label_for('assigned_to_id')