From 97a4f7ef4e67de88f849884fd2d5fdefad2790ce Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=A9dric=20Krier?= Date: Thu, 11 Dec 2008 13:58:55 +0100 Subject: [PATCH] Add local cache and prefetch of datas for webdav speed improvement --- TODO | 2 - trytond/tools/misc.py | 103 +++++++++++- trytond/webdav/webdav.py | 333 +++++++++++++++++++++++++++++++-------- trytond/webdavsvc.py | 43 +++-- 4 files changed, 393 insertions(+), 88 deletions(-) diff --git a/TODO b/TODO index 153cf14336..961d8241b4 100644 --- a/TODO +++ b/TODO @@ -10,5 +10,3 @@ - Add check for index and constraint name lenght (limit 31) - Change _constraint to pass a BrowseRecordList instead of a list of ids - Change action, menu on res.user into a Many2Many -- Add a pre-fetch of brothers for get_xxx function of webdav collection - for the same request diff --git a/trytond/tools/misc.py b/trytond/tools/misc.py index 2a3a80e0db..9c34b0e6bd 100644 --- a/trytond/tools/misc.py +++ b/trytond/tools/misc.py @@ -9,7 +9,7 @@ from trytond.config import CONFIG import socket import zipfile from trytond import pooler -from threading import Lock +from threading import Lock, local import logging try: import cStringIO as StringIO @@ -369,3 +369,104 @@ def mod10r(number): if digit.isdigit(): report = codec[ (int(digit) + report) % 10 ] return result + str((10 - report) % 10) + + +class LocalDict(local): + + def __init__(self, dict=None): + if dict is None: + dict = {} + self.dict = dict + + def __str__(self): + return str(self.dict) + + def __repr__(self): + return str(self.dict) + + def clear(self): + return self.dict.clear() + + def keys(self): + return self.dict.keys() + + def __setitem__(self, i, y): + self.dict.__setitem__(i, y) + + def __getitem__(self, i): + return self.dict.__getitem__(i) + + def copy(self): + return self.dict.copy() + + def iteritems(self): + return self.dict.iteritems() + + def iterkeys(self): + return self.dict.iterkeys() + + def itervalues(self): + return self.dict.itervalues() + + def pop(self, k, d=None): + return self.dict.pop(k, d) + + def popitem(self): + return self.dict.popitem() + + def setdefault(self, k, d=None): + return self.dict.setdefault(k, d) + + def update(self, E, **F): + return self.dict.update(E, F) + + def values(self): + return self.dict.values() + + def get(self, k, d=None): + return self.dict.get(k, d) + + def has_key(self, k): + return self.dict.has_key(k) + + def items(self): + return self.dict.items() + + def __cmp__(self, y): + return self.dict.__cmp__(y) + + def __contains__(self, k): + return self.dict.__contains__(k) + + def __delitem__(self, y): + return self.dict.__delitem__(y) + + def __eq__(self, y): + return self.dict.__eq__(y) + + def __ge__(self, y): + return self.dict.__ge__(y) + + def __getitem__(self, y): + return self.dict.__getitem__(y) + + def __gt__(self, y): + return self.dict.__gt__(y) + + def __hash__(self): + return self.dict.__hash__() + + def __iter__(self): + return self.dict.__iter__() + + def __le__(self, y): + return self.dict.__le__(y) + + def __len__(self): + return self.dict.__len__() + + def __lt__(self, y): + return self.dict.__lt__(y) + + def __ne__(self, y): + return self.dict.__ne__(y) diff --git a/trytond/webdav/webdav.py b/trytond/webdav/webdav.py index cdd650b1ca..307a1ce6f9 100644 --- a/trytond/webdav/webdav.py +++ b/trytond/webdav/webdav.py @@ -62,31 +62,93 @@ class Collection(OSV): return True def _uri2object(self, cursor, user, uri, object_name=_name, object_id=False, - context=None): + context=None, cache=None): attachment_obj = self.pool.get('ir.attachment') report_obj = self.pool.get('ir.action.report') + cache_uri = uri + + if cache is not None: + cache.setdefault('_uri2object', {}) + if cache_uri in cache['_uri2object']: + return cache['_uri2object'][cache_uri] + if not uri: + if cache is not None: + cache['_uri2object'][cache_uri] = (self._name, False) return self._name, False name, uri = (uri.split('/', 1) + [None])[0:2] if object_name == self._name: - collection_ids = self.search(cursor, user, [ - ('name', '=', name), - ('parent', '=', object_id), - ], limit=1, context=context) + collection_ids = None + if cache is not None: + cache.setdefault('_parent2collection_ids', {}) + if object_id in cache['_parent2collection_ids']: + collection_ids = cache['_parent2collection_ids']\ + [object_id].get(name, []) + if collection_ids is None: + collection_ids = self.search(cursor, user, [ + ('parent', '=', object_id), + ], context=context) + collections = self.browse(cursor, user, collection_ids, + context=context) + collection_ids = [] + if cache is not None: + cache['_parent2collection_ids'].setdefault(object_id, {}) + for collection in collections: + if cache is not None: + cache['_parent2collection_ids'][object_id]\ + .setdefault(collection.name, []) + cache['_parent2collection_ids'][object_id]\ + [collection.name].append(collection.id) + if collection.name == name: + collection_ids.append(collection.id) if collection_ids: object_id = collection_ids[0] - collection = self.browse(cursor, user, object_id, - context=context) - if collection.model and uri: - object_name = collection.model.model + object_name2 = None + if cache is not None: + cache.setdefault('_collection_name', {}) + if object_id in cache['_collection_name']: + object_name2 = cache['_collection_name'][object_id] + if object_name2 is None: + collection = self.browse(cursor, user, object_id, + context=context) + if collection.model and uri: + object_name = collection.model.model + if cache is not None: + cache['_collection_name'][object_id] = object_name + else: + object_name = object_name2 else: if uri: + if cache is not None: + cache['_uri2object'][cache_uri] = (None, 0) return None, 0 - attachment_ids = attachment_obj.search(cursor, user, [ - ('res_model', '=', object_name), - ('res_id', '=', object_id), - ('name', '=', name), - ], limit=1, context=context) + + attachment_ids = None + if cache is not None: + cache.setdefault('_model&id2attachment_ids', {}) + if (object_name, object_id) in \ + cache['_model&id2attachment_ids']: + attachment_ids = cache['_model&id2attachment_ids']\ + [(object_name, object_id)].get(name, []) + if attachment_ids is None: + attachment_ids = attachment_obj.search(cursor, user, [ + ('res_model', '=', object_name), + ('res_id', '=', object_id), + ], context=context) + attachments = attachment_obj.browse(cursor, user, + attachment_ids, context=context) + key = (object_name, object_id) + attachment_ids = [] + if cache is not None: + cache['_model&id2attachment_ids'].setdefault(key, {}) + for attachment in attachments: + if cache is not None: + cache['_model&id&name2attachment_ids'][key]\ + .setdefault(attachment.name, []) + cache['_model&id&name2attachment_ids'][key]\ + [attachment.name].append(attachment.id) + if attachment.name == name: + attachment_ids.append(attachment.id) if attachment_ids: object_name = 'ir.attachment' object_id = attachment_ids[0] @@ -96,10 +158,14 @@ class Collection(OSV): else: splitted_name = name.rsplit('-', 1) if len(splitted_name) != 2: + if cache is not None: + cache['_uri2object'][cache_uri] = (object_name, 0) return object_name, 0 object_id = int(splitted_name[1].strip()) if uri: if '/' in uri: + if cache is not None: + cache['_uri2object'][cache_uri] = (None, 0) return None, 0 report_ids = report_obj.search(cursor, user, [ ('model', '=', object_name), @@ -110,26 +176,57 @@ class Collection(OSV): report_name = report.name + '-' + str(report.id) \ + '.' + report.output_format.format if uri == report_name: + if cache is not None: + cache['_uri2object'][cache_uri] = \ + ('ir.action.report', object_id) return 'ir.action.report', object_id name = uri - attachment_ids = attachment_obj.search(cursor, user, [ - ('res_model', '=', object_name), - ('res_id', '=', object_id), - ('name', '=', name), - ], limit=1, context=context) + attachment_ids = None + if cache is not None: + cache.setdefault('_model&id2attachment_ids', {}) + if (object_name, object_id) in \ + cache['_model&id2attachment_ids']: + attachment_ids = cache['_model&id2attachment_ids']\ + [(object_name, object_id)].get(name, []) + if attachment_ids is None: + attachment_ids = attachment_obj.search(cursor, user, [ + ('res_model', '=', object_name), + ('res_id', '=', object_id), + ], context=context) + attachments = attachment_obj.browse(cursor, user, + attachment_ids, context=context) + key = (object_name, object_id) + attachment_ids = [] + if cache is not None: + cache['_model&id2attachment_ids'].setdefault(key, {}) + for attachment in attachments: + if cache is not None: + cache['_model&id2attachment_ids'][key]\ + .setdefault(attachment.name, []) + cache['_model&id2attachment_ids'][key]\ + [attachment.name].append(attachment.id) + if attachment.name == name: + attachment_ids.append(attachment.id) if attachment_ids: object_name = 'ir.attachment' object_id = attachment_ids[0] else: object_name = None object_id = False + if cache is not None: + cache['_uri2object'][cache_uri] = (object_name, object_id) return object_name, object_id if uri: - return self._uri2object(cursor, user, uri, object_name, - object_id, context) + res = self._uri2object(cursor, user, uri, object_name, + object_id, context=context, cache=cache) + if cache is not None: + cache['_uri2object'][cache_uri] = res + return res + if cache is not None: + cache['_uri2object'][cache_uri] = (object_name, object_id) return object_name, object_id - def get_childs(self, cursor, user, uri, context=None): + def get_childs(self, cursor, user, uri, context=None, cache=None): report_obj = self.pool.get('ir.action.report') res = [] if not uri: @@ -141,9 +238,12 @@ class Collection(OSV): if '/' in collection.name: continue res.append(collection.name) + if cache is not None: + cache.setdefault(self._name, {}) + cache[self._name][collection.id] = {} return res object_name, object_id = self._uri2object(cursor, user, uri, - context=context) + context=context, cache=cache) if object_name == self._name and object_id: collection = self.browse(cursor, user, object_id, context=context) if collection.model: @@ -157,12 +257,18 @@ class Collection(OSV): if '/' in child_name: continue res.append(child_name + '-' + str(child_id)) + if cache is not None: + cache.setdefault(model_obj._name, {}) + cache[model_obj._name][child_id] = {} return res else: for child in collection.childs: if '/' in child.name: continue res.append(child.name) + if cache is not None: + cache.setdefault(self._name, {}) + cache[self._name][child.id] = {} if object_name not in ('ir.attachment', 'ir.action.report'): report_ids = report_obj.search(cursor, user, [ ('model', '=', object_name), @@ -175,6 +281,9 @@ class Collection(OSV): if '/' in report_name: continue res.append(report_name) + if cache is not None: + cache.setdefault(report_obj._name, {}) + cache[report_obj._name][report.id] = {} attachment_obj = self.pool.get('ir.attachment') attachment_ids = attachment_obj.search(cursor, user, [ @@ -187,33 +296,58 @@ class Collection(OSV): if '/' in attachment.name: continue res.append(attachment.name) + if cache is not None: + cache.setdefault(attachment_obj._name, {}) + cache[attachment_obj._name][attachment.id] = {} return res - def get_resourcetype(self, cursor, user, uri, context=None): + def get_resourcetype(self, cursor, user, uri, context=None, cache=None): from DAV.constants import COLLECTION, OBJECT object_name, object_id = self._uri2object(cursor, user, uri, - context=context) + context=context, cache=cache) if object_name in ('ir.attachment', 'ir.action.report'): return OBJECT return COLLECTION - def get_contentlength(self, cursor, user, uri, context=None): + def get_contentlength(self, cursor, user, uri, context=None, cache=None): + attachment_obj = self.pool.get('ir.attachment') + object_name, object_id = self._uri2object(cursor, user, uri, - context=context) + context=context, cache=cache) if object_name == 'ir.attachment': - attachment_obj = self.pool.get('ir.attachment') - attachment = attachment_obj.browse(cursor, user, object_id, + + if cache is not None: + cache.setdefault('ir.attachment', {}) + ids = cache['ir.attachment'].keys() + if object_id not in ids: + ids.append(object_id) + elif 'contentlength' in cache['ir.attachment'][object_id]: + return cache['ir.attachment'][object_id]['contentlength'] + else: + ids = [object_id] + + attachments = attachment_obj.browse(cursor, user, ids, context=context) - try: - if attachment.datas_size: - return str(attachment.datas_size) - except: - return '0' + + res = '0' + for attachment in attachments: + try: + if attachment.datas_size: + size = str(attachment.datas_size) + except: + size = '0' + if attachment.id == object_id: + res = size + if cache is not None: + cache['ir.attachment'].setdefault(attachment.id, {}) + cache['ir.attachment'][attachment.id]['contentlength'] = \ + size + return res return '0' - def get_contenttype(self, cursor, user, uri, context=None): + def get_contenttype(self, cursor, user, uri, context=None, cache=None): object_name, object_id = self._uri2object(cursor, user, uri, - context=context) + context=context, cache=cache) if object_name in ('ir.attachment', 'ir.action.report'): ext = os.path.splitext(uri)[1] if not ext: @@ -221,48 +355,110 @@ class Collection(OSV): return self.ext2mime.get(ext, 'application/octet-stream') return "application/octet-stream" - def get_creationdate(self, cursor, user, uri, context=None): + def get_creationdate(self, cursor, user, uri, context=None, cache=None): object_name, object_id = self._uri2object(cursor, user, uri, - context=context) + context=context, cache=cache) if object_name: model_obj = self.pool.get(object_name) if object_id: - cursor.execute('SELECT EXTRACT(epoch FROM create_date) ' \ + if cache is not None: + cache.setdefault(model_obj._name, {}) + ids = cache[model_obj._name].keys() + if object_id not in ids: + ids.append(object_id) + elif 'creationdate' in cache[model_obj._name][object_id]: + return cache[model_obj._name][object_id]['creationdate'] + else: + ids = [object_id] + cursor.execute('SELECT id, EXTRACT(epoch FROM create_date) ' \ 'FROM "' + model_obj._table +'" ' \ - 'WHERE id = %s', (object_id,)) - if cursor.rowcount: - return cursor.fetchone()[0] + 'WHERE id IN (' + \ + ','.join(['%s' for x in ids]) + ')', ids) + res = None + for object_id2, date in cursor.fetchall(): + if object_id2 == object_id: + res = date + if cache is not None: + cache[model_obj._name].setdefault(object_id2, {}) + cache[model_obj._name][object_id2]['creationdate'] = \ + date + if res is not None: + return res return time.time() - def get_lastmodified(self, cursor, user, uri, context=None): + def get_lastmodified(self, cursor, user, uri, context=None, cache=None): object_name, object_id = self._uri2object(cursor, user, uri, - context=context) + context=context, cache=cache) if object_name: model_obj = self.pool.get(object_name) if object_id: - cursor.execute('SELECT EXTRACT(epoch FROM write_date) ' \ + if cache is not None: + cache.setdefault(model_obj._name, {}) + ids = cache[model_obj._name].keys() + if object_id not in ids: + ids.append(object_id) + elif 'lastmodified' in cache[model_obj._name][object_id]: + return cache[model_obj._name][object_id]['lastmodified'] + else: + ids = [object_id] + cursor.execute('SELECT id, EXTRACT(epoch FROM write_date) ' \ 'FROM "' + model_obj._table +'" ' \ - 'WHERE id = %s', (object_id,)) - if cursor.rowcount: - return cursor.fetchone()[0] + 'WHERE id IN (' + \ + ','.join(['%s' for x in ids]) + ')', ids) + res = None + for object_id2, date in cursor.fetchall(): + if object_id2 == object_id: + res = date + if cache is not None: + cache[model_obj._name].setdefault(object_id2, {}) + cache[model_obj._name][object_id2]['lastmodified'] = \ + date + if res is not None: + return res return time.time() - def get_data(self, cursor, user, uri, context=None): + def get_data(self, cursor, user, uri, context=None, cache=None): from DAV.errors import DAV_NotFound + attachment_obj = self.pool.get('ir.attachment') + report_obj = self.pool.get('ir.action.report') + if uri: object_name, object_id = self._uri2object(cursor, user, uri, - context=context) + context=context, cache=cache) + if object_name == 'ir.attachment' and object_id: - attachment_obj = self.pool.get('ir.attachment') - attachment = attachment_obj.browse(cursor, user, object_id, + if cache is not None: + cache.setdefault('ir.attachment', {}) + ids = cache['ir.attachment'].keys() + if object_id not in ids: + ids.append(object_id) + elif 'data' in cache['ir.attachment'][object_id]: + res = cache['ir.attachment'][object_id]['data'] + if res == DAV_NotFound: + raise DAV_NotFound + return res + else: + ids = [object_id] + attachments = attachment_obj.browse(cursor, user, ids, context=context) - try: - if attachment.datas: - return base64.decodestring(attachment.datas) - except: + + res = DAV_NotFound + for attachment in attachments: + try: + if attachment.datas: + data = base64.decodestring(attachment.datas) + except: + data = DAV_NotFound + if attachment.id == object_id: + res = data + if cache is not None: + cache['ir.attachment'].setdefault(attachment.id, {}) + cache['ir.attachment'][attachment.id]['data'] = data + if res == DAV_NotFound: raise DAV_NotFound + return res + if object_name == 'ir.action.report' and object_id: - report_obj = self.pool.get('ir.action.report') report_id = int(uri.rsplit('/', 1)[-1].rsplit('-', 1)[-1].rsplit('.', 1)[0]) report = report_obj.browse(cursor, user, report_id, @@ -280,18 +476,19 @@ class Collection(OSV): return base64.decodestring(val[1]) raise DAV_NotFound - def put(self, cursor, user, uri, data, content_type, context=None): + def put(self, cursor, user, uri, data, content_type, context=None, + cache=None): from DAV.errors import DAV_Forbidden from DAV.utils import get_uriparentpath, get_urifilename object_name, object_id = self._uri2object(cursor, user, - get_uriparentpath(uri), context=context) + get_uriparentpath(uri), context=context, cache=cache) if not object_name \ or object_name in ('ir.attachment') \ or not object_id: raise DAV_Forbidden attachment_obj = self.pool.get('ir.attachment') object_name2, object_id2 = self._uri2object(cursor, user, uri, - context=context) + context=context, cache=cache) if not object_id2: name = get_urifilename(uri) try: @@ -313,13 +510,13 @@ class Collection(OSV): raise DAV_Forbidden return 201 - def mkcol(self, cursor, user, uri, context=None): + def mkcol(self, cursor, user, uri, context=None, cache=None): from DAV.errors import DAV_Forbidden from DAV.utils import get_uriparentpath, get_urifilename if uri[-1:] == '/': uri = uri[:-1] object_name, object_id = self._uri2object(cursor, user, - get_uriparentpath(uri), context=context) + get_uriparentpath(uri), context=context, cache=cache) if object_name != 'webdav.collection': raise DAV_Forbidden name = get_urifilename(uri) @@ -332,10 +529,10 @@ class Collection(OSV): raise DAV_Forbidden return 201 - def rmcol(self, cursor, user, uri, context=None): + def rmcol(self, cursor, user, uri, context=None, cache=None): from DAV.errors import DAV_Forbidden object_name, object_id = self._uri2object(cursor, user, uri, - context=context) + context=context, cache=cache) if object_name != 'webdav.collection' \ or not object_id: raise DAV_Forbidden @@ -345,10 +542,10 @@ class Collection(OSV): raise DAV_Forbidden return 200 - def rm(self, cursor, user, uri, context=None): + def rm(self, cursor, user, uri, context=None, cache=None): from DAV.errors import DAV_Forbidden object_name, object_id = self._uri2object(cursor, user, uri, - context=context) + context=context, cache=cache) if not object_name: raise DAV_Forbidden if object_name != 'ir.attachment' \ @@ -361,9 +558,9 @@ class Collection(OSV): raise DAV_Forbidden return 200 - def exists(self, cursor, user, uri, context=None): + def exists(self, cursor, user, uri, context=None, cache=None): object_name, object_id = self._uri2object(cursor, user, uri, - context=context) + context=context, cache=cache) if object_name and object_id: return 1 return None diff --git a/trytond/webdavsvc.py b/trytond/webdavsvc.py index b028e6c2f7..6b26d628fc 100644 --- a/trytond/webdavsvc.py +++ b/trytond/webdavsvc.py @@ -13,14 +13,12 @@ from netsvc import LocalService, SSLSocket import security import pooler from version import PACKAGE, VERSION, WEBSITE -from tools.misc import Cache +from tools.misc import Cache, LocalDict +import urllib # Local int for multi-thread import sys -if sys.version_info[:2] < (2, 4): - from threadinglocal import local -else: - from threading import local +from threading import local class LocalInt(local): @@ -32,6 +30,7 @@ class LocalInt(local): return int(self.value) USER_ID = LocalInt(0) +CACHE = LocalDict() # Fix for bad use of Document in DAV.utils make_xmlresponse from DAV.utils import VERSION as DAV_VERSION @@ -84,7 +83,8 @@ class TrytonDAVInterface(iface.dav_interface): collection_obj = pool.get('webdav.collection') if uri[-1:] != '/': uri += '/' - for child in collection_obj.get_childs(cursor, int(USER_ID), dburi): + for child in collection_obj.get_childs(cursor, int(USER_ID), dburi, + cache=CACHE): res.append(urlparse.urljoin(self.baseuri, uri + child)) cursor.close() return res @@ -121,7 +121,8 @@ class TrytonDAVInterface(iface.dav_interface): cursor = pooler.get_db(dbname).cursor() collection_obj = pool.get('webdav.collection') try: - res = collection_obj.get_data(cursor, int(USER_ID), dburi) + res = collection_obj.get_data(cursor, int(USER_ID), dburi, + cache=CACHE) finally: cursor.close() return res @@ -136,7 +137,7 @@ class TrytonDAVInterface(iface.dav_interface): try: try: res = collection_obj.put(cursor, int(USER_ID), dburi, data, - content_type) + content_type, cache=CACHE) cursor.commit() except: cursor.rollback() @@ -154,7 +155,8 @@ class TrytonDAVInterface(iface.dav_interface): collection_obj = pool.get('webdav.collection') try: try: - res = collection_obj.mkcol(cursor, int(USER_ID), dburi) + res = collection_obj.mkcol(cursor, int(USER_ID), dburi, + cache=CACHE) cursor.commit() except: cursor.rollback() @@ -170,7 +172,8 @@ class TrytonDAVInterface(iface.dav_interface): pool = pooler.get_pool(dbname) cursor = pooler.get_db(dbname).cursor() collection_obj = pool.get('webdav.collection') - res = collection_obj.get_resourcetype(cursor, int(USER_ID), dburi) + res = collection_obj.get_resourcetype(cursor, int(USER_ID), dburi, + cache=CACHE) cursor.close() return res @@ -184,7 +187,8 @@ class TrytonDAVInterface(iface.dav_interface): pool = pooler.get_pool(dbname) cursor = pooler.get_db(dbname).cursor() collection_obj = pool.get('webdav.collection') - res = collection_obj.get_contentlength(cursor, int(USER_ID), dburi) + res = collection_obj.get_contentlength(cursor, int(USER_ID), dburi, + cache=CACHE) cursor.close() return res @@ -195,7 +199,8 @@ class TrytonDAVInterface(iface.dav_interface): pool = pooler.get_pool(dbname) cursor = pooler.get_db(dbname).cursor() collection_obj = pool.get('webdav.collection') - res = collection_obj.get_contenttype(cursor, int(USER_ID), dburi) + res = collection_obj.get_contenttype(cursor, int(USER_ID), dburi, + cache=CACHE) cursor.close() return res @@ -206,7 +211,8 @@ class TrytonDAVInterface(iface.dav_interface): pool = pooler.get_pool(dbname) cursor = pooler.get_db(dbname).cursor() collection_obj = pool.get('webdav.collection') - res = collection_obj.get_creationdate(cursor, int(USER_ID), dburi) + res = collection_obj.get_creationdate(cursor, int(USER_ID), dburi, + cache=CACHE) cursor.close() return res @@ -217,7 +223,8 @@ class TrytonDAVInterface(iface.dav_interface): pool = pooler.get_pool(dbname) cursor = pooler.get_db(dbname).cursor() collection_obj = pool.get('webdav.collection') - res = collection_obj.get_lastmodified(cursor, int(USER_ID), dburi) + res = collection_obj.get_lastmodified(cursor, int(USER_ID), dburi, + cache=CACHE) cursor.close() return res @@ -230,7 +237,8 @@ class TrytonDAVInterface(iface.dav_interface): collection_obj = pool.get('webdav.collection') try: try: - res = collection_obj.rmcol(cursor, int(USER_ID), dburi) + res = collection_obj.rmcol(cursor, int(USER_ID), dburi, + cache=CACHE) cursor.commit() except: cursor.rollback() @@ -248,7 +256,8 @@ class TrytonDAVInterface(iface.dav_interface): collection_obj = pool.get('webdav.collection') try: try: - res = collection_obj.rm(cursor, int(USER_ID), dburi) + res = collection_obj.rm(cursor, int(USER_ID), dburi, + cache=CACHE) cursor.commit() except: cursor.rollback() @@ -264,7 +273,7 @@ class TrytonDAVInterface(iface.dav_interface): pool = pooler.get_pool(dbname) cursor = pooler.get_db(dbname).cursor() collection_obj = pool.get('webdav.collection') - res = collection_obj.exists(cursor, int(USER_ID), dburi) + res = collection_obj.exists(cursor, int(USER_ID), dburi, cache=CACHE) cursor.close() return res