diff --git a/src/calibre/db/backend.py b/src/calibre/db/backend.py index 5077d1f1a7..3aa4b09b50 100644 --- a/src/calibre/db/backend.py +++ b/src/calibre/db/backend.py @@ -90,7 +90,9 @@ class DBPrefs(dict): # {{{ return json.loads(raw, object_hook=from_json) def to_raw(self, val): - return json.dumps(val, indent=2, default=to_json) + # sort_keys=True is required so that the serialization of dictionaries is + # not random, which is needed for the changed check in __setitem__ + return json.dumps(val, indent=2, default=to_json, sort_keys=True) def has_setting(self, key): return key in self @@ -110,8 +112,11 @@ class DBPrefs(dict): # {{{ raw = self.to_raw(val) with self.db.conn: dbraw = self.db.execute('SELECT val FROM preferences WHERE key=?', (key,)).fetchone() - if dbraw != raw: - self.db.execute('INSERT OR REPLACE INTO preferences (key,val) VALUES (?,?)', (key, raw)) + if dbraw != (raw,): + if dbraw is None: + self.db.execute('INSERT INTO preferences (key,val) VALUES (?,?)', (key, raw)) + else: + self.db.execute('UPDATE preferences SET val=? WHERE key=?', (raw, key)) dict.__setitem__(self, key, val) def set(self, key, val): diff --git a/src/calibre/db/tests/writing.py b/src/calibre/db/tests/writing.py index eca53bd86b..8430090586 100644 --- a/src/calibre/db/tests/writing.py +++ b/src/calibre/db/tests/writing.py @@ -7,7 +7,6 @@ __license__ = 'GPL v3' __copyright__ = '2013, Kovid Goyal ' __docformat__ = 'restructuredtext en' -import os from collections import namedtuple from functools import partial from io import BytesIO @@ -704,7 +703,10 @@ class WritingTest(BaseTest): prefs['test mutable'] = a prefs.load_from_db() self.assertIn(4, prefs['test mutable']) - before = os.stat(cache.backend.library_path) - prefs['test mutable'] = a - self.assertEqual(before, os.stat(cache.backend.library_path), 'The database was written to despite there being no change in value') + changes = [] + cache.backend.conn.setupdatehook(lambda typ, dbname, tblname, rowid: changes.append(rowid)) + prefs['test mutable'] = {str(k):k for k in range(4)} + self.assertEqual(len(changes), 1) + prefs['test mutable'] = {str(k):k for k in range(4)} + self.assertEqual(len(changes), 1, 'The database was written to despite there being no change in value') # }}}