def load(self, path): path = expand_path(path, config().basedir) if self.is_loaded(): unload_database() if not os.path.exists(path): self.load_failed = True raise LoadError try: infile = file(path, 'rb') db = cPickle.load(infile) self.start_date = db[0] self.categories = db[1] self.facts = db[2] self.fact_views = db[3] self.cards = db[4] infile.close() self.load_failed = False except: self.load_failed = True raise InvalidFormatError(stack_trace=True) # Work around a sip bug: don't store card types, but their ids. for f in self.facts: f.card_type = card_type_by_id(f.card_type) # TODO: This was to remove database inconsistencies. Still needed? #for c in self.categories: # self.remove_category_if_unused(c) config()["path"] = contract_path(path, config().basedir) log().loaded_database() for f in component_manager.get_all("function_hook", "after_load"): f.run()
def get_fact(self, guid=None, fact_id=None): """Get fact object by guid.""" # Get fact by id or guid if guid: fact = self.conn.execute("select * from facts where guid=?", (guid, )).fetchone() elif fact_id: fact = self.conn.execute("select * from facts where id=?", (fact_id, )).fetchone() else: raise RuntimeError("get_fact: No guid nor fact_id provided") # Get fact data by fact id cursor = self.conn.execute("""select * from factdata where fact_id=?""", (fact["id"], )) data = dict([(item["key"], item["value"]) for item in cursor]) categories = [Category(cat["name"]) for cat in self.conn.execute("""select cat.name from categories as cat, fact_categories as f_cat where f_cat.category_id=cat.id and f_cat.fact_id=?""", (fact["id"], ))] card_type = card_type_by_id(str(fact["facttype_id"])) return Fact(data, card_type, categories, uid=fact['guid'], added=fact['ctime'])
def save(self, path): path = expand_path(path, config().basedir) # Work around a sip bug: don't store card types, but their ids. for f in self.facts: f.card_type = f.card_type.id # Don't erase a database which failed to load. if self.load_failed == True: return try: # Write to a backup file first, as shutting down Windows can # interrupt the dump command and corrupt the database. outfile = file(path + "~", 'wb') db = [self.start_date, self.categories, self.facts, self.fact_views, self.cards] cPickle.dump(db, outfile) outfile.close() shutil.move(path + "~", path) # Should be atomic. except: print traceback_string() raise SaveError() config()["path"] = contract_path(path, config().basedir) # Work around sip bug again. for f in self.facts: f.card_type = card_type_by_id(f.card_type)