##// END OF EJS Templates
scm: mercurial: add :order => 'id DESC' explicitly for MySQL test fails....
Toshi MARUYAMA -
r4971:0d63e9e8fde3
parent child
Show More
@@ -1,118 +1,125
1 # redMine - project management software
1 # redMine - project management software
2 # Copyright (C) 2006-2007 Jean-Philippe Lang
2 # Copyright (C) 2006-2007 Jean-Philippe Lang
3 #
3 #
4 # This program is free software; you can redistribute it and/or
4 # This program is free software; you can redistribute it and/or
5 # modify it under the terms of the GNU General Public License
5 # modify it under the terms of the GNU General Public License
6 # as published by the Free Software Foundation; either version 2
6 # as published by the Free Software Foundation; either version 2
7 # of the License, or (at your option) any later version.
7 # of the License, or (at your option) any later version.
8 #
8 #
9 # This program is distributed in the hope that it will be useful,
9 # This program is distributed in the hope that it will be useful,
10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 # GNU General Public License for more details.
12 # GNU General Public License for more details.
13 #
13 #
14 # You should have received a copy of the GNU General Public License
14 # You should have received a copy of the GNU General Public License
15 # along with this program; if not, write to the Free Software
15 # along with this program; if not, write to the Free Software
16 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
16 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17
17
18 require 'redmine/scm/adapters/mercurial_adapter'
18 require 'redmine/scm/adapters/mercurial_adapter'
19
19
20 class Repository::Mercurial < Repository
20 class Repository::Mercurial < Repository
21 # sort changesets by revision number
21 # sort changesets by revision number
22 has_many :changesets, :order => "#{Changeset.table_name}.id DESC", :foreign_key => 'repository_id'
22 has_many :changesets, :order => "#{Changeset.table_name}.id DESC", :foreign_key => 'repository_id'
23
23
24 attr_protected :root_url
24 attr_protected :root_url
25 validates_presence_of :url
25 validates_presence_of :url
26
26
27 FETCH_AT_ONCE = 100 # number of changesets to fetch at once
27 FETCH_AT_ONCE = 100 # number of changesets to fetch at once
28
28
29 ATTRIBUTE_KEY_NAMES = {
29 ATTRIBUTE_KEY_NAMES = {
30 "url" => "Root directory",
30 "url" => "Root directory",
31 }
31 }
32 def self.human_attribute_name(attribute_key_name)
32 def self.human_attribute_name(attribute_key_name)
33 ATTRIBUTE_KEY_NAMES[attribute_key_name] || super
33 ATTRIBUTE_KEY_NAMES[attribute_key_name] || super
34 end
34 end
35
35
36 def self.scm_adapter_class
36 def self.scm_adapter_class
37 Redmine::Scm::Adapters::MercurialAdapter
37 Redmine::Scm::Adapters::MercurialAdapter
38 end
38 end
39
39
40 def self.scm_name
40 def self.scm_name
41 'Mercurial'
41 'Mercurial'
42 end
42 end
43
43
44 def repo_log_encoding
44 def repo_log_encoding
45 'UTF-8'
45 'UTF-8'
46 end
46 end
47
47
48 # Returns the readable identifier for the given mercurial changeset
48 # Returns the readable identifier for the given mercurial changeset
49 def self.format_changeset_identifier(changeset)
49 def self.format_changeset_identifier(changeset)
50 "#{changeset.revision}:#{changeset.scmid}"
50 "#{changeset.revision}:#{changeset.scmid}"
51 end
51 end
52
52
53 # Returns the identifier for the given Mercurial changeset
53 # Returns the identifier for the given Mercurial changeset
54 def self.changeset_identifier(changeset)
54 def self.changeset_identifier(changeset)
55 changeset.scmid
55 changeset.scmid
56 end
56 end
57
57
58 def branches
58 def branches
59 nil
59 nil
60 end
60 end
61
61
62 def tags
62 def tags
63 nil
63 nil
64 end
64 end
65
65
66 def diff_format_revisions(cs, cs_to, sep=':')
66 def diff_format_revisions(cs, cs_to, sep=':')
67 super(cs, cs_to, ' ')
67 super(cs, cs_to, ' ')
68 end
68 end
69
69
70 # Finds and returns a revision with a number or the beginning of a hash
70 # Finds and returns a revision with a number or the beginning of a hash
71 def find_changeset_by_name(name)
71 def find_changeset_by_name(name)
72 return nil if name.nil? || name.empty?
72 return nil if name.nil? || name.empty?
73 if /[^\d]/ =~ name or name.to_s.size > 8
73 if /[^\d]/ =~ name or name.to_s.size > 8
74 e = changesets.find(:first, :conditions => ['scmid = ?', name.to_s])
74 e = changesets.find(:first, :conditions => ['scmid = ?', name.to_s])
75 else
75 else
76 e = changesets.find(:first, :conditions => ['revision = ?', name.to_s])
76 e = changesets.find(:first, :conditions => ['revision = ?', name.to_s])
77 end
77 end
78 return e if e
78 return e if e
79 changesets.find(:first, :conditions => ['scmid LIKE ?', "#{name}%"]) # last ditch
79 changesets.find(:first, :conditions => ['scmid LIKE ?', "#{name}%"]) # last ditch
80 end
80 end
81
81
82 # Returns the latest changesets for +path+; sorted by revision number
82 # Returns the latest changesets for +path+; sorted by revision number
83 # Default behavior is to search in cached changesets
83 # Default behavior is to search in cached changesets
84 #
85 # Because :order => 'id DESC' is defined at 'has_many',
86 # there is no need to set 'order'.
87 # But, MySQL test fails.
88 # Sqlite3 and PostgreSQL pass.
89 # Is this MySQL bug?
84 def latest_changesets(path, rev, limit=10)
90 def latest_changesets(path, rev, limit=10)
85 if path.blank?
91 if path.blank?
86 changesets.find(:all, :include => :user, :limit => limit)
92 changesets.find(:all, :include => :user, :limit => limit, :order => 'id DESC')
87 else
93 else
88 changesets.find(:all, :select => "DISTINCT #{Changeset.table_name}.*",
94 changesets.find(:all, :select => "DISTINCT #{Changeset.table_name}.*",
89 :joins => :changes,
95 :joins => :changes,
90 :conditions => ["#{Change.table_name}.path = ? OR #{Change.table_name}.path LIKE ? ESCAPE ?",
96 :conditions => ["#{Change.table_name}.path = ? OR #{Change.table_name}.path LIKE ? ESCAPE ?",
91 path.with_leading_slash,
97 path.with_leading_slash,
92 "#{path.with_leading_slash.gsub(/[%_\\]/) { |s| "\\#{s}" }}/%", '\\'],
98 "#{path.with_leading_slash.gsub(/[%_\\]/) { |s| "\\#{s}" }}/%", '\\'],
93 :include => :user, :limit => limit)
99 :include => :user, :limit => limit,
100 :order => "#{Changeset.table_name}.id DESC" )
94 end
101 end
95 end
102 end
96
103
97 def fetch_changesets
104 def fetch_changesets
98 scm_rev = scm.info.lastrev.revision.to_i
105 scm_rev = scm.info.lastrev.revision.to_i
99 db_rev = latest_changeset ? latest_changeset.revision.to_i : -1
106 db_rev = latest_changeset ? latest_changeset.revision.to_i : -1
100 return unless db_rev < scm_rev # already up-to-date
107 return unless db_rev < scm_rev # already up-to-date
101
108
102 logger.debug "Fetching changesets for repository #{url}" if logger
109 logger.debug "Fetching changesets for repository #{url}" if logger
103 (db_rev + 1).step(scm_rev, FETCH_AT_ONCE) do |i|
110 (db_rev + 1).step(scm_rev, FETCH_AT_ONCE) do |i|
104 transaction do
111 transaction do
105 scm.each_revision('', i, [i + FETCH_AT_ONCE - 1, scm_rev].min) do |re|
112 scm.each_revision('', i, [i + FETCH_AT_ONCE - 1, scm_rev].min) do |re|
106 cs = Changeset.create(:repository => self,
113 cs = Changeset.create(:repository => self,
107 :revision => re.revision,
114 :revision => re.revision,
108 :scmid => re.scmid,
115 :scmid => re.scmid,
109 :committer => re.author,
116 :committer => re.author,
110 :committed_on => re.time,
117 :committed_on => re.time,
111 :comments => re.message)
118 :comments => re.message)
112 re.paths.each { |e| cs.create_change(e) }
119 re.paths.each { |e| cs.create_change(e) }
113 end
120 end
114 end
121 end
115 end
122 end
116 self
123 self
117 end
124 end
118 end
125 end
General Comments 0
You need to be logged in to leave comments. Login now