diff --git a/aaa.py b/aaa.py new file mode 100644 index 0000000..4248a3f --- /dev/null +++ b/aaa.py @@ -0,0 +1,14 @@ +import diskcache + +a = diskcache.Cache('/tmp/abcde', sqlite_query_only=True) +print(f'Query-only: ', a.sqlite_query_only) + +o = [1, 2, 3, 4] +# a['qq'] = o + +for k in a: + print(k) + +o = [1, 2, 3, 4] +a['qqe'] = o + diff --git a/diskcache/core.py b/diskcache/core.py index c74241e..0dc5791 100644 --- a/diskcache/core.py +++ b/diskcache/core.py @@ -80,12 +80,15 @@ def __repr__(self): MODE_TEXT = 3 MODE_PICKLE = 4 +# settings starting with sqlite_ are used as PRAGMAs in sqlite +# use with care DEFAULT_SETTINGS = { u'statistics': 0, # False u'tag_index': 0, # False u'eviction_policy': u'least-recently-stored', u'size_limit': 2 ** 30, # 1gb u'cull_limit': 10, + u'sqlite_query_only': False, u'sqlite_auto_vacuum': 1, # FULL u'sqlite_cache_size': 2 ** 13, # 8,192 pages u'sqlite_journal_mode': u'wal', @@ -439,6 +442,9 @@ def __init__(self, directory=None, timeout=60, disk=Disk, **settings): ' and could not be created' % self._directory ) + # this must be processed now because it is used in Cache._con + self.open_in_query_only = settings.get('sqlite_query_only', False) + sql = self._sql_retry # Setup Settings table. @@ -479,14 +485,16 @@ def __init__(self, directory=None, timeout=60, disk=Disk, **settings): # Set cached attributes: updates settings and sets pragmas. for key, value in sets.items(): - query = 'INSERT OR REPLACE INTO Settings VALUES (?, ?)' - sql(query, (key, value)) - self.reset(key, value) + if not self.sqlite_query_only: + query = 'INSERT OR REPLACE INTO Settings VALUES (?, ?)' + sql(query, (key, value)) + self.reset(key, value, update=not self.sqlite_query_only) for key, value in METADATA.items(): - query = 'INSERT OR IGNORE INTO Settings VALUES (?, ?)' - sql(query, (key, value)) - self.reset(key) + if not self.sqlite_query_only: + query = 'INSERT OR IGNORE INTO Settings VALUES (?, ?)' + sql(query, (key, value)) + self.reset(key, update=not self.sqlite_query_only) (self._page_size,), = sql('PRAGMA page_size').fetchall() @@ -555,10 +563,11 @@ def __init__(self, directory=None, timeout=60, disk=Disk, **settings): # Create tag index if requested. - if self.tag_index: # pylint: disable=no-member - self.create_tag_index() - else: - self.drop_tag_index() + if not self.sqlite_query_only: + if self.tag_index: # pylint: disable=no-member + self.create_tag_index() + else: + self.drop_tag_index() # Close and re-open database connection with given timeout. @@ -621,6 +630,11 @@ def _con(self): if key.startswith('sqlite_'): self.reset(key, value, update=False) + # the settings read fro the DB never contain query_only + # so we manually force it here, if it has been passed as a parameter + if self.open_in_query_only: + self.reset('sqlite_query_only', 1, update=False) + return con @@ -706,8 +720,9 @@ def _transact(self, retry=False, filename=None): begin = True self._txn_id = tid break - except sqlite3.OperationalError: - if retry: + except sqlite3.OperationalError as e: + # TODO: this is potentially an infinite loop anyway + if retry and 'readonly' not in str(e): continue if filename is not None: _disk_remove(filename)