[Box Backup-commit] COMMIT r2282 - box/trunk/bin/bbstored

boxbackup-dev@fluffy.co.uk boxbackup-dev@fluffy.co.uk
Sat, 13 Sep 2008 16:29:27 +0100 (BST)


Author: chris
Date: 2008-09-13 16:29:26 +0100 (Sat, 13 Sep 2008)
New Revision: 2282

Modified:
   box/trunk/bin/bbstored/BackupCommands.cpp
   box/trunk/bin/bbstored/BackupStoreContext.cpp
   box/trunk/bin/bbstored/BackupStoreContext.h
   box/trunk/bin/bbstored/backupprotocol.txt
Log:
Add command to undelete a file, to complete the set of commands
implemented by the bbstored server.


Modified: box/trunk/bin/bbstored/BackupCommands.cpp
===================================================================
--- box/trunk/bin/bbstored/BackupCommands.cpp	2008-09-13 15:28:38 UTC (rev 2281)
+++ box/trunk/bin/bbstored/BackupCommands.cpp	2008-09-13 15:29:26 UTC (rev 2282)
@@ -610,6 +610,30 @@
 // --------------------------------------------------------------------------
 //
 // Function
+//		Name:    BackupProtocolServerUndeleteFile::DoCommand(
+//			 BackupProtocolServer &, BackupStoreContext &)
+//		Purpose: Undelete a file
+//		Created: 2008-09-12
+//
+// --------------------------------------------------------------------------
+std::auto_ptr<ProtocolObject> 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<ProtocolObject>(
+		new BackupProtocolServerSuccess(result ? mObjectID : 0));
+}
+
+
+// --------------------------------------------------------------------------
+//
+// Function
 //		Name:    BackupProtocolServerDeleteDirectory::DoCommand(BackupProtocolServer &, BackupStoreContext &)
 //		Purpose: Delete a directory
 //		Created: 2003/10/21

Modified: box/trunk/bin/bbstored/BackupStoreContext.cpp
===================================================================
--- box/trunk/bin/bbstored/BackupStoreContext.cpp	2008-09-13 15:28:38 UTC (rev 2281)
+++ box/trunk/bin/bbstored/BackupStoreContext.cpp	2008-09-13 15:29:26 UTC (rev 2282)
@@ -695,6 +695,7 @@
 	{
 		THROW_EXCEPTION(BackupStoreException, StoreInfoNotLoaded)
 	}
+
 	if(mReadOnly)
 	{
 		THROW_EXCEPTION(BackupStoreException, ContextIsReadOnly)
@@ -759,14 +760,93 @@
 		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;
+}
+
+
 // --------------------------------------------------------------------------
 //
 // Function

Modified: box/trunk/bin/bbstored/BackupStoreContext.h
===================================================================
--- box/trunk/bin/bbstored/BackupStoreContext.h	2008-09-13 15:28:38 UTC (rev 2281)
+++ box/trunk/bin/bbstored/BackupStoreContext.h	2008-09-13 15:29:26 UTC (rev 2282)
@@ -112,6 +112,7 @@
 	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);
 

Modified: box/trunk/bin/bbstored/backupprotocol.txt
===================================================================
--- box/trunk/bin/bbstored/backupprotocol.txt	2008-09-13 15:28:38 UTC (rev 2281)
+++ box/trunk/bin/bbstored/backupprotocol.txt	2008-09-13 15:29:26 UTC (rev 2282)
@@ -204,6 +204,12 @@
 	# 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
 # -------------------------------------------------------------------------------------