From 2f4941613ca4f9b5ccbf620d80f15423d2ec4e97 Mon Sep 17 00:00:00 2001 From: Kovid Goyal Date: Tue, 17 Jan 2012 23:55:30 +0530 Subject: [PATCH] Nicer implementation of the mutable classes --- src/calibre/db/lazy.py | 94 ++++++++++++++++++++++++++ src/calibre/library/database2.py | 109 +------------------------------ 2 files changed, 97 insertions(+), 106 deletions(-) create mode 100644 src/calibre/db/lazy.py diff --git a/src/calibre/db/lazy.py b/src/calibre/db/lazy.py new file mode 100644 index 0000000000..b53cf2b54a --- /dev/null +++ b/src/calibre/db/lazy.py @@ -0,0 +1,94 @@ +#!/usr/bin/env python +# vim:fileencoding=UTF-8:ts=4:sw=4:sta:et:sts=4:ai +from __future__ import (unicode_literals, division, absolute_import, + print_function) + +__license__ = 'GPL v3' +__copyright__ = '2012, Kovid Goyal ' +__docformat__ = 'restructuredtext en' + +import weakref +from functools import wraps +from collections import MutableMapping, MutableSequence + +def resolved(f): + @wraps(f) + def wrapper(self, *args, **kwargs): + if getattr(self, '_must_resolve', True): + self._must_resolve = False + self._resolve() + return f(self, *args, **kwargs) + return wrapper + +class MutableBaseMixin(object): # {{{ + @resolved + def __str__(self): + return str(self.values) + + @resolved + def __repr__(self): + return repr(self.values) + + @resolved + def __unicode__(self): + return unicode(self.values) + + @resolved + def __len__(self): + return len(self.values) + + @resolved + def __iter__(self): + return iter(self.values) + + @resolved + def __contains__(self, key): + return key in self.values + + @resolved + def __getitem__(self, fmt): + return self.values[fmt] + + @resolved + def __setitem__(self, key, val): + self.values[key] = val + + @resolved + def __delitem__(self, key): + del self.values[key] + +# }}} + +class FormatMetadata(MutableBaseMixin, MutableMapping): # {{{ + + def __init__(self, db, id_, formats): + self.dbwref = weakref.ref(db) + self.id_ = id_ + self.formats = formats + self.values = {} + + def _resolve(self): + db = self.dbwref() + for f in self.formats: + try: + self.values[f] = db.format_metadata(self.id_, f) + except: + pass + +class FormatsList(MutableBaseMixin, MutableSequence): + + def __init__(self, formats, format_metadata): + self.formats = formats + self.format_metadata = format_metadata + self.values = [] + + def _resolve(self): + self.values = [f for f in self.formats if f in self.format_metadata] + + def insert(self, idx, val): + self._resolve() + self.values.insert(idx, val) + +# }}} + + diff --git a/src/calibre/library/database2.py b/src/calibre/library/database2.py index 513f0bc690..caa8134579 100644 --- a/src/calibre/library/database2.py +++ b/src/calibre/library/database2.py @@ -7,8 +7,8 @@ __docformat__ = 'restructuredtext en' The database used to store ebook metadata ''' import os, sys, shutil, cStringIO, glob, time, functools, traceback, re, \ - json, uuid, hashlib, copy, weakref -from collections import defaultdict, MutableMapping, MutableSequence + json, uuid, hashlib, copy +from collections import defaultdict import threading, random from itertools import repeat from math import ceil @@ -40,6 +40,7 @@ from calibre.utils.magick.draw import save_cover_data_to from calibre.utils.recycle_bin import delete_file, delete_tree from calibre.utils.formatter_functions import load_user_template_functions from calibre.db.errors import NoSuchFormat +from calibre.db.lazy import FormatMetadata, FormatsList from calibre.utils.localization import (canonicalize_lang, calibre_langcode_to_name) @@ -81,110 +82,6 @@ class Tag(object): def __repr__(self): return str(self) -class MutablePrintMixin(object): # {{{ - def __str__(self): - self._resolve() - return str(self.values) - - def __repr__(self): - self._resolve() - return repr(self.values) - - def __unicode__(self): - self._resolve() - return unicode(self.values) -# }}} - -class FormatMetadata(MutableMapping, MutablePrintMixin): # {{{ - - def __init__(self, db, id_, formats): - self.dbwref = weakref.ref(db) - self.id_ = id_ - self.formats = formats - self._must_do = True - self.values = {} - - def _resolve(self): - if self._must_do: - self._must_do = False - db = self.dbwref() - for f in self.formats: - try: - self.values[f] = db.format_metadata(self.id_, f) - except: - pass - - def __contains__(self, key): - self._resolve() - return key in self.values - - def __getitem__(self, fmt): - self._resolve() - return self.values[fmt] - - def __setitem__(self, key, val): - self._resolve() - self.values[key] = val - - def __delitem__(self, key): - self._resolve() - self.values.__delitem__(key) - - def __len__(self): - self._resolve() - return len(self.values) - - def __iter__(self): - self._resolve() - return self.values.__iter__() - - -class FormatsList(MutableSequence, MutablePrintMixin): - - def __init__(self, formats, format_metadata): - self.formats = formats - self.format_metadata = format_metadata - self._must_do = True - self.values = [] - - def _resolve(self): - if self._must_do: - self._must_do = False - for f in self.formats: - try: - if f in self.format_metadata: - self.values.append(f) - except: - pass - - def __getitem__(self, dex): - self._resolve() - return self.values[dex] - - def __setitem__(self, key, dex): - self._resolve() - self.values[key] = dex - - def __delitem__(self, dex): - self._resolve() - self.values.__delitem__(dex) - - def __len__(self): - self._resolve() - return len(self.values) - - def __iter__(self): - self._resolve() - return self.values.__iter__() - - def insert(self, idx, val): - self._resolve() - self.values.insert(idx, val) - -# }}} - - - class LibraryDatabase2(LibraryDatabase, SchemaUpgrade, CustomColumns): ''' An ebook metadata database that stores references to ebook files on disk.