~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/smart/vfs.py

  • Committer: John Arbash Meinel
  • Date: 2005-09-15 21:35:53 UTC
  • mfrom: (907.1.57)
  • mto: (1393.2.1)
  • mto: This revision was merged to the branch mainline in revision 1396.
  • Revision ID: john@arbash-meinel.com-20050915213552-a6c83a5ef1e20897
(broken) Transport work is merged in. Tests do not pass yet.

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
 
        backing_bytes = self._backing_transport.get_bytes(relpath)
73
 
        return request.SuccessfulSmartServerResponse(('ok',), backing_bytes)
74
 
 
75
 
 
76
 
class AppendRequest(VfsRequest):
77
 
 
78
 
    def do(self, relpath, mode):
79
 
        self._relpath = relpath
80
 
        self._mode = _deserialise_optional_mode(mode)
81
 
    
82
 
    def do_body(self, body_bytes):
83
 
        old_length = self._backing_transport.append_bytes(
84
 
            self._relpath, body_bytes, self._mode)
85
 
        return request.SuccessfulSmartServerResponse(('appended', '%d' % old_length))
86
 
 
87
 
 
88
 
class DeleteRequest(VfsRequest):
89
 
 
90
 
    def do(self, relpath):
91
 
        self._backing_transport.delete(relpath)
92
 
        return request.SuccessfulSmartServerResponse(('ok', ))
93
 
 
94
 
 
95
 
class IterFilesRecursiveRequest(VfsRequest):
96
 
 
97
 
    def do(self, relpath):
98
 
        transport = self._backing_transport.clone(relpath)
99
 
        filenames = transport.iter_files_recursive()
100
 
        return request.SuccessfulSmartServerResponse(('names',) + tuple(filenames))
101
 
 
102
 
 
103
 
class ListDirRequest(VfsRequest):
104
 
 
105
 
    def do(self, relpath):
106
 
        filenames = self._backing_transport.list_dir(relpath)
107
 
        return request.SuccessfulSmartServerResponse(('names',) + tuple(filenames))
108
 
 
109
 
 
110
 
class MkdirRequest(VfsRequest):
111
 
 
112
 
    def do(self, relpath, mode):
113
 
        self._backing_transport.mkdir(relpath,
114
 
                                      _deserialise_optional_mode(mode))
115
 
        return request.SuccessfulSmartServerResponse(('ok',))
116
 
 
117
 
 
118
 
class MoveRequest(VfsRequest):
119
 
 
120
 
    def do(self, rel_from, rel_to):
121
 
        self._backing_transport.move(rel_from, rel_to)
122
 
        return request.SuccessfulSmartServerResponse(('ok',))
123
 
 
124
 
 
125
 
class PutRequest(VfsRequest):
126
 
 
127
 
    def do(self, relpath, mode):
128
 
        self._relpath = relpath
129
 
        self._mode = _deserialise_optional_mode(mode)
130
 
 
131
 
    def do_body(self, body_bytes):
132
 
        self._backing_transport.put_bytes(self._relpath, body_bytes, self._mode)
133
 
        return request.SuccessfulSmartServerResponse(('ok',))
134
 
 
135
 
 
136
 
class PutNonAtomicRequest(VfsRequest):
137
 
 
138
 
    def do(self, relpath, mode, create_parent, dir_mode):
139
 
        self._relpath = relpath
140
 
        self._dir_mode = _deserialise_optional_mode(dir_mode)
141
 
        self._mode = _deserialise_optional_mode(mode)
142
 
        # a boolean would be nicer XXX
143
 
        self._create_parent = (create_parent == 'T')
144
 
 
145
 
    def do_body(self, body_bytes):
146
 
        self._backing_transport.put_bytes_non_atomic(self._relpath,
147
 
                body_bytes,
148
 
                mode=self._mode,
149
 
                create_parent_dir=self._create_parent,
150
 
                dir_mode=self._dir_mode)
151
 
        return request.SuccessfulSmartServerResponse(('ok',))
152
 
 
153
 
 
154
 
class ReadvRequest(VfsRequest):
155
 
 
156
 
    def do(self, relpath):
157
 
        self._relpath = relpath
158
 
 
159
 
    def do_body(self, body_bytes):
160
 
        """accept offsets for a readv request."""
161
 
        offsets = self._deserialise_offsets(body_bytes)
162
 
        backing_bytes = ''.join(bytes for offset, bytes in
163
 
            self._backing_transport.readv(self._relpath, offsets))
164
 
        return request.SuccessfulSmartServerResponse(('readv',), backing_bytes)
165
 
 
166
 
    def _deserialise_offsets(self, text):
167
 
        # XXX: FIXME this should be on the protocol object.
168
 
        offsets = []
169
 
        for line in text.split('\n'):
170
 
            if not line:
171
 
                continue
172
 
            start, length = line.split(',')
173
 
            offsets.append((int(start), int(length)))
174
 
        return offsets
175
 
 
176
 
 
177
 
class RenameRequest(VfsRequest):
178
 
 
179
 
    def do(self, rel_from, rel_to):
180
 
        self._backing_transport.rename(rel_from, rel_to)
181
 
        return request.SuccessfulSmartServerResponse(('ok', ))
182
 
 
183
 
 
184
 
class RmdirRequest(VfsRequest):
185
 
 
186
 
    def do(self, relpath):
187
 
        self._backing_transport.rmdir(relpath)
188
 
        return request.SuccessfulSmartServerResponse(('ok', ))
189
 
 
190
 
 
191
 
class StatRequest(VfsRequest):
192
 
 
193
 
    def do(self, relpath):
194
 
        stat = self._backing_transport.stat(relpath)
195
 
        return request.SuccessfulSmartServerResponse(
196
 
            ('stat', str(stat.st_size), oct(stat.st_mode)))
197