comparison mercurial/appendfile.py @ 4269:bdbfc2193524

appendfile: handle only changelog.i file
author Matt Mackall <mpm@selenic.com>
date Thu, 22 Mar 2007 20:10:46 -0500
parents eb081ba21eff
children
comparison
equal deleted inserted replaced
4268:eb081ba21eff 4269:bdbfc2193524
103 class appendopener(object): 103 class appendopener(object):
104 '''special opener for files that only read or append.''' 104 '''special opener for files that only read or append.'''
105 105
106 def __init__(self, opener): 106 def __init__(self, opener):
107 self.realopener = opener 107 self.realopener = opener
108 # key: file name, value: appendfile name 108 self.tmpname = None
109 self.tmpnames = {}
110 109
111 def __call__(self, name, mode='r'): 110 def __call__(self, name, mode='r'):
112 '''open file.''' 111 '''open file.'''
113 112 # only handle .i file
113 if not name.endswith("."):
114 return self.realopener(name, mode)
114 assert mode in 'ra+' 115 assert mode in 'ra+'
115 try: 116 try:
116 realfp = self.realopener(name, 'r') 117 realfp = self.realopener(name, 'r')
117 except IOError, err: 118 except IOError, err:
118 if err.errno != errno.ENOENT: raise 119 if err.errno != errno.ENOENT: raise
119 realfp = self.realopener(name, 'w+') 120 self.realfp = self.realopener(name, 'w+')
120 tmpname = self.tmpnames.get(name) 121 fp = appendfile(realfp, self.tmpname)
121 fp = appendfile(realfp, tmpname)
122 if tmpname is None: 122 if tmpname is None:
123 self.tmpnames[name] = fp.tmpname 123 self.tmpname = fp.tmpname
124 self.name = name
124 return fp 125 return fp
125 126
126 def writedata(self): 127 def writedata(self):
127 '''copy data from temp files to real files.''' 128 '''copy data from temp files to real files.'''
128 # write .d file before .i file. 129 if not self.tmpname:
129 tmpnames = self.tmpnames.items() 130 return
130 tmpnames.sort() 131 ifp = open(self.tmpname, 'rb')
131 for name, tmpname in tmpnames: 132 ofp = self.realopener(self.name, 'a')
132 ifp = open(tmpname, 'rb') 133 for chunk in util.filechunkiter(ifp):
133 ofp = self.realopener(name, 'a') 134 ofp.write(chunk)
134 for chunk in util.filechunkiter(ifp): 135 ifp.close()
135 ofp.write(chunk) 136 os.unlink(self.tmpname)
136 ifp.close() 137 ofp.close()
137 os.unlink(tmpname)
138 del self.tmpnames[name]
139 ofp.close()
140 138
141 def cleanup(self): 139 def cleanup(self):
142 '''delete temp files (this discards unwritten data!)''' 140 '''delete temp files (this discards unwritten data!)'''
143 for tmpname in self.tmpnames.values(): 141 if self.tmpname:
144 os.unlink(tmpname) 142 os.unlink(self.tmpname)
145 143
146 # files for changelog and manifest are in different appendopeners, so 144 # files for changelog and manifest are in different appendopeners, so
147 # not mixed up together. 145 # not mixed up together.
148 146
149 class appendchangelog(changelog.changelog, appendopener): 147 class appendchangelog(changelog.changelog, appendopener):