def restore_database(user_hash, time=None): assert user_hash # If the database doesn't exist, get_default_store will fail try: default_store = get_default_store() except Exception: default_store = None if default_store is not None and db_settings.has_database(): try: default_store.lock_database() except DatabaseError: raise TaskException( "Could not lock database. This means that there are other " "clients connected. Make sure to close every Stoq client " "before updating the database") except Exception: raise TaskException( "Database is empty or in a corrupted state. Fix or drop it " "before trying to proceed with the restore") else: default_store.unlock_database() # FIXME: Windows will not liberate resource for other process to # write to the file. We should write our own TemporaryFile on Stoq # that handles all those cases for us and use here with tempfile.NamedTemporaryFile(delete=False) as f: pass try: if not db_settings.dump_database(f.name): raise TaskException("Failed to dump the database") backup_name = db_settings.restore_database(f.name) logger.info("Created a backup of the current database state on %s", backup_name) finally: os.unlink(f.name) tmp_path = tempfile.mkdtemp() try: restore_path = os.path.join(tmp_path, 'stoq') backup.restore(restore_path, user_hash, time=time) # None will make the default store be closed, which we need # to sucessfully restore the database set_default_store(None) db_settings.clean_database(db_settings.dbname, force=True) db_settings.execute_sql(os.path.join(restore_path, 'stoq.dump'), lock_database=True) logger.info("Backup restore finished sucessfully") finally: # get_default_store will recreate it (since we closed it above) get_default_store() shutil.rmtree(tmp_path, ignore_errors=True)
def restore_database(user_hash, time=None): assert user_hash # If the database doesn't exist, get_default_store will fail try: default_store = get_default_store() except Exception: default_store = None if default_store is not None and db_settings.has_database(): try: default_store.lock_database() except DatabaseError: raise TaskException( "Could not lock database. This means that there are other " "clients connected. Make sure to close every Stoq client " "before updating the database") except Exception: raise TaskException( "Database is empty or in a corrupted state. Fix or drop it " "before trying to proceed with the restore") else: default_store.unlock_database() # FIXME: Windows will not liberate resource for other process to # write to the file. We should write our own TemporaryFile on Stoq # that handles all those cases for us and use here with tempfile.NamedTemporaryFile(delete=False) as f: pass try: if not db_settings.dump_database(f.name): raise TaskException("Failed to dump the database") backup_name = db_settings.restore_database(f.name) logger.info("Created a backup of the current database state on %s", backup_name) finally: os.unlink(f.name) tmp_path = tempfile.mkdtemp() try: restore_path = os.path.join(tmp_path, 'stoq') logger.info("restoring database to %s", restore_path) backup.restore(restore_path, user_hash, time=time) # None will make the default store be closed, which we need # to sucessfully restore the database set_default_store(None) db_settings.clean_database(db_settings.dbname, force=True) db_settings.execute_sql(os.path.join(restore_path, 'stoq.dump'), lock_database=True) logger.info("Backup restore finished sucessfully") finally: # get_default_store will recreate it (since we closed it above) get_default_store()