1
# Copyright (C) 2008 Canonical Ltd
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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
17
"""Serializer object for CHK based inventory storage."""
19
from cStringIO import (
27
revision as _mod_revision,
33
class RIORevisionSerializer1(object):
34
"""Simple line-based revision serializer.
36
This writes simple key/value pairs for all elements on the revision,
37
each on a separate line and using colons to separate key and value. Newlines
38
are backslash-escaped where necessary.
40
The commit message is always serialized last and can span multiple lines.
43
def write_revision(self, rev, f):
44
decode_utf8 = cache_utf8.decode
47
revision_id = rev.revision_id
48
if isinstance(revision_id, str):
49
revision_id = decode_utf8(revision_id)
50
s.add("revision-id", revision_id)
51
s.add("timestamp", "%.3f" % rev.timestamp)
54
" ".join([decode_utf8(p) for p in rev.parent_ids]))
55
s.add("inventory-sha1", rev.inventory_sha1)
56
s.add("committer", rev.committer)
57
if rev.timezone is not None:
58
s.add("timezone", str(rev.timezone))
60
revprops_stanza = rio.Stanza()
61
for k, v in rev.properties.iteritems():
62
if isinstance(v, str):
64
revprops_stanza.add(decode_utf8(k), v)
65
s.add("properties", revprops_stanza.to_unicode())
66
s.add("message", rev.message)
69
def write_revision_to_string(self, rev):
71
self.write_revision(rev, f)
74
def read_revision(self, f):
75
s = rio.read_stanza(f)
76
rev = _mod_revision.Revision(None)
77
for (field, value) in s.iter_pairs():
78
if field == "revision-id":
79
rev.revision_id = cache_utf8.encode(value)
80
elif field == "parent-ids":
81
rev.parent_ids = [cache_utf8.encode(p) for p in value.split(" ")]
82
elif field == "committer":
84
elif field == "inventory-sha1":
85
rev.inventory_sha1 = value
86
elif field == "timezone":
87
rev.timezone = int(value)
88
elif field == "timestamp":
89
rev.timestamp = float(value)
90
elif field == "message":
92
elif field == "properties":
93
rev.properties = rio.read_stanza_unicode(
94
osutils.split_lines(value)).as_dict()
96
raise AssertionError("Unknown field %s" % field)
100
def read_revision_from_string(self, xml_string):
101
f = StringIO(xml_string)
102
rev = self.read_revision(f)
106
class CHKSerializerSubtree(RIORevisionSerializer1,xml6.Serializer_v6):
107
"""A CHKInventory based serializer that supports tree references"""
109
supported_kinds = set(['file', 'directory', 'symlink', 'tree-reference'])
111
revision_format_num = None
112
support_altered_by_hack = False
114
def _unpack_entry(self, elt):
116
if not kind in self.supported_kinds:
117
raise AssertionError('unsupported entry kind %s' % kind)
118
if kind == 'tree-reference':
119
file_id = elt.attrib['file_id']
120
name = elt.attrib['name']
121
parent_id = elt.attrib['parent_id']
122
revision = elt.get('revision')
123
reference_revision = elt.get('reference_revision')
124
return inventory.TreeReference(file_id, name, parent_id, revision,
127
return xml6.Serializer_v6._unpack_entry(self, elt)
129
def __init__(self, node_size, search_key_name):
130
self.maximum_size = node_size
131
self.search_key_name = search_key_name
134
class CHKSerializer(RIORevisionSerializer1,xml5.Serializer_v5):
135
"""A CHKInventory based serializer with 'plain' behaviour."""
138
revision_format_num = None
139
support_altered_by_hack = False
141
def __init__(self, node_size, search_key_name):
142
self.maximum_size = node_size
143
self.search_key_name = search_key_name
146
chk_serializer_255_bigpage = CHKSerializer(65536, 'hash-255-way')