# HG changeset patch # User Sebastien Jodogne # Date 1379605418 -7200 # Node ID c2be0a0e049e92d01a6f8545c5770e0ffeea5d7d # Parent c931ac02db821c0c9d7c40983aa9e03c83c4d87f cont diff -r c931ac02db82 -r c2be0a0e049e CMakeLists.txt --- a/CMakeLists.txt Wed Sep 18 16:58:27 2013 +0200 +++ b/CMakeLists.txt Thu Sep 19 17:43:38 2013 +0200 @@ -73,6 +73,7 @@ # Prepare the embedded files set(EMBEDDED_FILES PREPARE_DATABASE ${CMAKE_CURRENT_SOURCE_DIR}/OrthancServer/PrepareDatabase.sql + PREPARE_DATABASE_V4 ${CMAKE_CURRENT_SOURCE_DIR}/OrthancServer/PrepareDatabaseV4.sql CONFIGURATION_SAMPLE ${CMAKE_CURRENT_SOURCE_DIR}/Resources/Configuration.json LUA_TOOLBOX ${CMAKE_CURRENT_SOURCE_DIR}/Resources/Toolbox.lua ) diff -r c931ac02db82 -r c2be0a0e049e Core/DicomFormat/DicomMap.cpp --- a/Core/DicomFormat/DicomMap.cpp Wed Sep 18 16:58:27 2013 +0200 +++ b/Core/DicomFormat/DicomMap.cpp Thu Sep 19 17:43:38 2013 +0200 @@ -331,4 +331,59 @@ IsMainDicomTag(tag, ResourceType_Series) || IsMainDicomTag(tag, ResourceType_Instance)); } + + + void DicomMap::GetMainDicomTagsInternal(std::set& result, ResourceType level) + { + DicomTag *tags = NULL; + size_t size; + + switch (level) + { + case ResourceType_Patient: + tags = patientTags; + size = sizeof(patientTags) / sizeof(DicomTag); + break; + + case ResourceType_Study: + tags = studyTags; + size = sizeof(studyTags) / sizeof(DicomTag); + break; + + case ResourceType_Series: + tags = seriesTags; + size = sizeof(seriesTags) / sizeof(DicomTag); + break; + + case ResourceType_Instance: + tags = instanceTags; + size = sizeof(instanceTags) / sizeof(DicomTag); + break; + + default: + throw OrthancException(ErrorCode_ParameterOutOfRange); + } + + for (size_t i = 0; i < size; i++) + { + result.insert(tags[i]); + } + } + + + void DicomMap::GetMainDicomTags(std::set& result, ResourceType level) + { + result.clear(); + GetMainDicomTagsInternal(result, level); + } + + + void DicomMap::GetMainDicomTags(std::set& result) + { + result.clear(); + GetMainDicomTagsInternal(result, ResourceType_Patient); + GetMainDicomTagsInternal(result, ResourceType_Study); + GetMainDicomTagsInternal(result, ResourceType_Series); + GetMainDicomTagsInternal(result, ResourceType_Instance); + } } diff -r c931ac02db82 -r c2be0a0e049e Core/DicomFormat/DicomMap.h --- a/Core/DicomFormat/DicomMap.h Wed Sep 18 16:58:27 2013 +0200 +++ b/Core/DicomFormat/DicomMap.h Thu Sep 19 17:43:38 2013 +0200 @@ -37,6 +37,7 @@ #include "DicomString.h" #include "../Enumerations.h" +#include #include #include @@ -64,6 +65,8 @@ void ExtractTags(DicomMap& source, const DicomTag* tags, size_t count) const; + + static void GetMainDicomTagsInternal(std::set& result, ResourceType level); public: DicomMap() @@ -153,5 +156,9 @@ static bool IsMainDicomTag(const DicomTag& tag, ResourceType level); static bool IsMainDicomTag(const DicomTag& tag); + + static void GetMainDicomTags(std::set& result, ResourceType level); + + static void GetMainDicomTags(std::set& result); }; } diff -r c931ac02db82 -r c2be0a0e049e OrthancServer/DatabaseWrapper.cpp --- a/OrthancServer/DatabaseWrapper.cpp Wed Sep 18 16:58:27 2013 +0200 +++ b/OrthancServer/DatabaseWrapper.cpp Thu Sep 19 17:43:38 2013 +0200 @@ -807,7 +807,7 @@ db_.Execute(query); } - // Sanity check of the version of the database + // Check the version of the database std::string version = GetGlobalProperty(GlobalProperty_DatabaseSchemaVersion, "Unknown"); bool ok = false; try @@ -815,9 +815,27 @@ LOG(INFO) << "Version of the Orthanc database: " << version; unsigned int v = boost::lexical_cast(version); - // This version of Orthanc is only compatible with version 3 of - // the DB schema (since Orthanc 0.3.2) - ok = (v == 3); + // This version of Orthanc is only compatible with versions 3 + // (Orthanc 0.3.2 to 0.6.1) and 4 (since Orthanc 0.6.2) of the + // DB schema + ok = (v == 3 || v == 4); + + if (v == 3) + { + LOG(WARNING) << "Upgrading the database from version 3 to version 4 (reconstructing the index)"; + + // Reconstruct the index for case insensitive queries in C-FIND + db_.Execute("DROP INDEX IF EXISTS MainDicomTagsIndexValues;"); + db_.Execute("DROP TABLE IF EXISTS AvailableTags;"); + + std::string query; + EmbeddedResources::GetFileResource(query, EmbeddedResources::PREPARE_DATABASE_V4); + db_.Execute(query); + + db_.Execute("INSERT INTO AvailableTags SELECT DISTINCT tagGroup, tagElement FROM MainDicomTags;"); + + //SetGlobalProperty(GlobalProperty_DatabaseSchemaVersion, "4"); + } } catch (boost::bad_lexical_cast&) { @@ -828,6 +846,8 @@ throw OrthancException(ErrorCode_IncompatibleDatabaseVersion); } + CompleteMainDicomTags(); + signalRemainingAncestor_ = new Internals::SignalRemainingAncestor; db_.Register(signalRemainingAncestor_); db_.Register(new Internals::SignalFileDeleted(listener_)); @@ -995,4 +1015,11 @@ result.push_back(s.ColumnInt64(0)); } } + + + void DatabaseWrapper::CompleteMainDicomTags() + { + std::set requiredTags; + + } } diff -r c931ac02db82 -r c2be0a0e049e OrthancServer/DatabaseWrapper.h --- a/OrthancServer/DatabaseWrapper.h Wed Sep 18 16:58:27 2013 +0200 +++ b/OrthancServer/DatabaseWrapper.h Thu Sep 19 17:43:38 2013 +0200 @@ -72,6 +72,8 @@ int64_t since, unsigned int maxResults); + void CompleteMainDicomTags(); + public: void SetGlobalProperty(GlobalProperty property, const std::string& value); diff -r c931ac02db82 -r c2be0a0e049e OrthancServer/PrepareDatabase.sql --- a/OrthancServer/PrepareDatabase.sql Wed Sep 18 16:58:27 2013 +0200 +++ b/OrthancServer/PrepareDatabase.sql Thu Sep 19 17:43:38 2013 +0200 @@ -67,7 +67,6 @@ CREATE INDEX MainDicomTagsIndex1 ON MainDicomTags(id); CREATE INDEX MainDicomTagsIndex2 ON MainDicomTags(tagGroup, tagElement); -CREATE INDEX MainDicomTagsIndexValues ON MainDicomTags(value COLLATE BINARY); CREATE INDEX ChangesIndex ON Changes(internalId); diff -r c931ac02db82 -r c2be0a0e049e OrthancServer/PrepareDatabaseV4.sql --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/OrthancServer/PrepareDatabaseV4.sql Thu Sep 19 17:43:38 2013 +0200 @@ -0,0 +1,12 @@ +-- New in database version 4 +CREATE TABLE AvailableTags( + tagGroup INTEGER, + tagElement INTEGER, + PRIMARY KEY(tagGroup, tagElement) + ); + +-- Until database version 4, the following index was set to "COLLATE +-- BINARY". This implies case-sensitive searches, but DICOM C-Find +-- requires case-insensitive searches. +-- http://www.sqlite.org/optoverview.html#like_opt +CREATE INDEX MainDicomTagsIndexValues ON MainDicomTags(value COLLATE NOCASE); diff -r c931ac02db82 -r c2be0a0e049e UnitTests/main.cpp --- a/UnitTests/main.cpp Wed Sep 18 16:58:27 2013 +0200 +++ b/UnitTests/main.cpp Thu Sep 19 17:43:38 2013 +0200 @@ -127,6 +127,10 @@ t = FromDcmtkBridge::ParseTag("0020-e040"); ASSERT_EQ(0x0020, t.GetGroup()); ASSERT_EQ(0xe040, t.GetElement()); + + // Test ==() and !=() operators + ASSERT_TRUE(DICOM_TAG_PATIENT_ID == DicomTag(0x0010, 0x0020)); + ASSERT_FALSE(DICOM_TAG_PATIENT_ID != DicomTag(0x0010, 0x0020)); }