From bed534690981df575f5e6000c28c6b7b6c0d84f4 Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Sat, 13 Sep 2008 15:29:26 +0000 Subject: Add command to undelete a file, to complete the set of commands implemented by the bbstored server. --- bin/bbstored/BackupCommands.cpp | 24 +++++++++++ bin/bbstored/BackupStoreContext.cpp | 82 ++++++++++++++++++++++++++++++++++++- bin/bbstored/BackupStoreContext.h | 1 + bin/bbstored/backupprotocol.txt | 6 +++ 4 files changed, 112 insertions(+), 1 deletion(-) (limited to 'bin') diff --git a/bin/bbstored/BackupCommands.cpp b/bin/bbstored/BackupCommands.cpp index b5ae365c..38cda234 100644 --- a/bin/bbstored/BackupCommands.cpp +++ b/bin/bbstored/BackupCommands.cpp @@ -607,6 +607,30 @@ std::auto_ptr BackupProtocolServerDeleteFile::DoCommand(BackupPr } +// -------------------------------------------------------------------------- +// +// Function +// Name: BackupProtocolServerUndeleteFile::DoCommand( +// BackupProtocolServer &, BackupStoreContext &) +// Purpose: Undelete a file +// Created: 2008-09-12 +// +// -------------------------------------------------------------------------- +std::auto_ptr BackupProtocolServerUndeleteFile::DoCommand( + BackupProtocolServer &rProtocol, BackupStoreContext &rContext) +{ + CHECK_PHASE(Phase_Commands) + CHECK_WRITEABLE_SESSION + + // Context handles this + bool result = rContext.UndeleteFile(mObjectID, mInDirectory); + + // return the object ID or zero for not found + return std::auto_ptr( + new BackupProtocolServerSuccess(result ? mObjectID : 0)); +} + + // -------------------------------------------------------------------------- // // Function diff --git a/bin/bbstored/BackupStoreContext.cpp b/bin/bbstored/BackupStoreContext.cpp index 8334658a..f8108beb 100644 --- a/bin/bbstored/BackupStoreContext.cpp +++ b/bin/bbstored/BackupStoreContext.cpp @@ -695,6 +695,7 @@ bool BackupStoreContext::DeleteFile(const BackupStoreFilename &rFilename, int64_ { THROW_EXCEPTION(BackupStoreException, StoreInfoNotLoaded) } + if(mReadOnly) { THROW_EXCEPTION(BackupStoreException, ContextIsReadOnly) @@ -759,12 +760,91 @@ bool BackupStoreContext::DeleteFile(const BackupStoreFilename &rFilename, int64_ RemoveDirectoryFromCache(InDirectory); throw; } - return fileExisted; } +// -------------------------------------------------------------------------- +// +// Function +// Name: BackupStoreContext::DeleteFile(const BackupStoreFilename &, int64_t, int64_t &) +// Purpose: Deletes a file, returning true if the file existed. Object ID returned too, set to zero if not found. +// Created: 2003/10/21 +// +// -------------------------------------------------------------------------- +bool BackupStoreContext::UndeleteFile(int64_t ObjectID, int64_t InDirectory) +{ + // Essential checks! + if(mpStoreInfo.get() == 0) + { + THROW_EXCEPTION(BackupStoreException, StoreInfoNotLoaded) + } + + if(mReadOnly) + { + THROW_EXCEPTION(BackupStoreException, ContextIsReadOnly) + } + + // Find the directory the file is in (will exception if it fails) + BackupStoreDirectory &dir(GetDirectoryInternal(InDirectory)); + + // Setup flags + bool fileExisted = false; + bool madeChanges = false; + + // Count of deleted blocks + int64_t blocksDel = 0; + + try + { + // Iterate through directory, only looking at files which have been deleted + BackupStoreDirectory::Iterator i(dir); + BackupStoreDirectory::Entry *e = 0; + while((e = i.Next(BackupStoreDirectory::Entry::Flags_File | + BackupStoreDirectory::Entry::Flags_Deleted, 0)) != 0) + { + // Compare name + if(e->GetObjectID() == ObjectID) + { + // Check that it's definitely already deleted + ASSERT((e->GetFlags() & BackupStoreDirectory::Entry::Flags_Deleted) != 0); + // Clear deleted flag + e->RemoveFlags(BackupStoreDirectory::Entry::Flags_Deleted); + // Mark as made a change + madeChanges = true; + blocksDel -= e->GetSizeInBlocks(); + + // Is this the last version? + if((e->GetFlags() & BackupStoreDirectory::Entry::Flags_OldVersion) == 0) + { + // Yes. It's been found. + fileExisted = true; + } + } + } + + // Save changes? + if(madeChanges) + { + // Save the directory back + SaveDirectory(dir, InDirectory); + + // Modify the store info, and write + mpStoreInfo->ChangeBlocksInDeletedFiles(blocksDel); + + // Maybe postponed save of store info + SaveStoreInfo(); + } + } + catch(...) + { + RemoveDirectoryFromCache(InDirectory); + throw; + } + + return fileExisted; +} // -------------------------------------------------------------------------- diff --git a/bin/bbstored/BackupStoreContext.h b/bin/bbstored/BackupStoreContext.h index da0a7668..4cfdb601 100644 --- a/bin/bbstored/BackupStoreContext.h +++ b/bin/bbstored/BackupStoreContext.h @@ -112,6 +112,7 @@ public: void ChangeDirAttributes(int64_t Directory, const StreamableMemBlock &Attributes, int64_t AttributesModTime); bool ChangeFileAttributes(const BackupStoreFilename &rFilename, int64_t InDirectory, const StreamableMemBlock &Attributes, int64_t AttributesHash, int64_t &rObjectIDOut); bool DeleteFile(const BackupStoreFilename &rFilename, int64_t InDirectory, int64_t &rObjectIDOut); + bool UndeleteFile(int64_t ObjectID, int64_t InDirectory); void DeleteDirectory(int64_t ObjectID, bool Undelete = false); void MoveObject(int64_t ObjectID, int64_t MoveFromDirectory, int64_t MoveToDirectory, const BackupStoreFilename &rNewFilename, bool MoveAllWithSameName, bool AllowMoveOverDeletedObject); diff --git a/bin/bbstored/backupprotocol.txt b/bin/bbstored/backupprotocol.txt index d5406ae2..3eca514a 100644 --- a/bin/bbstored/backupprotocol.txt +++ b/bin/bbstored/backupprotocol.txt @@ -204,6 +204,12 @@ GetBlockIndexByName 35 Command(Success) # stream of the block index follows the reply if found ID != 0 +UndeleteFile 36 Command(Success) + int64 InDirectory + int64 ObjectID + # will return 0 if the object couldn't be found in the specified directory + + # ------------------------------------------------------------------------------------- # Information commands # ------------------------------------------------------------------------------------- -- cgit v1.2.3