# HG changeset patch # User Sebastien Jodogne # Date 1354034179 -3600 # Node ID bee20e97883576de498138045bd6f70130d08be1 # Parent 9c58b2b03cf0b067d88043e191c18b7f430b0e39 refactoring of delete diff -r 9c58b2b03cf0 -r bee20e978835 Core/FileStorage.cpp --- a/Core/FileStorage.cpp Tue Nov 27 16:49:22 2012 +0100 +++ b/Core/FileStorage.cpp Tue Nov 27 17:36:19 2012 +0100 @@ -40,6 +40,7 @@ #include "Uuid.h" #include +#include static std::string ToString(const boost::filesystem::path& p) { @@ -275,6 +276,7 @@ void FileStorage::Remove(const std::string& uuid) { + LOG(INFO) << "Deleting file " << uuid; namespace fs = boost::filesystem; fs::path p = GetPath(uuid); diff -r 9c58b2b03cf0 -r bee20e978835 OrthancExplorer/explorer.js --- a/OrthancExplorer/explorer.js Tue Nov 27 16:49:22 2012 +0100 +++ b/OrthancExplorer/explorer.js Tue Nov 27 17:36:19 2012 +0100 @@ -557,7 +557,7 @@ if (ancestor == null) $.mobile.changePage('#find-patients'); else - $.mobile.changePage('#' + ancestor.Type + '?uuid=' + ancestor.ID); + $.mobile.changePage('#' + ancestor.Type.toLowerCase() + '?uuid=' + ancestor.ID); } }); } diff -r 9c58b2b03cf0 -r bee20e978835 OrthancServer/ServerEnumerations.cpp --- a/OrthancServer/ServerEnumerations.cpp Tue Nov 27 16:49:22 2012 +0100 +++ b/OrthancServer/ServerEnumerations.cpp Tue Nov 27 17:36:19 2012 +0100 @@ -56,6 +56,27 @@ } } + const char* GetBasePath(ResourceType type) + { + switch (type) + { + case ResourceType_Patient: + return "patients"; + + case ResourceType_Study: + return "studies"; + + case ResourceType_Series: + return "series"; + + case ResourceType_Instance: + return "instances"; + + default: + throw OrthancException(ErrorCode_ParameterOutOfRange); + } + } + const char* ToString(SeriesStatus status) { switch (status) diff -r 9c58b2b03cf0 -r bee20e978835 OrthancServer/ServerEnumerations.h --- a/OrthancServer/ServerEnumerations.h Tue Nov 27 16:49:22 2012 +0100 +++ b/OrthancServer/ServerEnumerations.h Tue Nov 27 17:36:19 2012 +0100 @@ -88,5 +88,7 @@ const char* ToString(ResourceType type); + const char* GetBasePath(ResourceType type); + const char* ToString(SeriesStatus status); } diff -r 9c58b2b03cf0 -r bee20e978835 OrthancServer/ServerIndex.cpp --- a/OrthancServer/ServerIndex.cpp Tue Nov 27 16:49:22 2012 +0100 +++ b/OrthancServer/ServerIndex.cpp Tue Nov 27 17:36:19 2012 +0100 @@ -53,18 +53,84 @@ { namespace Internals { + class ServerIndexListenerTodo : public IServerIndexListener + { + private: + FileStorage& fileStorage_; + bool hasRemainingLevel_; + ResourceType remainingType_; + std::string remainingPublicId_; + + public: + ServerIndexListenerTodo(FileStorage& fileStorage) : + fileStorage_(fileStorage), + hasRemainingLevel_(false) + { + assert(ResourceType_Patient < ResourceType_Study && + ResourceType_Study < ResourceType_Series && + ResourceType_Series < ResourceType_Instance); + } + + void Reset() + { + hasRemainingLevel_ = false; + } + + virtual void SignalRemainingAncestor(ResourceType parentType, + const std::string& publicId) + { + LOG(INFO) << "Remaining ancestor \"" << publicId << "\" (" << parentType << ")"; + + if (hasRemainingLevel_) + { + if (parentType < remainingType_) + { + remainingType_ = parentType; + remainingPublicId_ = publicId; + } + } + else + { + hasRemainingLevel_ = true; + remainingType_ = parentType; + remainingPublicId_ = publicId; + } + } + + virtual void SignalFileDeleted(const std::string& fileUuid) + { + assert(Toolbox::IsUuid(fileUuid)); + fileStorage_.Remove(fileUuid); + } + + bool HasRemainingLevel() const + { + return hasRemainingLevel_; + } + + ResourceType GetRemainingType() const + { + assert(HasRemainingLevel()); + return remainingType_; + } + + const std::string& GetRemainingPublicId() const + { + assert(HasRemainingLevel()); + return remainingPublicId_; + } + }; + + class DeleteFromFileStorageFunction : public SQLite::IScalarFunction { private: - std::auto_ptr fileStorage_; + FileStorage& fileStorage_; public: - DeleteFromFileStorageFunction(const std::string& path) + DeleteFromFileStorageFunction(FileStorage& fileStorage) : + fileStorage_(fileStorage) { - if (path != ":memory:") - { - fileStorage_.reset(new FileStorage(path)); - } } virtual const char* GetName() const @@ -79,18 +145,12 @@ virtual void Compute(SQLite::FunctionContext& context) { - if (fileStorage_.get() == NULL) - { - // In-memory index, for unit tests - return; - } - std::string fileUuid = context.GetStringValue(0); LOG(INFO) << "Removing file [" << fileUuid << "]"; if (Toolbox::IsUuid(fileUuid)) { - fileStorage_->Remove(fileUuid); + fileStorage_.Remove(fileUuid); } } }; @@ -350,6 +410,46 @@ { boost::mutex::scoped_lock scoped_lock(mutex_); + + { + listener2_->Reset(); + + std::auto_ptr t(db2_->StartTransaction()); + t->Begin(); + + int64_t id; + ResourceType type; + if (!db2_->LookupResource(uuid, id, type)) + { + return false; + } + + db2_->DeleteResource(id); + + if (listener2_->HasRemainingLevel()) + { + ResourceType type = listener2_->GetRemainingType(); + const std::string& uuid = listener2_->GetRemainingPublicId(); + + target["RemainingAncestor"] = Json::Value(Json::objectValue); + target["RemainingAncestor"]["Path"] = std::string(GetBasePath(type)) + "/" + uuid; + target["RemainingAncestor"]["Type"] = ToString(type); + target["RemainingAncestor"]["ID"] = uuid; + } + else + { + target["RemainingAncestor"] = Json::nullValue; + } + + std::cout << target << std::endl; + + t->Commit(); + + return true; + } + + + deletedLevels_->Clear(); SQLite::Statement s(db_, "DELETE FROM " + tableName + " WHERE uuid=?"); @@ -385,42 +485,23 @@ } - namespace Internals + ServerIndex::ServerIndex(FileStorage& fileStorage, + const std::string& dbPath) { - class ServerIndexListenerTodo : public IServerIndexListener - { - public: - virtual void SignalRemainingAncestor(ResourceType parentType, - const std::string& publicId) - { - LOG(INFO) << "Remaning ancestor \"" << publicId << "\" (" << parentType << ")"; - } + listener2_.reset(new Internals::ServerIndexListenerTodo(fileStorage)); - virtual void SignalFileDeleted(const std::string& fileUuid) - { - LOG(INFO) << "Deleted file " << fileUuid; - } - - }; - } - - - ServerIndex::ServerIndex(const std::string& storagePath) - { - listener2_.reset(new Internals::ServerIndexListenerTodo); - - if (storagePath == ":memory:") + if (dbPath == ":memory:") { db_.OpenInMemory(); db2_.reset(new DatabaseWrapper(*listener2_)); } else { - boost::filesystem::path p = storagePath; + boost::filesystem::path p = dbPath; try { - boost::filesystem::create_directories(storagePath); + boost::filesystem::create_directories(p); } catch (boost::filesystem::filesystem_error) { @@ -432,7 +513,7 @@ db_.Open(p.string()); } - db_.Register(new Internals::DeleteFromFileStorageFunction(storagePath)); + db_.Register(new Internals::DeleteFromFileStorageFunction(fileStorage)); deletedLevels_ = (Internals::SignalDeletedLevelFunction*) db_.Register(new Internals::SignalDeletedLevelFunction); diff -r 9c58b2b03cf0 -r bee20e978835 OrthancServer/ServerIndex.h --- a/OrthancServer/ServerIndex.h Tue Nov 27 16:49:22 2012 +0100 +++ b/OrthancServer/ServerIndex.h Tue Nov 27 17:36:19 2012 +0100 @@ -47,6 +47,7 @@ namespace Internals { class SignalDeletedLevelFunction; + class ServerIndexListenerTodo; } @@ -56,7 +57,7 @@ SQLite::Connection db_; boost::mutex mutex_; - std::auto_ptr listener2_; + std::auto_ptr listener2_; std::auto_ptr db2_; // DO NOT delete the following one, SQLite::Connection will do it automatically @@ -114,7 +115,8 @@ SeriesStatus GetSeriesStatus(int id); public: - ServerIndex(const std::string& storagePath); + ServerIndex(FileStorage& fileStorage, + const std::string& dbPath); StoreStatus Store(const DicomMap& dicomSummary, const std::string& fileUuid, diff -r 9c58b2b03cf0 -r bee20e978835 OrthancServer/main.cpp --- a/OrthancServer/main.cpp Tue Nov 27 16:49:22 2012 +0100 +++ b/OrthancServer/main.cpp Tue Nov 27 17:36:19 2012 +0100 @@ -217,9 +217,10 @@ OrthancInitialize(); } - std::string storageDirectory = GetGlobalStringParameter("StorageDirectory", "OrthancStorage"); - ServerIndex index(storageDirectory); - MyDicomStoreFactory storeScp(index, storageDirectory); + boost::filesystem::path storageDirectory = GetGlobalStringParameter("StorageDirectory", "OrthancStorage"); + FileStorage storage(storageDirectory.string()); + ServerIndex index(storage, storageDirectory.string()); + MyDicomStoreFactory storeScp(index, storageDirectory.string()); { // DICOM server @@ -257,7 +258,7 @@ httpServer.RegisterHandler(new FilesystemHttpHandler("/app", ORTHANC_PATH "/OrthancExplorer")); #endif - httpServer.RegisterHandler(new OrthancRestApi(index, storageDirectory)); + httpServer.RegisterHandler(new OrthancRestApi(index, storageDirectory.string())); // GO !!! httpServer.Start();