Revision 104626e3 pithos/backends/simple.py
b/pithos/backends/simple.py | ||
---|---|---|
66 | 66 |
sql = '''create table if not exists versions ( |
67 | 67 |
version_id integer primary key, |
68 | 68 |
name text, |
69 |
user text, |
|
69 | 70 |
tstamp datetime default current_timestamp, |
70 | 71 |
size integer default 0, |
71 | 72 |
hide integer default 0)''' |
... | ... | |
137 | 138 |
logger.debug("update_account_meta: %s %s %s", account, meta, replace) |
138 | 139 |
if user != account: |
139 | 140 |
raise NotAllowedError |
140 |
self._put_metadata(account, meta, replace) |
|
141 |
self._put_metadata(user, account, meta, replace)
|
|
141 | 142 |
|
142 | 143 |
def list_containers(self, user, account, marker=None, limit=10000, until=None): |
143 | 144 |
"""Return a list of containers existing under an account.""" |
... | ... | |
157 | 158 |
path, version_id, mtime = self._get_containerinfo(account, container) |
158 | 159 |
except NameError: |
159 | 160 |
path = os.path.join(account, container) |
160 |
version_id = self._put_version(path) |
|
161 |
version_id = self._put_version(path, user)
|
|
161 | 162 |
else: |
162 | 163 |
raise NameError('Container already exists') |
163 | 164 |
|
... | ... | |
172 | 173 |
if count > 0: |
173 | 174 |
raise IndexError('Container is not empty') |
174 | 175 |
self._del_path(path) # Point of no return. |
175 |
self._copy_version(account, account, True, True) # New account version. |
|
176 |
self._copy_version(user, account, account, True, True) # New account version.
|
|
176 | 177 |
|
177 | 178 |
def get_container_meta(self, user, account, container, until=None): |
178 | 179 |
"""Return a dictionary with the container metadata.""" |
... | ... | |
204 | 205 |
if user != account: |
205 | 206 |
raise NotAllowedError |
206 | 207 |
path, version_id, mtime = self._get_containerinfo(account, container) |
207 |
self._put_metadata(path, meta, replace) |
|
208 |
self._put_metadata(user, path, meta, replace)
|
|
208 | 209 |
|
209 | 210 |
def list_objects(self, user, account, container, prefix='', delimiter=None, marker=None, limit=10000, virtual=True, keys=[], until=None): |
210 | 211 |
"""Return a list of objects existing under a container.""" |
... | ... | |
233 | 234 |
|
234 | 235 |
logger.debug("get_object_meta: %s %s %s %s", account, container, name, version) |
235 | 236 |
self._can_read(user, account, container, name) |
236 |
path, version_id, mtime, size = self._get_objectinfo(account, container, name, version) |
|
237 |
path, version_id, muser, mtime, size = self._get_objectinfo(account, container, name, version)
|
|
237 | 238 |
if version is None: |
238 | 239 |
modified = mtime |
239 | 240 |
else: |
240 |
modified = self._get_version(path, version)[1] # Overall last modification
|
|
241 |
modified = self._get_version(path, version)[2] # Overall last modification
|
|
241 | 242 |
|
242 | 243 |
meta = self._get_metadata(path, version_id) |
243 |
meta.update({'name': name, 'bytes': size, 'version': version_id, 'version_timestamp': mtime, 'modified': modified}) |
|
244 |
meta.update({'name': name, 'bytes': size}) |
|
245 |
meta.update({'version': version_id, 'version_timestamp': mtime}) |
|
246 |
meta.update({'modified': modified, 'modified_by': muser}) |
|
244 | 247 |
return meta |
245 | 248 |
|
246 | 249 |
def update_object_meta(self, user, account, container, name, meta, replace=False): |
... | ... | |
248 | 251 |
|
249 | 252 |
logger.debug("update_object_meta: %s %s %s %s %s", account, container, name, meta, replace) |
250 | 253 |
self._can_write(user, account, container, name) |
251 |
path, version_id, mtime, size = self._get_objectinfo(account, container, name) |
|
252 |
self._put_metadata(path, meta, replace) |
|
254 |
path, version_id, muser, mtime, size = self._get_objectinfo(account, container, name)
|
|
255 |
self._put_metadata(user, path, meta, replace)
|
|
253 | 256 |
|
254 | 257 |
def get_object_permissions(self, user, account, container, name): |
255 | 258 |
"""Return the path from which this object gets its permissions from,\ |
... | ... | |
275 | 278 |
|
276 | 279 |
logger.debug("get_object_hashmap: %s %s %s %s", account, container, name, version) |
277 | 280 |
self._can_read(user, account, container, name) |
278 |
path, version_id, mtime, size = self._get_objectinfo(account, container, name, version) |
|
281 |
path, version_id, muser, mtime, size = self._get_objectinfo(account, container, name, version)
|
|
279 | 282 |
sql = 'select block_id from hashmaps where version_id = ? order by pos asc' |
280 | 283 |
c = self.con.execute(sql, (version_id,)) |
281 | 284 |
hashmap = [x[0] for x in c.fetchall()] |
... | ... | |
292 | 295 |
path = os.path.join(path, name) |
293 | 296 |
if permissions is not None: |
294 | 297 |
r, w = self._check_permissions(path, permissions) |
295 |
src_version_id, dest_version_id = self._copy_version(path, path, not replace_meta, False) |
|
298 |
src_version_id, dest_version_id = self._copy_version(user, path, path, not replace_meta, False)
|
|
296 | 299 |
sql = 'update versions set size = ? where version_id = ?' |
297 | 300 |
self.con.execute(sql, (size, dest_version_id)) |
298 | 301 |
# TODO: Check for block_id existence. |
... | ... | |
324 | 327 |
dest_path = os.path.join(dest_path, dest_name) |
325 | 328 |
if permissions is not None: |
326 | 329 |
r, w = self._check_permissions(dest_path, permissions) |
327 |
src_version_id, dest_version_id = self._copy_version(src_path, dest_path, not replace_meta, True, src_version) |
|
330 |
src_version_id, dest_version_id = self._copy_version(user, src_path, dest_path, not replace_meta, True, src_version)
|
|
328 | 331 |
for k, v in dest_meta.iteritems(): |
329 | 332 |
sql = 'insert or replace into metadata (version_id, key, value) values (?, ?, ?)' |
330 | 333 |
self.con.execute(sql, (dest_version_id, k, v)) |
... | ... | |
346 | 349 |
logger.debug("delete_object: %s %s %s", account, container, name) |
347 | 350 |
if user != account: |
348 | 351 |
raise NotAllowedError |
349 |
path, version_id, mtime, size = self._get_objectinfo(account, container, name)
|
|
350 |
self._put_version(path, 0, 1) |
|
352 |
path = self._get_objectinfo(account, container, name)[0]
|
|
353 |
self._put_version(path, user, 0, 1)
|
|
351 | 354 |
sql = 'delete from permissions where name = ?' |
352 | 355 |
self.con.execute(sql, (path,)) |
353 | 356 |
self.con.commit() |
... | ... | |
421 | 424 |
|
422 | 425 |
def _get_version(self, path, version=None): |
423 | 426 |
if version is None: |
424 |
sql = '''select version_id, strftime('%s', tstamp), size, hide from versions where name = ? |
|
427 |
sql = '''select version_id, user, strftime('%s', tstamp), size, hide from versions where name = ?
|
|
425 | 428 |
order by version_id desc limit 1''' |
426 | 429 |
c = self.con.execute(sql, (path,)) |
427 | 430 |
row = c.fetchone() |
428 |
if not row or int(row[3]):
|
|
431 |
if not row or int(row[4]):
|
|
429 | 432 |
raise NameError('Object does not exist') |
430 | 433 |
else: |
431 |
sql = '''select version_id, strftime('%s', tstamp), size from versions where name = ? |
|
434 |
# The database (sqlite) will not complain if the version is not an integer. |
|
435 |
sql = '''select version_id, user, strftime('%s', tstamp), size from versions where name = ? |
|
432 | 436 |
and version_id = ?''' |
433 | 437 |
c = self.con.execute(sql, (path, version)) |
434 | 438 |
row = c.fetchone() |
435 | 439 |
if not row: |
436 | 440 |
raise IndexError('Version does not exist') |
437 |
return str(row[0]), int(row[1]), int(row[2])
|
|
441 |
return str(row[0]), str(row[1]), int(row[2]), int(row[3])
|
|
438 | 442 |
|
439 |
def _put_version(self, path, size=0, hide=0): |
|
440 |
sql = 'insert into versions (name, size, hide) values (?, ?, ?)'
|
|
441 |
id = self.con.execute(sql, (path, size, hide)).lastrowid |
|
443 |
def _put_version(self, path, user, size=0, hide=0):
|
|
444 |
sql = 'insert into versions (name, user, size, hide) values (?, ?, ?, ?)'
|
|
445 |
id = self.con.execute(sql, (path, user, size, hide)).lastrowid
|
|
442 | 446 |
self.con.commit() |
443 | 447 |
return str(id) |
444 | 448 |
|
445 |
def _copy_version(self, src_path, dest_path, copy_meta=True, copy_data=True, src_version=None): |
|
449 |
def _copy_version(self, user, src_path, dest_path, copy_meta=True, copy_data=True, src_version=None):
|
|
446 | 450 |
if src_version is not None: |
447 |
src_version_id, mtime, size = self._get_version(src_path, src_version) |
|
451 |
src_version_id, muser, mtime, size = self._get_version(src_path, src_version)
|
|
448 | 452 |
else: |
449 | 453 |
# Latest or create from scratch. |
450 | 454 |
try: |
451 |
src_version_id, mtime, size = self._get_version(src_path) |
|
455 |
src_version_id, muser, mtime, size = self._get_version(src_path)
|
|
452 | 456 |
except NameError: |
453 | 457 |
src_version_id = None |
454 | 458 |
size = 0 |
455 | 459 |
if not copy_data: |
456 | 460 |
size = 0 |
457 |
dest_version_id = self._put_version(dest_path, size) |
|
461 |
dest_version_id = self._put_version(dest_path, user, size)
|
|
458 | 462 |
if copy_meta and src_version_id is not None: |
459 | 463 |
sql = 'insert into metadata select %s, key, value from metadata where version_id = ?' |
460 | 464 |
sql = sql % dest_version_id |
... | ... | |
499 | 503 |
|
500 | 504 |
def _get_objectinfo(self, account, container, name, version=None): |
501 | 505 |
path = os.path.join(account, container, name) |
502 |
version_id, mtime, size = self._get_version(path, version) |
|
503 |
return path, version_id, mtime, size |
|
506 |
version_id, muser, mtime, size = self._get_version(path, version)
|
|
507 |
return path, version_id, muser, mtime, size
|
|
504 | 508 |
|
505 | 509 |
def _get_metadata(self, path, version): |
506 | 510 |
sql = 'select key, value from metadata where version_id = ?' |
507 | 511 |
c = self.con.execute(sql, (version,)) |
508 | 512 |
return dict(c.fetchall()) |
509 | 513 |
|
510 |
def _put_metadata(self, path, meta, replace=False): |
|
514 |
def _put_metadata(self, user, path, meta, replace=False):
|
|
511 | 515 |
"""Create a new version and store metadata.""" |
512 | 516 |
|
513 |
src_version_id, dest_version_id = self._copy_version(path, path, not replace, True) |
|
517 |
src_version_id, dest_version_id = self._copy_version(user, path, path, not replace, True)
|
|
514 | 518 |
for k, v in meta.iteritems(): |
515 | 519 |
if not replace and v == '': |
516 | 520 |
sql = 'delete from metadata where version_id = ? and key = ?' |
Also available in: Unified diff