changeset 540:e72e43c7a1e2

integration OrthancMySQL-5.2->mainline
author Sebastien Jodogne <s.jodogne@gmail.com>
date Mon, 09 Sep 2024 12:45:18 +0200
parents aff02ad9fbbc (diff) e1d3da372805 (current diff)
children 9249064b675b
files MySQL/CMakeLists.txt
diffstat 17 files changed, 120 insertions(+), 35 deletions(-) [+]
line wrap: on
line diff
--- a/Framework/Common/DatabaseManager.cpp	Thu Jun 06 15:12:01 2024 +0200
+++ b/Framework/Common/DatabaseManager.cpp	Mon Sep 09 12:45:18 2024 +0200
@@ -663,13 +663,11 @@
       statement_.reset(GetManager().GetDatabase().Compile(*query));
       assert(statement_.get() != NULL);
 
+      std::unique_ptr<IResult> result(GetTransaction().Execute(*statement_, parameters));
+
       if (withResults)
       {
-        SetResult(GetTransaction().Execute(*statement_, parameters));
-      }
-      else
-      {
-        GetTransaction().Execute(*statement_, parameters);
+        SetResult(result.release());
       }
     }
     catch (Orthanc::OrthancException& e)
--- a/Framework/Plugins/DatabaseBackendAdapterV2.cpp	Thu Jun 06 15:12:01 2024 +0200
+++ b/Framework/Plugins/DatabaseBackendAdapterV2.cpp	Mon Sep 09 12:45:18 2024 +0200
@@ -1413,12 +1413,11 @@
     {
       DatabaseBackendAdapterV2::Adapter::DatabaseAccessor accessor(*adapter);
 
-      std::vector<Orthanc::DatabaseConstraint> lookup;
-      lookup.reserve(constraintsCount);
+      Orthanc::DatabaseConstraints lookup;
 
       for (uint32_t i = 0; i < constraintsCount; i++)
       {
-        lookup.push_back(Orthanc::DatabaseConstraint(constraints[i]));
+        lookup.AddConstraint(new Orthanc::DatabaseConstraint(constraints[i]));
       }
         
       std::set<std::string> noLabel;
--- a/Framework/Plugins/DatabaseBackendAdapterV3.cpp	Thu Jun 06 15:12:01 2024 +0200
+++ b/Framework/Plugins/DatabaseBackendAdapterV3.cpp	Mon Sep 09 12:45:18 2024 +0200
@@ -1640,12 +1640,11 @@
     {
       t->GetOutput().Clear();
 
-      std::vector<Orthanc::DatabaseConstraint> lookup;
-      lookup.reserve(constraintsCount);
+      Orthanc::DatabaseConstraints lookup;
 
       for (uint32_t i = 0; i < constraintsCount; i++)
       {
-        lookup.push_back(Orthanc::DatabaseConstraint(constraints[i]));
+        lookup.AddConstraint(new Orthanc::DatabaseConstraint(constraints[i]));
       }
         
       std::set<std::string> noLabel;
--- a/Framework/Plugins/DatabaseBackendAdapterV4.cpp	Thu Jun 06 15:12:01 2024 +0200
+++ b/Framework/Plugins/DatabaseBackendAdapterV4.cpp	Mon Sep 09 12:45:18 2024 +0200
@@ -544,9 +544,6 @@
                                    IndexBackend& backend,
                                    DatabaseManager& manager)
   {
-    std::vector<Orthanc::DatabaseConstraint> lookup;
-    lookup.reserve(request.lookup().size());
-
     size_t countValues = 0;
 
     for (int i = 0; i < request.lookup().size(); i++)
@@ -558,6 +555,8 @@
     std::vector<const char*> values;
     values.reserve(countValues);
 
+    Orthanc::DatabaseConstraints lookup;
+
     for (int i = 0; i < request.lookup().size(); i++)
     {
       const Orthanc::DatabasePluginMessages::DatabaseConstraint& constraint = request.lookup(i);
@@ -619,7 +618,7 @@
         }
       }
 
-      lookup.push_back(Orthanc::DatabaseConstraint(c));
+      lookup.AddConstraint(new Orthanc::DatabaseConstraint(c));
     }
 
     assert(values.size() == countValues);
--- a/Framework/Plugins/IDatabaseBackend.h	Thu Jun 06 15:12:01 2024 +0200
+++ b/Framework/Plugins/IDatabaseBackend.h	Mon Sep 09 12:45:18 2024 +0200
@@ -277,7 +277,7 @@
 #if ORTHANC_PLUGINS_HAS_DATABASE_CONSTRAINT == 1
     virtual void LookupResources(IDatabaseBackendOutput& output,
                                  DatabaseManager& manager,
-                                 const std::vector<Orthanc::DatabaseConstraint>& lookup,
+                                 const Orthanc::DatabaseConstraints& lookup,
                                  OrthancPluginResourceType queryLevel,
                                  const std::set<std::string>& labels,         // New in Orthanc 1.12.0
                                  Orthanc::LabelsConstraint labelsConstraint,  // New in Orthanc 1.12.0
--- a/Framework/Plugins/IndexBackend.cpp	Thu Jun 06 15:12:01 2024 +0200
+++ b/Framework/Plugins/IndexBackend.cpp	Mon Sep 09 12:45:18 2024 +0200
@@ -2101,7 +2101,7 @@
   // New primitive since Orthanc 1.5.2
   void IndexBackend::LookupResources(IDatabaseBackendOutput& output,
                                      DatabaseManager& manager,
-                                     const std::vector<Orthanc::DatabaseConstraint>& lookup,
+                                     const Orthanc::DatabaseConstraints& lookup,
                                      OrthancPluginResourceType queryLevel_,
                                      const std::set<std::string>& labels,
                                      Orthanc::LabelsConstraint labelsConstraint,
--- a/Framework/Plugins/IndexBackend.h	Thu Jun 06 15:12:01 2024 +0200
+++ b/Framework/Plugins/IndexBackend.h	Mon Sep 09 12:45:18 2024 +0200
@@ -303,7 +303,7 @@
     // New primitive since Orthanc 1.5.2
     virtual void LookupResources(IDatabaseBackendOutput& output,
                                  DatabaseManager& manager,
-                                 const std::vector<Orthanc::DatabaseConstraint>& lookup,
+                                 const Orthanc::DatabaseConstraints& lookup,
                                  OrthancPluginResourceType queryLevel,
                                  const std::set<std::string>& labels,
                                  Orthanc::LabelsConstraint labelsConstraint,
--- a/MySQL/CMakeLists.txt	Thu Jun 06 15:12:01 2024 +0200
+++ b/MySQL/CMakeLists.txt	Mon Sep 09 12:45:18 2024 +0200
@@ -22,7 +22,7 @@
 cmake_minimum_required(VERSION 2.8)
 project(OrthancMySQL)
 
-set(ORTHANC_PLUGIN_VERSION "5.2")
+set(ORTHANC_PLUGIN_VERSION "mainline")
 
 # This is the preferred version of the Orthanc SDK for this plugin
 set(ORTHANC_SDK_DEFAULT_VERSION "1.12.0")
--- a/MySQL/NEWS	Thu Jun 06 15:12:01 2024 +0200
+++ b/MySQL/NEWS	Mon Sep 09 12:45:18 2024 +0200
@@ -1,3 +1,6 @@
+* Fixed a memory leak when executing non cached SQL statements (rarely used)
+
+
 Release 5.2 (2024-06-06)
 ========================
 
--- a/Odbc/NEWS	Thu Jun 06 15:12:01 2024 +0200
+++ b/Odbc/NEWS	Mon Sep 09 12:45:18 2024 +0200
@@ -7,6 +7,7 @@
 Optimal Orthanc runtime: 1.12.0+
 
 * Fix check of Orthanc runtime version
+* Fixed a memory leak when executing non cached SQL statements (rarely used)
 
 
 Release 1.2 (2024-03-06)
--- a/PostgreSQL/NEWS	Thu Jun 06 15:12:01 2024 +0200
+++ b/PostgreSQL/NEWS	Mon Sep 09 12:45:18 2024 +0200
@@ -6,6 +6,7 @@
 Minimum Orthanc runtime: 1.12.3
 
 * Fix updates from plugin version 3.3 to latest version
+* Fixed a memory leak when executing non cached SQL statements (rarely used)
 
 
 Release 6.2 (2024-03-25)
--- a/Resources/Orthanc/CMake/Compiler.cmake	Thu Jun 06 15:12:01 2024 +0200
+++ b/Resources/Orthanc/CMake/Compiler.cmake	Mon Sep 09 12:45:18 2024 +0200
@@ -232,6 +232,10 @@
   endif()
 
 elseif (${CMAKE_SYSTEM_NAME} STREQUAL "Darwin")
+
+  # fix this error that appears with recent compilers on MacOS: boost/mpl/aux_/integral_wrapper.hpp:73:31: error: integer value -1 is outside the valid range of values [0, 3] for this enumeration type [-Wenum-constexpr-conversion]
+  SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wno-enum-constexpr-conversion")
+
   add_definitions(
     -D_XOPEN_SOURCE=1
     )
--- a/Resources/Orthanc/Databases/DatabaseConstraint.cpp	Thu Jun 06 15:12:01 2024 +0200
+++ b/Resources/Orthanc/Databases/DatabaseConstraint.cpp	Mon Sep 09 12:45:18 2024 +0200
@@ -245,4 +245,43 @@
     constraint.values = (tmpValues.empty() ? NULL : &tmpValues[0]);
   }
 #endif    
+
+
+  void DatabaseConstraints::Clear()
+  {
+    for (size_t i = 0; i < constraints_.size(); i++)
+    {
+      assert(constraints_[i] != NULL);
+      delete constraints_[i];
+    }
+
+    constraints_.clear();
+  }
+
+
+  void DatabaseConstraints::AddConstraint(DatabaseConstraint* constraint)
+  {
+    if (constraint == NULL)
+    {
+      throw OrthancException(ErrorCode_NullPointer);
+    }
+    else
+    {
+      constraints_.push_back(constraint);
+    }
+  }
+
+
+  const DatabaseConstraint& DatabaseConstraints::GetConstraint(size_t index) const
+  {
+    if (index >= constraints_.size())
+    {
+      throw OrthancException(ErrorCode_ParameterOutOfRange);
+    }
+    else
+    {
+      assert(constraints_[index] != NULL);
+      return *constraints_[index];
+    }
+  }
 }
--- a/Resources/Orthanc/Databases/DatabaseConstraint.h	Thu Jun 06 15:12:01 2024 +0200
+++ b/Resources/Orthanc/Databases/DatabaseConstraint.h	Mon Sep 09 12:45:18 2024 +0200
@@ -46,6 +46,8 @@
 #  endif
 #endif
 
+#include <deque>
+
 namespace Orthanc
 {
   enum ConstraintType
@@ -78,7 +80,7 @@
 
 
   // This class is also used by the "orthanc-databases" project
-  class DatabaseConstraint
+  class DatabaseConstraint : public boost::noncopyable
   {
   private:
     ResourceType              level_;
@@ -148,4 +150,33 @@
                           std::vector<const char*>& tmpValues) const;
 #endif    
   };
+
+
+  class DatabaseConstraints : public boost::noncopyable
+  {
+  private:
+    std::deque<DatabaseConstraint*>  constraints_;
+
+  public:
+    ~DatabaseConstraints()
+    {
+      Clear();
+    }
+
+    void Clear();
+
+    void AddConstraint(DatabaseConstraint* constraint);  // Takes ownership
+
+    bool IsEmpty() const
+    {
+      return constraints_.empty();
+    }
+
+    size_t GetSize() const
+    {
+      return constraints_.size();
+    }
+
+    const DatabaseConstraint& GetConstraint(size_t index) const;
+  };
 }
--- a/Resources/Orthanc/Databases/ISqlLookupFormatter.cpp	Thu Jun 06 15:12:01 2024 +0200
+++ b/Resources/Orthanc/Databases/ISqlLookupFormatter.cpp	Mon Sep 09 12:45:18 2024 +0200
@@ -475,7 +475,10 @@
   }
 
 
-  void ISqlLookupFormatter::GetLookupLevels(ResourceType& lowerLevel, ResourceType& upperLevel, const ResourceType& queryLevel, const std::vector<DatabaseConstraint>& lookup)
+  void ISqlLookupFormatter::GetLookupLevels(ResourceType& lowerLevel,
+                                            ResourceType& upperLevel,
+                                            const ResourceType& queryLevel,
+                                            const DatabaseConstraints& lookup)
   {
     assert(ResourceType_Patient < ResourceType_Study &&
            ResourceType_Study < ResourceType_Series &&
@@ -484,9 +487,9 @@
     lowerLevel = queryLevel;
     upperLevel = queryLevel;
 
-    for (size_t i = 0; i < lookup.size(); i++)
+    for (size_t i = 0; i < lookup.GetSize(); i++)
     {
-      ResourceType level = lookup[i].GetLevel();
+      ResourceType level = lookup.GetConstraint(i).GetLevel();
 
       if (level < upperLevel)
       {
@@ -503,7 +506,7 @@
 
   void ISqlLookupFormatter::Apply(std::string& sql,
                                   ISqlLookupFormatter& formatter,
-                                  const std::vector<DatabaseConstraint>& lookup,
+                                  const DatabaseConstraints& lookup,
                                   ResourceType queryLevel,
                                   const std::set<std::string>& labels,
                                   LabelsConstraint labelsConstraint,
@@ -521,14 +524,16 @@
 
     size_t count = 0;
     
-    for (size_t i = 0; i < lookup.size(); i++)
+    for (size_t i = 0; i < lookup.GetSize(); i++)
     {
+      const DatabaseConstraint& constraint = lookup.GetConstraint(i);
+
       std::string comparison;
       
-      if (FormatComparison(comparison, formatter, lookup[i], count, escapeBrackets))
+      if (FormatComparison(comparison, formatter, constraint, count, escapeBrackets))
       {
         std::string join;
-        FormatJoin(join, lookup[i], count);
+        FormatJoin(join, constraint, count);
         joins += join;
 
         if (!comparison.empty())
@@ -614,7 +619,7 @@
 
   void ISqlLookupFormatter::ApplySingleLevel(std::string& sql,
                                              ISqlLookupFormatter& formatter,
-                                             const std::vector<DatabaseConstraint>& lookup,
+                                             const DatabaseConstraints& lookup,
                                              ResourceType queryLevel,
                                              const std::set<std::string>& labels,
                                              LabelsConstraint labelsConstraint,
@@ -631,15 +636,17 @@
     
     std::vector<std::string> mainDicomTagsComparisons, dicomIdentifiersComparisons;
 
-    for (size_t i = 0; i < lookup.size(); i++)
+    for (size_t i = 0; i < lookup.GetSize(); i++)
     {
+      const DatabaseConstraint& constraint = lookup.GetConstraint(i);
+
       std::string comparison;
       
-      if (FormatComparison2(comparison, formatter, lookup[i], escapeBrackets))
+      if (FormatComparison2(comparison, formatter, constraint, escapeBrackets))
       {
         if (!comparison.empty())
         {
-          if (lookup[i].IsIdentifier())
+          if (constraint.IsIdentifier())
           {
             dicomIdentifiersComparisons.push_back(comparison);
           }
--- a/Resources/Orthanc/Databases/ISqlLookupFormatter.h	Thu Jun 06 15:12:01 2024 +0200
+++ b/Resources/Orthanc/Databases/ISqlLookupFormatter.h	Mon Sep 09 12:45:18 2024 +0200
@@ -34,7 +34,7 @@
 
 namespace Orthanc
 {
-  class DatabaseConstraint;
+  class DatabaseConstraints;
   
   enum LabelsConstraint
   {
@@ -64,11 +64,14 @@
      **/
     virtual bool IsEscapeBrackets() const = 0;
 
-    static void GetLookupLevels(ResourceType& lowerLevel, ResourceType& upperLevel, const ResourceType& queryLevel, const std::vector<DatabaseConstraint>& lookup);
+    static void GetLookupLevels(ResourceType& lowerLevel,
+                                ResourceType& upperLevel,
+                                const ResourceType& queryLevel,
+                                const DatabaseConstraints& lookup);
 
     static void Apply(std::string& sql,
                       ISqlLookupFormatter& formatter,
-                      const std::vector<DatabaseConstraint>& lookup,
+                      const DatabaseConstraints& lookup,
                       ResourceType queryLevel,
                       const std::set<std::string>& labels,  // New in Orthanc 1.12.0
                       LabelsConstraint labelsConstraint,    // New in Orthanc 1.12.0
@@ -76,7 +79,7 @@
 
     static void ApplySingleLevel(std::string& sql,
                                  ISqlLookupFormatter& formatter,
-                                 const std::vector<DatabaseConstraint>& lookup,
+                                 const DatabaseConstraints& lookup,
                                  ResourceType queryLevel,
                                  const std::set<std::string>& labels,  // New in Orthanc 1.12.0
                                  LabelsConstraint labelsConstraint,    // New in Orthanc 1.12.0
--- a/TODO	Thu Jun 06 15:12:01 2024 +0200
+++ b/TODO	Mon Sep 09 12:45:18 2024 +0200
@@ -58,6 +58,7 @@
 
 * MySQL performance => implement GlobalProperty_GetTotalSizeIsFast:
   https://groups.google.com/d/msg/orthanc-users/kSR4a110zDo/D7e4ITR8BwAJ
+  https://discourse.orthanc-server.org/t/when-running-housekeeping-mysqld-exe-searching-and-dicom-transfer-is-slow/4921/9
 
 * Add index to speed up wildcard search, as already done in PostgreSQL: