Feature #24013 » issue-24013-r16009-misc.diff
app/controllers/application_controller.rb | ||
---|---|---|
170 | 170 |
if User.current.logged? |
171 | 171 |
cookies.delete(autologin_cookie_name) |
172 | 172 |
Token.where(["user_id = ? AND action = ?", User.current.id, 'autologin']).delete_all |
173 |
Token.where(["user_id = ? AND action = ? AND value = ?", User.current.id, 'session', session[:tk]]).delete_all
|
|
173 |
Token.where(["user_id = ? AND action = ?", User.current.id, 'session']).where(:value => session[:tk]).delete_all
|
|
174 | 174 |
self.logged_user = nil |
175 | 175 |
end |
176 | 176 |
end |
app/controllers/versions_controller.rb | ||
---|---|---|
50 | 50 |
includes(:project, :tracker). |
51 | 51 |
preload(:status, :priority, :fixed_version). |
52 | 52 |
where(:tracker_id => @selected_tracker_ids, :project_id => project_ids, :fixed_version_id => @versions.map(&:id)). |
53 |
order("#{Project.table_name}.lft, #{Tracker.table_name}.position, #{Issue.table_name}.id")
|
|
53 |
order("#{Project.table_name}.lft, #{Tracker.table_name}.#{'position'.quote_column_name}, #{Issue.table_name}.id")
|
|
54 | 54 |
@issues_by_version = issues.group_by(&:fixed_version) |
55 | 55 |
end |
56 | 56 |
@versions.reject! {|version| !project_ids.include?(version.project_id) && @issues_by_version[version].blank?} |
... | ... | |
67 | 67 |
@issues = @version.fixed_issues.visible. |
68 | 68 |
includes(:status, :tracker, :priority). |
69 | 69 |
preload(:project). |
70 |
reorder("#{Tracker.table_name}.position, #{Issue.table_name}.id").
|
|
70 |
reorder("#{Issue.table_name}.id"). |
|
71 | 71 |
to_a |
72 | 72 |
} |
73 | 73 |
format.api |
app/models/project.rb | ||
---|---|---|
44 | 44 |
has_many :documents, :dependent => :destroy |
45 | 45 |
has_many :news, lambda {includes(:author)}, :dependent => :destroy |
46 | 46 |
has_many :issue_categories, lambda {order("#{IssueCategory.table_name}.name")}, :dependent => :delete_all |
47 |
has_many :boards, lambda {order("position ASC")}, :dependent => :destroy
|
|
47 |
has_many :boards, lambda { order(:position) }, :dependent => :destroy
|
|
48 | 48 |
has_one :repository, lambda {where(["is_default = ?", true])} |
49 | 49 |
has_many :repositories, :dependent => :destroy |
50 | 50 |
has_many :changesets, :through => :repository |
51 | 51 |
has_one :wiki, :dependent => :destroy |
52 | 52 |
# Custom field for the project issues |
53 | 53 |
has_and_belongs_to_many :issue_custom_fields, |
54 |
lambda {order("#{CustomField.table_name}.position")},
|
|
54 |
lambda { order("#{CustomField.table_name}.#{'position'.quote_column_name}") },
|
|
55 | 55 |
:class_name => 'IssueCustomField', |
56 | 56 |
:join_table => "#{table_name_prefix}custom_fields_projects#{table_name_suffix}", |
57 | 57 |
:association_foreign_key => 'custom_field_id' |
app/models/query.rb | ||
---|---|---|
824 | 824 | |
825 | 825 |
def sql_for_custom_field(field, operator, value, custom_field_id) |
826 | 826 |
db_table = CustomValue.table_name |
827 |
db_field = 'value' |
|
827 |
db_field = 'value'.quote_column_name
|
|
828 | 828 |
filter = @available_filters[field] |
829 | 829 |
return nil unless filter |
830 | 830 |
if filter[:field].format.target_class && filter[:field].format.target_class <= User |
... | ... | |
869 | 869 |
int_values = value.first.to_s.scan(/[+-]?\d+/).map(&:to_i).join(",") |
870 | 870 |
if int_values.present? |
871 | 871 |
if is_custom_filter |
872 |
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)) IN (#{int_values}))"
|
|
872 |
sql = "(#{db_table}.#{db_field} <> '' AND CAST(CASE #{db_table}.#{db_field} WHEN '' THEN '0' ELSE #{db_table}.#{db_field} END AS decimal(18,3)) IN (#{int_values}))"
|
|
873 | 873 |
else |
874 | 874 |
sql = "#{db_table}.#{db_field} IN (#{int_values})" |
875 | 875 |
end |
... | ... | |
878 | 878 |
end |
879 | 879 |
when :float |
880 | 880 |
if is_custom_filter |
881 |
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})"
|
|
881 |
sql = "(#{db_table}.#{db_field} <> '' AND CAST(CASE #{db_table}.#{db_field} WHEN '' THEN '0' ELSE #{db_table}.#{db_field} END AS decimal(18,3)) BETWEEN #{value.first.to_f - 1e-5} AND #{value.first.to_f + 1e-5})"
|
|
882 | 882 |
else |
883 | 883 |
sql = "#{db_table}.#{db_field} BETWEEN #{value.first.to_f - 1e-5} AND #{value.first.to_f + 1e-5}" |
884 | 884 |
end |
... | ... | |
907 | 907 |
sql = date_clause(db_table, db_field, parse_date(value.first), nil, is_custom_filter) |
908 | 908 |
else |
909 | 909 |
if is_custom_filter |
910 |
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})"
|
|
910 |
sql = "(#{db_table}.#{db_field} <> '' AND CAST(CASE #{db_table}.#{db_field} WHEN '' THEN '0' ELSE #{db_table}.#{db_field} END AS decimal(18,3)) >= #{value.first.to_f})"
|
|
911 | 911 |
else |
912 | 912 |
sql = "#{db_table}.#{db_field} >= #{value.first.to_f}" |
913 | 913 |
end |
... | ... | |
917 | 917 |
sql = date_clause(db_table, db_field, nil, parse_date(value.first), is_custom_filter) |
918 | 918 |
else |
919 | 919 |
if is_custom_filter |
920 |
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})"
|
|
920 |
sql = "(#{db_table}.#{db_field} <> '' AND CAST(CASE #{db_table}.#{db_field} WHEN '' THEN '0' ELSE #{db_table}.#{db_field} END AS decimal(18,3)) <= #{value.first.to_f})"
|
|
921 | 921 |
else |
922 | 922 |
sql = "#{db_table}.#{db_field} <= #{value.first.to_f}" |
923 | 923 |
end |
... | ... | |
927 | 927 |
sql = date_clause(db_table, db_field, parse_date(value[0]), parse_date(value[1]), is_custom_filter) |
928 | 928 |
else |
929 | 929 |
if is_custom_filter |
930 |
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})"
|
|
930 |
sql = "(#{db_table}.#{db_field} <> '' AND CAST(CASE #{db_table}.#{db_field} WHEN '' THEN '0' ELSE #{db_table}.#{db_field} END AS decimal(18,3)) BETWEEN #{value[0].to_f} AND #{value[1].to_f})"
|
|
931 | 931 |
else |
932 | 932 |
sql = "#{db_table}.#{db_field} BETWEEN #{value[0].to_f} AND #{value[1].to_f}" |
933 | 933 |
end |
... | ... | |
1079 | 1079 |
s = [] |
1080 | 1080 |
if from |
1081 | 1081 |
if from.is_a?(Date) |
1082 |
from = date_for_user_time_zone(from.year, from.month, from.day).yesterday.end_of_day |
|
1082 |
if Redmine::Database.firebird? |
|
1083 |
from = date_for_user_time_zone(from.year, from.month, from.day).yesterday.end_of_day.to_date |
|
1084 |
else |
|
1085 |
from = date_for_user_time_zone(from.year, from.month, from.day).yesterday.end_of_day |
|
1086 |
end |
|
1083 | 1087 |
else |
1084 | 1088 |
from = from - 1 # second |
1085 | 1089 |
end |
... | ... | |
1090 | 1094 |
end |
1091 | 1095 |
if to |
1092 | 1096 |
if to.is_a?(Date) |
1093 |
to = date_for_user_time_zone(to.year, to.month, to.day).end_of_day |
|
1097 |
if Redmine::Database.firebird? |
|
1098 |
to = date_for_user_time_zone(to.year, to.month, to.day).end_of_day.to_date |
|
1099 |
else |
|
1100 |
to = date_for_user_time_zone(to.year, to.month, to.day).end_of_day |
|
1101 |
end |
|
1094 | 1102 |
end |
1095 | 1103 |
if self.class.default_timezone == :utc |
1096 | 1104 |
to = to.utc |
app/models/repository.rb | ||
---|---|---|
422 | 422 |
# Notes: |
423 | 423 |
# - this hash honnors the users mapping defined for the repository |
424 | 424 |
def stats_by_author |
425 |
commits = Changeset.where("repository_id = ?", id).select("committer, user_id, count(*) as count").group("committer, user_id") |
|
425 |
commits = Changeset.where("repository_id = ?", id).select("committer, user_id, count(*) as commit_count").group("committer, user_id")
|
|
426 | 426 | |
427 | 427 |
#TODO: restore ordering ; this line probably never worked |
428 | 428 |
#commits.to_a.sort! {|x, y| x.last <=> y.last} |
429 | 429 | |
430 |
changes = Change.joins(:changeset).where("#{Changeset.table_name}.repository_id = ?", id).select("committer, user_id, count(*) as count").group("committer, user_id") |
|
430 |
changes = Change.joins(:changeset).where("#{Changeset.table_name}.repository_id = ?", id).select("committer, user_id, count(*) as commit_count").group("committer, user_id")
|
|
431 | 431 | |
432 | 432 |
user_ids = changesets.map(&:user_id).compact.uniq |
433 | 433 |
authors_names = User.where(:id => user_ids).inject({}) do |memo, user| |
... | ... | |
442 | 442 |
end |
443 | 443 |
hash[mapped_name] ||= { :commits_count => 0, :changes_count => 0 } |
444 | 444 |
if element.is_a?(Changeset) |
445 |
hash[mapped_name][:commits_count] += element.count.to_i |
|
445 |
hash[mapped_name][:commits_count] += element.commit_count.to_i
|
|
446 | 446 |
else |
447 |
hash[mapped_name][:changes_count] += element.count.to_i |
|
447 |
hash[mapped_name][:changes_count] += element.commit_count.to_i
|
|
448 | 448 |
end |
449 | 449 |
hash |
450 | 450 |
end |
app/models/user.rb | ||
---|---|---|
684 | 684 |
# Returns true if the user is allowed to delete the user's own account |
685 | 685 |
def own_account_deletable? |
686 | 686 |
Setting.unsubscribe? && |
687 |
(!admin? || User.active.where("admin = ? AND id <> ?", true, id).exists?)
|
|
687 |
(!admin? || User.active.where("id <> ?", id).where(:admin => true).exists?)
|
|
688 | 688 |
end |
689 | 689 | |
690 | 690 |
safe_attributes 'firstname', |
... | ... | |
821 | 821 |
where(["property = 'attr' AND prop_key = 'assigned_to_id' AND old_value = ?", id.to_s]). |
822 | 822 |
update_all(['old_value = ?', substitute.id.to_s]) |
823 | 823 |
JournalDetail. |
824 |
where(["property = 'attr' AND prop_key = 'assigned_to_id' AND value = ?", id.to_s]). |
|
825 |
update_all(['value = ?', substitute.id.to_s]) |
|
824 |
where(["property = 'attr' AND prop_key = 'assigned_to_id'"]). |
|
825 |
where(:value => id.to_s). |
|
826 |
update_all(:value => substitute.id.to_s) |
|
826 | 827 |
Message.where(['author_id = ?', id]).update_all(['author_id = ?', substitute.id]) |
827 | 828 |
News.where(['author_id = ?', id]).update_all(['author_id = ?', substitute.id]) |
828 | 829 |
# Remove private queries and keep public ones |
lib/plugins/acts_as_customizable/lib/acts_as_customizable.rb | ||
---|---|---|
27 | 27 |
return if self.included_modules.include?(Redmine::Acts::Customizable::InstanceMethods) |
28 | 28 |
cattr_accessor :customizable_options |
29 | 29 |
self.customizable_options = options |
30 |
has_many :custom_values, lambda {includes(:custom_field).order("#{CustomField.table_name}.position")},
|
|
30 |
has_many :custom_values, lambda {joins(:custom_field).merge(CustomField.order(:position))},
|
|
31 | 31 |
:as => :customized, |
32 | 32 |
:dependent => :delete_all, |
33 | 33 |
:validate => false |
lib/plugins/open_id_authentication/lib/open_id_authentication/association.rb | ||
---|---|---|
1 | 1 |
module OpenIdAuthentication |
2 | 2 |
class Association < ActiveRecord::Base |
3 |
self.table_name = :open_id_authentication_associations
|
|
3 |
self.table_name = :open_id_auth_associations |
|
4 | 4 | |
5 | 5 |
def from_record |
6 | 6 |
OpenID::Association.new(handle, secret, issued, lifetime, assoc_type) |
lib/redmine/database.rb | ||
---|---|---|
49 | 49 |
(ActiveRecord::Base.connection.adapter_name =~ /mysql/i).present? |
50 | 50 |
end |
51 | 51 | |
52 |
# Returns +true+ if the database is Firebird or RedDatabase |
|
53 |
def firebird? |
|
54 |
(ActiveRecord::Base.connection.adapter_name =~ /fb/i).present? |
|
55 |
end |
|
56 | ||
52 | 57 |
# Returns a SQL statement for case/accent (if possible) insensitive match |
53 | 58 |
def like(left, right, options={}) |
54 | 59 |
neg = (options[:match] == false ? 'NOT ' : '') |
lib/redmine/field_format.rb | ||
---|---|---|
294 | 294 |
# Returns nil if the custom field can not be used for sorting. |
295 | 295 |
def order_statement(custom_field) |
296 | 296 |
# COALESCE is here to make sure that blank and NULL values are sorted equally |
297 |
"COALESCE(#{join_alias custom_field}.value, '')"
|
|
297 |
"COALESCE(#{join_alias custom_field}.#{value_column}, '')"
|
|
298 | 298 |
end |
299 | 299 | |
300 | 300 |
# Returns a GROUP BY clause that can used to group by custom value |
... | ... | |
312 | 312 |
" AND #{alias_name}.customized_id = #{custom_field.class.customized_class.table_name}.id" + |
313 | 313 |
" AND #{alias_name}.custom_field_id = #{custom_field.id}" + |
314 | 314 |
" AND (#{custom_field.visibility_by_project_condition})" + |
315 |
" AND #{alias_name}.value <> ''" +
|
|
315 |
" AND #{alias_name}.#{value_column} <> ''" +
|
|
316 | 316 |
" AND #{alias_name}.id = (SELECT max(#{alias_name}_2.id) FROM #{CustomValue.table_name} #{alias_name}_2" + |
317 | 317 |
" WHERE #{alias_name}_2.customized_type = #{alias_name}.customized_type" + |
318 | 318 |
" AND #{alias_name}_2.customized_id = #{alias_name}.customized_id" + |
... | ... | |
322 | 322 |
def join_alias(custom_field) |
323 | 323 |
"cf_#{custom_field.id}" |
324 | 324 |
end |
325 | ||
326 |
def value_column |
|
327 |
'value'.quote_column_name |
|
328 |
end |
|
325 | 329 |
protected :join_alias |
326 | 330 |
end |
327 | 331 | |
... | ... | |
431 | 435 |
# Make the database cast values into numeric |
432 | 436 |
# Postgresql will raise an error if a value can not be casted! |
433 | 437 |
# CustomValue validations should ensure that it doesn't occur |
434 |
"CAST(CASE #{join_alias custom_field}.value WHEN '' THEN '0' ELSE #{join_alias custom_field}.value END AS decimal(30,3))"
|
|
438 |
"CAST(CASE #{join_alias custom_field}.#{value_column} WHEN '' THEN '0' ELSE #{join_alias custom_field}.#{value_column} END AS decimal(18,3))"
|
|
435 | 439 |
end |
436 | 440 | |
437 | 441 |
# Returns totals for the given scope |
... | ... | |
439 | 443 |
scope.joins(:custom_values). |
440 | 444 |
where(:custom_values => {:custom_field_id => custom_field.id}). |
441 | 445 |
where.not(:custom_values => {:value => ''}). |
442 |
sum("CAST(#{CustomValue.table_name}.value AS decimal(30,3))")
|
|
446 |
sum("CAST(#{CustomValue.table_name}.#{value_column} AS decimal(18,3))")
|
|
443 | 447 |
end |
444 | 448 | |
445 | 449 |
def cast_total_value(custom_field, value) |
... | ... | |
719 | 723 |
end |
720 | 724 | |
721 | 725 |
def group_statement(custom_field) |
722 |
"COALESCE(#{join_alias custom_field}.value, '')"
|
|
726 |
"COALESCE(#{join_alias custom_field}.#{value_column}, '')"
|
|
723 | 727 |
end |
724 | 728 | |
725 | 729 |
def join_for_order_statement(custom_field) |
... | ... | |
730 | 734 |
" AND #{alias_name}.customized_id = #{custom_field.class.customized_class.table_name}.id" + |
731 | 735 |
" AND #{alias_name}.custom_field_id = #{custom_field.id}" + |
732 | 736 |
" AND (#{custom_field.visibility_by_project_condition})" + |
733 |
" AND #{alias_name}.value <> ''" +
|
|
737 |
" AND #{alias_name}.#{value_column} <> ''" +
|
|
734 | 738 |
" AND #{alias_name}.id = (SELECT max(#{alias_name}_2.id) FROM #{CustomValue.table_name} #{alias_name}_2" + |
735 | 739 |
" WHERE #{alias_name}_2.customized_type = #{alias_name}.customized_type" + |
736 | 740 |
" AND #{alias_name}_2.customized_id = #{alias_name}.customized_id" + |
737 | 741 |
" AND #{alias_name}_2.custom_field_id = #{alias_name}.custom_field_id)" + |
738 | 742 |
" LEFT OUTER JOIN #{target_class.table_name} #{value_join_alias custom_field}" + |
739 |
" ON CAST(CASE #{alias_name}.value WHEN '' THEN '0' ELSE #{alias_name}.value END AS decimal(30,0)) = #{value_join_alias custom_field}.id"
|
|
743 |
" ON CAST(CASE #{alias_name}.#{value_column} WHEN '' THEN '0' ELSE #{alias_name}.#{value_column} END AS decimal(18,0)) = #{value_join_alias custom_field}.id"
|
|
740 | 744 |
end |
741 | 745 | |
742 | 746 |
def value_join_alias(custom_field) |
lib/tasks/migrate_from_mantis.rake | ||
---|---|---|
52 | 52 |
TRACKER_BUG = Tracker.find_by_position(1) |
53 | 53 |
TRACKER_FEATURE = Tracker.find_by_position(2) |
54 | 54 | |
55 |
roles = Role.where(:builtin => 0).order('position ASC').all
|
|
55 |
roles = Role.where(:builtin => 0).order(:position).all
|
|
56 | 56 |
manager_role = roles[0] |
57 | 57 |
developer_role = roles[1] |
58 | 58 |
DEFAULT_ROLE = roles.last |
lib/tasks/migrate_from_trac.rake | ||
---|---|---|
60 | 60 |
'patch' =>TRACKER_FEATURE |
61 | 61 |
} |
62 | 62 | |
63 |
roles = Role.where(:builtin => 0).order('position ASC').all
|
|
63 |
roles = Role.where(:builtin => 0).order(:position).all
|
|
64 | 64 |
manager_role = roles[0] |
65 | 65 |
developer_role = roles[1] |
66 | 66 |
DEFAULT_ROLE = roles.last |
test/unit/user_test.rb | ||
---|---|---|
1051 | 1051 |
end |
1052 | 1052 | |
1053 | 1053 |
def test_own_account_deletable_should_be_false_for_a_single_admin |
1054 |
User.where(["admin = ? AND id <> ?", true, 1]).delete_all
|
|
1054 |
User.where(["id <> ?", 1]).where(:admin => true).delete_all
|
|
1055 | 1055 | |
1056 | 1056 |
with_settings :unsubscribe => '1' do |
1057 | 1057 |
assert_equal false, User.find(1).own_account_deletable? |