1 # Copyright (C) 2006-2007 Jelmer Vernooij <jelmer@samba.org>
3 # This program is free software; you can redistribute it and/or modify
4 # it under the terms of the GNU General Public License as published by
5 # the Free Software Foundation; either version 2 of the License, or
6 # (at your option) any later version.
8 # This program is distributed in the hope that it will be useful,
9 # but WITHOUT ANY WARRANTY; without even the implied warranty of
10 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 # GNU General Public License for more details.
13 # You should have received a copy of the GNU General Public License
14 # along with this program; if not, write to the Free Software
15 # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17 """Branch property access and caching."""
19 from bzrlib.errors import NoSuchRevision
20 from bzrlib.trace import mutter
22 from svn.core import SubversionException, Pool
25 class BranchPropertyList:
26 def __init__(self, log, cachedb):
28 self.cachedb = cachedb
30 self.cachedb.executescript("""
31 create table if not exists branchprop (name text, value text, branchpath text, revnum integer);
32 create index if not exists branch_path_revnum on branchprop (branchpath, revnum);
33 create index if not exists branch_path_revnum_name on branchprop (branchpath, revnum, name);
38 def _get_dir_props(self, path, revnum):
39 assert isinstance(path, str)
40 path = path.lstrip("/")
43 (_, _, props) = self.log.transport.get_dir(path,
44 revnum, pool=self.pool)
45 except SubversionException, (_, num):
46 if num == svn.core.SVN_ERR_FS_NO_SUCH_REVISION:
47 raise NoSuchRevision(self, revnum)
52 def get_properties(self, path, origrevnum):
53 assert path is not None
54 assert isinstance(path, str)
55 assert isinstance(origrevnum, int) and origrevnum >= 0
56 revnum = self.log.find_latest_change(path, origrevnum)
57 assert revnum is not None, \
58 "can't find latest change for %r:%r" % (path, origrevnum)
60 if revnum == 0: # no properties are set in revision 0
64 for (name, value) in self.cachedb.execute("select name, value from branchprop where revnum=%d and branchpath='%s'" % (revnum, path)):
65 proplist[name] = value.encode("utf-8")
70 proplist = self._get_dir_props(path, revnum)
72 self.cachedb.execute("insert into branchprop (name, value, revnum, branchpath) values (?,?,?,?)", (name, proplist[name], revnum, path))
77 def get_property(self, path, revnum, name, default=None):
78 assert isinstance(revnum, int)
79 assert isinstance(path, str)
80 props = self.get_properties(path, revnum)
81 if props.has_key(name):
85 def get_property_diff(self, path, revnum, name):
86 """Returns the new lines that were added to a particular property."""
87 assert isinstance(path, str)
88 # If the path this property is set on didn't change, then
89 # the property can't have changed.
90 if not self.log.touches_path(path, revnum):
93 current = self.get_property(path, revnum, name, "")
94 (prev_path, prev_revnum) = self.log.get_previous(path, revnum)
95 if prev_path is None and prev_revnum == -1:
98 previous = self.get_property(prev_path.encode("utf-8"),
99 prev_revnum, name, "")
100 if len(previous) > len(current) or current[0:len(previous)] != previous:
101 mutter('original part changed for %r between %s:%d -> %s:%d' % (name, prev_path, prev_revnum, path, revnum))
103 return current[len(previous):]