~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/xml.py

  • Committer: Martin Pool
  • Date: 2005-09-06 02:26:28 UTC
  • Revision ID: mbp@sourcefrog.net-20050906022628-66d65f0feb4a9e80
- implement version 5 xml storage, and tests

  This stores files identified by the version that introduced the 
  text, and the version that introduced the name.  Entry kinds are
  given by the xml tag not an explicit kind field.

Show diffs side-by-side

added added

removed removed

Lines of Context:
30
30
 
31
31
from bzrlib.inventory import ROOT_ID, Inventory, InventoryEntry
32
32
from bzrlib.revision import Revision, RevisionReference        
 
33
from bzrlib.errors import BzrError
33
34
 
34
35
 
35
36
class Serializer(object):
58
59
 
59
60
 
60
61
class _Serializer_v4(Serializer):
61
 
    """Version 0.0.4 serializer"""
 
62
    """Version 0.0.4 serializer
 
63
 
 
64
    You should use the serialzer_v4 singleton."""
62
65
    
63
66
    __slots__ = []
64
67
    
176
179
        
177
180
        # <changeset> is deprecated...
178
181
        if elt.tag not in ('revision', 'changeset'):
179
 
            raise bzrlib.errors.BzrError("unexpected tag in revision file: %r" % elt)
 
182
            raise BzrError("unexpected tag in revision file: %r" % elt)
180
183
 
181
184
        rev = Revision(committer = elt.get('committer'),
182
185
                       timestamp = float(elt.get('timestamp')),
216
219
 
217
220
 
218
221
 
 
222
class _Serializer_v5(Serializer):
 
223
    """Version 5 serializer
 
224
 
 
225
    You should use the serialzer_v5 singleton."""
 
226
    
 
227
    __slots__ = []
 
228
    
 
229
    def _pack_inventory(self, inv):
 
230
        """Convert to XML Element"""
 
231
        e = Element('inventory')
 
232
        e.text = '\n'
 
233
        if inv.root.file_id not in (None, ROOT_ID):
 
234
            e.set('file_id', inv.root.file_id)
 
235
        for path, ie in inv.iter_entries():
 
236
            e.append(self._pack_entry(ie))
 
237
        return e
 
238
 
 
239
 
 
240
    def _pack_entry(self, ie):
 
241
        """Convert InventoryEntry to XML element"""
 
242
        e = Element('entry')
 
243
        e.set('name', ie.name)
 
244
        e.set('file_id', ie.file_id)
 
245
        e.set('kind', ie.kind)
 
246
 
 
247
        if ie.text_size != None:
 
248
            e.set('text_size', '%d' % ie.text_size)
 
249
 
 
250
        for f in ['text_version', 'text_sha1', 'entry_version']:
 
251
            v = getattr(ie, f)
 
252
            if v != None:
 
253
                e.set(f, v)
 
254
 
 
255
        # to be conservative, we don't externalize the root pointers
 
256
        # for now, leaving them as null in the xml form.  in a future
 
257
        # version it will be implied by nested elements.
 
258
        if ie.parent_id != ROOT_ID:
 
259
            assert isinstance(ie.parent_id, basestring)
 
260
            e.set('parent_id', ie.parent_id)
 
261
 
 
262
        e.tail = '\n'
 
263
 
 
264
        return e
 
265
 
 
266
 
 
267
    def _pack_revision(self, rev):
 
268
        """Revision object -> xml tree"""
 
269
        root = Element('revision',
 
270
                       committer = rev.committer,
 
271
                       timestamp = '%.9f' % rev.timestamp,
 
272
                       revision_id = rev.revision_id,
 
273
                       inventory_id = rev.inventory_id,
 
274
                       inventory_sha1 = rev.inventory_sha1,
 
275
                       )
 
276
        if rev.timezone:
 
277
            root.set('timezone', str(rev.timezone))
 
278
        root.text = '\n'
 
279
 
 
280
        msg = SubElement(root, 'message')
 
281
        msg.text = rev.message
 
282
        msg.tail = '\n'
 
283
 
 
284
        if rev.parents:
 
285
            pelts = SubElement(root, 'parents')
 
286
            pelts.tail = pelts.text = '\n'
 
287
            for rr in rev.parents:
 
288
                assert isinstance(rr, RevisionReference)
 
289
                p = SubElement(pelts, 'revision_ref')
 
290
                p.tail = '\n'
 
291
                assert rr.revision_id
 
292
                p.set('revision_id', rr.revision_id)
 
293
 
 
294
        return root
 
295
 
 
296
    
 
297
 
 
298
    def _unpack_inventory(self, elt):
 
299
        """Construct from XML Element
 
300
        """
 
301
        assert elt.tag == 'inventory'
 
302
        root_id = elt.get('file_id') or ROOT_ID
 
303
        inv = Inventory(root_id)
 
304
        for e in elt:
 
305
            ie = self._unpack_entry(e)
 
306
            if ie.parent_id == ROOT_ID:
 
307
                ie.parent_id = root_id
 
308
            inv.add(ie)
 
309
        return inv
 
310
 
 
311
 
 
312
    def _unpack_entry(self, elt):
 
313
        kind = elt.tag
 
314
        assert kind == 'directory' or kind == 'file'
 
315
 
 
316
        parent_id = elt.get('parent_id')
 
317
        if parent_id == None:
 
318
            parent_id = ROOT_ID
 
319
 
 
320
        ie = InventoryEntry(elt.get('file_id'),
 
321
                            elt.get('name'),
 
322
                            kind,
 
323
                            parent_id)
 
324
        ie.text_version = elt.get('text_version')
 
325
        ie.entry_version = elt.get('entry_version')
 
326
        ie.text_sha1 = elt.get('text_sha1')
 
327
        v = elt.get('text_size')
 
328
        ie.text_size = v and int(v)
 
329
 
 
330
        return ie
 
331
 
 
332
 
 
333
    def _unpack_revision(self, elt):
 
334
        """XML Element -> Revision object"""
 
335
        assert elt.tag == 'revision'
 
336
        
 
337
        rev = Revision(committer = elt.get('committer'),
 
338
                       timestamp = float(elt.get('timestamp')),
 
339
                       revision_id = elt.get('revision_id'),
 
340
                       inventory_id = elt.get('inventory_id'),
 
341
                       inventory_sha1 = elt.get('inventory_sha1')
 
342
                       )
 
343
 
 
344
        for p in elt.find('parents'):
 
345
            assert p.tag == 'revision_ref', \
 
346
                   "bad parent node tag %r" % p.tag
 
347
            rev_ref = RevisionReference(p.get('revision_id'))
 
348
            rev.parents.append(rev_ref)
 
349
 
 
350
        v = elt.get('timezone')
 
351
        rev.timezone = v and int(v)
 
352
 
 
353
        rev.message = elt.findtext('message') # text of <message>
 
354
        return rev
 
355
 
 
356
 
 
357
 
219
358
"""singleton instance"""
220
359
serializer_v4 = _Serializer_v4()
 
360
 
 
361
serializer_v5 = _Serializer_v5()