/brz/remove-bazaar

To get this branch, use:
bzr branch http://gegoxaren.bato24.eu/bzr/brz/remove-bazaar
2018.5.4 by Andrew Bennetts
Split smart server VFS logic out into a new file, and start using the command pattern in the SmartServerRequestHandler.
1
# Copyright (C) 2006 Canonical Ltd
2
#
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.
7
#
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.
12
#
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
16
17
"""VFS operations for the smart server.
18
19
This module defines the smart server methods that are low-level file operations
20
-- i.e. methods that operate directly on files and directories, rather than
21
higher-level concepts like branches and revisions.
2018.5.19 by Andrew Bennetts
Add docstrings to all the new modules, and a few other places.
22
23
These methods, plus 'hello' and 'get_bundle', are version 1 of the smart server
24
protocol, as implemented in bzr 0.11 and later.
2018.5.4 by Andrew Bennetts
Split smart server VFS logic out into a new file, and start using the command pattern in the SmartServerRequestHandler.
25
"""
26
2018.5.21 by Andrew Bennetts
Move bzrlib.transport.smart to bzrlib.smart
27
from bzrlib.smart import request
2018.5.4 by Andrew Bennetts
Split smart server VFS logic out into a new file, and start using the command pattern in the SmartServerRequestHandler.
28
29
2018.5.17 by Andrew Bennetts
Paramaterise the commands handled by SmartServerRequestHandler.
30
# vfs_commands is the set of commands handlers for the version 1 protocol.
31
vfs_commands = request.version_one_commands.copy()
2018.5.4 by Andrew Bennetts
Split smart server VFS logic out into a new file, and start using the command pattern in the SmartServerRequestHandler.
32
33
def register_command(command):
34
    vfs_commands[command.method] = command
35
36
37
def _deserialise_optional_mode(mode):
38
    # XXX: FIXME this should be on the protocol object.  Later protocol versions
39
    # might serialise modes differently.
40
    if mode == '':
41
        return None
42
    else:
43
        return int(mode)
44
45
46
class HasRequest(request.SmartServerRequest):
47
48
    method = 'has'
49
50
    def do(self, relpath):
51
        r = self._backing_transport.has(relpath) and 'yes' or 'no'
2018.5.16 by Andrew Bennetts
Move SmartServerResponse to smart/request.py, untangling more import dependencies.
52
        return request.SmartServerResponse((r,))
2018.5.4 by Andrew Bennetts
Split smart server VFS logic out into a new file, and start using the command pattern in the SmartServerRequestHandler.
53
register_command(HasRequest)
54
55
56
class GetRequest(request.SmartServerRequest):
57
58
    method = 'get'
59
60
    def do(self, relpath):
61
        backing_bytes = self._backing_transport.get_bytes(relpath)
2018.5.16 by Andrew Bennetts
Move SmartServerResponse to smart/request.py, untangling more import dependencies.
62
        return request.SmartServerResponse(('ok',), backing_bytes)
2018.5.4 by Andrew Bennetts
Split smart server VFS logic out into a new file, and start using the command pattern in the SmartServerRequestHandler.
63
register_command(GetRequest)
64
65
66
class AppendRequest(request.SmartServerRequest):
67
68
    method = 'append'
69
70
    def do(self, relpath, mode):
71
        self._relpath = relpath
72
        self._mode = _deserialise_optional_mode(mode)
73
    
2018.5.5 by Andrew Bennetts
Pass body_bytes directly to SmartServerRequest.do_body
74
    def do_body(self, body_bytes):
2018.5.4 by Andrew Bennetts
Split smart server VFS logic out into a new file, and start using the command pattern in the SmartServerRequestHandler.
75
        old_length = self._backing_transport.append_bytes(
2018.5.5 by Andrew Bennetts
Pass body_bytes directly to SmartServerRequest.do_body
76
            self._relpath, body_bytes, self._mode)
2018.5.16 by Andrew Bennetts
Move SmartServerResponse to smart/request.py, untangling more import dependencies.
77
        return request.SmartServerResponse(('appended', '%d' % old_length))
2018.5.4 by Andrew Bennetts
Split smart server VFS logic out into a new file, and start using the command pattern in the SmartServerRequestHandler.
78
79
register_command(AppendRequest)
80
81
82
class DeleteRequest(request.SmartServerRequest):
83
84
    method = 'delete'
85
86
    def do(self, relpath):
87
        self._backing_transport.delete(relpath)
2018.5.16 by Andrew Bennetts
Move SmartServerResponse to smart/request.py, untangling more import dependencies.
88
        return request.SmartServerResponse(('ok', ))
2018.5.4 by Andrew Bennetts
Split smart server VFS logic out into a new file, and start using the command pattern in the SmartServerRequestHandler.
89
register_command(DeleteRequest)
90
91
92
class IterFilesRecursive(request.SmartServerRequest):
93
94
    method = 'iter_files_recursive'
95
96
    def do(self, relpath):
97
        transport = self._backing_transport.clone(relpath)
98
        filenames = transport.iter_files_recursive()
2018.5.16 by Andrew Bennetts
Move SmartServerResponse to smart/request.py, untangling more import dependencies.
99
        return request.SmartServerResponse(('names',) + tuple(filenames))
2018.5.4 by Andrew Bennetts
Split smart server VFS logic out into a new file, and start using the command pattern in the SmartServerRequestHandler.
100
register_command(IterFilesRecursive)
101
102
103
class ListDirRequest(request.SmartServerRequest):
104
105
    method = 'list_dir'
106
107
    def do(self, relpath):
108
        filenames = self._backing_transport.list_dir(relpath)
2018.5.16 by Andrew Bennetts
Move SmartServerResponse to smart/request.py, untangling more import dependencies.
109
        return request.SmartServerResponse(('names',) + tuple(filenames))
2018.5.4 by Andrew Bennetts
Split smart server VFS logic out into a new file, and start using the command pattern in the SmartServerRequestHandler.
110
register_command(ListDirRequest)
111
112
113
class MkdirCommand(request.SmartServerRequest):
114
115
    method = 'mkdir'
116
117
    def do(self, relpath, mode):
118
        self._backing_transport.mkdir(relpath,
119
                                      _deserialise_optional_mode(mode))
2018.5.16 by Andrew Bennetts
Move SmartServerResponse to smart/request.py, untangling more import dependencies.
120
        return request.SmartServerResponse(('ok',))
2018.5.4 by Andrew Bennetts
Split smart server VFS logic out into a new file, and start using the command pattern in the SmartServerRequestHandler.
121
register_command(MkdirCommand)
122
123
124
class MoveCommand(request.SmartServerRequest):
125
126
    method = 'move'
127
128
    def do(self, rel_from, rel_to):
129
        self._backing_transport.move(rel_from, rel_to)
2018.5.16 by Andrew Bennetts
Move SmartServerResponse to smart/request.py, untangling more import dependencies.
130
        return request.SmartServerResponse(('ok',))
2018.5.4 by Andrew Bennetts
Split smart server VFS logic out into a new file, and start using the command pattern in the SmartServerRequestHandler.
131
register_command(MoveCommand)
132
133
134
class PutCommand(request.SmartServerRequest):
135
136
    method = 'put'
137
138
    def do(self, relpath, mode):
139
        self._relpath = relpath
140
        self._mode = _deserialise_optional_mode(mode)
141
2018.5.5 by Andrew Bennetts
Pass body_bytes directly to SmartServerRequest.do_body
142
    def do_body(self, body_bytes):
143
        self._backing_transport.put_bytes(self._relpath, body_bytes, self._mode)
2018.5.16 by Andrew Bennetts
Move SmartServerResponse to smart/request.py, untangling more import dependencies.
144
        return request.SmartServerResponse(('ok',))
2018.5.4 by Andrew Bennetts
Split smart server VFS logic out into a new file, and start using the command pattern in the SmartServerRequestHandler.
145
register_command(PutCommand)
146
147
148
class PutNonAtomicCommand(request.SmartServerRequest):
149
150
    method = 'put_non_atomic'
151
152
    def do(self, relpath, mode, create_parent, dir_mode):
153
        self._relpath = relpath
154
        self._dir_mode = _deserialise_optional_mode(dir_mode)
155
        self._mode = _deserialise_optional_mode(mode)
156
        # a boolean would be nicer XXX
157
        self._create_parent = (create_parent == 'T')
158
2018.5.5 by Andrew Bennetts
Pass body_bytes directly to SmartServerRequest.do_body
159
    def do_body(self, body_bytes):
2018.5.4 by Andrew Bennetts
Split smart server VFS logic out into a new file, and start using the command pattern in the SmartServerRequestHandler.
160
        self._backing_transport.put_bytes_non_atomic(self._relpath,
2018.5.5 by Andrew Bennetts
Pass body_bytes directly to SmartServerRequest.do_body
161
                body_bytes,
2018.5.4 by Andrew Bennetts
Split smart server VFS logic out into a new file, and start using the command pattern in the SmartServerRequestHandler.
162
                mode=self._mode,
163
                create_parent_dir=self._create_parent,
164
                dir_mode=self._dir_mode)
2018.5.16 by Andrew Bennetts
Move SmartServerResponse to smart/request.py, untangling more import dependencies.
165
        return request.SmartServerResponse(('ok',))
2018.5.4 by Andrew Bennetts
Split smart server VFS logic out into a new file, and start using the command pattern in the SmartServerRequestHandler.
166
register_command(PutNonAtomicCommand)
167
168
169
class ReadvCommand(request.SmartServerRequest):
170
171
    method = 'readv'
172
173
    def do(self, relpath):
174
        self._relpath = relpath
175
2018.5.5 by Andrew Bennetts
Pass body_bytes directly to SmartServerRequest.do_body
176
    def do_body(self, body_bytes):
2018.5.4 by Andrew Bennetts
Split smart server VFS logic out into a new file, and start using the command pattern in the SmartServerRequestHandler.
177
        """accept offsets for a readv request."""
2018.5.5 by Andrew Bennetts
Pass body_bytes directly to SmartServerRequest.do_body
178
        offsets = self._deserialise_offsets(body_bytes)
2018.5.4 by Andrew Bennetts
Split smart server VFS logic out into a new file, and start using the command pattern in the SmartServerRequestHandler.
179
        backing_bytes = ''.join(bytes for offset, bytes in
180
            self._backing_transport.readv(self._relpath, offsets))
2018.5.16 by Andrew Bennetts
Move SmartServerResponse to smart/request.py, untangling more import dependencies.
181
        return request.SmartServerResponse(('readv',), backing_bytes)
2018.5.4 by Andrew Bennetts
Split smart server VFS logic out into a new file, and start using the command pattern in the SmartServerRequestHandler.
182
183
    def _deserialise_offsets(self, text):
184
        # XXX: FIXME this should be on the protocol object.
185
        offsets = []
186
        for line in text.split('\n'):
187
            if not line:
188
                continue
189
            start, length = line.split(',')
190
            offsets.append((int(start), int(length)))
191
        return offsets
192
register_command(ReadvCommand)
193
194
195
class RenameCommand(request.SmartServerRequest):
196
197
    method = 'rename'
198
199
    def do(self, rel_from, rel_to):
200
        self._backing_transport.rename(rel_from, rel_to)
2018.5.16 by Andrew Bennetts
Move SmartServerResponse to smart/request.py, untangling more import dependencies.
201
        return request.SmartServerResponse(('ok', ))
2018.5.4 by Andrew Bennetts
Split smart server VFS logic out into a new file, and start using the command pattern in the SmartServerRequestHandler.
202
register_command(RenameCommand)
203
204
205
class RmdirCommand(request.SmartServerRequest):
206
207
    method = 'rmdir'
208
209
    def do(self, relpath):
210
        self._backing_transport.rmdir(relpath)
2018.5.16 by Andrew Bennetts
Move SmartServerResponse to smart/request.py, untangling more import dependencies.
211
        return request.SmartServerResponse(('ok', ))
2018.5.4 by Andrew Bennetts
Split smart server VFS logic out into a new file, and start using the command pattern in the SmartServerRequestHandler.
212
register_command(RmdirCommand)
213
214
215
class StatCommand(request.SmartServerRequest):
216
217
    method = 'stat'
218
219
    def do(self, relpath):
220
        stat = self._backing_transport.stat(relpath)
2018.5.16 by Andrew Bennetts
Move SmartServerResponse to smart/request.py, untangling more import dependencies.
221
        return request.SmartServerResponse(
2018.5.4 by Andrew Bennetts
Split smart server VFS logic out into a new file, and start using the command pattern in the SmartServerRequestHandler.
222
            ('stat', str(stat.st_size), oct(stat.st_mode)))
223
register_command(StatCommand)
224