# HG changeset patch # User Sebastien Jodogne # Date 1444751310 -7200 # Node ID 2ad22b2970a2f0f1ca352fddf96faab635177d8a # Parent 275780da54aeaa5f779c243e95bb7b190275b455 SearchableStudies diff -r 275780da54ae -r 2ad22b2970a2 CMakeLists.txt --- a/CMakeLists.txt Tue Oct 13 16:57:55 2015 +0200 +++ b/CMakeLists.txt Tue Oct 13 17:48:30 2015 +0200 @@ -240,6 +240,7 @@ PREPARE_DATABASE ${CMAKE_CURRENT_SOURCE_DIR}/OrthancServer/PrepareDatabase.sql UPGRADE_DATABASE_3_TO_4 ${CMAKE_CURRENT_SOURCE_DIR}/OrthancServer/Upgrade3To4.sql UPGRADE_DATABASE_4_TO_5 ${CMAKE_CURRENT_SOURCE_DIR}/OrthancServer/Upgrade4To5.sql + UPGRADE_DATABASE_5_TO_6 ${CMAKE_CURRENT_SOURCE_DIR}/OrthancServer/Upgrade5To6.sql CONFIGURATION_SAMPLE ${CMAKE_CURRENT_SOURCE_DIR}/Resources/Configuration.json DICOM_CONFORMANCE_STATEMENT ${CMAKE_CURRENT_SOURCE_DIR}/Resources/DicomConformanceStatement.txt LUA_TOOLBOX ${CMAKE_CURRENT_SOURCE_DIR}/Resources/Toolbox.lua diff -r 275780da54ae -r 2ad22b2970a2 OrthancServer/DatabaseWrapper.cpp --- a/OrthancServer/DatabaseWrapper.cpp Tue Oct 13 16:57:55 2015 +0200 +++ b/OrthancServer/DatabaseWrapper.cpp Tue Oct 13 17:48:30 2015 +0200 @@ -359,11 +359,13 @@ if (version_ == 5) { LOG(WARNING) << "Upgrading database version from 5 to 6"; - // No change in the DB schema, the step from version 5 to 6 only - // consists in reconstructing the main DICOM tags information. db_.BeginTransaction(); + ExecuteUpgradeScript(db_, EmbeddedResources::UPGRADE_DATABASE_5_TO_6); + // Reconstruct the main DICOM tags information. + Toolbox::ReconstructMainDicomTags(*this, storageArea, ResourceType_Patient); Toolbox::ReconstructMainDicomTags(*this, storageArea, ResourceType_Study); Toolbox::ReconstructMainDicomTags(*this, storageArea, ResourceType_Series); + Toolbox::ReconstructMainDicomTags(*this, storageArea, ResourceType_Instance); db_.CommitTransaction(); version_ = 6; } @@ -484,5 +486,4 @@ target[key] = s.ColumnString(1); } } - } diff -r 275780da54ae -r 2ad22b2970a2 OrthancServer/DatabaseWrapper.h --- a/OrthancServer/DatabaseWrapper.h Tue Oct 13 16:57:55 2015 +0200 +++ b/OrthancServer/DatabaseWrapper.h Tue Oct 13 17:48:30 2015 +0200 @@ -329,6 +329,11 @@ virtual void Upgrade(unsigned int targetVersion, IStorageArea& storageArea); + virtual void StoreStudyModule(int64_t id, + const DicomMap& module) + { + base_.StoreStudyModule(id, module); + } /** diff -r 275780da54ae -r 2ad22b2970a2 OrthancServer/DatabaseWrapperBase.cpp --- a/OrthancServer/DatabaseWrapperBase.cpp Tue Oct 13 16:57:55 2015 +0200 +++ b/OrthancServer/DatabaseWrapperBase.cpp Tue Oct 13 17:48:30 2015 +0200 @@ -33,6 +33,8 @@ #include "PrecompiledHeadersServer.h" #include "DatabaseWrapperBase.h" +#include "../Core/DicomFormat/DicomArray.h" + #include namespace Orthanc @@ -309,6 +311,13 @@ s.BindInt64(0, id); s.Run(); } + + // New in DB v6 (Orthanc >= 0.9.5) + { + SQLite::Statement s(db_, SQLITE_FROM_HERE, "DELETE FROM SearchableStudies WHERE id=?"); + s.BindInt64(0, id); + s.Run(); + } } @@ -712,4 +721,27 @@ target.push_back(s.ColumnInt64(0)); } } + + + void DatabaseWrapperBase::StoreStudyModule(int64_t id, + const DicomMap& module) + { + DicomArray a(module); + + for (size_t i = 0; i < a.GetSize(); i++) + { + const DicomTag& tag = a.GetElement(i).GetTag(); + const DicomValue& value = a.GetElement(i).GetValue(); + + if (!value.IsNull()) + { + SQLite::Statement s(db_, SQLITE_FROM_HERE, "INSERT INTO SearchableStudies VALUES(?, ?, ?, ?)"); + s.BindInt64(0, id); + s.BindInt(1, tag.GetGroup()); + s.BindInt(2, tag.GetElement()); + s.BindString(3, value.AsString()); + s.Run(); + } + } + } } diff -r 275780da54ae -r 2ad22b2970a2 OrthancServer/DatabaseWrapperBase.h --- a/OrthancServer/DatabaseWrapperBase.h Tue Oct 13 16:57:55 2015 +0200 +++ b/OrthancServer/DatabaseWrapperBase.h Tue Oct 13 17:48:30 2015 +0200 @@ -42,6 +42,7 @@ #include "ServerEnumerations.h" #include +#include namespace Orthanc @@ -51,7 +52,7 @@ * database plugin whose code is in * "../Plugins/Samples/DatabasePlugin". **/ - class DatabaseWrapperBase + class DatabaseWrapperBase : public boost::noncopyable { private: SQLite::Connection& db_; @@ -192,6 +193,9 @@ void LookupIdentifier(std::list& target, const std::string& value); + + void StoreStudyModule(int64_t id, + const DicomMap& module); }; } diff -r 275780da54ae -r 2ad22b2970a2 OrthancServer/IDatabaseWrapper.h --- a/OrthancServer/IDatabaseWrapper.h Tue Oct 13 16:57:55 2015 +0200 +++ b/OrthancServer/IDatabaseWrapper.h Tue Oct 13 17:48:30 2015 +0200 @@ -193,5 +193,8 @@ virtual void Upgrade(unsigned int targetVersion, IStorageArea& storageArea) = 0; + + virtual void StoreStudyModule(int64_t id, + const DicomMap& module) = 0; }; } diff -r 275780da54ae -r 2ad22b2970a2 OrthancServer/PrepareDatabase.sql --- a/OrthancServer/PrepareDatabase.sql Tue Oct 13 16:57:55 2015 +0200 +++ b/OrthancServer/PrepareDatabase.sql Tue Oct 13 17:48:30 2015 +0200 @@ -27,6 +27,15 @@ PRIMARY KEY(id, tagGroup, tagElement) ); +-- The following table was added in Orthanc 0.9.5 (database v6) +CREATE TABLE SearchableStudies( + id INTEGER REFERENCES Resources(internalId) ON DELETE CASCADE, + tagGroup INTEGER, + tagElement INTEGER, + value TEXT, -- assumed to be in upper case + PRIMARY KEY(id, tagGroup, tagElement) + ); + CREATE TABLE Metadata( id INTEGER REFERENCES Resources(internalId) ON DELETE CASCADE, type INTEGER, @@ -86,6 +95,10 @@ CREATE INDEX DicomIdentifiersIndex2 ON DicomIdentifiers(tagGroup, tagElement); CREATE INDEX DicomIdentifiersIndexValues ON DicomIdentifiers(value COLLATE BINARY); +-- The 2 following indexes were added in Orthanc 0.9.5 (database v6) +CREATE INDEX SearchableStudiesIndex1 ON SearchableStudies(id); +CREATE INDEX SearchableStudiesIndexValues ON SearchableStudies(value COLLATE BINARY); + CREATE INDEX ChangesIndex ON Changes(internalId); CREATE TRIGGER AttachedFileDeleted diff -r 275780da54ae -r 2ad22b2970a2 OrthancServer/ServerIndex.cpp --- a/OrthancServer/ServerIndex.cpp Tue Oct 13 16:57:55 2015 +0200 +++ b/OrthancServer/ServerIndex.cpp Tue Oct 13 17:48:30 2015 +0200 @@ -687,7 +687,14 @@ { study = CreateResource(hasher.HashStudy(), ResourceType_Study); Toolbox::SetMainDicomTags(db_, study, ResourceType_Study, dicomSummary, true); - Toolbox::SetMainDicomTags(db_, study, ResourceType_Patient, dicomSummary, false); // New in version 0.9.5 (db v6) + + // New in version 0.9.5 (db v6) + Toolbox::SetMainDicomTags(db_, study, ResourceType_Patient, dicomSummary, false); + + DicomMap module; + Toolbox::ExtractModule(module, dicomSummary, DicomModule_Patient, true /* normalize */); + Toolbox::ExtractModule(module, dicomSummary, DicomModule_Study, true /* normalize */); + db_.StoreStudyModule(study, module); } // Create the patient if needed diff -r 275780da54ae -r 2ad22b2970a2 OrthancServer/ServerToolbox.cpp --- a/OrthancServer/ServerToolbox.cpp Tue Oct 13 16:57:55 2015 +0200 +++ b/OrthancServer/ServerToolbox.cpp Tue Oct 13 17:48:30 2015 +0200 @@ -307,11 +307,19 @@ break; case ResourceType_Study: + { Toolbox::SetMainDicomTags(database, resource, ResourceType_Study, dicomSummary, true); // Duplicate the patient tags at the study level (new in Orthanc 0.9.5 - db v6) Toolbox::SetMainDicomTags(database, resource, ResourceType_Patient, dicomSummary, false); + + DicomMap module; + Toolbox::ExtractModule(module, dicomSummary, DicomModule_Patient, true /* normalize */); + Toolbox::ExtractModule(module, dicomSummary, DicomModule_Study, true /* normalize */); + database.StoreStudyModule(resource, module); + break; + } case ResourceType_Series: Toolbox::SetMainDicomTags(database, resource, ResourceType_Series, dicomSummary, true); @@ -326,5 +334,34 @@ } } } + + + void ExtractModule(DicomMap& result, // WARNING: Will not be cleared! + const DicomMap& summary, + DicomModule module, + bool normalize) + { + typedef std::set ModuleTags; + ModuleTags moduleTags; + DicomTag::AddTagsForModule(moduleTags, module); + + for (ModuleTags::const_iterator tag = moduleTags.begin(); tag != moduleTags.end(); ++tag) + { + const DicomValue* value = summary.TestAndGetValue(*tag); + if (value != NULL && + !value->IsNull()) + { + std::string t = value->AsString(); + + if (normalize) + { + t = StripSpaces(ConvertToAscii(t)); + ToUpperCase(t); + } + + result.SetValue(*tag, t); + } + } + } } } diff -r 275780da54ae -r 2ad22b2970a2 OrthancServer/ServerToolbox.h --- a/OrthancServer/ServerToolbox.h Tue Oct 13 16:57:55 2015 +0200 +++ b/OrthancServer/ServerToolbox.h Tue Oct 13 17:48:30 2015 +0200 @@ -60,5 +60,10 @@ void ReconstructMainDicomTags(IDatabaseWrapper& database, IStorageArea& storageArea, ResourceType level); + + void ExtractModule(DicomMap& result, // WARNING: Will not be cleared! + const DicomMap& summary, + DicomModule module, + bool normalize); } } diff -r 275780da54ae -r 2ad22b2970a2 OrthancServer/Upgrade5To6.sql --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/OrthancServer/Upgrade5To6.sql Tue Oct 13 17:48:30 2015 +0200 @@ -0,0 +1,21 @@ +-- This SQLite script updates the version of the Orthanc database from 5 to 6. + + +-- Add a new table to enable full-text indexed search over studies + +CREATE TABLE SearchableStudies( + id INTEGER REFERENCES Resources(internalId) ON DELETE CASCADE, + tagGroup INTEGER, + tagElement INTEGER, + value TEXT, -- assumed to be in upper case + PRIMARY KEY(id, tagGroup, tagElement) + ); + +CREATE INDEX SearchableStudiesIndex1 ON SearchableStudies(id); +CREATE INDEX SearchableStudiesIndexValues ON SearchableStudies(value COLLATE BINARY); + + +-- Change the database version +-- The "1" corresponds to the "GlobalProperty_DatabaseSchemaVersion" enumeration + +UPDATE GlobalProperties SET value="6" WHERE property=1; diff -r 275780da54ae -r 2ad22b2970a2 Plugins/Engine/OrthancPluginDatabase.cpp --- a/Plugins/Engine/OrthancPluginDatabase.cpp Tue Oct 13 16:57:55 2015 +0200 +++ b/Plugins/Engine/OrthancPluginDatabase.cpp Tue Oct 13 17:48:30 2015 +0200 @@ -869,6 +869,14 @@ } + void OrthancPluginDatabase::StoreStudyModule(int64_t id, + const DicomMap& module) + { + // TODO + throw OrthancException(ErrorCode_NotImplemented); + } + + void OrthancPluginDatabase::AnswerReceived(const _OrthancPluginDatabaseAnswer& answer) { if (answer.type == _OrthancPluginDatabaseAnswerType_None) diff -r 275780da54ae -r 2ad22b2970a2 Plugins/Engine/OrthancPluginDatabase.h --- a/Plugins/Engine/OrthancPluginDatabase.h Tue Oct 13 16:57:55 2015 +0200 +++ b/Plugins/Engine/OrthancPluginDatabase.h Tue Oct 13 17:48:30 2015 +0200 @@ -254,6 +254,9 @@ virtual void Upgrade(unsigned int targetVersion, IStorageArea& storageArea); + virtual void StoreStudyModule(int64_t id, + const DicomMap& module); + void AnswerReceived(const _OrthancPluginDatabaseAnswer& answer); }; }