def load_from_location(self, location=None): """ Restores :class:`TrackDB` state from the pickled representation stored at the specified location. :param location: the location to load the data from :type location: string """ if not location: location = self.location if not location: raise AttributeError( _("You did not specify a location to load the db from") ) logger.debug("Loading %s DB from %s.", self.name, location) pdata = common.open_shelf(location) if "_dbversion" in pdata: if int(pdata['_dbversion']) > int(self._dbversion): raise common.VersionError("DB was created on a newer Exaile version.") elif pdata['_dbversion'] < self._dbversion: logger.info("Upgrading DB format....") import shutil shutil.copyfile(location, location + "-%s.bak" % pdata['_dbversion']) import xl.migrations.database as dbmig dbmig.handle_migration( self, pdata, pdata['_dbversion'], self._dbversion ) for attr in self.pickle_attrs: try: if 'tracks' == attr: data = {} for k in (x for x in pdata.keys() if x.startswith("tracks-")): p = pdata[k] tr = Track(_unpickles=p[0]) loc = tr.get_loc_for_io() if loc not in data: data[loc] = TrackHolder(tr, p[1], **p[2]) else: logger.warning("Duplicate track found: %s", loc) # presumably the second track was written because of an error, # so use the first track found. del pdata[k] setattr(self, attr, data) else: setattr(self, attr, pdata.get(attr, getattr(self, attr))) except Exception: # FIXME: Do something about this logger.exception("Exception occurred while loading %s", location) pdata.close() self._dirty = False
def __init__(self, location, default=None): ''' @param location: specify the shelve file location @param default: can specify a default to return from getter when there is nothing in the shelve ''' self.location = location self.db = common.open_shelf(location) self.lock = threading.Lock() self.default = default # Callback to close db event.add_callback(self.on_quit_application, 'quit_application')
def test_migration(data): truth, loc, dbtype = data print(os.listdir(loc)) try: db = open_shelf(join(loc, 'music.db')) except Exception as e: if dbtype == 'dbm' and getattr(e, 'args', (None,))[0] == 2: # on fedora it seems like dbm is linked to gdbm, and on debian based # systems that dbm uses a bsd implementation. Ignore these errors, # as (presumably) users will only try to migrate databases on systems # that were previously able to read the database. pytest.skip("Invalid dbm module") return raise for k, v in truth.iteritems(): assert k in db assert v == db[k] assert os.listdir(loc) == ['music.db'] db.close()
def test_migration(data): truth, loc, dbtype = data print(os.listdir(loc)) try: db = open_shelf(join(loc, 'music.db')) except Exception as e: if dbtype == 'dbm' and getattr(e, 'args', (None, ))[0] == 2: # on fedora it seems like dbm is linked to gdbm, and on debian based # systems that dbm uses a bsd implementation. Ignore these errors, # as (presumably) users will only try to migrate databases on systems # that were previously able to read the database. pytest.skip("Invalid dbm module") return raise for k, v in truth.items(): assert k in db assert v == db[k] assert os.listdir(loc) == ['music.db'] db.close()
def save_to_location(self, location=None): """ Saves a pickled representation of this :class:`TrackDB` to the specified location. :param location: the location to save the data to :type location: string """ if not self._dirty: for track in self.tracks.values(): if track._track._dirty: self._dirty = True break if not self._dirty: return if not location: location = self.location if not location: raise AttributeError( _("You did not specify a location to save the db")) if self._saving: return self._saving = True logger.debug("Saving %s DB to %s.", self.name, location) try: pdata = common.open_shelf(location) if pdata.get('_dbversion', self._dbversion) > self._dbversion: raise common.VersionError("DB was created on a newer Exaile.") except Exception: logger.exception("Failed to open music DB for writing.") return for attr in self.pickle_attrs: # bad hack to allow saving of lists/dicts of Tracks if 'tracks' == attr: for k, track in self.tracks.items(): key = "tracks-%s" % track._key if track._track._dirty or key not in pdata: pdata[key] = ( track._track._pickles(), track._key, deepcopy(track._attrs), ) else: pdata[attr] = deepcopy(getattr(self, attr)) pdata['_dbversion'] = self._dbversion for key in self._deleted_keys: key = "tracks-%s" % key if key in pdata: del pdata[key] pdata.sync() pdata.close() for track in self.tracks.values(): track._track._dirty = False self._dirty = False self._saving = False
def save_to_location(self, location=None): """ Saves a pickled representation of this :class:`TrackDB` to the specified location. :param location: the location to save the data to :type location: string """ if not self._dirty: for track in self.tracks.itervalues(): if track._track._dirty: self._dirty = True break if not self._dirty: return if not location: location = self.location if not location: raise AttributeError(_("You did not specify a location to save the db")) if self._saving: return self._saving = True logger.debug("Saving %s DB to %s.", self.name, location) try: pdata = common.open_shelf(location) if pdata.get('_dbversion', self._dbversion) > self._dbversion: raise common.VersionError("DB was created on a newer Exaile.") except Exception: logger.exception("Failed to open music DB for writing.") return for attr in self.pickle_attrs: # bad hack to allow saving of lists/dicts of Tracks if 'tracks' == attr: for k, track in self.tracks.iteritems(): key = "tracks-%s" % track._key if track._track._dirty or key not in pdata: pdata[key] = ( track._track._pickles(), track._key, deepcopy(track._attrs), ) else: pdata[attr] = deepcopy(getattr(self, attr)) pdata['_dbversion'] = self._dbversion for key in self._deleted_keys: key = "tracks-%s" % key if key in pdata: del pdata[key] pdata.sync() pdata.close() for track in self.tracks.itervalues(): track._track._dirty = False self._dirty = False self._saving = False