~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/smart/vfs.py

  • Committer: John Arbash Meinel
  • Date: 2006-10-16 01:25:46 UTC
  • mfrom: (2071 +trunk)
  • mto: This revision was merged to the branch mainline in revision 2080.
  • Revision ID: john@arbash-meinel.com-20061016012546-d01a0740671b4d73
[merge] bzr.dev

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
# Copyright (C) 2006, 2007 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
 
higher-level concepts like branches and revisions.
21
 
 
22
 
These methods, plus 'hello' and 'get_bundle', are version 1 of the smart server
23
 
protocol, as implemented in bzr 0.11 and later.
24
 
"""
25
 
 
26
 
import os
27
 
 
28
 
from bzrlib import errors
29
 
from bzrlib.smart import request
30
 
 
31
 
 
32
 
def _deserialise_optional_mode(mode):
33
 
    # XXX: FIXME this should be on the protocol object.  Later protocol versions
34
 
    # might serialise modes differently.
35
 
    if mode == '':
36
 
        return None
37
 
    else:
38
 
        return int(mode)
39
 
 
40
 
 
41
 
def vfs_enabled():
42
 
    """Is the VFS enabled ?
43
 
 
44
 
    the VFS is disabled when the BZR_NO_SMART_VFS environment variable is set.
45
 
 
46
 
    :return: True if it is enabled.
47
 
    """
48
 
    return not 'BZR_NO_SMART_VFS' in os.environ
49
 
 
50
 
 
51
 
class VfsRequest(request.SmartServerRequest):
52
 
    """Base class for VFS requests.
53
 
    
54
 
    VFS requests are disabled if vfs_enabled() returns False.
55
 
    """
56
 
 
57
 
    def _check_enabled(self):
58
 
        if not vfs_enabled():
59
 
            raise errors.DisabledMethod(self.__class__.__name__)
60
 
 
61
 
 
62
 
class HasRequest(VfsRequest):
63
 
 
64
 
    def do(self, relpath):
65
 
        r = self._backing_transport.has(relpath) and 'yes' or 'no'
66
 
        return request.SuccessfulSmartServerResponse((r,))
67
 
 
68
 
 
69
 
class GetRequest(VfsRequest):
70
 
 
71
 
    def do(self, relpath):
72
 
        try:
73
 
            backing_bytes = self._backing_transport.get_bytes(relpath)
74
 
        except errors.ReadError:
75
 
            # cannot read the file
76
 
            return request.FailedSmartServerResponse(('ReadError', ))
77
 
        except errors.PermissionDenied:
78
 
            return request.FailedSmartServerResponse(('PermissionDenied',))
79
 
        return request.SuccessfulSmartServerResponse(('ok',), backing_bytes)
80
 
 
81
 
 
82
 
class AppendRequest(VfsRequest):
83
 
 
84
 
    def do(self, relpath, mode):
85
 
        self._relpath = relpath
86
 
        self._mode = _deserialise_optional_mode(mode)
87
 
    
88
 
    def do_body(self, body_bytes):
89
 
        old_length = self._backing_transport.append_bytes(
90
 
            self._relpath, body_bytes, self._mode)
91
 
        return request.SuccessfulSmartServerResponse(('appended', '%d' % old_length))
92
 
 
93
 
 
94
 
class DeleteRequest(VfsRequest):
95
 
 
96
 
    def do(self, relpath):
97
 
        self._backing_transport.delete(relpath)
98
 
        return request.SuccessfulSmartServerResponse(('ok', ))
99
 
 
100
 
 
101
 
class IterFilesRecursiveRequest(VfsRequest):
102
 
 
103
 
    def do(self, relpath):
104
 
        transport = self._backing_transport.clone(relpath)
105
 
        filenames = transport.iter_files_recursive()
106
 
        return request.SuccessfulSmartServerResponse(('names',) + tuple(filenames))
107
 
 
108
 
 
109
 
class ListDirRequest(VfsRequest):
110
 
 
111
 
    def do(self, relpath):
112
 
        filenames = self._backing_transport.list_dir(relpath)
113
 
        return request.SuccessfulSmartServerResponse(('names',) + tuple(filenames))
114
 
 
115
 
 
116
 
class MkdirRequest(VfsRequest):
117
 
 
118
 
    def do(self, relpath, mode):
119
 
        self._backing_transport.mkdir(relpath,
120
 
                                      _deserialise_optional_mode(mode))
121
 
        return request.SuccessfulSmartServerResponse(('ok',))
122
 
 
123
 
 
124
 
class MoveRequest(VfsRequest):
125
 
 
126
 
    def do(self, rel_from, rel_to):
127
 
        self._backing_transport.move(rel_from, rel_to)
128
 
        return request.SuccessfulSmartServerResponse(('ok',))
129
 
 
130
 
 
131
 
class PutRequest(VfsRequest):
132
 
 
133
 
    def do(self, relpath, mode):
134
 
        self._relpath = relpath
135
 
        self._mode = _deserialise_optional_mode(mode)
136
 
 
137
 
    def do_body(self, body_bytes):
138
 
        self._backing_transport.put_bytes(self._relpath, body_bytes, self._mode)
139
 
        return request.SuccessfulSmartServerResponse(('ok',))
140
 
 
141
 
 
142
 
class PutNonAtomicRequest(VfsRequest):
143
 
 
144
 
    def do(self, relpath, mode, create_parent, dir_mode):
145
 
        self._relpath = relpath
146
 
        self._dir_mode = _deserialise_optional_mode(dir_mode)
147
 
        self._mode = _deserialise_optional_mode(mode)
148
 
        # a boolean would be nicer XXX
149
 
        self._create_parent = (create_parent == 'T')
150
 
 
151
 
    def do_body(self, body_bytes):
152
 
        self._backing_transport.put_bytes_non_atomic(self._relpath,
153
 
                body_bytes,
154
 
                mode=self._mode,
155
 
                create_parent_dir=self._create_parent,
156
 
                dir_mode=self._dir_mode)
157
 
        return request.SuccessfulSmartServerResponse(('ok',))
158
 
 
159
 
 
160
 
class ReadvRequest(VfsRequest):
161
 
 
162
 
    def do(self, relpath):
163
 
        self._relpath = relpath
164
 
 
165
 
    def do_body(self, body_bytes):
166
 
        """accept offsets for a readv request."""
167
 
        offsets = self._deserialise_offsets(body_bytes)
168
 
        backing_bytes = ''.join(bytes for offset, bytes in
169
 
            self._backing_transport.readv(self._relpath, offsets))
170
 
        return request.SuccessfulSmartServerResponse(('readv',), backing_bytes)
171
 
 
172
 
    def _deserialise_offsets(self, text):
173
 
        # XXX: FIXME this should be on the protocol object.
174
 
        offsets = []
175
 
        for line in text.split('\n'):
176
 
            if not line:
177
 
                continue
178
 
            start, length = line.split(',')
179
 
            offsets.append((int(start), int(length)))
180
 
        return offsets
181
 
 
182
 
 
183
 
class RenameRequest(VfsRequest):
184
 
 
185
 
    def do(self, rel_from, rel_to):
186
 
        self._backing_transport.rename(rel_from, rel_to)
187
 
        return request.SuccessfulSmartServerResponse(('ok', ))
188
 
 
189
 
 
190
 
class RmdirRequest(VfsRequest):
191
 
 
192
 
    def do(self, relpath):
193
 
        self._backing_transport.rmdir(relpath)
194
 
        return request.SuccessfulSmartServerResponse(('ok', ))
195
 
 
196
 
 
197
 
class StatRequest(VfsRequest):
198
 
 
199
 
    def do(self, relpath):
200
 
        stat = self._backing_transport.stat(relpath)
201
 
        return request.SuccessfulSmartServerResponse(
202
 
            ('stat', str(stat.st_size), oct(stat.st_mode)))
203