Versioning extras, including account/container "time machine".
[pithos] / pithos / backends / base.py
1 # Copyright 2011 GRNET S.A. All rights reserved.
2
3 # Redistribution and use in source and binary forms, with or
4 # without modification, are permitted provided that the following
5 # conditions are met:
6
7 #   1. Redistributions of source code must retain the above
8 #      copyright notice, this list of conditions and the following
9 #      disclaimer.
10
11 #   2. Redistributions in binary form must reproduce the above
12 #      copyright notice, this list of conditions and the following
13 #      disclaimer in the documentation and/or other materials
14 #      provided with the distribution.
15
16 # THIS SOFTWARE IS PROVIDED BY GRNET S.A. ``AS IS'' AND ANY EXPRESS
17 # OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 # WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
19 # PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL GRNET S.A OR
20 # CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21 # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22 # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
23 # USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
24 # AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25 # LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
26 # ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
27 # POSSIBILITY OF SUCH DAMAGE.
28
29 # The views and conclusions contained in the software and
30 # documentation are those of the authors and should not be
31 # interpreted as representing official policies, either expressed
32 # or implied, of GRNET S.A.
33
34 class BaseBackend(object):
35     """Abstract backend class that serves as a reference for actual implementations.
36     
37     The purpose of the backend is to provide the necessary functions for handling data
38     and metadata. It is responsible for the actual storage and retrieval of information.
39     
40     Note that the account level is always valid as it is checked from another subsystem.
41     
42     The following variables should be available:
43         'hash_algorithm': Suggested is 'sha256'
44         'block_size': Suggested is 4MB
45     """
46     
47     def delete_account(self, user, account):
48         """Delete the account with the given name.
49         
50         Raises:
51             IndexError: Account is not empty
52         """
53         return
54     
55     def get_account_meta(self, user, account, until=None):
56         """Return a dictionary with the account metadata.
57         
58         The keys returned are all user-defined, except:
59             'name': The account name
60             'count': The number of containers (or 0)
61             'bytes': The total data size (or 0)
62             'modified': Last modification timestamp (overall)
63             'until_timestamp': Last modification until the timestamp provided
64         """
65         return {}
66     
67     def update_account_meta(self, user, account, meta, replace=False):
68         """Update the metadata associated with the account.
69         
70         Parameters:
71             'meta': Dictionary with metadata to update
72             'replace': Replace instead of update
73         """
74         return
75     
76     def list_containers(self, user, account, marker=None, limit=10000, until=None):
77         """Return a list of container (name, version_id) tuples existing under an account.
78         
79         Parameters:
80             'marker': Start list from the next item after 'marker'
81             'limit': Number of containers to return
82         """
83         return []
84     
85     def put_container(self, user, account, container):
86         """Create a new container with the given name.
87         
88         Raises:
89             NameError: Container already exists
90         """
91         return
92     
93     def delete_container(self, user, account, container):
94         """Delete the container with the given name.
95         
96         Raises:
97             NameError: Container does not exist
98             IndexError: Container is not empty
99         """
100         return
101     
102     def get_container_meta(self, user, account, container, until=None):
103         """Return a dictionary with the container metadata.
104         
105         The keys returned are all user-defined, except:
106             'name': The container name
107             'count': The number of objects
108             'bytes': The total data size
109             'modified': Last modification timestamp (overall)
110             'until_timestamp': Last modification until the timestamp provided
111         
112         Raises:
113             NameError: Container does not exist
114         """
115         return {}
116     
117     def update_container_meta(self, user, account, container, meta, replace=False):
118         """Update the metadata associated with the container.
119         
120         Parameters:
121             'meta': Dictionary with metadata to update
122             'replace': Replace instead of update
123         
124         Raises:
125             NameError: Container does not exist
126         """
127         return
128     
129     def list_objects(self, user, account, container, prefix='', delimiter=None, marker=None, limit=10000, virtual=True, keys=[], until=None):
130         """Return a list of object (name, version_id) tuples existing under a container.
131         
132         Parameters:
133             'prefix': List objects starting with 'prefix'
134             'delimiter': Return unique names before 'delimiter' and after 'prefix'
135             'marker': Start list from the next item after 'marker'
136             'limit': Number of objects to return
137             'virtual': If not set, the result will only include names starting\
138                        with 'prefix' and ending without a 'delimiter' or with\
139                        the first occurance of the 'delimiter' after 'prefix'.\
140                        If set, the result will include all names after 'prefix',\
141                        up to and including the 'delimiter' if it is found
142             'keys': Include objects that have meta with the keys in the list
143         
144         Raises:
145             NameError: Container does not exist
146         """
147         return []
148     
149     def list_object_meta(self, user, account, container, until=None):
150         """Return a list with all the container's object meta keys.
151         
152         Raises:
153             NameError: Container does not exist
154         """
155         return []
156     
157     def get_object_meta(self, user, account, container, name, version=None):
158         """Return a dictionary with the object metadata.
159         
160         The keys returned are all user-defined, except:
161             'name': The object name
162             'bytes': The total data size
163             'modified': Last modification timestamp (overall)
164             'version': The version identifier
165             'version_timestamp': The version's modification timestamp
166         
167         Raises:
168             NameError: Container/object does not exist
169             IndexError: Version does not exist
170         """
171         return {}
172     
173     def update_object_meta(self, user, account, container, name, meta, replace=False):
174         """Update the metadata associated with the object.
175         
176         Parameters:
177             'meta': Dictionary with metadata to update.
178             'replace': Replace instead of update
179         
180         Raises:
181             NameError: Container/object does not exist
182         """
183         return
184     
185     def get_object_hashmap(self, user, account, container, name, version=None):
186         """Return the object's size and a list with partial hashes.
187         
188         Raises:
189             NameError: Container/object does not exist
190             IndexError: Version does not exist
191         """
192         return 0, []
193     
194     def update_object_hashmap(self, user, account, container, name, size, hashmap, meta={}, replace_meta=False):
195         """Create/update an object with the specified size and partial hashes.
196         
197         Raises:
198             NameError: Container does not exist
199         """
200         return
201     
202     def copy_object(self, user, account, src_container, src_name, dest_container, dest_name, dest_meta={}, replace_meta=False, src_version=None):
203         """Copy an object's data and metadata.
204         
205         Parameters:
206             'dest_meta': Dictionary with metadata to changes from source to destination
207             'replace_meta': Replace metadata instead of update
208             'src_version': Copy from the version provided.
209         
210         Raises:
211             NameError: Container/object does not exist
212             IndexError: Version does not exist
213         """
214         return
215     
216     def move_object(self, user, account, src_container, src_name, dest_container, dest_name, dest_meta={}, replace_meta=False, src_version=None):
217         """Move an object's data and metadata.
218         
219         Parameters:
220             'dest_meta': Dictionary with metadata to changes from source to destination
221             'replace_meta': Replace metadata instead of update
222             'src_version': Copy from the version provided.
223         
224         Raises:
225             NameError: Container/object does not exist
226             IndexError: Version does not exist
227         """
228         return
229     
230     def delete_object(self, user, account, container, name):
231         """Delete an object.
232         
233         Raises:
234             NameError: Container/object does not exist
235         """
236         return
237     
238     def list_versions(self, user, account, container, name):
239         """Return a list of all (version, version_timestamp) tuples for an object."""
240         return []
241     
242     def get_block(self, hash):
243         """Return a block's data.
244         
245         Raises:
246             NameError: Block does not exist
247         """
248         return ''
249     
250     def put_block(self, data):
251         """Store a block and return the hash."""
252         return 0
253     
254     def update_block(self, hash, data, offset=0):
255         """Update a known block and return the hash.
256         
257         Raises:
258             IndexError: Offset or data outside block limits
259         """
260         return 0