changeset 567:c2be0a0e049e find-move-scp

cont
author Sebastien Jodogne <s.jodogne@gmail.com>
date Thu, 19 Sep 2013 17:43:38 +0200
parents c931ac02db82
children ce5d2040c47b
files CMakeLists.txt Core/DicomFormat/DicomMap.cpp Core/DicomFormat/DicomMap.h OrthancServer/DatabaseWrapper.cpp OrthancServer/DatabaseWrapper.h OrthancServer/PrepareDatabase.sql OrthancServer/PrepareDatabaseV4.sql UnitTests/main.cpp
diffstat 8 files changed, 112 insertions(+), 5 deletions(-) [+]
line wrap: on
line diff
--- 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
   )
--- 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<DicomTag>& 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<DicomTag>& result, ResourceType level)
+  {
+    result.clear();
+    GetMainDicomTagsInternal(result, level);
+  }
+
+
+  void DicomMap::GetMainDicomTags(std::set<DicomTag>& result)
+  {
+    result.clear();
+    GetMainDicomTagsInternal(result, ResourceType_Patient);
+    GetMainDicomTagsInternal(result, ResourceType_Study);
+    GetMainDicomTagsInternal(result, ResourceType_Series);
+    GetMainDicomTagsInternal(result, ResourceType_Instance);
+  }
 }
--- 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 <set>
 #include <map>
 #include <json/json.h>
 
@@ -64,6 +65,8 @@
     void ExtractTags(DicomMap& source,
                      const DicomTag* tags,
                      size_t count) const;
+   
+    static void GetMainDicomTagsInternal(std::set<DicomTag>& 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<DicomTag>& result, ResourceType level);
+
+    static void GetMainDicomTags(std::set<DicomTag>& result);
   };
 }
--- 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<unsigned int>(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<DicomTag> requiredTags;
+    
+  }
 }
--- 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);
--- 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);
 
--- /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);
--- 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));
 }